diff --git a/src/app/store/[slug]/components/product-details.tsx b/src/app/store/[slug]/components/product-details.tsx index 5b7c741d..652bdc97 100644 --- a/src/app/store/[slug]/components/product-details.tsx +++ b/src/app/store/[slug]/components/product-details.tsx @@ -1,12 +1,12 @@ "use client"; -import { useState, useMemo } from "react"; +import { useState } from "react"; import { VariantSelector, type Variant } from "./variant-selector"; import { AddToCartButton } from "./add-to-cart-button"; import { PriceDisplay } from "./price-display"; import { StockBadge } from "./stock-badge"; import { Truck } from "lucide-react"; -import { DiscountType, type DiscountInfo } from "@/lib/discount-utils"; +import { DiscountType, type DiscountInfo, getEffectiveDiscount } from "@/lib/discount-utils"; interface ProductDetailsProps { product: { @@ -41,19 +41,15 @@ export function ProductDetails({ storeSlug, onImageChange, }: ProductDetailsProps) { - const defaultVariant = useMemo( - () => variants.find((v) => v.isDefault) || variants[0] || null, - [variants] - ); - - const [selectedVariant, setSelectedVariant] = useState(defaultVariant); + // No variant pre-selected: show product.price initially, variant price only after user selection + const [selectedVariant, setSelectedVariant] = useState(null); - // Calculate current price and inventory based on variant selection + // Show product default price until user explicitly picks a variant const currentPrice = selectedVariant?.price ?? product.price; const currentCompareAtPrice = selectedVariant?.compareAtPrice ?? product.compareAtPrice; - const currentInventory = selectedVariant?.inventoryQty ?? product.inventoryQty; + const currentInventory = selectedVariant ? selectedVariant.inventoryQty : product.inventoryQty; - // Build discount info for price display + // Build discount info for product and variant const productDiscount: DiscountInfo = { discountType: product.discountType ?? null, discountValue: product.discountValue ?? null, @@ -61,14 +57,29 @@ export function ProductDetails({ discountEndDate: product.discountEndDate ? new Date(product.discountEndDate) : null, }; + const variantDiscount: DiscountInfo | null = selectedVariant ? { + discountType: selectedVariant.discountType ?? null, + discountValue: selectedVariant.discountValue ?? null, + discountStartDate: selectedVariant.discountStartDate ? new Date(selectedVariant.discountStartDate) : null, + discountEndDate: selectedVariant.discountEndDate ? new Date(selectedVariant.discountEndDate) : null, + } : null; + + // Use variant discount if active, otherwise fall back to product discount + const effectiveDiscount = getEffectiveDiscount(productDiscount, variantDiscount); + // Check if product has courier pricing const hasCourierPricing = (product.courierPriceInsideDhaka ?? 0) > 0 || (product.courierPriceOutsideDhaka ?? 0) > 0; const handleVariantChange = (variant: Variant) => { - setSelectedVariant(variant); - // Update image gallery if variant has an image - if (variant.image && onImageChange) { - onImageChange(variant.image); + // Toggle: if already selected, deselect it (go back to default product price) + if (selectedVariant?.id === variant.id) { + setSelectedVariant(null); + } else { + setSelectedVariant(variant); + // Update image gallery if variant has an image + if (variant.image && onImageChange) { + onImageChange(variant.image); + } } }; @@ -79,7 +90,7 @@ export function ProductDetails({ @@ -124,6 +135,7 @@ export function ProductDetails({ {variants.length >= 1 && ( )} diff --git a/src/app/store/[slug]/components/variant-selector.tsx b/src/app/store/[slug]/components/variant-selector.tsx index 00cf8c11..752e2915 100644 --- a/src/app/store/[slug]/components/variant-selector.tsx +++ b/src/app/store/[slug]/components/variant-selector.tsx @@ -1,6 +1,5 @@ "use client"; -import { useState } from "react"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; @@ -25,6 +24,7 @@ export interface Variant { interface VariantSelectorProps { variants: Variant[]; + selectedVariantId?: string | null; onVariantChange?: (variant: Variant) => void; className?: string; } @@ -36,14 +36,17 @@ interface VariantSelectorProps { */ export function VariantSelector({ variants, + selectedVariantId, onVariantChange, className, }: VariantSelectorProps) { - const defaultVariant = variants.find((v) => v.isDefault) || variants[0] || null; - const [selectedVariant, setSelectedVariant] = useState(defaultVariant); + // Use external selectedVariantId if provided, otherwise manage locally + const selectedVariant = selectedVariantId + ? variants.find((v) => v.id === selectedVariantId) ?? null + : null; // Early return if no variants - if (variants.length === 0 || !selectedVariant) { + if (variants.length === 0) { return null; } @@ -69,7 +72,6 @@ export function VariantSelector({ }); const handleVariantSelect = (variant: Variant) => { - setSelectedVariant(variant); onVariantChange?.(variant); }; @@ -80,12 +82,12 @@ export function VariantSelector({
{variants.map((variant) => { - const isSelected = selectedVariant.id === variant.id; + const isSelected = selectedVariant?.id === variant.id; const isOutOfStock = variant.inventoryQty === 0; return ( @@ -133,9 +135,10 @@ export function VariantSelector({ {optionName}:{" "} {(() => { + if (!selectedVariant) return "Select"; try { const opts = JSON.parse(selectedVariant.options); - return opts[optionName]; + return opts[optionName] || ""; } catch { return ""; } @@ -157,7 +160,7 @@ export function VariantSelector({ if (!matchingVariant) return null; - const isSelected = selectedVariant.id === matchingVariant.id; + const isSelected = selectedVariant?.id === matchingVariant.id; const isOutOfStock = matchingVariant.inventoryQty === 0; return (