import Layout from "@/components/Layout"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import ShowcaseCard from "@/components/showcase/ShowcaseCard"; 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); fetchBuilderList("showcase-project", { limit: 50 }) .then((res) => { const items: ShowcaseProject[] = (res.results || []).map((r) => ({ id: r.id, title: r.data?.title || r.name || "Untitled", orgUnit: r.data?.orgUnit, role: r.data?.role, timeframe: r.data?.timeframe, description: r.data?.description, tags: r.data?.tags || [], links: r.data?.links || [], contributors: r.data?.contributors || [], image: r.data?.image, })); setCmsItems(items); }) .catch(() => setCmsItems(null)) .finally(() => setLoading(false)); }, [dbItems]); const items = useMemo(() => (dbItems && dbItems.length ? dbItems : cmsItems && cmsItems.length ? cmsItems : SHOWCASE), [dbItems, cmsItems]); const hasProjects = Array.isArray(items) && items.length > 0; return (
Showcase

Projects & Testimonials

Studio initiatives across AeThex Platform, Labs, and Studio.

{isOwner && ( )}
{hasProjects ? (
{items.map((p) => ( ))}
) : ( No projects yet Add entries in code/client/data/showcase.ts or manage them via CMS. )}
); }