|
|
@ -2,7 +2,7 @@ |
|
|
|
|
|
|
|
|
import { useState, useEffect, useCallback, useMemo, useRef } from "react"; |
|
|
import { useState, useEffect, useCallback, useMemo, useRef } from "react"; |
|
|
import { WorkflowFile } from "@/store/workflowStore"; |
|
|
import { WorkflowFile } from "@/store/workflowStore"; |
|
|
import { getAllPresets, PRESET_TEMPLATES } from "@/lib/quickstart/templates"; |
|
|
import { getAllPresets, PRESET_TEMPLATES, getTemplateContent } from "@/lib/quickstart/templates"; |
|
|
import { QuickstartBackButton } from "./QuickstartBackButton"; |
|
|
import { QuickstartBackButton } from "./QuickstartBackButton"; |
|
|
import { TemplateCard } from "./TemplateCard"; |
|
|
import { TemplateCard } from "./TemplateCard"; |
|
|
import { CommunityWorkflowMeta, TemplateCategory, TemplateMetadata } from "@/types/quickstart"; |
|
|
import { CommunityWorkflowMeta, TemplateCategory, TemplateMetadata } from "@/types/quickstart"; |
|
|
@ -69,6 +69,20 @@ export function TemplateExplorerView({ |
|
|
return metadata; |
|
|
return metadata; |
|
|
}, []); |
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
// Get preview images for each template (from the "full" content level)
|
|
|
|
|
|
const previewImages = useMemo(() => { |
|
|
|
|
|
const images: Record<string, string[]> = {}; |
|
|
|
|
|
PRESET_TEMPLATES.forEach((template) => { |
|
|
|
|
|
const content = getTemplateContent(template.id, "full"); |
|
|
|
|
|
if (content?.images) { |
|
|
|
|
|
images[template.id] = Object.values(content.images).map((img) => img.url); |
|
|
|
|
|
} else { |
|
|
|
|
|
images[template.id] = []; |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
return images; |
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
// Filter presets based on search, category, and tags
|
|
|
// Filter presets based on search, category, and tags
|
|
|
const filteredPresets = useMemo(() => { |
|
|
const filteredPresets = useMemo(() => { |
|
|
return presets.filter((preset) => { |
|
|
return presets.filter((preset) => { |
|
|
@ -261,7 +275,7 @@ export function TemplateExplorerView({ |
|
|
{/* Content - Sidebar + Main Grid */} |
|
|
{/* Content - Sidebar + Main Grid */} |
|
|
<div className="flex-1 flex overflow-hidden"> |
|
|
<div className="flex-1 flex overflow-hidden"> |
|
|
{/* Sidebar */} |
|
|
{/* Sidebar */} |
|
|
<div className="w-48 flex-shrink-0 border-r border-neutral-700 p-4 space-y-5 overflow-y-auto"> |
|
|
<div className="w-48 flex-shrink-0 bg-neutral-900/80 border-r border-neutral-700 p-4 space-y-5 overflow-y-auto"> |
|
|
{/* Search Input */} |
|
|
{/* Search Input */} |
|
|
<div className="relative"> |
|
|
<div className="relative"> |
|
|
<svg |
|
|
<svg |
|
|
@ -386,12 +400,13 @@ export function TemplateExplorerView({ |
|
|
<h3 className="text-xs font-medium text-neutral-400 uppercase tracking-wider"> |
|
|
<h3 className="text-xs font-medium text-neutral-400 uppercase tracking-wider"> |
|
|
Quick Start |
|
|
Quick Start |
|
|
</h3> |
|
|
</h3> |
|
|
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4"> |
|
|
<div className="grid grid-cols-2 gap-4"> |
|
|
{filteredPresets.map((preset) => ( |
|
|
{filteredPresets.map((preset) => ( |
|
|
<TemplateCard |
|
|
<TemplateCard |
|
|
key={preset.id} |
|
|
key={preset.id} |
|
|
template={preset} |
|
|
template={preset} |
|
|
nodeCount={presetMetadata[preset.id]?.nodeCount ?? 0} |
|
|
nodeCount={presetMetadata[preset.id]?.nodeCount ?? 0} |
|
|
|
|
|
previewImages={previewImages[preset.id]} |
|
|
isLoading={loadingWorkflowId === preset.id} |
|
|
isLoading={loadingWorkflowId === preset.id} |
|
|
onClick={() => handlePresetSelect(preset.id)} |
|
|
onClick={() => handlePresetSelect(preset.id)} |
|
|
disabled={isLoading} |
|
|
disabled={isLoading} |
|
|
@ -436,7 +451,7 @@ export function TemplateExplorerView({ |
|
|
</svg> |
|
|
</svg> |
|
|
</div> |
|
|
</div> |
|
|
) : ( |
|
|
) : ( |
|
|
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4"> |
|
|
<div className="grid grid-cols-2 gap-4"> |
|
|
{filteredCommunity.map((workflow) => ( |
|
|
{filteredCommunity.map((workflow) => ( |
|
|
<button |
|
|
<button |
|
|
key={workflow.id} |
|
|
key={workflow.id} |
|
|
@ -447,7 +462,7 @@ export function TemplateExplorerView({ |
|
|
${ |
|
|
${ |
|
|
loadingWorkflowId === workflow.id |
|
|
loadingWorkflowId === workflow.id |
|
|
? "bg-purple-600/20 border-purple-500/50" |
|
|
? "bg-purple-600/20 border-purple-500/50" |
|
|
: "bg-neutral-800/50 border-neutral-700 hover:border-neutral-600 hover:bg-neutral-800/70" |
|
|
: "bg-neutral-900/50 border-neutral-700 hover:border-neutral-500 hover:bg-neutral-900/70" |
|
|
} |
|
|
} |
|
|
${isLoading && loadingWorkflowId !== workflow.id ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} |
|
|
${isLoading && loadingWorkflowId !== workflow.id ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} |
|
|
`}
|
|
|
`}
|
|
|
|