fix(admin): render medical history with each section's real shape
The medical sections in other are structured objects, not flat strings:
allergies {substance,reaction,severity}, medications {name,dose,frequency},
surgeries {type,year,hospital}, family_history {relation,disease}, disease
{id,name,status}. The admin view printed raw JSON for all but disease.
Give each section a formatter, and for disease show only entries marked
active (status true) instead of the full 30-item checklist.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -53,12 +53,19 @@ interface UserProfileData {
|
||||
const GENDER_LABELS: Record<string, string> = { male: 'مرد', female: 'زن' };
|
||||
const MARITAL_LABELS: Record<string, string> = { married: 'متاهل', single: 'مجرد' };
|
||||
|
||||
const MEDICAL_SECTIONS: { key: string; label: string }[] = [
|
||||
{ key: 'allergies', label: 'آلرژیها' },
|
||||
{ key: 'medications', label: 'داروهای مصرفی' },
|
||||
{ key: 'surgeries', label: 'جراحیها' },
|
||||
{ key: 'family_history', label: 'سابقه خانوادگی بیماری' },
|
||||
{ key: 'disease', label: 'بیماریها' },
|
||||
// Each medical section stores objects with its own shape; format an item to a label.
|
||||
const MEDICAL_SECTIONS: {
|
||||
key: string;
|
||||
label: string;
|
||||
format: (item: any) => string;
|
||||
filter?: (item: any) => boolean;
|
||||
}[] = [
|
||||
{ key: 'allergies', label: 'آلرژیها', format: (i) => [i.substance, i.reaction, i.severity].filter(Boolean).join(' — ') },
|
||||
{ key: 'medications', label: 'داروهای مصرفی', format: (i) => [i.name, i.dose, i.frequency].filter(Boolean).join(' — ') },
|
||||
{ key: 'surgeries', label: 'جراحیها', format: (i) => [i.type, i.year && `سال ${i.year}`, i.hospital].filter(Boolean).join(' — ') },
|
||||
{ key: 'family_history', label: 'سابقه خانوادگی بیماری', format: (i) => [i.relation, i.disease].filter(Boolean).join(': ') },
|
||||
// disease is a fixed checklist; only show the ones marked active
|
||||
{ key: 'disease', label: 'بیماریها', format: (i) => i.name, filter: (i) => i.status === 'true' || i.status === true },
|
||||
];
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||
@@ -548,8 +555,11 @@ export default function UserDetailPage() {
|
||||
<div className="pt-2 border-t border-slate-100 dark:border-gray-700 space-y-3">
|
||||
<h3 className="text-sm font-semibold text-slate-700 dark:text-slate-300">سوابق پزشکی</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
{MEDICAL_SECTIONS.map(({ key, label }) => {
|
||||
const items = Array.isArray(profile.other?.[key]) ? (profile.other![key] as unknown[]) : [];
|
||||
{MEDICAL_SECTIONS.map(({ key, label, format, filter }) => {
|
||||
const raw = Array.isArray(profile.other?.[key]) ? (profile.other![key] as any[]) : [];
|
||||
const items = (filter ? raw.filter(filter) : raw)
|
||||
.map(format)
|
||||
.filter((s) => s && s.trim());
|
||||
return (
|
||||
<div key={key} className="p-4 rounded-xl bg-slate-50 dark:bg-gray-800/60">
|
||||
<p className="text-[11px] font-medium text-slate-400 dark:text-slate-500 uppercase tracking-wide mb-1.5">{label}</p>
|
||||
@@ -557,9 +567,9 @@ export default function UserDetailPage() {
|
||||
<p className="text-sm text-slate-400 dark:text-slate-500">موردی ثبت نشده</p>
|
||||
) : (
|
||||
<ul className="flex flex-wrap gap-1.5">
|
||||
{items.map((it, i) => (
|
||||
{items.map((text, i) => (
|
||||
<li key={i} className="text-xs px-2 py-0.5 rounded-lg bg-white dark:bg-gray-700 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-gray-600">
|
||||
{typeof it === 'string' ? it : (it as any)?.name ?? (it as any)?.title ?? JSON.stringify(it)}
|
||||
{text}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user