1. Hidden fields now respected in SPA
- Added isFieldHidden helper to check if PHP sets type to 'hidden'
- Country/state/city fields conditionally rendered based on API response
- Set default country value for hidden country fields (Indonesia-only stores)
2. Coupon discount now shows correct amount
- Added calculate_totals() before reading discount
- Changed coupons response to include {code, discount, type} per coupon
- Added discount_total at root level for frontend compatibility
3. Order details page now shows shipping info and AWB tracking
- Added shipping_lines, tracking_number, tracking_url to Order interface
- Added Shipping Method section with courier name and cost
- Added AWB tracking section for processing/completed orders
- Track Shipment button with link to tracking URL
Backend:
- Added /checkout/shipping-rates REST endpoint
- Returns available shipping methods from matching zone
- Triggers woonoow/shipping/before_calculate hook for Rajaongkir
Frontend:
- Added ShippingRate interface and state
- Added fetchShippingRates with 500ms debounce
- Replaced hardcoded shipping options with dynamic rates
- Added loading and empty state handling
- Added shipping_method to order submission payload
This fixes:
- Rajaongkir rates not appearing (now fetched from API)
- Free shipping showing despite disabled (now from WC zones)
Issues fixed:
1. Country field was disabled when API failed (length 0)
- Changed: disabled={countries.length <= 1} → disabled={countries.length === 1}
- Only disables in single-country mode now
2. State field was disabled when no preloaded states
- Changed: Falls back to text input instead of disabled SearchableSelect
- Allows manual state entry for countries without state list
3. /countries API required admin permission
- Added public /countries endpoint to CheckoutController
- Uses permission_callback __return_true for customer checkout access
- Returns countries, states, and default_country
Backend (CheckoutController):
- Enhanced get_fields() API with custom_attributes, search_endpoint,
search_param, min_chars, input_class, default
- Supports new 'searchable_select' field type for API-backed search
Customer SPA:
- Created DynamicCheckoutField component for all field types
- Checkout fetches fields from /checkout/fields API
- Renders custom fields from PHP filters (billing + shipping)
- searchable_select type with live API search
- Custom field data included in checkout submission
This enables:
- Checkout Field Editor Pro compatibility
- Rajaongkir destination_id via simple code snippet
- Any plugin using woocommerce_checkout_fields filter
Updated RAJAONGKIR_INTEGRATION.md with code snippet approach.
Admin SPA:
- Changed billing/shipping state from Select to SearchableSelect
Customer SPA:
- Added cmdk package for command palette
- Created popover, command, and searchable-select UI components
- Added searchable country and state fields to checkout
- Fetches countries/states from /countries API
- Auto-clears state when country changes
Backend:
- Added generic woonoow/shipping/before_calculate hook
- Removed hardcoded Rajaongkir session handling
Documentation:
- Updated RAJAONGKIR_INTEGRATION.md with:
- Complete searchable destination selector plugin code
- JavaScript implementation
- React component version
- REST API endpoint for destination search
1. Category Selection Bug:
- Added 'id' alias to category/tag API responses
- Frontend uses cat.id which was undefined (API returned term_id)
2. Checkout Redirect:
- Changed from window.location.href + reload to navigate()
- Added !isProcessing check to empty cart condition
3. Sidebar Shipping for Virtual-Only:
- Hide Shipping Method section when isVirtualOnly
- Hide Shipping row in totals when isVirtualOnly
4. License Table:
- Table creation runs via ensure_tables() on plugins_loaded
1. Add allow_custom_avatar toggle to Customer Settings
2. Implement coupon apply/remove in Cart and Checkout pages
3. Update Cart interface with coupons array and discount_total
4. Implement Downloads page to fetch from /account/downloads API
Changed Checkout page order success handling:
- Before: SPA navigate() to thank-you page (cookies not refreshed)
- After: window.location.href + reload (cookies refreshed)
This ensures guests who are auto-registered during checkout
get their auth cookies properly set after order placement.
- Use clearCart() from store instead of iterating removeItem()
- Iteration could fail as items are removed during loop
- clearCart() resets cart to initial state atomically
- Add public /checkout/order/{id} endpoint with order_key validation
- Update checkout redirect to include order_key parameter
- Update ThankYou page to use new public endpoint with key
- Support both guest (via key) and logged-in (via customer_id) access
- Add AddressController with full CRUD API for saved addresses
- Implement address management UI in My Account > Addresses
- Add modal-based address selector in checkout (Tokopedia-style)
- Hide checkout forms when saved address is selected
- Add search functionality in address modal
- Auto-select default addresses on page load
- Fix variable products to show 'Select Options' instead of 'Add to Cart'
- Add admin toggle for multiple addresses feature
- Clean up debug logs and fix TypeScript errors
- Created LayoutWrapper component to conditionally render header/footer based on route
- Created MinimalHeader component (logo only)
- Created MinimalFooter component (trust badges + policy links)
- Created usePageVisibility hook to get visibility settings per page
- Wrapped ClassicLayout with LayoutWrapper for conditional rendering
- Header/footer visibility now controlled directly in React SPA
- Settings: show/minimal/hide for both header and footer
- Background color support for checkout and thankyou pages