From 474470900f172249958ea6872aa2ef294438c6ab Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 13 Feb 2026 13:27:19 -0700 Subject: [PATCH] Automatic inventory management for the store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Artworks now automatically appear in the store when their required fields are populated in Directus (name, image, and at least one price in GBP or USD). Changing status to 'sold' moves them to the sold section; 'draft' or 'archived' removes them entirely. No manual "add to store" step needed — field completeness drives visibility. Also ensures related works on detail pages only show store-ready items. Co-Authored-By: Claude Opus 4.6 --- frontend/src/app/store/[slug]/page.tsx | 2 +- frontend/src/lib/directus.ts | 30 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/store/[slug]/page.tsx b/frontend/src/app/store/[slug]/page.tsx index 9c82ff3..60b38d1 100644 --- a/frontend/src/app/store/[slug]/page.tsx +++ b/frontend/src/app/store/[slug]/page.tsx @@ -37,7 +37,7 @@ export default async function ArtworkDetailPage({ params }: PageProps) { // Fetch related works server-side let relatedWorks: Artwork[] = []; try { - const allWorks = await getArtworks({ status: 'published', limit: 4 }); + const allWorks = await getArtworks({ status: 'published', forSale: true, limit: 4 }); relatedWorks = allWorks.filter((w) => w.id !== artwork.id).slice(0, 3); } catch { relatedWorks = []; diff --git a/frontend/src/lib/directus.ts b/frontend/src/lib/directus.ts index 9cac97c..2c661df 100644 --- a/frontend/src/lib/directus.ts +++ b/frontend/src/lib/directus.ts @@ -240,12 +240,36 @@ export async function getArtworks(options?: { fields?: string[]; forSale?: boolean; }): Promise { + // When forSale is true, build a compound filter requiring: + // - name set, image set, and at least one price (GBP or USD) > 0 + // This means artworks automatically appear in the store once their + // required fields are populated, and disappear when status changes to sold/archived. + if (options?.forSale) { + const conditions: Record[] = [ + { name: { _nnull: true, _nempty: true } }, + { image: { _nnull: true } }, + { _or: [ + { price_gbp: { _gt: 0 } }, + { price_usd: { _gt: 0 } }, + ]}, + ]; + if (options?.status) conditions.push({ status: { _eq: options.status } }); + if (options?.series) conditions.push({ series: { _eq: options.series } }); + + const result = await directus.request( + readItems('artworks', { + filter: { _and: conditions }, + limit: options?.limit || -1, + sort: ['-date_created'], + fields: options?.fields || ['*'], + }) + ); + return (result as Artwork[]).map(mapArtwork); + } + const filter: Record = {}; if (options?.status) filter.status = { _eq: options.status }; if (options?.series) filter.series = { _eq: options.series }; - if (options?.forSale) { - filter.price_gbp = { _nnull: true, _gt: 0 }; - } const result = await directus.request( readItems('artworks', {