Initial commit: HealthManager full-stack health management platform

Backend: .NET 10 + PostgreSQL + EF Core + JWT + SignalR
Frontend patient: React 19 + TypeScript + Vite (mobile H5)
Frontend doctor: React 19 + TypeScript + Vite (desktop web)
This commit is contained in:
MingNian
2026-05-20 16:18:56 +08:00
commit 435af55c4a
215 changed files with 18595 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from '@/components/common/Button';
import { Input } from '@/components/common/Input';
import { PageHeader } from '@/components/layout/PageHeader';
import { ToastContainer, toast } from '@/components/common/Toast';
import * as followupService from '@/services/followup.service';
import styles from './FollowUpEditPage.module.css';
export function FollowUpEditPage() {
const navigate = useNavigate();
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [doctorName, setDoctorName] = useState('');
const [scheduledAt, setScheduledAt] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
if (!title) { toast('请填写标题', 'error'); return; }
setLoading(true);
await followupService.addFollowUp({
title, description,
scheduledAt: scheduledAt || new Date().toISOString(),
status: 'upcoming',
reminderEnabled: true,
});
toast('添加成功');
navigate(-1);
};
return (
<div className="page--no-tab">
<PageHeader title="新增复查" />
<div className={styles.form}>
<Input label="复查标题" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="如PCI术后3个月复查" />
<Input label="医生" value={doctorName} onChange={(e) => setDoctorName(e.target.value)} placeholder="医生姓名" />
<Input label="描述" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="复查描述" />
<Input label="复查时间" value={scheduledAt} onChange={(e) => setScheduledAt(e.target.value)} type="datetime-local" />
<div className={styles.textareaWrap}>
<label className={styles.label}></label>
<textarea className={styles.textarea} value={description} onChange={(e) => setDescription(e.target.value)} placeholder="复查说明..." rows={3} />
</div>
<Button variant="primary" size="lg" fullWidth loading={loading} onClick={handleSubmit}></Button>
</div>
<ToastContainer />
</div>
);
}