104 lines
3.8 KiB
TypeScript
104 lines
3.8 KiB
TypeScript
import { X } from "lucide-react";
|
||
import { useSizeAttributes } from "~/requestHandler/use-product-hooks";
|
||
|
||
interface SizeSelectorProps {
|
||
selectedSizes: string[];
|
||
onToggleSize: (size: string) => void;
|
||
onRemoveSize: (size: string) => void;
|
||
unselectedMode: boolean;
|
||
onToggleUnselectedMode: (enabled: boolean) => void;
|
||
}
|
||
|
||
export const SizeSelector: React.FC<SizeSelectorProps> = ({
|
||
selectedSizes,
|
||
onToggleSize,
|
||
onRemoveSize,
|
||
unselectedMode,
|
||
onToggleUnselectedMode,
|
||
}: SizeSelectorProps) => {
|
||
const { data: sizes, isLoading } = useSizeAttributes();
|
||
if (isLoading) {
|
||
return (
|
||
<div className="space-y-4">
|
||
<h4 className="font-medium text-right">انتخاب سایز های موجود:</h4>
|
||
<div className="grid grid-cols-4 gap-2">
|
||
{[...Array(7)].map((_, i) => (
|
||
<div
|
||
key={i}
|
||
className="py-3 px-4 rounded-lg border-2 border-WHITE2 bg-WHITE3 animate-pulse h-12"
|
||
/>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="space-y-4">
|
||
<h4 className="font-medium text-right">انتخاب سایز های موجود:</h4>
|
||
|
||
{/* Unselected Mode Switch */}
|
||
<div className="flex items-center justify-between p-3 bg-GRAY3 rounded-lg">
|
||
<span className="text-sm font-medium text-BLACK2">
|
||
بدون مشخص کردن سایز
|
||
</span>
|
||
<label className="relative inline-flex items-center cursor-pointer">
|
||
<input
|
||
type="checkbox"
|
||
checked={unselectedMode}
|
||
onChange={(e) => onToggleUnselectedMode(e.target.checked)}
|
||
className="sr-only peer"
|
||
aria-label="حالت بدون سایز"
|
||
/>
|
||
<div className="w-11 h-6 bg-WHITE2 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-WHITE after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-WHITE after:border-GRAY3 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-VITROWN_BLUE border"></div>
|
||
</label>
|
||
</div>
|
||
|
||
{/* Size Selection Grid - Disabled when unselected mode is on */}
|
||
<div
|
||
className={`grid grid-cols-4 gap-2 ${unselectedMode ? "opacity-50 pointer-events-none" : ""}`}
|
||
>
|
||
{sizes.map((size) => (
|
||
<>
|
||
{size.value !== "UNSELECTED" && (
|
||
<button
|
||
key={size.id}
|
||
onClick={() => !unselectedMode && onToggleSize(size.value)}
|
||
disabled={unselectedMode}
|
||
className={`py-3 px-4 rounded-lg border-2 text-sm font-medium transition-all ${
|
||
selectedSizes.includes(size.value)
|
||
? "border-blue-500 bg-blue-50 text-blue-700"
|
||
: "border-WHITE2 hover:border-GRAY3 hover:bg-WHITE3"
|
||
}`}
|
||
>
|
||
{size.info?.persian || size.value}
|
||
</button>
|
||
)}
|
||
</>
|
||
))}
|
||
</div>
|
||
|
||
{/* Selected Sizes */}
|
||
{selectedSizes.length > 0 && !unselectedMode && (
|
||
<div className="flex flex-wrap gap-2">
|
||
{selectedSizes.map((sizeValue) => {
|
||
const sizeInfo = sizes.find((s) => s.value === sizeValue);
|
||
return (
|
||
<div
|
||
key={sizeValue}
|
||
className="flex items-center gap-1 bg-blue-100 px-3 py-1 rounded-full text-sm text-blue-700"
|
||
>
|
||
<span>{sizeInfo?.info?.persian || sizeValue}</span>
|
||
<X
|
||
onClick={() => onRemoveSize(sizeValue)}
|
||
className="w-4 h-4 cursor-pointer text-red-500"
|
||
/>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|