Files
craft2prints/src/components/PromotionScopePicker.tsx
T

78 lines
2.4 KiB
TypeScript

'use client';
import { useState } from 'react';
type Product = { id: string; name: string };
// Checking a product auto-switches scope to "Specific items" — picking an
// item to discount only makes sense if the promotion is actually scoped to
// specific items, so we don't make the admin flip the radio manually too.
export default function PromotionScopePicker({
products,
defaultScope = 'ALL',
defaultSelectedIds = [],
}: {
products: Product[];
defaultScope?: 'ALL' | 'SPECIFIC';
defaultSelectedIds?: string[];
}) {
const [scope, setScope] = useState<'ALL' | 'SPECIFIC'>(defaultScope);
const [selected, setSelected] = useState<Set<string>>(new Set(defaultSelectedIds));
const toggleProduct = (id: string, checked: boolean) => {
setSelected((prev) => {
const next = new Set(prev);
if (checked) next.add(id);
else next.delete(id);
return next;
});
if (checked) setScope('SPECIFIC');
};
return (
<fieldset>
<legend className="tag-label mb-2 block">Applies to</legend>
<div className="space-y-3">
<label className="flex items-center gap-2 text-sm">
<input
type="radio"
name="scope"
value="ALL"
checked={scope === 'ALL'}
onChange={() => setScope('ALL')}
className="h-4 w-4 accent-clay"
/>
All items
</label>
<label className="flex items-center gap-2 text-sm">
<input
type="radio"
name="scope"
value="SPECIFIC"
checked={scope === 'SPECIFIC'}
onChange={() => setScope('SPECIFIC')}
className="h-4 w-4 accent-clay"
/>
Specific items
</label>
</div>
<div className="mt-3 max-h-64 space-y-2 overflow-y-auto border border-line bg-paper p-3">
{products.map((p) => (
<label key={p.id} className="flex items-center gap-2 text-sm">
<input
type="checkbox"
name="productIds"
value={p.id}
checked={selected.has(p.id)}
onChange={(e) => toggleProduct(p.id, e.target.checked)}
className="h-4 w-4 accent-clay"
/>
{p.name}
</label>
))}
</div>
<p className="mt-1 text-xs text-muted">Only used when &quot;Specific items&quot; is selected above.</p>
</fieldset>
);
}