proje / apps /web /src /components /auth /LoginForm.tsx
rodopsin
Initial commit: AJet360 dummy prototype
d34aa41
Raw
History Blame Contribute Delete
4.22 kB
'use client';
import { useState } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useRouter, useSearchParams } from 'next/navigation';
import { signIn } from 'next-auth/react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { DEMO_PASSWORD } from '@/lib/constants';
import { demoUsers } from '@/lib/mock-data';
const loginSchema = z.object({
email: z.string().min(1, 'Kullanici veya e-posta gerekli'),
password: z.string().min(1, 'Sifre gerekli'),
});
type LoginValues = z.infer<typeof loginSchema>;
export function LoginForm() {
const router = useRouter();
const searchParams = useSearchParams();
const [error, setError] = useState<string | null>(null);
const callbackUrl = searchParams.get('callbackUrl') ?? '/';
const form = useForm<LoginValues>({
resolver: zodResolver(loginSchema),
defaultValues: {
email: 'admin@ajet.com.tr',
password: DEMO_PASSWORD,
},
});
async function onSubmit(values: LoginValues) {
setError(null);
const result = await signIn('credentials', {
email: values.email,
password: values.password,
redirect: false,
callbackUrl,
});
if (result?.error) {
setError('E-posta veya sifre hatali');
return;
}
router.push(callbackUrl);
router.refresh();
}
return (
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>AJet Acente 360</CardTitle>
<CardDescription>Veritabanisiz MVP demo girisi</CardDescription>
</CardHeader>
<form onSubmit={form.handleSubmit(onSubmit)}>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">Kullanici veya e-posta</Label>
<Input
id="email"
type="text"
autoComplete="username"
{...form.register('email')}
/>
{form.formState.errors.email && (
<p className="text-sm text-destructive">
{form.formState.errors.email.message}
</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="password">Sifre</Label>
<Input
id="password"
type="password"
autoComplete="current-password"
{...form.register('password')}
/>
{form.formState.errors.password && (
<p className="text-sm text-destructive">
{form.formState.errors.password.message}
</p>
)}
</div>
{error && (
<p className="rounded-md bg-destructive/10 p-3 text-sm text-destructive">
{error}
</p>
)}
<div className="rounded-md bg-muted p-3 text-sm text-muted-foreground">
<p className="font-medium text-foreground">
Demo sifre: {DEMO_PASSWORD}
</p>
<p className="mt-1">Hizli tur icin hesaplar:</p>
<div className="mt-2 grid gap-1">
{demoUsers.map((user) => (
<button
key={user.email}
type="button"
className="text-left text-xs hover:text-foreground"
onClick={() => {
form.setValue('email', user.username);
form.setValue('password', DEMO_PASSWORD);
}}
>
{user.username} / {DEMO_PASSWORD} - {user.role}
</button>
))}
</div>
</div>
</CardContent>
<CardFooter>
<Button
type="submit"
className="w-full"
disabled={form.formState.isSubmitting}
>
{form.formState.isSubmitting ? 'Giris yapiliyor' : 'Giris yap'}
</Button>
</CardFooter>
</form>
</Card>
);
}