Jacksonnavigator7/Hospital_Queue_Management_System
0
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)