Vitron-Front/app/components/store/SizeSelector.tsx
2026-04-29 01:44:16 +03:30

104 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
};