@contractspec/bundle.marketing 3.8.8 → 3.8.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +73 -29
- package/CHANGELOG.md +63 -0
- package/dist/browser/components/templates/TemplateCard.js +83 -0
- package/dist/browser/components/templates/TemplateCommandDialog.js +110 -0
- package/dist/browser/components/templates/TemplatePreviewContent.js +96 -0
- package/dist/browser/components/templates/TemplatesBrowseControls.js +130 -0
- package/dist/browser/components/templates/TemplatesCatalogSection.js +307 -0
- package/dist/browser/components/templates/TemplatesClientPage.js +1020 -917
- package/dist/browser/components/templates/TemplatesHeroSection.js +87 -0
- package/dist/browser/components/templates/TemplatesNextStepsSection.js +126 -0
- package/dist/browser/components/templates/TemplatesOverlays.js +2874 -0
- package/dist/browser/components/templates/TemplatesPreviewModal.js +136 -126
- package/dist/browser/components/templates/index.js +1055 -952
- package/dist/browser/components/templates/template-catalog.js +83 -0
- package/dist/browser/components/templates/template-filters.js +99 -0
- package/dist/browser/components/templates/template-new.js +23 -0
- package/dist/browser/components/templates/template-preview.js +43 -0
- package/dist/browser/components/templates/template-source.js +19 -0
- package/dist/browser/components/templates/template-tag-visibility.js +40 -0
- package/dist/browser/components/templates/useTemplateBrowseState.js +191 -0
- package/dist/browser/index.js +1055 -952
- package/dist/components/templates/TemplateCard.d.ts +12 -0
- package/dist/components/templates/TemplateCard.js +78 -0
- package/dist/components/templates/TemplateCommandDialog.d.ts +6 -0
- package/dist/components/templates/TemplateCommandDialog.js +105 -0
- package/dist/components/templates/TemplatePreviewContent.d.ts +5 -0
- package/dist/components/templates/TemplatePreviewContent.js +91 -0
- package/dist/components/templates/TemplatesBrowseControls.d.ts +18 -0
- package/dist/components/templates/TemplatesBrowseControls.js +125 -0
- package/dist/components/templates/TemplatesCatalogSection.d.ts +17 -0
- package/dist/components/templates/TemplatesCatalogSection.js +302 -0
- package/dist/components/templates/TemplatesClientPage.js +1020 -917
- package/dist/components/templates/TemplatesHeroSection.d.ts +5 -0
- package/dist/components/templates/TemplatesHeroSection.js +82 -0
- package/dist/components/templates/TemplatesNextStepsSection.d.ts +1 -0
- package/dist/components/templates/TemplatesNextStepsSection.js +121 -0
- package/dist/components/templates/TemplatesOverlays.d.ts +10 -0
- package/dist/components/templates/TemplatesOverlays.js +2869 -0
- package/dist/components/templates/TemplatesPreviewModal.d.ts +3 -4
- package/dist/components/templates/TemplatesPreviewModal.js +136 -126
- package/dist/components/templates/index.js +1055 -952
- package/dist/components/templates/template-catalog.d.ts +28 -0
- package/dist/components/templates/template-catalog.js +78 -0
- package/dist/components/templates/template-catalog.test.d.ts +1 -0
- package/dist/components/templates/template-filters.d.ts +12 -0
- package/dist/components/templates/template-filters.js +94 -0
- package/dist/components/templates/template-new.d.ts +2 -0
- package/dist/components/templates/template-new.js +18 -0
- package/dist/components/templates/template-preview.d.ts +18 -0
- package/dist/components/templates/template-preview.js +38 -0
- package/dist/components/templates/template-source.d.ts +3 -0
- package/dist/components/templates/template-source.js +14 -0
- package/dist/components/templates/template-tag-visibility.d.ts +10 -0
- package/dist/components/templates/template-tag-visibility.js +35 -0
- package/dist/components/templates/useTemplateBrowseState.d.ts +22 -0
- package/dist/components/templates/useTemplateBrowseState.js +186 -0
- package/dist/index.js +1055 -952
- package/dist/node/components/templates/TemplateCard.js +78 -0
- package/dist/node/components/templates/TemplateCommandDialog.js +105 -0
- package/dist/node/components/templates/TemplatePreviewContent.js +91 -0
- package/dist/node/components/templates/TemplatesBrowseControls.js +125 -0
- package/dist/node/components/templates/TemplatesCatalogSection.js +302 -0
- package/dist/node/components/templates/TemplatesClientPage.js +1020 -917
- package/dist/node/components/templates/TemplatesHeroSection.js +82 -0
- package/dist/node/components/templates/TemplatesNextStepsSection.js +121 -0
- package/dist/node/components/templates/TemplatesOverlays.js +2869 -0
- package/dist/node/components/templates/TemplatesPreviewModal.js +136 -126
- package/dist/node/components/templates/index.js +1055 -952
- package/dist/node/components/templates/template-catalog.js +78 -0
- package/dist/node/components/templates/template-filters.js +94 -0
- package/dist/node/components/templates/template-new.js +18 -0
- package/dist/node/components/templates/template-preview.js +38 -0
- package/dist/node/components/templates/template-source.js +14 -0
- package/dist/node/components/templates/template-tag-visibility.js +35 -0
- package/dist/node/components/templates/useTemplateBrowseState.js +186 -0
- package/dist/node/index.js +1055 -952
- package/package.json +237 -26
- package/src/components/templates/TemplateCard.tsx +74 -0
- package/src/components/templates/TemplateCommandDialog.tsx +92 -0
- package/src/components/templates/TemplatePreviewContent.tsx +182 -0
- package/src/components/templates/TemplatesBrowseControls.tsx +144 -0
- package/src/components/templates/TemplatesCatalogSection.tsx +191 -0
- package/src/components/templates/TemplatesClientPage.tsx +85 -773
- package/src/components/templates/TemplatesHeroSection.tsx +41 -0
- package/src/components/templates/TemplatesNextStepsSection.tsx +80 -0
- package/src/components/templates/TemplatesOverlays.tsx +65 -0
- package/src/components/templates/TemplatesPreviewModal.tsx +19 -294
- package/src/components/templates/template-catalog.test.ts +162 -0
- package/src/components/templates/template-catalog.ts +140 -0
- package/src/components/templates/template-filters.ts +57 -0
- package/src/components/templates/template-new.ts +12 -0
- package/src/components/templates/template-preview.ts +57 -0
- package/src/components/templates/template-source.ts +13 -0
- package/src/components/templates/template-tag-visibility.ts +58 -0
- package/src/components/templates/useTemplateBrowseState.ts +101 -0
- package/.turbo/turbo-prebuild.log +0 -1
package/dist/browser/index.js
CHANGED
|
@@ -2566,989 +2566,1092 @@ function PricingThinkingModal({
|
|
|
2566
2566
|
}, undefined, true, undefined, this)
|
|
2567
2567
|
}, undefined, false, undefined, this);
|
|
2568
2568
|
}
|
|
2569
|
-
// src/components/templates/
|
|
2570
|
-
import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
|
|
2571
|
-
import { Dialog as Dialog2, DialogContent as DialogContent2 } from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
2572
|
-
import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
|
|
2573
|
-
import dynamic from "next/dynamic";
|
|
2574
|
-
import { useMemo } from "react";
|
|
2569
|
+
// src/components/templates/TemplateCard.tsx
|
|
2575
2570
|
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
2576
2571
|
"use client";
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
var
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
case "agent-console":
|
|
2647
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2648
|
-
title: "AI Agent Console",
|
|
2649
|
-
description: "AI agent orchestration with tools, agents, runs, and execution logs.",
|
|
2650
|
-
showSaveAction: false,
|
|
2651
|
-
children: /* @__PURE__ */ jsxDEV11(AgentDashboard, {}, undefined, false, undefined, this)
|
|
2652
|
-
}, undefined, false, undefined, this);
|
|
2653
|
-
case "ai-chat-assistant":
|
|
2654
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2655
|
-
title: "AI Chat Assistant",
|
|
2656
|
-
description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
|
|
2657
|
-
showSaveAction: false,
|
|
2658
|
-
children: /* @__PURE__ */ jsxDEV11(AiChatAssistantDashboard, {}, undefined, false, undefined, this)
|
|
2659
|
-
}, undefined, false, undefined, this);
|
|
2660
|
-
case "workflow-system":
|
|
2661
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2662
|
-
title: "Workflow System",
|
|
2663
|
-
description: "Multi-step workflows with role-based approvals.",
|
|
2664
|
-
showSaveAction: false,
|
|
2665
|
-
children: /* @__PURE__ */ jsxDEV11(WorkflowDashboard, {}, undefined, false, undefined, this)
|
|
2666
|
-
}, undefined, false, undefined, this);
|
|
2667
|
-
case "marketplace":
|
|
2668
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2669
|
-
title: "Marketplace",
|
|
2670
|
-
description: "Two-sided marketplace with stores, products, and orders.",
|
|
2671
|
-
showSaveAction: false,
|
|
2672
|
-
children: /* @__PURE__ */ jsxDEV11(MarketplaceDashboard, {}, undefined, false, undefined, this)
|
|
2673
|
-
}, undefined, false, undefined, this);
|
|
2674
|
-
case "integration-hub":
|
|
2675
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2676
|
-
title: "Integration Hub",
|
|
2677
|
-
description: "Third-party integrations with sync and field mapping.",
|
|
2678
|
-
showSaveAction: false,
|
|
2679
|
-
children: /* @__PURE__ */ jsxDEV11(IntegrationDashboard, {}, undefined, false, undefined, this)
|
|
2680
|
-
}, undefined, false, undefined, this);
|
|
2681
|
-
case "analytics-dashboard":
|
|
2682
|
-
return /* @__PURE__ */ jsxDEV11(TemplateShell, {
|
|
2683
|
-
title: "Analytics Dashboard",
|
|
2684
|
-
description: "Custom dashboards with widgets and queries.",
|
|
2685
|
-
showSaveAction: false,
|
|
2686
|
-
children: /* @__PURE__ */ jsxDEV11(AnalyticsDashboard, {}, undefined, false, undefined, this)
|
|
2687
|
-
}, undefined, false, undefined, this);
|
|
2688
|
-
case null:
|
|
2689
|
-
return null;
|
|
2690
|
-
default:
|
|
2691
|
-
return null;
|
|
2692
|
-
}
|
|
2693
|
-
}, [templateId]);
|
|
2694
|
-
return /* @__PURE__ */ jsxDEV11(Dialog2, {
|
|
2695
|
-
open: !!previewComponent,
|
|
2696
|
-
onOpenChange: onClose,
|
|
2697
|
-
children: /* @__PURE__ */ jsxDEV11(DialogContent2, {
|
|
2698
|
-
className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
|
|
2699
|
-
children: /* @__PURE__ */ jsxDEV11(ScrollArea, {
|
|
2700
|
-
className: "flex flex-col justify-between overflow-hidden",
|
|
2701
|
-
children: previewComponent
|
|
2702
|
-
}, undefined, false, undefined, this)
|
|
2703
|
-
}, undefined, false, undefined, this)
|
|
2704
|
-
}, undefined, false, undefined, this);
|
|
2705
|
-
};
|
|
2572
|
+
function TemplateCard({
|
|
2573
|
+
title,
|
|
2574
|
+
description,
|
|
2575
|
+
metaBadges,
|
|
2576
|
+
tags,
|
|
2577
|
+
featureList = [],
|
|
2578
|
+
isNew = false,
|
|
2579
|
+
previewAction,
|
|
2580
|
+
useAction
|
|
2581
|
+
}) {
|
|
2582
|
+
return /* @__PURE__ */ jsxDEV11("div", {
|
|
2583
|
+
className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
|
|
2584
|
+
children: [
|
|
2585
|
+
isNew ? /* @__PURE__ */ jsxDEV11("span", {
|
|
2586
|
+
className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
|
|
2587
|
+
children: "New"
|
|
2588
|
+
}, undefined, false, undefined, this) : null,
|
|
2589
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
2590
|
+
children: [
|
|
2591
|
+
/* @__PURE__ */ jsxDEV11("h3", {
|
|
2592
|
+
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
2593
|
+
children: title
|
|
2594
|
+
}, undefined, false, undefined, this),
|
|
2595
|
+
/* @__PURE__ */ jsxDEV11("p", {
|
|
2596
|
+
className: "mt-1 text-muted-foreground text-sm",
|
|
2597
|
+
children: description
|
|
2598
|
+
}, undefined, false, undefined, this)
|
|
2599
|
+
]
|
|
2600
|
+
}, undefined, true, undefined, this),
|
|
2601
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
2602
|
+
className: "flex-1 space-y-3",
|
|
2603
|
+
children: [
|
|
2604
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
2605
|
+
className: "flex flex-wrap gap-2",
|
|
2606
|
+
children: metaBadges.map((badge) => /* @__PURE__ */ jsxDEV11("span", {
|
|
2607
|
+
className: "rounded-full border border-border bg-background px-3 py-1 text-[11px] text-foreground",
|
|
2608
|
+
children: badge
|
|
2609
|
+
}, badge, false, undefined, this))
|
|
2610
|
+
}, undefined, false, undefined, this),
|
|
2611
|
+
featureList.length > 0 ? /* @__PURE__ */ jsxDEV11("p", {
|
|
2612
|
+
className: "text-muted-foreground text-xs",
|
|
2613
|
+
children: [
|
|
2614
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
2615
|
+
className: "font-medium text-foreground",
|
|
2616
|
+
children: "Features:"
|
|
2617
|
+
}, undefined, false, undefined, this),
|
|
2618
|
+
" ",
|
|
2619
|
+
featureList.join(", ")
|
|
2620
|
+
]
|
|
2621
|
+
}, undefined, true, undefined, this) : null,
|
|
2622
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
2623
|
+
className: "flex flex-wrap gap-1",
|
|
2624
|
+
children: tags.map((tag) => /* @__PURE__ */ jsxDEV11("span", {
|
|
2625
|
+
className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
|
|
2626
|
+
children: tag
|
|
2627
|
+
}, tag, false, undefined, this))
|
|
2628
|
+
}, undefined, false, undefined, this)
|
|
2629
|
+
]
|
|
2630
|
+
}, undefined, true, undefined, this),
|
|
2631
|
+
/* @__PURE__ */ jsxDEV11("div", {
|
|
2632
|
+
className: "flex gap-2 pt-4",
|
|
2633
|
+
children: [
|
|
2634
|
+
previewAction,
|
|
2635
|
+
useAction
|
|
2636
|
+
]
|
|
2637
|
+
}, undefined, true, undefined, this)
|
|
2638
|
+
]
|
|
2639
|
+
}, undefined, true, undefined, this);
|
|
2640
|
+
}
|
|
2706
2641
|
|
|
2707
|
-
// src/components/templates/
|
|
2642
|
+
// src/components/templates/TemplateCommandDialog.tsx
|
|
2708
2643
|
import {
|
|
2709
2644
|
analyticsEventNames as analyticsEventNames2,
|
|
2710
2645
|
captureAnalyticsEvent as captureAnalyticsEvent2
|
|
2711
2646
|
} from "@contractspec/bundle.library/libs/posthog/client";
|
|
2712
|
-
import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
|
|
2713
|
-
import { cn } from "@contractspec/lib.ui-kit-core/utils";
|
|
2714
2647
|
import {
|
|
2715
|
-
Dialog as
|
|
2716
|
-
DialogContent as
|
|
2648
|
+
Dialog as Dialog2,
|
|
2649
|
+
DialogContent as DialogContent2,
|
|
2717
2650
|
DialogDescription as DialogDescription2,
|
|
2718
2651
|
DialogHeader as DialogHeader2,
|
|
2719
2652
|
DialogTitle as DialogTitle2
|
|
2720
2653
|
} from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
2721
|
-
import {
|
|
2722
|
-
Tooltip,
|
|
2723
|
-
TooltipContent,
|
|
2724
|
-
TooltipProvider,
|
|
2725
|
-
TooltipTrigger
|
|
2726
|
-
} from "@contractspec/lib.ui-kit-web/ui/tooltip";
|
|
2727
|
-
import { getTemplate } from "@contractspec/module.examples";
|
|
2728
|
-
import { Search } from "lucide-react";
|
|
2729
|
-
import Link8 from "next/link";
|
|
2730
|
-
import { useState as useState2 } from "react";
|
|
2731
2654
|
import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
|
|
2732
2655
|
"use client";
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2656
|
+
function TemplateCommandDialog({
|
|
2657
|
+
templateId,
|
|
2658
|
+
onClose,
|
|
2659
|
+
onDeployStudio
|
|
2660
|
+
}) {
|
|
2661
|
+
const command = templateId ? `npx contractspec init --template ${templateId}` : "";
|
|
2662
|
+
return /* @__PURE__ */ jsxDEV12(Dialog2, {
|
|
2663
|
+
open: !!templateId,
|
|
2664
|
+
onOpenChange: (open) => !open && onClose(),
|
|
2665
|
+
children: /* @__PURE__ */ jsxDEV12(DialogContent2, {
|
|
2666
|
+
className: "max-w-md",
|
|
2667
|
+
children: [
|
|
2668
|
+
/* @__PURE__ */ jsxDEV12(DialogHeader2, {
|
|
2669
|
+
children: [
|
|
2670
|
+
/* @__PURE__ */ jsxDEV12(DialogTitle2, {
|
|
2671
|
+
children: "Use this template"
|
|
2672
|
+
}, undefined, false, undefined, this),
|
|
2673
|
+
/* @__PURE__ */ jsxDEV12(DialogDescription2, {
|
|
2674
|
+
children: "Initialize a new project with this template using the CLI."
|
|
2675
|
+
}, undefined, false, undefined, this)
|
|
2676
|
+
]
|
|
2677
|
+
}, undefined, true, undefined, this),
|
|
2678
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2679
|
+
className: "space-y-4 pt-4",
|
|
2680
|
+
children: [
|
|
2681
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2682
|
+
className: "rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50",
|
|
2683
|
+
children: command
|
|
2684
|
+
}, undefined, false, undefined, this),
|
|
2685
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2686
|
+
className: "flex gap-2",
|
|
2687
|
+
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
2688
|
+
className: "btn-secondary w-full",
|
|
2689
|
+
onClick: () => {
|
|
2690
|
+
if (!templateId) {
|
|
2691
|
+
return;
|
|
2692
|
+
}
|
|
2693
|
+
navigator.clipboard.writeText(command);
|
|
2694
|
+
captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
|
|
2695
|
+
surface: "templates",
|
|
2696
|
+
templateId,
|
|
2697
|
+
filename: "templates-cli"
|
|
2698
|
+
});
|
|
2699
|
+
},
|
|
2700
|
+
children: "Copy Command"
|
|
2701
|
+
}, undefined, false, undefined, this)
|
|
2702
|
+
}, undefined, false, undefined, this),
|
|
2703
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2704
|
+
className: "relative",
|
|
2705
|
+
children: [
|
|
2706
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2707
|
+
className: "absolute inset-0 flex items-center",
|
|
2708
|
+
children: /* @__PURE__ */ jsxDEV12("span", {
|
|
2709
|
+
className: "w-full border-border border-t"
|
|
2710
|
+
}, undefined, false, undefined, this)
|
|
2711
|
+
}, undefined, false, undefined, this),
|
|
2712
|
+
/* @__PURE__ */ jsxDEV12("div", {
|
|
2713
|
+
className: "relative flex justify-center text-xs uppercase",
|
|
2714
|
+
children: /* @__PURE__ */ jsxDEV12("span", {
|
|
2715
|
+
className: "bg-background px-2 text-muted-foreground",
|
|
2716
|
+
children: "Or"
|
|
2717
|
+
}, undefined, false, undefined, this)
|
|
2718
|
+
}, undefined, false, undefined, this)
|
|
2719
|
+
]
|
|
2720
|
+
}, undefined, true, undefined, this),
|
|
2721
|
+
/* @__PURE__ */ jsxDEV12("button", {
|
|
2722
|
+
className: "btn-ghost w-full text-sm",
|
|
2723
|
+
onClick: () => {
|
|
2724
|
+
if (!templateId) {
|
|
2725
|
+
return;
|
|
2726
|
+
}
|
|
2727
|
+
captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
|
|
2728
|
+
surface: "templates",
|
|
2729
|
+
templateId
|
|
2730
|
+
});
|
|
2731
|
+
onDeployStudio();
|
|
2732
|
+
},
|
|
2733
|
+
children: "Deploy to Studio"
|
|
2734
|
+
}, undefined, false, undefined, this)
|
|
2735
|
+
]
|
|
2736
|
+
}, undefined, true, undefined, this)
|
|
2737
|
+
]
|
|
2738
|
+
}, undefined, true, undefined, this)
|
|
2739
|
+
}, undefined, false, undefined, this);
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
// src/components/templates/TemplatePreviewContent.tsx
|
|
2743
|
+
import {
|
|
2744
|
+
TemplateShell
|
|
2745
|
+
} from "@contractspec/lib.example-shared-ui";
|
|
2746
|
+
import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
|
|
2747
|
+
import dynamic from "next/dynamic";
|
|
2748
|
+
import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
|
|
2749
|
+
"use client";
|
|
2750
|
+
var SaasDashboard = dynamic(() => import("@contractspec/example.saas-boilerplate").then((module) => module.SaasDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2751
|
+
var CrmDashboard = dynamic(() => import("@contractspec/example.crm-pipeline").then((module) => module.CrmDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2752
|
+
var DataGridShowcase = dynamic(() => import("@contractspec/example.data-grid-showcase/ui").then((module) => module.DataGridShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2753
|
+
var VisualizationShowcase = dynamic(() => import("@contractspec/example.visualization-showcase/ui").then((module) => module.VisualizationShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2754
|
+
var AgentDashboard = dynamic(() => import("@contractspec/example.agent-console/ui").then((module) => module.AgentDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2755
|
+
var AiChatAssistantDashboard = dynamic(() => import("@contractspec/example.ai-chat-assistant").then((module) => module.AiChatAssistantDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2756
|
+
var WorkflowDashboard = dynamic(() => import("@contractspec/example.workflow-system/ui").then((module) => module.WorkflowDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2757
|
+
var MarketplaceDashboard = dynamic(() => import("@contractspec/example.marketplace/ui").then((module) => module.MarketplaceDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2758
|
+
var IntegrationDashboard = dynamic(() => import("@contractspec/example.integration-hub/ui").then((module) => module.IntegrationDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2759
|
+
var AnalyticsDashboard = dynamic(() => import("@contractspec/example.analytics-dashboard").then((module) => module.AnalyticsDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
|
|
2760
|
+
var PREVIEW_DEFINITIONS = {
|
|
2761
|
+
"saas-boilerplate": {
|
|
2748
2762
|
title: "SaaS Boilerplate",
|
|
2749
|
-
description: "
|
|
2750
|
-
|
|
2751
|
-
capabilities: "Multi-tenancy, RBAC, Projects, Billing",
|
|
2752
|
-
isNew: true,
|
|
2753
|
-
previewUrl: "/sandbox?template=saas-boilerplate",
|
|
2754
|
-
docsUrl: "/docs/templates/saas-boilerplate"
|
|
2763
|
+
description: "Multi-tenant organizations, projects, settings, and billing usage tracking.",
|
|
2764
|
+
component: SaasDashboard
|
|
2755
2765
|
},
|
|
2756
|
-
{
|
|
2757
|
-
id: "crm-pipeline",
|
|
2758
|
-
templateId: "crm-pipeline",
|
|
2766
|
+
"crm-pipeline": {
|
|
2759
2767
|
title: "CRM Pipeline",
|
|
2760
|
-
description: "Sales CRM with contacts, companies, deals, pipeline stages
|
|
2761
|
-
|
|
2762
|
-
capabilities: "Contacts, Deals, Pipelines, Tasks",
|
|
2763
|
-
isNew: true,
|
|
2764
|
-
previewUrl: "/sandbox?template=crm-pipeline",
|
|
2765
|
-
docsUrl: "/docs/templates/crm-pipeline"
|
|
2768
|
+
description: "Sales CRM with contacts, companies, deals, and pipeline stages.",
|
|
2769
|
+
component: CrmDashboard
|
|
2766
2770
|
},
|
|
2767
|
-
{
|
|
2768
|
-
id: "data-grid-showcase",
|
|
2769
|
-
templateId: "data-grid-showcase",
|
|
2771
|
+
"data-grid-showcase": {
|
|
2770
2772
|
title: "Data Grid Showcase",
|
|
2771
|
-
description: "
|
|
2772
|
-
|
|
2773
|
-
capabilities: "Tables, Sorting, Pagination, Column Controls",
|
|
2774
|
-
isNew: true,
|
|
2775
|
-
previewUrl: "/sandbox?template=data-grid-showcase",
|
|
2776
|
-
docsUrl: "/docs/examples/data-grid-showcase"
|
|
2773
|
+
description: "Shared ContractSpec table primitives with client, server, and DataView-driven lanes.",
|
|
2774
|
+
component: DataGridShowcase
|
|
2777
2775
|
},
|
|
2778
|
-
{
|
|
2779
|
-
id: "visualization-showcase",
|
|
2780
|
-
templateId: "visualization-showcase",
|
|
2776
|
+
"visualization-showcase": {
|
|
2781
2777
|
title: "Visualization Showcase",
|
|
2782
|
-
description: "
|
|
2783
|
-
|
|
2784
|
-
capabilities: "Metrics, Charts, Timelines, Comparisons",
|
|
2785
|
-
isNew: true,
|
|
2786
|
-
previewUrl: "/sandbox?template=visualization-showcase",
|
|
2787
|
-
docsUrl: "/docs/examples/visualization-showcase"
|
|
2778
|
+
description: "ContractSpec-owned chart primitives rendered through shared visualization contracts and design-system wrappers.",
|
|
2779
|
+
component: VisualizationShowcase
|
|
2788
2780
|
},
|
|
2789
|
-
{
|
|
2790
|
-
id: "agent-console",
|
|
2791
|
-
templateId: "agent-console",
|
|
2781
|
+
"agent-console": {
|
|
2792
2782
|
title: "AI Agent Console",
|
|
2793
|
-
description: "AI agent orchestration
|
|
2794
|
-
|
|
2795
|
-
capabilities: "Tools, Agents, Runs, Metrics",
|
|
2796
|
-
isNew: true,
|
|
2797
|
-
previewUrl: "/sandbox?template=agent-console",
|
|
2798
|
-
docsUrl: "/docs/examples/agent-console"
|
|
2783
|
+
description: "AI agent orchestration with tools, agents, runs, and execution logs.",
|
|
2784
|
+
component: AgentDashboard
|
|
2799
2785
|
},
|
|
2800
|
-
{
|
|
2801
|
-
id: "ai-chat-assistant",
|
|
2802
|
-
templateId: "ai-chat-assistant",
|
|
2786
|
+
"ai-chat-assistant": {
|
|
2803
2787
|
title: "AI Chat Assistant",
|
|
2804
|
-
description: "Focused assistant
|
|
2805
|
-
|
|
2806
|
-
capabilities: "Chat UX, Sources, Suggestions, MCP",
|
|
2807
|
-
isNew: true,
|
|
2808
|
-
previewUrl: "/sandbox?template=ai-chat-assistant",
|
|
2809
|
-
docsUrl: "/docs/examples/ai-chat-assistant"
|
|
2788
|
+
description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
|
|
2789
|
+
component: AiChatAssistantDashboard
|
|
2810
2790
|
},
|
|
2811
|
-
{
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
description: "Multi-step workflows with role-based approvals and state transitions.",
|
|
2816
|
-
tags: ["Business", "Ops"],
|
|
2817
|
-
capabilities: "Workflows, Approvals, State Machine",
|
|
2818
|
-
isNew: true,
|
|
2819
|
-
previewUrl: "/sandbox?template=workflow-system",
|
|
2820
|
-
docsUrl: "/docs/examples/workflow-system"
|
|
2791
|
+
"workflow-system": {
|
|
2792
|
+
title: "Workflow System",
|
|
2793
|
+
description: "Multi-step workflows with role-based approvals.",
|
|
2794
|
+
component: WorkflowDashboard
|
|
2821
2795
|
},
|
|
2822
|
-
{
|
|
2823
|
-
id: "marketplace",
|
|
2824
|
-
templateId: "marketplace",
|
|
2796
|
+
marketplace: {
|
|
2825
2797
|
title: "Marketplace",
|
|
2826
2798
|
description: "Two-sided marketplace with stores, products, orders, and payouts.",
|
|
2827
|
-
|
|
2828
|
-
capabilities: "Stores, Products, Orders, Payouts",
|
|
2829
|
-
isNew: true,
|
|
2830
|
-
previewUrl: "/sandbox?template=marketplace",
|
|
2831
|
-
docsUrl: "/docs/templates/marketplace"
|
|
2799
|
+
component: MarketplaceDashboard
|
|
2832
2800
|
},
|
|
2833
|
-
{
|
|
2834
|
-
id: "integration-hub",
|
|
2835
|
-
templateId: "integration-hub",
|
|
2801
|
+
"integration-hub": {
|
|
2836
2802
|
title: "Integration Hub",
|
|
2837
2803
|
description: "Third-party integrations with connections, sync configs, and field mapping.",
|
|
2838
|
-
|
|
2839
|
-
capabilities: "Integrations, Connections, Sync",
|
|
2840
|
-
isNew: true,
|
|
2841
|
-
previewUrl: "/sandbox?template=integration-hub",
|
|
2842
|
-
docsUrl: "/docs/templates/integration-hub"
|
|
2804
|
+
component: IntegrationDashboard
|
|
2843
2805
|
},
|
|
2844
|
-
{
|
|
2845
|
-
id: "learning-journey-studio-onboarding",
|
|
2846
|
-
templateId: "learning-journey-studio-onboarding",
|
|
2847
|
-
title: "Learning Journey — Studio Getting Started",
|
|
2848
|
-
description: "First 30 minutes in Studio: choose template, edit spec, regenerate, playground, evolution.",
|
|
2849
|
-
tags: ["Learning", "Onboarding"],
|
|
2850
|
-
capabilities: "Spec-first onboarding, XP/streak, progress widget",
|
|
2851
|
-
isNew: true,
|
|
2852
|
-
previewUrl: "/sandbox?template=learning-journey-studio-onboarding",
|
|
2853
|
-
docsUrl: "/docs/templates/learning-journey-studio-onboarding"
|
|
2854
|
-
},
|
|
2855
|
-
{
|
|
2856
|
-
id: "learning-journey-platform-tour",
|
|
2857
|
-
templateId: "learning-journey-platform-tour",
|
|
2858
|
-
title: "Learning Journey — Platform Primitives Tour",
|
|
2859
|
-
description: "Touch identity, audit, notifications, jobs, flags, files, metering once with guided steps.",
|
|
2860
|
-
tags: ["Learning", "Platform"],
|
|
2861
|
-
capabilities: "Cross-module tour with event-driven completion",
|
|
2862
|
-
isNew: true,
|
|
2863
|
-
previewUrl: "/sandbox?template=learning-journey-platform-tour",
|
|
2864
|
-
docsUrl: "/docs/templates/learning-journey-platform-tour"
|
|
2865
|
-
},
|
|
2866
|
-
{
|
|
2867
|
-
id: "learning-journey-crm-onboarding",
|
|
2868
|
-
templateId: "learning-journey-crm-onboarding",
|
|
2869
|
-
title: "Learning Journey — CRM First Win",
|
|
2870
|
-
description: "Get to first closed-won deal: pipeline, contact/company, deal, stages, follow-up.",
|
|
2871
|
-
tags: ["Learning", "CRM"],
|
|
2872
|
-
capabilities: "CRM onboarding with XP/streak/badge",
|
|
2873
|
-
isNew: true,
|
|
2874
|
-
previewUrl: "/sandbox?template=learning-journey-crm-onboarding",
|
|
2875
|
-
docsUrl: "/docs/templates/learning-journey-crm-onboarding"
|
|
2876
|
-
},
|
|
2877
|
-
{
|
|
2878
|
-
id: "analytics-dashboard",
|
|
2879
|
-
templateId: "analytics-dashboard",
|
|
2806
|
+
"analytics-dashboard": {
|
|
2880
2807
|
title: "Analytics Dashboard",
|
|
2881
|
-
description: "Custom dashboards with widgets
|
|
2882
|
-
|
|
2883
|
-
capabilities: "Dashboards, Widgets, Queries",
|
|
2884
|
-
isNew: true,
|
|
2885
|
-
previewUrl: "/sandbox?template=analytics-dashboard",
|
|
2886
|
-
docsUrl: "/docs/templates/analytics-dashboard"
|
|
2887
|
-
},
|
|
2888
|
-
{
|
|
2889
|
-
id: "plumber-ops",
|
|
2890
|
-
templateId: "messaging-app",
|
|
2891
|
-
title: "Plumber Ops",
|
|
2892
|
-
description: "Complete workflow: Quotes → Deposit → Job → Invoice → Payment. Policy-enforced approvals.",
|
|
2893
|
-
tags: ["Trades", "Payments"],
|
|
2894
|
-
capabilities: "Quotes, Jobs, Invoicing, Payments",
|
|
2895
|
-
previewUrl: "/sandbox?template=plumber-ops",
|
|
2896
|
-
docsUrl: "/docs/specs/workflows"
|
|
2897
|
-
},
|
|
2898
|
-
{
|
|
2899
|
-
id: "coliving-management",
|
|
2900
|
-
templateId: "recipe-app-i18n",
|
|
2901
|
-
title: "Coliving Management",
|
|
2902
|
-
description: "Coliving management: Onboarding, chores, shared wallet. Multi-party approvals built-in.",
|
|
2903
|
-
tags: ["Coliving", "Finance"],
|
|
2904
|
-
capabilities: "Tasks, Approvals, Payments",
|
|
2905
|
-
previewUrl: "/sandbox?template=coliving-management",
|
|
2906
|
-
docsUrl: "/docs/specs/workflows"
|
|
2907
|
-
},
|
|
2908
|
-
{
|
|
2909
|
-
id: "chores-allowance",
|
|
2910
|
-
templateId: "todos-app",
|
|
2911
|
-
title: "Chores & Allowance",
|
|
2912
|
-
description: "Family task management with approval workflows. Teach financial accountability safely.",
|
|
2913
|
-
tags: ["Family", "Ops"],
|
|
2914
|
-
capabilities: "Tasks, Approvals, Notifications",
|
|
2915
|
-
previewUrl: "/sandbox?template=chores-allowance",
|
|
2916
|
-
docsUrl: "/docs/specs/workflows"
|
|
2917
|
-
},
|
|
2918
|
-
{
|
|
2919
|
-
id: "service-dispatch",
|
|
2920
|
-
templateId: "messaging-app",
|
|
2921
|
-
title: "Service Dispatch",
|
|
2922
|
-
description: "Field service scheduling, routing, and invoicing. Real-time coordination with policy gates.",
|
|
2923
|
-
tags: ["Ops", "Trades"],
|
|
2924
|
-
capabilities: "Scheduling, Maps, Invoicing",
|
|
2925
|
-
previewUrl: "/sandbox?template=service-dispatch",
|
|
2926
|
-
docsUrl: "/docs/specs/workflows"
|
|
2927
|
-
},
|
|
2928
|
-
{
|
|
2929
|
-
id: "content-review",
|
|
2930
|
-
templateId: "todos-app",
|
|
2931
|
-
title: "Content Review",
|
|
2932
|
-
description: "Multi-stage approval workflow for content. Audit trail for every decision.",
|
|
2933
|
-
tags: ["Ops"],
|
|
2934
|
-
capabilities: "Workflows, Approvals, Comments",
|
|
2935
|
-
previewUrl: "/sandbox?template=content-review",
|
|
2936
|
-
docsUrl: "/docs/specs/workflows"
|
|
2808
|
+
description: "Custom dashboards with widgets and queries.",
|
|
2809
|
+
component: AnalyticsDashboard
|
|
2937
2810
|
}
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2811
|
+
};
|
|
2812
|
+
function TemplatePreviewContent({
|
|
2813
|
+
templateId
|
|
2814
|
+
}) {
|
|
2815
|
+
const preview = PREVIEW_DEFINITIONS[templateId];
|
|
2816
|
+
if (!preview) {
|
|
2817
|
+
return null;
|
|
2818
|
+
}
|
|
2819
|
+
const PreviewComponent = preview.component;
|
|
2820
|
+
return /* @__PURE__ */ jsxDEV13(TemplateShell, {
|
|
2821
|
+
title: preview.title,
|
|
2822
|
+
description: preview.description,
|
|
2823
|
+
showSaveAction: false,
|
|
2824
|
+
children: /* @__PURE__ */ jsxDEV13(PreviewComponent, {}, undefined, false, undefined, this)
|
|
2825
|
+
}, undefined, false, undefined, this);
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
// src/components/templates/TemplatesBrowseControls.tsx
|
|
2829
|
+
import { cn } from "@contractspec/lib.ui-kit-core/utils";
|
|
2830
|
+
import { Search } from "lucide-react";
|
|
2831
|
+
import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
|
|
2832
|
+
"use client";
|
|
2833
|
+
function TemplatesBrowseControls({
|
|
2834
|
+
registryConfigured,
|
|
2835
|
+
availableSources,
|
|
2836
|
+
source,
|
|
2837
|
+
onSourceChange,
|
|
2838
|
+
search,
|
|
2839
|
+
onSearchChange,
|
|
2840
|
+
selectedTag,
|
|
2841
|
+
onTagChange,
|
|
2842
|
+
showTagFilters,
|
|
2843
|
+
visibleTagFacets,
|
|
2844
|
+
hiddenTagFacets,
|
|
2845
|
+
showAllTags,
|
|
2846
|
+
onShowAllTagsChange
|
|
2847
|
+
}) {
|
|
2848
|
+
return /* @__PURE__ */ jsxDEV14("section", {
|
|
2849
|
+
className: "editorial-section",
|
|
2850
|
+
children: /* @__PURE__ */ jsxDEV14("div", {
|
|
2851
|
+
className: "editorial-shell space-y-6",
|
|
2852
|
+
children: [
|
|
2853
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2854
|
+
className: "flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between",
|
|
2855
|
+
children: [
|
|
2856
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2857
|
+
className: "max-w-3xl space-y-3",
|
|
2975
2858
|
children: [
|
|
2976
|
-
/* @__PURE__ */
|
|
2977
|
-
className: "
|
|
2978
|
-
children:
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
className: "editorial-subtitle",
|
|
2989
|
-
children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
|
|
2990
|
-
}, undefined, false, undefined, this)
|
|
2991
|
-
]
|
|
2992
|
-
}, undefined, true, undefined, this),
|
|
2993
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2994
|
-
className: "editorial-proof-strip",
|
|
2995
|
-
children: [
|
|
2996
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2997
|
-
className: "editorial-stat",
|
|
2998
|
-
children: [
|
|
2999
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3000
|
-
className: "editorial-stat-value",
|
|
3001
|
-
children: templates.length
|
|
3002
|
-
}, undefined, false, undefined, this),
|
|
3003
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3004
|
-
className: "editorial-label",
|
|
3005
|
-
children: "curated scenarios"
|
|
3006
|
-
}, undefined, false, undefined, this)
|
|
3007
|
-
]
|
|
3008
|
-
}, undefined, true, undefined, this),
|
|
3009
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3010
|
-
className: "editorial-stat",
|
|
3011
|
-
children: [
|
|
3012
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3013
|
-
className: "editorial-stat-value",
|
|
3014
|
-
children: "2"
|
|
3015
|
-
}, undefined, false, undefined, this),
|
|
3016
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3017
|
-
className: "editorial-label",
|
|
3018
|
-
children: "entry paths"
|
|
3019
|
-
}, undefined, false, undefined, this)
|
|
3020
|
-
]
|
|
3021
|
-
}, undefined, true, undefined, this),
|
|
3022
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3023
|
-
className: "editorial-stat",
|
|
3024
|
-
children: [
|
|
3025
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3026
|
-
className: "editorial-stat-value",
|
|
3027
|
-
children: "OSS"
|
|
3028
|
-
}, undefined, false, undefined, this),
|
|
3029
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3030
|
-
className: "editorial-label",
|
|
3031
|
-
children: "first, Studio second"
|
|
3032
|
-
}, undefined, false, undefined, this)
|
|
3033
|
-
]
|
|
3034
|
-
}, undefined, true, undefined, this)
|
|
3035
|
-
]
|
|
3036
|
-
}, undefined, true, undefined, this)
|
|
2859
|
+
/* @__PURE__ */ jsxDEV14("p", {
|
|
2860
|
+
className: "editorial-kicker",
|
|
2861
|
+
children: "Browse by source"
|
|
2862
|
+
}, undefined, false, undefined, this),
|
|
2863
|
+
/* @__PURE__ */ jsxDEV14("h2", {
|
|
2864
|
+
className: "font-serif text-4xl tracking-[-0.04em]",
|
|
2865
|
+
children: "Use local scenarios for core proof, then scan the community."
|
|
2866
|
+
}, undefined, false, undefined, this),
|
|
2867
|
+
/* @__PURE__ */ jsxDEV14("p", {
|
|
2868
|
+
className: "text-muted-foreground text-sm leading-7",
|
|
2869
|
+
children: registryConfigured ? "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next." : "Local templates show the official adoption path. Community browsing appears automatically when a registry URL is configured."
|
|
2870
|
+
}, undefined, false, undefined, this)
|
|
3037
2871
|
]
|
|
3038
|
-
}, undefined, true, undefined, this)
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
2872
|
+
}, undefined, true, undefined, this),
|
|
2873
|
+
registryConfigured ? /* @__PURE__ */ jsxDEV14("div", {
|
|
2874
|
+
className: "flex gap-2",
|
|
2875
|
+
children: availableSources.map((option) => /* @__PURE__ */ jsxDEV14("button", {
|
|
2876
|
+
onClick: () => onSourceChange(option),
|
|
2877
|
+
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
2878
|
+
"bg-primary text-primary-foreground": source === option,
|
|
2879
|
+
"border border-border bg-card hover:bg-card/80": source !== option
|
|
2880
|
+
}),
|
|
2881
|
+
"aria-pressed": source === option,
|
|
2882
|
+
children: option === "local" ? "Local" : "Community"
|
|
2883
|
+
}, option, false, undefined, this))
|
|
2884
|
+
}, undefined, false, undefined, this) : null
|
|
2885
|
+
]
|
|
2886
|
+
}, undefined, true, undefined, this),
|
|
2887
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2888
|
+
className: "editorial-panel space-y-5",
|
|
2889
|
+
children: [
|
|
2890
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2891
|
+
className: "relative",
|
|
3044
2892
|
children: [
|
|
3045
|
-
/* @__PURE__ */
|
|
3046
|
-
className: "
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
className: "font-serif text-4xl tracking-[-0.04em]",
|
|
3057
|
-
children: "Use local scenarios for core proof, then scan the community."
|
|
3058
|
-
}, undefined, false, undefined, this),
|
|
3059
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3060
|
-
className: "text-muted-foreground text-sm leading-7",
|
|
3061
|
-
children: "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next."
|
|
3062
|
-
}, undefined, false, undefined, this)
|
|
3063
|
-
]
|
|
3064
|
-
}, undefined, true, undefined, this),
|
|
3065
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3066
|
-
className: "flex gap-2",
|
|
3067
|
-
children: [
|
|
3068
|
-
/* @__PURE__ */ jsxDEV12("button", {
|
|
3069
|
-
onClick: () => setSource("local"),
|
|
3070
|
-
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
3071
|
-
"bg-primary text-primary-foreground": source === "local",
|
|
3072
|
-
"border border-border bg-card hover:bg-card/80": source !== "local"
|
|
3073
|
-
}),
|
|
3074
|
-
"aria-pressed": source === "local",
|
|
3075
|
-
children: "Local"
|
|
3076
|
-
}, undefined, false, undefined, this),
|
|
3077
|
-
/* @__PURE__ */ jsxDEV12("button", {
|
|
3078
|
-
onClick: () => setSource("registry"),
|
|
3079
|
-
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
3080
|
-
"bg-primary text-primary-foreground": source === "registry",
|
|
3081
|
-
"border border-border bg-card hover:bg-card/80": source !== "registry"
|
|
3082
|
-
}),
|
|
3083
|
-
"aria-pressed": source === "registry",
|
|
3084
|
-
children: "Community"
|
|
3085
|
-
}, undefined, false, undefined, this)
|
|
3086
|
-
]
|
|
3087
|
-
}, undefined, true, undefined, this)
|
|
3088
|
-
]
|
|
3089
|
-
}, undefined, true, undefined, this),
|
|
3090
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3091
|
-
className: "editorial-panel space-y-5",
|
|
3092
|
-
children: [
|
|
3093
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3094
|
-
className: "relative",
|
|
3095
|
-
children: [
|
|
3096
|
-
/* @__PURE__ */ jsxDEV12(Search, {
|
|
3097
|
-
className: "absolute top-3.5 left-4 text-muted-foreground",
|
|
3098
|
-
size: 18
|
|
3099
|
-
}, undefined, false, undefined, this),
|
|
3100
|
-
/* @__PURE__ */ jsxDEV12("input", {
|
|
3101
|
-
type: "text",
|
|
3102
|
-
placeholder: "Search scenarios, industries, or capabilities",
|
|
3103
|
-
value: search,
|
|
3104
|
-
onChange: (e) => setSearch(e.target.value),
|
|
3105
|
-
className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
3106
|
-
"aria-label": "Search templates"
|
|
3107
|
-
}, undefined, false, undefined, this)
|
|
3108
|
-
]
|
|
3109
|
-
}, undefined, true, undefined, this),
|
|
3110
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3111
|
-
className: "flex flex-wrap gap-2",
|
|
3112
|
-
children: [
|
|
3113
|
-
/* @__PURE__ */ jsxDEV12("button", {
|
|
3114
|
-
onClick: () => setSelectedTag(null),
|
|
3115
|
-
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
3116
|
-
"bg-primary text-primary-foreground": selectedTag === null,
|
|
3117
|
-
"border border-border bg-card hover:bg-card/80": selectedTag !== null
|
|
3118
|
-
}),
|
|
3119
|
-
"aria-pressed": selectedTag === null,
|
|
3120
|
-
children: "All"
|
|
3121
|
-
}, undefined, false, undefined, this),
|
|
3122
|
-
allTags.map((tag) => /* @__PURE__ */ jsxDEV12("button", {
|
|
3123
|
-
onClick: () => setSelectedTag(tag),
|
|
3124
|
-
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
3125
|
-
"bg-primary text-primary-foreground": selectedTag === tag,
|
|
3126
|
-
"border border-border bg-card hover:bg-card/80": selectedTag !== tag
|
|
3127
|
-
}),
|
|
3128
|
-
"aria-pressed": selectedTag === tag,
|
|
3129
|
-
children: tag
|
|
3130
|
-
}, tag, false, undefined, this))
|
|
3131
|
-
]
|
|
3132
|
-
}, undefined, true, undefined, this)
|
|
3133
|
-
]
|
|
3134
|
-
}, undefined, true, undefined, this)
|
|
3135
|
-
]
|
|
3136
|
-
}, undefined, true, undefined, this)
|
|
3137
|
-
}, undefined, false, undefined, this),
|
|
3138
|
-
/* @__PURE__ */ jsxDEV12("section", {
|
|
3139
|
-
className: "section-padding",
|
|
3140
|
-
children: /* @__PURE__ */ jsxDEV12("div", {
|
|
3141
|
-
className: "editorial-shell",
|
|
3142
|
-
children: source === "registry" ? registryLoading ? /* @__PURE__ */ jsxDEV12("div", {
|
|
3143
|
-
className: "py-12 text-center",
|
|
3144
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3145
|
-
className: "text-muted-foreground",
|
|
3146
|
-
children: "Loading community templates…"
|
|
3147
|
-
}, undefined, false, undefined, this)
|
|
3148
|
-
}, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
|
|
3149
|
-
className: "py-12 text-center",
|
|
3150
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3151
|
-
className: "text-muted-foreground",
|
|
3152
|
-
children: "No community templates found (configure `NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL`)."
|
|
3153
|
-
}, undefined, false, undefined, this)
|
|
3154
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("div", {
|
|
3155
|
-
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
3156
|
-
children: registryTemplates.map((t) => /* @__PURE__ */ jsxDEV12("div", {
|
|
3157
|
-
className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
|
|
3158
|
-
children: [
|
|
3159
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3160
|
-
children: [
|
|
3161
|
-
/* @__PURE__ */ jsxDEV12("h3", {
|
|
3162
|
-
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3163
|
-
children: t.name
|
|
3164
|
-
}, undefined, false, undefined, this),
|
|
3165
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3166
|
-
className: "mt-1 text-muted-foreground text-sm",
|
|
3167
|
-
children: t.description
|
|
3168
|
-
}, undefined, false, undefined, this)
|
|
3169
|
-
]
|
|
3170
|
-
}, undefined, true, undefined, this),
|
|
3171
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3172
|
-
className: "flex-1 space-y-2",
|
|
3173
|
-
children: /* @__PURE__ */ jsxDEV12("div", {
|
|
3174
|
-
className: "flex flex-wrap gap-1",
|
|
3175
|
-
children: t.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
|
|
3176
|
-
className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
|
|
3177
|
-
children: tag
|
|
3178
|
-
}, tag, false, undefined, this))
|
|
3179
|
-
}, undefined, false, undefined, this)
|
|
3180
|
-
}, undefined, false, undefined, this),
|
|
3181
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3182
|
-
className: "flex gap-2 pt-4",
|
|
3183
|
-
children: [
|
|
3184
|
-
/* @__PURE__ */ jsxDEV12(Tooltip, {
|
|
3185
|
-
children: [
|
|
3186
|
-
/* @__PURE__ */ jsxDEV12(TooltipTrigger, {
|
|
3187
|
-
asChild: true,
|
|
3188
|
-
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
3189
|
-
className: "btn-ghost flex-1 text-center text-xs",
|
|
3190
|
-
onClick: () => {
|
|
3191
|
-
const local = getTemplate(t.id);
|
|
3192
|
-
if (!local) {
|
|
3193
|
-
setSelectedTemplateForCommand(t);
|
|
3194
|
-
return;
|
|
3195
|
-
}
|
|
3196
|
-
setPreview(t.id);
|
|
3197
|
-
},
|
|
3198
|
-
children: "Preview"
|
|
3199
|
-
}, undefined, false, undefined, this)
|
|
3200
|
-
}, undefined, false, undefined, this),
|
|
3201
|
-
/* @__PURE__ */ jsxDEV12(TooltipContent, {
|
|
3202
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3203
|
-
children: "Preview this template (if available locally)"
|
|
3204
|
-
}, undefined, false, undefined, this)
|
|
3205
|
-
}, undefined, false, undefined, this)
|
|
3206
|
-
]
|
|
3207
|
-
}, undefined, true, undefined, this),
|
|
3208
|
-
/* @__PURE__ */ jsxDEV12(Tooltip, {
|
|
3209
|
-
children: [
|
|
3210
|
-
/* @__PURE__ */ jsxDEV12(TooltipTrigger, {
|
|
3211
|
-
asChild: true,
|
|
3212
|
-
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
3213
|
-
className: "btn-primary flex-1 text-center text-xs",
|
|
3214
|
-
onClick: () => {
|
|
3215
|
-
captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
|
|
3216
|
-
surface: "templates",
|
|
3217
|
-
templateId: t.id,
|
|
3218
|
-
source: "registry"
|
|
3219
|
-
});
|
|
3220
|
-
setSelectedTemplateForCommand(t);
|
|
3221
|
-
},
|
|
3222
|
-
children: "Use Template"
|
|
3223
|
-
}, undefined, false, undefined, this)
|
|
3224
|
-
}, undefined, false, undefined, this),
|
|
3225
|
-
/* @__PURE__ */ jsxDEV12(TooltipContent, {
|
|
3226
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3227
|
-
children: "Get CLI command"
|
|
3228
|
-
}, undefined, false, undefined, this)
|
|
3229
|
-
}, undefined, false, undefined, this)
|
|
3230
|
-
]
|
|
3231
|
-
}, undefined, true, undefined, this)
|
|
3232
|
-
]
|
|
3233
|
-
}, undefined, true, undefined, this)
|
|
3234
|
-
]
|
|
3235
|
-
}, t.id, true, undefined, this))
|
|
3236
|
-
}, undefined, false, undefined, this) : filtered.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
|
|
3237
|
-
className: "py-12 text-center",
|
|
3238
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3239
|
-
className: "text-muted-foreground",
|
|
3240
|
-
children: "No templates match your filters. Try a different search."
|
|
2893
|
+
/* @__PURE__ */ jsxDEV14(Search, {
|
|
2894
|
+
className: "absolute top-3.5 left-4 text-muted-foreground",
|
|
2895
|
+
size: 18
|
|
2896
|
+
}, undefined, false, undefined, this),
|
|
2897
|
+
/* @__PURE__ */ jsxDEV14("input", {
|
|
2898
|
+
type: "text",
|
|
2899
|
+
placeholder: "Search scenarios, industries, or tags",
|
|
2900
|
+
value: search,
|
|
2901
|
+
onChange: (event) => onSearchChange(event.target.value),
|
|
2902
|
+
className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
2903
|
+
"aria-label": "Search templates"
|
|
3241
2904
|
}, undefined, false, undefined, this)
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
children: [
|
|
3247
|
-
"isNew" in template && template.isNew && /* @__PURE__ */ jsxDEV12("span", {
|
|
3248
|
-
className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
|
|
3249
|
-
children: "New"
|
|
3250
|
-
}, undefined, false, undefined, this),
|
|
3251
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3252
|
-
children: [
|
|
3253
|
-
/* @__PURE__ */ jsxDEV12("h3", {
|
|
3254
|
-
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3255
|
-
children: template.title
|
|
3256
|
-
}, undefined, false, undefined, this),
|
|
3257
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3258
|
-
className: "mt-1 text-muted-foreground text-sm",
|
|
3259
|
-
children: template.description
|
|
3260
|
-
}, undefined, false, undefined, this)
|
|
3261
|
-
]
|
|
3262
|
-
}, undefined, true, undefined, this),
|
|
3263
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3264
|
-
className: "flex-1 space-y-2",
|
|
3265
|
-
children: [
|
|
3266
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3267
|
-
className: "text-muted-foreground text-xs",
|
|
3268
|
-
children: [
|
|
3269
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
3270
|
-
className: "font-medium text-foreground",
|
|
3271
|
-
children: "Capabilities:"
|
|
3272
|
-
}, undefined, false, undefined, this),
|
|
3273
|
-
" ",
|
|
3274
|
-
template.capabilities
|
|
3275
|
-
]
|
|
3276
|
-
}, undefined, true, undefined, this),
|
|
3277
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3278
|
-
className: "flex flex-wrap gap-1",
|
|
3279
|
-
children: template.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
|
|
3280
|
-
className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
|
|
3281
|
-
children: tag
|
|
3282
|
-
}, tag, false, undefined, this))
|
|
3283
|
-
}, undefined, false, undefined, this)
|
|
3284
|
-
]
|
|
3285
|
-
}, undefined, true, undefined, this),
|
|
3286
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3287
|
-
className: "flex gap-2 pt-4",
|
|
3288
|
-
children: [
|
|
3289
|
-
/* @__PURE__ */ jsxDEV12(Tooltip, {
|
|
3290
|
-
children: [
|
|
3291
|
-
/* @__PURE__ */ jsxDEV12(TooltipTrigger, {
|
|
3292
|
-
asChild: true,
|
|
3293
|
-
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
3294
|
-
className: "btn-ghost flex-1 text-center text-xs",
|
|
3295
|
-
onClick: () => setPreview(template.templateId),
|
|
3296
|
-
children: "Preview"
|
|
3297
|
-
}, undefined, false, undefined, this)
|
|
3298
|
-
}, undefined, false, undefined, this),
|
|
3299
|
-
/* @__PURE__ */ jsxDEV12(TooltipContent, {
|
|
3300
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3301
|
-
children: "Preview this template in a modal"
|
|
3302
|
-
}, undefined, false, undefined, this)
|
|
3303
|
-
}, undefined, false, undefined, this)
|
|
3304
|
-
]
|
|
3305
|
-
}, undefined, true, undefined, this),
|
|
3306
|
-
/* @__PURE__ */ jsxDEV12(Tooltip, {
|
|
3307
|
-
children: [
|
|
3308
|
-
/* @__PURE__ */ jsxDEV12(TooltipTrigger, {
|
|
3309
|
-
asChild: true,
|
|
3310
|
-
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
3311
|
-
className: "btn-primary flex-1 text-center text-xs",
|
|
3312
|
-
onClick: () => {
|
|
3313
|
-
captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
|
|
3314
|
-
surface: "templates",
|
|
3315
|
-
templateId: template.templateId,
|
|
3316
|
-
source: "local"
|
|
3317
|
-
});
|
|
3318
|
-
setSelectedTemplateForCommand(template);
|
|
3319
|
-
},
|
|
3320
|
-
children: "Use Template"
|
|
3321
|
-
}, undefined, false, undefined, this)
|
|
3322
|
-
}, undefined, false, undefined, this),
|
|
3323
|
-
/* @__PURE__ */ jsxDEV12(TooltipContent, {
|
|
3324
|
-
children: /* @__PURE__ */ jsxDEV12("p", {
|
|
3325
|
-
children: "Get CLI command"
|
|
3326
|
-
}, undefined, false, undefined, this)
|
|
3327
|
-
}, undefined, false, undefined, this)
|
|
3328
|
-
]
|
|
3329
|
-
}, undefined, true, undefined, this)
|
|
3330
|
-
]
|
|
3331
|
-
}, undefined, true, undefined, this)
|
|
3332
|
-
]
|
|
3333
|
-
}, i, true, undefined, this))
|
|
3334
|
-
}, undefined, false, undefined, this)
|
|
3335
|
-
}, undefined, false, undefined, this)
|
|
3336
|
-
}, undefined, false, undefined, this),
|
|
3337
|
-
/* @__PURE__ */ jsxDEV12("section", {
|
|
3338
|
-
className: "editorial-section bg-striped",
|
|
3339
|
-
children: /* @__PURE__ */ jsxDEV12("div", {
|
|
3340
|
-
className: "editorial-shell space-y-8",
|
|
2905
|
+
]
|
|
2906
|
+
}, undefined, true, undefined, this),
|
|
2907
|
+
showTagFilters ? /* @__PURE__ */ jsxDEV14("div", {
|
|
2908
|
+
className: "space-y-3",
|
|
3341
2909
|
children: [
|
|
3342
|
-
/* @__PURE__ */
|
|
3343
|
-
className: "
|
|
2910
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2911
|
+
className: "flex flex-wrap gap-2",
|
|
3344
2912
|
children: [
|
|
3345
|
-
/* @__PURE__ */
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
2913
|
+
/* @__PURE__ */ jsxDEV14("button", {
|
|
2914
|
+
onClick: () => onTagChange(null),
|
|
2915
|
+
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
2916
|
+
"bg-primary text-primary-foreground": selectedTag === null,
|
|
2917
|
+
"border border-border bg-card hover:bg-card/80": selectedTag !== null
|
|
2918
|
+
}),
|
|
2919
|
+
"aria-pressed": selectedTag === null,
|
|
2920
|
+
children: "All"
|
|
3352
2921
|
}, undefined, false, undefined, this),
|
|
3353
|
-
/* @__PURE__ */
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
2922
|
+
visibleTagFacets.map((facet) => /* @__PURE__ */ jsxDEV14("button", {
|
|
2923
|
+
onClick: () => onTagChange(facet.tag),
|
|
2924
|
+
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
2925
|
+
"bg-primary text-primary-foreground": selectedTag === facet.tag,
|
|
2926
|
+
"border border-border bg-card hover:bg-card/80": selectedTag !== facet.tag
|
|
2927
|
+
}),
|
|
2928
|
+
"aria-pressed": selectedTag === facet.tag,
|
|
2929
|
+
children: facet.tag
|
|
2930
|
+
}, facet.tag, false, undefined, this))
|
|
3357
2931
|
]
|
|
3358
2932
|
}, undefined, true, undefined, this),
|
|
3359
|
-
/* @__PURE__ */
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3366
|
-
className: "text-3xl",
|
|
3367
|
-
children: "\uD83D\uDCB3"
|
|
3368
|
-
}, undefined, false, undefined, this),
|
|
3369
|
-
/* @__PURE__ */ jsxDEV12("h3", {
|
|
3370
|
-
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3371
|
-
children: "Add payments"
|
|
3372
|
-
}, undefined, false, undefined, this),
|
|
3373
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3374
|
-
className: "text-muted-foreground text-sm",
|
|
3375
|
-
children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
|
|
3376
|
-
}, undefined, false, undefined, this),
|
|
3377
|
-
/* @__PURE__ */ jsxDEV12(Link8, {
|
|
3378
|
-
href: "/docs/integrations/stripe",
|
|
3379
|
-
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3380
|
-
children: "Learn more →"
|
|
3381
|
-
}, undefined, false, undefined, this)
|
|
3382
|
-
]
|
|
3383
|
-
}, undefined, true, undefined, this),
|
|
3384
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3385
|
-
className: "editorial-panel space-y-4",
|
|
3386
|
-
children: [
|
|
3387
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3388
|
-
className: "text-3xl",
|
|
3389
|
-
children: "\uD83D\uDCE7"
|
|
3390
|
-
}, undefined, false, undefined, this),
|
|
3391
|
-
/* @__PURE__ */ jsxDEV12("h3", {
|
|
3392
|
-
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3393
|
-
children: "Add notifications"
|
|
3394
|
-
}, undefined, false, undefined, this),
|
|
3395
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3396
|
-
className: "text-muted-foreground text-sm",
|
|
3397
|
-
children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
|
|
3398
|
-
}, undefined, false, undefined, this),
|
|
3399
|
-
/* @__PURE__ */ jsxDEV12(Link8, {
|
|
3400
|
-
href: "/docs/integrations",
|
|
3401
|
-
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3402
|
-
children: "View integrations →"
|
|
3403
|
-
}, undefined, false, undefined, this)
|
|
3404
|
-
]
|
|
3405
|
-
}, undefined, true, undefined, this),
|
|
3406
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3407
|
-
className: "editorial-panel space-y-4",
|
|
3408
|
-
children: [
|
|
3409
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3410
|
-
className: "text-3xl",
|
|
3411
|
-
children: "\uD83E\uDDE0"
|
|
3412
|
-
}, undefined, false, undefined, this),
|
|
3413
|
-
/* @__PURE__ */ jsxDEV12("h3", {
|
|
3414
|
-
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3415
|
-
children: "Add AI and knowledge"
|
|
3416
|
-
}, undefined, false, undefined, this),
|
|
3417
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3418
|
-
className: "text-muted-foreground text-sm",
|
|
3419
|
-
children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
|
|
3420
|
-
}, undefined, false, undefined, this),
|
|
3421
|
-
/* @__PURE__ */ jsxDEV12(Link8, {
|
|
3422
|
-
href: "/docs/knowledge",
|
|
3423
|
-
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3424
|
-
children: "Learn about knowledge →"
|
|
3425
|
-
}, undefined, false, undefined, this)
|
|
3426
|
-
]
|
|
3427
|
-
}, undefined, true, undefined, this)
|
|
3428
|
-
]
|
|
3429
|
-
}, undefined, true, undefined, this),
|
|
3430
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3431
|
-
className: "pt-4 text-center",
|
|
3432
|
-
children: [
|
|
3433
|
-
/* @__PURE__ */ jsxDEV12("p", {
|
|
3434
|
-
className: "mb-4 text-muted-foreground text-sm",
|
|
3435
|
-
children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
|
|
3436
|
-
}, undefined, false, undefined, this),
|
|
3437
|
-
/* @__PURE__ */ jsxDEV12(Link8, {
|
|
3438
|
-
href: "/docs/architecture",
|
|
3439
|
-
className: "btn-primary",
|
|
3440
|
-
children: "View Architecture"
|
|
3441
|
-
}, undefined, false, undefined, this)
|
|
3442
|
-
]
|
|
3443
|
-
}, undefined, true, undefined, this)
|
|
2933
|
+
hiddenTagFacets.length > 0 || showAllTags ? /* @__PURE__ */ jsxDEV14("button", {
|
|
2934
|
+
type: "button",
|
|
2935
|
+
onClick: () => onShowAllTagsChange(!showAllTags),
|
|
2936
|
+
className: "text-muted-foreground text-sm transition-colors hover:text-foreground",
|
|
2937
|
+
children: showAllTags ? "Show fewer" : "More tags"
|
|
2938
|
+
}, undefined, false, undefined, this) : null
|
|
3444
2939
|
]
|
|
3445
|
-
}, undefined, true, undefined, this)
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
2940
|
+
}, undefined, true, undefined, this) : null
|
|
2941
|
+
]
|
|
2942
|
+
}, undefined, true, undefined, this)
|
|
2943
|
+
]
|
|
2944
|
+
}, undefined, true, undefined, this)
|
|
2945
|
+
}, undefined, false, undefined, this);
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
// src/components/templates/template-new.ts
|
|
2949
|
+
var NEW_TEMPLATE_IDS = [
|
|
2950
|
+
"minimal",
|
|
2951
|
+
"messaging-agent-actions",
|
|
2952
|
+
"policy-safe-knowledge-assistant",
|
|
2953
|
+
"visualization-showcase"
|
|
2954
|
+
];
|
|
2955
|
+
var NEW_TEMPLATE_ID_SET = new Set(NEW_TEMPLATE_IDS);
|
|
2956
|
+
function isNewTemplateId(templateId) {
|
|
2957
|
+
return NEW_TEMPLATE_ID_SET.has(templateId);
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
// src/components/templates/template-catalog.ts
|
|
2961
|
+
import { listExamples, listTemplates } from "@contractspec/module.examples";
|
|
2962
|
+
var NEW_TEMPLATE_INDEX = new Map(NEW_TEMPLATE_IDS.map((templateId, index) => [templateId, index]));
|
|
2963
|
+
function buildLocalTemplateCatalog(examples = listExamples(), templates = listTemplates()) {
|
|
2964
|
+
const templatesById = new Map(templates.map((template) => [template.id, template]));
|
|
2965
|
+
return examples.filter((example) => example.meta.visibility === "public" && example.surfaces.templates).map((example) => {
|
|
2966
|
+
const template = templatesById.get(example.meta.key);
|
|
2967
|
+
const tags = Array.from(new Set(example.meta.tags.map((tag) => tag.trim()).filter(Boolean))).sort((left, right) => left.localeCompare(right));
|
|
2968
|
+
return {
|
|
2969
|
+
id: example.meta.key,
|
|
2970
|
+
title: example.meta.title ?? template?.name ?? example.meta.key,
|
|
2971
|
+
description: example.meta.summary ?? example.meta.description,
|
|
2972
|
+
tags,
|
|
2973
|
+
kind: example.meta.kind,
|
|
2974
|
+
stability: example.meta.stability,
|
|
2975
|
+
previewUrl: template?.preview?.demoUrl ?? `/sandbox?template=${encodeURIComponent(example.meta.key)}`,
|
|
2976
|
+
featureList: [...template?.features ?? []],
|
|
2977
|
+
sandboxModes: example.surfaces.sandbox.modes,
|
|
2978
|
+
renderTargets: [...template?.renderTargets ?? []],
|
|
2979
|
+
isNew: isNewTemplateId(example.meta.key),
|
|
2980
|
+
packageName: example.entrypoints.packageName
|
|
2981
|
+
};
|
|
2982
|
+
}).sort(compareLocalTemplateCatalogItems);
|
|
2983
|
+
}
|
|
2984
|
+
function matchesTemplateFilters(template, search, selectedTag) {
|
|
2985
|
+
return matchesTemplateSearch(template, search) && (selectedTag === null || template.tags.includes(selectedTag));
|
|
2986
|
+
}
|
|
2987
|
+
function matchesTemplateSearch(template, search) {
|
|
2988
|
+
const haystack = [
|
|
2989
|
+
template.title,
|
|
2990
|
+
template.description,
|
|
2991
|
+
template.tags.join(" ")
|
|
2992
|
+
].join(" ").toLowerCase();
|
|
2993
|
+
const searchTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
2994
|
+
return searchTokens.length === 0 || searchTokens.every((token) => haystack.includes(token));
|
|
2995
|
+
}
|
|
2996
|
+
function formatExampleKindLabel(kind) {
|
|
2997
|
+
return kind.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
2998
|
+
}
|
|
2999
|
+
function formatStabilityLabel(stability) {
|
|
3000
|
+
return stability.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
3001
|
+
}
|
|
3002
|
+
function compareLocalTemplateCatalogItems(left, right) {
|
|
3003
|
+
const leftNewIndex = NEW_TEMPLATE_INDEX.get(left.id);
|
|
3004
|
+
const rightNewIndex = NEW_TEMPLATE_INDEX.get(right.id);
|
|
3005
|
+
if (leftNewIndex !== undefined || rightNewIndex !== undefined) {
|
|
3006
|
+
if (leftNewIndex === undefined) {
|
|
3007
|
+
return 1;
|
|
3008
|
+
}
|
|
3009
|
+
if (rightNewIndex === undefined) {
|
|
3010
|
+
return -1;
|
|
3011
|
+
}
|
|
3012
|
+
return leftNewIndex - rightNewIndex;
|
|
3013
|
+
}
|
|
3014
|
+
return left.title.localeCompare(right.title);
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
// src/components/templates/template-preview.ts
|
|
3018
|
+
var INLINE_TEMPLATE_PREVIEW_IDS = [
|
|
3019
|
+
"agent-console",
|
|
3020
|
+
"ai-chat-assistant",
|
|
3021
|
+
"analytics-dashboard",
|
|
3022
|
+
"crm-pipeline",
|
|
3023
|
+
"data-grid-showcase",
|
|
3024
|
+
"integration-hub",
|
|
3025
|
+
"marketplace",
|
|
3026
|
+
"saas-boilerplate",
|
|
3027
|
+
"visualization-showcase",
|
|
3028
|
+
"workflow-system"
|
|
3029
|
+
];
|
|
3030
|
+
var INLINE_TEMPLATE_PREVIEW_SET = new Set(INLINE_TEMPLATE_PREVIEW_IDS);
|
|
3031
|
+
function supportsInlineTemplatePreview(templateId) {
|
|
3032
|
+
return INLINE_TEMPLATE_PREVIEW_SET.has(templateId);
|
|
3033
|
+
}
|
|
3034
|
+
function getLocalTemplatePreviewAction(template) {
|
|
3035
|
+
if (supportsInlineTemplatePreview(template.id)) {
|
|
3036
|
+
return { kind: "modal", templateId: template.id };
|
|
3037
|
+
}
|
|
3038
|
+
return { kind: "sandbox", href: template.previewUrl };
|
|
3039
|
+
}
|
|
3040
|
+
function getRegistryTemplatePreviewAction(template, localTemplate) {
|
|
3041
|
+
if (!localTemplate) {
|
|
3042
|
+
return { kind: "disabled" };
|
|
3043
|
+
}
|
|
3044
|
+
return getLocalTemplatePreviewAction(localTemplate);
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
// src/components/templates/TemplatesCatalogSection.tsx
|
|
3048
|
+
import Link8 from "next/link";
|
|
3049
|
+
import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
|
|
3050
|
+
"use client";
|
|
3051
|
+
function TemplatesCatalogSection({
|
|
3052
|
+
source,
|
|
3053
|
+
registryConfigured,
|
|
3054
|
+
registryLoading,
|
|
3055
|
+
registryHasTemplates,
|
|
3056
|
+
localTemplates,
|
|
3057
|
+
registryTemplates,
|
|
3058
|
+
localTemplateById,
|
|
3059
|
+
onPreview,
|
|
3060
|
+
onUseTemplate,
|
|
3061
|
+
hasSearch,
|
|
3062
|
+
selectedTag
|
|
3063
|
+
}) {
|
|
3064
|
+
const showRegistry = source === "registry" && registryConfigured;
|
|
3065
|
+
const emptyStateMessage = getEmptyStateMessage(hasSearch, selectedTag);
|
|
3066
|
+
return /* @__PURE__ */ jsxDEV15("section", {
|
|
3067
|
+
className: "section-padding",
|
|
3068
|
+
children: /* @__PURE__ */ jsxDEV15("div", {
|
|
3069
|
+
className: "editorial-shell",
|
|
3070
|
+
children: showRegistry ? registryLoading ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3071
|
+
className: "py-12 text-center",
|
|
3072
|
+
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3073
|
+
className: "text-muted-foreground",
|
|
3074
|
+
children: "Loading community templates…"
|
|
3075
|
+
}, undefined, false, undefined, this)
|
|
3076
|
+
}, undefined, false, undefined, this) : !registryHasTemplates ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3077
|
+
className: "py-12 text-center",
|
|
3078
|
+
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3079
|
+
className: "text-muted-foreground",
|
|
3080
|
+
children: "No community templates found."
|
|
3081
|
+
}, undefined, false, undefined, this)
|
|
3082
|
+
}, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3083
|
+
className: "py-12 text-center",
|
|
3084
|
+
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3085
|
+
className: "text-muted-foreground",
|
|
3086
|
+
children: emptyStateMessage
|
|
3087
|
+
}, undefined, false, undefined, this)
|
|
3088
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3089
|
+
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
3090
|
+
children: registryTemplates.map((template) => {
|
|
3091
|
+
const localTemplate = localTemplateById.get(template.id);
|
|
3092
|
+
const previewAction = getRegistryTemplatePreviewAction(template, localTemplate);
|
|
3093
|
+
return /* @__PURE__ */ jsxDEV15(TemplateCard, {
|
|
3094
|
+
title: template.name,
|
|
3095
|
+
description: template.description,
|
|
3096
|
+
metaBadges: ["Community"],
|
|
3097
|
+
tags: template.tags,
|
|
3098
|
+
previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
|
|
3099
|
+
className: "btn-ghost flex-1 text-center text-xs",
|
|
3100
|
+
onClick: () => onPreview(template.id),
|
|
3101
|
+
children: "Preview"
|
|
3102
|
+
}, undefined, false, undefined, this) : previewAction.kind === "sandbox" ? /* @__PURE__ */ jsxDEV15(Link8, {
|
|
3103
|
+
href: previewAction.href,
|
|
3104
|
+
className: "btn-ghost flex-1 text-center text-xs",
|
|
3105
|
+
children: "Open Sandbox"
|
|
3106
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("button", {
|
|
3107
|
+
className: "btn-ghost flex-1 cursor-not-allowed text-center text-xs opacity-60",
|
|
3108
|
+
type: "button",
|
|
3109
|
+
disabled: true,
|
|
3110
|
+
children: "Preview Unavailable"
|
|
3111
|
+
}, undefined, false, undefined, this),
|
|
3112
|
+
useAction: /* @__PURE__ */ jsxDEV15("button", {
|
|
3113
|
+
className: "btn-primary flex-1 text-center text-xs",
|
|
3114
|
+
onClick: () => onUseTemplate(template.id, "registry"),
|
|
3115
|
+
children: "Use Template"
|
|
3116
|
+
}, undefined, false, undefined, this)
|
|
3117
|
+
}, template.id, false, undefined, this);
|
|
3118
|
+
})
|
|
3119
|
+
}, undefined, false, undefined, this) : localTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3120
|
+
className: "py-12 text-center",
|
|
3121
|
+
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3122
|
+
className: "text-muted-foreground",
|
|
3123
|
+
children: emptyStateMessage
|
|
3124
|
+
}, undefined, false, undefined, this)
|
|
3125
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3126
|
+
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
3127
|
+
children: localTemplates.map((template) => {
|
|
3128
|
+
const previewAction = getLocalTemplatePreviewAction(template);
|
|
3129
|
+
return /* @__PURE__ */ jsxDEV15(TemplateCard, {
|
|
3130
|
+
title: template.title,
|
|
3131
|
+
description: template.description,
|
|
3132
|
+
isNew: template.isNew,
|
|
3133
|
+
metaBadges: [
|
|
3134
|
+
formatExampleKindLabel(template.kind),
|
|
3135
|
+
formatStabilityLabel(template.stability)
|
|
3136
|
+
],
|
|
3137
|
+
tags: template.tags,
|
|
3138
|
+
featureList: template.featureList,
|
|
3139
|
+
previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
|
|
3140
|
+
className: "btn-ghost flex-1 text-center text-xs",
|
|
3141
|
+
onClick: () => onPreview(template.id),
|
|
3142
|
+
children: "Preview"
|
|
3143
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15(Link8, {
|
|
3144
|
+
href: previewAction.href,
|
|
3145
|
+
className: "btn-ghost flex-1 text-center text-xs",
|
|
3146
|
+
children: "Open Sandbox"
|
|
3147
|
+
}, undefined, false, undefined, this),
|
|
3148
|
+
useAction: /* @__PURE__ */ jsxDEV15("button", {
|
|
3149
|
+
className: "btn-primary flex-1 text-center text-xs",
|
|
3150
|
+
onClick: () => onUseTemplate(template.id, "local"),
|
|
3151
|
+
children: "Use Template"
|
|
3152
|
+
}, undefined, false, undefined, this)
|
|
3153
|
+
}, template.id, false, undefined, this);
|
|
3154
|
+
})
|
|
3155
|
+
}, undefined, false, undefined, this)
|
|
3156
|
+
}, undefined, false, undefined, this)
|
|
3157
|
+
}, undefined, false, undefined, this);
|
|
3158
|
+
}
|
|
3159
|
+
function getEmptyStateMessage(hasSearch, selectedTag) {
|
|
3160
|
+
if (selectedTag !== null && hasSearch) {
|
|
3161
|
+
return "No templates match this tag for the current search.";
|
|
3162
|
+
}
|
|
3163
|
+
if (selectedTag !== null) {
|
|
3164
|
+
return "No templates match this tag. Try another tag or reset filters.";
|
|
3165
|
+
}
|
|
3166
|
+
if (hasSearch) {
|
|
3167
|
+
return "No templates match your search. Try a different keyword.";
|
|
3168
|
+
}
|
|
3169
|
+
return "No templates match your filters. Try a different search.";
|
|
3170
|
+
}
|
|
3171
|
+
|
|
3172
|
+
// src/components/templates/TemplatesHeroSection.tsx
|
|
3173
|
+
import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
|
|
3174
|
+
function TemplatesHeroSection({
|
|
3175
|
+
localTemplateCount,
|
|
3176
|
+
sourceCount
|
|
3177
|
+
}) {
|
|
3178
|
+
return /* @__PURE__ */ jsxDEV16("section", {
|
|
3179
|
+
className: "section-padding hero-gradient border-border/70 border-b",
|
|
3180
|
+
children: /* @__PURE__ */ jsxDEV16("div", {
|
|
3181
|
+
className: "editorial-shell space-y-8",
|
|
3182
|
+
children: [
|
|
3183
|
+
/* @__PURE__ */ jsxDEV16("div", {
|
|
3184
|
+
className: "max-w-4xl space-y-5",
|
|
3460
3185
|
children: [
|
|
3461
|
-
/* @__PURE__ */
|
|
3186
|
+
/* @__PURE__ */ jsxDEV16("p", {
|
|
3187
|
+
className: "editorial-kicker",
|
|
3188
|
+
children: "Proof through real scenarios"
|
|
3189
|
+
}, undefined, false, undefined, this),
|
|
3190
|
+
/* @__PURE__ */ jsxDEV16("h1", {
|
|
3191
|
+
className: "editorial-title",
|
|
3192
|
+
children: "Templates that show the open system in practice."
|
|
3193
|
+
}, undefined, false, undefined, this),
|
|
3194
|
+
/* @__PURE__ */ jsxDEV16("p", {
|
|
3195
|
+
className: "editorial-subtitle",
|
|
3196
|
+
children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
|
|
3197
|
+
}, undefined, false, undefined, this)
|
|
3198
|
+
]
|
|
3199
|
+
}, undefined, true, undefined, this),
|
|
3200
|
+
/* @__PURE__ */ jsxDEV16("div", {
|
|
3201
|
+
className: "editorial-proof-strip",
|
|
3202
|
+
children: [
|
|
3203
|
+
/* @__PURE__ */ jsxDEV16("div", {
|
|
3204
|
+
className: "editorial-stat",
|
|
3462
3205
|
children: [
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
|
|
3206
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3207
|
+
className: "editorial-stat-value",
|
|
3208
|
+
children: localTemplateCount
|
|
3465
3209
|
}, undefined, false, undefined, this),
|
|
3466
|
-
/* @__PURE__ */
|
|
3467
|
-
|
|
3210
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3211
|
+
className: "editorial-label",
|
|
3212
|
+
children: "curated scenarios"
|
|
3468
3213
|
}, undefined, false, undefined, this)
|
|
3469
3214
|
]
|
|
3470
3215
|
}, undefined, true, undefined, this),
|
|
3471
|
-
/* @__PURE__ */
|
|
3472
|
-
|
|
3473
|
-
|
|
3216
|
+
/* @__PURE__ */ jsxDEV16("div", {
|
|
3217
|
+
className: "editorial-stat",
|
|
3218
|
+
children: [
|
|
3219
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3220
|
+
className: "editorial-stat-value",
|
|
3221
|
+
children: sourceCount
|
|
3222
|
+
}, undefined, false, undefined, this),
|
|
3223
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3224
|
+
className: "editorial-label",
|
|
3225
|
+
children: "entry paths"
|
|
3226
|
+
}, undefined, false, undefined, this)
|
|
3227
|
+
]
|
|
3228
|
+
}, undefined, true, undefined, this),
|
|
3229
|
+
/* @__PURE__ */ jsxDEV16("div", {
|
|
3230
|
+
className: "editorial-stat",
|
|
3231
|
+
children: [
|
|
3232
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3233
|
+
className: "editorial-stat-value",
|
|
3234
|
+
children: "OSS"
|
|
3235
|
+
}, undefined, false, undefined, this),
|
|
3236
|
+
/* @__PURE__ */ jsxDEV16("span", {
|
|
3237
|
+
className: "editorial-label",
|
|
3238
|
+
children: "first, Studio second"
|
|
3239
|
+
}, undefined, false, undefined, this)
|
|
3240
|
+
]
|
|
3241
|
+
}, undefined, true, undefined, this)
|
|
3474
3242
|
]
|
|
3475
3243
|
}, undefined, true, undefined, this)
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3244
|
+
]
|
|
3245
|
+
}, undefined, true, undefined, this)
|
|
3246
|
+
}, undefined, false, undefined, this);
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
// src/components/templates/TemplatesNextStepsSection.tsx
|
|
3250
|
+
import Link9 from "next/link";
|
|
3251
|
+
import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
|
|
3252
|
+
function TemplatesNextStepsSection() {
|
|
3253
|
+
return /* @__PURE__ */ jsxDEV17("section", {
|
|
3254
|
+
className: "editorial-section bg-striped",
|
|
3255
|
+
children: /* @__PURE__ */ jsxDEV17("div", {
|
|
3256
|
+
className: "editorial-shell space-y-8",
|
|
3257
|
+
children: [
|
|
3258
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3259
|
+
className: "max-w-3xl space-y-4",
|
|
3260
|
+
children: [
|
|
3261
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3262
|
+
className: "editorial-kicker",
|
|
3263
|
+
children: "From template to real system"
|
|
3264
|
+
}, undefined, false, undefined, this),
|
|
3265
|
+
/* @__PURE__ */ jsxDEV17("h2", {
|
|
3266
|
+
className: "font-serif text-4xl tracking-[-0.04em] md:text-5xl",
|
|
3267
|
+
children: "Templates become useful when the system can absorb more context."
|
|
3268
|
+
}, undefined, false, undefined, this),
|
|
3269
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3270
|
+
className: "editorial-copy",
|
|
3271
|
+
children: "Use templates to prove the base flow, then layer integrations, knowledge, and runtime behavior on top without losing the same contract source."
|
|
3272
|
+
}, undefined, false, undefined, this)
|
|
3273
|
+
]
|
|
3274
|
+
}, undefined, true, undefined, this),
|
|
3275
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3276
|
+
className: "grid gap-6 md:grid-cols-3",
|
|
3482
3277
|
children: [
|
|
3483
|
-
/* @__PURE__ */
|
|
3278
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3279
|
+
className: "editorial-panel space-y-4",
|
|
3484
3280
|
children: [
|
|
3485
|
-
/* @__PURE__ */
|
|
3486
|
-
|
|
3281
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3282
|
+
className: "text-3xl",
|
|
3283
|
+
children: "\uD83D\uDCB3"
|
|
3487
3284
|
}, undefined, false, undefined, this),
|
|
3488
|
-
/* @__PURE__ */
|
|
3489
|
-
|
|
3285
|
+
/* @__PURE__ */ jsxDEV17("h3", {
|
|
3286
|
+
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3287
|
+
children: "Add payments"
|
|
3288
|
+
}, undefined, false, undefined, this),
|
|
3289
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3290
|
+
className: "text-muted-foreground text-sm",
|
|
3291
|
+
children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
|
|
3292
|
+
}, undefined, false, undefined, this),
|
|
3293
|
+
/* @__PURE__ */ jsxDEV17(Link9, {
|
|
3294
|
+
href: "/docs/integrations/stripe",
|
|
3295
|
+
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3296
|
+
children: "Learn more →"
|
|
3490
3297
|
}, undefined, false, undefined, this)
|
|
3491
3298
|
]
|
|
3492
3299
|
}, undefined, true, undefined, this),
|
|
3493
|
-
/* @__PURE__ */
|
|
3494
|
-
className: "space-y-4
|
|
3300
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3301
|
+
className: "editorial-panel space-y-4",
|
|
3495
3302
|
children: [
|
|
3496
|
-
/* @__PURE__ */
|
|
3497
|
-
className: "
|
|
3498
|
-
children:
|
|
3499
|
-
"npx contractspec init --template ",
|
|
3500
|
-
commandId
|
|
3501
|
-
]
|
|
3502
|
-
}, undefined, true, undefined, this),
|
|
3503
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
3504
|
-
className: "flex gap-2",
|
|
3505
|
-
children: /* @__PURE__ */ jsxDEV12("button", {
|
|
3506
|
-
className: "btn-secondary w-full",
|
|
3507
|
-
onClick: () => {
|
|
3508
|
-
navigator.clipboard.writeText(`npx contractspec init --template ${commandId}`);
|
|
3509
|
-
captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
|
|
3510
|
-
surface: "templates",
|
|
3511
|
-
templateId: commandId,
|
|
3512
|
-
filename: "templates-cli"
|
|
3513
|
-
});
|
|
3514
|
-
},
|
|
3515
|
-
children: "Copy Command"
|
|
3516
|
-
}, undefined, false, undefined, this)
|
|
3303
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3304
|
+
className: "text-3xl",
|
|
3305
|
+
children: "\uD83D\uDCE7"
|
|
3517
3306
|
}, undefined, false, undefined, this),
|
|
3518
|
-
/* @__PURE__ */
|
|
3519
|
-
className: "
|
|
3520
|
-
children:
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
/* @__PURE__ */
|
|
3537
|
-
className: "
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
children: "
|
|
3307
|
+
/* @__PURE__ */ jsxDEV17("h3", {
|
|
3308
|
+
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3309
|
+
children: "Add notifications"
|
|
3310
|
+
}, undefined, false, undefined, this),
|
|
3311
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3312
|
+
className: "text-muted-foreground text-sm",
|
|
3313
|
+
children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
|
|
3314
|
+
}, undefined, false, undefined, this),
|
|
3315
|
+
/* @__PURE__ */ jsxDEV17(Link9, {
|
|
3316
|
+
href: "/docs/integrations",
|
|
3317
|
+
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3318
|
+
children: "View integrations →"
|
|
3319
|
+
}, undefined, false, undefined, this)
|
|
3320
|
+
]
|
|
3321
|
+
}, undefined, true, undefined, this),
|
|
3322
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3323
|
+
className: "editorial-panel space-y-4",
|
|
3324
|
+
children: [
|
|
3325
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3326
|
+
className: "text-3xl",
|
|
3327
|
+
children: "\uD83E\uDDE0"
|
|
3328
|
+
}, undefined, false, undefined, this),
|
|
3329
|
+
/* @__PURE__ */ jsxDEV17("h3", {
|
|
3330
|
+
className: "font-serif text-2xl tracking-[-0.03em]",
|
|
3331
|
+
children: "Add AI and knowledge"
|
|
3332
|
+
}, undefined, false, undefined, this),
|
|
3333
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3334
|
+
className: "text-muted-foreground text-sm",
|
|
3335
|
+
children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
|
|
3336
|
+
}, undefined, false, undefined, this),
|
|
3337
|
+
/* @__PURE__ */ jsxDEV17(Link9, {
|
|
3338
|
+
href: "/docs/knowledge",
|
|
3339
|
+
className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
|
|
3340
|
+
children: "Learn about knowledge →"
|
|
3547
3341
|
}, undefined, false, undefined, this)
|
|
3548
3342
|
]
|
|
3549
3343
|
}, undefined, true, undefined, this)
|
|
3550
3344
|
]
|
|
3345
|
+
}, undefined, true, undefined, this),
|
|
3346
|
+
/* @__PURE__ */ jsxDEV17("div", {
|
|
3347
|
+
className: "pt-4 text-center",
|
|
3348
|
+
children: [
|
|
3349
|
+
/* @__PURE__ */ jsxDEV17("p", {
|
|
3350
|
+
className: "mb-4 text-muted-foreground text-sm",
|
|
3351
|
+
children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
|
|
3352
|
+
}, undefined, false, undefined, this),
|
|
3353
|
+
/* @__PURE__ */ jsxDEV17(Link9, {
|
|
3354
|
+
href: "/docs/architecture",
|
|
3355
|
+
className: "btn-primary",
|
|
3356
|
+
children: "View Architecture"
|
|
3357
|
+
}, undefined, false, undefined, this)
|
|
3358
|
+
]
|
|
3551
3359
|
}, undefined, true, undefined, this)
|
|
3360
|
+
]
|
|
3361
|
+
}, undefined, true, undefined, this)
|
|
3362
|
+
}, undefined, false, undefined, this);
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
// src/components/templates/TemplatesPreviewModal.tsx
|
|
3366
|
+
import { Dialog as Dialog3, DialogContent as DialogContent3 } from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
3367
|
+
import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
|
|
3368
|
+
import { TemplateRuntimeProvider } from "@contractspec/module.examples";
|
|
3369
|
+
import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
|
|
3370
|
+
"use client";
|
|
3371
|
+
function TemplatePreviewModal({
|
|
3372
|
+
templateId,
|
|
3373
|
+
onClose
|
|
3374
|
+
}) {
|
|
3375
|
+
if (!supportsInlineTemplatePreview(templateId)) {
|
|
3376
|
+
return null;
|
|
3377
|
+
}
|
|
3378
|
+
return /* @__PURE__ */ jsxDEV18(Dialog3, {
|
|
3379
|
+
open: true,
|
|
3380
|
+
onOpenChange: (open) => !open && onClose(),
|
|
3381
|
+
children: /* @__PURE__ */ jsxDEV18(DialogContent3, {
|
|
3382
|
+
className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
|
|
3383
|
+
children: /* @__PURE__ */ jsxDEV18(ScrollArea, {
|
|
3384
|
+
className: "flex flex-col justify-between overflow-hidden",
|
|
3385
|
+
children: /* @__PURE__ */ jsxDEV18(TemplateRuntimeProvider, {
|
|
3386
|
+
templateId,
|
|
3387
|
+
projectId: `marketing-preview-${templateId}`,
|
|
3388
|
+
children: /* @__PURE__ */ jsxDEV18(TemplatePreviewContent, {
|
|
3389
|
+
templateId
|
|
3390
|
+
}, undefined, false, undefined, this)
|
|
3391
|
+
}, templateId, false, undefined, this)
|
|
3392
|
+
}, undefined, false, undefined, this)
|
|
3393
|
+
}, undefined, false, undefined, this)
|
|
3394
|
+
}, undefined, false, undefined, this);
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3397
|
+
// src/components/templates/TemplatesOverlays.tsx
|
|
3398
|
+
import {
|
|
3399
|
+
Dialog as Dialog4,
|
|
3400
|
+
DialogContent as DialogContent4,
|
|
3401
|
+
DialogDescription as DialogDescription3,
|
|
3402
|
+
DialogHeader as DialogHeader3,
|
|
3403
|
+
DialogTitle as DialogTitle3
|
|
3404
|
+
} from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
3405
|
+
import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
|
|
3406
|
+
"use client";
|
|
3407
|
+
function TemplatesOverlays({
|
|
3408
|
+
previewTemplateId,
|
|
3409
|
+
onPreviewClose,
|
|
3410
|
+
studioSignupModalOpen,
|
|
3411
|
+
onStudioSignupModalOpenChange,
|
|
3412
|
+
selectedTemplateId,
|
|
3413
|
+
onTemplateCommandClose,
|
|
3414
|
+
onDeployStudio
|
|
3415
|
+
}) {
|
|
3416
|
+
return /* @__PURE__ */ jsxDEV19(Fragment, {
|
|
3417
|
+
children: [
|
|
3418
|
+
previewTemplateId ? /* @__PURE__ */ jsxDEV19(TemplatePreviewModal, {
|
|
3419
|
+
templateId: previewTemplateId,
|
|
3420
|
+
onClose: onPreviewClose
|
|
3421
|
+
}, undefined, false, undefined, this) : null,
|
|
3422
|
+
/* @__PURE__ */ jsxDEV19(Dialog4, {
|
|
3423
|
+
open: studioSignupModalOpen,
|
|
3424
|
+
onOpenChange: onStudioSignupModalOpenChange,
|
|
3425
|
+
children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
|
|
3426
|
+
className: "max-h-[90vh] max-w-2xl overflow-y-auto",
|
|
3427
|
+
children: [
|
|
3428
|
+
/* @__PURE__ */ jsxDEV19(DialogHeader3, {
|
|
3429
|
+
children: [
|
|
3430
|
+
/* @__PURE__ */ jsxDEV19(DialogTitle3, {
|
|
3431
|
+
children: "Deploy in Studio"
|
|
3432
|
+
}, undefined, false, undefined, this),
|
|
3433
|
+
/* @__PURE__ */ jsxDEV19(DialogDescription3, {
|
|
3434
|
+
children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
|
|
3435
|
+
}, undefined, false, undefined, this)
|
|
3436
|
+
]
|
|
3437
|
+
}, undefined, true, undefined, this),
|
|
3438
|
+
/* @__PURE__ */ jsxDEV19(StudioSignupSection, {
|
|
3439
|
+
variant: "compact"
|
|
3440
|
+
}, undefined, false, undefined, this)
|
|
3441
|
+
]
|
|
3442
|
+
}, undefined, true, undefined, this)
|
|
3443
|
+
}, undefined, false, undefined, this),
|
|
3444
|
+
/* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
|
|
3445
|
+
templateId: selectedTemplateId,
|
|
3446
|
+
onClose: onTemplateCommandClose,
|
|
3447
|
+
onDeployStudio
|
|
3448
|
+
}, undefined, false, undefined, this)
|
|
3449
|
+
]
|
|
3450
|
+
}, undefined, true, undefined, this);
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
// src/components/templates/template-filters.ts
|
|
3454
|
+
function buildTemplateFilterState(templates, search, selectedTag, getCandidate) {
|
|
3455
|
+
const searchScopedTemplates = templates.filter((template) => matchesTemplateSearch(getCandidate(template), search));
|
|
3456
|
+
const finalTemplates = selectedTag === null ? searchScopedTemplates : searchScopedTemplates.filter((template) => getCandidate(template).tags.includes(selectedTag));
|
|
3457
|
+
return {
|
|
3458
|
+
searchScopedTemplates,
|
|
3459
|
+
finalTemplates,
|
|
3460
|
+
tagFacets: buildTemplateTagFacets(searchScopedTemplates, getCandidate)
|
|
3461
|
+
};
|
|
3462
|
+
}
|
|
3463
|
+
function buildTemplateTagFacets(templates, getCandidate) {
|
|
3464
|
+
const counts = new Map;
|
|
3465
|
+
for (const template of templates) {
|
|
3466
|
+
for (const tag of new Set(getCandidate(template).tags)) {
|
|
3467
|
+
counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
return [...counts.entries()].map(([tag, count]) => ({ tag, count })).sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
// src/components/templates/template-source.ts
|
|
3474
|
+
function isRegistryConfigured(registryUrl) {
|
|
3475
|
+
return Boolean(registryUrl?.trim());
|
|
3476
|
+
}
|
|
3477
|
+
function getAvailableTemplateSources(registryUrl) {
|
|
3478
|
+
return isRegistryConfigured(registryUrl) ? ["local", "registry"] : ["local"];
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
// src/components/templates/template-tag-visibility.ts
|
|
3482
|
+
var DEFAULT_VISIBLE_TEMPLATE_TAGS = 10;
|
|
3483
|
+
function getVisibleTemplateTagFacets(tagFacets, selectedTag, expanded, visibleCount = DEFAULT_VISIBLE_TEMPLATE_TAGS) {
|
|
3484
|
+
if (expanded) {
|
|
3485
|
+
return {
|
|
3486
|
+
visibleTagFacets: pinSelectedTagFacet(tagFacets, selectedTag),
|
|
3487
|
+
hiddenTagFacets: []
|
|
3488
|
+
};
|
|
3489
|
+
}
|
|
3490
|
+
const visibleTagFacets = pinSelectedTagFacet(tagFacets.slice(0, visibleCount), selectedTag, tagFacets);
|
|
3491
|
+
const visibleTags = new Set(visibleTagFacets.map((facet) => facet.tag));
|
|
3492
|
+
return {
|
|
3493
|
+
visibleTagFacets,
|
|
3494
|
+
hiddenTagFacets: tagFacets.filter((facet) => !visibleTags.has(facet.tag))
|
|
3495
|
+
};
|
|
3496
|
+
}
|
|
3497
|
+
function pinSelectedTagFacet(tagFacets, selectedTag, fallbackTagFacets = tagFacets) {
|
|
3498
|
+
if (selectedTag === null || tagFacets.some((facet) => facet.tag === selectedTag)) {
|
|
3499
|
+
return [...tagFacets];
|
|
3500
|
+
}
|
|
3501
|
+
return [
|
|
3502
|
+
...tagFacets,
|
|
3503
|
+
fallbackTagFacets.find((facet) => facet.tag === selectedTag) ?? {
|
|
3504
|
+
tag: selectedTag,
|
|
3505
|
+
count: 0
|
|
3506
|
+
}
|
|
3507
|
+
];
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
// src/components/templates/useTemplateBrowseState.ts
|
|
3511
|
+
import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
|
|
3512
|
+
import { useEffect, useMemo, useState as useState2 } from "react";
|
|
3513
|
+
"use client";
|
|
3514
|
+
var REGISTRY_URL = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL;
|
|
3515
|
+
function useTemplateBrowseState() {
|
|
3516
|
+
const [selectedTag, setSelectedTag] = useState2(null);
|
|
3517
|
+
const [search, setSearch] = useState2("");
|
|
3518
|
+
const [source, setSource] = useState2("local");
|
|
3519
|
+
const [showAllTags, setShowAllTags] = useState2(false);
|
|
3520
|
+
const registryConfigured = isRegistryConfigured(REGISTRY_URL);
|
|
3521
|
+
const availableSources = getAvailableTemplateSources(REGISTRY_URL);
|
|
3522
|
+
const localTemplates = useMemo(() => buildLocalTemplateCatalog(), []);
|
|
3523
|
+
const localTemplateById = useMemo(() => new Map(localTemplates.map((template) => [template.id, template])), [localTemplates]);
|
|
3524
|
+
const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
|
|
3525
|
+
const localFilterState = useMemo(() => buildTemplateFilterState(localTemplates, search, selectedTag, (template) => ({
|
|
3526
|
+
title: template.title,
|
|
3527
|
+
description: template.description,
|
|
3528
|
+
tags: template.tags
|
|
3529
|
+
})), [localTemplates, search, selectedTag]);
|
|
3530
|
+
const registryFilterState = useMemo(() => buildTemplateFilterState(registryTemplates, search, selectedTag, (template) => ({
|
|
3531
|
+
title: template.name,
|
|
3532
|
+
description: template.description,
|
|
3533
|
+
tags: template.tags
|
|
3534
|
+
})), [registryTemplates, search, selectedTag]);
|
|
3535
|
+
const activeFilterState = source === "registry" ? registryFilterState : localFilterState;
|
|
3536
|
+
const suppressTagRail = source === "registry" && (registryLoading || registryTemplates.length === 0);
|
|
3537
|
+
const { visibleTagFacets, hiddenTagFacets } = useMemo(() => getVisibleTemplateTagFacets(activeFilterState.tagFacets, selectedTag, showAllTags), [activeFilterState.tagFacets, selectedTag, showAllTags]);
|
|
3538
|
+
const showTagFilters = !suppressTagRail && (visibleTagFacets.length > 0 || hiddenTagFacets.length > 0);
|
|
3539
|
+
useEffect(() => {
|
|
3540
|
+
setShowAllTags(false);
|
|
3541
|
+
}, [search, showTagFilters, source]);
|
|
3542
|
+
return {
|
|
3543
|
+
selectedTag,
|
|
3544
|
+
setSelectedTag,
|
|
3545
|
+
search,
|
|
3546
|
+
setSearch,
|
|
3547
|
+
source,
|
|
3548
|
+
setSource,
|
|
3549
|
+
showAllTags,
|
|
3550
|
+
setShowAllTags,
|
|
3551
|
+
registryConfigured,
|
|
3552
|
+
availableSources,
|
|
3553
|
+
localTemplates,
|
|
3554
|
+
localTemplateById,
|
|
3555
|
+
registryTemplates,
|
|
3556
|
+
registryLoading,
|
|
3557
|
+
localFilterState,
|
|
3558
|
+
registryFilterState,
|
|
3559
|
+
visibleTagFacets,
|
|
3560
|
+
hiddenTagFacets,
|
|
3561
|
+
showTagFilters
|
|
3562
|
+
};
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
// src/components/templates/TemplatesClientPage.tsx
|
|
3566
|
+
import {
|
|
3567
|
+
analyticsEventNames as analyticsEventNames3,
|
|
3568
|
+
captureAnalyticsEvent as captureAnalyticsEvent3
|
|
3569
|
+
} from "@contractspec/bundle.library/libs/posthog/client";
|
|
3570
|
+
import { useState as useState3 } from "react";
|
|
3571
|
+
import { jsxDEV as jsxDEV20, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
3572
|
+
"use client";
|
|
3573
|
+
var TemplatesPage = () => {
|
|
3574
|
+
const [previewTemplateId, setPreviewTemplateId] = useState3(null);
|
|
3575
|
+
const [studioSignupModalOpen, setStudioSignupModalOpen] = useState3(false);
|
|
3576
|
+
const [selectedTemplateId, setSelectedTemplateId] = useState3(null);
|
|
3577
|
+
const {
|
|
3578
|
+
selectedTag,
|
|
3579
|
+
setSelectedTag,
|
|
3580
|
+
search,
|
|
3581
|
+
setSearch,
|
|
3582
|
+
source,
|
|
3583
|
+
setSource,
|
|
3584
|
+
showAllTags,
|
|
3585
|
+
setShowAllTags,
|
|
3586
|
+
registryConfigured,
|
|
3587
|
+
availableSources,
|
|
3588
|
+
localTemplates,
|
|
3589
|
+
localTemplateById,
|
|
3590
|
+
registryTemplates,
|
|
3591
|
+
registryLoading,
|
|
3592
|
+
localFilterState,
|
|
3593
|
+
registryFilterState,
|
|
3594
|
+
visibleTagFacets,
|
|
3595
|
+
hiddenTagFacets,
|
|
3596
|
+
showTagFilters
|
|
3597
|
+
} = useTemplateBrowseState();
|
|
3598
|
+
return /* @__PURE__ */ jsxDEV20(Fragment2, {
|
|
3599
|
+
children: [
|
|
3600
|
+
/* @__PURE__ */ jsxDEV20("main", {
|
|
3601
|
+
children: [
|
|
3602
|
+
/* @__PURE__ */ jsxDEV20(TemplatesHeroSection, {
|
|
3603
|
+
localTemplateCount: localTemplates.length,
|
|
3604
|
+
sourceCount: availableSources.length
|
|
3605
|
+
}, undefined, false, undefined, this),
|
|
3606
|
+
/* @__PURE__ */ jsxDEV20(TemplatesBrowseControls, {
|
|
3607
|
+
registryConfigured,
|
|
3608
|
+
availableSources,
|
|
3609
|
+
source,
|
|
3610
|
+
onSourceChange: setSource,
|
|
3611
|
+
search,
|
|
3612
|
+
onSearchChange: setSearch,
|
|
3613
|
+
selectedTag,
|
|
3614
|
+
onTagChange: setSelectedTag,
|
|
3615
|
+
showTagFilters,
|
|
3616
|
+
visibleTagFacets,
|
|
3617
|
+
hiddenTagFacets,
|
|
3618
|
+
showAllTags,
|
|
3619
|
+
onShowAllTagsChange: setShowAllTags
|
|
3620
|
+
}, undefined, false, undefined, this),
|
|
3621
|
+
/* @__PURE__ */ jsxDEV20(TemplatesCatalogSection, {
|
|
3622
|
+
source,
|
|
3623
|
+
registryConfigured,
|
|
3624
|
+
registryLoading,
|
|
3625
|
+
registryHasTemplates: registryTemplates.length > 0,
|
|
3626
|
+
localTemplates: localFilterState.finalTemplates,
|
|
3627
|
+
registryTemplates: registryFilterState.finalTemplates,
|
|
3628
|
+
localTemplateById,
|
|
3629
|
+
onPreview: setPreviewTemplateId,
|
|
3630
|
+
onUseTemplate: (templateId, templateSource) => {
|
|
3631
|
+
captureAnalyticsEvent3(analyticsEventNames3.EXAMPLE_REPO_OPEN, {
|
|
3632
|
+
surface: "templates",
|
|
3633
|
+
templateId,
|
|
3634
|
+
source: templateSource
|
|
3635
|
+
});
|
|
3636
|
+
setSelectedTemplateId(templateId);
|
|
3637
|
+
},
|
|
3638
|
+
hasSearch: search.trim().length > 0,
|
|
3639
|
+
selectedTag
|
|
3640
|
+
}, undefined, false, undefined, this),
|
|
3641
|
+
/* @__PURE__ */ jsxDEV20(TemplatesNextStepsSection, {}, undefined, false, undefined, this)
|
|
3642
|
+
]
|
|
3643
|
+
}, undefined, true, undefined, this),
|
|
3644
|
+
/* @__PURE__ */ jsxDEV20(TemplatesOverlays, {
|
|
3645
|
+
previewTemplateId,
|
|
3646
|
+
onPreviewClose: () => setPreviewTemplateId(null),
|
|
3647
|
+
studioSignupModalOpen,
|
|
3648
|
+
onStudioSignupModalOpenChange: setStudioSignupModalOpen,
|
|
3649
|
+
selectedTemplateId,
|
|
3650
|
+
onTemplateCommandClose: () => setSelectedTemplateId(null),
|
|
3651
|
+
onDeployStudio: () => {
|
|
3652
|
+
setSelectedTemplateId(null);
|
|
3653
|
+
setStudioSignupModalOpen(true);
|
|
3654
|
+
}
|
|
3552
3655
|
}, undefined, false, undefined, this)
|
|
3553
3656
|
]
|
|
3554
3657
|
}, undefined, true, undefined, this);
|
|
@@ -3567,9 +3670,9 @@ import {
|
|
|
3567
3670
|
MarketingSection
|
|
3568
3671
|
} from "@contractspec/lib.design-system";
|
|
3569
3672
|
import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
3570
|
-
import { listTemplates } from "@contractspec/module.examples";
|
|
3571
|
-
import { useMemo as useMemo2, useState as
|
|
3572
|
-
import { jsxDEV as
|
|
3673
|
+
import { listTemplates as listTemplates2 } from "@contractspec/module.examples";
|
|
3674
|
+
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
3675
|
+
import { jsxDEV as jsxDEV21, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
3573
3676
|
"use client";
|
|
3574
3677
|
function matchesQuery(t, query) {
|
|
3575
3678
|
const q = query.trim().toLowerCase();
|
|
@@ -3579,38 +3682,38 @@ function matchesQuery(t, query) {
|
|
|
3579
3682
|
return hay.includes(q);
|
|
3580
3683
|
}
|
|
3581
3684
|
function TemplatesMarketingPage() {
|
|
3582
|
-
const [query, setQuery] =
|
|
3583
|
-
const
|
|
3584
|
-
const filtered = useMemo2(() =>
|
|
3585
|
-
return /* @__PURE__ */
|
|
3685
|
+
const [query, setQuery] = useState4("");
|
|
3686
|
+
const templates = useMemo2(() => listTemplates2(), []);
|
|
3687
|
+
const filtered = useMemo2(() => templates.filter((t) => matchesQuery(t, query)), [templates, query]);
|
|
3688
|
+
return /* @__PURE__ */ jsxDEV21(Fragment3, {
|
|
3586
3689
|
children: [
|
|
3587
|
-
/* @__PURE__ */
|
|
3690
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3588
3691
|
tone: "default",
|
|
3589
|
-
children: /* @__PURE__ */
|
|
3692
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3590
3693
|
as: "header",
|
|
3591
3694
|
gap: "lg",
|
|
3592
3695
|
align: "center",
|
|
3593
3696
|
children: [
|
|
3594
|
-
/* @__PURE__ */
|
|
3697
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3595
3698
|
gap: "sm",
|
|
3596
3699
|
align: "center",
|
|
3597
3700
|
children: [
|
|
3598
|
-
/* @__PURE__ */
|
|
3701
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3599
3702
|
href: "/docs",
|
|
3600
3703
|
variant: "ghost",
|
|
3601
3704
|
children: "Docs"
|
|
3602
3705
|
}, undefined, false, undefined, this),
|
|
3603
|
-
/* @__PURE__ */
|
|
3706
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3604
3707
|
href: "/sandbox",
|
|
3605
3708
|
variant: "ghost",
|
|
3606
3709
|
children: "Open Sandbox"
|
|
3607
3710
|
}, undefined, false, undefined, this)
|
|
3608
3711
|
]
|
|
3609
3712
|
}, undefined, true, undefined, this),
|
|
3610
|
-
/* @__PURE__ */
|
|
3713
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3611
3714
|
gap: "sm",
|
|
3612
3715
|
align: "center",
|
|
3613
|
-
children: /* @__PURE__ */
|
|
3716
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3614
3717
|
href: "/templates",
|
|
3615
3718
|
variant: "default",
|
|
3616
3719
|
children: "Templates"
|
|
@@ -3619,25 +3722,25 @@ function TemplatesMarketingPage() {
|
|
|
3619
3722
|
]
|
|
3620
3723
|
}, undefined, true, undefined, this)
|
|
3621
3724
|
}, undefined, false, undefined, this),
|
|
3622
|
-
/* @__PURE__ */
|
|
3725
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3623
3726
|
tone: "muted",
|
|
3624
|
-
children: /* @__PURE__ */
|
|
3727
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3625
3728
|
gap: "lg",
|
|
3626
3729
|
children: [
|
|
3627
|
-
/* @__PURE__ */
|
|
3730
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3628
3731
|
gap: "sm",
|
|
3629
|
-
children: /* @__PURE__ */
|
|
3732
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3630
3733
|
href: "/templates",
|
|
3631
3734
|
variant: "ghost",
|
|
3632
3735
|
children: "Browse all examples"
|
|
3633
3736
|
}, undefined, false, undefined, this)
|
|
3634
3737
|
}, undefined, false, undefined, this),
|
|
3635
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3636
3739
|
gap: "md",
|
|
3637
3740
|
align: "center",
|
|
3638
3741
|
justify: "between",
|
|
3639
3742
|
wrap: "wrap",
|
|
3640
|
-
children: /* @__PURE__ */
|
|
3743
|
+
children: /* @__PURE__ */ jsxDEV21(Input2, {
|
|
3641
3744
|
"aria-label": "Search templates and examples",
|
|
3642
3745
|
placeholder: "Search templates and examples…",
|
|
3643
3746
|
value: query,
|
|
@@ -3647,52 +3750,52 @@ function TemplatesMarketingPage() {
|
|
|
3647
3750
|
]
|
|
3648
3751
|
}, undefined, true, undefined, this)
|
|
3649
3752
|
}, undefined, false, undefined, this),
|
|
3650
|
-
/* @__PURE__ */
|
|
3753
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3651
3754
|
tone: "default",
|
|
3652
|
-
children: /* @__PURE__ */
|
|
3755
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3653
3756
|
gap: "lg",
|
|
3654
|
-
children: /* @__PURE__ */
|
|
3757
|
+
children: /* @__PURE__ */ jsxDEV21(HStack, {
|
|
3655
3758
|
gap: "md",
|
|
3656
3759
|
wrap: "wrap",
|
|
3657
|
-
children: filtered.map((t) => /* @__PURE__ */
|
|
3760
|
+
children: filtered.map((t) => /* @__PURE__ */ jsxDEV21(MarketingCard, {
|
|
3658
3761
|
className: "w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]",
|
|
3659
3762
|
children: [
|
|
3660
|
-
/* @__PURE__ */
|
|
3763
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardHeader, {
|
|
3661
3764
|
children: [
|
|
3662
|
-
/* @__PURE__ */
|
|
3765
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardTitle, {
|
|
3663
3766
|
children: [
|
|
3664
3767
|
t.icon,
|
|
3665
3768
|
" ",
|
|
3666
3769
|
t.name
|
|
3667
3770
|
]
|
|
3668
3771
|
}, undefined, true, undefined, this),
|
|
3669
|
-
/* @__PURE__ */
|
|
3772
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardDescription, {
|
|
3670
3773
|
children: t.description
|
|
3671
3774
|
}, undefined, false, undefined, this)
|
|
3672
3775
|
]
|
|
3673
3776
|
}, undefined, true, undefined, this),
|
|
3674
|
-
/* @__PURE__ */
|
|
3675
|
-
children: /* @__PURE__ */
|
|
3777
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardContent, {
|
|
3778
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3676
3779
|
gap: "md",
|
|
3677
3780
|
children: [
|
|
3678
|
-
/* @__PURE__ */
|
|
3781
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3679
3782
|
gap: "sm",
|
|
3680
3783
|
wrap: "wrap",
|
|
3681
|
-
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */
|
|
3784
|
+
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3682
3785
|
href: `/templates?tag=${encodeURIComponent(tag)}`,
|
|
3683
3786
|
variant: "ghost",
|
|
3684
3787
|
children: tag
|
|
3685
3788
|
}, `${t.id}-${tag}`, false, undefined, this))
|
|
3686
3789
|
}, undefined, false, undefined, this),
|
|
3687
|
-
/* @__PURE__ */
|
|
3790
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3688
3791
|
gap: "sm",
|
|
3689
3792
|
justify: "between",
|
|
3690
3793
|
wrap: "wrap",
|
|
3691
3794
|
children: [
|
|
3692
|
-
/* @__PURE__ */
|
|
3795
|
+
/* @__PURE__ */ jsxDEV21(ButtonLinkToSandbox, {
|
|
3693
3796
|
templateId: t.id
|
|
3694
3797
|
}, undefined, false, undefined, this),
|
|
3695
|
-
/* @__PURE__ */
|
|
3798
|
+
/* @__PURE__ */ jsxDEV21(Button3, {
|
|
3696
3799
|
variant: "outline",
|
|
3697
3800
|
onClick: () => {
|
|
3698
3801
|
return;
|
|
@@ -3714,7 +3817,7 @@ function TemplatesMarketingPage() {
|
|
|
3714
3817
|
}, undefined, true, undefined, this);
|
|
3715
3818
|
}
|
|
3716
3819
|
function ButtonLinkToSandbox({ templateId }) {
|
|
3717
|
-
return /* @__PURE__ */
|
|
3820
|
+
return /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3718
3821
|
href: `/sandbox?template=${encodeURIComponent(templateId)}`,
|
|
3719
3822
|
variant: "default",
|
|
3720
3823
|
children: "Preview"
|