Add full CRUD for Medicine, Allergies, Doctor Visits, Illness
- Renamed Visits to Doctor Visit - Medicine: add edit delete with name, dose, notes, reminder time - Allergies: add edit delete with severity (mild/moderate/severe) - Doctor Visit: add edit delete with doctor, reason, date, notes - Illness: add edit delete with start/end dates - All data persists to localStorage Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
e1bd89e664
commit
a1b436710f
1 changed files with 521 additions and 61 deletions
|
|
@ -2,6 +2,37 @@
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
interface Medicine {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
dose: string;
|
||||||
|
notes: string;
|
||||||
|
reminderTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Allergy {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
severity: string;
|
||||||
|
notes: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Visit {
|
||||||
|
id: string;
|
||||||
|
doctorName: string;
|
||||||
|
reason: string;
|
||||||
|
date: string;
|
||||||
|
notes: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Illness {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
startDate: string;
|
||||||
|
endDate?: string;
|
||||||
|
notes: string;
|
||||||
|
}
|
||||||
|
|
||||||
// IAP Vaccination Schedule (India)
|
// IAP Vaccination Schedule (India)
|
||||||
const IAP_SCHEDULE = [
|
const IAP_SCHEDULE = [
|
||||||
{ name: "BCG", weeks: 0 },
|
{ name: "BCG", weeks: 0 },
|
||||||
|
|
@ -48,6 +79,218 @@ export default function MedicalPage() {
|
||||||
const [showReminder, setShowReminder] = useState<string | null>(null);
|
const [showReminder, setShowReminder] = useState<string | null>(null);
|
||||||
const [reminderTime, setReminderTime] = useState("08:00");
|
const [reminderTime, setReminderTime] = useState("08:00");
|
||||||
|
|
||||||
|
// CRUD state for medicine, allergies, visits, illness
|
||||||
|
const [medicines, setMedicines] = useState<Medicine[]>([]);
|
||||||
|
const [allergies, setAllergies] = useState<Allergy[]>([]);
|
||||||
|
const [visits, setVisits] = useState<Visit[]>([]);
|
||||||
|
const [illnesses, setIllnesses] = useState<Illness[]>([]);
|
||||||
|
|
||||||
|
// Add/Edit mode
|
||||||
|
const [editingMed, setEditingMed] = useState<Medicine | null>(null);
|
||||||
|
const [editingAllergy, setEditingAllergy] = useState<Allergy | null>(null);
|
||||||
|
const [editingVisit, setEditingVisit] = useState<Visit | null>(null);
|
||||||
|
const [editingIllness, setEditingIllness] = useState<Illness | null>(null);
|
||||||
|
const [showAddMed, setShowAddMed] = useState(false);
|
||||||
|
const [showAddAllergy, setShowAddAllergy] = useState(false);
|
||||||
|
const [showAddVisit, setShowAddVisit] = useState(false);
|
||||||
|
const [showAddIllness, setShowAddIllness] = useState(false);
|
||||||
|
|
||||||
|
// Form state for new items
|
||||||
|
const [newMedName, setNewMedName] = useState("");
|
||||||
|
const [newMedDose, setNewMedDose] = useState("");
|
||||||
|
const [newMedNotes, setNewMedNotes] = useState("");
|
||||||
|
const [newAllergyName, setNewAllergyName] = useState("");
|
||||||
|
const [newAllergySeverity, setNewAllergySeverity] = useState("mild");
|
||||||
|
const [newAllergyNotes, setNewAllergyNotes] = useState("");
|
||||||
|
const [newVisitDoctor, setNewVisitDoctor] = useState("");
|
||||||
|
const [newVisitReason, setNewVisitReason] = useState("");
|
||||||
|
const [newVisitDate, setNewVisitDate] = useState("");
|
||||||
|
const [newVisitNotes, setNewVisitNotes] = useState("");
|
||||||
|
const [newIllnessName, setNewIllnessName] = useState("");
|
||||||
|
const [newIllnessStart, setNewIllnessStart] = useState("");
|
||||||
|
const [newIllnessEnd, setNewIllnessEnd] = useState("");
|
||||||
|
const [newIllnessNotes, setNewIllnessNotes] = useState("");
|
||||||
|
|
||||||
|
// Load data from localStorage on mount
|
||||||
|
useEffect(() => {
|
||||||
|
// Load medicines
|
||||||
|
const savedMeds = localStorage.getItem("tia_medicines");
|
||||||
|
if (savedMeds) setMedicines(JSON.parse(savedMeds));
|
||||||
|
|
||||||
|
const savedAllergies = localStorage.getItem("tia_allergies");
|
||||||
|
if (savedAllergies) setAllergies(JSON.parse(savedAllergies));
|
||||||
|
|
||||||
|
const savedVisits = localStorage.getItem("tia_visits");
|
||||||
|
if (savedVisits) setVisits(JSON.parse(savedVisits));
|
||||||
|
|
||||||
|
const savedIllnesses = localStorage.getItem("tia_illnesses");
|
||||||
|
if (savedIllnesses) setIllnesses(JSON.parse(savedIllnesses));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Medicine CRUD
|
||||||
|
const saveMedicine = () => {
|
||||||
|
if (!newMedName) return;
|
||||||
|
const newItem: Medicine = {
|
||||||
|
id: editingMed?.id || Date.now().toString(),
|
||||||
|
name: newMedName,
|
||||||
|
dose: newMedDose,
|
||||||
|
notes: newMedNotes,
|
||||||
|
reminderTime: reminderTime,
|
||||||
|
};
|
||||||
|
const updated = editingMed
|
||||||
|
? medicines.map((m) => (m.id === editingMed.id ? newItem : m))
|
||||||
|
: [...medicines, newItem];
|
||||||
|
setMedicines(updated);
|
||||||
|
localStorage.setItem("tia_medicines", JSON.stringify(updated));
|
||||||
|
resetMedForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteMedicine = (id: string) => {
|
||||||
|
const updated = medicines.filter((m) => m.id !== id);
|
||||||
|
setMedicines(updated);
|
||||||
|
localStorage.setItem("tia_medicines", JSON.stringify(updated));
|
||||||
|
};
|
||||||
|
|
||||||
|
const editMedicine = (med: Medicine) => {
|
||||||
|
setEditingMed(med);
|
||||||
|
setNewMedName(med.name);
|
||||||
|
setNewMedDose(med.dose);
|
||||||
|
setNewMedNotes(med.notes);
|
||||||
|
setReminderTime(med.reminderTime || "08:00");
|
||||||
|
setShowAddMed(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetMedForm = () => {
|
||||||
|
setEditingMed(null);
|
||||||
|
setNewMedName("");
|
||||||
|
setNewMedDose("");
|
||||||
|
setNewMedNotes("");
|
||||||
|
setShowAddMed(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allergy CRUD
|
||||||
|
const saveAllergy = () => {
|
||||||
|
if (!newAllergyName) return;
|
||||||
|
const newItem: Allergy = {
|
||||||
|
id: editingAllergy?.id || Date.now().toString(),
|
||||||
|
name: newAllergyName,
|
||||||
|
severity: newAllergySeverity,
|
||||||
|
notes: newAllergyNotes,
|
||||||
|
};
|
||||||
|
const updated = editingAllergy
|
||||||
|
? allergies.map((a) => (a.id === editingAllergy.id ? newItem : a))
|
||||||
|
: [...allergies, newItem];
|
||||||
|
setAllergies(updated);
|
||||||
|
localStorage.setItem("tia_allergies", JSON.stringify(updated));
|
||||||
|
resetAllergyForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteAllergy = (id: string) => {
|
||||||
|
const updated = allergies.filter((a) => a.id !== id);
|
||||||
|
setAllergies(updated);
|
||||||
|
localStorage.setItem("tia_allergies", JSON.stringify(updated));
|
||||||
|
};
|
||||||
|
|
||||||
|
const editAllergy = (allergy: Allergy) => {
|
||||||
|
setEditingAllergy(allergy);
|
||||||
|
setNewAllergyName(allergy.name);
|
||||||
|
setNewAllergySeverity(allergy.severity);
|
||||||
|
setNewAllergyNotes(allergy.notes);
|
||||||
|
setShowAddAllergy(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetAllergyForm = () => {
|
||||||
|
setEditingAllergy(null);
|
||||||
|
setNewAllergyName("");
|
||||||
|
setNewAllergySeverity("mild");
|
||||||
|
setNewAllergyNotes("");
|
||||||
|
setShowAddAllergy(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Visit CRUD
|
||||||
|
const saveVisit = () => {
|
||||||
|
if (!newVisitDoctor) return;
|
||||||
|
const newItem: Visit = {
|
||||||
|
id: editingVisit?.id || Date.now().toString(),
|
||||||
|
doctorName: newVisitDoctor,
|
||||||
|
reason: newVisitReason,
|
||||||
|
date: newVisitDate || new Date().toISOString().split("T")[0],
|
||||||
|
notes: newVisitNotes,
|
||||||
|
};
|
||||||
|
const updated = editingVisit
|
||||||
|
? visits.map((v) => (v.id === editingVisit.id ? newItem : v))
|
||||||
|
: [...visits, newItem];
|
||||||
|
setVisits(updated);
|
||||||
|
localStorage.setItem("tia_visits", JSON.stringify(updated));
|
||||||
|
resetVisitForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteVisit = (id: string) => {
|
||||||
|
const updated = visits.filter((v) => v.id !== id);
|
||||||
|
setVisits(updated);
|
||||||
|
localStorage.setItem("tia_visits", JSON.stringify(updated));
|
||||||
|
};
|
||||||
|
|
||||||
|
const editVisit = (visit: Visit) => {
|
||||||
|
setEditingVisit(visit);
|
||||||
|
setNewVisitDoctor(visit.doctorName);
|
||||||
|
setNewVisitReason(visit.reason);
|
||||||
|
setNewVisitDate(visit.date);
|
||||||
|
setNewVisitNotes(visit.notes);
|
||||||
|
setShowAddVisit(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetVisitForm = () => {
|
||||||
|
setEditingVisit(null);
|
||||||
|
setNewVisitDoctor("");
|
||||||
|
setNewVisitReason("");
|
||||||
|
setNewVisitDate("");
|
||||||
|
setNewVisitNotes("");
|
||||||
|
setShowAddVisit(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Illness CRUD
|
||||||
|
const saveIllness = () => {
|
||||||
|
if (!newIllnessName) return;
|
||||||
|
const newItem: Illness = {
|
||||||
|
id: editingIllness?.id || Date.now().toString(),
|
||||||
|
name: newIllnessName,
|
||||||
|
startDate: newIllnessStart || new Date().toISOString().split("T")[0],
|
||||||
|
endDate: newIllnessEnd || undefined,
|
||||||
|
notes: newIllnessNotes,
|
||||||
|
};
|
||||||
|
const updated = editingIllness
|
||||||
|
? illnesses.map((i) => (i.id === editingIllness.id ? newItem : i))
|
||||||
|
: [...illnesses, newItem];
|
||||||
|
setIllnesses(updated);
|
||||||
|
localStorage.setItem("tia_illnesses", JSON.stringify(updated));
|
||||||
|
resetIllnessForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteIllness = (id: string) => {
|
||||||
|
const updated = illnesses.filter((i) => i.id !== id);
|
||||||
|
setIllnesses(updated);
|
||||||
|
localStorage.setItem("tia_illnesses", JSON.stringify(updated));
|
||||||
|
};
|
||||||
|
|
||||||
|
const editIllness = (illness: Illness) => {
|
||||||
|
setEditingIllness(illness);
|
||||||
|
setNewIllnessName(illness.name);
|
||||||
|
setNewIllnessStart(illness.startDate);
|
||||||
|
setNewIllnessEnd(illness.endDate || "");
|
||||||
|
setNewIllnessNotes(illness.notes);
|
||||||
|
setShowAddIllness(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetIllnessForm = () => {
|
||||||
|
setEditingIllness(null);
|
||||||
|
setNewIllnessName("");
|
||||||
|
setNewIllnessStart("");
|
||||||
|
setNewIllnessEnd("");
|
||||||
|
setNewIllnessNotes("");
|
||||||
|
setShowAddIllness(false);
|
||||||
|
};
|
||||||
|
|
||||||
// Reminder save handler
|
// Reminder save handler
|
||||||
const handleSetReminder = (medName: string) => {
|
const handleSetReminder = (medName: string) => {
|
||||||
// In production, save to database with reminder time
|
// In production, save to database with reminder time
|
||||||
|
|
@ -134,7 +377,7 @@ const SUPPLEMENTS = [
|
||||||
onClick={() => setTab("visits")}
|
onClick={() => setTab("visits")}
|
||||||
className={`px-4 p-3 rounded-xl ${tab === "visits" ? "bg-rose-400 text-white" : "bg-white"}`}
|
className={`px-4 p-3 rounded-xl ${tab === "visits" ? "bg-rose-400 text-white" : "bg-white"}`}
|
||||||
>
|
>
|
||||||
Visits
|
Doctor Visit
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setTab("illness")}
|
onClick={() => setTab("illness")}
|
||||||
|
|
@ -212,86 +455,303 @@ const SUPPLEMENTS = [
|
||||||
|
|
||||||
{tab === "medicine" && (
|
{tab === "medicine" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h2 className="font-semibold mb-3">Supplements & Medicine</h2>
|
<h2 className="font-semibold mb-3">Medicine & Supplements</h2>
|
||||||
{SUPPLEMENTS.map((supp) => (
|
|
||||||
<div key={supp.name} className="p-4 bg-white rounded-xl">
|
{/* Add Form */}
|
||||||
<div className="flex items-center justify-between">
|
{showAddMed && (
|
||||||
<div className="flex-1">
|
<div className="p-4 bg-white rounded-xl space-y-3">
|
||||||
<div className="font-medium">{supp.name}</div>
|
<input
|
||||||
<div className="text-sm text-gray-500">
|
type="text"
|
||||||
{supp.dose} · {supp.notes}
|
value={newMedName}
|
||||||
</div>
|
onChange={(e) => setNewMedName(e.target.value)}
|
||||||
</div>
|
placeholder="Medicine name"
|
||||||
<div className="flex gap-2">
|
className="w-full p-2 border rounded-lg"
|
||||||
{showReminder === supp.name ? (
|
/>
|
||||||
<div className="flex items-center gap-2">
|
<input
|
||||||
<input
|
type="text"
|
||||||
type="time"
|
value={newMedDose}
|
||||||
value={reminderTime}
|
onChange={(e) => setNewMedDose(e.target.value)}
|
||||||
onChange={(e) => setReminderTime(e.target.value)}
|
placeholder="Dose (e.g., 5ml, 1 tablet)"
|
||||||
className="p-1 text-sm border rounded"
|
className="w-full p-2 border rounded-lg"
|
||||||
/>
|
/>
|
||||||
<button
|
<input
|
||||||
onClick={() => handleSetReminder(supp.name)}
|
type="text"
|
||||||
className="px-2 py-1 bg-rose-400 text-white rounded text-sm"
|
value={newMedNotes}
|
||||||
>
|
onChange={(e) => setNewMedNotes(e.target.value)}
|
||||||
✓
|
placeholder="Notes"
|
||||||
</button>
|
className="w-full p-2 border rounded-lg"
|
||||||
<button
|
/>
|
||||||
onClick={() => setShowReminder(null)}
|
<div className="flex gap-2">
|
||||||
className="text-gray-400"
|
<button onClick={saveMedicine} className="flex-1 py-2 bg-rose-400 text-white rounded-lg">
|
||||||
>
|
{editingMed ? "Update" : "Add"}
|
||||||
✕
|
</button>
|
||||||
</button>
|
<button onClick={resetMedForm} className="flex-1 py-2 bg-gray-200 rounded-lg">
|
||||||
</div>
|
Cancel
|
||||||
) : (
|
</button>
|
||||||
<button
|
|
||||||
onClick={() => setShowReminder(supp.name)}
|
|
||||||
className="px-3 py-1 bg-gray-100 rounded-lg text-sm"
|
|
||||||
>
|
|
||||||
⏰
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
)}
|
||||||
|
|
||||||
|
{medicines.length === 0 && !showAddMed ? (
|
||||||
|
<div className="p-4 bg-white rounded-xl">
|
||||||
|
<p className="text-gray-500">No medicines added</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
medicines.map((med) => (
|
||||||
|
<div key={med.id} className="p-4 bg-white rounded-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-medium">{med.name}</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{med.dose} {med.notes && `· ${med.notes}`}
|
||||||
|
{med.reminderTime && ` · ⏰ ${med.reminderTime}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={() => editMedicine(med)} className="p-2 text-gray-400">✏️</button>
|
||||||
|
<button onClick={() => deleteMedicine(med.id)} className="p-2 text-red-400">🗑️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!showAddMed && (
|
||||||
|
<button onClick={() => setShowAddMed(true)} className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
||||||
|
+ Add Medicine
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{tab === "allergies" && (
|
{tab === "allergies" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h2 className="font-semibold mb-3">Known Allergies</h2>
|
<h2 className="font-semibold mb-3">Known Allergies</h2>
|
||||||
<div className="p-4 bg-white rounded-xl">
|
|
||||||
<p className="text-gray-500">No allergies recorded</p>
|
{showAddAllergy && (
|
||||||
</div>
|
<div className="p-4 bg-white rounded-xl space-y-3">
|
||||||
<button className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
<input
|
||||||
+ Add Allergy
|
type="text"
|
||||||
</button>
|
value={newAllergyName}
|
||||||
|
onChange={(e) => setNewAllergyName(e.target.value)}
|
||||||
|
placeholder="Allergy name (e.g., Peanut, Milk)"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<select
|
||||||
|
value={newAllergySeverity}
|
||||||
|
onChange={(e) => setNewAllergySeverity(e.target.value)}
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
>
|
||||||
|
<option value="mild">Mild</option>
|
||||||
|
<option value="moderate">Moderate</option>
|
||||||
|
<option value="severe">Severe</option>
|
||||||
|
</select>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={newAllergyNotes}
|
||||||
|
onChange={(e) => setNewAllergyNotes(e.target.value)}
|
||||||
|
placeholder="Notes"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={saveAllergy} className="flex-1 py-2 bg-rose-400 text-white rounded-lg">
|
||||||
|
{editingAllergy ? "Update" : "Add"}
|
||||||
|
</button>
|
||||||
|
<button onClick={resetAllergyForm} className="flex-1 py-2 bg-gray-200 rounded-lg">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{allergies.length === 0 && !showAddAllergy ? (
|
||||||
|
<div className="p-4 bg-white rounded-xl">
|
||||||
|
<p className="text-gray-500">No allergies recorded</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
allergies.map((allergy) => (
|
||||||
|
<div key={allergy.id} className="p-4 bg-white rounded-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-medium">{allergy.name}</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
<span className={allergy.severity === "severe" ? "text-red-500" : "text-orange-500"}>
|
||||||
|
{allergy.severity.toUpperCase()}
|
||||||
|
</span>
|
||||||
|
{allergy.notes && ` · ${allergy.notes}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={() => editAllergy(allergy)} className="p-2 text-gray-400">✏️</button>
|
||||||
|
<button onClick={() => deleteAllergy(allergy.id)} className="p-2 text-red-400">🗑️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!showAddAllergy && (
|
||||||
|
<button onClick={() => setShowAddAllergy(true)} className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
||||||
|
+ Add Allergy
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{tab === "visits" && (
|
{tab === "visits" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h2 className="font-semibold mb-3">Doctor Visits</h2>
|
<h2 className="font-semibold mb-3">Doctor Visits</h2>
|
||||||
<div className="p-4 bg-white rounded-xl">
|
|
||||||
<p className="text-gray-500">No visits recorded</p>
|
{showAddVisit && (
|
||||||
</div>
|
<div className="p-4 bg-white rounded-xl space-y-3">
|
||||||
<button className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
<input
|
||||||
+ Add Visit
|
type="text"
|
||||||
</button>
|
value={newVisitDoctor}
|
||||||
|
onChange={(e) => setNewVisitDoctor(e.target.value)}
|
||||||
|
placeholder="Doctor name"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={newVisitReason}
|
||||||
|
onChange={(e) => setNewVisitReason(e.target.value)}
|
||||||
|
placeholder="Reason (e.g., Checkup, Fever)"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={newVisitDate}
|
||||||
|
onChange={(e) => setNewVisitDate(e.target.value)}
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={newVisitNotes}
|
||||||
|
onChange={(e) => setNewVisitNotes(e.target.value)}
|
||||||
|
placeholder="Notes"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={saveVisit} className="flex-1 py-2 bg-rose-400 text-white rounded-lg">
|
||||||
|
{editingVisit ? "Update" : "Add"}
|
||||||
|
</button>
|
||||||
|
<button onClick={resetVisitForm} className="flex-1 py-2 bg-gray-200 rounded-lg">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{visits.length === 0 && !showAddVisit ? (
|
||||||
|
<div className="p-4 bg-white rounded-xl">
|
||||||
|
<p className="text-gray-500">No visits recorded</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
visits.map((visit) => (
|
||||||
|
<div key={visit.id} className="p-4 bg-white rounded-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-medium">{visit.doctorName}</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{new Date(visit.date).toLocaleDateString()}
|
||||||
|
{visit.reason && ` · ${visit.reason}`}
|
||||||
|
{visit.notes && ` · ${visit.notes}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={() => editVisit(visit)} className="p-2 text-gray-400">✏️</button>
|
||||||
|
<button onClick={() => deleteVisit(visit.id)} className="p-2 text-red-400">🗑️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!showAddVisit && (
|
||||||
|
<button onClick={() => setShowAddVisit(true)} className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
||||||
|
+ Add Visit
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{tab === "illness" && (
|
{tab === "illness" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h2 className="font-semibold mb-3">Illness Log</h2>
|
<h2 className="font-semibold mb-3">Illness Log</h2>
|
||||||
<div className="p-4 bg-white rounded-xl">
|
|
||||||
<p className="text-gray-500">No illnesses recorded</p>
|
{showAddIllness && (
|
||||||
</div>
|
<div className="p-4 bg-white rounded-xl space-y-3">
|
||||||
<button className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
<input
|
||||||
+ Log Illness
|
type="text"
|
||||||
</button>
|
value={newIllnessName}
|
||||||
|
onChange={(e) => setNewIllnessName(e.target.value)}
|
||||||
|
placeholder="Illness (e.g., Cold, Fever, Flu)"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<div className="grid grid-cols-2 gap-2">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={newIllnessStart}
|
||||||
|
onChange={(e) => setNewIllnessStart(e.target.value)}
|
||||||
|
placeholder="Start date"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={newIllnessEnd}
|
||||||
|
onChange={(e) => setNewIllnessEnd(e.target.value)}
|
||||||
|
placeholder="End date"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={newIllnessNotes}
|
||||||
|
onChange={(e) => setNewIllnessNotes(e.target.value)}
|
||||||
|
placeholder="Notes"
|
||||||
|
className="w-full p-2 border rounded-lg"
|
||||||
|
/>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={saveIllness} className="flex-1 py-2 bg-rose-400 text-white rounded-lg">
|
||||||
|
{editingIllness ? "Update" : "Add"}
|
||||||
|
</button>
|
||||||
|
<button onClick={resetIllnessForm} className="flex-1 py-2 bg-gray-200 rounded-lg">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{illnesses.length === 0 && !showAddIllness ? (
|
||||||
|
<div className="p-4 bg-white rounded-xl">
|
||||||
|
<p className="text-gray-500">No illnesses recorded</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
illnesses.map((illness) => (
|
||||||
|
<div key={illness.id} className="p-4 bg-white rounded-xl">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="font-medium">{illness.name}</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
|
{new Date(illness.startDate).toLocaleDateString()}
|
||||||
|
{illness.endDate && ` - ${new Date(illness.endDate).toLocaleDateString()}`}
|
||||||
|
{illness.notes && ` · ${illness.notes}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button onClick={() => editIllness(illness)} className="p-2 text-gray-400">✏️</button>
|
||||||
|
<button onClick={() => deleteIllness(illness.id)} className="p-2 text-red-400">🗑️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!showAddIllness && (
|
||||||
|
<button onClick={() => setShowAddIllness(true)} className="w-full p-4 border-2 border-dashed border-gray-300 rounded-xl text-gray-500">
|
||||||
|
+ Log Illness
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue