You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.7 KiB
JavaScript
138 lines
4.7 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { X } from 'lucide-react';
|
|
|
|
export default function RouteForm({ route, onSubmit, onCancel }) {
|
|
const [formData, setFormData] = useState({
|
|
route_number: '',
|
|
name: '',
|
|
type: 'bus',
|
|
color: '#0066CC',
|
|
description: ''
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (route) {
|
|
setFormData({
|
|
route_number: route.route_number,
|
|
name: route.name,
|
|
type: route.type,
|
|
color: route.color,
|
|
description: route.description || ''
|
|
});
|
|
}
|
|
}, [route]);
|
|
|
|
const handleSubmit = (e) => {
|
|
e.preventDefault();
|
|
onSubmit(formData);
|
|
};
|
|
|
|
const handleChange = (e) => {
|
|
const { name, value } = e.target;
|
|
setFormData(prev => ({ ...prev, [name]: value }));
|
|
};
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-end sm:items-center justify-center z-50">
|
|
<div className="bg-white w-full sm:max-w-lg sm:mx-4 sm:rounded-lg rounded-t-2xl max-h-[90vh] overflow-hidden flex flex-col">
|
|
<div className="flex justify-between items-center p-4 sm:p-6 border-b border-gray-200">
|
|
<h2 className="text-lg sm:text-xl font-semibold">
|
|
{route ? 'Редактировать маршрут' : 'Новый маршрут'}
|
|
</h2>
|
|
<button onClick={onCancel} className="text-gray-400 hover:text-gray-600 p-1">
|
|
<X className="h-6 w-6" />
|
|
</button>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="flex flex-col flex-1 overflow-hidden">
|
|
<div className="p-4 sm:p-6 overflow-y-auto flex-1 space-y-4">
|
|
<div className="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label className="label">Номер маршрута *</label>
|
|
<input
|
|
type="text"
|
|
name="route_number"
|
|
value={formData.route_number}
|
|
onChange={handleChange}
|
|
className="input"
|
|
required
|
|
placeholder="1, 5A"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="label">Тип *</label>
|
|
<select
|
|
name="type"
|
|
value={formData.type}
|
|
onChange={handleChange}
|
|
className="input"
|
|
required
|
|
>
|
|
<option value="bus">Автобус</option>
|
|
<option value="minibus">Маршрутка</option>
|
|
<option value="trolleybus">Троллейбус</option>
|
|
<option value="tram">Трамвай</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="label">Название *</label>
|
|
<input
|
|
type="text"
|
|
name="name"
|
|
value={formData.name}
|
|
onChange={handleChange}
|
|
className="input"
|
|
required
|
|
placeholder="Центр - Вокзал"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="label">Цвет</label>
|
|
<div className="flex space-x-2">
|
|
<input
|
|
type="color"
|
|
name="color"
|
|
value={formData.color}
|
|
onChange={handleChange}
|
|
className="h-11 w-16 rounded border border-gray-300 cursor-pointer"
|
|
/>
|
|
<input
|
|
type="text"
|
|
value={formData.color}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, color: e.target.value }))}
|
|
className="input flex-1"
|
|
placeholder="#0066CC"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="label">Описание</label>
|
|
<textarea
|
|
name="description"
|
|
value={formData.description}
|
|
onChange={handleChange}
|
|
className="input"
|
|
rows="2"
|
|
placeholder="Дополнительная информация"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="p-4 sm:p-6 border-t border-gray-200 flex flex-col-reverse sm:flex-row sm:justify-end gap-2 sm:gap-3 safe-bottom">
|
|
<button type="button" onClick={onCancel} className="btn-secondary w-full sm:w-auto">
|
|
Отмена
|
|
</button>
|
|
<button type="submit" className="btn-primary w-full sm:w-auto">
|
|
{route ? 'Сохранить' : 'Создать'}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |