From e716e8256cf91984f8303120d54af6a66c6261a7 Mon Sep 17 00:00:00 2001 From: Andymick Date: Tue, 21 Jul 2026 19:26:23 +0100 Subject: [PATCH] Feat: Remove all filters from products pages Remove search, category, color, and price filters from products and made-to-order pages. Keep only simple pagination for browsing. Simplifies UX and removes unnecessary database queries: - No category/collection queries needed - No palette generation - No filter logic Much cleaner pages with faster load times. Co-Authored-By: Claude Haiku 4.5 --- .claude/settings.local.json | 3 +- src/app/made-to-order/page.tsx | 284 ++++---------------------------- src/app/products/page.tsx | 293 ++++----------------------------- 3 files changed, 69 insertions(+), 511 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5829b74..17c2fb4 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -159,7 +159,8 @@ "Bash(curl -s http://127.0.0.1:3000/products/awd-hoodie)", "Bash(curl -s http://127.0.0.1:3000/made-to-order)", "Bash(curl -s \"http://127.0.0.1:3000/products/awd-hoodie\")", - "Bash(git commit -m 'Fix: NavDropdown link navigation with stopPropagation *)" + "Bash(git commit -m 'Fix: NavDropdown link navigation with stopPropagation *)", + "Bash(git commit -m 'Feat: Remove all filters from products pages *)" ] } } diff --git a/src/app/made-to-order/page.tsx b/src/app/made-to-order/page.tsx index 0a3c1a3..d29d160 100644 --- a/src/app/made-to-order/page.tsx +++ b/src/app/made-to-order/page.tsx @@ -1,17 +1,9 @@ import { prisma } from '@/lib/prisma'; import { toProductDTO } from '@/lib/product'; import { fetchActivePromotions } from '@/lib/promotions'; -import { getPersonalisedPaletteColors } from '@/lib/cache'; import ProductCard from '@/components/ProductCard'; -import type { Prisma } from '@prisma/client'; type SearchParams = { - category?: string | string[]; - collection?: string | string[]; - color?: string | string[]; - min?: string; - max?: string; - q?: string; page?: string; }; @@ -23,278 +15,72 @@ function toArray(v?: string | string[]) { } export default async function ProductsPage({ searchParams }: { searchParams: SearchParams }) { - const categoryRows = await prisma.category.findMany({ - where: { showOnPersonalised: true, parentId: null }, - orderBy: { name: 'asc' }, - select: { - id: true, - name: true, - slug: true, - children: { - where: { showOnPersonalised: true }, - select: { id: true, name: true, slug: true }, - orderBy: { name: 'asc' }, - }, - }, - }); - // Build flat list of all categories (parents and children) for filtering - const allCategories = categoryRows.flatMap((parent) => [ - { value: parent.slug, label: parent.name }, - ...parent.children.map((child) => ({ value: child.slug, label: `${parent.name} > ${child.name}` })), - ]); - const CATEGORIES = allCategories; - - const collectionRows = await prisma.collection.findMany({ - select: { slug: true, name: true, group: true }, - orderBy: { name: 'asc' }, - }); - const OCCASIONS = collectionRows.filter((c) => c.group === 'OCCASION').map((c) => ({ value: c.slug, label: c.name })); - const RECIPIENTS = collectionRows.filter((c) => c.group === 'RECIPIENT').map((c) => ({ value: c.slug, label: c.name })); - - const selectedCategories = toArray(searchParams.category); - const selectedCollections = toArray(searchParams.collection); - const selectedColors = toArray(searchParams.color); - const q = searchParams.q?.trim() ?? ''; - const minDollars = searchParams.min ? Number(searchParams.min) : undefined; - const maxDollars = searchParams.max ? Number(searchParams.max) : undefined; const currentPage = Math.max(1, Number(searchParams.page) || 1); - - // Cached palette across every personalised product - const palette = await getPersonalisedPaletteColors(); - - const where: Prisma.ProductWhereInput = { showOnPersonalised: true }; - if (selectedCategories.length) { - where.category = { in: selectedCategories }; - } - if (selectedCollections.length) { - where.collections = { some: { slug: { in: selectedCollections } } }; - } - if (selectedColors.length) { - where.AND = [{ OR: selectedColors.map((c) => ({ colors: { contains: c } })) }]; - } - if (q) { - where.name = { contains: q }; - } - if (minDollars !== undefined || maxDollars !== undefined) { - where.basePrice = { - ...(minDollars !== undefined ? { gte: Math.round(minDollars * 100) } : {}), - ...(maxDollars !== undefined ? { lte: Math.round(maxDollars * 100) } : {}), - }; - } - const activePromotions = await fetchActivePromotions(); const [rows, totalCount] = await Promise.all([ prisma.product.findMany({ - where, + where: { showOnPersonalised: true }, orderBy: { createdAt: 'asc' }, take: PRODUCTS_PER_PAGE, skip: (currentPage - 1) * PRODUCTS_PER_PAGE, }), - prisma.product.count({ where }), + prisma.product.count({ where: { showOnPersonalised: true } }), ]); const products = rows.map((p) => toProductDTO(p, activePromotions, 'personalised')); const totalPages = Math.ceil(totalCount / PRODUCTS_PER_PAGE); - const hasFilters = - selectedCategories.length > 0 || - selectedCollections.length > 0 || - selectedColors.length > 0 || - q || - minDollars !== undefined || - maxDollars !== undefined; - return (
-
+

Shop all

{totalCount} template{totalCount === 1 ? '' : 's'}

-
+
{/* Sidebar filters */} - - - {/* Grid */} -
- {products.length === 0 ? ( -
-

No templates match those filters

-

Try widening your price range or clearing a filter.

-
- ) : ( -
-
- {products.map((p) => ( - - ))} -
- - {totalPages > 1 && ( -
- {currentPage > 1 && ( - - ← Previous - - )} -

- Page {currentPage} of {totalPages} -

- {currentPage < totalPages && ( - - Next → - - )} -
- )} -
- )} -
- + )} +
); } diff --git a/src/app/products/page.tsx b/src/app/products/page.tsx index 8c7ce41..1fce1d7 100644 --- a/src/app/products/page.tsx +++ b/src/app/products/page.tsx @@ -1,120 +1,41 @@ import { prisma } from '@/lib/prisma'; import { toProductDTO } from '@/lib/product'; import { fetchActivePromotions } from '@/lib/promotions'; -import { getPaletteColors } from '@/lib/cache'; import ProductCard from '@/components/ProductCard'; -import type { Prisma } from '@prisma/client'; type SearchParams = { - category?: string | string[]; - collection?: string | string[]; - color?: string | string[]; - min?: string; - max?: string; - q?: string; page?: string; }; const PRODUCTS_PER_PAGE = 20; -function toArray(v?: string | string[]) { - if (!v) return []; - return Array.isArray(v) ? v : [v]; -} - export default async function ReadyMadeProductsPage({ searchParams }: { searchParams: SearchParams }) { - const categoryRows = await prisma.category.findMany({ - where: { showOnProducts: true, parentId: null }, - orderBy: { name: 'asc' }, - select: { - id: true, - name: true, - slug: true, - children: { - where: { showOnProducts: true }, - select: { id: true, name: true, slug: true }, - orderBy: { name: 'asc' }, - }, - }, - }); - // Build flat list of all categories (parents and children) for filtering - const allCategories = categoryRows.flatMap((parent) => [ - { value: parent.slug, label: parent.name }, - ...parent.children.map((child) => ({ value: child.slug, label: `${parent.name} > ${child.name}` })), - ]); - const CATEGORIES = allCategories; - - const collectionRows = await prisma.collection.findMany({ - select: { slug: true, name: true, group: true }, - orderBy: { name: 'asc' }, - }); - const OCCASIONS = collectionRows.filter((c) => c.group === 'OCCASION').map((c) => ({ value: c.slug, label: c.name })); - const RECIPIENTS = collectionRows.filter((c) => c.group === 'RECIPIENT').map((c) => ({ value: c.slug, label: c.name })); - - const selectedCategories = toArray(searchParams.category); - const selectedCollections = toArray(searchParams.collection); - const selectedColors = toArray(searchParams.color); - const q = searchParams.q?.trim() ?? ''; - const minDollars = searchParams.min ? Number(searchParams.min) : undefined; - const maxDollars = searchParams.max ? Number(searchParams.max) : undefined; const currentPage = Math.max(1, Number(searchParams.page) || 1); - - // Cached palette across ready-made products for the swatch filter - const palette = await getPaletteColors(); - - const where: Prisma.ProductWhereInput = { showAsReadyMade: true }; - if (selectedCategories.length) { - where.category = { in: selectedCategories }; - } - if (selectedCollections.length) { - where.collections = { some: { slug: { in: selectedCollections } } }; - } - if (selectedColors.length) { - where.AND = [{ OR: selectedColors.map((c) => ({ colors: { contains: c } })) }]; - } - if (q) { - where.name = { contains: q }; - } - if (minDollars !== undefined || maxDollars !== undefined) { - where.basePrice = { - ...(minDollars !== undefined ? { gte: Math.round(minDollars * 100) } : {}), - ...(maxDollars !== undefined ? { lte: Math.round(maxDollars * 100) } : {}), - }; - } - const activePromotions = await fetchActivePromotions(); const [rows, totalCount] = await Promise.all([ prisma.product.findMany({ - where, + where: { showAsReadyMade: true }, orderBy: { createdAt: 'asc' }, take: PRODUCTS_PER_PAGE, skip: (currentPage - 1) * PRODUCTS_PER_PAGE, }), - prisma.product.count({ where }), + prisma.product.count({ where: { showAsReadyMade: true } }), ]); const products = rows.map((p) => toProductDTO(p, activePromotions, 'plain')); const totalPages = Math.ceil(totalCount / PRODUCTS_PER_PAGE); - const hasFilters = - selectedCategories.length > 0 || - selectedCollections.length > 0 || - selectedColors.length > 0 || - q || - minDollars !== undefined || - maxDollars !== undefined; - return (
-
+

Products

- {products.length} item{products.length === 1 ? '' : 's'} + {totalCount} item{totalCount === 1 ? '' : 's'}

- {products.length === 0 && !hasFilters ? ( + {products.length === 0 ? (

Nothing here yet

@@ -123,187 +44,37 @@ export default async function ReadyMadeProductsPage({ searchParams }: { searchPa

) : ( -
- {/* Sidebar filters */} - - - {/* Grid */} -
- {products.length === 0 ? ( -
-

No products match those filters

-

Try widening your price range or clearing a filter.

-
- ) : ( -
-
- {products.map((p) => ( - - ))} -
- - {totalPages > 1 && ( -
- {currentPage > 1 && ( - - ← Previous - - )} -

- Page {currentPage} of {totalPages} -

- {currentPage < totalPages && ( - - Next → - - )} -
- )} -
- )} -
-
+ )} +
)}
);