Commit Graph

440 Commits

Author SHA1 Message Date
Dwindi Ramadhana
1af1add5d4 fix: show reset_link in button URL variable suggestions
Button modals in both RichTextEditor and EmailBuilder filtered
for _url variables only, excluding reset_link. Updated filter to
include both _url and _link patterns.

Files changed:
- rich-text-editor.tsx line 415
- EmailBuilder.tsx line 359
2026-01-01 22:12:26 +07:00
Dwindi Ramadhana
6bd50c1659 fix: button href broken by variable highlighting HTML spans
ROOT CAUSE (from screenshot DevTools):
href="<span style=...>[login_url]</span>" - HTML span inside href attribute!

Flow causing the bug:
1. parseCardsForPreview converts [button url="{login_url}"] to <a href="{login_url}">
2. sampleData replacement runs but login_url NOT in sampleData
3. Variable highlighting injects <span>[login_url]</span> INTO href="..."
4. HTML is completely broken

FIXES APPLIED:
1. Added missing URL variables to sampleData:
   - login_url, reset_link, reset_key
   - user_login, user_email, user_temp_password
   - customer_first_name, customer_last_name

2. Changed variable highlighting from HTML spans to plain text [variable]
   - Prevents breaking HTML attributes if variable is inside href, src, etc.
2026-01-01 22:04:20 +07:00
Dwindi Ramadhana
5a831ddf9d fix: button/card syntax mismatch between blocksToMarkdown and markdownToBlocks
ROOT CAUSE: Complete flow trace revealed syntax mismatch:
- blocksToMarkdown outputs NEW syntax: [card:type], [button:style](url)Text[/button]
- markdownToBlocks ONLY parsed OLD syntax: [card type="..."], [button url="..."]

This caused buttons/cards to be lost when:
1. User adds button in Visual mode
2. blocksToMarkdown converts to [button:solid]({url})Text[/button]
3. handleBlocksChange stores this in markdownContent
4. When switching tabs/previewing, markdownToBlocks runs
5. It FAILED to parse new syntax, buttons disappear!

FIX: Added handlers for NEW syntax in markdownToBlocks (converter.ts):
- [card:type]...[/card] pattern (before old syntax)
- [button:style](url)Text[/button] pattern (before old syntax)

Now both syntaxes work correctly in round-trip conversion.
2026-01-01 21:57:58 +07:00
Dwindi Ramadhana
70006beeb9 fix: button rendering consistency between visual and preview
Root cause: parseCardsForPreview was called TWICE in generatePreviewHTML:
1. Line 179 - correctly parses markdown to HTML including buttons
2. Line 283 - redundantly called AGAIN after variable highlighting

After first call, variable highlighting (lines 275-280) replaced unknown
variables like {login_url} with <span>[login_url]</span>. When the second
parseCardsForPreview ran, the [login_url] text was misinterpreted as
shortcode syntax, corrupting button HTML output.

Fix: Remove the redundant second call to parseCardsForPreview at line 283.
The function is already called at line 179 before any variable replacement.
2026-01-01 21:51:39 +07:00
Dwindi Ramadhana
e84fa969bb fix: button rendering from RichEditor to markdown to HTML
- Added multiple htmlToMarkdown patterns for TipTap button output:
  1. data-button with data-href/data-style attributes
  2. Alternate attribute order (data-style before data-href)
  3. Simple data-button fallback with href and class
  4. Buttons wrapped in p tags (from preview HTML)
  5. Direct button links without p wrapper

- Button shortcodes now correctly roundtrip:
  RichEditor -> HTML -> [button url=... style=...] -> Preview/Email

- All patterns now explicitly include style=solid for consistency
2026-01-01 21:37:55 +07:00
Dwindi Ramadhana
ccdd88a629 fix: template save API + contextual variables per event
1. API Route Fix (NotificationsController.php):
   - Changed PUT to POST for /templates/:eventId/:channelId
   - Frontend was using api.post() but backend only accepted PUT
   - Templates can now be saved

2. Contextual Variables (EventRegistry.php):
   - Added get_variables_for_event() method
   - Returns category-based variables (order, customer, product, etc.)
   - Merges event-specific variables from event definition
   - Sorted alphabetically for easy browsing

3. API Response (NotificationsController.php):
   - Template API now returns available_variables for the event
   - Frontend can show only relevant variables

