diff --git a/.gitignore b/.gitignore index 1eb2038..471aa24 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ pids # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +.sprint-plan.md diff --git a/apps/web/components/TagMultiSelect.tsx b/apps/web/components/TagMultiSelect.tsx new file mode 100644 index 0000000..94a871f --- /dev/null +++ b/apps/web/components/TagMultiSelect.tsx @@ -0,0 +1,46 @@ +'use client'; + +interface TagMultiSelectProps { + options: readonly string[]; + selected: string[]; + onChange: (selected: string[]) => void; + max?: number; + label: string; +} + +export function TagMultiSelect({ options, selected, onChange, max, label }: TagMultiSelectProps) { + function toggle(tag: string) { + if (selected.includes(tag)) { + onChange(selected.filter((t) => t !== tag)); + } else { + if (max && selected.length >= max) return; + onChange([...selected, tag]); + } + } + + return ( +
+

{label}

+
+ {options.map((tag) => { + const isSelected = selected.includes(tag); + const isDisabled = !isSelected && max !== undefined && selected.length >= max; + + return ( + + ); + })} +
+ {max &&

{selected.length} of {max} selected

} +
+ ); +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 3205808..cf8f814 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,2 +1,4 @@ export * from './types/auth.js'; export * from './validation/auth.js'; +export * from './types/tags.js'; +export * from './validation/tags.js'; diff --git a/packages/shared/src/types/tags.ts b/packages/shared/src/types/tags.ts new file mode 100644 index 0000000..5ec3066 --- /dev/null +++ b/packages/shared/src/types/tags.ts @@ -0,0 +1,41 @@ +export const CUISINE_TAGS = [ + 'american', + 'barbecue', + 'breakfast', + 'burgers', + 'caribbean', + 'chinese', + 'desserts', + 'fast-food', + 'french', + 'greek', + 'indian', + 'italian', + 'japanese', + 'korean', + 'lebanese', + 'mediterranean', + 'mexican', + 'pizza', + 'seafood', + 'sushi', + 'thai', + 'turkish', + 'vegan-friendly', + 'vietnamese', +] as const; + +export type CuisineTag = (typeof CUISINE_TAGS)[number]; + +export const DIETARY_TAGS = [ + 'vegetarian', + 'vegan', + 'gluten-free', + 'halal', + 'kosher', + 'dairy-free', + 'nut-free', + 'low-carb', +] as const; + +export type DietaryTag = (typeof DIETARY_TAGS)[number]; diff --git a/packages/shared/src/validation/tags.ts b/packages/shared/src/validation/tags.ts new file mode 100644 index 0000000..fc4eb9d --- /dev/null +++ b/packages/shared/src/validation/tags.ts @@ -0,0 +1,5 @@ +import { z } from 'zod'; +import { CUISINE_TAGS, DIETARY_TAGS } from '../types/tags.js'; + +export const cuisineTagSchema = z.enum(CUISINE_TAGS); +export const dietaryTagSchema = z.enum(DIETARY_TAGS);