klg-asutk-app/components/AircraftAddModal.tsx
Yuriy b147d16798 MVP: заглушки, auth, .env.example, связь с бэкендом, главная КЛГ
- Заполнены заглушки: user-friendly-messages, health, aria, keyboard
- backend: core/auth.py, /api/v1/stats; cached-api → backend-client при USE_MOCK_DATA=false
- .env.example, middleware auth (skip при USE_MOCK_DATA), убраны неиспользуемые deps
- Страницы: airworthiness, maintenance, defects, modifications; AircraftAddModal, Sidebar
- Главная страница: REFLY — Контроль лётной годности (вместо Numerology App)
- Линт/скрипты: eslintrc, security, cleanup, logs, api inbox/knowledge

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-13 16:43:53 +03:00

214 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useState, useRef } from 'react';
export interface AircraftFormData {
registrationNumber: string;
serialNumber: string;
aircraftType: string;
model: string;
operator: string;
status: string;
manufacturer?: string;
yearOfManufacture?: string;
flightHours?: string;
}
interface AircraftAddModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (data: AircraftFormData, files: File[]) => void | Promise<void>;
}
export default function AircraftAddModal({ isOpen, onClose, onSave }: AircraftAddModalProps) {
const [formData, setFormData] = useState<AircraftFormData>({
registrationNumber: '',
serialNumber: '',
aircraftType: 'Boeing 737-800',
model: '737-800',
operator: '',
status: 'active',
manufacturer: '',
yearOfManufacture: '',
flightHours: '',
});
const [files, setFiles] = useState<File[]>([]);
const fileInputRef = useRef<HTMLInputElement>(null);
if (!isOpen) {
return null;
}
const handleChange = (field: keyof AircraftFormData, value: string) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selected = e.target.files ? Array.from(e.target.files) : [];
setFiles((prev) => [...prev, ...selected]);
};
const handleSubmit = async () => {
if (!formData.registrationNumber || !formData.serialNumber || !formData.operator) {
alert('Заполните обязательные поля: регистрационный номер, серийный номер, оператор');
return;
}
await onSave(formData, files);
setFormData({
registrationNumber: '',
serialNumber: '',
aircraftType: 'Boeing 737-800',
model: '737-800',
operator: '',
status: 'active',
manufacturer: '',
yearOfManufacture: '',
flightHours: '',
});
setFiles([]);
if (fileInputRef.current) fileInputRef.current.value = '';
onClose();
};
const inputStyle = { width: '100%', padding: '8px', border: '1px solid #ccc', borderRadius: '4px', fontSize: '14px' };
const labelStyle = { display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 };
return (
<div
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1000,
}}
onClick={onClose}
>
<div
style={{
backgroundColor: 'white',
borderRadius: '8px',
padding: '24px',
maxWidth: '500px',
width: '90%',
maxHeight: '90vh',
overflowY: 'auto',
boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
}}
onClick={(e) => e.stopPropagation()}
>
<h3 style={{ margin: '0 0 20px', fontSize: '20px' }}>Добавить воздушное судно</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginBottom: '20px' }}>
<div>
<label style={labelStyle}>Регистрационный номер *</label>
<input
type="text"
value={formData.registrationNumber}
onChange={(e) => handleChange('registrationNumber', e.target.value)}
placeholder="RA-73701"
style={inputStyle}
/>
</div>
<div>
<label style={labelStyle}>Серийный номер *</label>
<input
type="text"
value={formData.serialNumber}
onChange={(e) => handleChange('serialNumber', e.target.value)}
placeholder="MSN-4521"
style={inputStyle}
/>
</div>
<div>
<label style={labelStyle}>Тип ВС</label>
<select
value={formData.aircraftType}
onChange={(e) => handleChange('aircraftType', e.target.value)}
style={inputStyle}
>
<option value="Boeing 737-800">Boeing 737-800</option>
<option value="Sukhoi Superjet 100">Sukhoi Superjet 100</option>
<option value="An-148-100V">An-148-100V</option>
<option value="Il-76TD-90VD">Il-76TD-90VD</option>
<option value="Mi-8MTV-1">Mi-8MTV-1</option>
</select>
</div>
<div>
<label style={labelStyle}>Оператор *</label>
<input
type="text"
value={formData.operator}
onChange={(e) => handleChange('operator', e.target.value)}
placeholder="REFLY Airlines"
style={inputStyle}
/>
</div>
<div>
<label style={labelStyle}>Статус</label>
<select
value={formData.status}
onChange={(e) => handleChange('status', e.target.value)}
style={inputStyle}
>
<option value="active">Активен</option>
<option value="maintenance">На ТО</option>
<option value="storage">На хранении</option>
</select>
</div>
<div>
<label style={labelStyle}>Прикрепить файлы</label>
<input
ref={fileInputRef}
type="file"
multiple
onChange={handleFileChange}
accept=".pdf,.doc,.docx"
style={inputStyle}
/>
{files.length > 0 && (
<div style={{ marginTop: '4px', fontSize: '12px', color: '#666' }}>
Выбрано файлов: {files.length}
</div>
)}
</div>
</div>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end' }}>
<button
onClick={onClose}
style={{
padding: '10px 20px',
backgroundColor: '#f5f5f5',
border: '1px solid #ccc',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Отмена
</button>
<button
onClick={handleSubmit}
style={{
padding: '10px 20px',
backgroundColor: '#1e3a5f',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
}}
>
Сохранить
</button>
</div>
</div>
</div>
);
}