'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { useSession } from 'next-auth/react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card' import { Progress } from '@/components/ui/progress' import { Loader2, Lock, CheckCircle2, AlertCircle, Eye, EyeOff } from 'lucide-react' import Image from 'next/image' import { trpc } from '@/lib/trpc/client' export default function SetPasswordPage() { const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [showPassword, setShowPassword] = useState(false) const [showConfirmPassword, setShowConfirmPassword] = useState(false) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) const [isSuccess, setIsSuccess] = useState(false) const router = useRouter() const { data: session, update: updateSession } = useSession() const setPasswordMutation = trpc.user.setPassword.useMutation({ onSuccess: async () => { setIsSuccess(true) // Update the session to reflect the password has been set await updateSession() // Redirect after a short delay setTimeout(() => { if (session?.user?.role === 'JURY_MEMBER') { router.push('/jury') } else if (session?.user?.role === 'SUPER_ADMIN' || session?.user?.role === 'PROGRAM_ADMIN') { router.push('/admin') } else { router.push('/') } }, 2000) }, onError: (err) => { setError(err.message || 'Failed to set password. Please try again.') setIsLoading(false) }, }) // Redirect if not authenticated useEffect(() => { if (session === null) { router.push('/login') } }, [session, router]) // Password validation const validatePassword = (pwd: string) => { const errors: string[] = [] if (pwd.length < 8) errors.push('At least 8 characters') if (!/[A-Z]/.test(pwd)) errors.push('One uppercase letter') if (!/[a-z]/.test(pwd)) errors.push('One lowercase letter') if (!/[0-9]/.test(pwd)) errors.push('One number') return errors } const passwordErrors = validatePassword(password) const isPasswordValid = passwordErrors.length === 0 const doPasswordsMatch = password === confirmPassword && password.length > 0 // Password strength const getPasswordStrength = (pwd: string): { score: number; label: string; color: string } => { let score = 0 if (pwd.length >= 8) score++ if (pwd.length >= 12) score++ if (/[a-z]/.test(pwd) && /[A-Z]/.test(pwd)) score++ if (/[0-9]/.test(pwd)) score++ if (/[^a-zA-Z0-9]/.test(pwd)) score++ const normalizedScore = Math.min(4, score) const labels = ['Very Weak', 'Weak', 'Fair', 'Strong', 'Very Strong'] const colors = ['bg-red-500', 'bg-orange-500', 'bg-yellow-500', 'bg-green-500', 'bg-green-600'] return { score: normalizedScore, label: labels[normalizedScore], color: colors[normalizedScore], } } const strength = getPasswordStrength(password) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setError(null) if (!isPasswordValid) { setError('Password does not meet requirements.') return } if (!doPasswordsMatch) { setError('Passwords do not match.') return } setIsLoading(true) setPasswordMutation.mutate({ password, confirmPassword }) } // Loading state while checking session if (session === undefined) { return ( ) } // Success state if (isSuccess) { return (
Password Set Successfully Your password has been set. You can now sign in with your email and password.

Redirecting you to the dashboard...

) } return (
MOPC
Set Your Password Create a secure password to sign in to your account in the future.
{error && (

{error}

)}
setPassword(e.target.value)} required disabled={isLoading} autoComplete="new-password" autoFocus className="pr-10" />
{/* Password strength indicator */} {password.length > 0 && (
{strength.label}
{/* Requirements checklist */}
{[ { label: '8+ characters', met: password.length >= 8 }, { label: 'Uppercase', met: /[A-Z]/.test(password) }, { label: 'Lowercase', met: /[a-z]/.test(password) }, { label: 'Number', met: /[0-9]/.test(password) }, ].map((req) => (
{req.met ? ( ) : (
)} {req.label}
))}
)}
setConfirmPassword(e.target.value)} required disabled={isLoading} autoComplete="new-password" className="pr-10" />
{confirmPassword.length > 0 && (

{doPasswordsMatch ? 'Passwords match' : 'Passwords do not match'}

)}
) }