fix: Newsletter React error #310 and refactor Wishlist module

Newsletter Fix:
- Move all hooks (useQuery, useMutation) before conditional returns
- Add 'enabled' option to useQuery to control when it fetches
- Fixes React error #310: useEffect called conditionally
- Newsletter page now loads without errors at /marketing/newsletter

Wishlist Module Refactoring:
- Create WishlistSettings.php with 8 configurable settings:
  * Enable guest wishlists
  * Wishlist page selector
  * Show in header toggle
  * Enable sharing
  * Back in stock notifications
  * Max items per wishlist
  * Multiple wishlists support
  * Show add to cart button
- Add has_settings flag to wishlist module in ModuleRegistry
- Initialize WishlistSettings in woonoow.php
- Update customer-spa BaseLayout to use isEnabled('wishlist') check
- Wishlist page already has module check (no changes needed)

Files Added (1):
- includes/Modules/WishlistSettings.php

Files Modified (5):
- admin-spa/src/routes/Marketing/Newsletter.tsx
- includes/Core/ModuleRegistry.php
- woonoow.php
- customer-spa/src/layouts/BaseLayout.tsx
- admin-spa/dist/app.js (rebuilt)

Both newsletter and wishlist now follow the same module pattern:
- Settings via schema (no code required)
- Module enable/disable controls feature visibility
- Settings page at /settings/modules/{module_id}
- Consistent user experience
This commit is contained in:
Dwindi Ramadhana
2025-12-26 21:29:27 +07:00
parent c6cef97ef8
commit daebd5f989
7 changed files with 567 additions and 21 deletions

View File

@@ -0,0 +1 @@
(()=>{var{React:e,hooks:y,components:b,icons:_,utils:k}=window.WooNooW,{useModuleSettings:w}=y,{SettingsLayout:E,SettingsCard:c,Input:o,Button:f,Switch:r,Select:I,SelectContent:A,SelectItem:h,SelectTrigger:P,SelectValue:B,Badge:D}=b,{Settings:M,Save:L,AlertCircle:T,Check:W}=_,{toast:m}=k;function j(){let{settings:l,isLoading:v,updateSettings:i}=w("biteship-shipping"),[n,u]=e.useState({}),[d,g]=e.useState(!1),[s,p]=e.useState(null);e.useEffect(()=>{l&&u(l)},[l]);let a=(t,N)=>{u(S=>({...S,[t]:N}))},x=()=>{i.mutate(n)},C=async()=>{if(!n.api_key){m.error("Please enter an API key first");return}g(!0),p(null),setTimeout(()=>{let t=n.api_key.startsWith("biteship_");p(t?"success":"error"),g(!1),t?m.success("Connection successful!"):m.error("Invalid API key format")},1500)};return v?e.createElement(E,{title:"Biteship Settings",isLoading:!0}):e.createElement(E,{title:"Biteship Shipping Settings",description:"Configure your Biteship integration for Indonesian shipping"},e.createElement(c,{title:"API Configuration",description:"Connect your Biteship account"},e.createElement("div",{className:"space-y-4"},e.createElement("div",{className:"space-y-2"},e.createElement("label",{className:"text-sm font-medium"},"API Key"),e.createElement("div",{className:"flex gap-2"},e.createElement(o,{type:"password",value:n.api_key||"",onChange:t=>a("api_key",t.target.value),placeholder:"biteship_xxxxxxxxxxxxx"}),e.createElement(f,{variant:"outline",onClick:C,disabled:d},d?"Testing...":"Test Connection")),s&&e.createElement("div",{className:`flex items-center gap-2 text-sm ${s==="success"?"text-green-600":"text-red-600"}`},e.createElement(s==="success"?W:T,{className:"h-4 w-4"}),s==="success"?"Connection successful":"Connection failed")),e.createElement("div",{className:"space-y-2"},e.createElement("label",{className:"text-sm font-medium"},"Environment"),e.createElement(I,{value:n.environment||"test",onValueChange:t=>a("environment",t)},e.createElement(P,null,e.createElement(B,null)),e.createElement(A,null,e.createElement(h,{value:"test"},"Test Mode"),e.createElement(h,{value:"production"},"Production"))),e.createElement("p",{className:"text-xs text-muted-foreground"},"Use test mode for development and testing")))),e.createElement(c,{title:"Origin Location",description:"Your warehouse or pickup location"},e.createElement("div",{className:"grid grid-cols-2 gap-4"},e.createElement("div",{className:"space-y-2"},e.createElement("label",{className:"text-sm font-medium"},"Latitude"),e.createElement(o,{value:n.origin_lat||"",onChange:t=>a("origin_lat",t.target.value),placeholder:"-6.200000"})),e.createElement("div",{className:"space-y-2"},e.createElement("label",{className:"text-sm font-medium"},"Longitude"),e.createElement(o,{value:n.origin_lng||"",onChange:t=>a("origin_lng",t.target.value),placeholder:"106.816666"})))),e.createElement(c,{title:"Features",description:"Enable or disable shipping features"},e.createElement("div",{className:"space-y-4"},e.createElement("div",{className:"flex items-center justify-between"},e.createElement("div",null,e.createElement("p",{className:"font-medium"},"Cash on Delivery"),e.createElement("p",{className:"text-sm text-muted-foreground"},"Allow customers to pay on delivery")),e.createElement(r,{checked:n.enable_cod||!1,onCheckedChange:t=>a("enable_cod",t)})),e.createElement("div",{className:"flex items-center justify-between"},e.createElement("div",null,e.createElement("p",{className:"font-medium"},"Shipping Insurance"),e.createElement("p",{className:"text-sm text-muted-foreground"},"Automatically add insurance to shipments")),e.createElement(r,{checked:n.enable_insurance!==!1,onCheckedChange:t=>a("enable_insurance",t)})),e.createElement("div",{className:"flex items-center justify-between"},e.createElement("div",null,e.createElement("p",{className:"font-medium"},"Debug Mode"),e.createElement("p",{className:"text-sm text-muted-foreground"},"Log API requests for troubleshooting")),e.createElement(r,{checked:n.debug_mode||!1,onCheckedChange:t=>a("debug_mode",t)})))),e.createElement("div",{className:"flex justify-end"},e.createElement(f,{onClick:x,disabled:i.isPending},e.createElement(L,{className:"mr-2 h-4 w-4"}),i.isPending?"Saving...":"Save Settings")))}window.WooNooWAddon_biteship_shipping=j;})();