import style from '../styles/summary.module.css'; import React, { useEffect, useState, useMemo } from 'react'; import formatCurrency from '~/libs/formatCurrency'; import clsxm from '~/libs/clsxm'; import { Skeleton, Box, useColorModeValue, Text } from '@chakra-ui/react'; type Props = { total?: number; discount?: number; subtotal?: number; tax?: number; shipping?: number; grandTotal?: number; isLoaded: boolean; products?: any[]; // Added to detect changes in selected products }; const CartSummary = ({ total, discount, subtotal, tax, shipping, grandTotal, isLoaded = false, products = [], }: Props) => { const PPN: number = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; const [isMounted, setIsMounted] = useState(false); // Local state to store calculated values const [summaryValues, setSummaryValues] = useState({ subtotal: 0, discount: 0, total: 0, tax: 0, shipping: 0, grandTotal: 0, }); // This fixes hydration issues by ensuring the component only renders fully after mounting useEffect(() => { setIsMounted(true); }, []); // Calculate summary based on products whenever products change useMemo(() => { if (!products || products.length === 0) return; // Only count selected products const selectedProducts = products.filter((product) => product.selected); // Calculate values based on selected products let calculatedSubtotal = 0; let calculatedDiscount = 0; selectedProducts.forEach((product) => { // Get raw price and discount from product const productBasePrice = product.price?.price || 0; const productQty = product.quantity || 1; const productDiscountedPrice = product.price?.price_discount || productBasePrice; const productDiscount = productBasePrice - productDiscountedPrice; calculatedSubtotal += productBasePrice * productQty; calculatedDiscount += productDiscount * productQty; }); const calculatedTotal = calculatedSubtotal - calculatedDiscount; const calculatedTax = calculatedTotal * (PPN - 1); const calculatedShipping = shipping || 0; const calculatedGrandTotal = calculatedTotal + calculatedTax + calculatedShipping; // If calculated values are different from props, use calculated ones const shouldUpdateValues = Math.abs((subtotal || 0) - calculatedSubtotal) > 0.01 || Math.abs((discount || 0) - calculatedDiscount) > 0.01 || Math.abs((total || 0) - calculatedTotal) > 0.01 || Math.abs((tax || 0) - calculatedTax) > 0.01 || Math.abs((grandTotal || 0) - calculatedGrandTotal) > 0.01; if (shouldUpdateValues && isLoaded) { setSummaryValues({ subtotal: calculatedSubtotal, discount: calculatedDiscount, total: calculatedTotal, tax: calculatedTax, shipping: calculatedShipping, grandTotal: calculatedGrandTotal, }); } else if (isLoaded) { // Use values from props when available setSummaryValues({ subtotal: subtotal || 0, discount: discount || 0, total: total || 0, tax: tax || 0, shipping: shipping || 0, grandTotal: grandTotal || 0, }); } }, [ products, isLoaded, subtotal, discount, total, tax, shipping, grandTotal, PPN, ]); // Update local values whenever props change useEffect(() => { if (isLoaded) { setSummaryValues({ subtotal: subtotal || 0, discount: discount || 0, total: total || 0, tax: tax || 0, shipping: shipping || 0, grandTotal: grandTotal || 0, }); } }, [isLoaded, subtotal, discount, total, tax, shipping, grandTotal]); if (!isMounted) { return ( Ringkasan Pesanan {Array(6) .fill(0) .map((_, index) => ( ))} ); } // Use local state for rendering to ensure responsiveness const { subtotal: displaySubtotal, discount: displayDiscount, total: displayTotal, tax: displayTax, shipping: displayShipping, grandTotal: displayGrandTotal, } = summaryValues; return (
Ringkasan Pesanan
Total Belanja Rp {formatCurrency(displaySubtotal)} Total Diskon - Rp {formatCurrency(displayDiscount)}
Subtotal Rp {formatCurrency(displayTotal)} Tax {((PPN - 1) * 100).toFixed(0)}% Rp {formatCurrency(displayTax)} Biaya Kirim Rp {formatCurrency(displayShipping)}
Grand Total Rp {formatCurrency(grandTotal || 0)}
); }; export default CartSummary;