107 lines
3.3 KiB
React
107 lines
3.3 KiB
React
import React, { useState, useEffect } from 'react';
|
|
import axios from 'axios';
|
|
import './Statistics.css';
|
|
|
|
const Statistics = () => {
|
|
const [stats, setStats] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
|
|
useEffect(() => {
|
|
fetchStatistics();
|
|
}, []);
|
|
|
|
const fetchStatistics = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const response = await axios.get('/api/v1/stats/summary');
|
|
setStats(response.data);
|
|
setError(null);
|
|
} catch (err) {
|
|
setError('Ошибка загрузки статистики');
|
|
console.error(err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (loading) return <div className="loading-state">Загрузка...</div>;
|
|
if (error) return <div className="error-state">{error}</div>;
|
|
if (!stats) return <div className="error-state">Нет данных</div>;
|
|
|
|
return (
|
|
<div className="statistics">
|
|
<div className="stats-header">
|
|
<h1>Статистика</h1>
|
|
<button className="btn-primary" onClick={fetchStatistics}>
|
|
🔄 Обновить
|
|
</button>
|
|
</div>
|
|
|
|
<div className="stats-grid">
|
|
{/* Общая статистика */}
|
|
<div className="stat-card">
|
|
<h3>Всего карточек</h3>
|
|
<div className="stat-value">{stats.total_cases || 0}</div>
|
|
</div>
|
|
|
|
{/* По полу */}
|
|
<div className="stat-card">
|
|
<h3>По полу</h3>
|
|
<div className="stat-breakdown">
|
|
<div className="stat-item">
|
|
<span>Мужской:</span>
|
|
<strong>{stats.by_gender?.male || 0}</strong>
|
|
</div>
|
|
<div className="stat-item">
|
|
<span>Женский:</span>
|
|
<strong>{stats.by_gender?.female || 0}</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* По возрасту */}
|
|
<div className="stat-card">
|
|
<h3>По возрасту</h3>
|
|
<div className="stat-breakdown">
|
|
{stats.by_age && Object.entries(stats.by_age).map(([range, count]) => (
|
|
<div key={range} className="stat-item">
|
|
<span>{range}:</span>
|
|
<strong>{count}</strong>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* По психотипам */}
|
|
<div className="stat-card">
|
|
<h3>По психотипам</h3>
|
|
<div className="stat-breakdown">
|
|
{stats.by_psychotype && Object.entries(stats.by_psychotype).map(([type, count]) => (
|
|
<div key={type} className="stat-item">
|
|
<span>{type}:</span>
|
|
<strong>{count}</strong>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* По диагнозам */}
|
|
<div className="stat-card wide">
|
|
<h3>По диагнозам</h3>
|
|
<div className="stat-breakdown">
|
|
{stats.by_diagnosis && Object.entries(stats.by_diagnosis).map(([diagnosis, count]) => (
|
|
<div key={diagnosis} className="stat-item">
|
|
<span>{diagnosis}:</span>
|
|
<strong>{count}</strong>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Statistics;
|