diff --git a/app/api/auth/register/route.ts b/app/api/auth/register/route.ts new file mode 100644 index 0000000..2e2bd37 --- /dev/null +++ b/app/api/auth/register/route.ts @@ -0,0 +1,6 @@ +import { handleApiRequest } from '@/lib/api-utils' +import { NextRequest } from 'next/server' + +export async function POST(request: NextRequest) { + return handleApiRequest(request, '/auth/register', 'POST') +} \ No newline at end of file diff --git a/app/api/auth/resend/route.ts b/app/api/auth/resend/route.ts new file mode 100644 index 0000000..d1aafae --- /dev/null +++ b/app/api/auth/resend/route.ts @@ -0,0 +1,6 @@ +import { handleApiRequest } from '@/lib/api-utils' +import { NextRequest } from 'next/server' + +export async function POST(request: NextRequest) { + return handleApiRequest(request, 'auth/resend-verification-mail', 'POST') +} \ No newline at end of file diff --git a/app/api/auth/verify/route.ts b/app/api/auth/verify/route.ts new file mode 100644 index 0000000..445914b --- /dev/null +++ b/app/api/auth/verify/route.ts @@ -0,0 +1,6 @@ +import { handleApiRequest } from '@/lib/api-utils' +import { NextRequest } from 'next/server' + +export async function POST(request: NextRequest) { + return handleApiRequest(request, '/auth/email/verify', 'POST') +} \ No newline at end of file diff --git a/app/auth/otp/page.tsx b/app/auth/otp/page.tsx index 7fc09f8..f3331f1 100644 --- a/app/auth/otp/page.tsx +++ b/app/auth/otp/page.tsx @@ -5,10 +5,10 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { motion } from 'framer-motion'; import { Button } from '@/components/ui/button'; import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp'; -import { apiService } from '@/lib/api-service'; import { useToast } from '@/hooks/use-toast'; import { AuthCard } from '../auth-card'; import { REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp'; +import { useAuth } from '@/hooks/useAuth'; export default function OtpPage() { const router = useRouter(); @@ -18,17 +18,19 @@ export default function OtpPage() { const [loading, setLoading] = useState(false); const [otp, setOtp] = useState(''); + const auth = useAuth(); + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { - await apiService.verifyEmail({ email, token: otp }); + await auth.verify(email, otp); toast({ title: 'Success', description: 'Email verified successfully', }); - router.push('/auth/basic-info'); + router.push('/auth/login'); } catch (error: any) { toast({ variant: 'destructive', @@ -42,7 +44,7 @@ export default function OtpPage() { const handleResendOtp = async () => { try { - await apiService.resendOtp(email); + await auth.resend(email); toast({ title: 'Success', description: 'OTP resent successfully', diff --git a/app/auth/register/page.tsx b/app/auth/register/page.tsx index 7f4fcf3..880af83 100644 --- a/app/auth/register/page.tsx +++ b/app/auth/register/page.tsx @@ -7,14 +7,14 @@ import { motion } from 'framer-motion'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { apiService } from '@/lib/api-service'; import { useToast } from '@/hooks/use-toast'; import { AuthCard } from '../auth-card'; +import { useAuthStore } from '@/store/authStore'; +import { useAuth } from '@/hooks/useAuth'; export default function RegisterPage() { const router = useRouter(); const { toast } = useToast(); - const [loading, setLoading] = useState(false); const [formData, setFormData] = useState({ email: '', password: '', @@ -23,6 +23,9 @@ export default function RegisterPage() { last_name: '', }); + const { register, loading } = useAuthStore(); + const auth = useAuth(); + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -35,16 +38,16 @@ export default function RegisterPage() { return; } - setLoading(true); + // setLoading(true); try { - await apiService.register({ - email: formData.email, - password: formData.password, - last_name: formData.last_name, - first_name: formData.first_name, - password_confirmation: formData.confirmPassword, - }); + await auth.register( + formData.email, + formData.password, + formData.confirmPassword, + formData.first_name, + formData.last_name + ); toast({ title: 'Success', description: 'Registration successful. Please verify your email.', @@ -56,8 +59,6 @@ export default function RegisterPage() { title: 'Error', description: error instanceof Error ? error.message : 'Failed to register', }); - } finally { - setLoading(false); } }; diff --git a/hooks/useAuth.ts b/hooks/useAuth.ts index 3ade0ff..016265f 100644 --- a/hooks/useAuth.ts +++ b/hooks/useAuth.ts @@ -3,7 +3,7 @@ import { useRouter } from 'next/navigation'; import { useAuthStore } from '../store/authStore'; export function useAuth() { - const { user, loading, login, logout, register, fetchCurrentUser } = useAuthStore(); + const { user, loading, login, logout, register, fetchCurrentUser, verifyEmail, resendOtp } = useAuthStore(); const router = useRouter(); useEffect(() => { @@ -25,6 +25,16 @@ export function useAuth() { router.push('/dashboard'); // Redirect to the dashboard after login }; + const verify = async (email: string, token: string) => { + await verifyEmail(email, token); + router.push('/auth/login'); + }; + + const resend = async (email: string) => { + await resendOtp(email); + router.push('/auth/otp'); + }; + const handleLogout = async () => { await logout(); router.push('/auth/login'); // Redirect to login page after logout @@ -41,5 +51,5 @@ export function useAuth() { router.push('/dashboard'); // Redirect to the dashboard after registration }; - return { user, loading, login: handleLogin, logout: handleLogout, register: handleRegister }; + return { user, loading, login: handleLogin, logout: handleLogout, register: handleRegister, verify, resend }; } diff --git a/store/authStore.ts b/store/authStore.ts index 97938de..b878e0f 100644 --- a/store/authStore.ts +++ b/store/authStore.ts @@ -10,6 +10,8 @@ interface AuthState { loading: boolean; login: (email: string, password: string) => Promise; logout: () => Promise; + verifyEmail: (email: string, token: string) => Promise; + resendOtp: (email: string) => Promise; register: ( email: string, password: string, @@ -50,6 +52,48 @@ export const useAuthStore = create((set) => ({ throw error; } }, + verifyEmail: async (email: string, token: string) => { + try { + set({ loading: true }); + + const response = await fetch('/api/auth/verify', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, token }), + }); + + if (response.ok) { + set({ loading: false }); + } else { + throw new Error('Verification failed'); + } + } catch (error) { + console.error('Verification error:', error); + set({ loading: false }); + throw error; + } + }, + resendOtp: async (email: string) => { + try { + set({ loading: true }); + + const response = await fetch('/api/auth/resend', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email }), + }); + + if (response.ok) { + set({ loading: false }); + } else { + throw new Error('Verification failed'); + } + } catch (error) { + console.error('Verification error:', error); + set({ loading: false }); + throw error; + } + }, logout: async () => { try {