4. Frontend (EditTemplate.tsx):
   - Removed hardcoded 50+ variable list
   - Now uses template.available_variables from API
   - Variables update based on selected event type
2026-01-01 21:31:10 +07:00
Dwindi Ramadhana
b8f179a984 feat: password reset email event with WooNooW template 2026-01-01 20:54:27 +07:00
Dwindi Ramadhana
78d7bc1161 fix: auto-login after checkout, ThankYou guest buttons, forgot password page
1. Auto-login after checkout:
   - Added wp_set_auth_cookie() and wp_set_current_user() in CheckoutController
   - Auto-registered users are now logged in when thank-you page loads

2. ThankYou page guest buttons:
   - Added 'Login / Create Account' button for guests
   - Shows for both receipt and basic templates
   - No more dead-end after placing order as guest

3. Forgot password flow:
   - Created ForgotPassword page component (/forgot-password route)
   - Added forgot_password API endpoint in AuthController
   - Uses WordPress retrieve_password() for reset email
   - Replaced wp-login.php link in Login page
2026-01-01 17:36:40 +07:00
Dwindi Ramadhana
62f25b624b feat: auto-login after checkout via page reload
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.
2026-01-01 17:25:19 +07:00
Dwindi Ramadhana
10b3c0e47f feat: Go-to-Account button + wishlist merge on login
1. ThankYou page - Go to Account button:
   - Added for logged-in users (next to Continue Shopping)
   - Shows in both receipt and basic templates
   - Uses outline variant with User icon

2. Wishlist merge on login:
   - Reads guest wishlist from localStorage (woonoow_guest_wishlist)
   - POSTs each product to /account/wishlist API
   - Handles duplicates gracefully (skips on error)
   - Clears localStorage after successful merge
2026-01-01 17:17:12 +07:00
Dwindi Ramadhana
508ec682a7 fix: login page reload + custom logout dialog
1. Login fix:
   - Added window.location.reload() after setting hash URL
   - Forces full page reload to refresh cookies from server
   - Resolves 'Cookie check failed' error after login

2. Logout UX improvement:
   - Created alert-dialog.tsx component (Radix UI AlertDialog)
   - Replaced window.confirm() with custom AlertDialog
   - Dialog shows: title, description, Cancel/Log Out buttons
   - Red 'Log Out' action button for clear intent
2026-01-01 17:08:34 +07:00
Dwindi Ramadhana
c83ea78911 feat: improve login/logout flow in customer SPA
1. Logout flow:
   - Added confirmation dialog (window.confirm)
   - Changed to API-based logout (/auth/logout)
   - Full page reload after logout to clear cookies
   - Added loading state during logout

2. Login flow (already correct):
   - Uses window.location.href for full page redirect
   - Redirects to /store/#/my-account after login
2026-01-01 17:00:11 +07:00
Dwindi Ramadhana
58681e272e feat: temp password in emails + WC page redirects to SPA
1. Temp password for auto-registered users:
   - Store password in _woonoow_temp_password user meta (CheckoutController)
   - Add {user_temp_password} and {login_url} variables (EmailRenderer)
   - Update new_customer email template to show credentials

2. WC page redirects to SPA routes:
   - Added redirect_wc_pages_to_spa() in TemplateOverride
   - Maps: /shop → /store/#/, /cart → /store/#/cart, etc.
   - /checkout → /store/#/checkout, /my-account → /store/#/account
   - Single products → /store/#/products/{slug}

3. Removed shortcode system:
   - Commented out Shortcodes::init() in Bootstrap
   - WC pages now redirect to SPA instead
2026-01-01 16:45:24 +07:00
Dwindi Ramadhana
38a7a4ee23 fix: email variable replacement + icon URL path
1. Added missing base variables in get_variables():
   - site_name, site_title, store_name
   - shop_url, my_account_url
   - support_email, current_year

2. Fixed social icon URL path calculation:
   - Was using 3x dirname which pointed to 'includes/' not plugin root
   - Now uses WOONOOW_URL constant or correct 4x dirname

3. Added px-6 padding to EmailBuilder dialog body

4. Added portal container to Select component for CSS scoping
2026-01-01 02:12:09 +07:00
Dwindi Ramadhana
875ab7af34 fix: dialog portal scope + UX improvements
1. Dialog Portal: Render inside #woonoow-admin-app container instead
   of document.body to fix Tailwind CSS scoping in WordPress admin

