153 lines
5.2 KiB
TypeScript
153 lines
5.2 KiB
TypeScript
import { useState, useEffect } from 'react';
|
||
import { ArrowLeft, Filter, Loader2, AlertCircle } from 'lucide-react';
|
||
import { useDeliveryStore } from '../stores/deliveryStore';
|
||
import { DeliveryList as DeliveryListComponent } from '../components/delivery/DeliveryList';
|
||
import { DeliveryForm } from '../components/delivery/DeliveryForm';
|
||
import { Button } from '../components/ui/Button';
|
||
import { Select } from '../components/ui/Select';
|
||
import type { Delivery, PickupLocation } from '../types';
|
||
import { pickupLocationLabels } from '../types';
|
||
|
||
interface DeliveryListPageProps {
|
||
selectedDate: string;
|
||
onBack: () => void;
|
||
}
|
||
|
||
export const DeliveryListPage = ({ selectedDate, onBack }: DeliveryListPageProps) => {
|
||
const deliveries = useDeliveryStore(state => state.deliveries);
|
||
const isLoading = useDeliveryStore(state => state.isLoading);
|
||
const error = useDeliveryStore(state => state.error);
|
||
const fetchDeliveriesByDate = useDeliveryStore(state => state.fetchDeliveriesByDate);
|
||
const toggleStatus = useDeliveryStore(state => state.toggleStatus);
|
||
const deleteDelivery = useDeliveryStore(state => state.deleteDelivery);
|
||
const updateDelivery = useDeliveryStore(state => state.updateDelivery);
|
||
const addDelivery = useDeliveryStore(state => state.addDelivery);
|
||
const clearError = useDeliveryStore(state => state.clearError);
|
||
|
||
// Fetch deliveries when date changes
|
||
useEffect(() => {
|
||
fetchDeliveriesByDate(selectedDate);
|
||
}, [selectedDate, fetchDeliveriesByDate]);
|
||
|
||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||
const [editingDelivery, setEditingDelivery] = useState<Delivery | null>(null);
|
||
const [pickupFilter, setPickupFilter] = useState<PickupLocation | 'all'>('all');
|
||
|
||
// Use all deliveries from store (already filtered by API)
|
||
const dayDeliveries = deliveries;
|
||
const filteredDeliveries = pickupFilter === 'all'
|
||
? dayDeliveries
|
||
: dayDeliveries.filter(d => d.pickupLocation === pickupFilter);
|
||
|
||
const pickupOptions: { value: PickupLocation | 'all'; label: string }[] = [
|
||
{ value: 'all', label: 'Все места загрузки' },
|
||
{ value: 'warehouse', label: pickupLocationLabels.warehouse },
|
||
{ value: 'symbat', label: pickupLocationLabels.symbat },
|
||
{ value: 'nursaya', label: pickupLocationLabels.nursaya },
|
||
{ value: 'galaktika', label: pickupLocationLabels.galaktika },
|
||
];
|
||
|
||
const handleStatusChange = async (id: string) => {
|
||
const delivery = deliveries.find(d => d.id === id);
|
||
if (delivery) {
|
||
await toggleStatus(id, delivery.status);
|
||
}
|
||
};
|
||
|
||
const handleEdit = (delivery: Delivery) => {
|
||
setEditingDelivery(delivery);
|
||
setIsFormOpen(true);
|
||
};
|
||
|
||
const handleDelete = async (id: string) => {
|
||
if (confirm('Удалить эту доставку?')) {
|
||
try {
|
||
await deleteDelivery(id);
|
||
} catch {
|
||
// Error is handled by store
|
||
}
|
||
}
|
||
};
|
||
|
||
const handleSubmit = async (data: Omit<Delivery, 'id' | 'createdAt' | 'updatedAt'>) => {
|
||
try {
|
||
if (editingDelivery) {
|
||
await updateDelivery(editingDelivery.id, data);
|
||
} else {
|
||
await addDelivery(data);
|
||
}
|
||
setEditingDelivery(null);
|
||
} catch {
|
||
// Error is handled by store
|
||
}
|
||
};
|
||
|
||
const handleAdd = () => {
|
||
setEditingDelivery(null);
|
||
setIsFormOpen(true);
|
||
};
|
||
|
||
const handleCloseForm = () => {
|
||
setIsFormOpen(false);
|
||
setEditingDelivery(null);
|
||
};
|
||
|
||
return (
|
||
<div className="space-y-4">
|
||
<div className="flex items-center justify-between flex-wrap gap-4">
|
||
<div className="flex items-center gap-4">
|
||
<Button variant="ghost" size="sm" onClick={onBack}>
|
||
<ArrowLeft size={18} className="mr-1" />
|
||
Назад
|
||
</Button>
|
||
<div className="flex items-center gap-2 text-sm text-[#75777d]">
|
||
<Filter size={16} />
|
||
<span>Всего: {filteredDeliveries.length}</span>
|
||
</div>
|
||
</div>
|
||
<div className="w-48">
|
||
<Select
|
||
label=""
|
||
value={pickupFilter}
|
||
onChange={(e) => setPickupFilter(e.target.value as PickupLocation | 'all')}
|
||
options={pickupOptions}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{isLoading ? (
|
||
<div className="flex items-center justify-center py-12">
|
||
<Loader2 className="w-8 h-8 animate-spin text-[#1B263B]" />
|
||
</div>
|
||
) : error ? (
|
||
<div className="bg-red-50 border border-red-200 rounded-lg p-4 flex items-center gap-3">
|
||
<AlertCircle className="w-5 h-5 text-red-500" />
|
||
<div className="flex-1">
|
||
<p className="text-red-700">{error}</p>
|
||
</div>
|
||
<Button variant="ghost" size="sm" onClick={() => { clearError(); fetchDeliveriesByDate(selectedDate); }}>
|
||
Повторить
|
||
</Button>
|
||
</div>
|
||
) : (
|
||
<DeliveryListComponent
|
||
deliveries={filteredDeliveries}
|
||
onStatusChange={handleStatusChange}
|
||
onEdit={handleEdit}
|
||
onDelete={handleDelete}
|
||
onAdd={handleAdd}
|
||
date={selectedDate}
|
||
/>
|
||
)}
|
||
|
||
<DeliveryForm
|
||
isOpen={isFormOpen}
|
||
onClose={handleCloseForm}
|
||
onSubmit={handleSubmit}
|
||
initialData={editingDelivery}
|
||
defaultDate={selectedDate}
|
||
/>
|
||
</div>
|
||
);
|
||
};
|