Refactor appointment detail components to improve meeting join logic

Enhance the appointment detail page for both admin and user interfaces by refining the logic for joining meetings. Update the handling of participant and moderator permissions, ensuring clarity in button displays based on meeting status. Remove the end meeting API endpoint from the API URLs as it is no longer needed.
This commit is contained in:
iamkiddy 2025-12-04 15:56:53 +00:00
parent 74d7a35e60
commit fcb8fe3356
3 changed files with 53 additions and 22 deletions

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="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 hasStarted = startedAt != null && startedAt !== "";
if (!canJoin) {
// If can_join_as_moderator != true, display "Meeting Not Available"
if (!canJoinAsModerator) {
return (
<button
disabled
@ -711,6 +714,7 @@ export default function AppointmentDetailPage() {
);
}
// If can_join_as_moderator == true && started_at != null, show "Join Now" button
if (hasStarted) {
return (
<>
@ -745,6 +749,7 @@ export default function AppointmentDetailPage() {
);
}
// If can_join_as_moderator == true && started_at == null, show "Start Meeting" button
return (
<Button
onClick={handleStartMeeting}

View File

@ -578,7 +578,29 @@ export default function UserAppointmentDetailPage() {
{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="p-6">
{appointment.can_join_as_participant ? (
{(() => {
// Check if can join as participant (handle both boolean and string values)
const canJoinAsParticipant = appointment.can_join_as_participant === true || appointment.can_join_as_participant === "true";
// Check if meeting has started (handle both field names)
const startedAt = appointment.started_at || appointment.meeting_started_at;
const hasStarted = startedAt != null && startedAt !== "";
// If can_join_as_participant != true, display "Meeting Not Available"
if (!canJoinAsParticipant) {
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>
);
}
// If can_join_as_participant == true && started_at != null, show "Join Now" button
if (hasStarted) {
return (
<a
href={appointment.participant_join_url}
target="_blank"
@ -586,17 +608,22 @@ export default function UserAppointmentDetailPage() {
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 Meeting
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 Yet
Meeting Not Available
</button>
)}
);
})()}
</div>
</div>
)}

View File

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