Import Vector lab project

This commit is contained in:
root
2026-06-06 18:31:55 +00:00
commit fcc22063ed
105 changed files with 31639 additions and 0 deletions
+175
View File
@@ -0,0 +1,175 @@
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import './CasesList.css';
const CasesList = () => {
const [cases, setCases] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [filters, setFilters] = useState({
gender: '',
ageFrom: '',
ageTo: '',
diagnosis: '',
psychotype: ''
});
useEffect(() => {
fetchCases();
}, [filters]);
const fetchCases = async () => {
setLoading(true);
try {
const params = new URLSearchParams();
if (filters.gender) params.append('gender', filters.gender);
if (filters.ageFrom) params.append('age_from', filters.ageFrom);
if (filters.ageTo) params.append('age_to', filters.ageTo);
if (filters.diagnosis) params.append('diagnosis', filters.diagnosis);
if (filters.psychotype) params.append('psychotype', filters.psychotype);
const response = await axios.get(`/api/v1/cases?${params}`);
setCases(response.data);
setError(null);
} catch (err) {
setError('Ошибка загрузки данных');
console.error(err);
} finally {
setLoading(false);
}
};
const formatDate = (dateString) => {
if (!dateString) return 'Не указано';
return new Date(dateString).toLocaleDateString('ru-RU');
};
const getPsychotypeLabel = (psychotype) => {
const labels = {
'explorer': 'Исследователь',
'cautious': 'Осторожный',
'passive': 'Пассивный',
'panicker': 'Паникёр'
};
return labels[psychotype] || psychotype;
};
return (
<div className="cases-list">
<div className="cases-header">
<h1>Карточки пропавших</h1>
<div className="header-actions">
<button className="btn-primary" onClick={fetchCases}>
🔄 Обновить
</button>
</div>
</div>
{/* Фильтры */}
<div className="filters-panel">
<div className="filter-group">
<label>Пол:</label>
<select value={filters.gender} onChange={(e) => setFilters({...filters, gender: e.target.value})}>
<option value="">Все</option>
<option value="male">Мужской</option>
<option value="female">Женский</option>
</select>
</div>
<div className="filter-group">
<label>Возраст от:</label>
<input
type="number"
value={filters.ageFrom}
onChange={(e) => setFilters({...filters, ageFrom: e.target.value})}
placeholder="0"
/>
</div>
<div className="filter-group">
<label>до:</label>
<input
type="number"
value={filters.ageTo}
onChange={(e) => setFilters({...filters, ageTo: e.target.value})}
placeholder="100"
/>
</div>
<div className="filter-group">
<label>Диагноз:</label>
<select value={filters.diagnosis} onChange={(e) => setFilters({...filters, diagnosis: e.target.value})}>
<option value="">Все</option>
<option value="РАС">РАС</option>
<option value="эпилепсия">Эпилепсия</option>
<option value="СДВГ">СДВГ</option>
<option value="деменция">Деменция</option>
</select>
</div>
<button className="btn-secondary" onClick={() => setFilters({
gender: '', ageFrom: '', ageTo: '', diagnosis: '', psychotype: ''
})}>
Сбросить фильтры
</button>
</div>
{/* Таблица */}
{loading ? (
<div className="loading-state">Загрузка...</div>
) : error ? (
<div className="error-state">{error}</div>
) : cases.length === 0 ? (
<div className="empty-state">Карточки не найдены</div>
) : (
<div className="table-container">
<table className="cases-table">
<thead>
<tr>
<th>ID</th>
<th>Возраст</th>
<th>Пол</th>
<th>Диагнозы</th>
<th>Психотип</th>
<th>Дата создания</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
{cases.map(caseItem => (
<tr key={caseItem.id}>
<td>{caseItem.id}</td>
<td>{caseItem.age || '—'}</td>
<td>{caseItem.gender === 'male' ? 'М' : caseItem.gender === 'female' ? 'Ж' : '—'}</td>
<td>
{caseItem.diagnosis_type && caseItem.diagnosis_type.length > 0
? caseItem.diagnosis_type.join(', ')
: '—'}
</td>
<td>
{caseItem.psychotype_result
? <span className="psychotype-badge">{getPsychotypeLabel(caseItem.psychotype_result)}</span>
: '—'}
</td>
<td>{formatDate(caseItem.created_at)}</td>
<td>
<Link to={`/admin/cases/${caseItem.id}`} className="btn-link">
Подробнее
</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
<div className="cases-footer">
<p>Всего карточек: <strong>{cases.length}</strong></p>
</div>
</div>
);
};
export default CasesList;