frontend refactor
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Button, Input, Select, Modal } from '../ui';
|
||||
import { pickupOptions } from '../../constants/pickup';
|
||||
import { formatDateForInput, parseDateFromInput, getTodayFrontend } from '../../utils/date';
|
||||
import type { Delivery, PickupLocation, DeliveryStatus } from '../../types';
|
||||
import { pickupLocationLabels } from '../../types';
|
||||
|
||||
interface DeliveryFormProps {
|
||||
isOpen: boolean;
|
||||
@@ -12,16 +13,12 @@ interface DeliveryFormProps {
|
||||
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 },
|
||||
];
|
||||
// Phone validation regex for Kazakhstan numbers
|
||||
const PHONE_REGEX = /^\+7\s?\(?\d{3}\)?\s?\d{3}[\s-]?\d{2}[\s-]?\d{2}$/;
|
||||
|
||||
export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDate, isSubmitting }: DeliveryFormProps) => {
|
||||
const [formData, setFormData] = useState({
|
||||
date: defaultDate || new Date().toLocaleDateString('ru-RU').split('.').join('-'),
|
||||
date: defaultDate || getTodayFrontend(),
|
||||
pickupLocation: 'warehouse' as PickupLocation,
|
||||
productName: '',
|
||||
address: '',
|
||||
@@ -50,34 +47,39 @@ export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDa
|
||||
}
|
||||
}, [initialData, defaultDate, isOpen]);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
const validatePhone = useCallback((phone: string): boolean => {
|
||||
if (!phone) return false;
|
||||
return PHONE_REGEX.test(phone);
|
||||
}, []);
|
||||
|
||||
const isPhoneValid = !formData.phone || validatePhone(formData.phone);
|
||||
const isAdditionalPhoneValid = !formData.additionalPhone || validatePhone(formData.additionalPhone);
|
||||
const isFormValid = formData.productName && formData.address && formData.phone && isPhoneValid;
|
||||
|
||||
const handleSubmit = async (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',
|
||||
});
|
||||
if (!isFormValid) return;
|
||||
try {
|
||||
await onSubmit(formData);
|
||||
if (!initialData) {
|
||||
setFormData({
|
||||
date: defaultDate || getTodayFrontend(),
|
||||
pickupLocation: 'warehouse',
|
||||
productName: '',
|
||||
address: '',
|
||||
phone: '',
|
||||
additionalPhone: '',
|
||||
hasElevator: false,
|
||||
comment: '',
|
||||
status: 'new',
|
||||
});
|
||||
}
|
||||
onClose();
|
||||
} catch {
|
||||
// Error is handled by parent, keep form open
|
||||
}
|
||||
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
|
||||
@@ -89,7 +91,7 @@ export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDa
|
||||
<Button variant="ghost" onClick={onClose} disabled={isSubmitting}>
|
||||
Отмена
|
||||
</Button>
|
||||
<Button type="submit" form="delivery-form" disabled={isSubmitting}>
|
||||
<Button type="submit" form="delivery-form" disabled={isSubmitting || !isFormValid}>
|
||||
{isSubmitting ? 'Сохранение...' : initialData ? 'Сохранить' : 'Создать'}
|
||||
</Button>
|
||||
</>
|
||||
@@ -103,7 +105,7 @@ export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDa
|
||||
<input
|
||||
type="date"
|
||||
value={formatDateForInput(formData.date)}
|
||||
onChange={(e) => setFormData({ ...formData, date: formatDateFromInput(e.target.value) })}
|
||||
onChange={(e) => setFormData({ ...formData, date: parseDateFromInput(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
|
||||
/>
|
||||
@@ -144,7 +146,14 @@ export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDa
|
||||
}}
|
||||
placeholder="+7 (776)-567-89-01"
|
||||
required
|
||||
aria-invalid={!isPhoneValid}
|
||||
aria-describedby={!isPhoneValid ? 'phone-error' : undefined}
|
||||
/>
|
||||
{!isPhoneValid && formData.phone && (
|
||||
<p id="phone-error" className="text-sm text-red-500 mt-1">
|
||||
Введите корректный номер: +7 (XXX) XXX-XX-XX
|
||||
</p>
|
||||
)}
|
||||
|
||||
<Input
|
||||
label="Дополнительный номер телефона"
|
||||
@@ -157,7 +166,14 @@ export const DeliveryForm = ({ isOpen, onClose, onSubmit, initialData, defaultDa
|
||||
}
|
||||
}}
|
||||
placeholder="+7 (776)-567-89-01"
|
||||
aria-invalid={!isAdditionalPhoneValid}
|
||||
aria-describedby={!isAdditionalPhoneValid ? 'additional-phone-error' : undefined}
|
||||
/>
|
||||
{!isAdditionalPhoneValid && formData.additionalPhone && (
|
||||
<p id="additional-phone-error" className="text-sm text-red-500 mt-1">
|
||||
Введите корректный номер: +7 (XXX) XXX-XX-XX
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user