Files
delivery-tracker/frontend/src/components/delivery/DeliveryForm.tsx
2026-04-14 16:17:42 +06:00

185 lines
6.2 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.
import { useState, useEffect } from 'react';
import { Button, Input, Select, Modal } from '../ui';
import type { Delivery, PickupLocation, DeliveryStatus } from '../../types';
import { pickupLocationLabels } from '../../types';
interface DeliveryFormProps {
isOpen: boolean;
onClose: () => void;
onSubmit: (delivery: Omit<Delivery, 'id' | 'createdAt' | 'updatedAt'>) => void | Promise<void>;
initialData?: Delivery | null;
defaultDate?: string;
isSubmitting?: boolean;
}
const pickupOptions: { value: PickupLocation; label: string }[] = [
{ value: 'warehouse', label: pickupLocationLabels.warehouse },
{ value: 'symbat', label: pickupLocationLabels.symbat },
{ value: 'nursaya', label: pickupLocationLabels.nursaya },
{ value: 'galaktika', label: pickupLocationLabels.galaktika },
];
export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDate, isSubmitting }: DeliveryFormProps) => {
const [formData, setFormData] = useState({
date: defaultDate || new Date().toLocaleDateString('ru-RU').split('.').join('-'),
pickupLocation: 'warehouse' as PickupLocation,
productName: '',
address: '',
phone: '',
additionalPhone: '',
hasElevator: false,
comment: '',
status: 'new' as DeliveryStatus,
});
useEffect(() => {
if (initialData) {
setFormData({
date: initialData.date,
pickupLocation: initialData.pickupLocation,
productName: initialData.productName,
address: initialData.address,
phone: initialData.phone,
additionalPhone: initialData.additionalPhone || '',
hasElevator: initialData.hasElevator,
comment: initialData.comment,
status: initialData.status,
});
} else if (defaultDate) {
setFormData(prev => ({ ...prev, date: defaultDate }));
}
}, [initialData, defaultDate, isOpen]);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);
if (!initialData) {
setFormData({
date: defaultDate || new Date().toLocaleDateString('ru-RU').split('.').join('-'),
pickupLocation: 'warehouse',
productName: '',
address: '',
phone: '',
additionalPhone: '',
hasElevator: false,
comment: '',
status: 'new',
});
}
onClose();
};
const formatDateForInput = (dateStr: string) => {
const [day, month, year] = dateStr.split('-');
return `${year}-${month}-${day}`;
};
const formatDateFromInput = (dateStr: string) => {
const [year, month, day] = dateStr.split('-');
return `${day}-${month}-${year}`;
};
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title={initialData ? 'Редактировать доставку' : 'Новая доставка'}
footer={
<>
<Button variant="ghost" onClick={onClose} disabled={isSubmitting}>
Отмена
</Button>
<Button type="submit" form="delivery-form" disabled={isSubmitting}>
{isSubmitting ? 'Сохранение...' : initialData ? 'Сохранить' : 'Создать'}
</Button>
</>
}
>
<form id="delivery-form" onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-[#1b1b1d] mb-1">
Дата доставки
</label>
<input
type="date"
value={formatDateForInput(formData.date)}
onChange={(e) => setFormData({ ...formData, date: formatDateFromInput(e.target.value) })}
className="w-full px-3 py-2 bg-[#f5f3f5] border border-[#c5c6cd] rounded-md text-[#1b1b1d] focus:outline-none focus:ring-2 focus:ring-[#1B263B] focus:border-transparent transition-colors"
required
/>
</div>
<Select
label="Место загрузки"
value={formData.pickupLocation}
onChange={(e) => setFormData({ ...formData, pickupLocation: e.target.value as PickupLocation })}
options={pickupOptions}
/>
<Input
label="Название товара"
value={formData.productName}
onChange={(e) => setFormData({ ...formData, productName: e.target.value })}
placeholder="Введите название товара"
required
/>
<Input
label="Адрес разгрузки"
value={formData.address}
onChange={(e) => setFormData({ ...formData, address: e.target.value })}
placeholder="ул. Примерная, д. 1"
required
/>
<Input
label="Телефон покупателя"
type="tel"
value={formData.phone}
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
onFocus={(e) => {
if (!e.target.value) {
setFormData({ ...formData, phone: '+7' });
}
}}
placeholder="+7 (776)-567-89-01"
required
/>
<Input
label="Дополнительный номер телефона"
type="tel"
value={formData.additionalPhone}
onChange={(e) => setFormData({ ...formData, additionalPhone: e.target.value })}
onFocus={(e) => {
if (!e.target.value) {
setFormData({ ...formData, additionalPhone: '+7' });
}
}}
placeholder="+7 (776)-567-89-01"
/>
<div className="flex items-center gap-2">
<input
type="checkbox"
id="hasElevator"
checked={formData.hasElevator}
onChange={(e) => setFormData({ ...formData, hasElevator: e.target.checked })}
className="w-4 h-4 text-[#1B263B] border-[#c5c6cd] rounded focus:ring-[#1B263B]"
/>
<label htmlFor="hasElevator" className="text-sm text-[#1b1b1d]">
Наличие лифта
</label>
</div>
<Input
label="Комментарий"
value={formData.comment}
onChange={(e) => setFormData({ ...formData, comment: e.target.value })}
placeholder="Дополнительная информация..."
/>
</form>
</Modal>
);
};