Files
AI-Health/doctor_web/src/components/layout/DoctorLayout.tsx
MingNian d0d7d8428d feat: 医生端Web后台 + SignalR实时问诊
- 新增 doctor_web/ React前端 (dashboard/患者/问诊/报告/随访)
- 后端新增 doctor_endpoints (14个医生API) + ConsultationHub (SignalR)
- Flutter端 SignalR 替换轮询实现实时聊天
2026-06-05 17:46:07 +08:00

71 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
}