78 lines
2.4 KiB
TypeScript
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 "Specific items" is selected above.</p>
|
|
</fieldset>
|
|
);
|
|
}
|