From 10b3c0e47f14ac33dd0eb9efa882fafc6df6ebcf Mon Sep 17 00:00:00 2001 From: Dwindi Ramadhana Date: Thu, 1 Jan 2026 17:17:12 +0700 Subject: [PATCH] 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 --- customer-spa/src/pages/Login/index.tsx | 33 ++++++++++++++++ customer-spa/src/pages/ThankYou/index.tsx | 47 ++++++++++++++++------- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/customer-spa/src/pages/Login/index.tsx b/customer-spa/src/pages/Login/index.tsx index ea2eee6..413852b 100644 --- a/customer-spa/src/pages/Login/index.tsx +++ b/customer-spa/src/pages/Login/index.tsx @@ -54,6 +54,39 @@ export default function Login() { }; } + // Merge guest wishlist to account + const GUEST_WISHLIST_KEY = 'woonoow_guest_wishlist'; + try { + const stored = localStorage.getItem(GUEST_WISHLIST_KEY); + if (stored) { + const guestProductIds = JSON.parse(stored) as number[]; + if (guestProductIds.length > 0) { + // Merge each product to account wishlist + const newNonce = data.nonce; + for (const productId of guestProductIds) { + try { + await fetch(`${apiRoot}/account/wishlist`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': newNonce, + }, + credentials: 'include', + body: JSON.stringify({ product_id: productId }), + }); + } catch (e) { + // Skip if product already in wishlist or other error + console.debug('Wishlist merge skipped for product:', productId); + } + } + // Clear guest wishlist after merge + localStorage.removeItem(GUEST_WISHLIST_KEY); + } + } + } catch (e) { + console.error('Failed to merge guest wishlist:', e); + } + toast.success('Login successful!'); // Set the target URL with hash route, then force reload diff --git a/customer-spa/src/pages/ThankYou/index.tsx b/customer-spa/src/pages/ThankYou/index.tsx index 529f8e8..0c36750 100644 --- a/customer-spa/src/pages/ThankYou/index.tsx +++ b/customer-spa/src/pages/ThankYou/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { useParams, Link, useSearchParams } from 'react-router-dom'; import { useThankYouSettings } from '@/hooks/useAppearanceSettings'; import Container from '@/components/Layout/Container'; -import { CheckCircle, ShoppingBag, Package, Truck } from 'lucide-react'; +import { CheckCircle, ShoppingBag, Package, Truck, User } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { formatPrice } from '@/lib/currency'; import { apiClient } from '@/lib/api/client'; @@ -16,6 +16,7 @@ export default function ThankYou() { const [relatedProducts, setRelatedProducts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const isLoggedIn = (window as any).woonoowCustomer?.user?.isLoggedIn; useEffect(() => { const fetchOrderData = async () => { @@ -186,14 +187,24 @@ export default function ThankYou() { : 'Thank you for your business!'}

- {elements.continue_shopping_button && ( - - - - )} +
+ {elements.continue_shopping_button && ( + + + + )} + {isLoggedIn && ( + + + + )} +
@@ -430,17 +441,25 @@ export default function ThankYou() { )} - {/* Continue Shopping Button */} - {elements.continue_shopping_button && ( -
+ {/* Action Buttons */} +
+ {elements.continue_shopping_button && ( -
- )} + )} + {isLoggedIn && ( + + + + )} +
{/* Related Products */} {elements.related_products && relatedProducts.length > 0 && (