Spaces:
Running
Running
import gradio as gr | |
import json | |
from datetime import datetime | |
from patient_registration import register_patient | |
from test_selection import select_tests, get_tests_by_category | |
from billing import fetch_billing | |
# Load data | |
def load_data(): | |
try: | |
with open("data.json", "r") as file: | |
data = json.load(file) | |
return data.get("patients", {}), data.get("last_sequence", {"year": None, "month": None, "number": 0}) | |
except FileNotFoundError: | |
return {}, {"year": None, "month": None, "number": 0} | |
# Save data | |
def save_data(patients, last_sequence): | |
with open("data.json", "w") as file: | |
json.dump({"patients": patients, "last_sequence": last_sequence}, file) | |
# Generate patient ID | |
def generate_patient_id(phone, last_sequence): | |
today = datetime.now() | |
current_year = today.year | |
current_month = today.month | |
if last_sequence["year"] != current_year or last_sequence["month"] != current_month: | |
last_sequence["year"] = current_year | |
last_sequence["month"] = current_month | |
last_sequence["number"] = 1 | |
else: | |
last_sequence["number"] += 1 | |
patient_id = f"{current_year}{current_month:02d}{last_sequence['number']:05d}" | |
return patient_id | |
# Patient Registration Tab | |
def registration_interface(name, father_name, age, phone, address, pincode): | |
patients, last_sequence = load_data() | |
patient_id = generate_patient_id(phone, last_sequence) | |
patients[patient_id] = { | |
"name": name, | |
"father_name": father_name, | |
"age": age, | |
"phone": phone, | |
"address": address, | |
"pincode": pincode, | |
"tests": [], | |
"total_cost": 0 | |
} | |
save_data(patients, last_sequence) | |
return f"Patient Registered. Patient ID: {patient_id}", patient_id | |
# Gradio Interface | |
with gr.Blocks() as app: | |
gr.Markdown("<h1 style='text-align: center;'>Sathkrutha LIMS</h1>", elem_id="header") | |
with gr.Tab("Patient Registration"): | |
with gr.Row(): | |
name = gr.Textbox(label="Patient Name", placeholder="Enter patient name", elem_id="name_field", lines=1) | |
father_name = gr.Textbox(label="Father/Husband Name", placeholder="Enter father or husband name", elem_id="father_name_field", lines=1) | |
with gr.Row(): | |
age = gr.Number(label="Age", value=None, minimum=0, maximum=99, elem_id="age_field") | |
phone = gr.Number(label="Phone Number", value=None, elem_id="phone_field") | |
with gr.Row(): | |
address = gr.Textbox(label="Address", placeholder="Enter address", lines=2) | |
pincode = gr.Number(label="Pincode", value=None, elem_id="pincode_field") | |
register_button = gr.Button("Register Patient") | |
registration_output = gr.Textbox(label="Registration Output") | |
hidden_patient_id = gr.Textbox(visible=False) # Hidden field to store the patient ID | |
register_button.click(registration_interface, [name, father_name, age, phone, address, pincode], [registration_output, hidden_patient_id]) | |
# Custom HTML for Copy ID Button | |
copy_id_html = """ | |
<button onclick="copyPatientID()" style="background-color: #3b74f2; color: white; padding: 10px; border-radius: 5px; border: none; cursor: pointer;">Copy Patient ID</button> | |
<script> | |
function copyPatientID() { | |
navigator.clipboard.writeText(document.querySelector('#hidden_patient_id textarea').value); | |
alert('Patient ID copied to clipboard'); | |
} | |
</script> | |
""" | |
gr.HTML(copy_id_html) | |
# Custom CSS styling | |
app.css = """ | |
body { | |
font-family: 'Roboto', Arial, sans-serif; | |
background: url('./background.png') no-repeat center center fixed; | |
background-size: cover; | |
color: #f0f0f0; | |
margin: 0; | |
padding: 0; | |
} | |
#header { | |
color: #ccdb42; | |
font-weight: 700; | |
text-transform: uppercase; | |
margin-bottom: 20px; | |
} | |
.gradio-container { | |
max-width: 850px; | |
margin: 30px auto; | |
padding: 25px; | |
background: rgba(30, 30, 30, 0.95); | |
border-radius: 12px; | |
box-shadow: 0px 0px 25px rgba(0, 0, 0, 0.3); | |
color: #e0e0e0; | |
} | |
#name_field, #father_name_field, #age_field, #phone_field, #pincode_field { | |
max-width: 700px; | |
border: 1px solid #888; | |
border-radius: 6px; | |
padding: 10px; | |
background: #f5f5f5; | |
color: #333; | |
font-size: 14px; | |
margin-bottom: 12px; | |
transition: all 0.3s ease; | |
} | |
#name_field:focus, #father_name_field:focus, #age_field:focus, #phone_field:focus, #pincode_field:focus { | |
border-color: #ccdb42; | |
box-shadow: 0 0 8px rgba(204, 219, 66, 0.5); | |
} | |
textarea { | |
font-size: 15px; | |
color: #080707; | |
background: #fefefe; | |
padding: 12px; | |
border-radius: 6px; | |
} | |
.gr-button { | |
color: #ffffff; | |
background-color: #3b74f2; | |
border: none; | |
border-radius: 6px; | |
padding: 12px 24px; | |
cursor: pointer; | |
font-weight: 600; | |
transition: background-color 0.3s ease, transform 0.2s; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); | |
} | |
.gr-button:hover { | |
background-color: #2a5bc1; | |
transform: scale(1.05); | |
} | |
.gr-tab { | |
background-color: rgba(255, 255, 255, 0.05); | |
border-radius: 8px; | |
padding: 20px; | |
} | |
h1, h2, h3, h4, h5, h6 { | |
color: #ccdb42; | |
font-weight: 700; | |
} | |
#billing_output { | |
background-color: #333333; | |
padding: 15px; | |
border-radius: 6px; | |
color: #d1f542; | |
font-size: 16px; | |
font-weight: bold; | |
} | |
.checkbox, .textbox { | |
margin-bottom: 15px; | |
color: #f0f0f0; | |
} | |
""" | |
app.launch() | |