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

This commit is contained in:
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,33 +31,32 @@ 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="px-8 pb-10"> <CardContent className="pb-8">
{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"> <div className="mb-4 text-sm font-medium text-green-600">
{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)}
@@ -67,14 +65,14 @@ export default function Login({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<div className="flex items-center justify-between mb-1"> <div className="flex items-center justify-between">
<Label htmlFor="password" className="text-[10px] font-black uppercase tracking-widest text-muted-foreground ml-1">Password</Label> <Label htmlFor="password">Password</Label>
{canResetPassword && ( {canResetPassword && (
<Link <Link
href={route('password.request')} href={route('password.request')}
className="text-[10px] text-nihonbuzz-red hover:underline font-black uppercase tracking-widest" className="text-xs text-nihonbuzz-red hover:underline font-medium"
> >
Lupa sandi? Lupa password?
</Link> </Link>
)} )}
</div> </div>
@@ -84,37 +82,36 @@ export default function Login({
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="current-password" autoComplete="current-password"
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="flex items-center space-x-2 pb-2"> <div className="flex items-center space-x-2">
<Checkbox <Checkbox
id="remember" id="remember"
checked={data.remember} checked={data.remember}
onCheckedChange={(checked) => setData('remember', checked as boolean)} onCheckedChange={(checked) => setData('remember', checked as boolean)}
className="rounded-md border-white/30"
/> />
<Label htmlFor="remember" className="text-xs text-muted-foreground font-bold cursor-pointer hover:text-foreground transition-colors"> <Label htmlFor="remember" className="text-sm text-gray-600 font-normal cursor-pointer">
Ingat sesi saya di perangkat ini Ingat saya
</Label> </Label>
</div> </div>
<div className="pt-2"> <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}> <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}>
Masuk ke Platform <LogIn className="ml-2 w-5 h-5 group-hover:translate-x-1 transition-transform" /> Masuk Sekarang
</Button> </Button>
</div> </div>
<div className="relative py-4"> <div className="relative">
<div className="absolute inset-0 flex items-center px-4"> <div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-muted-foreground/10" /> <span className="w-full border-t border-gray-100" />
</div> </div>
<div className="relative flex justify-center text-[10px] uppercase font-black tracking-[0.2em]"> <div className="relative flex justify-center text-xs uppercase">
<span className="bg-transparent px-4 text-muted-foreground/40">Atau gunakan</span> <span className="bg-white px-2 text-gray-500 font-medium">Atau masuk dengan</span>
</div> </div>
</div> </div>
@@ -122,7 +119,7 @@ export default function Login({
<Button <Button
type="button" type="button"
variant="outline" variant="outline"
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" 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"
onClick={() => window.location.href = route('social.redirect', { provider: 'google' })} onClick={() => window.location.href = route('social.redirect', { provider: 'google' })}
> >
<svg className="w-5 h-5" viewBox="0 0 24 24"> <svg className="w-5 h-5" viewBox="0 0 24 24">
@@ -143,24 +140,23 @@ export default function Login({
fill="#EA4335" fill="#EA4335"
/> />
</svg> </svg>
<span className="text-gray-600 dark:text-gray-300">Akses Cepat via Google</span> Google
</Button> </Button>
</div> </div>
<div className="text-center pt-4"> <div className="text-center text-sm text-gray-500">
<p className="text-xs text-muted-foreground font-medium"> Belum punya akun?{' '}
Belum menjadi peserta didik?{' '}
<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,28 +25,27 @@ 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="px-8 pb-10"> <CardContent className="pb-8">
<form onSubmit={submit} className="space-y-4"> <form onSubmit={submit} className="space-y-6">
<div className="space-y-2"> <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> <Label htmlFor="name">Nama Lengkap</Label>
<Input <Input
id="name" id="name"
name="name" name="name"
value={data.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" className="block w-full"
autoComplete="name" autoComplete="name"
placeholder="Masukkan nama lengkap Anda" placeholder="Nama Lengkap Anda"
onChange={(e) => setData('name', e.target.value)} onChange={(e) => setData('name', e.target.value)}
required required
/> />
@@ -55,30 +53,30 @@ export default function Register() {
</div> </div>
<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">Alamat Email</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="email@contoh.com" placeholder="nama@email.com"
onChange={(e) => setData('email', e.target.value)} onChange={(e) => setData('email', e.target.value)}
required required
/> />
<InputError message={errors.email} /> <InputError message={errors.email} />
</div> </div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-1"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<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="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"
onChange={(e) => setData('password', e.target.value)} onChange={(e) => setData('password', e.target.value)}
required required
@@ -87,13 +85,13 @@ export default function Register() {
</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="password_confirmation">Konfirmasi</Label>
<Input <Input
id="password_confirmation" id="password_confirmation"
type="password" type="password"
name="password_confirmation" name="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)}
required required
@@ -102,26 +100,25 @@ export default function Register() {
</div> </div>
</div> </div>
<div className="pt-6"> <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}> <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 <UserPlus className="ml-2 w-5 h-5 group-hover:rotate-12 transition-transform" /> Daftar Sekarang
</Button> </Button>
</div> </div>
<div className="text-center pt-4"> <div className="text-center text-sm text-gray-500">
<p className="text-xs text-muted-foreground font-medium"> Sudah punya akun?{' '}
Sudah memiliki akun LPK?{' '}
<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>
<div className="text-center pt-2">
<Link <Link
href={route('logout')} href={route('logout')}
method="post" method="post"
as="button" as="button"
className="text-muted-foreground font-black hover:text-nihonbuzz-red uppercase tracking-widest text-[10px] flex items-center justify-center gap-1 transition-colors" 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"
> >
<LogOut className="w-3 h-3" /> Keluar dari Sesi Log Out
</Link> </Link>
</div>
</form> </form>
</CardContent> </div>
</Card> </div>
</GuestLayout> </GuestLayout>
); );
} }