diff --git a/admin-spa/src/routes/Settings/Shipping.tsx b/admin-spa/src/routes/Settings/Shipping.tsx index 4c7d045..c3e3d50 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, Plus, X } from 'lucide-react'; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; +import { Globe, Truck, MapPin, Edit, Trash2, RefreshCw, Loader2, ExternalLink, Settings, Plus, X, ChevronDown } from 'lucide-react'; import { toast } from 'sonner'; import { __ } from '@/lib/i18n'; import { useMediaQuery } from '@/hooks/use-media-query'; @@ -34,8 +35,8 @@ export default function ShippingPage() { const [selectedZone, setSelectedZone] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [showAddMethod, setShowAddMethod] = useState(false); - const [editingMethod, setEditingMethod] = useState(null); - const [showEditDialog, setShowEditDialog] = useState(false); + const [expandedMethod, setExpandedMethod] = useState(''); + const [methodSettings, setMethodSettings] = useState>({}); const isDesktop = useMediaQuery("(min-width: 768px)"); // Fetch shipping zones from WooCommerce @@ -98,24 +99,33 @@ export default function ShippingPage() { }, }); - // Fetch method settings for editing - const { data: methodSettings, isLoading: isLoadingSettings } = useQuery({ - queryKey: ['method-settings', selectedZone?.id, editingMethod?.instance_id], - queryFn: () => api.get(`/settings/shipping/zones/${selectedZone.id}/methods/${editingMethod.instance_id}/settings`), - enabled: !!editingMethod && !!selectedZone, - }); + // Fetch method settings when accordion expands + const fetchMethodSettings = async (instanceId: number) => { + if (!selectedZone || methodSettings[instanceId]) return; + + try { + const settings = await api.get(`/settings/shipping/zones/${selectedZone.id}/methods/${instanceId}/settings`); + setMethodSettings(prev => ({ ...prev, [instanceId]: settings })); + } catch (error) { + console.error('Failed to fetch method settings:', error); + } + }; // Update method settings mutation const updateSettingsMutation = useMutation({ mutationFn: async ({ zoneId, instanceId, settings }: { zoneId: number; instanceId: number; settings: any }) => { return api.post(`/settings/shipping/zones/${zoneId}/methods/${instanceId}/settings`, { settings }); }, - onSuccess: () => { + onSuccess: (_, variables) => { queryClient.invalidateQueries({ queryKey: ['shipping-zones'] }); - queryClient.invalidateQueries({ queryKey: ['method-settings'] }); + // Clear cached settings to force refetch + setMethodSettings(prev => { + const newSettings = { ...prev }; + delete newSettings[variables.instanceId]; + return newSettings; + }); toast.success(__('Settings saved')); - setShowEditDialog(false); - setEditingMethod(null); + setExpandedMethod(''); }, onError: (error: any) => { toast.error(error?.message || __('Failed to save settings')); @@ -314,51 +324,145 @@ export default function ShippingPage() { {__('Add Delivery Option')} - {/* Delivery Options List */} -
+ {/* Delivery Options Accordion */} + { + setExpandedMethod(value); + if (value) { + const instanceId = parseInt(value); + fetchMethodSettings(instanceId); + } + }}> {selectedZone.rates?.map((rate: any) => ( -
-
-
-
+ +
+ +
- +
+
+
+ + + {rate.enabled ? __('On') : __('Off')} + +
+
-
- - - {rate.enabled ? __('Active') : __('Inactive')} - -
-
-
- - -
+
+
-
+ + {methodSettings[rate.instance_id] ? ( +
+
+ + +

+ {__('Name shown to customers at checkout')} +

+
+ + {methodSettings[rate.instance_id].settings?.cost && ( +
+ + + {methodSettings[rate.instance_id].settings.cost.description && ( +

+ )} +

+ )} + + {methodSettings[rate.instance_id].settings?.min_amount && ( +
+ + + {methodSettings[rate.instance_id].settings.min_amount.description && ( +

+ )} +

+ )} + +
+ + +
+
+ ) : ( +
+ +
+ )} +
+ ))} -
+
@@ -497,109 +601,6 @@ export default function ShippingPage() { - {/* Edit Settings Dialog */} - { - setShowEditDialog(open); - if (!open) setEditingMethod(null); - }}> - - - {__('Edit Delivery Option')} - - {isLoadingSettings ? ( -
- -
- ) : methodSettings ? ( -
-
- - -

- {__('Name shown to customers at checkout')} -

-
- - {methodSettings.settings?.cost && ( -
- - - {methodSettings.settings.cost.description && ( -

- {methodSettings.settings.cost.description} -

- )} -
- )} - - {methodSettings.settings?.min_amount && ( -
- - - {methodSettings.settings.min_amount.description && ( -

- {methodSettings.settings.min_amount.description} -

- )} -
- )} - -
- - -
-
- ) : null} -
-
); }