From f25826b3b4a86c64745004bf71bccc8a9a54c7f6 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Fri, 16 Jan 2026 21:28:49 +1300 Subject: [PATCH] feat(25-02): improve template explorer layout and visuals - Change to 2-column grid layout for better visual balance - Add animated thumbnail cycling through preview images (2.5s interval, fade transition) - Add indicator dots for multi-image templates - Add darker sidebar background (bg-neutral-900/80) for visual separation - Update card backgrounds to neutral-900/50 for better contrast - Pass preview images from template content to TemplateCard --- src/components/quickstart/TemplateCard.tsx | 117 +++++++++++++----- .../quickstart/TemplateExplorerView.tsx | 25 +++- 2 files changed, 105 insertions(+), 37 deletions(-) diff --git a/src/components/quickstart/TemplateCard.tsx b/src/components/quickstart/TemplateCard.tsx index a26ee2d8..1b848dc3 100644 --- a/src/components/quickstart/TemplateCard.tsx +++ b/src/components/quickstart/TemplateCard.tsx @@ -1,5 +1,6 @@ "use client"; +import { useState, useEffect } from "react"; import { TemplateCategory } from "@/types/quickstart"; interface TemplateCardProps { @@ -12,6 +13,7 @@ interface TemplateCardProps { tags: string[]; }; nodeCount: number; + previewImages?: string[]; isLoading: boolean; onClick: () => void; disabled: boolean; @@ -34,10 +36,31 @@ const CATEGORY_COLORS: Record = { export function TemplateCard({ template, nodeCount, + previewImages = [], isLoading, onClick, disabled, }: TemplateCardProps) { + const [currentImageIndex, setCurrentImageIndex] = useState(0); + const [isTransitioning, setIsTransitioning] = useState(false); + + // Cycle through preview images + useEffect(() => { + if (previewImages.length <= 1) return; + + const interval = setInterval(() => { + setIsTransitioning(true); + setTimeout(() => { + setCurrentImageIndex((prev) => (prev + 1) % previewImages.length); + setIsTransitioning(false); + }, 300); // Fade out duration + }, 2500); // Time between transitions + + return () => clearInterval(interval); + }, [previewImages.length]); + + const hasImages = previewImages.length > 0; + return (