168 lines
6.5 KiB
TypeScript
168 lines
6.5 KiB
TypeScript
import { Plus } from "lucide-react";
|
||
import { Button } from "../ui/button";
|
||
import { QuantityControl } from "../cart/QuantityControl";
|
||
import { ProductVariantDrawer } from "./ProductVariantDrawer";
|
||
import { useState } from "react";
|
||
import { useColorAttributes } from "~/requestHandler/use-product-hooks";
|
||
|
||
interface ProductVariant {
|
||
color: string;
|
||
size: string;
|
||
quantity: number;
|
||
}
|
||
|
||
interface ProductVariantsSectionProps {
|
||
productVariants: ProductVariant[];
|
||
setProductVariants: (variants: ProductVariant[]) => void;
|
||
onUpdateVariantQuantity: (index: number, newQuantity: number) => void;
|
||
}
|
||
|
||
export const ProductVariantsSection: React.FC<ProductVariantsSectionProps> = ({
|
||
productVariants,
|
||
setProductVariants,
|
||
onUpdateVariantQuantity,
|
||
}: ProductVariantsSectionProps) => {
|
||
const { data: colorAttributes } = useColorAttributes();
|
||
|
||
// Handle variants
|
||
const [isVariantDrawerOpen, setIsVariantDrawerOpen] = useState(false);
|
||
const [variantDrawerKey, setVariantDrawerKey] = useState(0);
|
||
const [isEditingVariants, setIsEditingVariants] = useState(false);
|
||
const handleAddVariantClick = () => {
|
||
setVariantDrawerKey(Date.now());
|
||
setIsEditingVariants(productVariants.length > 0);
|
||
setIsVariantDrawerOpen(true);
|
||
};
|
||
return (
|
||
<>
|
||
<div className="flex flex-col gap-6 p-4">
|
||
<div className="w-full gap-2 flex flex-col">
|
||
<p className="text-R14">ویژگیهای محصول:</p>
|
||
<Button
|
||
className="w-full"
|
||
size="xl"
|
||
variant="dark"
|
||
onClick={handleAddVariantClick}
|
||
>
|
||
<Plus className="w-5 h-5" />
|
||
{productVariants.length > 0
|
||
? "ویرایش ویژگیها"
|
||
: "افزودن ویژگی جدید"}
|
||
</Button>
|
||
|
||
{/* Variants Preview */}
|
||
{productVariants.length > 0 && (
|
||
<div className="mt-4 space-y-3">
|
||
<h4 className="text-sm font-medium text-right">
|
||
انواع محصول ({productVariants.length} نوع):
|
||
</h4>
|
||
<div className="space-y-2 max-h-60 overflow-y-auto">
|
||
{productVariants.map((variant, index) => {
|
||
return (
|
||
<div
|
||
key={`${variant.color}-${variant.size}-${index}`}
|
||
className="flex items-center justify-between p-3 bg-WHITE3 border rounded-lg"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
{/* Display color only if not unselected */}
|
||
{variant.color !== "unselected" && (
|
||
<div className="flex items-center gap-2">
|
||
<div
|
||
className="w-6 h-6 rounded border border-GRAY3"
|
||
style={{
|
||
backgroundColor: variant.color,
|
||
}}
|
||
/>
|
||
<span className="text-sm">
|
||
{(() => {
|
||
try {
|
||
const colorInfo = colorAttributes?.find(
|
||
(c) => c.value === variant.color
|
||
);
|
||
return (
|
||
colorInfo?.info?.persian || variant.color
|
||
);
|
||
} catch {
|
||
return variant.color;
|
||
}
|
||
})()}
|
||
</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Display size only if not unselected */}
|
||
{variant.size !== "unselected" && (
|
||
<div className="flex items-center gap-1">
|
||
<span className="text-xs text-GRAY">سایز:</span>
|
||
<span className="text-sm font-medium">
|
||
{variant.size}
|
||
</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Show general text when both are unselected */}
|
||
{variant.color === "unselected" &&
|
||
variant.size === "unselected" && (
|
||
<span className="text-sm font-medium text-BLACK2">
|
||
محصول کلی
|
||
</span>
|
||
)}
|
||
</div>
|
||
<QuantityControl
|
||
isPending={false}
|
||
quantity={variant.quantity}
|
||
maxQuantity={1000}
|
||
allowManualEdit={true}
|
||
onQuantityChange={(newQuantity) => {
|
||
onUpdateVariantQuantity(index, newQuantity);
|
||
}}
|
||
onIncrease={() => {
|
||
onUpdateVariantQuantity(index, variant.quantity + 1);
|
||
}}
|
||
onDecrease={() => {
|
||
if (variant.quantity > 0) {
|
||
onUpdateVariantQuantity(
|
||
index,
|
||
variant.quantity - 1
|
||
);
|
||
}
|
||
}}
|
||
/>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
<div className="mt-3 pt-3 border-t border-WHITE2">
|
||
<div className="flex justify-between text-sm font-medium">
|
||
<span>مجموع موجودی:</span>
|
||
<span>
|
||
{productVariants.reduce((sum, v) => sum + v.quantity, 0)}{" "}
|
||
عدد
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
{/* Product Variant Drawer */}
|
||
<ProductVariantDrawer
|
||
key={variantDrawerKey}
|
||
isOpen={isVariantDrawerOpen}
|
||
onClose={() => {
|
||
setIsVariantDrawerOpen(false);
|
||
setIsEditingVariants(false);
|
||
}}
|
||
onSave={(variants) => {
|
||
setProductVariants(
|
||
variants.filter((variant) => variant.quantity > 0)
|
||
);
|
||
setVariantDrawerKey(Date.now());
|
||
setIsEditingVariants(false);
|
||
}}
|
||
initialVariants={isEditingVariants ? productVariants : []}
|
||
/>
|
||
</>
|
||
);
|
||
};
|