"use client"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { useAppTheme } from "@/components/ThemeProvider"; import { Input } from "@/components/ui/input"; import { InputOTP, InputOTPGroup, InputOTPSlot, } from "@/components/ui/input-otp"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Eye, EyeOff, Loader2, X, CheckCircle2 } from "lucide-react"; import { useAuth } from "@/hooks/useAuth"; import { registerSchema, verifyOtpSchema, type RegisterInput, type VerifyOtpInput } from "@/lib/schema/auth"; import { toast } from "sonner"; interface SignupDialogProps { open: boolean; onOpenChange: (open: boolean) => void; onSignupSuccess?: () => void; onSwitchToLogin?: (email?: string) => void; } type Step = "signup" | "verify"; export function SignupDialog({ open, onOpenChange, onSignupSuccess, onSwitchToLogin }: SignupDialogProps) { const { theme } = useAppTheme(); const isDark = theme === "dark"; const { register, verifyOtp, registerMutation, verifyOtpMutation, resendOtpMutation } = useAuth(); const [step, setStep] = useState("signup"); const [registeredEmail, setRegisteredEmail] = useState(""); const [signupData, setSignupData] = useState({ first_name: "", last_name: "", email: "", phone_number: "", password: "", password2: "", }); const [otpData, setOtpData] = useState({ email: "", otp: "", }); const [showPassword, setShowPassword] = useState(false); const [showPassword2, setShowPassword2] = useState(false); const handleSignup = async (e: React.FormEvent) => { e.preventDefault(); // Validate form const validation = registerSchema.safeParse(signupData); if (!validation.success) { const firstError = validation.error.issues[0]; toast.error(firstError.message); return; } try { const result = await register(signupData); // Always switch to OTP verification step after successful registration const email = signupData.email; setRegisteredEmail(email); setOtpData({ email: email, otp: "" }); // Clear signup form setSignupData({ first_name: "", last_name: "", email: "", phone_number: "", password: "", password2: "", }); // Switch to verify step setStep("verify"); toast.success("Registration successful! Please check your email for OTP verification."); } catch (err) { const errorMessage = err instanceof Error ? err.message : "Signup failed. Please try again."; toast.error(errorMessage); } }; const handleVerifyOtp = async (e: React.FormEvent) => { e.preventDefault(); const emailToVerify = registeredEmail || otpData.email; if (!emailToVerify) { toast.error("Email is required"); return; } const validation = verifyOtpSchema.safeParse({ email: emailToVerify, otp: otpData.otp, }); if (!validation.success) { const firstError = validation.error.issues[0]; toast.error(firstError.message); return; } try { const result = await verifyOtp({ email: emailToVerify, otp: otpData.otp, }); if (result.message) { toast.success("Email verified successfully! Please log in."); // Close signup dialog and open login dialog with email const emailToPass = emailToVerify; onOpenChange(false); // Call onSwitchToLogin with email to open login dialog with pre-filled email if (onSwitchToLogin) { onSwitchToLogin(emailToPass); } } } catch (err) { const errorMessage = err instanceof Error ? err.message : "OTP verification failed. Please try again."; toast.error(errorMessage); } }; const handleResendOtp = async () => { const emailToResend = registeredEmail || otpData.email; if (!emailToResend) { toast.error("Email is required"); return; } try { await resendOtpMutation.mutateAsync({ email: emailToResend, context: "registration" }); toast.success("OTP resent successfully! Please check your email."); } catch (err) { const errorMessage = err instanceof Error ? err.message : "Failed to resend OTP"; toast.error(errorMessage); } }; const handleOtpChange = (field: keyof VerifyOtpInput, value: string) => { setOtpData((prev) => ({ ...prev, [field]: value })); }; // Reset step when dialog closes const handleDialogChange = (isOpen: boolean) => { if (!isOpen) { setStep("signup"); setRegisteredEmail(""); setOtpData({ email: "", otp: "" }); setSignupData({ first_name: "", last_name: "", email: "", phone_number: "", password: "", password2: "", }); } onOpenChange(isOpen); }; return ( {/* Header with Close Button - Fixed */}
{step === "signup" && "Create an account"} {step === "verify" && "Verify your email"} {step === "signup" && "Sign up to complete your booking"} {step === "verify" && "Enter the verification code sent to your email"} {/* Close Button */}
{/* Scrollable Content */}
{/* Signup Form */} {step === "signup" && (
{/* First Name Field */}
setSignupData({ ...signupData, first_name: e.target.value })} className={`h-11 sm:h-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
{/* Last Name Field */}
setSignupData({ ...signupData, last_name: e.target.value })} className={`h-11 sm:h-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
{/* Email Field */}
setSignupData({ ...signupData, email: e.target.value })} className={`h-11 sm:h-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
{/* Phone Field */}
setSignupData({ ...signupData, phone_number: e.target.value })} className={`h-11 sm:h-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} />
{/* Password Field */}
setSignupData({ ...signupData, password: e.target.value })} className={`h-11 sm:h-12 pr-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
{/* Confirm Password Field */}
setSignupData({ ...signupData, password2: e.target.value })} className={`h-11 sm:h-12 pr-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
{/* Submit Button */} {/* Switch to Login */}

Already have an account?{" "}

)} {/* OTP Verification Form */} {step === "verify" && (

Check your email

We've sent a 6-digit verification code to {registeredEmail || otpData.email || "your email address"}.

{/* Email Field (if not set) */} {!registeredEmail && (
handleOtpChange("email", e.target.value)} className={`h-11 sm:h-12 text-sm sm:text-base ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900'}`} required />
)} {/* OTP Field */}
handleOtpChange("otp", value)} >
{/* Resend OTP */}
{/* Submit Button */} {/* Back to signup */}
)}
); }