@contractspec/bundle.marketing 3.8.9 → 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 +54 -42
- package/CHANGELOG.md +33 -0
- package/dist/browser/components/templates/TemplatesBrowseControls.js +37 -22
- package/dist/browser/components/templates/TemplatesCatalogSection.js +29 -6
- package/dist/browser/components/templates/TemplatesClientPage.js +269 -89
- package/dist/browser/components/templates/TemplatesOverlays.js +2874 -0
- package/dist/browser/components/templates/index.js +301 -121
- package/dist/browser/components/templates/template-catalog.js +5 -3
- package/dist/browser/components/templates/template-filters.js +99 -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 +301 -121
- package/dist/components/templates/TemplatesBrowseControls.d.ts +7 -2
- package/dist/components/templates/TemplatesBrowseControls.js +37 -22
- package/dist/components/templates/TemplatesCatalogSection.d.ts +4 -1
- package/dist/components/templates/TemplatesCatalogSection.js +29 -6
- package/dist/components/templates/TemplatesClientPage.js +269 -89
- package/dist/components/templates/TemplatesOverlays.d.ts +10 -0
- package/dist/components/templates/TemplatesOverlays.js +2869 -0
- package/dist/components/templates/index.js +301 -121
- package/dist/components/templates/template-catalog.d.ts +1 -0
- package/dist/components/templates/template-catalog.js +5 -3
- package/dist/components/templates/template-filters.d.ts +12 -0
- package/dist/components/templates/template-filters.js +94 -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 +301 -121
- package/dist/node/components/templates/TemplatesBrowseControls.js +37 -22
- package/dist/node/components/templates/TemplatesCatalogSection.js +29 -6
- package/dist/node/components/templates/TemplatesClientPage.js +269 -89
- package/dist/node/components/templates/TemplatesOverlays.js +2869 -0
- package/dist/node/components/templates/index.js +301 -121
- package/dist/node/components/templates/template-catalog.js +5 -3
- package/dist/node/components/templates/template-filters.js +94 -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 +301 -121
- package/package.json +82 -26
- package/src/components/templates/TemplatesBrowseControls.tsx +59 -35
- package/src/components/templates/TemplatesCatalogSection.tsx +29 -4
- package/src/components/templates/TemplatesClientPage.tsx +41 -97
- package/src/components/templates/TemplatesOverlays.tsx +65 -0
- package/src/components/templates/template-catalog.test.ts +96 -0
- package/src/components/templates/template-catalog.ts +14 -6
- package/src/components/templates/template-filters.ts +57 -0
- package/src/components/templates/template-tag-visibility.ts +58 -0
- package/src/components/templates/useTemplateBrowseState.ts +101 -0
|
@@ -2839,7 +2839,11 @@ function TemplatesBrowseControls({
|
|
|
2839
2839
|
onSearchChange,
|
|
2840
2840
|
selectedTag,
|
|
2841
2841
|
onTagChange,
|
|
2842
|
-
|
|
2842
|
+
showTagFilters,
|
|
2843
|
+
visibleTagFacets,
|
|
2844
|
+
hiddenTagFacets,
|
|
2845
|
+
showAllTags,
|
|
2846
|
+
onShowAllTagsChange
|
|
2843
2847
|
}) {
|
|
2844
2848
|
return /* @__PURE__ */ jsxDEV14("section", {
|
|
2845
2849
|
className: "editorial-section",
|
|
@@ -2900,29 +2904,40 @@ function TemplatesBrowseControls({
|
|
|
2900
2904
|
}, undefined, false, undefined, this)
|
|
2901
2905
|
]
|
|
2902
2906
|
}, undefined, true, undefined, this),
|
|
2903
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2904
|
-
className: "
|
|
2907
|
+
showTagFilters ? /* @__PURE__ */ jsxDEV14("div", {
|
|
2908
|
+
className: "space-y-3",
|
|
2905
2909
|
children: [
|
|
2906
|
-
/* @__PURE__ */ jsxDEV14("
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2910
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2911
|
+
className: "flex flex-wrap gap-2",
|
|
2912
|
+
children: [
|
|
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"
|
|
2921
|
+
}, undefined, false, undefined, this),
|
|
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))
|
|
2931
|
+
]
|
|
2932
|
+
}, 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
|
|
2924
2939
|
]
|
|
2925
|
-
}, undefined, true, undefined, this)
|
|
2940
|
+
}, undefined, true, undefined, this) : null
|
|
2926
2941
|
]
|
|
2927
2942
|
}, undefined, true, undefined, this)
|
|
2928
2943
|
]
|
|
@@ -2967,15 +2982,16 @@ function buildLocalTemplateCatalog(examples = listExamples(), templates = listTe
|
|
|
2967
2982
|
}).sort(compareLocalTemplateCatalogItems);
|
|
2968
2983
|
}
|
|
2969
2984
|
function matchesTemplateFilters(template, search, selectedTag) {
|
|
2985
|
+
return matchesTemplateSearch(template, search) && (selectedTag === null || template.tags.includes(selectedTag));
|
|
2986
|
+
}
|
|
2987
|
+
function matchesTemplateSearch(template, search) {
|
|
2970
2988
|
const haystack = [
|
|
2971
2989
|
template.title,
|
|
2972
2990
|
template.description,
|
|
2973
2991
|
template.tags.join(" ")
|
|
2974
2992
|
].join(" ").toLowerCase();
|
|
2975
2993
|
const searchTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
2976
|
-
|
|
2977
|
-
const matchesTag = selectedTag === null || template.tags.includes(selectedTag);
|
|
2978
|
-
return matchesSearch && matchesTag;
|
|
2994
|
+
return searchTokens.length === 0 || searchTokens.every((token) => haystack.includes(token));
|
|
2979
2995
|
}
|
|
2980
2996
|
function formatExampleKindLabel(kind) {
|
|
2981
2997
|
return kind.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
@@ -3036,13 +3052,17 @@ function TemplatesCatalogSection({
|
|
|
3036
3052
|
source,
|
|
3037
3053
|
registryConfigured,
|
|
3038
3054
|
registryLoading,
|
|
3055
|
+
registryHasTemplates,
|
|
3039
3056
|
localTemplates,
|
|
3040
3057
|
registryTemplates,
|
|
3041
3058
|
localTemplateById,
|
|
3042
3059
|
onPreview,
|
|
3043
|
-
onUseTemplate
|
|
3060
|
+
onUseTemplate,
|
|
3061
|
+
hasSearch,
|
|
3062
|
+
selectedTag
|
|
3044
3063
|
}) {
|
|
3045
3064
|
const showRegistry = source === "registry" && registryConfigured;
|
|
3065
|
+
const emptyStateMessage = getEmptyStateMessage(hasSearch, selectedTag);
|
|
3046
3066
|
return /* @__PURE__ */ jsxDEV15("section", {
|
|
3047
3067
|
className: "section-padding",
|
|
3048
3068
|
children: /* @__PURE__ */ jsxDEV15("div", {
|
|
@@ -3053,12 +3073,18 @@ function TemplatesCatalogSection({
|
|
|
3053
3073
|
className: "text-muted-foreground",
|
|
3054
3074
|
children: "Loading community templates…"
|
|
3055
3075
|
}, undefined, false, undefined, this)
|
|
3056
|
-
}, undefined, false, undefined, this) :
|
|
3076
|
+
}, undefined, false, undefined, this) : !registryHasTemplates ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3057
3077
|
className: "py-12 text-center",
|
|
3058
3078
|
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3059
3079
|
className: "text-muted-foreground",
|
|
3060
3080
|
children: "No community templates found."
|
|
3061
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)
|
|
3062
3088
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3063
3089
|
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
3064
3090
|
children: registryTemplates.map((template) => {
|
|
@@ -3094,7 +3120,7 @@ function TemplatesCatalogSection({
|
|
|
3094
3120
|
className: "py-12 text-center",
|
|
3095
3121
|
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3096
3122
|
className: "text-muted-foreground",
|
|
3097
|
-
children:
|
|
3123
|
+
children: emptyStateMessage
|
|
3098
3124
|
}, undefined, false, undefined, this)
|
|
3099
3125
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3100
3126
|
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
@@ -3130,6 +3156,18 @@ function TemplatesCatalogSection({
|
|
|
3130
3156
|
}, undefined, false, undefined, this)
|
|
3131
3157
|
}, undefined, false, undefined, this);
|
|
3132
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
|
+
}
|
|
3133
3171
|
|
|
3134
3172
|
// src/components/templates/TemplatesHeroSection.tsx
|
|
3135
3173
|
import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
|
|
@@ -3356,6 +3394,82 @@ function TemplatePreviewModal({
|
|
|
3356
3394
|
}, undefined, false, undefined, this);
|
|
3357
3395
|
}
|
|
3358
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
|
+
|
|
3359
3473
|
// src/components/templates/template-source.ts
|
|
3360
3474
|
function isRegistryConfigured(registryUrl) {
|
|
3361
3475
|
return Boolean(registryUrl?.trim());
|
|
@@ -3364,51 +3478,132 @@ function getAvailableTemplateSources(registryUrl) {
|
|
|
3364
3478
|
return isRegistryConfigured(registryUrl) ? ["local", "registry"] : ["local"];
|
|
3365
3479
|
}
|
|
3366
3480
|
|
|
3367
|
-
// src/components/templates/
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
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
|
|
3372
3511
|
import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
|
|
3373
|
-
import {
|
|
3374
|
-
Dialog as Dialog4,
|
|
3375
|
-
DialogContent as DialogContent4,
|
|
3376
|
-
DialogDescription as DialogDescription3,
|
|
3377
|
-
DialogHeader as DialogHeader3,
|
|
3378
|
-
DialogTitle as DialogTitle3
|
|
3379
|
-
} from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
3380
|
-
import { useMemo, useState as useState2 } from "react";
|
|
3381
|
-
import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
|
|
3512
|
+
import { useEffect, useMemo, useState as useState2 } from "react";
|
|
3382
3513
|
"use client";
|
|
3383
3514
|
var REGISTRY_URL = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL;
|
|
3384
|
-
|
|
3515
|
+
function useTemplateBrowseState() {
|
|
3385
3516
|
const [selectedTag, setSelectedTag] = useState2(null);
|
|
3386
3517
|
const [search, setSearch] = useState2("");
|
|
3387
|
-
const [previewTemplateId, setPreviewTemplateId] = useState2(null);
|
|
3388
|
-
const [studioSignupModalOpen, setStudioSignupModalOpen] = useState2(false);
|
|
3389
|
-
const [selectedTemplateId, setSelectedTemplateId] = useState2(null);
|
|
3390
3518
|
const [source, setSource] = useState2("local");
|
|
3519
|
+
const [showAllTags, setShowAllTags] = useState2(false);
|
|
3391
3520
|
const registryConfigured = isRegistryConfigured(REGISTRY_URL);
|
|
3392
3521
|
const availableSources = getAvailableTemplateSources(REGISTRY_URL);
|
|
3393
3522
|
const localTemplates = useMemo(() => buildLocalTemplateCatalog(), []);
|
|
3394
3523
|
const localTemplateById = useMemo(() => new Map(localTemplates.map((template) => [template.id, template])), [localTemplates]);
|
|
3395
|
-
const availableTags = useMemo(() => Array.from(new Set(localTemplates.flatMap((template) => template.tags))).sort((left, right) => left.localeCompare(right)), [localTemplates]);
|
|
3396
3524
|
const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
|
|
3397
|
-
const
|
|
3398
|
-
|
|
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) => ({
|
|
3399
3531
|
title: template.name,
|
|
3400
3532
|
description: template.description,
|
|
3401
3533
|
tags: template.tags
|
|
3402
|
-
}
|
|
3403
|
-
|
|
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, {
|
|
3404
3599
|
children: [
|
|
3405
|
-
/* @__PURE__ */
|
|
3600
|
+
/* @__PURE__ */ jsxDEV20("main", {
|
|
3406
3601
|
children: [
|
|
3407
|
-
/* @__PURE__ */
|
|
3602
|
+
/* @__PURE__ */ jsxDEV20(TemplatesHeroSection, {
|
|
3408
3603
|
localTemplateCount: localTemplates.length,
|
|
3409
3604
|
sourceCount: availableSources.length
|
|
3410
3605
|
}, undefined, false, undefined, this),
|
|
3411
|
-
/* @__PURE__ */
|
|
3606
|
+
/* @__PURE__ */ jsxDEV20(TemplatesBrowseControls, {
|
|
3412
3607
|
registryConfigured,
|
|
3413
3608
|
availableSources,
|
|
3414
3609
|
source,
|
|
@@ -3417,14 +3612,19 @@ var TemplatesPage = () => {
|
|
|
3417
3612
|
onSearchChange: setSearch,
|
|
3418
3613
|
selectedTag,
|
|
3419
3614
|
onTagChange: setSelectedTag,
|
|
3420
|
-
|
|
3615
|
+
showTagFilters,
|
|
3616
|
+
visibleTagFacets,
|
|
3617
|
+
hiddenTagFacets,
|
|
3618
|
+
showAllTags,
|
|
3619
|
+
onShowAllTagsChange: setShowAllTags
|
|
3421
3620
|
}, undefined, false, undefined, this),
|
|
3422
|
-
/* @__PURE__ */
|
|
3621
|
+
/* @__PURE__ */ jsxDEV20(TemplatesCatalogSection, {
|
|
3423
3622
|
source,
|
|
3424
3623
|
registryConfigured,
|
|
3425
3624
|
registryLoading,
|
|
3426
|
-
|
|
3427
|
-
|
|
3625
|
+
registryHasTemplates: registryTemplates.length > 0,
|
|
3626
|
+
localTemplates: localFilterState.finalTemplates,
|
|
3627
|
+
registryTemplates: registryFilterState.finalTemplates,
|
|
3428
3628
|
localTemplateById,
|
|
3429
3629
|
onPreview: setPreviewTemplateId,
|
|
3430
3630
|
onUseTemplate: (templateId, templateSource) => {
|
|
@@ -3434,40 +3634,20 @@ var TemplatesPage = () => {
|
|
|
3434
3634
|
source: templateSource
|
|
3435
3635
|
});
|
|
3436
3636
|
setSelectedTemplateId(templateId);
|
|
3437
|
-
}
|
|
3637
|
+
},
|
|
3638
|
+
hasSearch: search.trim().length > 0,
|
|
3639
|
+
selectedTag
|
|
3438
3640
|
}, undefined, false, undefined, this),
|
|
3439
|
-
/* @__PURE__ */
|
|
3641
|
+
/* @__PURE__ */ jsxDEV20(TemplatesNextStepsSection, {}, undefined, false, undefined, this)
|
|
3440
3642
|
]
|
|
3441
3643
|
}, undefined, true, undefined, this),
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
|
|
3450
|
-
className: "max-h-[90vh] max-w-2xl overflow-y-auto",
|
|
3451
|
-
children: [
|
|
3452
|
-
/* @__PURE__ */ jsxDEV19(DialogHeader3, {
|
|
3453
|
-
children: [
|
|
3454
|
-
/* @__PURE__ */ jsxDEV19(DialogTitle3, {
|
|
3455
|
-
children: "Deploy in Studio"
|
|
3456
|
-
}, undefined, false, undefined, this),
|
|
3457
|
-
/* @__PURE__ */ jsxDEV19(DialogDescription3, {
|
|
3458
|
-
children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
|
|
3459
|
-
}, undefined, false, undefined, this)
|
|
3460
|
-
]
|
|
3461
|
-
}, undefined, true, undefined, this),
|
|
3462
|
-
/* @__PURE__ */ jsxDEV19(StudioSignupSection, {
|
|
3463
|
-
variant: "compact"
|
|
3464
|
-
}, undefined, false, undefined, this)
|
|
3465
|
-
]
|
|
3466
|
-
}, undefined, true, undefined, this)
|
|
3467
|
-
}, undefined, false, undefined, this),
|
|
3468
|
-
/* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
|
|
3469
|
-
templateId: selectedTemplateId,
|
|
3470
|
-
onClose: () => setSelectedTemplateId(null),
|
|
3644
|
+
/* @__PURE__ */ jsxDEV20(TemplatesOverlays, {
|
|
3645
|
+
previewTemplateId,
|
|
3646
|
+
onPreviewClose: () => setPreviewTemplateId(null),
|
|
3647
|
+
studioSignupModalOpen,
|
|
3648
|
+
onStudioSignupModalOpenChange: setStudioSignupModalOpen,
|
|
3649
|
+
selectedTemplateId,
|
|
3650
|
+
onTemplateCommandClose: () => setSelectedTemplateId(null),
|
|
3471
3651
|
onDeployStudio: () => {
|
|
3472
3652
|
setSelectedTemplateId(null);
|
|
3473
3653
|
setStudioSignupModalOpen(true);
|
|
@@ -3491,8 +3671,8 @@ import {
|
|
|
3491
3671
|
} from "@contractspec/lib.design-system";
|
|
3492
3672
|
import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
3493
3673
|
import { listTemplates as listTemplates2 } from "@contractspec/module.examples";
|
|
3494
|
-
import { useMemo as useMemo2, useState as
|
|
3495
|
-
import { jsxDEV as
|
|
3674
|
+
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
3675
|
+
import { jsxDEV as jsxDEV21, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
3496
3676
|
"use client";
|
|
3497
3677
|
function matchesQuery(t, query) {
|
|
3498
3678
|
const q = query.trim().toLowerCase();
|
|
@@ -3502,38 +3682,38 @@ function matchesQuery(t, query) {
|
|
|
3502
3682
|
return hay.includes(q);
|
|
3503
3683
|
}
|
|
3504
3684
|
function TemplatesMarketingPage() {
|
|
3505
|
-
const [query, setQuery] =
|
|
3685
|
+
const [query, setQuery] = useState4("");
|
|
3506
3686
|
const templates = useMemo2(() => listTemplates2(), []);
|
|
3507
3687
|
const filtered = useMemo2(() => templates.filter((t) => matchesQuery(t, query)), [templates, query]);
|
|
3508
|
-
return /* @__PURE__ */
|
|
3688
|
+
return /* @__PURE__ */ jsxDEV21(Fragment3, {
|
|
3509
3689
|
children: [
|
|
3510
|
-
/* @__PURE__ */
|
|
3690
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3511
3691
|
tone: "default",
|
|
3512
|
-
children: /* @__PURE__ */
|
|
3692
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3513
3693
|
as: "header",
|
|
3514
3694
|
gap: "lg",
|
|
3515
3695
|
align: "center",
|
|
3516
3696
|
children: [
|
|
3517
|
-
/* @__PURE__ */
|
|
3697
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3518
3698
|
gap: "sm",
|
|
3519
3699
|
align: "center",
|
|
3520
3700
|
children: [
|
|
3521
|
-
/* @__PURE__ */
|
|
3701
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3522
3702
|
href: "/docs",
|
|
3523
3703
|
variant: "ghost",
|
|
3524
3704
|
children: "Docs"
|
|
3525
3705
|
}, undefined, false, undefined, this),
|
|
3526
|
-
/* @__PURE__ */
|
|
3706
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3527
3707
|
href: "/sandbox",
|
|
3528
3708
|
variant: "ghost",
|
|
3529
3709
|
children: "Open Sandbox"
|
|
3530
3710
|
}, undefined, false, undefined, this)
|
|
3531
3711
|
]
|
|
3532
3712
|
}, undefined, true, undefined, this),
|
|
3533
|
-
/* @__PURE__ */
|
|
3713
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3534
3714
|
gap: "sm",
|
|
3535
3715
|
align: "center",
|
|
3536
|
-
children: /* @__PURE__ */
|
|
3716
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3537
3717
|
href: "/templates",
|
|
3538
3718
|
variant: "default",
|
|
3539
3719
|
children: "Templates"
|
|
@@ -3542,25 +3722,25 @@ function TemplatesMarketingPage() {
|
|
|
3542
3722
|
]
|
|
3543
3723
|
}, undefined, true, undefined, this)
|
|
3544
3724
|
}, undefined, false, undefined, this),
|
|
3545
|
-
/* @__PURE__ */
|
|
3725
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3546
3726
|
tone: "muted",
|
|
3547
|
-
children: /* @__PURE__ */
|
|
3727
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3548
3728
|
gap: "lg",
|
|
3549
3729
|
children: [
|
|
3550
|
-
/* @__PURE__ */
|
|
3730
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3551
3731
|
gap: "sm",
|
|
3552
|
-
children: /* @__PURE__ */
|
|
3732
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3553
3733
|
href: "/templates",
|
|
3554
3734
|
variant: "ghost",
|
|
3555
3735
|
children: "Browse all examples"
|
|
3556
3736
|
}, undefined, false, undefined, this)
|
|
3557
3737
|
}, undefined, false, undefined, this),
|
|
3558
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3559
3739
|
gap: "md",
|
|
3560
3740
|
align: "center",
|
|
3561
3741
|
justify: "between",
|
|
3562
3742
|
wrap: "wrap",
|
|
3563
|
-
children: /* @__PURE__ */
|
|
3743
|
+
children: /* @__PURE__ */ jsxDEV21(Input2, {
|
|
3564
3744
|
"aria-label": "Search templates and examples",
|
|
3565
3745
|
placeholder: "Search templates and examples…",
|
|
3566
3746
|
value: query,
|
|
@@ -3570,52 +3750,52 @@ function TemplatesMarketingPage() {
|
|
|
3570
3750
|
]
|
|
3571
3751
|
}, undefined, true, undefined, this)
|
|
3572
3752
|
}, undefined, false, undefined, this),
|
|
3573
|
-
/* @__PURE__ */
|
|
3753
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3574
3754
|
tone: "default",
|
|
3575
|
-
children: /* @__PURE__ */
|
|
3755
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3576
3756
|
gap: "lg",
|
|
3577
|
-
children: /* @__PURE__ */
|
|
3757
|
+
children: /* @__PURE__ */ jsxDEV21(HStack, {
|
|
3578
3758
|
gap: "md",
|
|
3579
3759
|
wrap: "wrap",
|
|
3580
|
-
children: filtered.map((t) => /* @__PURE__ */
|
|
3760
|
+
children: filtered.map((t) => /* @__PURE__ */ jsxDEV21(MarketingCard, {
|
|
3581
3761
|
className: "w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]",
|
|
3582
3762
|
children: [
|
|
3583
|
-
/* @__PURE__ */
|
|
3763
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardHeader, {
|
|
3584
3764
|
children: [
|
|
3585
|
-
/* @__PURE__ */
|
|
3765
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardTitle, {
|
|
3586
3766
|
children: [
|
|
3587
3767
|
t.icon,
|
|
3588
3768
|
" ",
|
|
3589
3769
|
t.name
|
|
3590
3770
|
]
|
|
3591
3771
|
}, undefined, true, undefined, this),
|
|
3592
|
-
/* @__PURE__ */
|
|
3772
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardDescription, {
|
|
3593
3773
|
children: t.description
|
|
3594
3774
|
}, undefined, false, undefined, this)
|
|
3595
3775
|
]
|
|
3596
3776
|
}, undefined, true, undefined, this),
|
|
3597
|
-
/* @__PURE__ */
|
|
3598
|
-
children: /* @__PURE__ */
|
|
3777
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardContent, {
|
|
3778
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3599
3779
|
gap: "md",
|
|
3600
3780
|
children: [
|
|
3601
|
-
/* @__PURE__ */
|
|
3781
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3602
3782
|
gap: "sm",
|
|
3603
3783
|
wrap: "wrap",
|
|
3604
|
-
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */
|
|
3784
|
+
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3605
3785
|
href: `/templates?tag=${encodeURIComponent(tag)}`,
|
|
3606
3786
|
variant: "ghost",
|
|
3607
3787
|
children: tag
|
|
3608
3788
|
}, `${t.id}-${tag}`, false, undefined, this))
|
|
3609
3789
|
}, undefined, false, undefined, this),
|
|
3610
|
-
/* @__PURE__ */
|
|
3790
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3611
3791
|
gap: "sm",
|
|
3612
3792
|
justify: "between",
|
|
3613
3793
|
wrap: "wrap",
|
|
3614
3794
|
children: [
|
|
3615
|
-
/* @__PURE__ */
|
|
3795
|
+
/* @__PURE__ */ jsxDEV21(ButtonLinkToSandbox, {
|
|
3616
3796
|
templateId: t.id
|
|
3617
3797
|
}, undefined, false, undefined, this),
|
|
3618
|
-
/* @__PURE__ */
|
|
3798
|
+
/* @__PURE__ */ jsxDEV21(Button3, {
|
|
3619
3799
|
variant: "outline",
|
|
3620
3800
|
onClick: () => {
|
|
3621
3801
|
return;
|
|
@@ -3637,7 +3817,7 @@ function TemplatesMarketingPage() {
|
|
|
3637
3817
|
}, undefined, true, undefined, this);
|
|
3638
3818
|
}
|
|
3639
3819
|
function ButtonLinkToSandbox({ templateId }) {
|
|
3640
|
-
return /* @__PURE__ */
|
|
3820
|
+
return /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3641
3821
|
href: `/sandbox?template=${encodeURIComponent(templateId)}`,
|
|
3642
3822
|
variant: "default",
|
|
3643
3823
|
children: "Preview"
|