feat/booking-panel #47

Merged
Hammond merged 2 commits from feat/booking-panel into master 2025-12-04 15:58:53 +00:00
3 changed files with 53 additions and 22 deletions
Showing only changes of commit fcb8fe3356 - Show all commits

View File

@ -695,11 +695,14 @@ export default function AppointmentDetailPage() {
<div className={`rounded-2xl border shadow-sm overflow-hidden ${isDark ? "bg-gradient-to-br from-blue-900/20 to-purple-900/20 border-blue-800/30" : "bg-gradient-to-br from-blue-50 to-purple-50 border-blue-200"}`}> <div className={`rounded-2xl border shadow-sm overflow-hidden ${isDark ? "bg-gradient-to-br from-blue-900/20 to-purple-900/20 border-blue-800/30" : "bg-gradient-to-br from-blue-50 to-purple-50 border-blue-200"}`}>
<div className="p-6 space-y-3"> <div className="p-6 space-y-3">
{(() => { {(() => {
const canJoin = appointment.can_join_as_moderator === true || appointment.can_join_as_moderator === "true"; // Check if can join as moderator (handle both boolean and string values)
const canJoinAsModerator = appointment.can_join_as_moderator === true || appointment.can_join_as_moderator === "true";
// Check if meeting has started (handle both field names)
const startedAt = appointment.started_at || appointment.meeting_started_at; const startedAt = appointment.started_at || appointment.meeting_started_at;
const hasStarted = startedAt != null && startedAt !== ""; const hasStarted = startedAt != null && startedAt !== "";
if (!canJoin) { // If can_join_as_moderator != true, display "Meeting Not Available"
if (!canJoinAsModerator) {
return ( return (
<button <button
disabled disabled
@ -711,6 +714,7 @@ export default function AppointmentDetailPage() {
); );
} }
// If can_join_as_moderator == true && started_at != null, show "Join Now" button
if (hasStarted) { if (hasStarted) {
return ( return (
<> <>
@ -745,6 +749,7 @@ export default function AppointmentDetailPage() {
); );
} }
// If can_join_as_moderator == true && started_at == null, show "Start Meeting" button
return ( return (
<Button <Button
onClick={handleStartMeeting} onClick={handleStartMeeting}

View File

@ -578,25 +578,52 @@ export default function UserAppointmentDetailPage() {
{appointment.status === "scheduled" && appointment.participant_join_url && ( {appointment.status === "scheduled" && appointment.participant_join_url && (
<div className={`rounded-2xl border shadow-sm overflow-hidden ${isDark ? "bg-gradient-to-br from-blue-900/20 to-purple-900/20 border-blue-800/30" : "bg-gradient-to-br from-blue-50 to-purple-50 border-blue-200"}`}> <div className={`rounded-2xl border shadow-sm overflow-hidden ${isDark ? "bg-gradient-to-br from-blue-900/20 to-purple-900/20 border-blue-800/30" : "bg-gradient-to-br from-blue-50 to-purple-50 border-blue-200"}`}>
<div className="p-6"> <div className="p-6">
{appointment.can_join_as_participant ? ( {(() => {
<a // Check if can join as participant (handle both boolean and string values)
href={appointment.participant_join_url} const canJoinAsParticipant = appointment.can_join_as_participant === true || appointment.can_join_as_participant === "true";
target="_blank" // Check if meeting has started (handle both field names)
rel="noopener noreferrer" const startedAt = appointment.started_at || appointment.meeting_started_at;
className={`flex items-center justify-center gap-2 w-full bg-blue-600 hover:bg-blue-700 text-white h-12 rounded-lg text-base font-medium transition-colors`} const hasStarted = startedAt != null && startedAt !== "";
>
<Video className="w-5 h-5" /> // If can_join_as_participant != true, display "Meeting Not Available"
Join Meeting if (!canJoinAsParticipant) {
</a> return (
) : ( <button
<button disabled
disabled className={`flex items-center justify-center gap-2 w-full cursor-not-allowed h-12 rounded-lg text-base font-medium transition-colors ${isDark ? "bg-gray-700 text-gray-500" : "bg-gray-300 text-gray-500"}`}
className={`flex items-center justify-center gap-2 w-full cursor-not-allowed h-12 rounded-lg text-base font-medium transition-colors ${isDark ? "bg-gray-700 text-gray-500" : "bg-gray-300 text-gray-500"}`} >
> <Video className="w-5 h-5" />
<Video className="w-5 h-5" /> Meeting Not Available
Meeting Not Available Yet </button>
</button> );
)} }
// If can_join_as_participant == true && started_at != null, show "Join Now" button
if (hasStarted) {
return (
<a
href={appointment.participant_join_url}
target="_blank"
rel="noopener noreferrer"
className={`flex items-center justify-center gap-2 w-full bg-blue-600 hover:bg-blue-700 text-white h-12 rounded-lg text-base font-medium transition-colors`}
>
<Video className="w-5 h-5" />
Join Now
</a>
);
}
// If can_join_as_participant == true && started_at == null, show "Meeting Not Available"
return (
<button
disabled
className={`flex items-center justify-center gap-2 w-full cursor-not-allowed h-12 rounded-lg text-base font-medium transition-colors ${isDark ? "bg-gray-700 text-gray-500" : "bg-gray-300 text-gray-500"}`}
>
<Video className="w-5 h-5" />
Meeting Not Available
</button>
);
})()}
</div> </div>
</div> </div>
)} )}

View File

@ -30,7 +30,6 @@ export const API_ENDPOINTS = {
checkDateAvailability: `${API_BASE_URL}/meetings/availability/check/`, checkDateAvailability: `${API_BASE_URL}/meetings/availability/check/`,
availabilityOverview: `${API_BASE_URL}/meetings/availability/overview/`, availabilityOverview: `${API_BASE_URL}/meetings/availability/overview/`,
startMeeting: (id: string) => `${API_BASE_URL}/meetings/appointments/${id}/start/`, startMeeting: (id: string) => `${API_BASE_URL}/meetings/appointments/${id}/start/`,
endMeeting: (id: string) => `${API_BASE_URL}/meetings/appointments/${id}/end/`,
}, },
} as const; } as const;