- Introduced new percentage fields in the AppointmentStats and UserAppointmentStats interfaces. - Updated the admin and user dashboard components to include and display percentage metrics for scheduled, completed, pending review, and rejected appointments. - Removed commented-out percentage badges and implemented conditional rendering for displaying percentage values, enhancing the clarity of the dashboard statistics.
199 lines
5.4 KiB
TypeScript
199 lines
5.4 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;
|
|
pending_review_pct?: number;
|
|
scheduled: number;
|
|
scheduled_pct?: number;
|
|
rejected: number;
|
|
rejected_pct?: number;
|
|
completed: number;
|
|
completed_pct?: number;
|
|
completion_rate: number;
|
|
users?: number; // Total users count from API
|
|
users_pct?: number;
|
|
active_upcoming_meetings?: number;
|
|
availability_coverage?: number;
|
|
availability_coverage_pct?: number;
|
|
available_days_count?: number;
|
|
jitsi_meetings_created?: number;
|
|
meetings_with_video?: number;
|
|
meetings_with_video_pct?: number;
|
|
video_meetings?: number;
|
|
}
|
|
|
|
export interface UserAppointmentStats {
|
|
total_requests: number;
|
|
pending_review: number;
|
|
pending_review_pct?: number;
|
|
scheduled: number;
|
|
scheduled_pct?: number;
|
|
rejected: number;
|
|
rejected_pct?: number;
|
|
completed: number;
|
|
completed_pct?: 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;
|
|
}
|
|
|