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 && (