Implement authentication checks on booking page to require user login before accessing appointment features. Update form fields and buttons to disable when not authenticated, and enhance user experience with appropriate prompts and dialog handling.

This commit is contained in:
iamkiddy 2025-12-04 19:52:58 +00:00
parent 77bc00999d
commit e05f81ddae

View File

@ -104,6 +104,14 @@ export default function BookNowPage() {
const [showSignupDialog, setShowSignupDialog] = useState(false);
const [loginPrefillEmail, setLoginPrefillEmail] = useState<string | undefined>(undefined);
// Require authentication before accessing booking page
useEffect(() => {
if (!isAuthenticated) {
// Show login dialog immediately if not authenticated
setShowLoginDialog(true);
}
}, [isAuthenticated]);
// Helper function to convert day name to day number (0-6)
const getDayNumber = (dayName: string): number => {
const dayMap: Record<string, number> = {
@ -241,15 +249,21 @@ export default function BookNowPage() {
const handleLoginSuccess = async () => {
// Close login dialog
setShowLoginDialog(false);
// After successful login, proceed with booking submission
await submitBooking();
// If there's a pending booking submission, proceed with it
// Otherwise, just close the dialog and allow user to fill the form
if (formData.selectedSlots.length > 0 && formData.firstName && formData.lastName && formData.email) {
await submitBooking();
}
};
const handleSignupSuccess = async () => {
// Close signup dialog
setShowSignupDialog(false);
// After successful signup, proceed with booking submission
await submitBooking();
// If there's a pending booking submission, proceed with it
// Otherwise, just close the dialog and allow user to fill the form
if (formData.selectedSlots.length > 0 && formData.firstName && formData.lastName && formData.email) {
await submitBooking();
}
};
const handleSwitchToSignup = () => {
@ -652,6 +666,13 @@ export default function BookNowPage() {
<p className={`text-sm ${isDark ? 'text-red-200' : 'text-red-800'}`}>{error}</p>
</div>
)}
{!isAuthenticated && (
<div className={`mb-6 p-4 rounded-lg border ${isDark ? 'bg-yellow-900/20 border-yellow-800' : 'bg-yellow-50 border-yellow-200'}`}>
<p className={`text-sm ${isDark ? 'text-yellow-200' : 'text-yellow-800'}`}>
Please log in to book an appointment. The login dialog should appear automatically.
</p>
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
{/* Personal Information Section */}
<div className="space-y-4">
@ -678,6 +699,7 @@ export default function BookNowPage() {
}
maxLength={100}
required
disabled={!isAuthenticated}
className={`h-11 ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900 placeholder:text-gray-500'}`}
/>
</div>
@ -699,6 +721,7 @@ export default function BookNowPage() {
}
maxLength={100}
required
disabled={!isAuthenticated}
className={`h-11 ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900 placeholder:text-gray-500'}`}
/>
</div>
@ -720,6 +743,7 @@ export default function BookNowPage() {
onChange={(e) => handleChange("email", e.target.value)}
maxLength={100}
required
disabled={!isAuthenticated}
className={`h-11 ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900 placeholder:text-gray-500'}`}
/>
</div>
@ -740,6 +764,7 @@ export default function BookNowPage() {
onChange={(e) => handleChange("phone", e.target.value)}
maxLength={100}
required
disabled={!isAuthenticated}
className={`h-11 ${isDark ? 'bg-gray-700 border-gray-600 text-white placeholder:text-gray-400' : 'bg-white border-gray-300 text-gray-900 placeholder:text-gray-500'}`}
/>
</div>
@ -814,9 +839,14 @@ export default function BookNowPage() {
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (!isAuthenticated) {
setShowLoginDialog(true);
return;
}
// Pass the specific day and time slot for this button
handleSlotToggle(currentDay, normalizedTimeSlot);
}}
disabled={!isAuthenticated}
aria-pressed={isSelected}
className={`flex items-center gap-2 cursor-pointer px-4 py-2 rounded-lg border-2 transition-all focus:outline-none focus:ring-2 focus:ring-rose-500 ${
isSelected
@ -861,6 +891,7 @@ export default function BookNowPage() {
value={formData.message}
onChange={(e) => handleChange("message", e.target.value)}
maxLength={100}
disabled={!isAuthenticated}
className={`w-full rounded-md border px-3 py-2 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-rose-500 focus-visible:border-rose-500 disabled:cursor-not-allowed disabled:opacity-50 ${isDark ? 'border-gray-600 bg-gray-700 text-white placeholder:text-gray-400 focus-visible:ring-rose-400 focus-visible:border-rose-400' : 'border-gray-300 bg-white text-gray-900 placeholder:text-gray-500'}`}
/>
</div>
@ -870,7 +901,7 @@ export default function BookNowPage() {
<Button
type="submit"
size="lg"
disabled={isCreating || availableDaysOfWeek.length === 0 || formData.selectedSlots.length === 0}
disabled={!isAuthenticated || isCreating || availableDaysOfWeek.length === 0 || formData.selectedSlots.length === 0}
className="w-full bg-gradient-to-r from-rose-500 to-pink-600 hover:from-rose-600 hover:to-pink-700 text-white shadow-lg hover:shadow-xl transition-all h-12 text-base font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
>
{isCreating ? (
@ -915,6 +946,12 @@ export default function BookNowPage() {
<LoginDialog
open={showLoginDialog}
onOpenChange={(open) => {
// Prevent closing if user is not authenticated (force login)
if (!open && !isAuthenticated) {
// Redirect to home if they try to close without logging in
router.push("/");
return;
}
setShowLoginDialog(open);
if (!open) {
setLoginPrefillEmail(undefined);