Merge version_2_1777290330734 into main
Merge version_2_1777290330734 into main
This commit was merged in pull request #1.
This commit is contained in:
@@ -17,6 +17,7 @@ type ProductQuantityCardsProps = {
|
||||
name: string;
|
||||
price: string;
|
||||
imageSrc: string;
|
||||
description?: string;
|
||||
onAddToCart?: (quantity: number) => void;
|
||||
}[];
|
||||
};
|
||||
@@ -37,6 +38,7 @@ const ProductQuantityCards = ({
|
||||
name: p.name,
|
||||
price: p.price,
|
||||
imageSrc: p.imageSrc,
|
||||
description: p.description,
|
||||
onAddToCart: undefined as ((quantity: number) => void) | undefined,
|
||||
}))
|
||||
: productsProp;
|
||||
@@ -90,7 +92,7 @@ const ProductQuantityCards = ({
|
||||
{(primaryButton || secondaryButton) && (
|
||||
<div className="flex flex-wrap justify-center gap-3 mt-3">
|
||||
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary"/>}
|
||||
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary"animationDelay={0.1} />}
|
||||
{secondaryButton && <Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animationDelay={0.1} />}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -100,42 +102,87 @@ const ProductQuantityCards = ({
|
||||
{products.map((product) => (
|
||||
<div
|
||||
key={product.name}
|
||||
className="h-full flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 card rounded"
|
||||
className="group perspective-1000 w-full h-full min-h-[420px]"
|
||||
>
|
||||
<div className="aspect-square rounded overflow-hidden">
|
||||
<ImageOrVideo imageSrc={product.imageSrc} />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<h3 className="text-xl font-medium truncate">{product.name}</h3>
|
||||
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => handleDecrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Decrease quantity"
|
||||
>
|
||||
<Minus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
|
||||
<span className="w-fit text-base text-center font-medium">{getQuantity(product.name)}</span>
|
||||
|
||||
<button
|
||||
onClick={() => handleIncrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Increase quantity"
|
||||
>
|
||||
<Plus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
<div className="relative w-full h-full transform-style-preserve-3d transition-transform duration-700 group-hover:rotate-y-180">
|
||||
{/* Front Face */}
|
||||
<div className="absolute inset-0 backface-hidden flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 card rounded">
|
||||
<div className="aspect-square rounded overflow-hidden shrink-0">
|
||||
<ImageOrVideo imageSrc={product.imageSrc} />
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => product.onAddToCart?.(getQuantity(product.name))}
|
||||
className="h-8 px-5 rounded primary-button text-base text-primary-cta-text font-medium cursor-pointer"
|
||||
>
|
||||
{product.price}
|
||||
</button>
|
||||
<div className="flex flex-col gap-3 flex-1 justify-between">
|
||||
<h3 className="text-xl font-medium truncate">{product.name}</h3>
|
||||
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => handleDecrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Decrease quantity"
|
||||
>
|
||||
<Minus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
|
||||
<span className="w-fit text-base text-center font-medium">{getQuantity(product.name)}</span>
|
||||
|
||||
<button
|
||||
onClick={() => handleIncrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Increase quantity"
|
||||
>
|
||||
<Plus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => product.onAddToCart?.(getQuantity(product.name))}
|
||||
className="h-8 px-5 rounded primary-button text-base text-primary-cta-text font-medium cursor-pointer"
|
||||
>
|
||||
{product.price}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Back Face */}
|
||||
<div className="absolute inset-0 backface-hidden rotate-y-180 flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 card rounded">
|
||||
<h3 className="text-xl font-medium">{product.name}</h3>
|
||||
|
||||
<div className="flex-1 overflow-y-auto pr-2">
|
||||
<p className="text-base leading-relaxed opacity-80">
|
||||
{product.description || "Detailed product information will be displayed here. This includes specifications, materials, and care instructions to help you make an informed decision."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between gap-3 pt-3 border-t border-foreground/10 shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => handleDecrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Decrease quantity"
|
||||
>
|
||||
<Minus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
|
||||
<span className="w-fit text-base text-center font-medium">{getQuantity(product.name)}</span>
|
||||
|
||||
<button
|
||||
onClick={() => handleIncrement(product.name)}
|
||||
className="flex items-center justify-center size-8 rounded card cursor-pointer"
|
||||
aria-label="Increase quantity"
|
||||
>
|
||||
<Plus className="size-4" strokeWidth={1.5} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => product.onAddToCart?.(getQuantity(product.name))}
|
||||
className="h-8 px-5 rounded primary-button text-base text-primary-cta-text font-medium cursor-pointer"
|
||||
>
|
||||
{product.price}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,4 +194,4 @@ const ProductQuantityCards = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductQuantityCards;
|
||||
export default ProductQuantityCards;
|
||||
@@ -198,3 +198,18 @@ h6 {
|
||||
bg, a same-color border is invisible and the button disappears. */
|
||||
border: 1px solid color-mix(in srgb, var(--color-foreground) 18%, transparent);
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.perspective-1000 {
|
||||
perspective: 1000px;
|
||||
}
|
||||
.transform-style-preserve-3d {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
.backface-hidden {
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
.rotate-y-180 {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user