"use client"; import { createContext, type ReactNode, useCallback, useContext, useMemo, useState, } from "react"; import type { PortfolioProjectView } from "@/lib/portfolio-data"; import { SHOWCASE, type ShowcaseConfig } from "@/lib/project-showcase"; import { ProjectLightbox } from "./ProjectLightbox"; export interface ShowcaseItem { config: ShowcaseConfig; project: PortfolioProjectView; } interface ShowcaseApi { open(id: string): void; items: ShowcaseItem[]; } const ApiContext = createContext(null); /** Só aparece como card com vídeo o projeto que existe na lista e tem vídeo gravado. */ export function buildShowcaseItems( projects: PortfolioProjectView[], ): ShowcaseItem[] { const items: ShowcaseItem[] = []; for (const config of SHOWCASE) { const project = projects.find((candidate) => candidate.id === config.id); if (project) items.push({ config, project }); } return items; } /** Itens da vitrine para quem está dentro do provedor. */ export function useShowcaseItems() { return useContext(ApiContext)?.items ?? []; } /** Abre a janela ampliada de um projeto (nada acontece fora do provedor). */ export function useShowcaseOpen() { const api = useContext(ApiContext); return useCallback((id: string) => api?.open(id), [api]); } /** * Guarda os projetos da vitrine e qual deles está ampliado, e mostra a janela ampliada. A vitrine animada * (ProjectReel) e a lista do celular (ProjectList) leem a mesma lista de itens. */ export function ShowcaseProvider({ projects, children, }: { projects: PortfolioProjectView[]; children: ReactNode; }) { const items = useMemo(() => buildShowcaseItems(projects), [projects]); const [openId, setOpenId] = useState(null); const api = useMemo(() => ({ items, open: setOpenId }), [items]); const openIndex = openId ? items.findIndex((item) => item.config.id === openId) : -1; return ( {children} {openIndex >= 0 && ( setOpenId(null)} onNavigate={(index) => setOpenId(items[index]?.config.id ?? null)} /> )} ); }