2. Variables Panel: Redesigned from flat list to collapsible accordion
   - Collapsed by default (less visual noise)
   - Categorized: Order (blue), Customer (green), Shipping (orange), Store (purple)
   - Color-coded pills for quick recognition
   - Shows count of available variables

3. StarterKit: Disable built-in Link to prevent duplicate extension warning
2026-01-01 01:53:22 +07:00
Dwindi Ramadhana
861c45638b fix: resolve dialog freeze caused by infinite loop in RichTextEditor
The RichTextEditor useEffect was comparing raw content with editor HTML,
but they differed due to whitespace normalization (e.g., '\n\n' vs '').
This caused continuous setContent calls, freezing the edit dialog.

Fixed by normalizing whitespace in both strings before comparison.
2026-01-01 01:19:55 +07:00
Dwindi Ramadhana
8bd2713385 fix: resolve tiptap duplicate Link extension warning
StarterKit 3.10+ now includes Link by default. Our code was adding
Link.configure() separately, causing duplicate extension warning and
breaking the email builder visual editor modal.

Fixed by configuring StarterKit with { link: false } so our custom
Link.configure() with specific options is the only Link extension.
2026-01-01 01:16:47 +07:00
Dwindi Ramadhana
9671c7255a fix: visual editor dialog and password reset flow
1. EmailBuilder: Fixed dialog handlers to not block all interactions
   - Previously dialog prevented all outside clicks
   - Now only blocks when WP media modal is open
   - Dialog can be properly closed via escape or outside click

2. DefaultTemplates: Updated new_customer email
   - Added note about using 'Forgot Password?' if link expires
   - Clear instructions for users
2026-01-01 01:12:08 +07:00
Dwindi Ramadhana
52cea87078 fix: email buttons now render with inline styles for Gmail
1. EmailRenderer: Added button parsing with full inline styles
   - Buttons now use table-based layout for email client compatibility
   - Solid and outline button styles with custom colors from settings

2. DefaultTemplates: Updated new_customer template
   - Added 'Set Your Password' button for auto-registered users
   - Uses {set_password_url} variable for password reset link

3. EmailRenderer: Added set_password_url variable
   - Generates secure password reset link for new customers
   - Also added my_account_url and shop_url to customer variables
2026-01-01 01:06:18 +07:00
Dwindi Ramadhana
e9e54f52a7 fix: update all header login links to use SPA login
- BaseLayout.tsx: Updated 4 guest account links
- Wishlist.tsx: Updated guest wishlist login link
- All now use Link to /login instead of href to /wp-login.php
2025-12-31 22:50:58 +07:00
Dwindi Ramadhana
4fcc69bfcd chore: add input and label UI components for customer-spa 2025-12-31 22:44:35 +07:00
Dwindi Ramadhana
56042d4b8e feat: add customer login page in SPA
- Created Login/index.tsx with styled form
- Added /auth/customer-login API endpoint (no admin perms required)
- Registered route in Routes.php
- Added /login route in customer-spa App.tsx
- Account page now redirects to SPA login instead of wp-login.php
- Login supports redirect param for post-login navigation
2025-12-31 22:43:13 +07:00
Dwindi Ramadhana
3d7eb5bf48 fix: multiple checkout and settings fixes
1. Remove wishlist setting from customer settings (now in module toggle)
   - Removed from CustomerSettingsProvider.php
   - Removed from Customers.tsx

2. Remove auto-login from REST API (causes cookie issues)
   - Auto-login in REST context doesn't properly set browser cookies
   - Removed wp_set_current_user/wp_set_auth_cookie calls

3. Fix cart not clearing after order
   - Added WC()->cart->empty_cart() after successful order
   - Server-side cart was not being cleared, causing re-population
   - Frontend clears local store but Cart page syncs with server
