From f40ced5fb00f9991a451474038e4abf1435e29ac Mon Sep 17 00:00:00 2001 From: iamkiddy Date: Fri, 5 Dec 2025 13:03:58 +0000 Subject: [PATCH] Add meeting status indication to appointment detail pages and dashboard stats - Implemented logic to display a "Meeting has ended" button on both admin and user appointment detail pages when the meeting has concluded. - Updated the dashboard to include a new statistic for active upcoming meetings, enhancing the overview of current appointments. - Adjusted appointment stats model to accommodate the new active upcoming meetings metric, ensuring accurate data representation. --- app/(admin)/admin/booking/[id]/page.tsx | 17 +++++++++++++++ app/(admin)/admin/dashboard/page.tsx | 24 ++++++++++++++++------ app/(user)/user/appointments/[id]/page.tsx | 17 +++++++++++++++ lib/models/appointments.ts | 6 ++++++ 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/app/(admin)/admin/booking/[id]/page.tsx b/app/(admin)/admin/booking/[id]/page.tsx index ee74de5..8f1023a 100644 --- a/app/(admin)/admin/booking/[id]/page.tsx +++ b/app/(admin)/admin/booking/[id]/page.tsx @@ -697,6 +697,23 @@ export default function AppointmentDetailPage() {
{(() => { + // Check if meeting has ended + const endedAt = appointment.meeting_ended_at; + const hasEnded = endedAt != null && endedAt !== ""; + + // If meeting has ended, show "Meeting has ended" + if (hasEnded) { + return ( + + ); + } + // 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) diff --git a/app/(admin)/admin/dashboard/page.tsx b/app/(admin)/admin/dashboard/page.tsx index f32965d..29a1ff5 100644 --- a/app/(admin)/admin/dashboard/page.tsx +++ b/app/(admin)/admin/dashboard/page.tsx @@ -36,6 +36,7 @@ interface DashboardStats { upcoming_bookings: number; completed_bookings: number; cancelled_bookings: number; + active_upcoming_meetings: number; total_revenue: number; monthly_revenue: number; trends: { @@ -78,10 +79,12 @@ export default function Dashboard() { const totalBookings = appointmentStats?.total_requests || appointments.length; const upcomingBookings = appointmentStats?.scheduled || appointments.filter((apt) => apt.status === "scheduled").length; - // Completed bookings - not in API status types, so set to 0 - const completedBookings = 0; + // Completed bookings from API stats + const completedBookings = appointmentStats?.completed || + appointments.filter((apt) => apt.status === "completed").length; const cancelledBookings = appointmentStats?.rejected || appointments.filter((apt) => apt.status === "rejected").length; + const activeUpcomingMeetings = appointmentStats?.active_upcoming_meetings || 0; // Calculate revenue (assuming appointments have amount field, defaulting to 0) const now = new Date(); @@ -127,6 +130,7 @@ export default function Dashboard() { upcoming_bookings: upcomingBookings, completed_bookings: completedBookings, cancelled_bookings: cancelledBookings, + active_upcoming_meetings: activeUpcomingMeetings, total_revenue: totalRevenue, monthly_revenue: monthlyRevenue, trends, @@ -139,10 +143,11 @@ export default function Dashboard() { active_users: 0, total_bookings: 0, upcoming_bookings: 0, - completed_bookings: 0, - cancelled_bookings: 0, - total_revenue: 0, - monthly_revenue: 0, + completed_bookings: 0, + cancelled_bookings: 0, + active_upcoming_meetings: 0, + total_revenue: 0, + monthly_revenue: 0, trends: { total_users: "0%", active_users: "0%", @@ -205,6 +210,13 @@ export default function Dashboard() { trend: stats?.trends.cancelled_bookings ?? "0%", trendUp: false, }, + { + title: "Active Upcoming Meetings", + value: stats?.active_upcoming_meetings ?? 0, + icon: CalendarCheck, + trend: "0", + trendUp: true, + }, ]; diff --git a/app/(user)/user/appointments/[id]/page.tsx b/app/(user)/user/appointments/[id]/page.tsx index 56a64b2..af204a4 100644 --- a/app/(user)/user/appointments/[id]/page.tsx +++ b/app/(user)/user/appointments/[id]/page.tsx @@ -545,6 +545,23 @@ export default function UserAppointmentDetailPage() {
{(() => { + // Check if meeting has ended + const endedAt = appointment.meeting_ended_at; + const hasEnded = endedAt != null && endedAt !== ""; + + // If meeting has ended, show "Meeting has ended" + if (hasEnded) { + return ( + + ); + } + // 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) diff --git a/lib/models/appointments.ts b/lib/models/appointments.ts index 43830d7..e77d39a 100644 --- a/lib/models/appointments.ts +++ b/lib/models/appointments.ts @@ -142,8 +142,14 @@ export interface AppointmentStats { pending_review: number; scheduled: number; rejected: number; + completed: number; completion_rate: number; users?: number; // Total users count from API + active_upcoming_meetings?: number; + availability_coverage?: number; + available_days_count?: number; + jitsi_meetings_created?: number; + meetings_with_video?: number; } export interface UserAppointmentStats {