mirror of
https://github.com/khairul169/garage-webui.git
synced 2026-09-18 10:23:21 +07:00
feat: add authentication
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { z } from "zod";
|
||||
import { loginSchema } from "./schema";
|
||||
import api from "@/lib/api";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export const useLogin = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (body: z.infer<typeof loginSchema>) => {
|
||||
return api.post("/auth/login", { body });
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["auth"] });
|
||||
},
|
||||
onError: (err) => {
|
||||
toast.error(err?.message || "Unknown error");
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import Button from "@/components/ui/button";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Card } from "react-daisyui";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { loginSchema } from "./schema";
|
||||
import { InputField } from "@/components/ui/input";
|
||||
import { useLogin } from "./hooks";
|
||||
|
||||
export default function LoginPage() {
|
||||
const form = useForm({
|
||||
resolver: zodResolver(loginSchema),
|
||||
defaultValues: { username: "", password: "" },
|
||||
});
|
||||
const login = useLogin();
|
||||
|
||||
return (
|
||||
<form onSubmit={form.handleSubmit((v) => login.mutate(v))}>
|
||||
<Card className="w-full max-w-md" bordered>
|
||||
<Card.Body>
|
||||
<Card.Title tag="h2">Login</Card.Title>
|
||||
<p className="text-base-content/60">
|
||||
Enter username and password below to log in to your account
|
||||
</p>
|
||||
|
||||
<InputField
|
||||
form={form}
|
||||
name="username"
|
||||
title="Username"
|
||||
placeholder="Enter your username"
|
||||
/>
|
||||
|
||||
<InputField
|
||||
form={form}
|
||||
name="password"
|
||||
title="Password"
|
||||
type="password"
|
||||
placeholder="Enter your password"
|
||||
/>
|
||||
|
||||
<Card.Actions className="mt-4">
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
className="w-full md:w-auto min-w-[100px]"
|
||||
loading={login.isPending}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
</Card.Actions>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const loginSchema = z.object({
|
||||
username: z.string().min(1, "Username is required"),
|
||||
password: z.string().min(1, "Password is required"),
|
||||
});
|
||||
Reference in New Issue
Block a user