// ══════════════════════════════════════════════════════════════════
// ClinicalAI.jsx — Trang phân tích lâm sàng
// Cách tích hợp vào App.jsx hiện tại:
// 1. Copy toàn bộ component ClinicalAI bên dưới vào App.jsx
// 2. Trong state điều hướng, thêm: const [page, setPage] = useState('chat') // 'chat' | 'clinical'
// 3. Thêm nút "Clinical AI" vào Sidebar
// 4. Render: {page === 'clinical' ? : }
// ══════════════════════════════════════════════════════════════════
import React, { useState, useRef } from 'react';
// ── Config ───────────────────────────────────────────────────────────
const API_BASE = import.meta.env.VITE_API_URL || '';
const SECTIONS = [
{ id: 's1', color: '#1D9E75', label: 'Mục 1 — Phân tích ca bệnh & xét nghiệm còn thiếu, chẩn đoán phân biệt' },
{ id: 's2', color: '#378ADD', label: 'Mục 2 — Chẩn đoán xác định & phù hợp phác đồ' },
{ id: 's3', color: '#1D9E75', label: 'Mục 3 — Khuyến cáo điều trị cụ thể' },
{ id: 's4', color: '#7F77DD', label: 'Mục 4 — Nhận xét thuốc đang dùng' },
{ id: 's5', color: '#BA7517', label: 'Mục 5 — Hướng dẫn theo dõi' },
{ id: 's6', color: '#E24B4A', label: 'Mục 6 — Cảnh báo đặc biệt' },
{ id: 's7', color: '#888780', label: 'Mục 7 — Tài liệu tham khảo nội bộ' },
];
// ── Component ────────────────────────────────────────────────────────
export default function ClinicalAI() {
const [caseText, setCaseText] = useState('');
const [loading, setLoading] = useState(false);
const [result, setResult] = useState(null);
const [error, setError] = useState('');
const [collapsed, setCollapsed] = useState({});
const textRef = useRef(null);
const toggleSection = (id) =>
setCollapsed(prev => ({ ...prev, [id]: !prev[id] }));
const analyze = async () => {
if (!caseText.trim() || caseText.trim().length < 20) {
setError('Vui lòng nhập đầy đủ thông tin ca bệnh (tối thiểu 20 ký tự).');
return;
}
setLoading(true);
setError('');
setResult(null);
try {
const res = await fetch(`${API_BASE}/api/v1/clinical-analysis`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ case_text: caseText }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.detail || `Lỗi server: ${res.status}`);
}
const data = await res.json();
if (data.success && data.data) {
setResult(data.data);
setCollapsed({});
} else {
throw new Error(data.error || 'Phản hồi không hợp lệ từ server.');
}
} catch (e) {
setError(e.message || 'Không thể kết nối đến server. Vui lòng thử lại.');
} finally {
setLoading(false);
}
};
const clearAll = () => {
setCaseText('');
setResult(null);
setError('');
setCollapsed({});
};
const handleKeyDown = (e) => {
if (e.ctrlKey && e.key === 'Enter') analyze();
};
return (
{/* Header */}
ClinicalAI — BaoThang
Phân tích lâm sàng hỗ trợ ra quyết định · BVĐK KV Bảo Thắng
{/* Input */}
{/* Loading bar */}
{loading && (
)}
{/* Results */}
{result && (
{SECTIONS.map(s => {
const content = result[s.id];
if (!content) return null;
const open = !collapsed[s.id];
return (
{open && (
{content}
)}
);
})}
Kết quả phân tích mang tính hỗ trợ quyết định lâm sàng.
Bác sĩ điều trị chịu trách nhiệm quyết định cuối cùng.
)}
);
}