feat: Implement authentication flow, core application pages, and initial landing page components.

This commit is contained in:
nihonbuzz
2026-01-24 10:20:15 +07:00
parent fe6b195156
commit 62dc61aa31
7 changed files with 271 additions and 328 deletions

View File

@@ -5,13 +5,9 @@ import { Footer } from "@/Components/Landing/Footer";
export default function GuestLayout({ children }: { children: React.ReactNode }) { export default function GuestLayout({ children }: { children: React.ReactNode }) {
return ( return (
<ThemeProvider defaultTheme="dark" storageKey="nihonbuzz-theme"> <ThemeProvider defaultTheme="dark" storageKey="nihonbuzz-theme">
<div className="min-h-screen bg-background text-foreground selection:bg-primary/30 selection:text-primary flex flex-col"> <div className="min-h-screen bg-background text-foreground selection:bg-primary/30 selection:text-primary">
<Navbar /> <Navbar />
<main className="flex-1 flex items-center justify-center p-4 lg:p-8 pt-24 lg:pt-32"> <main>{children}</main>
<div className="w-full flex justify-center py-8">
{children}
</div>
</main>
<Footer /> <Footer />
</div> </div>
</ThemeProvider> </ThemeProvider>

View File

@@ -5,8 +5,6 @@ import { FormEventHandler } from 'react';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input'; import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label'; import { Label } from '@/Components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { Lock, ArrowRight } from 'lucide-react';
export default function ConfirmPassword() { export default function ConfirmPassword() {
const { data, setData, post, processing, errors, reset } = useForm({ const { data, setData, post, processing, errors, reset } = useForm({
@@ -23,44 +21,38 @@ export default function ConfirmPassword() {
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Konfirmasi Kata Sandi" /> <Head title="Confirm Password" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden w-full max-w-md"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <div className="w-full max-w-md bg-white p-8 rounded-3xl shadow-2xl border border-gray-100">
<div className="mx-auto w-12 h-12 bg-nihonbuzz-red/10 rounded-2xl flex items-center justify-center mb-4 text-nihonbuzz-red"> <div className="mb-6 text-sm text-gray-600 dark:text-gray-400">
<Lock className="w-6 h-6" /> This is a secure area of the application. Please confirm your
password before continuing.
</div> </div>
<CardTitle className="text-2xl font-black tracking-tight text-foreground">
Area Aman
</CardTitle>
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2 px-4 leading-loose">
Ini adalah area aman. Harap konfirmasi kata sandi Anda sebelum melanjutkan.
</CardDescription>
</CardHeader>
<CardContent className="px-8 pb-10">
<form onSubmit={submit} className="space-y-6"> <form onSubmit={submit} className="space-y-6">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Kata Sandi Anda</Label> <Label htmlFor="password">Password</Label>
<Input <Input
id="password" id="password"
type="password" type="password"
name="password" name="password"
value={data.password} value={data.password}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoFocus
onChange={(e) => setData('password', e.target.value)} onChange={(e) => setData('password', e.target.value)}
/> />
<InputError message={errors.password} /> <InputError message={errors.password} />
</div> </div>
<div className="pt-2"> <div className="flex items-center justify-end">
<Button className="w-full h-16 rounded-[1.5rem] text-sm font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98] group" disabled={processing}> <Button className="w-full bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 text-white font-bold py-3 rounded-xl" disabled={processing}>
Konfirmasi & Lanjutkan <ArrowRight className="inline-block w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" /> Confirm
</Button> </Button>
</div> </div>
</form> </form>
</CardContent> </div>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }

View File

@@ -1,12 +1,10 @@
import InputError from '@/Components/InputError'; import InputError from '@/Components/InputError';
import GuestLayout from '@/Layouts/GuestLayout'; import GuestLayout from '@/Layouts/GuestLayout';
import { Head, useForm, Link } from '@inertiajs/react'; import { Head, useForm } from '@inertiajs/react';
import { FormEventHandler } from 'react'; import { FormEventHandler } from 'react';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input'; import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label'; import { Label } from '@/Components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { KeyRound, ArrowLeft } from 'lucide-react';
export default function ForgotPassword({ status }: { status?: string }) { export default function ForgotPassword({ status }: { status?: string }) {
const { data, setData, post, processing, errors } = useForm({ const { data, setData, post, processing, errors } = useForm({
@@ -21,60 +19,45 @@ export default function ForgotPassword({ status }: { status?: string }) {
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Lupa Kata Sandi" /> <Head title="Forgot Password" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden w-full max-w-md"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <div className="w-full max-w-md bg-white p-8 rounded-3xl shadow-2xl border border-gray-100">
<div className="mx-auto w-12 h-12 bg-nihonbuzz-red/10 rounded-2xl flex items-center justify-center mb-4 text-nihonbuzz-red"> <div className="mb-6 text-sm text-gray-600 dark:text-gray-400">
<KeyRound className="w-6 h-6" /> Forgot your password? No problem. Just let us know your email
address and we will email you a password reset link that will
allow you to choose a new one.
</div> </div>
<CardTitle className="text-2xl font-black tracking-tight text-foreground">
Pemulihan Akses
</CardTitle>
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2 px-4 leading-loose">
Kami akan mengirimkan tautan reset kata sandi melalui alamat email terdaftar Anda.
</CardDescription>
</CardHeader>
<CardContent className="px-8 pb-10">
{status && ( {status && (
<div className="mb-6 p-4 rounded-2xl bg-green-500/10 border border-green-500/20 text-xs font-bold text-green-600 text-center animate-in fade-in slide-in-from-top-2"> <div className="mb-4 text-sm font-medium text-green-600 dark:text-green-400">
{status} {status}
</div> </div>
)} )}
<form onSubmit={submit} className="space-y-6"> <form onSubmit={submit} className="space-y-6">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="email" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Email Terdaftar</Label> <Label htmlFor="email">Email</Label>
<Input <Input
id="email" id="email"
type="email" type="email"
name="email" name="email"
value={data.email} value={data.email}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
placeholder="nama@email.com"
autoFocus
onChange={(e) => setData('email', e.target.value)} onChange={(e) => setData('email', e.target.value)}
/> />
<InputError message={errors.email} /> <InputError message={errors.email} />
</div> </div>
<div className="pt-2"> <div className="flex items-center justify-end">
<Button className="w-full h-16 rounded-[1.5rem] text-sm font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98]" disabled={processing}> <Button className="w-full bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 text-white font-bold py-3 rounded-xl" disabled={processing}>
Kirim Tautan Pemulihan Email Password Reset Link
</Button> </Button>
</div> </div>
<div className="text-center pt-2">
<Link
href={route('login')}
className="text-nihonbuzz-red font-black hover:underline uppercase tracking-widest text-[10px] flex items-center justify-center gap-1"
>
<ArrowLeft className="w-3 h-3" /> Kembali ke Halaman Masuk
</Link>
</div>
</form> </form>
</CardContent> </div>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }

View File

@@ -7,7 +7,6 @@ import { Input } from '@/Components/ui/input';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Checkbox } from '@/Components/ui/checkbox'; import { Checkbox } from '@/Components/ui/checkbox';
import InputError from '@/Components/InputError'; import InputError from '@/Components/InputError';
import { LogIn, ArrowRight } from 'lucide-react';
export default function Login({ export default function Login({
status, status,
@@ -32,135 +31,132 @@ export default function Login({
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Masuk ke Academy" /> <Head title="Log in" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <Card className="w-full max-w-md border-gray-100 shadow-2xl rounded-3xl overflow-hidden">
<CardTitle className="text-3xl font-black tracking-tight text-foreground flex items-center justify-center gap-3"> <CardHeader className="space-y-1 text-center pt-8">
Selamat Datang Kembali <CardTitle className="text-3xl font-extrabold tracking-tight">Selamat Datang Kembali</CardTitle>
</CardTitle> <CardDescription className="text-gray-500">
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2"> Masuk ke akun NihonBuzz Academy anda
Masuk ke portal siswa LPK NihonBuzz </CardDescription>
</CardDescription> </CardHeader>
</CardHeader> <CardContent className="pb-8">
<CardContent className="px-8 pb-10"> {status && (
{status && ( <div className="mb-4 text-sm font-medium text-green-600">
<div className="mb-6 p-4 rounded-2xl bg-green-500/10 border border-green-500/20 text-xs font-bold text-green-600 text-center"> {status}
{status} </div>
</div> )}
)}
<form onSubmit={submit} className="space-y-5"> <form onSubmit={submit} className="space-y-6">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="email" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Email Addres</Label> <Label htmlFor="email">Email</Label>
<Input <Input
id="email" id="email"
type="email" type="email"
name="email" name="email"
value={data.email} value={data.email}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoComplete="username" autoComplete="username"
placeholder="nama@email.com" placeholder="nama@email.com"
onChange={(e) => setData('email', e.target.value)} onChange={(e) => setData('email', e.target.value)}
/> />
<InputError message={errors.email} /> <InputError message={errors.email} />
</div>
<div className="space-y-2">
<div className="flex items-center justify-between mb-1">
<Label htmlFor="password" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Password</Label>
{canResetPassword && (
<Link
href={route('password.request')}
className="text-[10px] text-nihonbuzz-red hover:underline font-black uppercase tracking-widest"
>
Lupa sandi?
</Link>
)}
</div> </div>
<Input <div className="space-y-2">
id="password" <div className="flex items-center justify-between">
type="password" <Label htmlFor="password">Password</Label>
name="password" {canResetPassword && (
value={data.password} <Link
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" href={route('password.request')}
autoComplete="current-password" className="text-xs text-nihonbuzz-red hover:underline font-medium"
onChange={(e) => setData('password', e.target.value)} >
/> Lupa password?
<InputError message={errors.password} /> </Link>
</div> )}
</div>
<div className="flex items-center space-x-2 pb-2"> <Input
<Checkbox id="password"
id="remember" type="password"
checked={data.remember} name="password"
onCheckedChange={(checked) => setData('remember', checked as boolean)} value={data.password}
className="rounded-md border-white/30" className="block w-full"
/> autoComplete="current-password"
<Label htmlFor="remember" className="text-xs text-muted-foreground font-bold cursor-pointer hover:text-foreground transition-colors"> onChange={(e) => setData('password', e.target.value)}
Ingat sesi saya di perangkat ini />
</Label> <InputError message={errors.password} />
</div>
<div className="pt-2">
<Button className="w-full h-16 rounded-[1.5rem] text-base font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98] group" disabled={processing}>
Masuk ke Platform <LogIn className="ml-2 w-5 h-5 group-hover:translate-x-1 transition-transform" />
</Button>
</div>
<div className="relative py-4">
<div className="absolute inset-0 flex items-center px-4">
<span className="w-full border-t border-muted-foreground/10" />
</div> </div>
<div className="relative flex justify-center text-[10px] uppercase font-black tracking-[0.2em]">
<span className="bg-transparent px-4 text-muted-foreground/40">Atau gunakan</span>
</div>
</div>
<div className="grid grid-cols-1 gap-3"> <div className="flex items-center space-x-2">
<Button <Checkbox
type="button" id="remember"
variant="outline" checked={data.remember}
className="w-full h-16 rounded-[1.5rem] text-sm font-bold border-white/20 bg-white/50 dark:bg-white/5 hover:bg-white dark:hover:bg-white/10 flex items-center justify-center gap-3 transition-all group" onCheckedChange={(checked) => setData('remember', checked as boolean)}
onClick={() => window.location.href = route('social.redirect', { provider: 'google' })} />
> <Label htmlFor="remember" className="text-sm text-gray-600 font-normal cursor-pointer">
<svg className="w-5 h-5" viewBox="0 0 24 24"> Ingat saya
<path </Label>
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" </div>
fill="#4285F4"
/> <div className="pt-2">
<path <Button className="w-full py-6 rounded-2xl text-base font-bold shadow-lg shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90" disabled={processing}>
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" Masuk Sekarang
fill="#34A853" </Button>
/> </div>
<path
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z" <div className="relative">
fill="#FBBC05" <div className="absolute inset-0 flex items-center">
/> <span className="w-full border-t border-gray-100" />
<path </div>
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" <div className="relative flex justify-center text-xs uppercase">
fill="#EA4335" <span className="bg-white px-2 text-gray-500 font-medium">Atau masuk dengan</span>
/> </div>
</svg> </div>
<span className="text-gray-600 dark:text-gray-300">Akses Cepat via Google</span>
</Button> <div className="grid grid-cols-1 gap-3">
</div> <Button
type="button"
<div className="text-center pt-4"> variant="outline"
<p className="text-xs text-muted-foreground font-medium"> className="w-full py-6 rounded-2xl text-sm font-bold border-gray-100 hover:bg-gray-50 flex items-center justify-center gap-3 transition-all"
Belum menjadi peserta didik?{' '} onClick={() => window.location.href = route('social.redirect', { provider: 'google' })}
>
<svg className="w-5 h-5" viewBox="0 0 24 24">
<path
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
fill="#4285F4"
/>
<path
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
fill="#34A853"
/>
<path
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z"
fill="#FBBC05"
/>
<path
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
fill="#EA4335"
/>
</svg>
Google
</Button>
</div>
<div className="text-center text-sm text-gray-500">
Belum punya akun?{' '}
<Link <Link
href={route('register')} href={route('register')}
className="text-nihonbuzz-red font-black hover:underline uppercase tracking-widest text-[10px] ml-1" className="text-nihonbuzz-red font-bold hover:underline"
> >
Daftar Sekarang <ArrowRight className="inline-block w-3 h-3 ml-1" /> Daftar Gratis
</Link> </Link>
</p> </div>
</div> </form>
</form> </CardContent>
</CardContent> </Card>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }

View File

@@ -6,7 +6,6 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Com
import { Label } from '@/Components/ui/label'; import { Label } from '@/Components/ui/label';
import { Input } from '@/Components/ui/input'; import { Input } from '@/Components/ui/input';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { UserPlus, ArrowLeft } from 'lucide-react';
export default function Register() { export default function Register() {
const { data, setData, post, processing, errors, reset } = useForm({ const { data, setData, post, processing, errors, reset } = useForm({
@@ -26,102 +25,100 @@ export default function Register() {
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Registrasi Peserta Didik" /> <Head title="Register" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <Card className="w-full max-w-md border-gray-100 shadow-2xl rounded-3xl overflow-hidden">
<CardTitle className="text-3xl font-black tracking-tight text-foreground flex items-center justify-center gap-3"> <CardHeader className="space-y-1 text-center pt-8">
Mulai Belajar <CardTitle className="text-3xl font-extrabold tracking-tight">Buat Akun Baru</CardTitle>
</CardTitle> <CardDescription className="text-gray-500">
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2"> Mulai petualangan belajarmu hari ini
Pendaftaran Peserta Didik LPK NihonBuzz </CardDescription>
</CardDescription> </CardHeader>
</CardHeader> <CardContent className="pb-8">
<CardContent className="px-8 pb-10"> <form onSubmit={submit} className="space-y-6">
<form onSubmit={submit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="name" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Nama Lengkap Siswa</Label>
<Input
id="name"
name="name"
value={data.name}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all"
autoComplete="name"
placeholder="Masukkan nama lengkap Anda"
onChange={(e) => setData('name', e.target.value)}
required
/>
<InputError message={errors.name} />
</div>
<div className="space-y-2">
<Label htmlFor="email" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Alamat Email</Label>
<Input
id="email"
type="email"
name="email"
value={data.email}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all"
autoComplete="username"
placeholder="email@contoh.com"
onChange={(e) => setData('email', e.target.value)}
required
/>
<InputError message={errors.email} />
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-1">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Password</Label> <Label htmlFor="name">Nama Lengkap</Label>
<Input <Input
id="password" id="name"
type="password" name="name"
name="password" value={data.name}
value={data.password} className="block w-full"
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" autoComplete="name"
autoComplete="new-password" placeholder="Nama Lengkap Anda"
onChange={(e) => setData('password', e.target.value)} onChange={(e) => setData('name', e.target.value)}
required required
/> />
<InputError message={errors.password} /> <InputError message={errors.name} />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password_confirmation" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Konfirmasi</Label> <Label htmlFor="email">Email</Label>
<Input <Input
id="password_confirmation" id="email"
type="password" type="email"
name="password_confirmation" name="email"
value={data.password_confirmation} value={data.email}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoComplete="new-password" autoComplete="username"
onChange={(e) => setData('password_confirmation', e.target.value)} placeholder="nama@email.com"
onChange={(e) => setData('email', e.target.value)}
required required
/> />
<InputError message={errors.password_confirmation} /> <InputError message={errors.email} />
</div> </div>
</div>
<div className="pt-6"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<Button className="w-full h-16 rounded-[1.5rem] text-base font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98] group" disabled={processing}> <div className="space-y-2">
Daftar Sekarang <UserPlus className="ml-2 w-5 h-5 group-hover:rotate-12 transition-transform" /> <Label htmlFor="password">Password</Label>
</Button> <Input
</div> id="password"
type="password"
name="password"
value={data.password}
className="block w-full"
autoComplete="new-password"
onChange={(e) => setData('password', e.target.value)}
required
/>
<InputError message={errors.password} />
</div>
<div className="text-center pt-4"> <div className="space-y-2">
<p className="text-xs text-muted-foreground font-medium"> <Label htmlFor="password_confirmation">Konfirmasi</Label>
Sudah memiliki akun LPK?{' '} <Input
id="password_confirmation"
type="password"
name="password_confirmation"
value={data.password_confirmation}
className="block w-full"
autoComplete="new-password"
onChange={(e) => setData('password_confirmation', e.target.value)}
required
/>
<InputError message={errors.password_confirmation} />
</div>
</div>
<div className="pt-2">
<Button className="w-full py-6 rounded-2xl text-base font-bold shadow-lg shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90" disabled={processing}>
Daftar Sekarang
</Button>
</div>
<div className="text-center text-sm text-gray-500">
Sudah punya akun?{' '}
<Link <Link
href={route('login')} href={route('login')}
className="text-nihonbuzz-red font-black hover:underline uppercase tracking-widest text-[10px] ml-1" className="text-nihonbuzz-red font-bold hover:underline"
> >
<ArrowLeft className="inline-block w-3 h-3 mr-1" /> Kembali Masuk Masuk Saja
</Link> </Link>
</p> </div>
</div> </form>
</form> </CardContent>
</CardContent> </Card>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }

View File

@@ -5,8 +5,6 @@ import { FormEventHandler } from 'react';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input'; import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label'; import { Label } from '@/Components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { ShieldCheck, ArrowRight } from 'lucide-react';
export default function ResetPassword({ export default function ResetPassword({
token, token,
@@ -32,30 +30,21 @@ export default function ResetPassword({
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Reset Kata Sandi" /> <Head title="Reset Password" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden w-full max-w-md"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <div className="w-full max-w-md bg-white p-8 rounded-3xl shadow-2xl border border-gray-100">
<div className="mx-auto w-12 h-12 bg-nihonbuzz-red/10 rounded-2xl flex items-center justify-center mb-4 text-nihonbuzz-red"> <h2 className="text-2xl font-bold mb-6 text-center">Reset Password</h2>
<ShieldCheck className="w-6 h-6" />
</div> <form onSubmit={submit} className="space-y-6">
<CardTitle className="text-2xl font-black tracking-tight text-foreground">
Atur Ulang Sandi
</CardTitle>
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2 px-4 leading-loose">
Silakan masukkan kata sandi baru untuk akun Academy Anda.
</CardDescription>
</CardHeader>
<CardContent className="px-8 pb-10">
<form onSubmit={submit} className="space-y-5">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="email" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Email Konfirmasi</Label> <Label htmlFor="email">Email</Label>
<Input <Input
id="email" id="email"
type="email" type="email"
name="email" name="email"
value={data.email} value={data.email}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoComplete="username" autoComplete="username"
onChange={(e) => setData('email', e.target.value)} onChange={(e) => setData('email', e.target.value)}
/> />
@@ -63,42 +52,41 @@ export default function ResetPassword({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Kata Sandi Baru</Label> <Label htmlFor="password">Password</Label>
<Input <Input
id="password" id="password"
type="password" type="password"
name="password" name="password"
value={data.password} value={data.password}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoComplete="new-password" autoComplete="new-password"
autoFocus
onChange={(e) => setData('password', e.target.value)} onChange={(e) => setData('password', e.target.value)}
/> />
<InputError message={errors.password} /> <InputError message={errors.password} />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password_confirmation" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Konfirmasi Sandi Baru</Label> <Label htmlFor="password_confirmation">Confirm Password</Label>
<Input <Input
type="password" type="password"
name="password_confirmation" name="password_confirmation"
id="password_confirmation"
value={data.password_confirmation} value={data.password_confirmation}
className="h-14 rounded-2xl bg-white/50 dark:bg-black/50 border-white/20 focus:ring-nihonbuzz-red/20 focus:border-nihonbuzz-red transition-all" className="block w-full"
autoComplete="new-password" autoComplete="new-password"
onChange={(e) => setData('password_confirmation', e.target.value)} onChange={(e) => setData('password_confirmation', e.target.value)}
/> />
<InputError message={errors.password_confirmation} /> <InputError message={errors.password_confirmation} />
</div> </div>
<div className="pt-4"> <div className="flex items-center justify-end">
<Button className="w-full h-16 rounded-[1.5rem] text-sm font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98] group" disabled={processing}> <Button className="w-full bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 text-white font-bold py-3 rounded-xl" disabled={processing}>
Atur Ulang & Masuk <ArrowRight className="inline-block w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" /> Reset Password
</Button> </Button>
</div> </div>
</form> </form>
</CardContent> </div>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }

View File

@@ -2,8 +2,6 @@ import GuestLayout from '@/Layouts/GuestLayout';
import { Head, Link, useForm } from '@inertiajs/react'; import { Head, Link, useForm } from '@inertiajs/react';
import { FormEventHandler } from 'react'; import { FormEventHandler } from 'react';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { Mail, LogOut, Send } from 'lucide-react';
export default function VerifyEmail({ status }: { status?: string }) { export default function VerifyEmail({ status }: { status?: string }) {
const { post, processing } = useForm({}); const { post, processing } = useForm({});
@@ -16,47 +14,40 @@ export default function VerifyEmail({ status }: { status?: string }) {
return ( return (
<GuestLayout> <GuestLayout>
<Head title="Verifikasi Email" /> <Head title="Email Verification" />
<Card className="border-white/10 bg-white/40 dark:bg-black/40 backdrop-blur-2xl shadow-[0_24px_48px_-12px_rgba(0,0,0,0.1)] rounded-[2.5rem] overflow-hidden w-full max-w-md"> <div className="flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<CardHeader className="space-y-1 text-center pt-10 pb-6 px-8"> <div className="w-full max-w-md bg-white p-8 rounded-3xl shadow-2xl border border-gray-100 text-center">
<div className="mx-auto w-12 h-12 bg-nihonbuzz-red/10 rounded-2xl flex items-center justify-center mb-4 text-nihonbuzz-red"> <div className="mb-6 text-sm text-gray-600 dark:text-gray-400">
<Mail className="w-6 h-6" /> Thanks for signing up! Before getting started, could you verify
your email address by clicking on the link we just emailed to
you? If you didn't receive the email, we will gladly send you
another.
</div> </div>
<CardTitle className="text-2xl font-black tracking-tight text-foreground">
Verifikasi Akun
</CardTitle>
<CardDescription className="text-muted-foreground font-medium text-xs uppercase tracking-widest pt-2 px-4 leading-loose">
Terima kasih telah mendaftar! Sebelum memulai, silakan verifikasi alamat email Anda melalui tautan yang baru saja kami kirimkan.
</CardDescription>
</CardHeader>
<CardContent className="px-8 pb-10">
{status === 'verification-link-sent' && ( {status === 'verification-link-sent' && (
<div className="mb-6 p-4 rounded-2xl bg-green-500/10 border border-green-500/20 text-xs font-bold text-green-600 text-center animate-in fade-in slide-in-from-top-2"> <div className="mb-6 text-sm font-medium text-green-600 dark:text-green-400">
Tautan verifikasi baru telah berhasil dikirim ke alamat email Anda. A new verification link has been sent to the email address
you provided during registration.
</div> </div>
)} )}
<form onSubmit={submit} className="space-y-6"> <form onSubmit={submit} className="space-y-4">
<div className="pt-2"> <Button className="w-full bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 text-white font-bold py-3 rounded-xl" disabled={processing}>
<Button className="w-full h-16 rounded-[1.5rem] text-sm font-black shadow-2xl shadow-nihonbuzz-red/20 bg-nihonbuzz-red hover:bg-nihonbuzz-red/90 transition-all hover:scale-[1.02] active:scale-[0.98] group" disabled={processing}> Resend Verification Email
Kirim Ulang Email Verifikasi <Send className="ml-2 w-4 h-4 group-hover:translate-x-1 group-hover:-translate-y-1 transition-transform" /> </Button>
</Button>
</div> <Link
href={route('logout')}
<div className="text-center pt-2"> method="post"
<Link as="button"
href={route('logout')} className="text-sm text-gray-600 underline hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:text-gray-400 dark:hover:text-gray-100"
method="post" >
as="button" Log Out
className="text-muted-foreground font-black hover:text-nihonbuzz-red uppercase tracking-widest text-[10px] flex items-center justify-center gap-1 transition-colors" </Link>
>
<LogOut className="w-3 h-3" /> Keluar dari Sesi
</Link>
</div>
</form> </form>
</CardContent> </div>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }