From d8ed3af6ecc075ed92a22c43ae22d0878b6af141 Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sun, 19 Oct 2025 03:00:43 +0000 Subject: [PATCH] Projects: prefer Supabase data with embedding; fallback to CMS/local cgen-3ef9f282e96c4d179464123af37f4d5d --- client/pages/Projects.tsx | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/client/pages/Projects.tsx b/client/pages/Projects.tsx index 8f0de0f8..7f6639e6 100644 --- a/client/pages/Projects.tsx +++ b/client/pages/Projects.tsx @@ -7,14 +7,46 @@ import { SHOWCASE, type ShowcaseProject } from "@/data/showcase"; import { useEffect, useMemo, useState } from "react"; import { fetchBuilderList, getBuilderApiKey } from "@/lib/builder"; import { useAuth } from "@/contexts/AuthContext"; +import { supabase } from "@/lib/supabase"; export default function Projects() { const { roles } = useAuth(); const isOwner = Array.isArray(roles) && roles.includes("owner"); + const [dbItems, setDbItems] = useState(null); const [cmsItems, setCmsItems] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { + // Try Supabase first (public read with RLS) + setLoading(true); + supabase + .from("showcase_projects" as any) + .select( + "id,title,org_unit,role,timeframe,description,tags,image, links:showcase_project_links(label,href), contributors:showcase_contributors(name,title,avatar)" + ) + .order("created_at", { ascending: false }) + .then(({ data, error }) => { + if (!error && Array.isArray(data) && data.length) { + const mapped: ShowcaseProject[] = data.map((r: any) => ({ + id: r.id, + title: r.title, + orgUnit: r.org_unit as any, + role: r.role ?? undefined, + timeframe: r.timeframe ?? undefined, + description: r.description ?? undefined, + tags: r.tags ?? [], + image: r.image ?? undefined, + links: r.links ?? [], + contributors: r.contributors ?? [], + })); + setDbItems(mapped); + } + }) + .finally(() => setLoading(false)); + }, []); + + useEffect(() => { + if (dbItems && dbItems.length) return; // Skip CMS if DB has content const apiKey = getBuilderApiKey(); if (!apiKey) return; setLoading(true); @@ -36,9 +68,9 @@ export default function Projects() { }) .catch(() => setCmsItems(null)) .finally(() => setLoading(false)); - }, []); + }, [dbItems]); - const items = useMemo(() => (cmsItems && cmsItems.length ? cmsItems : SHOWCASE), [cmsItems]); + const items = useMemo(() => (dbItems && dbItems.length ? dbItems : cmsItems && cmsItems.length ? cmsItems : SHOWCASE), [dbItems, cmsItems]); const hasProjects = Array.isArray(items) && items.length > 0; return (