Dwindi Ramadhana
9204189448
fix: add more hooks for license generation on order completion
...
- Added woocommerce_payment_complete hook
- Added woocommerce_thankyou hook for COD/virtual orders
- Added is_virtual_order helper to detect virtual-only orders
- generate_licenses_for_order now called from multiple hooks
(safe due to license_exists_for_order_item check)
2026-01-07 22:58:29 +07:00
Dwindi Ramadhana
d7b132d9d9
fix: dbDelta separate tables, add SEOHead for page titles
...
1. License table creation:
- dbDelta requires separate calls per CREATE TABLE
- Split into sql_licenses and sql_activations
- Added 'PRIMARY KEY (id)' with two spaces (dbDelta requirement)
2. Page titles:
- Added SEOHead to Cart page (title: Shopping Cart)
- Added SEOHead to Checkout page (title: Checkout)
- Shop already had SEOHead
3. usePageTitle hook created (alternative to SEOHead for non-Helmet usage)
2026-01-07 22:40:45 +07:00
Dwindi Ramadhana
2cc20ff760
fix: licensing table creation, consistent meta keys, checkout virtual detection
...
1. License table auto-creation:
- Added ensure_tables() check on plugins_loaded
- Tables created automatically if missing
2. Consistent licensing meta keys:
- ProductsController now uses _woonoow_licensing_enabled
- Matches LicensingModule and LicenseManager
3. Checkout virtual-only detection:
- Added needs_shipping to Cart interface
- Checkout uses cart.needs_shipping from WooCommerce API
- Fallback to item-level virtual/downloadable check
4. Login redirect for logged-in users added previously
2026-01-07 22:15:51 +07:00
Dwindi Ramadhana
f334e018fa
fix: 4 bugs - checkout virtual, login redirect, licensing, categories
...
1. Virtual-only checkout:
- Added 'virtual' and 'downloadable' to CartController response
- Checkout can now detect virtual-only carts
2. Login redirect:
- Added useEffect to redirect logged-in users to /my-account
3. License generation:
- Fixed meta key mismatch (_woonoow_licensing_enabled -> _licensing_enabled)
4. Product categories:
- Added queryClient.invalidateQueries after creating new category
- List now refreshes immediately
2026-01-07 21:08:01 +07:00
Dwindi Ramadhana
b367c1fcf8
feat: Add licensing module backend
...
- LicensingSettings.php with key format, activation limits, expiry settings
- LicenseManager.php with key generation, activation/deactivation, validation
- LicensingModule.php with WooCommerce product meta integration
- LicensesController.php with admin, customer, and public API endpoints
- Database tables: woonoow_licenses, woonoow_license_activations
- has_settings enabled in ModuleRegistry
2026-01-05 16:20:32 +07:00
Dwindi Ramadhana
d7505252ac
feat: complete Newsletter Campaigns Phase 1
...
- Add default campaign email template to DefaultTemplates.php
- Add toggle settings (campaign_scheduling, subscriber_limit_enabled)
- Add public unsubscribe endpoint with secure token verification
- Update CampaignManager to use NewsletterController unsubscribe URLs
- Add generate_unsubscribe_url() helper for email templates
2025-12-31 21:17:59 +07:00
Dwindi Ramadhana
4095d2a70c
feat: Wishlist settings cleanup + Categories/Tags/Attributes CRUD pages
...
Wishlist Settings Cleanup:
- Removed wishlist_page setting (not needed for SPA architecture)
- Marked advanced features as 'Coming Soon' with disabled flag:
* Wishlist Sharing
* Back in Stock Notifications
* Multiple Wishlists
- Added disabled prop support to SchemaField toggle component
- Kept only working features: guest wishlist, show in header, max items, add to cart button
Product Taxonomy CRUD Pages:
Built full CRUD interfaces for all three taxonomy types:
1. Categories (/products/categories):
- Table view with search
- Create/Edit dialog with name, slug, description
- Delete with confirmation
- Product count display
- Parent category support
2. Tags (/products/tags):
- Table view with search
- Create/Edit dialog with name, slug, description
- Delete with confirmation
- Product count display
3. Attributes (/products/attributes):
- Table view with search
- Create/Edit dialog with label, slug, type, orderby
- Delete with confirmation
- Type selector (Select/Text)
- Sort order selector (Custom/Name/ID)
All pages include:
- React Query for data fetching/mutations
- Toast notifications for success/error
- Loading states
- Empty states
- Responsive tables
- Dialog forms with validation
Files Modified:
- includes/Modules/WishlistSettings.php (removed page selector, marked advanced as coming soon)
- admin-spa/src/components/forms/SchemaField.tsx (added disabled prop)
- admin-spa/src/routes/Products/Categories.tsx (full CRUD)
- admin-spa/src/routes/Products/Tags.tsx (full CRUD)
- admin-spa/src/routes/Products/Attributes.tsx (full CRUD)
- admin-spa/src/components/nav/SubmenuBar.tsx (removed debug logging)
- admin-spa/dist/app.js (rebuilt)
Result:
✅ Wishlist settings now clearly show what's implemented vs coming soon
✅ Categories/Tags/Attributes pages fully functional
✅ Professional CRUD interfaces matching admin design
✅ All taxonomy management now in SPA
2025-12-26 23:43:40 +07:00
Dwindi Ramadhana
daebd5f989
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
2025-12-26 21:29:27 +07:00
Dwindi Ramadhana
c6cef97ef8
feat: Implement Phase 2, 3, 4 - Module Settings System with Schema Forms and Addon API
...
Phase 2: Schema-Based Form System
- Add ModuleSettingsController with GET/POST/schema endpoints
- Create SchemaField component supporting 8 field types (text, textarea, email, url, number, toggle, checkbox, select)
- Create SchemaForm component for automatic form generation from schema
- Add ModuleSettings page with dynamic routing (/settings/modules/:moduleId)
- Add useModuleSettings React hook for settings management
- Implement NewsletterSettings as example with 8 configurable fields
- Add has_settings flag to module registry
- Settings stored as woonoow_module_{module_id}_settings
Phase 3: Advanced Features
- Create windowAPI.ts exposing React, hooks, components, icons, utils to addons via window.WooNooW
- Add DynamicComponentLoader for loading external React components
- Create TypeScript definitions (woonoow-addon.d.ts) for addon developers
- Initialize Window API in App.tsx on mount
- Enable custom React components for addon settings pages
Phase 4: Production Polish & Example
- Create complete Biteship addon example demonstrating both approaches:
* Schema-based settings (no build required)
* Custom React component (with build)
- Add comprehensive README with installation and testing guide
- Include package.json with esbuild configuration
- Demonstrate window.WooNooW API usage in custom component
Bug Fixes:
- Fix footer newsletter form visibility (remove redundant module check)
- Fix footer contact_data and social_links not saving (parameter name mismatch: snake_case vs camelCase)
- Fix useModules hook returning undefined (remove .data wrapper, add fallback)
- Add optional chaining to footer settings rendering
- Fix TypeScript errors in woonoow-addon.d.ts (use any for external types)
Files Added (15):
- includes/Api/ModuleSettingsController.php
- includes/Modules/NewsletterSettings.php
- admin-spa/src/components/forms/SchemaField.tsx
- admin-spa/src/components/forms/SchemaForm.tsx
- admin-spa/src/routes/Settings/ModuleSettings.tsx
- admin-spa/src/hooks/useModuleSettings.ts
- admin-spa/src/lib/windowAPI.ts
- admin-spa/src/components/DynamicComponentLoader.tsx
- types/woonoow-addon.d.ts
- examples/biteship-addon/biteship-addon.php
- examples/biteship-addon/src/Settings.jsx
- examples/biteship-addon/package.json
- examples/biteship-addon/README.md
- PHASE_2_3_4_SUMMARY.md
Files Modified (11):
- admin-spa/src/App.tsx
- admin-spa/src/hooks/useModules.ts
- admin-spa/src/routes/Appearance/Footer.tsx
- admin-spa/src/routes/Settings/Modules.tsx
- customer-spa/src/hooks/useModules.ts
- customer-spa/src/layouts/BaseLayout.tsx
- customer-spa/src/components/NewsletterForm.tsx
- includes/Api/Routes.php
- includes/Api/ModulesController.php
- includes/Core/ModuleRegistry.php
- woonoow.php
API Endpoints Added:
- GET /woonoow/v1/modules/{module_id}/settings
- POST /woonoow/v1/modules/{module_id}/settings
- GET /woonoow/v1/modules/{module_id}/schema
For Addon Developers:
- Schema-based: Define settings via woonoow/module_settings_schema filter
- Custom React: Build component using window.WooNooW API, externalize react/react-dom
- Both approaches use same storage and retrieval methods
- TypeScript definitions provided for type safety
- Complete working example (Biteship) included
2025-12-26 21:16:06 +07:00