210 lines
6.5 KiB
TypeScript
210 lines
6.5 KiB
TypeScript
"use client";
|
|
|
|
import LOGO from "@/assets/logo.png";
|
|
import type { LoginRequest } from "@/features/auth/lib";
|
|
import { userInfoStore } from "@/shared/hooks/user-info";
|
|
import { Button } from "@/shared/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/shared/ui/card";
|
|
import {
|
|
Form,
|
|
FormControl,
|
|
FormField,
|
|
FormItem,
|
|
FormMessage,
|
|
} from "@/shared/ui/form";
|
|
import { Input } from "@/shared/ui/input";
|
|
import { Label } from "@/shared/ui/label";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/shared/ui/select";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
import { AxiosError } from "axios";
|
|
import { Loader2 } from "lucide-react";
|
|
import { useForm } from "react-hook-form";
|
|
import { toast } from "sonner";
|
|
import z from "zod";
|
|
import { auth_api } from "../lib/api";
|
|
import { loginform } from "../lib/form";
|
|
|
|
export default function LoginForm() {
|
|
const { user, setLoginUser } = userInfoStore();
|
|
|
|
const form = useForm<z.infer<typeof loginform>>({
|
|
resolver: zodResolver(loginform),
|
|
defaultValues: {
|
|
firstName: "",
|
|
lastName: "",
|
|
regions: "",
|
|
},
|
|
});
|
|
|
|
const { data: regions } = useQuery({
|
|
queryKey: ["region"],
|
|
queryFn: () => auth_api.getRegions(),
|
|
select(data) {
|
|
return data.data.data;
|
|
},
|
|
});
|
|
|
|
const { mutate, isPending } = useMutation({
|
|
mutationFn: (body: LoginRequest) => auth_api.create(body),
|
|
onSuccess: () => {
|
|
toast.success("Siz ro'yxatdan o'tingiz");
|
|
setLoginUser({
|
|
active: false,
|
|
first_name: form.getValues("firstName"),
|
|
last_name: form.getValues("lastName"),
|
|
});
|
|
},
|
|
onError: (error: AxiosError) => {
|
|
const data = error.response?.data as { message?: string };
|
|
const errorData = error.response?.data as {
|
|
messages?: {
|
|
token_class: string;
|
|
token_type: string;
|
|
message: string;
|
|
}[];
|
|
};
|
|
const errorName = error.response?.data as {
|
|
data?: {
|
|
name: string[];
|
|
};
|
|
};
|
|
|
|
const message =
|
|
Array.isArray(errorName.data?.name) && errorName.data.name.length
|
|
? errorName.data.name[0]
|
|
: data?.message ||
|
|
(Array.isArray(errorData?.messages) && errorData.messages.length
|
|
? errorData.messages[0].message
|
|
: undefined) ||
|
|
"Xatolik yuz berdi";
|
|
|
|
toast.error(message);
|
|
},
|
|
});
|
|
|
|
function handleSubmit(value: z.infer<typeof loginform>) {
|
|
mutate({
|
|
first_name: value.firstName,
|
|
last_name: value.lastName,
|
|
region: Number(value.regions),
|
|
telegram_id: user.user_id,
|
|
});
|
|
}
|
|
|
|
return (
|
|
<div className="w-full max-w-md h-screen flex items-center justify-center mx-auto">
|
|
<Card className="border-0 w-full shadow-none">
|
|
<CardHeader className="text-center">
|
|
<CardTitle className="text-2xl w-full flex justify-center items-center">
|
|
<img
|
|
src={LOGO}
|
|
width={300}
|
|
height={300}
|
|
alt="logo"
|
|
className="w-52 h-16"
|
|
/>
|
|
</CardTitle>
|
|
<CardDescription className="text-slate-600 mt-2 text-lg dark:text-slate-400">
|
|
Tizimga xush kelibsiz
|
|
</CardDescription>
|
|
</CardHeader>
|
|
|
|
<CardContent>
|
|
<Form {...form}>
|
|
<form
|
|
onSubmit={form.handleSubmit(handleSubmit)}
|
|
className="space-y-4"
|
|
>
|
|
<FormField
|
|
control={form.control}
|
|
name="firstName"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<Label>Ism</Label>
|
|
<FormControl>
|
|
<Input
|
|
placeholder="Ismingizni kiriting"
|
|
className="h-12 rounded-lg border-slate-200 dark:border-slate-700 focus:ring-2 focus:ring-emerald-500"
|
|
{...field}
|
|
/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="lastName"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<Label>Familiya</Label>
|
|
<FormControl>
|
|
<Input
|
|
placeholder="Familiyangizni kiriting"
|
|
className="h-12 rounded-lg border-slate-200 dark:border-slate-700 focus:ring-2 focus:ring-emerald-500"
|
|
{...field}
|
|
/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="regions"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<Label>Hudud</Label>
|
|
<FormControl>
|
|
<Select
|
|
onValueChange={field.onChange}
|
|
value={field.value}
|
|
>
|
|
<SelectTrigger className="!h-12 w-full rounded-lg border-slate-200 dark:border-slate-700 focus:ring-2 focus:ring-emerald-500">
|
|
<SelectValue placeholder="Hududingizni tanlang" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{regions &&
|
|
regions.map((region) => (
|
|
<SelectItem
|
|
key={region.id}
|
|
value={String(region.id)}
|
|
>
|
|
{region.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<Button
|
|
type="submit"
|
|
disabled={isPending}
|
|
className="w-full h-12 text-lg bg-emerald-600 hover:bg-emerald-700 dark:bg-emerald-500 dark:hover:bg-emerald-600 text-white font-medium rounded-lg transition-colors"
|
|
>
|
|
{isPending ? <Loader2 className="animate-spin" /> : "Kirish"}
|
|
</Button>
|
|
</form>
|
|
</Form>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|