2025-12-31 22:29:59 +07:00
Dwindi Ramadhana
f97cca8061 fix: properly clear cart 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
2025-12-31 22:18:06 +07:00
Dwindi Ramadhana
f79938c5be feat: auto-login newly registered customers after checkout
- After creating new user account, immediately log them in
- Uses wp_set_current_user() and wp_set_auth_cookie()
- Provides smoother UX - customer is logged in after placing order
2025-12-31 22:06:57 +07:00
Dwindi Ramadhana
0dd7c7af70 fix: make module settings GET endpoint public
- Shop page and other customer pages need to read module settings
- Settings are non-sensitive configuration values (e.g. wishlist display)
- POST endpoint remains admin-only for security
- Fixes 401 errors on shop page for /modules/wishlist/settings
2025-12-31 22:01:06 +07:00
Dwindi Ramadhana
285589937a feat: add auto-register to CheckoutController for guest checkout
- When 'Auto-register customers as site members' is enabled
- Creates WP user account with 'customer' role for guest checkouts
- Links order to existing user if email already registered
- Sets WooCommerce customer billing data on new account
- Triggers woocommerce_created_customer action for email notification
2025-12-31 21:55:18 +07:00
Dwindi Ramadhana
a87357d890 fix: thank you page 401 error
- 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
2025-12-31 21:42:40 +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
3d5191aab3 feat: add Newsletter Campaigns frontend UI
- Add Campaigns list page with table, status badges, search, actions
- Add Campaign editor with title, subject, content fields
- Add preview modal, test email dialog, send confirmation
- Update Marketing index to show hub with Newsletter, Campaigns, Coupons cards
- Add routes in App.tsx
2025-12-31 18:59:49 +07:00
Dwindi Ramadhana
65dd847a66 feat: add Newsletter Campaigns backend infrastructure
- Add CampaignManager.php with CPT registration, CRUD, batch sending
- Add CampaignsController.php with 8 REST endpoints (list, create, get, update, delete, send, test, preview)
- Register newsletter_campaign event in EventRegistry for email template
- Initialize CampaignManager in Bootstrap.php
- Register routes in Routes.php
2025-12-31 14:58:57 +07:00
Dwindi Ramadhana
2dbc43a4eb fix: simplify More page - Marketing as simple button without submenu
- Remove inline submenu expansion for Marketing
- Keep it consistent with Appearance and Settings (simple buttons)
- Description provides enough context about what's inside
2025-12-31 14:27:06 +07:00
Dwindi Ramadhana
771c48e4bb fix: align mobile bottom bar with desktop nav structure
- Add Marketing section to More page with Newsletter and Coupons submenu
- Remove standalone Coupons entry (now under Marketing)
- Add submenu rendering support for items with children
- Use Megaphone icon for Marketing section
2025-12-31 14:19:08 +07:00
Dwindi Ramadhana
4104c6d6ba docs: update Feature Roadmap with accurate module statuses
- Module 1 (Module Management): Changed from Planning to Built
- Added Module Management to 'Already Built' section
- Marked Product Reviews as not yet implemented
- Updated last modified date
2025-12-31 14:09:38 +07:00
Dwindi Ramadhana
82399d4ddf fix: WP-Admin CSS conflicts and add-to-cart redirect
- Fix CSS conflicts between WP-Admin and SPA (radio buttons, chart text)
- Add Tailwind important selector scoped to #woonoow-admin-app
- Remove overly aggressive inline SVG styles from Assets.php
- Add targeted WordPress admin CSS overrides in index.css
- Fix add-to-cart redirect to use woocommerce_add_to_cart_redirect filter
- Let WooCommerce handle cart operations natively for proper session management
- Remove duplicate tailwind.config.cjs
2025-12-31 14:06:04 +07:00
Dwindi Ramadhana
93523a74ac feat: Add-to-cart from URL parameters
Implements direct-to-cart functionality for landing page CTAs.

Features:
- Parse URL parameters: ?add-to-cart=123
- Support simple products: ?add-to-cart=123
- Support variable products: ?add-to-cart=123&variation_id=456
- Support quantity: ?add-to-cart=123&quantity=2
- Auto-navigate to cart after adding
- Clean URL after adding (remove parameters)
- Toast notification on success/error

Usage examples:
1. Simple product:
   https://site.com/store?add-to-cart=332

2. Variable product:
   https://site.com/store?add-to-cart=332&variation_id=456

3. With quantity:
   https://site.com/store?add-to-cart=332&quantity=3

Flow:
- User clicks CTA on landing page
- Redirects to SPA with add-to-cart parameter
- SPA loads, hook detects parameter
- Adds product to cart via API
- Navigates to cart page
- Shows success toast

Works with both SPA modes:
- Full SPA: loads shop, adds to cart, navigates to cart
- Checkout Only: loads cart, adds to cart, stays on cart
2025-12-30 20:54:54 +07:00
Dwindi Ramadhana
2c4050451c feat: Customer SPA reads initial route from data attribute
Changes:
- App.tsx reads data-initial-route attribute from #woonoow-customer-app
- Root route (/) redirects to initial route based on SPA mode
- Fallback route (*) also redirects to initial route
- Full SPA mode: initial route = /shop
- Checkout Only mode: initial route = /cart

