From 0f755cac53903703789231e14b3955baa146c438 Mon Sep 17 00:00:00 2001 From: optrader Date: Sun, 2 Nov 2025 11:04:13 +0900 Subject: [PATCH] [251102] fix: CartPanel mock-2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿ• ์ปค๋ฐ‹ ์‹œ๊ฐ„: 2025. 11. 02. 11:04:08 ๐Ÿ“Š ๋ณ€๊ฒฝ ํ†ต๊ณ„: โ€ข ์ด ํŒŒ์ผ: 10๊ฐœ โ€ข ์ถ”๊ฐ€: +453์ค„ โ€ข ์‚ญ์ œ: -162์ค„ ๐Ÿ“ ์ˆ˜์ •๋œ ํŒŒ์ผ: ~ com.twin.app.shoptime/src/actions/mockCartActions.js ~ com.twin.app.shoptime/src/reducers/mockCartReducer.js ~ com.twin.app.shoptime/src/utils/BuyNowDataManipulator.js ~ com.twin.app.shoptime/src/views/CartPanel/CartPanel.jsx ~ com.twin.app.shoptime/src/views/CartPanel/CartProduct.jsx ~ com.twin.app.shoptime/src/views/CartPanel/CartSidebar.jsx ~ com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx ~ com.twin.app.shoptime/src/views/CheckOutPanel/container/SummaryContainerMock.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/components/BuyOption.jsx ~ com.twin.app.shoptime/src/views/MainView/MainView.jsx ๐Ÿ”ง ์ฃผ์š” ๋ณ€๊ฒฝ ๋‚ด์šฉ: โ€ข ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ฐœ์„  โ€ข ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ์ตœ์ ํ™” โ€ข UI ์ปดํฌ๋„ŒํŠธ ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์„  โ€ข ๋Œ€๊ทœ๋ชจ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ โ€ข ๋ชจ๋“ˆ ๊ตฌ์กฐ ๊ฐœ์„  --- .../src/actions/mockCartActions.js | 63 +++++--- .../src/reducers/mockCartReducer.js | 20 +++ .../src/utils/BuyNowDataManipulator.js | 76 +--------- .../src/views/CartPanel/CartPanel.jsx | 25 ++- .../src/views/CartPanel/CartProduct.jsx | 28 +++- .../src/views/CartPanel/CartSidebar.jsx | 143 ++++++++++++++++-- .../src/views/CheckOutPanel/CheckOutPanel.jsx | 16 +- .../container/SummaryContainerMock.jsx | 101 +++++++++---- .../DetailPanel/components/BuyOption.jsx | 130 ++++++++++++++-- .../src/views/MainView/MainView.jsx | 7 +- 10 files changed, 450 insertions(+), 159 deletions(-) diff --git a/com.twin.app.shoptime/src/actions/mockCartActions.js b/com.twin.app.shoptime/src/actions/mockCartActions.js index 6206fb24..a1cf4200 100644 --- a/com.twin.app.shoptime/src/actions/mockCartActions.js +++ b/com.twin.app.shoptime/src/actions/mockCartActions.js @@ -1,5 +1,5 @@ import { BUYNOW_CONFIG } from '../utils/BuyNowConfig'; -import { createMockCartListData, addMockCartItem, removeMockCartItem, updateMockCartItemQuantity } from '../utils/BuyNowDataManipulator'; +import { createMockCartListData, createMockCartData, addMockCartItem, removeMockCartItem, updateMockCartItemQuantity } from '../utils/BuyNowDataManipulator'; // Mock Cart Action Types export const MOCK_CART_TYPES = { @@ -9,11 +9,12 @@ export const MOCK_CART_TYPES = { UPDATE_MOCK_CART_ITEM: 'mockCart/UPDATE_MOCK_CART_ITEM', CLEAR_MOCK_CART: 'mockCart/CLEAR_MOCK_CART', SET_MOCK_CART_QUANTITY: 'mockCart/SET_MOCK_CART_QUANTITY', + UPDATE_SELECTED_ITEMS: 'mockCart/UPDATE_SELECTED_ITEMS', }; /** * Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ดˆ๊ธฐํ™” - * BuyOption์—์„œ ADD TO CART ์‹œ ํ˜ธ์ถœ + * BuyOption์—์„œ ADD TO CART ์‹œ ํ˜ธ์ถœ - ๊ธฐ์กด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ ์ถ”๊ฐ€ */ export const initializeMockCart = (productData, optionInfo = {}, quantity = 1) => (dispatch, getState) => { if (!BUYNOW_CONFIG.isMockMode()) { @@ -22,20 +23,19 @@ export const initializeMockCart = (productData, optionInfo = {}, quantity = 1) = console.log('[MockCartActions] initializeMockCart - productData:', productData); - // ์ดˆ๊ธฐ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ - const mockCartData = createMockCartListData(productData, optionInfo, quantity); + // ๊ธฐ์กด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ํ™•์ธ + const currentCart = getState().mockCart.cartInfo || []; + console.log('[MockCartActions] initializeMockCart - current cart items:', currentCart.length); - dispatch({ - type: MOCK_CART_TYPES.INIT_MOCK_CART, - payload: { - items: mockCartData, - lastAction: { - type: 'init', - data: productData, - timestamp: Date.now(), - }, - }, - }); + // ์ƒˆ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ + const newCartItem = createMockCartData(productData, optionInfo, quantity); + + if (newCartItem) { + // addToMockCart๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ ์ถ”๊ฐ€ (๋ฎ์–ด์“ฐ๊ธฐ ๋ฐฉ์ง€) + dispatch(addToMockCart(productData, optionInfo, quantity)); + } else { + console.log('[MockCartActions] initializeMockCart - Failed to create cart item'); + } }; /** @@ -177,26 +177,47 @@ export const clearMockCart = () => (dispatch, getState) => { }; /** - * Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ์žฌ์„ค์ • (์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋ณต์›) + * Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ์žฌ์„ค์ • (๋นˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋กœ ๋ณต์›) */ export const resetMockCart = () => (dispatch, getState) => { if (!BUYNOW_CONFIG.isMockMode()) { return; } - console.log('[MockCartActions] resetMockCart'); - - // ๊ธฐ๋ณธ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ๋กœ ์žฌ์„ค์ • - const defaultMockCartData = createMockCartListData(); + console.log('[MockCartActions] resetMockCart - Clearing cart to empty'); + // ๋นˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋กœ ์žฌ์„ค์ • (๊ธฐ๋ณธ Mock ์ƒํ’ˆ ์—†์Œ) dispatch({ type: MOCK_CART_TYPES.INIT_MOCK_CART, payload: { - items: defaultMockCartData, + items: [], // ๋นˆ ๋ฐฐ์—ด๋กœ ์žฌ์„ค์ • lastAction: { type: 'reset', timestamp: Date.now(), }, }, }); +}; + +/** + * ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค ์—…๋ฐ์ดํŠธ + * @param {Array} selectedItems - ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค์˜ prodSno ๋ฐฐ์—ด + */ +export const updateSelectedItems = (selectedItems) => (dispatch, getState) => { + if (!BUYNOW_CONFIG.isMockMode()) { + return; + } + + console.log('[MockCartActions] updateSelectedItems - selectedItems:', selectedItems); + + dispatch({ + type: MOCK_CART_TYPES.UPDATE_SELECTED_ITEMS, + payload: { + selectedItems, + lastAction: { + type: 'update_selected', + timestamp: Date.now(), + }, + }, + }); }; \ No newline at end of file diff --git a/com.twin.app.shoptime/src/reducers/mockCartReducer.js b/com.twin.app.shoptime/src/reducers/mockCartReducer.js index 32ab3ac2..929904c0 100644 --- a/com.twin.app.shoptime/src/reducers/mockCartReducer.js +++ b/com.twin.app.shoptime/src/reducers/mockCartReducer.js @@ -10,6 +10,8 @@ const isBrowser = typeof window !== 'undefined' && typeof window.localStorage != const initialState = { // Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก cartInfo: [], + // ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค + selectedItems: [], // ๋งˆ์ง€๋ง‰ ์‹คํ–‰๋œ ์•ก์…˜ ์ •๋ณด lastAction: null, // ์—๋Ÿฌ ์ •๋ณด @@ -34,6 +36,7 @@ const saveToLocalStorage = (state) => { try { const dataToSave = { cartInfo: state.cartInfo, + selectedItems: state.selectedItems, totalQuantity: state.totalQuantity, totalPrice: state.totalPrice, lastUpdated: state.lastUpdated, @@ -57,6 +60,7 @@ const loadFromLocalStorage = () => { return { ...initialState, cartInfo: parsedData.cartInfo || [], + selectedItems: parsedData.selectedItems || [], totalQuantity: parsedData.totalQuantity || 0, totalPrice: parsedData.totalPrice || 0, lastUpdated: parsedData.lastUpdated || Date.now(), @@ -254,6 +258,7 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { const newState = { ...state, cartInfo: [], + selectedItems: [], // ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค๋„ ์ดˆ๊ธฐํ™” lastAction: action.payload.lastAction, error: null, lastUpdated: Date.now(), @@ -266,6 +271,21 @@ export const mockCartReducer = (state = loadFromLocalStorage(), action) => { return newState; } + case MOCK_CART_TYPES.UPDATE_SELECTED_ITEMS: { + const { selectedItems } = action.payload; + + const newState = { + ...state, + selectedItems, + lastAction: action.payload.lastAction, + lastUpdated: Date.now(), + }; + + // localStorage์— ์ €์žฅ + saveToLocalStorage(newState); + return newState; + } + default: return state; } diff --git a/com.twin.app.shoptime/src/utils/BuyNowDataManipulator.js b/com.twin.app.shoptime/src/utils/BuyNowDataManipulator.js index 0bbb7aa7..9621088e 100644 --- a/com.twin.app.shoptime/src/utils/BuyNowDataManipulator.js +++ b/com.twin.app.shoptime/src/utils/BuyNowDataManipulator.js @@ -107,82 +107,18 @@ export const createMockCartListData = (productData, optionInfo = {}, quantity = return []; } - // โœ… ๊ธฐ๋ณธ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ (CartPanel ๊ตฌ์กฐ์— ๋งž์ถฐ ๊ฐœ์„  - ๋ชจ๋“  ์ด๋ฏธ์ง€ ํ•„๋“œ ํฌํ•จ) - const defaultMockItems = [ - // QVC ์ƒํ’ˆ - { - prodSno: 'MOCK_CART_1', - prdtId: 'MOCK_QVC_001', - prdtNm: 'Mock Premium Wireless Headphones', - patnrId: 'QVC', - patncNm: 'QVC', - patncLogPath: '/assets/images/ic-partners-qvc@3x.png', - imgUrl: '/assets/images/img-thumb-empty-144@3x.png', - thumbnailUrl: '/assets/images/img-thumb-empty-144@3x.png', - imgList: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], - imgUrls: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], // CheckOutPanel ํ˜ธํ™˜์„ฑ - price2: '299.99', // ์›๊ฐ€ - price3: '199.99', // ํ• ์ธ๊ฐ€ - price5: '29.99', // ์˜ต์…˜ ํ• ์ธ๊ฐ€ - optPrc: '29.99', // ์˜ต์…˜ ๊ฐ€๊ฒฉ - shippingCharge: '12.99', - prodQty: 1, - optNm: 'Color: Black, Warranty: 2 Years', - addedAt: new Date().toISOString() - }, - // HSN ์ƒํ’ˆ - { - prodSno: 'MOCK_CART_2', - prdtId: 'MOCK_HSN_001', - prdtNm: 'Mock Smart Watch Pro', - patnrId: 'HSN', - patncNm: 'HSN', - patncLogPath: '/assets/images/ic-partners-hsn@3x.png', - imgUrl: '/assets/images/img-thumb-empty-144@3x.png', - thumbnailUrl: '/assets/images/img-thumb-empty-144@3x.png', - imgList: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], - imgUrls: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], // CheckOutPanel ํ˜ธํ™˜์„ฑ - price2: '399.99', - price3: '299.99', - price5: '49.99', - optPrc: '49.99', - shippingCharge: '9.99', - prodQty: 2, - optNm: 'Color: Silver, Size: 42mm', - addedAt: new Date().toISOString() - }, - // ๋‹ค๋ฅธ ํŒŒํŠธ๋„ˆ์‚ฌ ์ƒํ’ˆ - { - prodSno: 'MOCK_CART_3', - prdtId: 'MOCK_EVINE_001', - prdtNm: 'Mock Luxury Skincare Set', - patnrId: 'EVINE', - patncNm: 'EVINE', - patncLogPath: '/assets/images/ic-partners-evine@3x.png', - imgUrl: '/assets/images/img-thumb-empty-144@3x.png', - thumbnailUrl: '/assets/images/img-thumb-empty-144@3x.png', - imgList: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], - imgUrls: [{ imgUrl: '/assets/images/img-thumb-empty-144@3x.png' }], // CheckOutPanel ํ˜ธํ™˜์„ฑ - price2: '149.99', - price3: '99.99', - price5: '19.99', - optPrc: '19.99', - shippingCharge: '7.99', - prodQty: 1, - optNm: 'Size: Full Set, Type: Anti-Aging', - addedAt: new Date().toISOString() - } - ]; - - // ์ดˆ๊ธฐ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ + // ์ดˆ๊ธฐ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น ์ƒํ’ˆ ์ถ”๊ฐ€ if (productData) { const newCartItem = createMockCartData(productData, optionInfo, quantity); if (newCartItem) { - return [newCartItem, ...defaultMockItems]; + console.log('[BuyNowDataManipulator] createMockCartListData - Adding only user product:', newCartItem.prdtNm); + return [newCartItem]; } } - return defaultMockItems; + // ๊ธฐ๋ณธ Mock ์ƒํ’ˆ์€ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Œ + console.log('[BuyNowDataManipulator] createMockCartListData - No product data, returning empty array'); + return []; }; // Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ „์—ญ ๋ณ€์ˆ˜ diff --git a/com.twin.app.shoptime/src/views/CartPanel/CartPanel.jsx b/com.twin.app.shoptime/src/views/CartPanel/CartPanel.jsx index 90b3047e..07f2a934 100644 --- a/com.twin.app.shoptime/src/views/CartPanel/CartPanel.jsx +++ b/com.twin.app.shoptime/src/views/CartPanel/CartPanel.jsx @@ -86,22 +86,26 @@ export default function CartPanel({ spotlightId, scrollOptions = [], panelInfo } console.log('[CartPanel] Component mounted - isMockMode:', isMockMode, 'panelInfo:', panelInfo); if (isMockMode) { - // Mock Mode: panelInfo๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ์ƒํ’ˆ ์ถ”๊ฐ€, ์—†์œผ๋ฉด ๊ธฐ๋ณธ Mock ๋ฐ์ดํ„ฐ ์„ค์ • + // Mock Mode: panelInfo๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ์ƒํ’ˆ ์ถ”๊ฐ€ if (panelInfo?.productInfo) { console.log('[CartPanel] Mock Mode - Adding product from panelInfo:', panelInfo.productInfo); console.log('[CartPanel] Mock Mode - Option info:', panelInfo.optionInfo); console.log('[CartPanel] Mock Mode - Quantity:', panelInfo.quantity); - // panelInfo์˜ ์ƒํ’ˆ ์ •๋ณด๋กœ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ดˆ๊ธฐํ™” (๊ธฐ์กด ๋ฐ์ดํ„ฐ ์œ ์ง€) + // panelInfo์˜ ์ƒํ’ˆ ์ •๋ณด๋กœ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ƒํ’ˆ ์ถ”๊ฐ€ (๊ธฐ์กด ๋ฐ์ดํ„ฐ ์œ ์ง€) + console.log('[CartPanel] Mock Mode - Adding product to existing cart:', panelInfo.productInfo.prdtNm); dispatch(initializeMockCart( panelInfo.productInfo, panelInfo.optionInfo || {}, panelInfo.quantity || 1 )); - } else { - // panelInfo๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ๋ณธ Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ๋กœ ์„ค์ • - console.log('[CartPanel] Mock Mode - Initializing with default mock data'); + } else if (!mockCartData || mockCartData.length === 0) { + // localStorage์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ๋งŒ ๊ธฐ๋ณธ Mock ๋ฐ์ดํ„ฐ๋กœ ์„ค์ • + console.log('[CartPanel] Mock Mode - No existing cart data, initializing with default mock data'); dispatch(resetMockCart()); + } else { + // localStorage์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ + console.log('[CartPanel] Mock Mode - Using existing cart data from localStorage:', mockCartData.length, 'items'); } } else if (userNumber) { // API Mode: ์‹ค์ œ API ํ˜ธ์ถœ @@ -110,6 +114,17 @@ export default function CartPanel({ spotlightId, scrollOptions = [], panelInfo } } }, [dispatch, userNumber, isMockMode, panelInfo]); + // Mock ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๊ฐ์ง€ (๋””๋ฒ„๊น…์šฉ) + useEffect(() => { + console.log('[CartPanel] mockCartData changed:', mockCartData?.length, 'items'); + console.log('[CartPanel] mockCartData:', JSON.stringify(mockCartData)); + }, [mockCartData]); + + // displayCartData ๋ณ€๊ฒฝ ๊ฐ์ง€ (๋””๋ฒ„๊น…์šฉ) + useEffect(() => { + console.log('[CartPanel] displayCartData changed:', displayCartData?.length, 'items'); + }, [displayCartData]); + const { getScrollTo, getScrollTo: getScrollToBody, diff --git a/com.twin.app.shoptime/src/views/CartPanel/CartProduct.jsx b/com.twin.app.shoptime/src/views/CartPanel/CartProduct.jsx index 484036b7..0def4907 100644 --- a/com.twin.app.shoptime/src/views/CartPanel/CartProduct.jsx +++ b/com.twin.app.shoptime/src/views/CartPanel/CartProduct.jsx @@ -8,6 +8,8 @@ import React, { import classNames from 'classnames'; import { useSelector, useDispatch } from 'react-redux'; +import { updateSelectedItems } from '../../actions/mockCartActions'; + import Spotlight from '@enact/spotlight'; import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator'; @@ -30,6 +32,7 @@ const CartProduct = ({ cartInfo }) => { // ํ•ญ์ƒ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋Š” Hook๋“ค const fallbackCartData = useSelector((state) => state.cart.getMyinfoCartSearch.cartInfo); + const selectedItems = useSelector((state) => state.mockCart.selectedItems || []); // ์‹ค์ œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ์™€ Mock ๋ฐ์ดํ„ฐ ์ค‘ ์„ ํƒ const cartData = cartInfo || fallbackCartData; @@ -129,6 +132,27 @@ const CartProduct = ({ cartInfo }) => { } }, [dispatch, isMockMode]); + // ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ ํ•ธ๋“ค๋Ÿฌ + const handleCheckboxChange = useCallback((prodSno, isChecked) => { + if (isMockMode) { + let newSelectedItems; + if (isChecked) { + // ์ƒํ’ˆ ์„ ํƒ + newSelectedItems = [...selectedItems, prodSno]; + } else { + // ์ƒํ’ˆ ์„ ํƒ ํ•ด์ œ + newSelectedItems = selectedItems.filter(id => id !== prodSno); + } + dispatch(updateSelectedItems(newSelectedItems)); + console.log('[CartProduct] Checkbox changed - prodSno:', prodSno, 'isChecked:', isChecked, 'selectedItems:', newSelectedItems); + } + }, [dispatch, isMockMode, selectedItems]); + + // ์ƒํ’ˆ์ด ์„ ํƒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ + const isItemSelected = useCallback((prodSno) => { + return selectedItems.includes(prodSno); + }, [selectedItems]); + return ( <> {Object.entries(groupedCartData).map(([partnerKey, group]) => { @@ -196,7 +220,9 @@ const CartProduct = ({ cartInfo }) => {
handleCheckboxChange(item.prodSno, isChecked)} /> ID : {item.prdtId} diff --git a/com.twin.app.shoptime/src/views/CartPanel/CartSidebar.jsx b/com.twin.app.shoptime/src/views/CartPanel/CartSidebar.jsx index 3fcdfd9b..b8ee9250 100644 --- a/com.twin.app.shoptime/src/views/CartPanel/CartSidebar.jsx +++ b/com.twin.app.shoptime/src/views/CartPanel/CartSidebar.jsx @@ -5,6 +5,7 @@ import TButton from '../../components/TButton/TButton'; import { BUYNOW_CONFIG } from '../../utils/BuyNowConfig'; import { pushPanel } from '../../actions/panelActions'; import Config from '../../utils/Config'; +import { calculateOrderSummaryFromProductInfo } from '../../utils/mockDataSafetyUtils'; import css from './CartSidebar.module.less'; const CartSidebar = ({ cartInfo }) => { @@ -15,21 +16,118 @@ const CartSidebar = ({ cartInfo }) => { // ์‹ค์ œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ (API ๋ชจ๋“œ์ผ ๋•Œ๋งŒ ์‚ฌ์šฉ) const fallbackCartInfo = useSelector((state) => state.cart.getMyinfoCartSearch.cartInfo); + const selectedItems = useSelector((state) => state.mockCart.selectedItems || []); // ์‚ฌ์šฉํ•  ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ ๊ฒฐ์ • const displayCartInfo = cartInfo || (isMockMode ? null : fallbackCartInfo); - // Mock ๋ฐ์ดํ„ฐ ๋˜๋Š” ์‹ค์ œ ๋ฐ์ดํ„ฐ ๊ณ„์‚ฐ + // ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค๋งŒ ํ•„ํ„ฐ๋ง - ํ•ญ์ƒ ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค๋งŒ ๋ฐ˜ํ™˜ + const getSelectedItems = useCallback((items) => { + console.log('[CartSidebar] getSelectedItems called - isMockMode:', isMockMode, 'selectedItems:', selectedItems); + + if (!items || !Array.isArray(items)) { + console.log('[CartSidebar] No items provided, returning empty array'); + return []; + } + + if (!isMockMode) { + console.log('[CartSidebar] API Mode - returning all items'); + return items; + } + + if (selectedItems.length === 0) { + console.log('[CartSidebar] No items selected, returning empty array'); + return []; // ์„ ํƒ๋œ ์ƒํ’ˆ์ด ์—†์œผ๋ฉด ๋นˆ ๋ฐฐ์—ด ๋ฐ˜ํ™˜ + } + + const filtered = items.filter(item => { + const itemId = item.prodSno || item.cartId; + const isSelected = selectedItems.includes(itemId); + console.log('[CartSidebar] Item filter:', { + itemName: item.prdtNm, + itemId, + isSelected + }); + return isSelected; + }); + + console.log('[CartSidebar] Filtered selected items:', filtered.length, 'out of', items.length); + return filtered; + }, [isMockMode, selectedItems]); + + // Mock ๋ฐ์ดํ„ฐ ๋˜๋Š” ์‹ค์ œ ๋ฐ์ดํ„ฐ ๊ณ„์‚ฐ (์„ ํƒ๋œ ์ƒํ’ˆ๋งŒ) - CheckOutPanel ๋ฐฉ์‹ ์ ์šฉ const calculatedData = useMemo(() => { if (isMockMode) { - // Mock Mode: ๊ธฐ๋ณธ mockData ์‚ฌ์šฉ - return { - itemCount: 3, - subtotal: 199.97, - optionTotal: 29.99, - shippingHandling: 19.99, - orderTotalBeforeTax: 249.95, - }; + // Mock Mode: ์„ ํƒ๋œ ์ƒํ’ˆ๋“ค๋กœ ๊ฐœ๋ณ„ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ + if (displayCartInfo && Array.isArray(displayCartInfo) && displayCartInfo.length > 0) { + const selectedCartItems = getSelectedItems(displayCartInfo); + console.log('[CartSidebar] Selected items for calculation:', selectedCartItems); + + // CheckOutPanel ๋ฐฉ์‹: ๊ฐ ์ƒํ’ˆ์˜ ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ถ”์ถœ + let totalItems = 0; + let totalCoupon = 0; + let totalShipping = 0; + let totalQuantity = 0; + + selectedCartItems.forEach((item) => { + console.log('[CartSidebar] Processing item:', item.prdtNm, 'price fields:', { + price2: item.price2, + price3: item.price3, + price5: item.price5, + finalPrice: item.finalPrice, + discountPrice: item.discountPrice, + }); + + // CheckOutPanel์˜ calculateOrderSummaryFromProductInfo ๋กœ์ง ์‚ฌ์šฉ + const orderSummary = calculateOrderSummaryFromProductInfo(item); + + const qty = item.prodQty || item.qty || 1; + const itemPrice = orderSummary.items; // ๊ฐœ๋ณ„ ์ƒํ’ˆ ๊ฐ€๊ฒฉ + const itemCoupon = orderSummary.couponSavings; // ๊ฐœ๋ณ„ ์ƒํ’ˆ ์ฟ ํฐ + const itemShipping = orderSummary.shipping; // ๊ฐœ๋ณ„ ์ƒํ’ˆ ๋ฐฐ์†ก๋น„ + + totalItems += itemPrice * qty; + totalCoupon += itemCoupon * qty; + totalShipping += itemShipping * qty; // ๋ฐฐ์†ก๋น„๋„ ์ˆ˜๋Ÿ‰๋งŒํผ ๊ณ„์‚ฐ + totalQuantity += qty; + + console.log('[CartSidebar] Item calculation:', { + name: item.prdtNm, + qty, + itemPrice, + itemCoupon, + itemShipping, + runningTotal: totalItems + }); + }); + + const subtotal = Math.max(0, totalItems - totalCoupon + totalShipping); + + console.log('[CartSidebar] Final calculation for selected items:', { + totalQuantity, + totalItems, + totalCoupon, + totalShipping, + subtotal, + }); + + return { + itemCount: totalQuantity, + subtotal: totalItems, + optionTotal: totalCoupon, + shippingHandling: totalShipping, + orderTotalBeforeTax: subtotal, + }; + } else { + // Mock Mode์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ + return { + itemCount: 0, + subtotal: 0, + optionTotal: 0, + shippingHandling: 0, + orderTotalBeforeTax: 0, + }; + } } else if (displayCartInfo && Array.isArray(displayCartInfo) && displayCartInfo.length > 0) { // API Mode: ์‹ค์ œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฐ์ดํ„ฐ๋กœ ๊ณ„์‚ฐ const itemCount = displayCartInfo.reduce((sum, item) => sum + (item.prodQty || 1), 0); @@ -62,21 +160,36 @@ const CartSidebar = ({ cartInfo }) => { orderTotalBeforeTax: 0, }; } - }, [isMockMode, displayCartInfo]); + }, [isMockMode, displayCartInfo, getSelectedItems]); // ์ฒดํฌ์•„์›ƒ ๋ฒ„ํŠผ ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ - const handleCheckoutClick = useCallback(() => { + const handleCheckoutClick = useCallback(() => { + if (isMockMode) { // Mock Mode: ๋ฐ”๋กœ ์ฒดํฌ์•„์›ƒ ํŒจ๋„๋กœ ์ด๋™ console.log('[CartSidebar] Mock Mode - Going to Checkout'); - dispatch(pushPanel({ - name: Config.panel_names.CHECKOUT_PANEL, - })); + console.log('[CartSidebar] Mock Mode - cartInfo:', JSON.stringify(cartInfo)); + + // โœ… panelInfo์— cartInfo๋ฅผ ํฌํ•จํ•˜์—ฌ ์ „๋‹ฌ + // CheckOutPanel์—์„œ productList๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ + const cartItems = cartInfo && Array.isArray(cartInfo) ? cartInfo : []; + + console.log('[CartSidebar] Mock Mode - cartItems:', JSON.stringify(cartItems)); + + // dispatch(pushPanel({ + // name: Config.panel_names.CHECKOUT_PANEL, + // panelInfo: { + // productInfo: cartItems.length > 0 ? cartItems[0] : null, // ์ฒซ ๋ฒˆ์งธ ์ƒํ’ˆ + // cartItems: cartItems, // ์ „์ฒด ์นดํŠธ ์•„์ดํ…œ + // isFromCart: true, // CartPanel์—์„œ ์™”์Œ์„ ํ‘œ์‹œ + // } + // })); + } else { // API Mode: ์‹ค์ œ ๋กœ์ง (ํ–ฅํ›„ ๊ตฌํ˜„) console.log('[CartSidebar] API Mode - Checkout (to be implemented)'); } - }, [dispatch, isMockMode]); + }, [dispatch, isMockMode, cartInfo]); const { itemCount, subtotal, optionTotal, shippingHandling, orderTotalBeforeTax } = calculatedData; diff --git a/com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx b/com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx index 4b71dc15..7d3ce87e 100644 --- a/com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx +++ b/com.twin.app.shoptime/src/views/CheckOutPanel/CheckOutPanel.jsx @@ -115,20 +115,28 @@ export default function CheckOutPanel({ panelInfo }) { ? (() => { console.log('[BuyOption][CheckOutPanel] Mock Mode - panelInfo:', panelInfo); console.log('[BuyOption][CheckOutPanel] Mock Mode - panelInfo.productInfo:', panelInfo?.productInfo); + console.log('[BuyOption][CheckOutPanel] Mock Mode - panelInfo.cartItems:', panelInfo?.cartItems); + console.log('[BuyOption][CheckOutPanel] Mock Mode - panelInfo.isFromCart:', panelInfo?.isFromCart); - // 1์ˆœ์œ„: BuyOption์—์„œ ์ „๋‹ฌ๋œ productInfo (Mock Mode์—์„œ๋Š” ๊ฒ€์ฆ ์ตœ์†Œํ™”) + // โœ… 1์ˆœ์œ„: CartPanel์—์„œ ์ „๋‹ฌ๋œ cartItems (์ „์ฒด ์นดํŠธ ๋ฐ์ดํ„ฐ) + if (panelInfo?.isFromCart && panelInfo?.cartItems && Array.isArray(panelInfo.cartItems) && panelInfo.cartItems.length > 0) { + console.log('%c[BuyOption][CheckOutPanel] โœ… Mock Mode - Using cartItems from CartPanel (multi-product):', 'background: blue; color: white; font-weight: bold; padding: 5px;', panelInfo.cartItems); + return panelInfo.cartItems; + } + + // 2์ˆœ์œ„: BuyOption์—์„œ ์ „๋‹ฌ๋œ productInfo (๋‹จ์ผ ์ƒํ’ˆ) if (panelInfo?.productInfo) { - console.log('%c[BuyOption][CheckOutPanel] โœ… Mock Mode - Using panelInfo.productInfo (no validation):', 'background: green; color: white; font-weight: bold; padding: 5px;', panelInfo.productInfo); + console.log('%c[BuyOption][CheckOutPanel] โœ… Mock Mode - Using panelInfo.productInfo (single product):', 'background: green; color: white; font-weight: bold; padding: 5px;', panelInfo.productInfo); return [panelInfo.productInfo]; } - // 2์ˆœ์œ„: Redux์—์„œ ๊ฐ€์ ธ์˜จ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ + // 3์ˆœ์œ„: Redux์—์„œ ๊ฐ€์ ธ์˜จ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ if (reduxProductData && Array.isArray(reduxProductData) && reduxProductData.length > 0) { console.log('%c[BuyOption][CheckOutPanel] โœ… Mock Mode - Using reduxProductData:', 'background: green; color: white; font-weight: bold; padding: 5px;', 'count=' + reduxProductData.length); return reduxProductData; } - // 3์ˆœ์œ„: ๊ธฐ๋ณธ Hardcoded Mock ๋ฐ์ดํ„ฐ (์ตœํ›„์˜ fallback) + // 4์ˆœ์œ„: ๊ธฐ๋ณธ Hardcoded Mock ๋ฐ์ดํ„ฐ (์ตœํ›„์˜ fallback) console.error('%c[BuyOption][CheckOutPanel] โš ๏ธ Mock Mode - Using fallback mock data:', 'background: orange; color: white; font-weight: bold; padding: 5px;', 'panelInfo=', panelInfo, 'reduxProductData=', reduxProductData); return [ { diff --git a/com.twin.app.shoptime/src/views/CheckOutPanel/container/SummaryContainerMock.jsx b/com.twin.app.shoptime/src/views/CheckOutPanel/container/SummaryContainerMock.jsx index 910af758..f4ce7a53 100644 --- a/com.twin.app.shoptime/src/views/CheckOutPanel/container/SummaryContainerMock.jsx +++ b/com.twin.app.shoptime/src/views/CheckOutPanel/container/SummaryContainerMock.jsx @@ -25,47 +25,88 @@ export default function SummaryContainerMock({ console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - productInfo.price2:', productInfo?.price2); console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - productInfo.price5:', productInfo?.price5); - // Mock Mode: productInfo๋กœ๋ถ€ํ„ฐ ORDER SUMMARY์šฉ ๊ฐ€๊ฒฉ ๋ฐ์ดํ„ฐ ๊ณ„์‚ฐ + // โœ… Mock Mode: productData ๋ฐฐ์—ด ์ „์ฒด๋ฅผ ํ•ฉ์‚ฐํ•˜๊ฑฐ๋‚˜ productInfo ์‚ฌ์šฉ const orderSummaryData = useMemo(() => { - if (productInfo) { - // productInfo๊ฐ€ ์žˆ์œผ๋ฉด ์ง์ ‘ ๊ณ„์‚ฐ - console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Using calculateOrderSummaryFromProductInfo'); - return calculateOrderSummaryFromProductInfo(productInfo); - } else { - // productInfo๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ์กด ๋ฐฉ์‹์œผ๋กœ fallback - console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Using fallback calculation (no productInfo)'); - const selectedProduct = getSafeFirstProduct(productData); + // โœ… 1์ˆœ์œ„: CartPanel์˜ ์—ฌ๋Ÿฌ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ (productData ๋ฐฐ์—ด) + if (Array.isArray(productData) && productData.length > 0) { + console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Using calculateOrderSummaryFromProductData (multiple items)'); - // ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ๊ฐ€๊ฒฉ์ด๋ผ๋„ ์ฐพ๊ธฐ - const anyPrice = parseFloat( - defaultPrice || - selectedProduct?.finalPrice || - selectedProduct?.discountPrice || - selectedProduct?.price || - 0 - ); + // ์ „์ฒด ์ƒํ’ˆ์˜ ๊ฐ€๊ฒฉ ํ•ฉ์‚ฐ + let totalItems = 0; + let totalCoupon = 0; + let totalShipping = 0; - const productPrice = anyPrice > 0 ? anyPrice : 0; - const productDiscount = parseFloat(selectedProduct?.discount || 0); - const tax = Math.round((productPrice * 0.1) * 100) / 100; + productData.forEach((product) => { + const price = parseFloat(product.price3 || product.price2 || product.finalPrice || product.discountPrice || 0); + const qty = product.prodQty || 1; + const coupon = parseFloat(product.discount || product.price5 || 0); + const shipping = parseFloat(product.shippingCharge || 0); - console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Fallback calculation:', { - productPrice, - productDiscount, - tax, - selectedProduct + totalItems += price * qty; + totalCoupon += coupon * qty; + totalShipping += shipping; + }); + + const subtotal = Math.max(0, totalItems - totalCoupon + totalShipping); + const tax = Math.round((subtotal * 0.1) * 100) / 100; + + console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Multi-product calculation:', { + totalItems, + totalCoupon, + totalShipping, + subtotal, + tax }); return { - items: productPrice, - couponSavings: productDiscount, - shipping: 0, - subtotal: Math.max(0, productPrice - productDiscount), + items: totalItems, + couponSavings: totalCoupon, + shipping: totalShipping, + subtotal: subtotal, tax: tax, - total: Math.max(0, productPrice - productDiscount) + tax, + total: subtotal + tax, currency: { currSign, currSignLoc } }; } + + // 2์ˆœ์œ„: productInfo (๋‹จ์ผ ์ƒํ’ˆ) + if (productInfo) { + console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Using calculateOrderSummaryFromProductInfo (single product)'); + return calculateOrderSummaryFromProductInfo(productInfo); + } + + // 3์ˆœ์œ„: ๊ธฐ์กด ๋ฐฉ์‹์œผ๋กœ fallback + console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Using fallback calculation (no data)'); + const selectedProduct = getSafeFirstProduct(productData); + + const anyPrice = parseFloat( + defaultPrice || + selectedProduct?.finalPrice || + selectedProduct?.discountPrice || + selectedProduct?.price || + 0 + ); + + const productPrice = anyPrice > 0 ? anyPrice : 0; + const productDiscount = parseFloat(selectedProduct?.discount || 0); + const tax = Math.round((productPrice * 0.1) * 100) / 100; + + console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - Fallback calculation:', { + productPrice, + productDiscount, + tax, + selectedProduct + }); + + return { + items: productPrice, + couponSavings: productDiscount, + shipping: 0, + subtotal: Math.max(0, productPrice - productDiscount), + tax: tax, + total: Math.max(0, productPrice - productDiscount) + tax, + currency: { currSign, currSignLoc } + }; }, [productInfo, productData, defaultPrice, currSign, currSignLoc]); console.log('[BuyOption][CheckOutPanel] SummaryContainerMock - orderSummaryData:', orderSummaryData); diff --git a/com.twin.app.shoptime/src/views/DetailPanel/components/BuyOption.jsx b/com.twin.app.shoptime/src/views/DetailPanel/components/BuyOption.jsx index df7c0712..87b86c54 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/components/BuyOption.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/components/BuyOption.jsx @@ -823,9 +823,51 @@ const BuyOption = ({ productInfo?.patncLogPath || '/assets/images/img-thumb-empty-144@3x.png'; - // ๊ฐ€๊ฒฉ ์ •๋ณด ๊ตฌ์„ฑ - const regularPrice = productInfo?.regularPrice || 299.99; - const discountPrice = productInfo?.discountPrice || regularPrice; + // โœ… ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ถ”์ถœ (Mock Mode์™€ ๋™์ผํ•œ ๋กœ์ง) + console.log('[BuyOption] API Mode ADD TO CART - Extracting accurate prices from productInfo'); + console.log('[BuyOption] API Mode ADD TO CART - productInfo.price2:', productInfo?.price2); + console.log('[BuyOption] API Mode ADD TO CART - productInfo.price5:', productInfo?.price5); + console.log('[BuyOption] API Mode ADD TO CART - productInfo.priceInfo:', productInfo?.priceInfo); + + // ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ถ”์ถœ ๋กœ์ง + const extractNumericPrice = (value) => { + if (typeof value === 'number') return value; + if (typeof value === 'string') { + const numMatch = value.match(/[\d.]+/); + return numMatch ? parseFloat(numMatch[0]) : 0; + } + return 0; + }; + + const price2Value = extractNumericPrice(productInfo?.price2); + const price5Value = extractNumericPrice(productInfo?.price5); + + console.log('[BuyOption] API Mode ADD TO CART - extracted price2Value:', price2Value); + console.log('[BuyOption] API Mode ADD TO CART - extracted price5Value:', price5Value); + + // ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ (ProductAllSection์˜ ๊ฐ€๊ฒฉ ์ •๋ณด ์‚ฌ์šฉ) + let discountPrice = price2Value > 0 ? price2Value : 521.66; // ProductAllSection ๊ฐ€๊ฒฉ fallback + let regularPrice = price2Value + price5Value; + + // priceInfo์—์„œ ์ง์ ‘ ๊ฐ€๊ฒฉ ์ถ”์ถœ ์‹œ๋„ + if (productInfo?.priceInfo) { + const priceParts = productInfo.priceInfo.split('|'); + if (priceParts.length >= 2) { + const infoDiscountPrice = extractNumericPrice(priceParts[1]); + const infoRegularPrice = extractNumericPrice(priceParts[0]); + if (infoDiscountPrice > 0) { + discountPrice = infoDiscountPrice; + regularPrice = infoRegularPrice > 0 ? infoRegularPrice : discountPrice; + } + } + } + + console.log('[BuyOption] API Mode ADD TO CART - Final calculated prices:', { + discountPrice, + regularPrice, + price2Value, + price5Value + }); const productInfoForCart = { // ๊ธฐ๋ณธ ์ •๋ณด @@ -843,9 +885,15 @@ const BuyOption = ({ imgUrls: productInfo?.imgUrls || [{ imgUrl: imgUrl }], // imgUrls ๋ฐฐ์—ด ๊ตฌ์กฐ ์ถ”๊ฐ€ (CheckOutPanel ํ˜ธํ™˜์„ฑ) imgUrls600: productInfo?.imgUrls600, // โœ… ๊ณ ํ’ˆ์งˆ ์ด๋ฏธ์ง€ ๋ฐฐ์—ด ํฌํ•จ - // ๊ฐ€๊ฒฉ ์ •๋ณด (๋ฌธ์ž์—ด ํ˜•์‹์œผ๋กœ) - price2: regularPrice.toFixed(2), // ์›๊ฐ€ - price3: discountPrice.toFixed(2), // ํ• ์ธ๊ฐ€/ํŒ๋งค๊ฐ€ + // ๊ฐ€๊ฒฉ ์ •๋ณด (์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ •๋ณด - ๋ฌธ์ž์—ด ํ˜•์‹์œผ๋กœ) + price2: regularPrice.toFixed(2), // ์›๊ฐ€ (ProductAllSection ๊ฐ€๊ฒฉ) + price3: discountPrice.toFixed(2), // ํ• ์ธ๊ฐ€/ํŒ๋งค๊ฐ€ (ProductAllSection ๊ฐ€๊ฒฉ) + // ์ถ”๊ฐ€ ๊ฐ€๊ฒฉ ํ•„๋“œ๋“ค (๋‹ค์–‘ํ•œ fallback ์ง€์›) + finalPrice: discountPrice, + discountPrice: discountPrice, + origPrice: regularPrice, + discount: Math.max(0, regularPrice - discountPrice), + priceInfo: productInfo?.priceInfo, // ์›๋ณธ priceInfo ๋ณด์กด // ์ˆ˜๋Ÿ‰ ์ •๋ณด prodQty: quantity, @@ -865,6 +913,11 @@ const BuyOption = ({ price: productOptionInfos[0]?.prdtOptDtl[0]?.optPrc || '0.00' }; + console.log('[BuyOption] ๐Ÿ›’ API Mode - Pushing CART_PANEL with name:', Config.panel_names.CART_PANEL); + console.log('[BuyOption] ๐Ÿ›’ API Mode - productInfoForCart:', productInfoForCart); + console.log('[BuyOption] ๐Ÿ›’ API Mode - optionInfoForCart:', optionInfoForCart); + console.log('[BuyOption] ๐Ÿ›’ API Mode - quantity:', quantity); + dispatch( pushPanel({ name: Config.panel_names.CART_PANEL, @@ -887,9 +940,51 @@ const BuyOption = ({ productInfo?.patncLogPath || '/assets/images/img-thumb-empty-144@3x.png'; - // ๊ฐ€๊ฒฉ ์ •๋ณด ๊ตฌ์„ฑ (CheckOutPanel๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹) - const regularPrice = productInfo?.regularPrice || 299.99; - const discountPrice = productInfo?.discountPrice || regularPrice; + // โœ… ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ถ”์ถœ (handleBuyNowClick์™€ ๋™์ผํ•œ ๋กœ์ง ์‚ฌ์šฉ) + console.log('[BuyOption] Mock Mode ADD TO CART - Extracting accurate prices from productInfo'); + console.log('[BuyOption] Mock Mode ADD TO CART - productInfo.price2:', productInfo?.price2); + console.log('[BuyOption] Mock Mode ADD TO CART - productInfo.price5:', productInfo?.price5); + console.log('[BuyOption] Mock Mode ADD TO CART - productInfo.priceInfo:', productInfo?.priceInfo); + + // handleBuyNowClick์˜ ๊ฐ€๊ฒฉ ์ถ”์ถœ ๋กœ์ง๊ณผ ๋™์ผํ•˜๊ฒŒ ์ ์šฉ + const extractNumericPrice = (value) => { + if (typeof value === 'number') return value; + if (typeof value === 'string') { + const numMatch = value.match(/[\d.]+/); + return numMatch ? parseFloat(numMatch[0]) : 0; + } + return 0; + }; + + const price2Value = extractNumericPrice(productInfo?.price2); + const price5Value = extractNumericPrice(productInfo?.price5); + + console.log('[BuyOption] Mock Mode ADD TO CART - extracted price2Value:', price2Value); + console.log('[BuyOption] Mock Mode ADD TO CART - extracted price5Value:', price5Value); + + // ์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ (ProductAllSection์˜ ๊ฐ€๊ฒฉ ์ •๋ณด ์‚ฌ์šฉ) + let discountPrice = price2Value > 0 ? price2Value : 521.66; // ProductAllSection ๊ฐ€๊ฒฉ fallback + let regularPrice = price2Value + price5Value; + + // priceInfo์—์„œ ์ง์ ‘ ๊ฐ€๊ฒฉ ์ถ”์ถœ ์‹œ๋„ + if (productInfo?.priceInfo) { + const priceParts = productInfo.priceInfo.split('|'); + if (priceParts.length >= 2) { + const infoDiscountPrice = extractNumericPrice(priceParts[1]); + const infoRegularPrice = extractNumericPrice(priceParts[0]); + if (infoDiscountPrice > 0) { + discountPrice = infoDiscountPrice; + regularPrice = infoRegularPrice > 0 ? infoRegularPrice : discountPrice; + } + } + } + + console.log('[BuyOption] Mock Mode ADD TO CART - Final calculated prices:', { + discountPrice, + regularPrice, + price2Value, + price5Value + }); // Mock ์ƒํ’ˆ ์ •๋ณด ๊ตฌ์„ฑ (CheckOutPanel ๊ตฌ์กฐ ์ฐธ๊ณ ) const mockProductInfo = { @@ -908,9 +1003,15 @@ const BuyOption = ({ imgUrls: productInfo?.imgUrls || [{ imgUrl: imgUrl }], // imgUrls ๋ฐฐ์—ด ๊ตฌ์กฐ ์ถ”๊ฐ€ (CheckOutPanel ํ˜ธํ™˜์„ฑ) imgUrls600: productInfo?.imgUrls600, // โœ… ๊ณ ํ’ˆ์งˆ ์ด๋ฏธ์ง€ ๋ฐฐ์—ด ํฌํ•จ - // ๊ฐ€๊ฒฉ ์ •๋ณด (๋ฌธ์ž์—ด ํ˜•์‹์œผ๋กœ) - price2: regularPrice.toFixed(2), // ์›๊ฐ€ - price3: discountPrice.toFixed(2), // ํ• ์ธ๊ฐ€/ํŒ๋งค๊ฐ€ + // ๊ฐ€๊ฒฉ ์ •๋ณด (์ •ํ™•ํ•œ ๊ฐ€๊ฒฉ ์ •๋ณด - ๋ฌธ์ž์—ด ํ˜•์‹์œผ๋กœ) + price2: regularPrice.toFixed(2), // ์›๊ฐ€ (ProductAllSection ๊ฐ€๊ฒฉ) + price3: discountPrice.toFixed(2), // ํ• ์ธ๊ฐ€/ํŒ๋งค๊ฐ€ (ProductAllSection ๊ฐ€๊ฒฉ) + // ์ถ”๊ฐ€ ๊ฐ€๊ฒฉ ํ•„๋“œ๋“ค (๋‹ค์–‘ํ•œ fallback ์ง€์›) + finalPrice: discountPrice, + discountPrice: discountPrice, + origPrice: regularPrice, + discount: Math.max(0, regularPrice - discountPrice), + priceInfo: productInfo?.priceInfo, // ์›๋ณธ priceInfo ๋ณด์กด // ์ˆ˜๋Ÿ‰ ์ •๋ณด prodQty: quantity, @@ -933,6 +1034,11 @@ const BuyOption = ({ }; // CartPanel๋กœ ์ด๋™ (productInfo ํฌํ•จ) - CartPanel์—์„œ ์ง์ ‘ ์ƒํ’ˆ ์ถ”๊ฐ€ + console.log('[BuyOption] ๐Ÿ›’ Pushing CART_PANEL with name:', Config.panel_names.CART_PANEL); + console.log('[BuyOption] ๐Ÿ›’ mockProductInfo:', mockProductInfo); + console.log('[BuyOption] ๐Ÿ›’ optionInfo:', optionInfo); + console.log('[BuyOption] ๐Ÿ›’ quantity:', quantity); + dispatch( pushPanel({ name: Config.panel_names.CART_PANEL, diff --git a/com.twin.app.shoptime/src/views/MainView/MainView.jsx b/com.twin.app.shoptime/src/views/MainView/MainView.jsx index 9fa64d2b..5067463d 100644 --- a/com.twin.app.shoptime/src/views/MainView/MainView.jsx +++ b/com.twin.app.shoptime/src/views/MainView/MainView.jsx @@ -201,8 +201,13 @@ export default function MainView({ className, initService }) { const topPanel = panels[panels.length - 1]; // ๋‹จ๋… ํŒจ๋„ ์ฒดํฌ - CheckOutPanel, CartPanel ๋“ฑ ๋‹จ๋…์œผ๋กœ ๋ Œ๋”๋ง๋˜์–ด์•ผ ํ•˜๋Š” ํŒจ๋„๋“ค + console.log(`[MainView] ๐Ÿ” Top panel name: ${topPanel?.name}`); + console.log(`[MainView] ๐Ÿ” isStandalonePanel check:`, isStandalonePanel(topPanel?.name)); + console.log(`[MainView] ๐Ÿ” STANDALONE_PANELS:`, STANDALONE_PANELS); + console.log(`[MainView] ๐Ÿ” All panels:`, panels.map(p => ({ name: p.name, hasModal: !!p.panelInfo?.modal }))); + if (isStandalonePanel(topPanel?.name)) { - console.log(`[MainView] Standalone panel detected: ${topPanel?.name} - rendering independently`); + console.log(`[MainView] โœ… Standalone panel detected: ${topPanel?.name} - rendering independently`); renderingPanels = [topPanel]; // ๋‹จ๋… ํŒจ๋„๋งŒ ๋‹จ๋…์œผ๋กœ ๋ Œ๋”๋ง } // ๊ธฐ์กด 3-layer ๊ตฌ์กฐ ์ฒดํฌ: PlayerPanel + DetailPanel + MediaPanel(modal)