Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -423,7 +423,9 @@ st.markdown("---")
|
|
| 423 |
if st.button("🔄 " + ("Refresh Firebase data" if st.session_state.lang == "en" else "Làm mới dữ liệu Firebase")):
|
| 424 |
render_latest_firebase_data(show_toast=True)
|
| 425 |
|
| 426 |
-
#
|
|
|
|
|
|
|
| 427 |
if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
| 428 |
st.header("Advanced assistance")
|
| 429 |
st.markdown(f"**Wound type:** `{st.session_state.wound_type}`")
|
|
@@ -431,14 +433,26 @@ if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
|
| 431 |
with st.form("victim_form", clear_on_submit=True):
|
| 432 |
st.subheader(t("victim_name"))
|
| 433 |
name = st.text_input(t("victim_name"))
|
| 434 |
-
phone = st.text_input(t("phone"),
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 442 |
|
| 443 |
col1, col2 = st.columns(2)
|
| 444 |
with col1:
|
|
@@ -446,38 +460,71 @@ if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
|
| 446 |
with col2:
|
| 447 |
emergency_submit = st.form_submit_button(t("emergency_btn"))
|
| 448 |
|
| 449 |
-
# common validation
|
| 450 |
-
def validate_fields(age_str, phone_str):
|
| 451 |
age_v = None
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
if age_str and age_str.strip():
|
| 453 |
try:
|
| 454 |
age_v = int(age_str.strip())
|
| 455 |
except Exception:
|
| 456 |
-
st.error(("Age must be an integer (or leave blank)." if st.session_state.lang == "en"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
st.stop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 458 |
phone_clean = phone_str.strip()
|
| 459 |
if phone_clean and not phone_clean.replace("+", "").isdigit():
|
| 460 |
-
st.error(("Phone number should contain digits only." if st.session_state.lang == "en"
|
|
|
|
| 461 |
st.stop()
|
| 462 |
-
|
|
|
|
| 463 |
|
| 464 |
if (submit or emergency_submit) and not st.session_state.victim_saved:
|
| 465 |
-
|
|
|
|
|
|
|
| 466 |
victim = {
|
| 467 |
"name": name or "unknown",
|
| 468 |
"phone": phone_clean or None,
|
| 469 |
"age": age_v,
|
|
|
|
|
|
|
| 470 |
"notes": notes or "",
|
| 471 |
"wound_type": st.session_state.wound_type,
|
| 472 |
"saved_at": datetime.utcnow().isoformat() + "Z",
|
| 473 |
"emergency": bool(emergency_submit),
|
| 474 |
}
|
|
|
|
| 475 |
try:
|
| 476 |
record = save_victim_info(victim)
|
| 477 |
st.session_state.last_saved_record = record
|
| 478 |
st.session_state.victim_saved = True
|
| 479 |
if emergency_submit:
|
| 480 |
-
st.error(("EMERGENCY recorded. Call local emergency services now." if st.session_state.lang == "en"
|
|
|
|
| 481 |
else:
|
| 482 |
st.success(("Victim info saved." if st.session_state.lang == "en" else "Đã lưu thông tin nạn nhân."))
|
| 483 |
except Exception as e:
|
|
@@ -487,7 +534,11 @@ if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
|
| 487 |
# For non-emergency: ask OpenAI for guidance
|
| 488 |
if submit and st.session_state.victim_saved:
|
| 489 |
system_prompt = make_system_prompt(st.session_state.wound_type, victim)
|
| 490 |
-
initial_user_msg = (
|
|
|
|
|
|
|
|
|
|
|
|
|
| 491 |
with st.spinner(("Contacting assistant..." if st.session_state.lang == "en" else "Đang liên hệ trợ lý...")):
|
| 492 |
resp = query_openai(system_prompt, initial_user_msg)
|
| 493 |
if "error" in resp:
|
|
@@ -499,6 +550,7 @@ if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
|
| 499 |
st.markdown("**" + t("assistant_guidance") + "**")
|
| 500 |
st.text_area(t("assistant_guidance"), value=assistant_text, height=250, key="assistant_output")
|
| 501 |
|
|
|
|
| 502 |
# Chat follow-ups
|
| 503 |
st.subheader(("Ask follow-up questions" if st.session_state.lang == "en" else "Hỏi thêm"))
|
| 504 |
st.markdown(("Ask the assistant further questions related to the victim or care. Keep questions concise." if st.session_state.lang == "en" else "Hỏi trợ lý các câu liên quan tới nạn nhân hoặc chăm sóc. Giữ câu hỏi ngắn."))
|
|
|
|
| 423 |
if st.button("🔄 " + ("Refresh Firebase data" if st.session_state.lang == "en" else "Làm mới dữ liệu Firebase")):
|
| 424 |
render_latest_firebase_data(show_toast=True)
|
| 425 |
|
| 426 |
+
# -----------------------
|
| 427 |
+
# Advanced assistance block (fixed: adds weight/height, VN/EN, saves to victim profile)
|
| 428 |
+
# -----------------------
|
| 429 |
if st.session_state.get("basic_done") and st.session_state.get("wound_type"):
|
| 430 |
st.header("Advanced assistance")
|
| 431 |
st.markdown(f"**Wound type:** `{st.session_state.wound_type}`")
|
|
|
|
| 433 |
with st.form("victim_form", clear_on_submit=True):
|
| 434 |
st.subheader(t("victim_name"))
|
| 435 |
name = st.text_input(t("victim_name"))
|
| 436 |
+
phone = st.text_input(t("phone"),
|
| 437 |
+
help=("Emergency contact number" if st.session_state.lang == "en" else "Số liên hệ khẩn cấp"))
|
| 438 |
+
age = st.text_input(t("age"),
|
| 439 |
+
help=("Enter an integer or leave blank" if st.session_state.lang == "en" else "Nhập số nguyên hoặc để trống"))
|
| 440 |
+
# new localized weight / height fields
|
| 441 |
+
weight = st.text_input(
|
| 442 |
+
(t("weight") if "weight" in TRANSLATIONS else "Weight (kg)"),
|
| 443 |
+
help=(t("weight_help") if "weight_help" in TRANSLATIONS else ("Enter a number or leave blank" if st.session_state.lang == "en" else "Nhập số hoặc để trống"))
|
| 444 |
+
)
|
| 445 |
+
height = st.text_input(
|
| 446 |
+
(t("height") if "height" in TRANSLATIONS else "Height (cm)"),
|
| 447 |
+
help=(t("height_help") if "height_help" in TRANSLATIONS else ("Enter a number or leave blank" if st.session_state.lang == "en" else "Nhập số hoặc để trống"))
|
| 448 |
+
)
|
| 449 |
+
|
| 450 |
+
# localized notes label (falls back if t("notes") missing)
|
| 451 |
+
notes_label = t("notes") if "notes" in TRANSLATIONS else (
|
| 452 |
+
"Notes (allergies, meds, conscious status)" if st.session_state.lang == "en"
|
| 453 |
+
else "Ghi chú thêm (dị ứng, thuốc đang dùng, tình trạng tỉnh táo)"
|
| 454 |
+
)
|
| 455 |
+
notes = st.text_area(notes_label, max_chars=500)
|
| 456 |
|
| 457 |
col1, col2 = st.columns(2)
|
| 458 |
with col1:
|
|
|
|
| 460 |
with col2:
|
| 461 |
emergency_submit = st.form_submit_button(t("emergency_btn"))
|
| 462 |
|
| 463 |
+
# common validation (now parses weight & height as floats)
|
| 464 |
+
def validate_fields(age_str, phone_str, weight_str, height_str):
|
| 465 |
age_v = None
|
| 466 |
+
weight_v = None
|
| 467 |
+
height_v = None
|
| 468 |
+
|
| 469 |
+
# age
|
| 470 |
if age_str and age_str.strip():
|
| 471 |
try:
|
| 472 |
age_v = int(age_str.strip())
|
| 473 |
except Exception:
|
| 474 |
+
st.error(("Age must be an integer (or leave blank)." if st.session_state.lang == "en"
|
| 475 |
+
else "Tuổi phải là số nguyên (hoặc để trống)."))
|
| 476 |
+
st.stop()
|
| 477 |
+
|
| 478 |
+
# weight
|
| 479 |
+
if weight_str and weight_str.strip():
|
| 480 |
+
try:
|
| 481 |
+
weight_v = float(weight_str.strip())
|
| 482 |
+
except Exception:
|
| 483 |
+
st.error(("Weight must be a number (kg) or leave blank." if st.session_state.lang == "en"
|
| 484 |
+
else "Cân nặng phải là số (kg) hoặc để trống."))
|
| 485 |
st.stop()
|
| 486 |
+
|
| 487 |
+
# height
|
| 488 |
+
if height_str and height_str.strip():
|
| 489 |
+
try:
|
| 490 |
+
height_v = float(height_str.strip())
|
| 491 |
+
except Exception:
|
| 492 |
+
st.error(("Height must be a number (cm) or leave blank." if st.session_state.lang == "en"
|
| 493 |
+
else "Chiều cao phải là số (cm) hoặc để trống."))
|
| 494 |
+
st.stop()
|
| 495 |
+
|
| 496 |
+
# phone
|
| 497 |
phone_clean = phone_str.strip()
|
| 498 |
if phone_clean and not phone_clean.replace("+", "").isdigit():
|
| 499 |
+
st.error(("Phone number should contain digits only." if st.session_state.lang == "en"
|
| 500 |
+
else "Số điện thoại chỉ chứa chữ số."))
|
| 501 |
st.stop()
|
| 502 |
+
|
| 503 |
+
return age_v, weight_v, height_v, phone_clean
|
| 504 |
|
| 505 |
if (submit or emergency_submit) and not st.session_state.victim_saved:
|
| 506 |
+
# validate including weight/height
|
| 507 |
+
age_v, weight_v, height_v, phone_clean = validate_fields(age, phone, weight, height)
|
| 508 |
+
|
| 509 |
victim = {
|
| 510 |
"name": name or "unknown",
|
| 511 |
"phone": phone_clean or None,
|
| 512 |
"age": age_v,
|
| 513 |
+
"weight_kg": weight_v,
|
| 514 |
+
"height_cm": height_v,
|
| 515 |
"notes": notes or "",
|
| 516 |
"wound_type": st.session_state.wound_type,
|
| 517 |
"saved_at": datetime.utcnow().isoformat() + "Z",
|
| 518 |
"emergency": bool(emergency_submit),
|
| 519 |
}
|
| 520 |
+
|
| 521 |
try:
|
| 522 |
record = save_victim_info(victim)
|
| 523 |
st.session_state.last_saved_record = record
|
| 524 |
st.session_state.victim_saved = True
|
| 525 |
if emergency_submit:
|
| 526 |
+
st.error(("EMERGENCY recorded. Call local emergency services now." if st.session_state.lang == "en"
|
| 527 |
+
else "Đã ghi nhận KHẨN CẤP. Gọi dịch vụ khẩn cấp ngay."))
|
| 528 |
else:
|
| 529 |
st.success(("Victim info saved." if st.session_state.lang == "en" else "Đã lưu thông tin nạn nhân."))
|
| 530 |
except Exception as e:
|
|
|
|
| 534 |
# For non-emergency: ask OpenAI for guidance
|
| 535 |
if submit and st.session_state.victim_saved:
|
| 536 |
system_prompt = make_system_prompt(st.session_state.wound_type, victim)
|
| 537 |
+
initial_user_msg = (
|
| 538 |
+
"The patient has completed the basic steps. Provide the next, in-depth first aid guidance and any monitoring steps. Keep guidance concise and list immediate priorities first."
|
| 539 |
+
if st.session_state.lang == "en"
|
| 540 |
+
else "Bệnh nhân đã hoàn thành các bước cơ bản. Cung cấp hướng dẫn sơ cứu chi tiết tiếp theo và các bước giám sát. Giữ gọn và nêu ưu tiên trước."
|
| 541 |
+
)
|
| 542 |
with st.spinner(("Contacting assistant..." if st.session_state.lang == "en" else "Đang liên hệ trợ lý...")):
|
| 543 |
resp = query_openai(system_prompt, initial_user_msg)
|
| 544 |
if "error" in resp:
|
|
|
|
| 550 |
st.markdown("**" + t("assistant_guidance") + "**")
|
| 551 |
st.text_area(t("assistant_guidance"), value=assistant_text, height=250, key="assistant_output")
|
| 552 |
|
| 553 |
+
|
| 554 |
# Chat follow-ups
|
| 555 |
st.subheader(("Ask follow-up questions" if st.session_state.lang == "en" else "Hỏi thêm"))
|
| 556 |
st.markdown(("Ask the assistant further questions related to the victim or care. Keep questions concise." if st.session_state.lang == "en" else "Hỏi trợ lý các câu liên quan tới nạn nhân hoặc chăm sóc. Giữ câu hỏi ngắn."))
|