Flow:
1. User visits /store page (SPA entry page)
2. PHP template sets data-initial-route based on spa_mode setting
3. React reads attribute and navigates to correct initial route
4. HashRouter handles rest: /#/product/123, /#/checkout, etc.

Example:
- Full SPA: /store loads → redirects to /#/shop
- Checkout Only: /store loads → redirects to /#/cart
- User can navigate: /#/product/abc, /#/checkout, etc.

Next: Add direct-to-cart functionality with product parameter
2025-12-30 20:34:40 +07:00
Dwindi Ramadhana
fe98e6233d refactor: Simplify to single SPA entry page architecture
User feedback: 'SPA means Single Page, why 4 pages?'

Correct architecture:
- 1 SPA entry page (e.g., /store)
- SPA Mode determines initial route:
  * Full SPA → starts at shop page
  * Checkout Only → starts at cart page
  * Disabled → never loads
- React Router handles rest via /#/ routing

Changes:
- Admin UI: Changed from 4 page selectors to 1 SPA entry page
- Backend: spa_pages array → spa_page integer
- Template: Initial route based on spa_mode setting
- Simplified is_spa_page() checks (single ID comparison)

Benefits:
- User can set /store as homepage (Settings → Reading)
- Landing page → CTA → direct to cart/checkout
- Clean single entry point
- Mode controls behavior, not multiple pages

Example flow:
- Visit https://site.com/store
- Full SPA: loads shop, navigate via /#/product/123
- Checkout Only: loads cart, navigate via /#/checkout
- Homepage: set /store as homepage, SPA loads on site root

Next: Add direct-to-cart CTA with product parameter
2025-12-30 20:33:15 +07:00
Dwindi Ramadhana
f054a78c5d feat: Add SPA page selection UI in admin
Complete WooCommerce-style page architecture implementation:

Backend (already committed):
- API endpoint to fetch WordPress pages
- spa_pages field in appearance settings
- is_spa_page() checks in TemplateOverride and Assets

Frontend (this commit):
- Added page selector UI in Appearance > General
- Dropdowns for Shop, Cart, Checkout, Account pages
- Loads available WordPress pages from API
- Saves selected page IDs to settings
- Info alert explaining full-body rendering

UI Features:
- Clean page selection interface
- Shows all published WordPress pages
- '— None —' option to disable
- Integrated into existing General settings tab
- Follows existing design patterns

How it works:
1. Admin selects pages in Appearance > General
2. Page IDs saved to woonoow_appearance_settings
3. Frontend checks if current page matches selected pages
4. If match, renders full SPA to body (no theme interference)
5. Works with ANY theme consistently

