From 64adef53d35432a3a293675af8cbae0d2abf717b Mon Sep 17 00:00:00 2001 From: Andymick Date: Tue, 21 Jul 2026 17:54:08 +0100 Subject: [PATCH] Feat: Add cascading category picker to product forms Implemented hierarchical category selection in product creation and edit forms. Now displays parent categories first, then shows child categories when a parent is selected (e.g., Apparel > Adults, Kids, Babies). Changes: - Create CategoryPicker client component for cascading selection - Update new product page to use CategoryPicker - Update edit product page to use CategoryPicker - Query categories with children relationship User experience: 1. Select parent category (Apparel, Drinkware, Phone Cases, etc.) 2. Select specific type (Adults/Kids/Babies, Ceramic/Steel, etc.) 3. Form automatically validates that both selections are made Co-Authored-By: Claude Haiku 4.5 --- src/app/admin/products/[id]/edit/page.tsx | 23 ++---- src/app/admin/products/new/page.tsx | 24 ++---- src/components/CategoryPicker.tsx | 93 +++++++++++++++++++++++ 3 files changed, 106 insertions(+), 34 deletions(-) create mode 100644 src/components/CategoryPicker.tsx diff --git a/src/app/admin/products/[id]/edit/page.tsx b/src/app/admin/products/[id]/edit/page.tsx index ef35582..03b1bd8 100644 --- a/src/app/admin/products/[id]/edit/page.tsx +++ b/src/app/admin/products/[id]/edit/page.tsx @@ -7,6 +7,7 @@ import AdminNav from '@/components/AdminNav'; import ColorPicker from '@/components/ColorPicker'; import SizePicker from '@/components/SizePicker'; import PhotoPrintAreaField, { type Box } from '@/components/PhotoPrintAreaField'; +import CategoryPicker from '@/components/CategoryPicker'; import { MOCKUP_OPTIONS } from '@/lib/mockupDefaults'; export default async function EditProductPage({ params }: { params: { id: string } }) { @@ -15,7 +16,10 @@ export default async function EditProductPage({ params }: { params: { id: string if (!row) notFound(); const product = toProductDTO(row, activePromotions); - const categories = await prisma.category.findMany({ orderBy: { name: 'asc' } }); + const categories = await prisma.category.findMany({ + orderBy: { name: 'asc' }, + include: { children: { orderBy: { name: 'asc' } } }, + }); const collections = await prisma.collection.findMany({ orderBy: { name: 'asc' } }); const occasions = collections.filter((c) => c.group === 'OCCASION'); const recipients = collections.filter((c) => c.group === 'RECIPIENT'); @@ -100,22 +104,7 @@ export default async function EditProductPage({ params }: { params: { id: string
- - +