diff --git a/admin-spa/src/routes/Settings/Shipping.tsx b/admin-spa/src/routes/Settings/Shipping.tsx index 25b093d..fbb8194 100644 --- a/admin-spa/src/routes/Settings/Shipping.tsx +++ b/admin-spa/src/routes/Settings/Shipping.tsx @@ -7,7 +7,8 @@ import { ToggleField } from './components/ToggleField'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer'; -import { Globe, Truck, MapPin, Edit, Trash2, RefreshCw, Loader2, ExternalLink, Settings } from 'lucide-react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { Globe, Truck, MapPin, Edit, Trash2, RefreshCw, Loader2, ExternalLink, Settings, Plus, X } from 'lucide-react'; import { toast } from 'sonner'; import { __ } from '@/lib/i18n'; import { useMediaQuery } from '@/hooks/use-media-query'; @@ -33,6 +34,8 @@ export default function ShippingPage() { const [togglingMethod, setTogglingMethod] = useState(null); const [selectedZone, setSelectedZone] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); + const [activeTab, setActiveTab] = useState('methods'); + const [showAddMethod, setShowAddMethod] = useState(false); const isDesktop = useMediaQuery("(min-width: 768px)"); // Fetch shipping zones from WooCommerce @@ -42,6 +45,13 @@ export default function ShippingPage() { staleTime: 5 * 60 * 1000, // 5 minutes }); + // Fetch available shipping methods + const { data: availableMethods = [] } = useQuery({ + queryKey: ['available-shipping-methods'], + queryFn: () => api.get('/settings/shipping/methods/available'), + enabled: showAddMethod, + }); + // Toggle shipping method mutation const toggleMutation = useMutation({ mutationFn: async ({ zoneId, instanceId, enabled }: { zoneId: number; instanceId: number; enabled: boolean }) => { @@ -59,11 +69,52 @@ export default function ShippingPage() { }, }); + // Add shipping method mutation + const addMethodMutation = useMutation({ + mutationFn: async ({ zoneId, methodId }: { zoneId: number; methodId: string }) => { + return api.post(`/settings/shipping/zones/${zoneId}/methods`, { method_id: methodId }); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['shipping-zones'] }); + toast.success(__('Shipping method added successfully')); + setShowAddMethod(false); + }, + onError: (error: any) => { + toast.error(error?.message || __('Failed to add shipping method')); + }, + }); + + // Delete shipping method mutation + const deleteMethodMutation = useMutation({ + mutationFn: async ({ zoneId, instanceId }: { zoneId: number; instanceId: number }) => { + return api.delete(`/settings/shipping/zones/${zoneId}/methods/${instanceId}`); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['shipping-zones'] }); + toast.success(__('Shipping method deleted successfully')); + }, + onError: (error: any) => { + toast.error(error?.message || __('Failed to delete shipping method')); + }, + }); + const handleToggle = (zoneId: number, instanceId: number, enabled: boolean) => { setTogglingMethod(`${zoneId}-${instanceId}`); toggleMutation.mutate({ zoneId, instanceId, enabled }); }; + const handleAddMethod = (methodId: string) => { + if (selectedZone) { + addMethodMutation.mutate({ zoneId: selectedZone.id, methodId }); + } + }; + + const handleDeleteMethod = (instanceId: number) => { + if (selectedZone && confirm(__('Are you sure you want to delete this shipping method?'))) { + deleteMethodMutation.mutate({ zoneId: selectedZone.id, instanceId }); + } + }; + if (isLoading) { return ( -
-
- {/* Zone Summary */} -
-
-
-

{__('Zone Order')}

-

{__('Priority in shipping calculations')}

-
- {selectedZone.order} -
-
+ + + {__('Shipping Methods')} + {__('Zone Details')} + + + +
+ {/* Add Method Button */} + - {/* Shipping Methods */} -
-
-

{__('Shipping Methods')}

- - {selectedZone.rates?.length} {selectedZone.rates?.length === 1 ? 'method' : 'methods'} - -
+ {/* Methods List */}
{selectedZone.rates?.map((rate: any) => ( -
-
+
+
-
- - {__('Cost')}: - - - {rate.description && ( - - )} +
+ {__('Cost')}:{' '} +
@@ -275,14 +319,47 @@ export default function ShippingPage() { }`}> {rate.enabled ? __('Active') : __('Inactive')} +
))}
-
-
+ + + +
+
+
+
+

{__('Zone Name')}

+

{selectedZone.name}

+
+
+

{__('Regions')}

+

{selectedZone.regions}

+
+
+

{__('Zone Order')}

+

{selectedZone.order}

+

{__('Priority in shipping calculations')}

+
+
+
+

+ {__('To edit zone name, regions, or order, use WooCommerce.')} +

+
+
+
+ ))} +
+
+ + ); }