Skip to content

Commit 722f3d0

Browse files
committed
feat(appointments): enhance appointment details and status management with improved UI and validation
1 parent a17af47 commit 722f3d0

6 files changed

Lines changed: 167 additions & 118 deletions

File tree

‎apps/codebility/app/home/admin-controls/appointments/_components/AppointmentDetailSidebar.tsx‎

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,95 +14,98 @@ interface AppointmentDetailSidebarProps {
1414
export function AppointmentDetailSidebar({ appointment, isOpen, onClose }: AppointmentDetailSidebarProps) {
1515
if (!appointment) return null;
1616

17-
const fullName = [appointment.first_name, appointment.last_name].filter(Boolean).join(" ") || "Prospect Client";
17+
const fullName = [appointment.first_name, appointment.last_name].filter(Boolean).join(" ") || "Not provided";
1818

1919
return (
2020
<Sheet open={isOpen} onOpenChange={onClose}>
21-
<SheetContent className="bg-neutral-950 border-neutral-800 text-neutral-200 overflow-y-auto sm:max-w-md w-full shadow-2xl">
22-
<SheetHeader className="border-b border-neutral-800 pb-4">
23-
<SheetTitle className="text-xl font-bold text-white">{fullName}</SheetTitle>
24-
<SheetDescription className="text-neutral-400 text-xs mt-0.5">
21+
<SheetContent className="background-light900_dark300 border-light_dark text-dark200_light900 w-full overflow-y-auto shadow-2xl sm:max-w-md">
22+
<SheetHeader className="table-border-light_dark border-b pb-4">
23+
<SheetTitle className="text-xl font-bold text-dark-200 dark:text-light-900">{fullName}</SheetTitle>
24+
<SheetDescription className="mt-0.5 text-xs text-slate-500 dark:text-slate-400">
2525
Submitted request on {format(new Date(appointment.created_at), "PPP p")}
2626
</SheetDescription>
2727
</SheetHeader>
2828

2929
<div className="flex flex-col gap-6 py-6 text-sm">
30-
{/* Section 1: Contact Profiling Details */}
3130
<div className="flex flex-col gap-2">
32-
<h3 className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Contact Profiles</h3>
33-
<div className="rounded-lg bg-neutral-900/50 border border-neutral-800 p-3 flex flex-col gap-1.5 font-sans">
34-
<div><span className="text-neutral-500 text-xs">Email:</span> <span className="text-neutral-300 font-medium">{appointment.email || "N/A"}</span></div>
35-
<div><span className="text-neutral-500 text-xs">Phone:</span> <span className="text-neutral-300 font-medium">{appointment.phone_number || "N/A"}</span></div>
36-
<div><span className="text-neutral-500 text-xs">Company:</span> <span className="text-neutral-300 font-medium">{appointment.company_name || "N/A"}</span></div>
37-
<div><span className="text-neutral-500 text-xs">Industry:</span> <span className="text-neutral-300 font-medium">{appointment.industry || "N/A"}</span></div>
31+
<h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Contact Profile</h3>
32+
<div className="background-light800_dark400 border-light_dark flex flex-col gap-1.5 rounded-lg border p-3 font-sans">
33+
<div><span className="text-xs text-slate-500 dark:text-slate-400">Email:</span> <span className="font-medium">{appointment.email ?? "Not provided"}</span></div>
34+
<div><span className="text-xs text-slate-500 dark:text-slate-400">Phone:</span> <span className="font-medium">{appointment.phone_number ?? "Not provided"}</span></div>
35+
<div><span className="text-xs text-slate-500 dark:text-slate-400">Company:</span> <span className="font-medium">{appointment.company_name ?? "Not provided"}</span></div>
36+
<div><span className="text-xs text-slate-500 dark:text-slate-400">Industry:</span> <span className="font-medium">{appointment.industry ?? "Not provided"}</span></div>
3837
</div>
3938
</div>
4039

41-
{/* Section 2: Step 2 Short Survey Metrics Insights */}
4240
<div className="flex flex-col gap-2">
43-
<h3 className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Survey Metrics (Step 2)</h3>
44-
<div className="rounded-lg bg-neutral-900/50 border border-neutral-800 p-3 flex flex-col gap-3">
41+
<h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Survey Metrics (Step 2)</h3>
42+
<div className="background-light800_dark400 border-light_dark flex flex-col gap-3 rounded-lg border p-3">
4543
<div>
46-
<div className="text-neutral-500 text-xs">Target Scope Interest:</div>
47-
<div className="text-neutral-200 font-medium mt-0.5">{appointment.services_interested || "Web Development"}</div>
44+
<div className="text-xs text-slate-500 dark:text-slate-400">Inquiry Subject:</div>
45+
<div className="mt-0.5 font-medium">{appointment.service_interest ?? "Not specified"}</div>
4846
</div>
4947
<div>
50-
<div className="text-neutral-500 text-xs">Current Product Infrastructure Status:</div>
51-
<div className="text-neutral-200 font-medium mt-0.5">{appointment.website_status || "New project — no existing site"}</div>
48+
<div className="text-xs text-slate-500 dark:text-slate-400">Project Type:</div>
49+
<div className="mt-0.5 font-medium">{appointment.project_type ?? "Not provided"}</div>
5250
</div>
5351
<div>
54-
<div className="text-neutral-500 text-xs">Requested Features / Functionalities:</div>
55-
<div className="text-neutral-300 text-xs mt-1 bg-neutral-950 p-2 rounded border border-neutral-800 whitespace-pre-wrap">
56-
{appointment.required_features || "e-commerce"}
52+
<div className="text-xs text-slate-500 dark:text-slate-400">Requested Features:</div>
53+
<div className="background-light900_dark300 border-light_dark mt-1 whitespace-pre-wrap rounded border p-2 text-xs">
54+
{appointment.features_needed ?? "Not provided"}
5755
</div>
5856
</div>
59-
<div className="flex justify-between items-center pt-1 border-t border-neutral-800/60">
57+
<div className="table-border-light_dark flex items-center justify-between border-t pt-1">
6058
<div>
61-
<div className="text-neutral-500 text-xs">Referral Channel:</div>
62-
<div className="text-neutral-300 font-medium text-xs mt-0.5">{appointment.referral_source || "Social media"}</div>
59+
<div className="text-xs text-slate-500 dark:text-slate-400">Referral Channel:</div>
60+
<div className="mt-0.5 text-xs font-medium">{appointment.referral_source ?? "Not provided"}</div>
6361
</div>
6462
<div className="text-right">
65-
<div className="text-neutral-500 text-xs mb-0.5">Interest Rating:</div>
66-
<div className="flex gap-0.5 justify-end">
67-
{Array.from({ length: 5 }).map((_, i) => (
68-
<Star
69-
key={i}
70-
className={`w-3.5 h-3.5 ${i < (appointment.interest_rating || 5) ? "fill-purple-500 text-purple-500" : "text-neutral-700"}`}
71-
/>
72-
))}
73-
</div>
63+
<div className="mb-0.5 text-xs text-slate-500 dark:text-slate-400">Interest Rating:</div>
64+
{appointment.interest_level != null ? (
65+
<div className="flex justify-end gap-0.5">
66+
{(() => {
67+
const interestLevel = appointment.interest_level;
68+
return Array.from({ length: 5 }).map((_, i) => (
69+
<Star
70+
key={i}
71+
className={`h-3.5 w-3.5 ${i < interestLevel ? "fill-purple-500 text-purple-500" : "text-slate-300 dark:text-slate-700"}`}
72+
/>
73+
));
74+
})()}
75+
</div>
76+
) : (
77+
<span className="text-xs text-slate-500 dark:text-slate-400">No rating</span>
78+
)}
7479
</div>
7580
</div>
7681
</div>
7782
</div>
7883

79-
{/* Section 3: Step 3 Chosen Schedule Specifications */}
8084
<div className="flex flex-col gap-2">
81-
<h3 className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Meeting Parameters (Step 3)</h3>
82-
<div className="rounded-lg bg-neutral-900/50 border border-neutral-800 p-3 flex flex-col gap-2 bg-gradient-to-r from-purple-950/10 to-transparent">
85+
<h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Meeting Parameters (Step 3)</h3>
86+
<div className="background-light800_dark400 border-light_dark flex flex-col gap-2 rounded-lg border bg-gradient-to-r from-purple-200/20 to-transparent p-3 dark:from-purple-950/10">
8387
<div>
84-
<div className="text-neutral-500 text-xs">Chosen Slot Timestamp:</div>
85-
<div className="text-sm font-semibold text-purple-400 mt-0.5">
88+
<div className="text-xs text-slate-500 dark:text-slate-400">Preferred Meeting Date and Time:</div>
89+
<div className="mt-0.5 text-sm font-semibold text-purple-600 dark:text-purple-400">
8690
{appointment.appointment_date
87-
? format(new Date(appointment.appointment_date), "EEEE, MMMM dd, yyyy 'at' hh:mm a")
88-
: "Not finalized by user dropoff"}
91+
? `${format(new Date(appointment.appointment_date), "EEEE, MMMM dd, yyyy")} at ${appointment.appointment_time ?? "Time not provided"}`
92+
: "Not provided"}
8993
</div>
9094
</div>
9195
<div>
92-
<div className="text-neutral-500 text-xs">Target Communication Room Environment:</div>
93-
<div className="text-neutral-200 font-medium text-xs mt-0.5 capitalize">
94-
Via {appointment.meeting_type || "Zoom"} Connection Link
96+
<div className="text-xs text-slate-500 dark:text-slate-400">Meeting Type:</div>
97+
<div className="mt-0.5 text-xs font-medium capitalize">
98+
{appointment.meeting_type ?? "Not provided"}
9599
</div>
96100
</div>
97101
</div>
98102
</div>
99103

100-
{/* Additional Comments Block */}
101-
{appointment.message && (
104+
{appointment.other_requirements && (
102105
<div className="flex flex-col gap-2">
103-
<h3 className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Additional Comments</h3>
104-
<p className="text-xs text-neutral-400 italic bg-neutral-900/30 p-2.5 rounded-lg border border-neutral-800/40">
105-
"{appointment.message}"
106+
<h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Additional Requirements</h3>
107+
<p className="background-light800_dark400 border-light_dark rounded-lg border p-2.5 text-xs italic text-slate-600 dark:text-slate-300">
108+
"{appointment.other_requirements}"
106109
</p>
107110
</div>
108111
)}

0 commit comments

Comments
 (0)