Next: Test page selection and verify clean SPA rendering
2025-12-30 20:19:46 +07:00
Dwindi Ramadhana
012effd11d feat: Add dedicated SPA page selection (WooCommerce-style)
Problem: Shortcode 'island' architecture is fragile and theme-dependent
- SPA div buried deep in theme structure (body > div.wp-site-blocks > main > div#app)
- Theme and plugins can intervene at any level
- Different themes have different structures
- Breaks easily with theme changes

Solution: Dedicated page-based SPA system (like WooCommerce)
- Add page selection in Appearance > General settings
- Store page IDs for Shop, Cart, Checkout, Account
- Full-body SPA rendering on designated pages
- No theme interference

Changes:
- AppearanceController.php:
  * Added spa_pages field to general settings
  * Stores page IDs for each SPA type (shop/cart/checkout/account)

- TemplateOverride.php:
  * Added is_spa_page() method to check designated pages
  * Use blank template for designated pages (priority over legacy)
  * Remove theme elements for designated pages

- Assets.php:
  * Added is_spa_page() check before mode/shortcode checks
  * Load assets on designated pages regardless of mode

Architecture:
- Designated pages render directly to <body>
- No theme wrapper/structure interference
- Clean full-page SPA experience
- Works with ANY theme consistently

Next: Add UI in admin-spa General tab for page selection
2025-12-30 19:42:16 +07:00
Dwindi Ramadhana
48a5a5593b fix: Include fonts in production build and strengthen theme override
Problem 1: Fonts not loading (404 errors)
Root Cause: Build script only copied app.js and app.css, not fonts folder
Solution: Include fonts directory in production build

Problem 2: Theme header/footer still showing on some themes
Root Cause: Header/footer removal only worked in 'full' mode, not for shortcode pages
Solution:
- Use blank template (spa-full-page.php) for ANY page with WooNooW shortcodes
- Remove theme elements for shortcode pages even in 'disabled' mode
- Stronger detection for Shop page (archive) shortcode check

Changes:
- build-production.sh: Copy fonts folder if exists
- TemplateOverride.php:
  * use_spa_template() now checks for shortcodes in disabled mode
  * should_remove_theme_elements() removes for shortcode pages
  * Added Shop page archive check for shortcode detection

Result:
 Fonts now included in production build (~500KB added)
 Theme header/footer removed on ALL shortcode pages
 Works with any theme (Astra, Twenty Twenty-Three, etc.)
 Clean SPA experience regardless of SPA mode setting
 Package size: 2.1M (was 1.6M, +500KB for fonts)
2025-12-30 19:34:39 +07:00
Dwindi Ramadhana
e0777c708b fix: Remove theme header and footer in Full SPA mode
Problem: Duplicate headers and footers showing (theme + SPA)
Root Cause: Theme's header and footer still rendering when Full SPA mode is active

Solution: Remove theme header/footer elements when on WooCommerce pages in Full SPA mode
- Hook into get_header and get_footer actions
- Remove all theme header/footer actions
- Keep only essential WordPress head/footer scripts
- Only applies when mode='full' and on WooCommerce pages

Changes:
- Added remove_theme_header() method
- Added remove_theme_footer() method
- Added should_remove_theme_elements() check
- Hooks into get_header and get_footer

Result:
 Clean SPA experience without theme header/footer
 Essential WordPress scripts still load
 Only affects Full SPA mode on WooCommerce pages
 Other pages keep theme header/footer
2025-12-30 18:10:29 +07:00
Dwindi Ramadhana
b2ac2996f9 fix: Detect shortcode on WooCommerce Shop page correctly
Problem: Customer SPA not loading on Shop page despite having [woonoow_shop] shortcode
Root Cause: WooCommerce Shop page is an archive page - when visiting /shop/, WordPress sets $post to the first product in the loop, not the Shop page itself. So shortcode check was checking product content instead of Shop page content.

Solution: Add special handling for is_shop() - get Shop page content directly using woocommerce_shop_page_id option and check for shortcode there.

Changes:
- Check is_shop() first before checking $post content
- Get Shop page via get_option('woocommerce_shop_page_id')
- Check shortcode on actual Shop page content
- Falls back to regular $post check for other pages

Result:
 Shop page shortcode detection now works correctly
 Customer SPA will load on Shop page with [woonoow_shop] shortcode
 Other WooCommerce pages (Cart, Checkout, Account) still work
2025-12-30 18:02:48 +07:00
Dwindi Ramadhana
c8ce892d15 debug: Add Shop page diagnostic script for live site troubleshooting 2025-12-30 17:59:49 +07:00
Dwindi Ramadhana
b6a0a66000 fix: Add SPA mounting point for full mode
Problem: Customer SPA not loading in 'full' mode
Root Cause: In full mode, SPA loads on WooCommerce pages without shortcodes, so there's no #woonoow-customer-app div for React to mount to

Solution: Inject mounting point div when in full mode via woocommerce_before_main_content hook

Changes:
- Added inject_spa_mount_point() method
- Hooks into woocommerce_before_main_content when in full mode
- Only injects if mount point doesn't exist from shortcode

Result:
 Full mode now has mounting point on WooCommerce pages
 Shortcode mode still works with shortcode-provided divs
 Customer SPA can now initialize properly
2025-12-30 17:54:12 +07:00
Dwindi Ramadhana
3260c8c112 debug: Add detailed logging to customer SPA asset loading
Added comprehensive logging to track:
- should_load_assets() decision flow
- SPA mode setting
- Post ID and content
- Shortcode detection
- Asset enqueue URLs
- Dev vs production mode

This will help identify why customer SPA is not loading.
2025-12-30 17:51:04 +07:00
Dwindi Ramadhana
0609c6e3d8 fix: Customer SPA loading and optimize production build size
Problem 1: Customer SPA not loading (stuck on 'Loading...')
Root Cause: Missing type='module' attribute on customer SPA script tag
Solution: Added script_loader_tag filter to inject type='module' for ES modules

Problem 2: Production zip too large (21-41MB)
Root Cause: Build script included unnecessary files (dist folder, fonts, .vite, test files, archives)
Solution:
- Exclude entire customer-spa and admin-spa directories from rsync
- Manually copy only app.js and app.css for both SPAs
- Exclude dist/, archive/, test-*.php, check-*.php files
- Simplified Frontend/Assets.php to always load app.js/app.css directly (no manifest needed)

Changes:
- includes/Frontend/Assets.php:
  * Added type='module' to customer SPA script (both manifest and fallback paths)
  * Removed manifest logic, always load app.js and app.css directly
- build-production.sh:
  * Exclude customer-spa and admin-spa directories completely
  * Manually copy only dist/app.js and dist/app.css
  * Exclude dist/, archive/, test files

Result:
 Customer SPA loads with type='module' support
 Production zip reduced from 21-41MB to 1.6MB
 Only essential files included (app.js + app.css for both SPAs)
 Clean production package without dev artifacts

Package contents:
- Customer SPA: 480K (app.js) + 52K (app.css) = 532K
- Admin SPA: 2.6M (app.js) + 76K (app.css) = 2.7M
- PHP Backend: ~500K
- Total: 1.6M (compressed)
2025-12-30 17:48:09 +07:00
Dwindi Ramadhana
a5e5db827b fix: Admin SPA loading and remove MailQueue debug logs
Problem 1: Admin SPA not loading in production
Root Cause: Vite builds require type='module' attribute on script tags
Solution: Added script_loader_tag filter to add type='module' to admin SPA script

Problem 2: Annoying MailQueue debug logs in console
Solution: Removed all error_log statements from MailQueue class
- Removed init() debug log
- Removed enqueue() debug log
- Removed all sendNow() debug logs (was 10+ lines)
- Kept only essential one-line log after successful send

Changes:
- includes/Admin/Assets.php: Add type='module' to wnw-admin script
- includes/Core/Mail/MailQueue.php: Remove debug logging noise

Result:
 Admin SPA now loads with proper ES module support
 MailQueue logs removed from console
 Email functionality still works (kept minimal logging)

Note: Production zip is 21M (includes .vite manifests and dynamic imports)
2025-12-30 17:33:35 +07:00
Dwindi Ramadhana
447ca501c7 fix: Generate Vite manifest for customer SPA loading
Problem: Customer SPA stuck on 'Loading...' message after installation
Root Cause: Vite build wasn't generating manifest.json, causing WordPress asset loader to fall back to direct app.js loading without proper module configuration

Solution:
1. Added manifest: true to both SPA vite configs
2. Updated Assets.php to look for manifest in correct location (.vite/manifest.json)
3. Rebuilt both SPAs with manifest generation

Changes:
- customer-spa/vite.config.ts: Added manifest: true
- admin-spa/vite.config.ts: Added manifest: true
- includes/Frontend/Assets.php: Updated manifest path from 'manifest.json' to '.vite/manifest.json'

Build Output:
- Customer SPA: dist/.vite/manifest.json generated
- Admin SPA: dist/.vite/manifest.json generated
- Production zip: 10M (includes manifest files)

Result:
 Customer SPA now loads correctly via manifest
 Admin SPA continues to work
 Proper asset loading with CSS and JS from manifest
 Production package ready for deployment
2025-12-30 17:26:18 +07:00
Dwindi Ramadhana
f1bab5ec46 fix: Include SPA dist folders in production build
Problem: Production zip was only 692K instead of expected 2.5MB+
Root Cause: Global --exclude='dist' was removing SPA build folders

Solution:
- Removed global dist exclusion
- Added specific exclusions for dev config files:
  - tailwind.config.js/cjs
  - postcss.config.js/cjs
  - .eslintrc.cjs
  - components.json
  - .cert directory

Result:
 Production zip now 5.2M (correct size)
 Customer SPA dist included (480K)
 Admin SPA dist included (2.6M)
 No dev config files in package

Verified:
- Activation hook creates pages with correct shortcodes:
  - [woonoow_shop]
  - [woonoow_cart]
  - [woonoow_checkout]
  - [woonoow_account]
- Installer reuses existing WooCommerce pages if available
- Sets WooCommerce HPOS enabled on activation
2025-12-30 17:21:38 +07:00