website/lib/models/appointments.ts
iamkiddy f40ced5fb0 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.
2025-12-05 13:03:58 +00:00

187 lines
5.1 KiB
TypeScript

// Appointment Models
export interface Appointment {
id: string;
first_name: string;
last_name: string;
email: string;
phone?: string;
reason?: string;
preferred_dates?: string | string[]; // YYYY-MM-DD format - API can return as string or array
preferred_time_slots?: string | string[]; // "morning", "afternoon", "evening" - API can return as string or array
selected_slots?: SelectedSlot[]; // New format: day-time combinations
status: "pending_review" | "scheduled" | "rejected" | "completed" | "cancelled";
created_at: string;
updated_at: string;
scheduled_datetime?: string;
scheduled_duration?: number;
rejection_reason?: string;
jitsi_meet_url?: string;
jitsi_room_id?: string;
jitsi_meeting_created?: boolean;
meeting_started_at?: string;
started_at?: string; // Alternative field name from API
meeting_ended_at?: string;
meeting_duration_actual?: number;
meeting_info?: any;
has_jitsi_meeting?: boolean | string;
can_join_meeting?: boolean | string;
can_join_as_moderator?: boolean | string;
can_join_as_participant?: boolean | string;
moderator_join_url?: string;
participant_join_url?: string;
meeting_status?: string;
matching_availability?: MatchingAvailability | Array<{
date: string;
day_name: string;
available_slots: string[];
date_obj?: string;
}>;
are_preferences_available?: boolean | string;
// Additional fields from API response
full_name?: string;
formatted_created_at?: string;
formatted_scheduled_datetime?: string;
preferred_dates_display?: string;
preferred_time_slots_display?: string;
meeting_duration_display?: string;
}
export interface SelectedSlot {
day: number; // 0-6 (Monday-Sunday)
date?: string; // YYYY-MM-DD format
time_slot: "morning" | "afternoon" | "evening";
}
export interface AppointmentResponse {
appointment?: Appointment;
message?: string;
[key: string]: any;
}
export interface AppointmentsListResponse {
appointments: Appointment[];
count?: number;
next?: string | null;
previous?: string | null;
}
export interface AvailableDatesResponse {
dates?: string[]; // YYYY-MM-DD format (legacy)
available_days?: number[]; // 0-6 (Monday-Sunday)
available_days_display?: string[];
// New format - array of date objects with time slots
available_dates?: Array<{
date: string; // YYYY-MM-DD
day_name: string;
available_slots: string[];
available_slots_display?: string[];
is_available: boolean;
}>;
}
export interface WeeklyAvailabilityDay {
day: number; // 0-6 (Monday-Sunday)
day_name: string;
available_slots: string[]; // ["morning", "afternoon", "evening"]
available_slots_display?: string[];
is_available: boolean;
}
export type WeeklyAvailabilityResponse = WeeklyAvailabilityDay[] | {
week?: WeeklyAvailabilityDay[];
[key: string]: any; // Allow for different response formats
};
export interface AvailabilityConfig {
days_of_week: Record<string, string>; // {"0": "Monday", ...}
time_slots: Record<string, string>; // {"morning": "Morning (9AM - 12PM)", ...}
}
export interface CheckDateAvailabilityResponse {
date: string;
day_name: string;
available_slots: string[];
available_slots_display?: string[];
is_available: boolean;
}
export interface AvailabilityOverview {
available: boolean;
total_available_slots: number;
available_days: string[];
next_available_dates: Array<{
date: string;
day_name: string;
available_slots: string[];
is_available: boolean;
}>;
}
export interface AdminAvailability {
available_days?: number[]; // 0-6 (Monday-Sunday) (legacy)
available_days_display?: string[];
availability_schedule?: Record<string, string[]>; // {"0": ["morning", "evening"], "1": ["afternoon"]}
availability_schedule_display?: string;
all_available_slots?: SelectedSlot[];
}
export interface MatchingAvailability {
appointment_id: string;
preferences_match_availability: boolean;
matching_slots: Array<{
date: string; // YYYY-MM-DD
time_slot: string;
day: number;
}>;
total_matching_slots: number;
}
export interface AppointmentStats {
total_requests: number;
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 {
total_requests: number;
pending_review: number;
scheduled: number;
rejected: number;
completed: number;
completion_rate: number;
email?: string;
}
export interface JitsiMeetingInfo {
meeting_url: string;
room_id: string;
scheduled_time: string;
duration: string;
can_join: boolean;
meeting_status: string;
join_instructions: string;
}
export interface ApiError {
detail?: string | string[];
message?: string | string[];
error?: string;
preferred_dates?: string[];
preferred_time_slots?: string[];
email?: string[];
first_name?: string[];
last_name?: string[];
[key: string]: string | string[] | undefined;
}