This commit is contained in:
2026-06-29 23:45:08 +07:00
parent 5290eeeb91
commit c736326162
15 changed files with 3067 additions and 388 deletions

View File

@@ -0,0 +1,137 @@
import React, { useEffect, useState } from 'react';
import { api } from '../api';
import type { StatsResponse } from '../api';
interface DashboardTabProps {
onNavigate: (tab: string) => void;
}
export const DashboardTab: React.FC<DashboardTabProps> = ({ onNavigate }) => {
const [stats, setStats] = useState<StatsResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchStats = async () => {
try {
setLoading(true);
const data = await api.getStats();
setStats(data);
} catch (err: any) {
setError(err.message || 'Không thể tải dữ liệu thống kê');
} finally {
setLoading(false);
}
};
fetchStats();
}, []);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
<div className="page-header">
<div className="page-title">
<h1>Tổng Quan Hệ Thống</h1>
<p>Giám sát đng bộ quản lớp học, sinh viên từ hệ thống chính</p>
</div>
</div>
{loading && (
<div className="empty-state">
<div className="sync-spinner" style={{ width: '40px', height: '40px', borderWidth: '3px' }}></div>
<p style={{ marginTop: '1rem' }}>Đang tải thông số hệ thống...</p>
</div>
)}
{error && (
<div className="empty-state" style={{ border: '1px solid rgba(239, 68, 68, 0.2)', backgroundColor: 'rgba(239, 68, 68, 0.05)' }}>
<div className="empty-state-icon" style={{ color: 'var(--danger)' }}></div>
<p style={{ color: 'var(--danger)', fontWeight: 600 }}>Lỗi: {error}</p>
</div>
)}
{!loading && !error && stats && (
<>
<div className="stats-grid">
<div className="stat-card" onClick={() => onNavigate('classes')} style={{ cursor: 'pointer' }}>
<div>
<div className="stat-label">Tổng lớp học đã đng bộ</div>
<div className="stat-value">{stats.totalClasses}</div>
</div>
<div className="stat-icon">🏫</div>
</div>
<div className="stat-card" onClick={() => onNavigate('classes')} style={{ cursor: 'pointer' }}>
<div>
<div className="stat-label">Lớp đang giảng dạy</div>
<div className="stat-value" style={{ color: 'var(--success)' }}>{stats.activeClasses}</div>
</div>
<div className="stat-icon" style={{ color: 'var(--success)' }}>🟢</div>
</div>
<div className="stat-card" onClick={() => onNavigate('students')} style={{ cursor: 'pointer' }}>
<div>
<div className="stat-label">Tổng sinh viên đã đng bộ</div>
<div className="stat-value" style={{ color: 'var(--accent-hover)' }}>{stats.totalStudents}</div>
</div>
<div className="stat-icon">🎓</div>
</div>
</div>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))',
gap: '1.5rem',
marginTop: '1rem'
}}>
<div style={{
backgroundColor: 'var(--bg-card)',
border: '1px solid var(--border-color)',
padding: '2rem',
borderRadius: '18px',
backdropFilter: 'blur(10px)'
}}>
<h2 style={{ marginBottom: '1rem', color: 'white', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
🚀 Khởi đng nhanh
</h2>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.95rem', lineHeight: '1.6', marginBottom: '1.5rem' }}>
Chào mừng bạn đến với trang quản trị <b>Simple Care</b>.
Hệ thống hỗ trợ đng bộ hóa thông tin tự đng từ cổng đào tạo chính (QLĐT), giúp lưu trữ, cập nhật trạng thái lớp học danh sách sinh viên nội bộ không lo nh hưởng đến dữ liệu hiện .
</p>
<div style={{ display: 'flex', gap: '1rem' }}>
<button className="btn btn-primary" onClick={() => onNavigate('classes')}>
Quản Lớp học
</button>
<button className="btn btn-secondary" onClick={() => onNavigate('students')}>
Danh sách Sinh viên
</button>
</div>
</div>
<div style={{
backgroundColor: 'var(--bg-card)',
border: '1px solid var(--border-color)',
padding: '2rem',
borderRadius: '18px',
backdropFilter: 'blur(10px)'
}}>
<h2 style={{ marginBottom: '1rem', color: 'white' }}>📋 Quy trình hoạt đng</h2>
<ul style={{
color: 'var(--text-secondary)',
fontSize: '0.95rem',
lineHeight: '1.8',
paddingLeft: '1.25rem',
display: 'flex',
flexDirection: 'column',
gap: '0.5rem'
}}>
<li><b>Đng bộ Lớp học:</b> Tải toàn bộ danh sách lớp học các môn học tương ng. Đng thời kéo thông tin sinh viên thuộc từng lớp thông qua bảng kết quả lớp học.</li>
<li><b>Quản Lớp:</b> Lọc danh sách lớp theo Phân hệ (System ID), Tìm kiếm tên hoặc lớp Bật/Tắt cờ <b>Đang học</b>.</li>
<li><b>Đng bộ Sinh viên:</b> Thực hiện kéo toàn bộ sinh viên trên hệ thống chính (kèm thông tin liên hệ, hệ học) lưu trữ vào Database phục vụ cho học tập thi cử.</li>
</ul>
</div>
</div>
</>
)}
</div>
);
};