Initial commit: HealthCarePregnant project documentation and platform

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
selfrelease
2026-06-18 09:48:05 +08:00
commit eab91174db
301 changed files with 42491 additions and 0 deletions
@@ -0,0 +1,96 @@
import { useCallback, useEffect, useState } from 'react';
import {
Activity,
Armchair,
Bell,
CalendarCheck,
Droplet,
Footprints,
Pill,
type LucideIcon,
} from 'lucide-react';
import { api, ApiError } from '../api/client';
import { useAuth } from '../auth/AuthContext';
import { usePatient } from '../lib/usePatient';
import { useAutoRefresh } from '../lib/useAutoRefresh';
import { BindPatient } from '../components/BindPatient';
import type { Reminder } from '../api/types';
import { formatTime, reminderLabel } from '../lib/format';
import './RemindersPage.css';
const TYPE_ICON: Record<string, LucideIcon> = {
measurement: Activity,
water: Droplet,
exercise: Footprints,
rest: Armchair,
checkup: CalendarCheck,
medication: Pill,
};
export function RemindersPage(): JSX.Element {
const { boundPatientId } = useAuth();
const { patient, loading, reload } = usePatient();
const [reminders, setReminders] = useState<Reminder[]>([]);
const [err, setErr] = useState<string | null>(null);
const load = useCallback(() => {
if (!boundPatientId) return;
api
.listReminders(boundPatientId)
.then((list) => setReminders([...list].reverse()))
.catch((e) => setErr(e instanceof ApiError ? e.message : '加载提醒失败'));
}, [boundPatientId]);
useEffect(() => {
load();
}, [load]);
// 多端一致:管理师下发提醒近实时出现
useAutoRefresh(load);
if (!boundPatientId || (!patient && !loading)) {
return (
<div className="page">
<h1 className="section-title" style={{ marginTop: 0 }}>
</h1>
<BindPatient onBound={reload} />
</div>
);
}
return (
<div className="page">
<h1 className="section-title" style={{ marginTop: 0 }}>
怀
</h1>
<p className="muted" style={{ marginBottom: 'var(--space-4)' }}>
{patient ? `${patient.name} 的孕期提醒,方便你协助陪伴。` : ''}
</p>
{err && <p className="muted">{err}</p>}
{reminders.length === 0 ? (
<p className="muted"></p>
) : (
reminders.map((r) => {
const Icon = TYPE_ICON[r.effectiveType] ?? Bell;
return (
<div key={r.id} className="rem-card">
<span className="rem-card__icon">
<Icon size={26} strokeWidth={1.75} />
</span>
<div className="rem-card__body">
<p className="rem-card__title">
{reminderLabel(r.effectiveType)}
{r.adjustedForRisk && <span className="badge badge-warn"></span>}
</p>
<p className="rem-card__msg muted">{r.message}</p>
<p className="rem-card__time muted">{formatTime(r.scheduledAt)}</p>
</div>
</div>
);
})
)}
</div>
);
}