From a487baa61dd48937191a6eb363df5bb5532ff47f Mon Sep 17 00:00:00 2001 From: dwindown Date: Mon, 10 Nov 2025 15:42:16 +0700 Subject: [PATCH] fix: Resolve Tax and OrderForm errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Error 1: Tax Settings - Empty SelectItem value ✅ **Issue:** Radix UI Select does not allow empty string as SelectItem value **Error:** "A must have a value prop that is not an empty string" **Solution:** - Use 'standard' instead of empty string for UI - Convert 'standard' → '' when submitting to API - Initialize selectedTaxClass to 'standard' - Update all dialog handlers to use 'standard' ## Error 2: OrderForm - Undefined shipping variables ✅ **Issue:** Removed individual shipping state variables (sFirst, sLast, sCountry, etc.) but forgot to update all references **Error:** "Cannot find name 'sCountry'" **Solution:** Fixed all remaining references: 1. **useEffect for country sync:** `setSCountry(bCountry)` → `setShippingData({...shippingData, country: bCountry})` 2. **useEffect for state validation:** `sState && !states[sCountry]` → `shippingData.state && !states[shippingData.country]` 3. **Customer autofill:** Individual setters → `setShippingData({ first_name, last_name, ... })` 4. **Removed sStateOptions:** No longer needed with dynamic fields ## Testing: - ✅ Tax settings page loads without errors - ✅ Add/Edit tax rate dialog works - ✅ OrderForm loads without errors - ✅ Shipping fields render dynamically - ✅ Customer autofill works with new state structure --- .../src/routes/Orders/partials/OrderForm.tsx | 33 +++++++++++-------- admin-spa/src/routes/Settings/Tax.tsx | 16 ++++----- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/admin-spa/src/routes/Orders/partials/OrderForm.tsx b/admin-spa/src/routes/Orders/partials/OrderForm.tsx index 8347c6f..88c98c1 100644 --- a/admin-spa/src/routes/Orders/partials/OrderForm.tsx +++ b/admin-spa/src/routes/Orders/partials/OrderForm.tsx @@ -149,13 +149,15 @@ export default function OrderForm({ if (oneCountryOnly) { const only = countries[0]?.code || ''; if (shipDiff) { - if (only && sCountry !== only) setSCountry(only); + if (only && shippingData.country !== only) { + setShippingData({...shippingData, country: only}); + } } else { // keep shipping synced to billing when not different - setSCountry(bCountry); + setShippingData({...shippingData, country: bCountry}); } } - }, [oneCountryOnly, countries, shipDiff, bCountry, sCountry]); + }, [oneCountryOnly, countries, shipDiff, bCountry, shippingData.country]); // Order meta const [status, setStatus] = React.useState(initial?.status || 'pending'); @@ -292,7 +294,7 @@ export default function OrderForm({ // Keep shipping country synced to billing when unchecked React.useEffect(() => { - if (!shipDiff) setSCountry(bCountry); + if (!shipDiff) setShippingData({...shippingData, country: bCountry}); }, [shipDiff, bCountry]); // Clamp states when country changes @@ -300,12 +302,13 @@ export default function OrderForm({ if (bState && !states[bCountry]?.[bState]) setBState(''); }, [bCountry]); React.useEffect(() => { - if (sState && !states[sCountry]?.[sState]) setSState(''); - }, [sCountry]); + if (shippingData.state && !states[shippingData.country]?.[shippingData.state]) { + setShippingData({...shippingData, state: ''}); + } + }, [shippingData.country]); const countryOptions = countries.map(c => ({ value: c.code, label: `${c.name} (${c.code})` })); const bStateOptions = Object.entries(states[bCountry] || {}).map(([code, name]) => ({ value: code, label: name })); - const sStateOptions = Object.entries(states[sCountry] || {}).map(([code, name]) => ({ value: code, label: name })); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); @@ -692,13 +695,15 @@ export default function OrderForm({ // Autofill shipping if available if (data.shipping && data.shipping.address_1) { setShipDiff(true); - setSFirst(data.shipping.first_name || ''); - setSLast(data.shipping.last_name || ''); - setSAddr1(data.shipping.address_1 || ''); - setSCity(data.shipping.city || ''); - setSPost(data.shipping.postcode || ''); - setSCountry(data.shipping.country || bCountry); - setSState(data.shipping.state || ''); + setShippingData({ + first_name: data.shipping.first_name || '', + last_name: data.shipping.last_name || '', + address_1: data.shipping.address_1 || '', + city: data.shipping.city || '', + postcode: data.shipping.postcode || '', + country: data.shipping.country || bCountry, + state: data.shipping.state || '', + }); } } diff --git a/admin-spa/src/routes/Settings/Tax.tsx b/admin-spa/src/routes/Settings/Tax.tsx index 7ac7a56..8db6274 100644 --- a/admin-spa/src/routes/Settings/Tax.tsx +++ b/admin-spa/src/routes/Settings/Tax.tsx @@ -24,7 +24,7 @@ export default function TaxSettings() { const [editingRate, setEditingRate] = useState(null); const [deletingRate, setDeletingRate] = useState(null); const [dismissedSuggestions, setDismissedSuggestions] = useState([]); - const [selectedTaxClass, setSelectedTaxClass] = useState(''); + const [selectedTaxClass, setSelectedTaxClass] = useState('standard'); // Fetch tax settings const { data: settings, isLoading } = useQuery({ @@ -142,7 +142,7 @@ export default function TaxSettings() { state: formData.get('state') as string || '', rate: parseFloat(formData.get('rate') as string), name: formData.get('name') as string, - tax_class: selectedTaxClass || '', + tax_class: selectedTaxClass === 'standard' ? '' : selectedTaxClass, priority: 1, compound: 0, shipping: 1, @@ -222,7 +222,7 @@ export default function TaxSettings() {