import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { api } from '@/lib/api'; import { SettingsLayout } from './components/SettingsLayout'; import { SettingsCard } from './components/SettingsCard'; import { SettingsSection } from './components/SettingsSection'; import { ToggleField } from './components/ToggleField'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { SearchableSelect } from '@/components/ui/searchable-select'; import { ExternalLink, RefreshCw, Plus, Pencil, Trash2, Check } from 'lucide-react'; import { toast } from 'sonner'; import { __ } from '@/lib/i18n'; export default function TaxSettings() { const queryClient = useQueryClient(); const wcAdminUrl = (window as any).WNW_CONFIG?.wpAdminUrl || '/wp-admin'; const [showAddRate, setShowAddRate] = useState(false); const [editingRate, setEditingRate] = useState(null); const [deletingRate, setDeletingRate] = useState(null); const [dismissedSuggestions, setDismissedSuggestions] = useState([]); const [selectedTaxClass, setSelectedTaxClass] = useState('standard'); // Fetch tax settings const { data: settings, isLoading } = useQuery({ queryKey: ['tax-settings'], queryFn: () => api.get('/settings/tax'), }); // Fetch suggested rates const { data: suggested } = useQuery({ queryKey: ['tax-suggested'], queryFn: () => api.get('/settings/tax/suggested'), enabled: settings?.calc_taxes === 'yes', }); // Toggle tax calculation const toggleMutation = useMutation({ mutationFn: async (enabled: boolean) => { return api.post('/settings/tax/toggle', { enabled }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); toast.success(__('Tax calculation updated')); }, onError: (error: any) => { toast.error(error?.message || __('Failed to update tax settings')); }, }); // Create tax rate const createMutation = useMutation({ mutationFn: async (data: any) => { const response = await api.post('/settings/tax/rates', data); return response; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); queryClient.invalidateQueries({ queryKey: ['tax-suggested'] }); setShowAddRate(false); toast.success(__('Tax rate created')); }, onError: (error: any) => { console.error('[Tax] Create error:', error); toast.error(error?.message || __('Failed to create tax rate')); }, }); // Update tax rate const updateMutation = useMutation({ mutationFn: async ({ id, data }: any) => { return api.put(`/settings/tax/rates/${id}`, data); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); setEditingRate(null); toast.success(__('Tax rate updated')); }, onError: (error: any) => { toast.error(error?.message || __('Failed to update tax rate')); }, }); // Delete tax rate const deleteMutation = useMutation({ mutationFn: async (id: number) => { return api.del(`/settings/tax/rates/${id}`); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); setDeletingRate(null); toast.success(__('Tax rate deleted')); }, onError: (error: any) => { toast.error(error?.message || __('Failed to delete tax rate')); }, }); // Quick add suggested rate const quickAddMutation = useMutation({ mutationFn: async (suggestedRate: any) => { const response = await api.post('/settings/tax/rates', { country: suggestedRate.code, state: '', rate: suggestedRate.rate, name: suggestedRate.name, tax_class: '', priority: 1, compound: 0, shipping: 1, }); return response; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); queryClient.invalidateQueries({ queryKey: ['tax-suggested'] }); toast.success(__('Tax rate added')); }, onError: (error: any) => { console.error('[Tax] Quick add error:', error); toast.error(error?.message || __('Failed to add tax rate')); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const data = { country: formData.get('country') as string, state: formData.get('state') as string || '', rate: parseFloat(formData.get('rate') as string), name: formData.get('name') as string, tax_class: selectedTaxClass === 'standard' ? '' : selectedTaxClass, priority: 1, compound: 0, shipping: 1, }; if (editingRate) { updateMutation.mutate({ id: editingRate.id, data }); } else { createMutation.mutate(data); } }; if (isLoading) { return (
); } const allRates = [ ...(settings?.standard_rates || []), ...(settings?.reduced_rates || []), ...(settings?.zero_rates || []), ]; // Check if a suggested rate is already added const isRateAdded = (countryCode: string) => { return allRates.some((rate: any) => rate.country === countryCode); }; return ( { queryClient.invalidateQueries({ queryKey: ['tax-settings'] }); queryClient.invalidateQueries({ queryKey: ['tax-suggested'] }); }} > {__('Refresh')} } >
{/* Enable Tax Calculation */} toggleMutation.mutate(checked)} disabled={toggleMutation.isPending} /> {/* Tax Rates */} {settings?.calc_taxes === 'yes' && ( { setSelectedTaxClass('standard'); setShowAddRate(true); }} > {__('Add Tax Rate')} } > {/* Suggested Rates Notice */} {suggested?.suggested && suggested.suggested.length > 0 && suggested.suggested.some((r: any) => !isRateAdded(r.code)) && (

{__('Suggested tax rates based on your selling locations')}

{suggested.suggested.filter((r: any) => !isRateAdded(r.code)).map((rate: any) => (
{rate.country}: {rate.rate}% ({rate.name})
))}
)} {/* Tax Rates List */} {allRates.length === 0 ? (

{__('No tax rates configured yet')}

{__('Add a tax rate to get started')}

) : (
{allRates.map((rate: any) => (
{rate.name} {rate.country} {rate.state && `- ${rate.state}`}

{rate.rate}% tax rate

))}
)}
)} {/* Display Settings */} {settings?.calc_taxes === 'yes' && (
)} {/* Advanced Settings Link */}
{/* Add/Edit Tax Rate Dialog */} { if (!open) { setShowAddRate(false); setEditingRate(null); setSelectedTaxClass('standard'); } else { // Initialize tax class when opening (convert empty to 'standard') setSelectedTaxClass(editingRate?.tax_class || 'standard'); } }}> {editingRate ? __('Edit Tax Rate') : __('Add Tax Rate')}

{__('2-letter country code (e.g., ID, MY, SG)')}

{__('Leave empty for country-wide rate')}

{/* Delete Confirmation */} !open && setDeletingRate(null)}> {__('Delete Tax Rate?')} {__('Are you sure you want to delete this tax rate? This action cannot be undone.')} {__('Cancel')} deletingRate && deleteMutation.mutate(deletingRate.id)} className="bg-destructive text-destructive-foreground hover:bg-destructive/90" > {__('Delete')}
); }