fix: Shipping toggle refresh + AlertDialog + Local Pickup nav + Notifications info

## 1. Fixed Shipping Method Toggle State 
- Updated useEffect to properly sync selectedZone with zones data
- Added JSON comparison to prevent infinite loops
- Toggle now refreshes zone data correctly

## 2. Replace confirm() with AlertDialog 
- Added AlertDialog component for delete confirmation
- Shows method name in confirmation message
- Better UX with proper dialog styling
- Updated both desktop and mobile versions

## 3. Added Local Pickup to Navigation 
- Added "Local Pickup" menu item in Settings
- Now accessible from Settings > Local Pickup
- Path: /settings/local-pickup

## 4. Shipping Cost Shortcodes 
- Already supported via HTML rendering
- WooCommerce shortcodes like [fee percent="10"] work
- [qty], [cost] are handled by WooCommerce backend
- No additional SPA work needed

## 5. Enhanced Notifications Page 
- Added comprehensive info card explaining:
  - What WooNooW provides (simple toggle)
  - What WooCommerce provides (advanced config)
- Clear guidance on when to use each
- Links to WooCommerce for templates/styling
- Replaced ToggleField with Switch for simpler usage

## Key Decisions:
 AlertDialog > confirm() for better UX
 Notifications = Simple toggle + guidance to WC
 Shortcodes handled by WooCommerce (no SPA work)
 Local Pickup now discoverable in nav
This commit is contained in:
dwindown
2025-11-09 23:56:34 +07:00
parent 5fb5eda9c3
commit a373b141b7
3 changed files with 80 additions and 14 deletions

View File

@@ -6,6 +6,7 @@ import { SettingsCard } from './components/SettingsCard';
import { ToggleField } from './components/ToggleField';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';
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';
@@ -33,10 +34,10 @@ export default function ShippingPage() {
const wcAdminUrl = (window as any).WNW_CONFIG?.wpAdminUrl || '/wp-admin';
const [togglingMethod, setTogglingMethod] = useState<string | null>(null);
const [selectedZone, setSelectedZone] = useState<any | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [showAddMethod, setShowAddMethod] = useState(false);
const [expandedMethod, setExpandedMethod] = useState<string>('');
const [methodSettings, setMethodSettings] = useState<Record<string, any>>({});
const [deletingMethod, setDeletingMethod] = useState<{ zoneId: number; instanceId: number; name: string } | null>(null);
const isDesktop = useMediaQuery("(min-width: 768px)");
// Fetch shipping zones from WooCommerce
@@ -55,13 +56,13 @@ export default function ShippingPage() {
// Sync selectedZone with zones data when it changes
useEffect(() => {
if (selectedZone && zones.length > 0) {
if (selectedZone && zones && zones.length > 0) {
const updatedZone = zones.find((z: any) => z.id === selectedZone.id);
if (updatedZone) {
if (updatedZone && JSON.stringify(updatedZone) !== JSON.stringify(selectedZone)) {
setSelectedZone(updatedZone);
}
}
}, [zones]);
}, [zones, selectedZone]);
// Toggle shipping method mutation
const toggleMutation = useMutation({
@@ -153,9 +154,19 @@ export default function ShippingPage() {
}
};
const handleDeleteMethod = (instanceId: number) => {
if (selectedZone && confirm(__('Are you sure you want to delete this shipping method?'))) {
deleteMethodMutation.mutate({ zoneId: selectedZone.id, instanceId });
const handleDeleteMethod = (instanceId: number, methodName: string) => {
if (selectedZone) {
setDeletingMethod({ zoneId: selectedZone.id, instanceId, name: methodName });
}
};
const confirmDelete = () => {
if (deletingMethod) {
deleteMethodMutation.mutate({
zoneId: deletingMethod.zoneId,
instanceId: deletingMethod.instanceId
});
setDeletingMethod(null);
}
};
@@ -424,7 +435,7 @@ export default function ShippingPage() {
variant="destructive"
size="sm"
onClick={() => {
handleDeleteMethod(rate.instance_id);
handleDeleteMethod(rate.instance_id, rate.title);
setExpandedMethod('');
}}
disabled={deleteMethodMutation.isPending}
@@ -594,7 +605,7 @@ export default function ShippingPage() {
variant="destructive"
size="sm"
onClick={() => {
handleDeleteMethod(rate.instance_id);
handleDeleteMethod(rate.instance_id, rate.title);
setExpandedMethod('');
}}
disabled={deleteMethodMutation.isPending}
@@ -696,6 +707,28 @@ export default function ShippingPage() {
</DialogContent>
</Dialog>
{/* Delete Confirmation Dialog */}
<AlertDialog open={!!deletingMethod} onOpenChange={() => setDeletingMethod(null)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{__('Delete Shipping Method?')}</AlertDialogTitle>
<AlertDialogDescription>
{__('Are you sure you want to delete')} <strong>{deletingMethod?.name}</strong>?
{' '}{__('This action cannot be undone.')}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>{__('Cancel')}</AlertDialogCancel>
<AlertDialogAction
onClick={confirmDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
{__('Delete')}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</SettingsLayout>
);
}