- 新增 doctor_web/ React前端 (dashboard/患者/问诊/报告/随访) - 后端新增 doctor_endpoints (14个医生API) + ConsultationHub (SignalR) - Flutter端 SignalR 替换轮询实现实时聊天
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { NavLink, Outlet, useLocation } from 'react-router-dom';
|
||
import { useEffect, useState } from 'react';
|
||
import { api } from '../../services/api-client';
|
||
import type { DashboardStats } from '../../types';
|
||
import styles from './DoctorLayout.module.css';
|
||
|
||
const NAV_ITEMS = [
|
||
{ to: '/dashboard', label: '工作台', icon: '📊' },
|
||
{ to: '/patients', label: '患者管理', icon: '👥' },
|
||
{ to: '/consultations', label: '在线问诊', icon: '💬' },
|
||
{ to: '/reports', label: '报告审核', icon: '📋' },
|
||
{ to: '/follow-ups', label: '复查随访', icon: '📅' },
|
||
];
|
||
|
||
export default function DoctorLayout() {
|
||
const location = useLocation();
|
||
const [doctor, setDoctor] = useState<DashboardStats | null>(null);
|
||
|
||
useEffect(() => {
|
||
api.get<DashboardStats>('/api/doctor/dashboard').then(setDoctor).catch(() => {});
|
||
}, []);
|
||
|
||
return (
|
||
<div className={styles.layout}>
|
||
{/* 侧边栏 */}
|
||
<aside className={styles.sidebar}>
|
||
<div className={styles.brand}>
|
||
<div className={styles.brandTitle}>
|
||
<span>❤️</span> 健康管家
|
||
</div>
|
||
<div className={styles.brandSub}>医生工作台</div>
|
||
</div>
|
||
|
||
<nav className={styles.nav}>
|
||
{NAV_ITEMS.map(item => (
|
||
<NavLink
|
||
key={item.to}
|
||
to={item.to}
|
||
className={({ isActive }) =>
|
||
`${styles.navItem} ${isActive ? styles.active : ''}`
|
||
}
|
||
>
|
||
<span className={styles.navIcon}>{item.icon}</span>
|
||
{item.label}
|
||
</NavLink>
|
||
))}
|
||
</nav>
|
||
|
||
<div className={styles.footer}>
|
||
<div className={styles.doctorInfo}>
|
||
<div className={styles.avatar}>
|
||
{doctor?.doctorName?.[0] ?? '王'}
|
||
</div>
|
||
<div>
|
||
<div className={styles.doctorName}>{doctor?.doctorName ?? '王建国'}</div>
|
||
<div className={styles.doctorMeta}>
|
||
{doctor?.doctorTitle ?? '主任医师'} · {doctor?.doctorDepartment ?? '心血管内科'}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
{/* 内容区 */}
|
||
<main className={styles.content} key={location.pathname}>
|
||
<Outlet />
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|