website/components/ScheduleAppointmentDialog.tsx

175 lines
5.7 KiB
TypeScript
Raw Normal View History

'use client';
import * as React from 'react';
import { CalendarCheck, Loader2, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { DatePicker } from '@/components/DatePicker';
import { ClockTimePicker } from '@/components/ClockTimePicker';
import { DurationPicker } from '@/components/DurationPicker';
import type { Appointment } from '@/lib/models/appointments';
interface ScheduleAppointmentDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
appointment: Appointment | null;
scheduledDate: Date | undefined;
setScheduledDate: (date: Date | undefined) => void;
scheduledTime: string;
setScheduledTime: (time: string) => void;
scheduledDuration: number;
setScheduledDuration: (duration: number) => void;
onSchedule: () => Promise<void>;
isScheduling: boolean;
isDark?: boolean;
title?: string;
description?: string;
}
export function ScheduleAppointmentDialog({
open,
onOpenChange,
appointment,
scheduledDate,
setScheduledDate,
scheduledTime,
setScheduledTime,
scheduledDuration,
setScheduledDuration,
onSchedule,
isScheduling,
isDark = false,
title,
description,
}: ScheduleAppointmentDialogProps) {
const formatDate = (date: Date) => {
return date.toLocaleDateString("en-US", {
weekday: "long",
month: "long",
day: "numeric",
year: "numeric",
});
};
const formatTime = (timeString: string) => {
const [hours, minutes] = timeString.split(":").map(Number);
const date = new Date();
date.setHours(hours);
date.setMinutes(minutes);
return date.toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
hour12: true,
});
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className={`max-w-4xl max-h-[90vh] overflow-y-auto ${isDark ? "bg-gray-800 border-gray-700" : "bg-white border-gray-200"}`}>
<DialogHeader className="pb-4">
<DialogTitle className={`text-2xl font-semibold ${isDark ? "text-white" : "text-gray-900"}`}>
{title || "Schedule Appointment"}
</DialogTitle>
<DialogDescription className={`text-base ${isDark ? "text-gray-400" : "text-gray-500"}`}>
{description || (appointment
? `Set date and time for ${appointment.first_name} ${appointment.last_name}'s appointment`
: "Set date and time for this appointment")}
</DialogDescription>
</DialogHeader>
<div className="space-y-6 py-4">
{/* Date Selection */}
<div className="space-y-3">
<label className={`text-sm font-semibold ${isDark ? "text-gray-300" : "text-gray-700"}`}>
Select Date *
</label>
<div className={`p-4 rounded-xl border ${isDark ? "bg-gray-700/50 border-gray-600" : "bg-gray-50 border-gray-200"}`}>
<DatePicker
date={scheduledDate}
setDate={setScheduledDate}
/>
</div>
</div>
{/* Time Selection */}
<div className="space-y-3 -mt-2">
<div className={`p-4 rounded-xl border ${isDark ? "bg-gray-700/50 border-gray-600" : "bg-gray-50 border-gray-200"}`}>
<ClockTimePicker
time={scheduledTime}
setTime={setScheduledTime}
label="Select Time *"
isDark={isDark}
/>
</div>
</div>
{/* Duration Selection */}
<div className="space-y-3">
<div className={`p-4 rounded-xl border ${isDark ? "bg-gray-700/50 border-gray-600" : "bg-gray-50 border-gray-200"}`}>
<DurationPicker
duration={scheduledDuration}
setDuration={setScheduledDuration}
label="Duration"
isDark={isDark}
/>
</div>
</div>
{/* Preview */}
{scheduledDate && scheduledTime && (
<div className={`p-4 rounded-xl border ${isDark ? "bg-blue-500/10 border-blue-500/30" : "bg-blue-50 border-blue-200"}`}>
<p className={`text-sm font-medium mb-2 ${isDark ? "text-blue-300" : "text-blue-700"}`}>
Appointment Preview
</p>
<div className="space-y-1">
<p className={`text-base font-semibold ${isDark ? "text-white" : "text-gray-900"}`}>
{formatDate(scheduledDate)}
</p>
<p className={`text-sm ${isDark ? "text-gray-300" : "text-gray-700"}`}>
{formatTime(scheduledTime)} {scheduledDuration} minutes
</p>
</div>
</div>
)}
</div>
<DialogFooter className="gap-3 pt-4">
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isScheduling}
className={`h-12 px-6 ${isDark ? "border-gray-700 text-gray-300 hover:bg-gray-700" : ""}`}
>
Cancel
</Button>
<Button
onClick={onSchedule}
disabled={isScheduling || !scheduledDate || !scheduledTime}
className="h-12 px-6 bg-blue-600 hover:bg-blue-700 text-white"
>
{isScheduling ? (
<>
<Loader2 className="w-5 h-5 mr-2 animate-spin" />
Scheduling...
</>
) : (
<>
<CalendarCheck className="w-5 h-5 mr-2" />
Schedule Appointment
</>
)}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}