CoolFace
Apppublic

Jacksonnavigator7/Hospital_Queue_Management_System

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py891 linesDownload Raw Back to root
1import sqlite32import gradio as gr3import pandas as pd4import time5from datetime import datetime, timedelta6import random7import string8import os9 10# ---------------------------11# DATABASE SETUP12# ---------------------------13def get_db_connection():14    """Create a database connection with proper error handling"""15    try:16        conn = sqlite3.connect("hospital.db", check_same_thread=False)17        conn.row_factory = sqlite3.Row  # Return rows as dictionaries18        return conn19    except sqlite3.Error as e:20        print(f"Database connection error: {e}")21        return None22 23conn = get_db_connection()24cursor = conn.cursor()25 26# Create tables with improved schema27cursor.execute('''CREATE TABLE IF NOT EXISTS doctors (28    id INTEGER PRIMARY KEY AUTOINCREMENT,29    name TEXT NOT NULL,30    specialty TEXT,31    avg_consultation_time INTEGER DEFAULT 15,  -- in minutes32    available BOOLEAN DEFAULT 133)''')34 35cursor.execute('''CREATE TABLE IF NOT EXISTS patients (36    id INTEGER PRIMARY KEY AUTOINCREMENT,37    name TEXT NOT NULL,38    phone TEXT NOT NULL,39    email TEXT,40    symptoms TEXT,41    priority INTEGER DEFAULT 3,  -- 1=emergency, 2=urgent, 3=normal42    doctor_id INTEGER,43    queue_number INTEGER,44    token TEXT UNIQUE,45    registration_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,46    estimated_start_time TIMESTAMP,47    status TEXT DEFAULT 'Waiting',48    completed_time TIMESTAMP,49    notes TEXT,50    FOREIGN KEY (doctor_id) REFERENCES doctors(id)51)''')52 53cursor.execute('''CREATE TABLE IF NOT EXISTS appointments (54    id INTEGER PRIMARY KEY AUTOINCREMENT,55    patient_name TEXT NOT NULL,56    phone TEXT NOT NULL,57    email TEXT,58    doctor_id INTEGER,59    appointment_date TEXT,60    appointment_time TEXT,61    reason TEXT,62    status TEXT DEFAULT 'Scheduled',63    FOREIGN KEY (doctor_id) REFERENCES doctors(id)64)''')65 66cursor.execute('''CREATE TABLE IF NOT EXISTS notifications (67    id INTEGER PRIMARY KEY AUTOINCREMENT,68    patient_id INTEGER,69    message TEXT,70    sent_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,71    FOREIGN KEY (patient_id) REFERENCES patients(id)72)''')73 74conn.commit()75 76# Seed doctors if table is empty77cursor.execute("SELECT COUNT(*) FROM doctors")78if cursor.fetchone()[0] == 0:79    doctors = [80        ("Dr. Smith", "General Medicine", 15, 1),81        ("Dr. Lee", "Pediatrics", 20, 1),82        ("Dr. Patel", "Cardiology", 25, 1),83        ("Dr. Johnson", "Orthopedics", 20, 1),84        ("Dr. Garcia", "Dermatology", 15, 1)85    ]86    cursor.executemany("INSERT INTO doctors (name, specialty, avg_consultation_time, available) VALUES (?, ?, ?, ?)", doctors)87    conn.commit()88 89# ---------------------------90# HELPER FUNCTIONS91# ---------------------------92def generate_token():93    """Generate a unique alphanumeric token for patients"""94    token = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))95    return token96 97def calculate_wait_time(doctor_id, queue_position):98    """Calculate estimated wait time based on doctor's avg consultation time and queue position"""99    cursor.execute("SELECT avg_consultation_time FROM doctors WHERE id=?", (doctor_id,))100    avg_time = cursor.fetchone()[0]101    102    # Count how many patients are currently in consultation (usually just 1)103    cursor.execute("SELECT COUNT(*) FROM patients WHERE doctor_id=? AND status='In Consultation'", (doctor_id,))104    in_consultation = cursor.fetchone()[0]105    106    # Calculate wait time: (patients ahead + in consultation) * avg time107    wait_minutes = (queue_position - 1 + in_consultation) * avg_time108    109    # Add some randomness to make it realistic (ยฑ20%)110    variation = random.uniform(0.8, 1.2)111    wait_minutes = int(wait_minutes * variation)112    113    return wait_minutes114 115def format_wait_time(minutes):116    """Format wait time into hours and minutes"""117    if minutes < 60:118        return f"{minutes} minutes"119    hours = minutes // 60120    mins = minutes % 60121    return f"{hours} hour{'s' if hours > 1 else ''} {mins} minutes"122 123def update_all_wait_times():124    """Update estimated wait times for all waiting patients"""125    # Get all waiting patients126    cursor.execute("""127        SELECT p.id, p.doctor_id, p.queue_number 128        FROM patients p 129        WHERE p.status='Waiting' 130        ORDER BY p.doctor_id, p.queue_number131    """)132    waiting_patients = cursor.fetchall()133    134    # Group by doctor135    for doctor_id in set([p[1] for p in waiting_patients]):136        # Get all patients for this doctor137        doctor_patients = [p for p in waiting_patients if p[1] == doctor_id]138        139        # Update wait time for each patient140        for patient in doctor_patients:141            wait_minutes = calculate_wait_time(doctor_id, patient[2])142            estimated_time = datetime.now() + timedelta(minutes=wait_minutes)143            cursor.execute(144                "UPDATE patients SET estimated_start_time=? WHERE id=?", 145                (estimated_time.strftime('%Y-%m-%d %H:%M:%S'), patient[0])146            )147    148    conn.commit()149 150# ---------------------------151# CORE FUNCTIONS152# ---------------------------153def register_patient(name, phone, email, symptoms, priority, doctor_name):154    """Register a new patient with improved data validation and wait time estimation"""155    # Input validation156    if not name or not phone or not doctor_name:157        return "Error: Name, phone number, and doctor selection are required."158    159    try:160        # Get doctor details161        cursor.execute("SELECT id, available FROM doctors WHERE name=?", (doctor_name,))162        doctor_result = cursor.fetchone()163        164        if not doctor_result:165            return f"Error: Doctor {doctor_name} not found."166        167        doctor_id, is_available = doctor_result168        169        if not is_available:170            return f"Sorry, {doctor_name} is currently not available. Please select another doctor."171        172        # Check if patient with same phone is already in queue173        cursor.execute("SELECT id FROM patients WHERE phone=? AND status IN ('Waiting', 'In Consultation')", (phone,))174        if cursor.fetchone():175            return "This phone number is already registered in the active queue."176        177        # Get next queue number178        cursor.execute("SELECT MAX(queue_number) FROM patients WHERE doctor_id=?", (doctor_id,))179        last_queue = cursor.fetchone()[0]180        next_queue = 1 if last_queue is None else last_queue + 1181        182        # Generate unique token183        token = generate_token()184        while True:185            # Check if token already exists186            cursor.execute("SELECT id FROM patients WHERE token=?", (token,))187            if not cursor.fetchone():188                break189            token = generate_token()  # Generate new token if exists190            191        # Calculate estimated wait time192        wait_minutes = calculate_wait_time(doctor_id, next_queue)193        estimated_time = datetime.now() + timedelta(minutes=wait_minutes)194        195        # Insert patient196        cursor.execute("""197            INSERT INTO patients 198            (name, phone, email, symptoms, priority, doctor_id, queue_number, token, estimated_start_time, status) 199            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)200        """, (name, phone, email, symptoms, priority, doctor_id, next_queue, token, 201              estimated_time.strftime('%Y-%m-%d %H:%M:%S'), 'Waiting'))202        conn.commit()203        204        # Get patient ID for notification205        patient_id = cursor.lastrowid206        207        # Add welcome notification208        notification_msg = f"Welcome {name}! You are registered with {doctor_name}. Your token is {token} and queue number is {next_queue}."209        cursor.execute("INSERT INTO notifications (patient_id, message) VALUES (?, ?)", 210                      (patient_id, notification_msg))211        conn.commit()212        213        # Update wait times for all patients214        update_all_wait_times()215        216        # Format response217        wait_time_str = format_wait_time(wait_minutes)218        return f"Registered successfully!\n\nYour token: {token}\nQueue number: {next_queue}\nDoctor: {doctor_name}\nEstimated wait time: {wait_time_str}"219        220    except Exception as e:221        conn.rollback()222        return f"An error occurred: {str(e)}"223 224def check_status(phone_or_token):225    """Check patient status by phone or token"""226    if not phone_or_token:227        return "Please enter a phone number or token."228        229    try:230        # Try to find by token first (more specific)231        cursor.execute("""232            SELECT 233                p.id, p.name, p.token, p.queue_number, p.status, p.estimated_start_time,234                d.name as doctor_name, d.specialty235            FROM patients p 236            JOIN doctors d ON p.doctor_id = d.id 237            WHERE p.token=? AND p.status IN ('Waiting', 'In Consultation')238            LIMIT 1239        """, (phone_or_token,))240        241        result = cursor.fetchone()242        243        # If not found by token, try phone244        if not result:245            cursor.execute("""246                SELECT 247                    p.id, p.name, p.token, p.queue_number, p.status, p.estimated_start_time,248                    d.name as doctor_name, d.specialty249                FROM patients p 250                JOIN doctors d ON p.doctor_id = d.id 251                WHERE p.phone=? AND p.status IN ('Waiting', 'In Consultation')252                ORDER BY p.id DESC LIMIT 1253            """, (phone_or_token,))254            result = cursor.fetchone()255        256        if not result:257            return "No active registration found. If you've already completed your visit or haven't registered yet, please check with reception."258        259        # Format estimated time260        estimated_time = datetime.strptime(result[5], '%Y-%m-%d %H:%M:%S') if result[5] else None261        now = datetime.now()262        263        if estimated_time and estimated_time > now:264            time_diff = estimated_time - now265            wait_minutes = int(time_diff.total_seconds() / 60)266            wait_str = format_wait_time(wait_minutes)267        else:268            wait_str = "You should be called soon"269        270        status_info = f"""271        Patient: {result[1]}272        Token: {result[2]}273        Queue #: {result[3]}274        Status: {result[4]}275        Doctor: {result[6]} ({result[7]})276        """277        278        if result[4] == 'Waiting':279            status_info += f"Estimated wait: {wait_str}"280            281        # Get any notifications282        cursor.execute("""283            SELECT message FROM notifications 284            WHERE patient_id=? 285            ORDER BY sent_time DESC LIMIT 1286        """, (result[0],))287        288        notification = cursor.fetchone()289        if notification:290            status_info += f"\n\nNotification: {notification[0]}"291            292        return status_info293        294    except Exception as e:295        return f"Error checking status: {str(e)}"296 297def get_doctor_queue(doctor_name):298    """Get current queue for a specific doctor"""299    try:300        cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))301        doctor_id = cursor.fetchone()[0]302        303        cursor.execute("""304            SELECT 305                id, name, queue_number, priority, 306                strftime('%H:%M', registration_time) as reg_time, 307                status, phone, token 308            FROM patients 309            WHERE doctor_id=? AND status IN ('Waiting', 'In Consultation')310            ORDER BY 311                CASE status 312                    WHEN 'In Consultation' THEN 0 313                    ELSE 1 314                END,315                priority, queue_number316        """, (doctor_id,))317        318        rows = cursor.fetchall()319        320        # Convert to list of lists for gradio dataframe321        result = []322        for row in rows:323            # Format priority as text324            priority_text = {1: "Emergency", 2: "Urgent", 3: "Normal"}.get(row[3], "Normal")325            326            result.append([row[0], row[1], row[2], priority_text, row[4], row[5], row[6], row[7]])327            328        return result329        330    except Exception as e:331        print(f"Error getting doctor queue: {e}")332        return []333 334def get_doctor_availability():335    """Get the list of available doctors with their specialties"""336    cursor.execute("""337        SELECT id, name, specialty, available 338        FROM doctors 339        ORDER BY name340    """)341    doctors = cursor.fetchall()342    343    # Format for display344    result = []345    for doc in doctors:346        status = "Available" if doc[3] else "Unavailable"347        result.append([doc[0], doc[1], doc[2], status])348    349    return result350 351def toggle_doctor_availability(doctor_id):352    """Toggle a doctor's availability status"""353    try:354        if not doctor_id:355            return "Please select a doctor."356            357        cursor.execute("SELECT available FROM doctors WHERE id=?", (doctor_id,))358        current_status = cursor.fetchone()[0]359        360        # Toggle status361        new_status = 0 if current_status else 1362        cursor.execute("UPDATE doctors SET available=? WHERE id=?", (new_status, doctor_id))363        conn.commit()364        365        status_text = "available" if new_status else "unavailable"366        return f"Doctor status updated to {status_text}"367        368    except Exception as e:369        conn.rollback()370        return f"Error updating status: {str(e)}"371 372def call_next(doctor_name):373    """Call the next patient in queue with notifications"""374    try:375        cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))376        doctor_id = cursor.fetchone()[0]377        378        # First check if any patient is currently in consultation379        cursor.execute("""380            SELECT id, name 381            FROM patients 382            WHERE doctor_id=? AND status='In Consultation'383            LIMIT 1384        """, (doctor_id,))385        current_patient = cursor.fetchone()386        387        if current_patient:388            return f"{current_patient[1]} is currently in consultation. Please complete their visit before calling the next patient."389        390        # Find next patient based on priority and queue number391        cursor.execute("""392            SELECT id, name, token, queue_number, phone 393            FROM patients 394            WHERE doctor_id=? AND status='Waiting' 395            ORDER BY priority, queue_number ASC 396            LIMIT 1397        """, (doctor_id,))398        399        patient = cursor.fetchone()400        401        if not patient:402            return "No patients waiting."403        404        # Update patient status405        cursor.execute("UPDATE patients SET status='In Consultation' WHERE id=?", (patient[0],))406        407        # Create notification408        notification_msg = f"It's your turn! Please proceed to {doctor_name}'s room immediately."409        cursor.execute("INSERT INTO notifications (patient_id, message) VALUES (?, ?)", 410                      (patient[0], notification_msg))411        412        conn.commit()413        414        # Update wait times for all remaining patients415        update_all_wait_times()416        417        # Return formatted message418        return f"Now calling: {patient[1]} (Token: {patient[2]}, Queue #: {patient[3]})"419        420    except Exception as e:421        conn.rollback()422        return f"Error calling next patient: {str(e)}"423 424def complete_patient(patient_id, notes=""):425    """Mark patient consultation as completed with optional notes"""426    try:427        if not patient_id:428            return "Please select a patient to mark as completed."429            430        # Update patient status and add completion time431        cursor.execute(432            "UPDATE patients SET status='Completed', completed_time=?, notes=? WHERE id=?", 433            (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), notes, patient_id)434        )435        436        # Get patient info for confirmation437        cursor.execute("SELECT name, token FROM patients WHERE id=?", (patient_id,))438        patient = cursor.fetchone()439        440        conn.commit()441        442        # Update wait times for all remaining patients443        update_all_wait_times()444        445        return f"Patient {patient[0]} (Token: {patient[1]}) marked as completed."446        447    except Exception as e:448        conn.rollback()449        return f"Error completing patient visit: {str(e)}"450 451def schedule_appointment(name, phone, email, doctor_name, date, time, reason):452    """Schedule a future appointment"""453    try:454        # Validate inputs455        if not name or not phone or not doctor_name or not date or not time:456            return "Error: Name, phone, doctor, date and time are required fields."457            458        # Get doctor ID459        cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))460        doctor_result = cursor.fetchone()461        462        if not doctor_result:463            return f"Error: Doctor {doctor_name} not found."464            465        doctor_id = doctor_result[0]466        467        # Check if time slot is available468        cursor.execute("""469            SELECT COUNT(*) FROM appointments 470            WHERE doctor_id=? AND appointment_date=? AND appointment_time=? AND status='Scheduled'471        """, (doctor_id, date, time))472        473        if cursor.fetchone()[0] > 0:474            return f"Sorry, {doctor_name} is already booked at {time} on {date}. Please select another time."475            476        # Insert appointment477        cursor.execute("""478            INSERT INTO appointments479            (patient_name, phone, email, doctor_id, appointment_date, appointment_time, reason, status)480            VALUES (?, ?, ?, ?, ?, ?, ?, 'Scheduled')481        """, (name, phone, email, doctor_id, date, time, reason))482        483        conn.commit()484        485        return f"Appointment scheduled successfully for {name} with {doctor_name} on {date} at {time}."486        487    except Exception as e:488        conn.rollback()489        return f"Error scheduling appointment: {str(e)}"490 491def get_appointments(date=None, doctor_name=None):492    """Get list of appointments by date and/or doctor"""493    try:494        query = """495            SELECT 496                a.id, a.patient_name, a.phone, a.appointment_time, 497                d.name as doctor_name, a.reason, a.status498            FROM appointments a499            JOIN doctors d ON a.doctor_id = d.id500            WHERE 1=1501        """502        params = []503        504        if date:505            query += " AND a.appointment_date = ?"506            params.append(date)507            508        if doctor_name and doctor_name != "All Doctors":509            query += " AND d.name = ?"510            params.append(doctor_name)511            512        query += " ORDER BY a.appointment_time"513        514        cursor.execute(query, params)515        appointments = cursor.fetchall()516        517        # Format for display518        result = []519        for appt in appointments:520            result.append([appt[0], appt[1], appt[2], appt[3], appt[4], appt[5], appt[6]])521            522        return result523        524    except Exception as e:525        print(f"Error getting appointments: {e}")526        return []527 528def get_daily_stats():529    """Get daily statistics for the dashboard"""530    try:531        today = datetime.now().strftime('%Y-%m-%d')532        533        # Total patients today534        cursor.execute("""535            SELECT COUNT(*) FROM patients 536            WHERE date(registration_time) = ?537        """, (today,))538        total_patients = cursor.fetchone()[0]539        540        # Waiting patients541        cursor.execute("SELECT COUNT(*) FROM patients WHERE status='Waiting'")542        waiting_patients = cursor.fetchone()[0]543        544        # In consultation545        cursor.execute("SELECT COUNT(*) FROM patients WHERE status='In Consultation'")546        in_consultation = cursor.fetchone()[0]547        548        # Completed today549        cursor.execute("""550            SELECT COUNT(*) FROM patients 551            WHERE status='Completed' AND date(completed_time) = ?552        """, (today,))553        completed_today = cursor.fetchone()[0]554        555        # Average wait time today556        cursor.execute("""557            SELECT AVG(558                (julianday(completed_time) - julianday(registration_time)) * 24 * 60559            ) FROM patients 560            WHERE status='Completed' AND date(completed_time) = ?561        """, (today,))562        avg_wait_time = cursor.fetchone()[0]563        avg_wait_formatted = f"{int(avg_wait_time)} minutes" if avg_wait_time else "N/A"564        565        return {566            "total_patients": total_patients,567            "waiting": waiting_patients,568            "in_consultation": in_consultation,569            "completed": completed_today,570            "avg_wait_time": avg_wait_formatted571        }572        573    except Exception as e:574        print(f"Error getting stats: {e}")575        return {576            "total_patients": 0,577            "waiting": 0,578            "in_consultation": 0,579            "completed": 0,580            "avg_wait_time": "N/A"581        }582 583# ---------------------------584# GRADIO INTERFACE585# ---------------------------586def get_doctor_names():587    """Get list of available doctor names"""588    cursor.execute("SELECT name FROM doctors WHERE available=1 ORDER BY name")589    doctors = [row[0] for row in cursor.fetchall()]590    return doctors591 592def get_all_doctor_names():593    """Get list of all doctor names regardless of availability"""594    cursor.execute("SELECT name FROM doctors ORDER BY name")595    doctors = [row[0] for row in cursor.fetchall()]596    return doctors597 598# Create the Gradio interface with theme and improved UI599theme = gr.themes.Soft(600    primary_hue="blue",601    secondary_hue="indigo",602)603 604with gr.Blocks(theme=theme, title="Hospital Queue Management System") as demo:605    gr.Markdown("# ๐Ÿฅ Hospital Queue Management System")606    607    # Dashboard Tab608    with gr.Tab("๐Ÿ“Š Dashboard"):609        gr.Markdown("### Today's Statistics")610        611        with gr.Row():612            total_count = gr.Textbox(label="Total Patients Today")613            waiting_count = gr.Textbox(label="Currently Waiting")614            consulting_count = gr.Textbox(label="In Consultation")615            completed_count = gr.Textbox(label="Completed Today")616            avg_wait = gr.Textbox(label="Average Wait Time")617            618        refresh_stats_btn = gr.Button("Refresh Statistics")619        620        def update_dashboard():621            stats = get_daily_stats()622            return [623                stats["total_patients"],624                stats["waiting"],625                stats["in_consultation"],626                stats["completed"],627                stats["avg_wait_time"]628            ]629            630        refresh_stats_btn.click(631            fn=update_dashboard, 632            inputs=[], 633            outputs=[total_count, waiting_count, consulting_count, completed_count, avg_wait]634        )635        636        # Initialize dashboard637        demo.load(638            fn=update_dashboard, 639            inputs=[], 640            outputs=[total_count, waiting_count, consulting_count, completed_count, avg_wait]641        )642    643    # Patient Registration Tab644    with gr.Tab("โž• Register Patient"):645        gr.Markdown("### New Patient Registration")646        647        with gr.Row():648            name = gr.Textbox(label="Patient Name*", placeholder="Enter full name")649            phone = gr.Textbox(label="Phone Number*", placeholder="Enter phone number")650            651        with gr.Row():652            email = gr.Textbox(label="Email (Optional)", placeholder="Enter email address")653            priority = gr.Dropdown(654                choices=[655                    {"label": "Normal", "value": 3},656                    {"label": "Urgent", "value": 2},657                    {"label": "Emergency", "value": 1}658                ],659                label="Priority",660                value=3661            )662            663        symptoms = gr.Textbox(664            label="Symptoms/Reason for Visit",665            placeholder="Briefly describe the symptoms or reason for visit",666            lines=3667        )668        669        # Fixed dropdown: Use the actual list rather than the function670        doctor = gr.Dropdown(671            choices=get_doctor_names(),  # Call the function to get its return value672            label="Select Doctor*",673            info="Only shows available doctors"674        )675        676        register_btn = gr.Button("Register Patient", variant="primary")677        register_output = gr.Textbox(label="Registration Details", lines=6)678        679        register_btn.click(680            fn=register_patient, 681            inputs=[name, phone, email, symptoms, priority, doctor], 682            outputs=register_output683        )684 685    # Status Check Tab686    with gr.Tab("๐Ÿ” Check My Status"):687        gr.Markdown("### Patient Status Lookup")688        689        phone_lookup = gr.Textbox(690            label="Enter Your Phone Number or Token", 691            placeholder="Enter phone number or 6-digit token",692            info="You can use either your phone number or token to check your status"693        )694        695        check_btn = gr.Button("Check Status", variant="primary")696        status_output = gr.Textbox(label="Your Status", lines=8)697        698        check_btn.click(fn=check_status, inputs=phone_lookup, outputs=status_output)699 700    # Doctor Panel Tab701    with gr.Tab("๐Ÿฉบ Doctor Panel"):702        gr.Markdown("### Manage Patient Queue")703        704        with gr.Row():705            # Fixed dropdown: Use the actual list rather than the function706            doc_select = gr.Dropdown(707                choices=get_all_doctor_names(),  # Call the function to get its return value708                label="Select Doctor",709                info="Select doctor to view their queue"710            )711            712            with gr.Column():713                call_btn = gr.Button("Call Next Patient", variant="primary")714                call_output = gr.Textbox(label="Now Calling", lines=2)715        716        queue_table = gr.Dataframe(717            headers=["ID", "Name", "Queue #", "Priority", "Reg. Time", "Status", "Phone", "Token"],718            datatype=["number", "str", "number", "str", "str", "str", "str", "str"],719            interactive=False,720            label="Current Queue"721        )722        723        with gr.Row():724            selected_patient_id = gr.Number(label="Patient ID", precision=0)725            patient_notes = gr.Textbox(label="Consultation Notes", lines=2)726            complete_btn = gr.Button("Complete Visit")727            complete_output = gr.Textbox(label="Result")728            729        refresh_btn = gr.Button("Refresh Queue")730 731        # Set up event handlers732        call_btn.click(fn=call_next, inputs=doc_select, outputs=call_output)733        734        complete_btn.click(735            fn=complete_patient, 736            inputs=[selected_patient_id, patient_notes], 737            outputs=complete_output738        )739        740        refresh_btn.click(741            fn=lambda d: get_doctor_queue(d), 742            inputs=doc_select, 743            outputs=queue_table744        )745        746        # Update queue when doctor selection changes747        doc_select.change(748            fn=lambda d: get_doctor_queue(d), 749            inputs=doc_select, 750            outputs=queue_table751        )752        753    # Appointment Scheduling Tab754    with gr.Tab("๐Ÿ“… Schedule Appointment"):755        gr.Markdown("### Schedule a Future Appointment")756        757        with gr.Row():758            appt_name = gr.Textbox(label="Patient Name*", placeholder="Enter full name")759            appt_phone = gr.Textbox(label="Phone Number*", placeholder="Enter phone number")760            761        with gr.Row():762            appt_email = gr.Textbox(label="Email (Optional)", placeholder="Enter email address")763            # Fixed dropdown: Use the actual list rather than the function764            appt_doctor = gr.Dropdown(765                choices=get_all_doctor_names(),  # Call the function to get its return value766                label="Select Doctor*"767            )768            769        with gr.Row():770            appt_date = gr.Textbox(771                label="Appointment Date*", 772                placeholder="YYYY-MM-DD",773                info="Enter date in YYYY-MM-DD format"774            )775            appt_time = gr.Dropdown(776                choices=[777                    "09:00 AM", "09:30 AM", "10:00 AM", "10:30 AM", "11:00 AM", "11:30 AM",778                    "01:00 PM", "01:30 PM", "02:00 PM", "02:30 PM", "03:00 PM", "03:30 PM",779                    "04:00 PM", "04:30 PM"780                ],781                label="Appointment Time*"782            )783            784        appt_reason = gr.Textbox(785            label="Reason for Appointment",786            placeholder="Briefly describe the reason for appointment",787            lines=3788        )789        790        schedule_btn = gr.Button("Schedule Appointment", variant="primary")791        schedule_output = gr.Textbox(label="Appointment Details")792        793        schedule_btn.click(794            fn=schedule_appointment, 795            inputs=[appt_name, appt_phone, appt_email, appt_doctor, appt_date, appt_time, appt_reason], 796            outputs=schedule_output797        ) 798        # Appointment List799        gr.Markdown("### View Appointments")800        801        with gr.Row():802            view_date = gr.Textbox(803                label="Date (YYYY-MM-DD)", 804                placeholder="Leave empty for all dates",805                value=datetime.now().strftime('%Y-%m-%d')806            )807            view_doctor = gr.Dropdown(808                choices=["All Doctors"] + get_all_doctor_names(),809                label="Doctor",810                value="All Doctors"811            )812            view_btn = gr.Button("View Appointments")813            814        appointments_table = gr.Dataframe(815            headers=["ID", "Patient Name", "Phone", "Time", "Doctor", "Reason", "Status"],816            interactive=False,817            label="Appointments"818        )819        820        view_btn.click(821            fn=get_appointments, 822            inputs=[view_date, view_doctor], 823            outputs=appointments_table824        )825        826    # Admin Panel Tab    827    with gr.Tab("โš™๏ธ Admin Panel"):828        gr.Markdown("### Doctor Availability Management")829    830    doctors_table = gr.Dataframe(831        headers=["ID", "Name", "Specialty", "Status"],832        interactive=False,833        label="Doctors"834    )835    836    with gr.Row():837        doctor_id = gr.Number(label="Doctor ID", precision=0)838        toggle_btn = gr.Button("Toggle Availability")839        toggle_output = gr.Textbox(label="Result")840    841    refresh_doctors_btn = gr.Button("Refresh Doctor List")842    843    # Set up event handlers844    toggle_btn.click(845        fn=toggle_doctor_availability, 846        inputs=doctor_id, 847        outputs=toggle_output848    )849    850    refresh_doctors_btn.click(851        fn=get_doctor_availability, 852        inputs=[], 853        outputs=doctors_table854    )855    856    # Initialize doctors table857    demo.load(858        fn=get_doctor_availability, 859        inputs=[], 860        outputs=doctors_table861    )862 863    # System Maintenance Section864    gr.Markdown("### System Maintenance")865    866    with gr.Row():867        backup_btn = gr.Button("Backup Database")868        backup_output = gr.Textbox(label="Backup Status")869    870    def backup_database():871        """Create a backup of the database"""872        try:873            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")874            backup_file = f"hospital_backup_{timestamp}.db"875            876            # Create connection to new file877            backup_conn = sqlite3.connect(backup_file)878            879            # Copy data880            conn.backup(backup_conn)881            backup_conn.close()882            883            return f"Backup created successfully: {backup_file}"884        except Exception as e:885            return f"Backup failed: {str(e)}"886    887    backup_btn.click(fn=backup_database, inputs=[], outputs=backup_output)888 889# Launch the app890if __name__ == "__main__":891    demo.launch(share=False)