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
+296
View File
@@ -0,0 +1,296 @@
import React, { useState } from 'react';
import axios from 'axios';
import './MobileForm.css';
interface PsychotypeAnswers {
unfamiliar_env?: string;
stress_reaction?: string;
group_role?: string;
risk_taking?: string;
}
interface FormData {
age?: number;
gender?: string;
diagnosis_type?: string[];
psychotype_answers?: PsychotypeAnswers;
}
const MobileForm: React.FC = () => {
const [formData, setFormData] = useState<FormData>({
diagnosis_type: [],
psychotype_answers: {}
});
const [submitting, setSubmitting] = useState(false);
const [success, setSuccess] = useState(false);
const [error, setError] = useState<string | null>(null);
const handlePsychotypeAnswer = (question: keyof PsychotypeAnswers, value: string) => {
setFormData(prev => ({
...prev,
psychotype_answers: {
...prev.psychotype_answers,
[question]: value
}
}));
};
const isPsychotypeSelected = (question: keyof PsychotypeAnswers, value: string) => {
return formData.psychotype_answers?.[question] === value;
};
const validateForm = (): string | null => {
if (!formData.age || formData.age < 0 || formData.age > 120) {
return 'Укажите корректный возраст';
}
if (!formData.gender) {
return 'Выберите пол';
}
return null;
};
const handleSubmit = async () => {
const validationError = validateForm();
if (validationError) {
setError(validationError);
return;
}
setSubmitting(true);
setError(null);
try {
const response = await axios.post('/api/v1/cases', formData);
console.log('Case created:', response.data);
setSuccess(true);
setTimeout(() => {
setFormData({
diagnosis_type: [],
psychotype_answers: {}
});
setSuccess(false);
}, 2000);
} catch (err: any) {
setError(err.response?.data?.detail || 'Ошибка при создании карточки');
console.error('Submit error:', err);
} finally {
setSubmitting(false);
}
};
if (success) {
return (
<div className="mobile-form">
<div className="success-message">
<div className="success-icon">✓</div>
<h2>Карточка создана!</h2>
<p>Данные успешно сохранены</p>
</div>
</div>
);
}
return (
<div className="mobile-form">
<h1>Карточка пропавшего</h1>
{error && (
<div className="error-banner">
{error}
</div>
)}
<section className="form-section">
<h2>Основная информация</h2>
<div className="form-group">
<label>Возраст *</label>
<input
type="number"
placeholder="Лет"
value={formData.age || ''}
onChange={(e) => setFormData({...formData, age: parseInt(e.target.value)})}
required
/>
</div>
<div className="form-group">
<label>Пол *</label>
<div className="button-group">
<button
type="button"
className={formData.gender === 'male' ? 'selected' : ''}
onClick={() => setFormData({...formData, gender: 'male'})}
>
Мужской
</button>
<button
type="button"
className={formData.gender === 'female' ? 'selected' : ''}
onClick={() => setFormData({...formData, gender: 'female'})}
>
Женский
</button>
</div>
</div>
</section>
<section className="form-section">
<h2>Диагнозы (если есть)</h2>
<div className="checkbox-group">
{['РАС', 'эпилепсия', 'СДВГ', 'деменция'].map(diagnosis => (
<label key={diagnosis} className="checkbox-label">
<input
type="checkbox"
checked={formData.diagnosis_type?.includes(diagnosis)}
onChange={(e) => {
const current = formData.diagnosis_type || [];
setFormData({
...formData,
diagnosis_type: e.target.checked
? [...current, diagnosis]
: current.filter(d => d !== diagnosis)
});
}}
/>
{diagnosis}
</label>
))}
</div>
</section>
<section className="form-section psychotype-section">
<div className="section-header">
<h2>Поведение ребёнка (спросить родителей)</h2>
<p className="section-subtitle">Помогает уточнить зону поиска</p>
</div>
<div className="psychotype-question">
<label className="question-label">Как ведёт себя в незнакомой обстановке?</label>
<div className="button-group-vertical">
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('unfamiliar_env', 'explore') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('unfamiliar_env', 'explore')}
>
Активно исследует
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('unfamiliar_env', 'wait') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('unfamiliar_env', 'wait')}
>
Ждёт
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('unfamiliar_env', 'freeze') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('unfamiliar_env', 'freeze')}
>
Замирает
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('unfamiliar_env', 'panic') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('unfamiliar_env', 'panic')}
>
Паникует
</button>
</div>
</div>
<div className="psychotype-question">
<label className="question-label">Реакция на неудачи?</label>
<div className="button-group-vertical">
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('stress_reaction', 'active') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('stress_reaction', 'active')}
>
Злится, кричит
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('stress_reaction', 'cry') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('stress_reaction', 'cry')}
>
Плачет, замыкается
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('stress_reaction', 'calm') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('stress_reaction', 'calm')}
>
Спокойно ищет выход
</button>
</div>
</div>
<div className="psychotype-question">
<label className="question-label">Лидер или ведомый?</label>
<div className="button-group-vertical">
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('group_role', 'leader') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('group_role', 'leader')}
>
Лидер
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('group_role', 'sometimes') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('group_role', 'sometimes')}
>
Иногда
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('group_role', 'follower') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('group_role', 'follower')}
>
Всегда ведомый
</button>
</div>
</div>
<div className="psychotype-question">
<label className="question-label">Любит рисковать?</label>
<div className="button-group-vertical">
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('risk_taking', 'high') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('risk_taking', 'high')}
>
Очень
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsycotypeSelected('risk_taking', 'medium') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('risk_taking', 'medium')}
>
Иногда
</button>
<button
type="button"
className={'psychotype-btn ' + (isPsychotypeSelected('risk_taking', 'low') ? 'selected' : '')}
onClick={() => handlePsychotypeAnswer('risk_taking', 'low')}
>
Нет, осторожный
</button>
</div>
</div>
</section>
<button
className="submit-btn"
onClick={handleSubmit}
disabled={submitting}
>
{submitting ? 'Создание...' : 'Создать карточку'}
</button>
</div>
);
};
export default MobileForm;