Jacksonnavigator7's picture
Update app.py
7aa8ed5 verified
Raw
History Blame Contribute Delete
32 kB
import sqlite3
import gradio as gr
import pandas as pd
import time
from datetime import datetime, timedelta
import random
import string
import os
# ---------------------------
# DATABASE SETUP
# ---------------------------
def get_db_connection():
"""Create a database connection with proper error handling"""
try:
conn = sqlite3.connect("hospital.db", check_same_thread=False)
conn.row_factory = sqlite3.Row # Return rows as dictionaries
return conn
except sqlite3.Error as e:
print(f"Database connection error: {e}")
return None
conn = get_db_connection()
cursor = conn.cursor()
# Create tables with improved schema
cursor.execute('''CREATE TABLE IF NOT EXISTS doctors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
specialty TEXT,
avg_consultation_time INTEGER DEFAULT 15, -- in minutes
available BOOLEAN DEFAULT 1
)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS patients (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT,
symptoms TEXT,
priority INTEGER DEFAULT 3, -- 1=emergency, 2=urgent, 3=normal
doctor_id INTEGER,
queue_number INTEGER,
token TEXT UNIQUE,
registration_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
estimated_start_time TIMESTAMP,
status TEXT DEFAULT 'Waiting',
completed_time TIMESTAMP,
notes TEXT,
FOREIGN KEY (doctor_id) REFERENCES doctors(id)
)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS appointments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
patient_name TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT,
doctor_id INTEGER,
appointment_date TEXT,
appointment_time TEXT,
reason TEXT,
status TEXT DEFAULT 'Scheduled',
FOREIGN KEY (doctor_id) REFERENCES doctors(id)
)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS notifications (
id INTEGER PRIMARY KEY AUTOINCREMENT,
patient_id INTEGER,
message TEXT,
sent_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (patient_id) REFERENCES patients(id)
)''')
conn.commit()
# Seed doctors if table is empty
cursor.execute("SELECT COUNT(*) FROM doctors")
if cursor.fetchone()[0] == 0:
doctors = [
("Dr. Smith", "General Medicine", 15, 1),
("Dr. Lee", "Pediatrics", 20, 1),
("Dr. Patel", "Cardiology", 25, 1),
("Dr. Johnson", "Orthopedics", 20, 1),
("Dr. Garcia", "Dermatology", 15, 1)
]
cursor.executemany("INSERT INTO doctors (name, specialty, avg_consultation_time, available) VALUES (?, ?, ?, ?)", doctors)
conn.commit()
# ---------------------------
# HELPER FUNCTIONS
# ---------------------------
def generate_token():
"""Generate a unique alphanumeric token for patients"""
token = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
return token
def calculate_wait_time(doctor_id, queue_position):
"""Calculate estimated wait time based on doctor's avg consultation time and queue position"""
cursor.execute("SELECT avg_consultation_time FROM doctors WHERE id=?", (doctor_id,))
avg_time = cursor.fetchone()[0]
# Count how many patients are currently in consultation (usually just 1)
cursor.execute("SELECT COUNT(*) FROM patients WHERE doctor_id=? AND status='In Consultation'", (doctor_id,))
in_consultation = cursor.fetchone()[0]
# Calculate wait time: (patients ahead + in consultation) * avg time
wait_minutes = (queue_position - 1 + in_consultation) * avg_time
# Add some randomness to make it realistic (±20%)
variation = random.uniform(0.8, 1.2)
wait_minutes = int(wait_minutes * variation)
return wait_minutes
def format_wait_time(minutes):
"""Format wait time into hours and minutes"""
if minutes < 60:
return f"{minutes} minutes"
hours = minutes // 60
mins = minutes % 60
return f"{hours} hour{'s' if hours > 1 else ''} {mins} minutes"
def update_all_wait_times():
"""Update estimated wait times for all waiting patients"""
# Get all waiting patients
cursor.execute("""
SELECT p.id, p.doctor_id, p.queue_number
FROM patients p
WHERE p.status='Waiting'
ORDER BY p.doctor_id, p.queue_number
""")
waiting_patients = cursor.fetchall()
# Group by doctor
for doctor_id in set([p[1] for p in waiting_patients]):
# Get all patients for this doctor
doctor_patients = [p for p in waiting_patients if p[1] == doctor_id]
# Update wait time for each patient
for patient in doctor_patients:
wait_minutes = calculate_wait_time(doctor_id, patient[2])
estimated_time = datetime.now() + timedelta(minutes=wait_minutes)
cursor.execute(
"UPDATE patients SET estimated_start_time=? WHERE id=?",
(estimated_time.strftime('%Y-%m-%d %H:%M:%S'), patient[0])
)
conn.commit()
# ---------------------------
# CORE FUNCTIONS
# ---------------------------
def register_patient(name, phone, email, symptoms, priority, doctor_name):
"""Register a new patient with improved data validation and wait time estimation"""
# Input validation
if not name or not phone or not doctor_name:
return "Error: Name, phone number, and doctor selection are required."
try:
# Get doctor details
cursor.execute("SELECT id, available FROM doctors WHERE name=?", (doctor_name,))
doctor_result = cursor.fetchone()
if not doctor_result:
return f"Error: Doctor {doctor_name} not found."
doctor_id, is_available = doctor_result
if not is_available:
return f"Sorry, {doctor_name} is currently not available. Please select another doctor."
# Check if patient with same phone is already in queue
cursor.execute("SELECT id FROM patients WHERE phone=? AND status IN ('Waiting', 'In Consultation')", (phone,))
if cursor.fetchone():
return "This phone number is already registered in the active queue."
# Get next queue number
cursor.execute("SELECT MAX(queue_number) FROM patients WHERE doctor_id=?", (doctor_id,))
last_queue = cursor.fetchone()[0]
next_queue = 1 if last_queue is None else last_queue + 1
# Generate unique token
token = generate_token()
while True:
# Check if token already exists
cursor.execute("SELECT id FROM patients WHERE token=?", (token,))
if not cursor.fetchone():
break
token = generate_token() # Generate new token if exists
# Calculate estimated wait time
wait_minutes = calculate_wait_time(doctor_id, next_queue)
estimated_time = datetime.now() + timedelta(minutes=wait_minutes)
# Insert patient
cursor.execute("""
INSERT INTO patients
(name, phone, email, symptoms, priority, doctor_id, queue_number, token, estimated_start_time, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (name, phone, email, symptoms, priority, doctor_id, next_queue, token,
estimated_time.strftime('%Y-%m-%d %H:%M:%S'), 'Waiting'))
conn.commit()
# Get patient ID for notification
patient_id = cursor.lastrowid
# Add welcome notification
notification_msg = f"Welcome {name}! You are registered with {doctor_name}. Your token is {token} and queue number is {next_queue}."
cursor.execute("INSERT INTO notifications (patient_id, message) VALUES (?, ?)",
(patient_id, notification_msg))
conn.commit()
# Update wait times for all patients
update_all_wait_times()
# Format response
wait_time_str = format_wait_time(wait_minutes)
return f"Registered successfully!\n\nYour token: {token}\nQueue number: {next_queue}\nDoctor: {doctor_name}\nEstimated wait time: {wait_time_str}"
except Exception as e:
conn.rollback()
return f"An error occurred: {str(e)}"
def check_status(phone_or_token):
"""Check patient status by phone or token"""
if not phone_or_token:
return "Please enter a phone number or token."
try:
# Try to find by token first (more specific)
cursor.execute("""
SELECT
p.id, p.name, p.token, p.queue_number, p.status, p.estimated_start_time,
d.name as doctor_name, d.specialty
FROM patients p
JOIN doctors d ON p.doctor_id = d.id
WHERE p.token=? AND p.status IN ('Waiting', 'In Consultation')
LIMIT 1
""", (phone_or_token,))
result = cursor.fetchone()
# If not found by token, try phone
if not result:
cursor.execute("""
SELECT
p.id, p.name, p.token, p.queue_number, p.status, p.estimated_start_time,
d.name as doctor_name, d.specialty
FROM patients p
JOIN doctors d ON p.doctor_id = d.id
WHERE p.phone=? AND p.status IN ('Waiting', 'In Consultation')
ORDER BY p.id DESC LIMIT 1
""", (phone_or_token,))
result = cursor.fetchone()
if not result:
return "No active registration found. If you've already completed your visit or haven't registered yet, please check with reception."
# Format estimated time
estimated_time = datetime.strptime(result[5], '%Y-%m-%d %H:%M:%S') if result[5] else None
now = datetime.now()
if estimated_time and estimated_time > now:
time_diff = estimated_time - now
wait_minutes = int(time_diff.total_seconds() / 60)
wait_str = format_wait_time(wait_minutes)
else:
wait_str = "You should be called soon"
status_info = f"""
Patient: {result[1]}
Token: {result[2]}
Queue #: {result[3]}
Status: {result[4]}
Doctor: {result[6]} ({result[7]})
"""
if result[4] == 'Waiting':
status_info += f"Estimated wait: {wait_str}"
# Get any notifications
cursor.execute("""
SELECT message FROM notifications
WHERE patient_id=?
ORDER BY sent_time DESC LIMIT 1
""", (result[0],))
notification = cursor.fetchone()
if notification:
status_info += f"\n\nNotification: {notification[0]}"
return status_info
except Exception as e:
return f"Error checking status: {str(e)}"
def get_doctor_queue(doctor_name):
"""Get current queue for a specific doctor"""
try:
cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))
doctor_id = cursor.fetchone()[0]
cursor.execute("""
SELECT
id, name, queue_number, priority,
strftime('%H:%M', registration_time) as reg_time,
status, phone, token
FROM patients
WHERE doctor_id=? AND status IN ('Waiting', 'In Consultation')
ORDER BY
CASE status
WHEN 'In Consultation' THEN 0
ELSE 1
END,
priority, queue_number
""", (doctor_id,))
rows = cursor.fetchall()
# Convert to list of lists for gradio dataframe
result = []
for row in rows:
# Format priority as text
priority_text = {1: "Emergency", 2: "Urgent", 3: "Normal"}.get(row[3], "Normal")
result.append([row[0], row[1], row[2], priority_text, row[4], row[5], row[6], row[7]])
return result
except Exception as e:
print(f"Error getting doctor queue: {e}")
return []
def get_doctor_availability():
"""Get the list of available doctors with their specialties"""
cursor.execute("""
SELECT id, name, specialty, available
FROM doctors
ORDER BY name
""")
doctors = cursor.fetchall()
# Format for display
result = []
for doc in doctors:
status = "Available" if doc[3] else "Unavailable"
result.append([doc[0], doc[1], doc[2], status])
return result
def toggle_doctor_availability(doctor_id):
"""Toggle a doctor's availability status"""
try:
if not doctor_id:
return "Please select a doctor."
cursor.execute("SELECT available FROM doctors WHERE id=?", (doctor_id,))
current_status = cursor.fetchone()[0]
# Toggle status
new_status = 0 if current_status else 1
cursor.execute("UPDATE doctors SET available=? WHERE id=?", (new_status, doctor_id))
conn.commit()
status_text = "available" if new_status else "unavailable"
return f"Doctor status updated to {status_text}"
except Exception as e:
conn.rollback()
return f"Error updating status: {str(e)}"
def call_next(doctor_name):
"""Call the next patient in queue with notifications"""
try:
cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))
doctor_id = cursor.fetchone()[0]
# First check if any patient is currently in consultation
cursor.execute("""
SELECT id, name
FROM patients
WHERE doctor_id=? AND status='In Consultation'
LIMIT 1
""", (doctor_id,))
current_patient = cursor.fetchone()
if current_patient:
return f"{current_patient[1]} is currently in consultation. Please complete their visit before calling the next patient."
# Find next patient based on priority and queue number
cursor.execute("""
SELECT id, name, token, queue_number, phone
FROM patients
WHERE doctor_id=? AND status='Waiting'
ORDER BY priority, queue_number ASC
LIMIT 1
""", (doctor_id,))
patient = cursor.fetchone()
if not patient:
return "No patients waiting."
# Update patient status
cursor.execute("UPDATE patients SET status='In Consultation' WHERE id=?", (patient[0],))
# Create notification
notification_msg = f"It's your turn! Please proceed to {doctor_name}'s room immediately."
cursor.execute("INSERT INTO notifications (patient_id, message) VALUES (?, ?)",
(patient[0], notification_msg))
conn.commit()
# Update wait times for all remaining patients
update_all_wait_times()
# Return formatted message
return f"Now calling: {patient[1]} (Token: {patient[2]}, Queue #: {patient[3]})"
except Exception as e:
conn.rollback()
return f"Error calling next patient: {str(e)}"
def complete_patient(patient_id, notes=""):
"""Mark patient consultation as completed with optional notes"""
try:
if not patient_id:
return "Please select a patient to mark as completed."
# Update patient status and add completion time
cursor.execute(
"UPDATE patients SET status='Completed', completed_time=?, notes=? WHERE id=?",
(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), notes, patient_id)
)
# Get patient info for confirmation
cursor.execute("SELECT name, token FROM patients WHERE id=?", (patient_id,))
patient = cursor.fetchone()
conn.commit()
# Update wait times for all remaining patients
update_all_wait_times()
return f"Patient {patient[0]} (Token: {patient[1]}) marked as completed."
except Exception as e:
conn.rollback()
return f"Error completing patient visit: {str(e)}"
def schedule_appointment(name, phone, email, doctor_name, date, time, reason):
"""Schedule a future appointment"""
try:
# Validate inputs
if not name or not phone or not doctor_name or not date or not time:
return "Error: Name, phone, doctor, date and time are required fields."
# Get doctor ID
cursor.execute("SELECT id FROM doctors WHERE name=?", (doctor_name,))
doctor_result = cursor.fetchone()
if not doctor_result:
return f"Error: Doctor {doctor_name} not found."
doctor_id = doctor_result[0]
# Check if time slot is available
cursor.execute("""
SELECT COUNT(*) FROM appointments
WHERE doctor_id=? AND appointment_date=? AND appointment_time=? AND status='Scheduled'
""", (doctor_id, date, time))
if cursor.fetchone()[0] > 0:
return f"Sorry, {doctor_name} is already booked at {time} on {date}. Please select another time."
# Insert appointment
cursor.execute("""
INSERT INTO appointments
(patient_name, phone, email, doctor_id, appointment_date, appointment_time, reason, status)
VALUES (?, ?, ?, ?, ?, ?, ?, 'Scheduled')
""", (name, phone, email, doctor_id, date, time, reason))
conn.commit()
return f"Appointment scheduled successfully for {name} with {doctor_name} on {date} at {time}."
except Exception as e:
conn.rollback()
return f"Error scheduling appointment: {str(e)}"
def get_appointments(date=None, doctor_name=None):
"""Get list of appointments by date and/or doctor"""
try:
query = """
SELECT
a.id, a.patient_name, a.phone, a.appointment_time,
d.name as doctor_name, a.reason, a.status
FROM appointments a
JOIN doctors d ON a.doctor_id = d.id
WHERE 1=1
"""
params = []
if date:
query += " AND a.appointment_date = ?"
params.append(date)
if doctor_name and doctor_name != "All Doctors":
query += " AND d.name = ?"
params.append(doctor_name)
query += " ORDER BY a.appointment_time"
cursor.execute(query, params)
appointments = cursor.fetchall()
# Format for display
result = []
for appt in appointments:
result.append([appt[0], appt[1], appt[2], appt[3], appt[4], appt[5], appt[6]])
return result
except Exception as e:
print(f"Error getting appointments: {e}")
return []
def get_daily_stats():
"""Get daily statistics for the dashboard"""
try:
today = datetime.now().strftime('%Y-%m-%d')
# Total patients today
cursor.execute("""
SELECT COUNT(*) FROM patients
WHERE date(registration_time) = ?
""", (today,))
total_patients = cursor.fetchone()[0]
# Waiting patients
cursor.execute("SELECT COUNT(*) FROM patients WHERE status='Waiting'")
waiting_patients = cursor.fetchone()[0]
# In consultation
cursor.execute("SELECT COUNT(*) FROM patients WHERE status='In Consultation'")
in_consultation = cursor.fetchone()[0]
# Completed today
cursor.execute("""
SELECT COUNT(*) FROM patients
WHERE status='Completed' AND date(completed_time) = ?
""", (today,))
completed_today = cursor.fetchone()[0]
# Average wait time today
cursor.execute("""
SELECT AVG(
(julianday(completed_time) - julianday(registration_time)) * 24 * 60
) FROM patients
WHERE status='Completed' AND date(completed_time) = ?
""", (today,))
avg_wait_time = cursor.fetchone()[0]
avg_wait_formatted = f"{int(avg_wait_time)} minutes" if avg_wait_time else "N/A"
return {
"total_patients": total_patients,
"waiting": waiting_patients,
"in_consultation": in_consultation,
"completed": completed_today,
"avg_wait_time": avg_wait_formatted
}
except Exception as e:
print(f"Error getting stats: {e}")
return {
"total_patients": 0,
"waiting": 0,
"in_consultation": 0,
"completed": 0,
"avg_wait_time": "N/A"
}
# ---------------------------
# GRADIO INTERFACE
# ---------------------------
def get_doctor_names():
"""Get list of available doctor names"""
cursor.execute("SELECT name FROM doctors WHERE available=1 ORDER BY name")
doctors = [row[0] for row in cursor.fetchall()]
return doctors
def get_all_doctor_names():
"""Get list of all doctor names regardless of availability"""
cursor.execute("SELECT name FROM doctors ORDER BY name")
doctors = [row[0] for row in cursor.fetchall()]
return doctors
# Create the Gradio interface with theme and improved UI
theme = gr.themes.Soft(
primary_hue="blue",
secondary_hue="indigo",
)
with gr.Blocks(theme=theme, title="Hospital Queue Management System") as demo:
gr.Markdown("# 🏥 Hospital Queue Management System")
# Dashboard Tab
with gr.Tab("📊 Dashboard"):
gr.Markdown("### Today's Statistics")
with gr.Row():
total_count = gr.Textbox(label="Total Patients Today")
waiting_count = gr.Textbox(label="Currently Waiting")
consulting_count = gr.Textbox(label="In Consultation")
completed_count = gr.Textbox(label="Completed Today")
avg_wait = gr.Textbox(label="Average Wait Time")
refresh_stats_btn = gr.Button("Refresh Statistics")
def update_dashboard():
stats = get_daily_stats()
return [
stats["total_patients"],
stats["waiting"],
stats["in_consultation"],
stats["completed"],
stats["avg_wait_time"]
]
refresh_stats_btn.click(
fn=update_dashboard,
inputs=[],
outputs=[total_count, waiting_count, consulting_count, completed_count, avg_wait]
)
# Initialize dashboard
demo.load(
fn=update_dashboard,
inputs=[],
outputs=[total_count, waiting_count, consulting_count, completed_count, avg_wait]
)
# Patient Registration Tab
with gr.Tab("➕ Register Patient"):
gr.Markdown("### New Patient Registration")
with gr.Row():
name = gr.Textbox(label="Patient Name*", placeholder="Enter full name")
phone = gr.Textbox(label="Phone Number*", placeholder="Enter phone number")
with gr.Row():
email = gr.Textbox(label="Email (Optional)", placeholder="Enter email address")
priority = gr.Dropdown(
choices=[
{"label": "Normal", "value": 3},
{"label": "Urgent", "value": 2},
{"label": "Emergency", "value": 1}
],
label="Priority",
value=3
)
symptoms = gr.Textbox(
label="Symptoms/Reason for Visit",
placeholder="Briefly describe the symptoms or reason for visit",
lines=3
)
# Fixed dropdown: Use the actual list rather than the function
doctor = gr.Dropdown(
choices=get_doctor_names(), # Call the function to get its return value
label="Select Doctor*",
info="Only shows available doctors"
)
register_btn = gr.Button("Register Patient", variant="primary")
register_output = gr.Textbox(label="Registration Details", lines=6)
register_btn.click(
fn=register_patient,
inputs=[name, phone, email, symptoms, priority, doctor],
outputs=register_output
)
# Status Check Tab
with gr.Tab("🔍 Check My Status"):
gr.Markdown("### Patient Status Lookup")
phone_lookup = gr.Textbox(
label="Enter Your Phone Number or Token",
placeholder="Enter phone number or 6-digit token",
info="You can use either your phone number or token to check your status"
)
check_btn = gr.Button("Check Status", variant="primary")
status_output = gr.Textbox(label="Your Status", lines=8)
check_btn.click(fn=check_status, inputs=phone_lookup, outputs=status_output)
# Doctor Panel Tab
with gr.Tab("🩺 Doctor Panel"):
gr.Markdown("### Manage Patient Queue")
with gr.Row():
# Fixed dropdown: Use the actual list rather than the function
doc_select = gr.Dropdown(
choices=get_all_doctor_names(), # Call the function to get its return value
label="Select Doctor",
info="Select doctor to view their queue"
)
with gr.Column():
call_btn = gr.Button("Call Next Patient", variant="primary")
call_output = gr.Textbox(label="Now Calling", lines=2)
queue_table = gr.Dataframe(
headers=["ID", "Name", "Queue #", "Priority", "Reg. Time", "Status", "Phone", "Token"],
datatype=["number", "str", "number", "str", "str", "str", "str", "str"],
interactive=False,
label="Current Queue"
)
with gr.Row():
selected_patient_id = gr.Number(label="Patient ID", precision=0)
patient_notes = gr.Textbox(label="Consultation Notes", lines=2)
complete_btn = gr.Button("Complete Visit")
complete_output = gr.Textbox(label="Result")
refresh_btn = gr.Button("Refresh Queue")
# Set up event handlers
call_btn.click(fn=call_next, inputs=doc_select, outputs=call_output)
complete_btn.click(
fn=complete_patient,
inputs=[selected_patient_id, patient_notes],
outputs=complete_output
)
refresh_btn.click(
fn=lambda d: get_doctor_queue(d),
inputs=doc_select,
outputs=queue_table
)
# Update queue when doctor selection changes
doc_select.change(
fn=lambda d: get_doctor_queue(d),
inputs=doc_select,
outputs=queue_table
)
# Appointment Scheduling Tab
with gr.Tab("📅 Schedule Appointment"):
gr.Markdown("### Schedule a Future Appointment")
with gr.Row():
appt_name = gr.Textbox(label="Patient Name*", placeholder="Enter full name")
appt_phone = gr.Textbox(label="Phone Number*", placeholder="Enter phone number")
with gr.Row():
appt_email = gr.Textbox(label="Email (Optional)", placeholder="Enter email address")
# Fixed dropdown: Use the actual list rather than the function
appt_doctor = gr.Dropdown(
choices=get_all_doctor_names(), # Call the function to get its return value
label="Select Doctor*"
)
with gr.Row():
appt_date = gr.Textbox(
label="Appointment Date*",
placeholder="YYYY-MM-DD",
info="Enter date in YYYY-MM-DD format"
)
appt_time = gr.Dropdown(
choices=[
"09:00 AM", "09:30 AM", "10:00 AM", "10:30 AM", "11:00 AM", "11:30 AM",
"01:00 PM", "01:30 PM", "02:00 PM", "02:30 PM", "03:00 PM", "03:30 PM",
"04:00 PM", "04:30 PM"
],
label="Appointment Time*"
)
appt_reason = gr.Textbox(
label="Reason for Appointment",
placeholder="Briefly describe the reason for appointment",
lines=3
)
schedule_btn = gr.Button("Schedule Appointment", variant="primary")
schedule_output = gr.Textbox(label="Appointment Details")
schedule_btn.click(
fn=schedule_appointment,
inputs=[appt_name, appt_phone, appt_email, appt_doctor, appt_date, appt_time, appt_reason],
outputs=schedule_output
)
# Appointment List
gr.Markdown("### View Appointments")
with gr.Row():
view_date = gr.Textbox(
label="Date (YYYY-MM-DD)",
placeholder="Leave empty for all dates",
value=datetime.now().strftime('%Y-%m-%d')
)
view_doctor = gr.Dropdown(
choices=["All Doctors"] + get_all_doctor_names(),
label="Doctor",
value="All Doctors"
)
view_btn = gr.Button("View Appointments")
appointments_table = gr.Dataframe(
headers=["ID", "Patient Name", "Phone", "Time", "Doctor", "Reason", "Status"],
interactive=False,
label="Appointments"
)
view_btn.click(
fn=get_appointments,
inputs=[view_date, view_doctor],
outputs=appointments_table
)
# Admin Panel Tab
with gr.Tab("⚙️ Admin Panel"):
gr.Markdown("### Doctor Availability Management")
doctors_table = gr.Dataframe(
headers=["ID", "Name", "Specialty", "Status"],
interactive=False,
label="Doctors"
)
with gr.Row():
doctor_id = gr.Number(label="Doctor ID", precision=0)
toggle_btn = gr.Button("Toggle Availability")
toggle_output = gr.Textbox(label="Result")
refresh_doctors_btn = gr.Button("Refresh Doctor List")
# Set up event handlers
toggle_btn.click(
fn=toggle_doctor_availability,
inputs=doctor_id,
outputs=toggle_output
)
refresh_doctors_btn.click(
fn=get_doctor_availability,
inputs=[],
outputs=doctors_table
)
# Initialize doctors table
demo.load(
fn=get_doctor_availability,
inputs=[],
outputs=doctors_table
)
# System Maintenance Section
gr.Markdown("### System Maintenance")
with gr.Row():
backup_btn = gr.Button("Backup Database")
backup_output = gr.Textbox(label="Backup Status")
def backup_database():
"""Create a backup of the database"""
try:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = f"hospital_backup_{timestamp}.db"
# Create connection to new file
backup_conn = sqlite3.connect(backup_file)
# Copy data
conn.backup(backup_conn)
backup_conn.close()
return f"Backup created successfully: {backup_file}"
except Exception as e:
return f"Backup failed: {str(e)}"
backup_btn.click(fn=backup_database, inputs=[], outputs=backup_output)
# Launch the app
if __name__ == "__main__":
demo.launch(share=False)