@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
|
@@ -2834,7 +2834,11 @@ function TemplatesBrowseControls({
|
|
|
2834
2834
|
onSearchChange,
|
|
2835
2835
|
selectedTag,
|
|
2836
2836
|
onTagChange,
|
|
2837
|
-
|
|
2837
|
+
showTagFilters,
|
|
2838
|
+
visibleTagFacets,
|
|
2839
|
+
hiddenTagFacets,
|
|
2840
|
+
showAllTags,
|
|
2841
|
+
onShowAllTagsChange
|
|
2838
2842
|
}) {
|
|
2839
2843
|
return /* @__PURE__ */ jsxDEV14("section", {
|
|
2840
2844
|
className: "editorial-section",
|
|
@@ -2895,29 +2899,40 @@ function TemplatesBrowseControls({
|
|
|
2895
2899
|
}, undefined, false, undefined, this)
|
|
2896
2900
|
]
|
|
2897
2901
|
}, undefined, true, undefined, this),
|
|
2898
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2899
|
-
className: "
|
|
2902
|
+
showTagFilters ? /* @__PURE__ */ jsxDEV14("div", {
|
|
2903
|
+
className: "space-y-3",
|
|
2900
2904
|
children: [
|
|
2901
|
-
/* @__PURE__ */ jsxDEV14("
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2905
|
+
/* @__PURE__ */ jsxDEV14("div", {
|
|
2906
|
+
className: "flex flex-wrap gap-2",
|
|
2907
|
+
children: [
|
|
2908
|
+
/* @__PURE__ */ jsxDEV14("button", {
|
|
2909
|
+
onClick: () => onTagChange(null),
|
|
2910
|
+
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
2911
|
+
"bg-primary text-primary-foreground": selectedTag === null,
|
|
2912
|
+
"border border-border bg-card hover:bg-card/80": selectedTag !== null
|
|
2913
|
+
}),
|
|
2914
|
+
"aria-pressed": selectedTag === null,
|
|
2915
|
+
children: "All"
|
|
2916
|
+
}, undefined, false, undefined, this),
|
|
2917
|
+
visibleTagFacets.map((facet) => /* @__PURE__ */ jsxDEV14("button", {
|
|
2918
|
+
onClick: () => onTagChange(facet.tag),
|
|
2919
|
+
className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
|
|
2920
|
+
"bg-primary text-primary-foreground": selectedTag === facet.tag,
|
|
2921
|
+
"border border-border bg-card hover:bg-card/80": selectedTag !== facet.tag
|
|
2922
|
+
}),
|
|
2923
|
+
"aria-pressed": selectedTag === facet.tag,
|
|
2924
|
+
children: facet.tag
|
|
2925
|
+
}, facet.tag, false, undefined, this))
|
|
2926
|
+
]
|
|
2927
|
+
}, undefined, true, undefined, this),
|
|
2928
|
+
hiddenTagFacets.length > 0 || showAllTags ? /* @__PURE__ */ jsxDEV14("button", {
|
|
2929
|
+
type: "button",
|
|
2930
|
+
onClick: () => onShowAllTagsChange(!showAllTags),
|
|
2931
|
+
className: "text-muted-foreground text-sm transition-colors hover:text-foreground",
|
|
2932
|
+
children: showAllTags ? "Show fewer" : "More tags"
|
|
2933
|
+
}, undefined, false, undefined, this) : null
|
|
2919
2934
|
]
|
|
2920
|
-
}, undefined, true, undefined, this)
|
|
2935
|
+
}, undefined, true, undefined, this) : null
|
|
2921
2936
|
]
|
|
2922
2937
|
}, undefined, true, undefined, this)
|
|
2923
2938
|
]
|
|
@@ -2962,15 +2977,16 @@ function buildLocalTemplateCatalog(examples = listExamples(), templates = listTe
|
|
|
2962
2977
|
}).sort(compareLocalTemplateCatalogItems);
|
|
2963
2978
|
}
|
|
2964
2979
|
function matchesTemplateFilters(template, search, selectedTag) {
|
|
2980
|
+
return matchesTemplateSearch(template, search) && (selectedTag === null || template.tags.includes(selectedTag));
|
|
2981
|
+
}
|
|
2982
|
+
function matchesTemplateSearch(template, search) {
|
|
2965
2983
|
const haystack = [
|
|
2966
2984
|
template.title,
|
|
2967
2985
|
template.description,
|
|
2968
2986
|
template.tags.join(" ")
|
|
2969
2987
|
].join(" ").toLowerCase();
|
|
2970
2988
|
const searchTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
2971
|
-
|
|
2972
|
-
const matchesTag = selectedTag === null || template.tags.includes(selectedTag);
|
|
2973
|
-
return matchesSearch && matchesTag;
|
|
2989
|
+
return searchTokens.length === 0 || searchTokens.every((token) => haystack.includes(token));
|
|
2974
2990
|
}
|
|
2975
2991
|
function formatExampleKindLabel(kind) {
|
|
2976
2992
|
return kind.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
@@ -3031,13 +3047,17 @@ function TemplatesCatalogSection({
|
|
|
3031
3047
|
source,
|
|
3032
3048
|
registryConfigured,
|
|
3033
3049
|
registryLoading,
|
|
3050
|
+
registryHasTemplates,
|
|
3034
3051
|
localTemplates,
|
|
3035
3052
|
registryTemplates,
|
|
3036
3053
|
localTemplateById,
|
|
3037
3054
|
onPreview,
|
|
3038
|
-
onUseTemplate
|
|
3055
|
+
onUseTemplate,
|
|
3056
|
+
hasSearch,
|
|
3057
|
+
selectedTag
|
|
3039
3058
|
}) {
|
|
3040
3059
|
const showRegistry = source === "registry" && registryConfigured;
|
|
3060
|
+
const emptyStateMessage = getEmptyStateMessage(hasSearch, selectedTag);
|
|
3041
3061
|
return /* @__PURE__ */ jsxDEV15("section", {
|
|
3042
3062
|
className: "section-padding",
|
|
3043
3063
|
children: /* @__PURE__ */ jsxDEV15("div", {
|
|
@@ -3048,12 +3068,18 @@ function TemplatesCatalogSection({
|
|
|
3048
3068
|
className: "text-muted-foreground",
|
|
3049
3069
|
children: "Loading community templates…"
|
|
3050
3070
|
}, undefined, false, undefined, this)
|
|
3051
|
-
}, undefined, false, undefined, this) :
|
|
3071
|
+
}, undefined, false, undefined, this) : !registryHasTemplates ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3052
3072
|
className: "py-12 text-center",
|
|
3053
3073
|
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3054
3074
|
className: "text-muted-foreground",
|
|
3055
3075
|
children: "No community templates found."
|
|
3056
3076
|
}, undefined, false, undefined, this)
|
|
3077
|
+
}, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
|
|
3078
|
+
className: "py-12 text-center",
|
|
3079
|
+
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3080
|
+
className: "text-muted-foreground",
|
|
3081
|
+
children: emptyStateMessage
|
|
3082
|
+
}, undefined, false, undefined, this)
|
|
3057
3083
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3058
3084
|
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
3059
3085
|
children: registryTemplates.map((template) => {
|
|
@@ -3089,7 +3115,7 @@ function TemplatesCatalogSection({
|
|
|
3089
3115
|
className: "py-12 text-center",
|
|
3090
3116
|
children: /* @__PURE__ */ jsxDEV15("p", {
|
|
3091
3117
|
className: "text-muted-foreground",
|
|
3092
|
-
children:
|
|
3118
|
+
children: emptyStateMessage
|
|
3093
3119
|
}, undefined, false, undefined, this)
|
|
3094
3120
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
|
|
3095
3121
|
className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
|
|
@@ -3125,6 +3151,18 @@ function TemplatesCatalogSection({
|
|
|
3125
3151
|
}, undefined, false, undefined, this)
|
|
3126
3152
|
}, undefined, false, undefined, this);
|
|
3127
3153
|
}
|
|
3154
|
+
function getEmptyStateMessage(hasSearch, selectedTag) {
|
|
3155
|
+
if (selectedTag !== null && hasSearch) {
|
|
3156
|
+
return "No templates match this tag for the current search.";
|
|
3157
|
+
}
|
|
3158
|
+
if (selectedTag !== null) {
|
|
3159
|
+
return "No templates match this tag. Try another tag or reset filters.";
|
|
3160
|
+
}
|
|
3161
|
+
if (hasSearch) {
|
|
3162
|
+
return "No templates match your search. Try a different keyword.";
|
|
3163
|
+
}
|
|
3164
|
+
return "No templates match your filters. Try a different search.";
|
|
3165
|
+
}
|
|
3128
3166
|
|
|
3129
3167
|
// src/components/templates/TemplatesHeroSection.tsx
|
|
3130
3168
|
import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
|
|
@@ -3351,6 +3389,82 @@ function TemplatePreviewModal({
|
|
|
3351
3389
|
}, undefined, false, undefined, this);
|
|
3352
3390
|
}
|
|
3353
3391
|
|
|
3392
|
+
// src/components/templates/TemplatesOverlays.tsx
|
|
3393
|
+
import {
|
|
3394
|
+
Dialog as Dialog4,
|
|
3395
|
+
DialogContent as DialogContent4,
|
|
3396
|
+
DialogDescription as DialogDescription3,
|
|
3397
|
+
DialogHeader as DialogHeader3,
|
|
3398
|
+
DialogTitle as DialogTitle3
|
|
3399
|
+
} from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
3400
|
+
import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
|
|
3401
|
+
"use client";
|
|
3402
|
+
function TemplatesOverlays({
|
|
3403
|
+
previewTemplateId,
|
|
3404
|
+
onPreviewClose,
|
|
3405
|
+
studioSignupModalOpen,
|
|
3406
|
+
onStudioSignupModalOpenChange,
|
|
3407
|
+
selectedTemplateId,
|
|
3408
|
+
onTemplateCommandClose,
|
|
3409
|
+
onDeployStudio
|
|
3410
|
+
}) {
|
|
3411
|
+
return /* @__PURE__ */ jsxDEV19(Fragment, {
|
|
3412
|
+
children: [
|
|
3413
|
+
previewTemplateId ? /* @__PURE__ */ jsxDEV19(TemplatePreviewModal, {
|
|
3414
|
+
templateId: previewTemplateId,
|
|
3415
|
+
onClose: onPreviewClose
|
|
3416
|
+
}, undefined, false, undefined, this) : null,
|
|
3417
|
+
/* @__PURE__ */ jsxDEV19(Dialog4, {
|
|
3418
|
+
open: studioSignupModalOpen,
|
|
3419
|
+
onOpenChange: onStudioSignupModalOpenChange,
|
|
3420
|
+
children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
|
|
3421
|
+
className: "max-h-[90vh] max-w-2xl overflow-y-auto",
|
|
3422
|
+
children: [
|
|
3423
|
+
/* @__PURE__ */ jsxDEV19(DialogHeader3, {
|
|
3424
|
+
children: [
|
|
3425
|
+
/* @__PURE__ */ jsxDEV19(DialogTitle3, {
|
|
3426
|
+
children: "Deploy in Studio"
|
|
3427
|
+
}, undefined, false, undefined, this),
|
|
3428
|
+
/* @__PURE__ */ jsxDEV19(DialogDescription3, {
|
|
3429
|
+
children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
|
|
3430
|
+
}, undefined, false, undefined, this)
|
|
3431
|
+
]
|
|
3432
|
+
}, undefined, true, undefined, this),
|
|
3433
|
+
/* @__PURE__ */ jsxDEV19(StudioSignupSection, {
|
|
3434
|
+
variant: "compact"
|
|
3435
|
+
}, undefined, false, undefined, this)
|
|
3436
|
+
]
|
|
3437
|
+
}, undefined, true, undefined, this)
|
|
3438
|
+
}, undefined, false, undefined, this),
|
|
3439
|
+
/* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
|
|
3440
|
+
templateId: selectedTemplateId,
|
|
3441
|
+
onClose: onTemplateCommandClose,
|
|
3442
|
+
onDeployStudio
|
|
3443
|
+
}, undefined, false, undefined, this)
|
|
3444
|
+
]
|
|
3445
|
+
}, undefined, true, undefined, this);
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
// src/components/templates/template-filters.ts
|
|
3449
|
+
function buildTemplateFilterState(templates, search, selectedTag, getCandidate) {
|
|
3450
|
+
const searchScopedTemplates = templates.filter((template) => matchesTemplateSearch(getCandidate(template), search));
|
|
3451
|
+
const finalTemplates = selectedTag === null ? searchScopedTemplates : searchScopedTemplates.filter((template) => getCandidate(template).tags.includes(selectedTag));
|
|
3452
|
+
return {
|
|
3453
|
+
searchScopedTemplates,
|
|
3454
|
+
finalTemplates,
|
|
3455
|
+
tagFacets: buildTemplateTagFacets(searchScopedTemplates, getCandidate)
|
|
3456
|
+
};
|
|
3457
|
+
}
|
|
3458
|
+
function buildTemplateTagFacets(templates, getCandidate) {
|
|
3459
|
+
const counts = new Map;
|
|
3460
|
+
for (const template of templates) {
|
|
3461
|
+
for (const tag of new Set(getCandidate(template).tags)) {
|
|
3462
|
+
counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
return [...counts.entries()].map(([tag, count]) => ({ tag, count })).sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));
|
|
3466
|
+
}
|
|
3467
|
+
|
|
3354
3468
|
// src/components/templates/template-source.ts
|
|
3355
3469
|
function isRegistryConfigured(registryUrl) {
|
|
3356
3470
|
return Boolean(registryUrl?.trim());
|
|
@@ -3359,51 +3473,132 @@ function getAvailableTemplateSources(registryUrl) {
|
|
|
3359
3473
|
return isRegistryConfigured(registryUrl) ? ["local", "registry"] : ["local"];
|
|
3360
3474
|
}
|
|
3361
3475
|
|
|
3362
|
-
// src/components/templates/
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3476
|
+
// src/components/templates/template-tag-visibility.ts
|
|
3477
|
+
var DEFAULT_VISIBLE_TEMPLATE_TAGS = 10;
|
|
3478
|
+
function getVisibleTemplateTagFacets(tagFacets, selectedTag, expanded, visibleCount = DEFAULT_VISIBLE_TEMPLATE_TAGS) {
|
|
3479
|
+
if (expanded) {
|
|
3480
|
+
return {
|
|
3481
|
+
visibleTagFacets: pinSelectedTagFacet(tagFacets, selectedTag),
|
|
3482
|
+
hiddenTagFacets: []
|
|
3483
|
+
};
|
|
3484
|
+
}
|
|
3485
|
+
const visibleTagFacets = pinSelectedTagFacet(tagFacets.slice(0, visibleCount), selectedTag, tagFacets);
|
|
3486
|
+
const visibleTags = new Set(visibleTagFacets.map((facet) => facet.tag));
|
|
3487
|
+
return {
|
|
3488
|
+
visibleTagFacets,
|
|
3489
|
+
hiddenTagFacets: tagFacets.filter((facet) => !visibleTags.has(facet.tag))
|
|
3490
|
+
};
|
|
3491
|
+
}
|
|
3492
|
+
function pinSelectedTagFacet(tagFacets, selectedTag, fallbackTagFacets = tagFacets) {
|
|
3493
|
+
if (selectedTag === null || tagFacets.some((facet) => facet.tag === selectedTag)) {
|
|
3494
|
+
return [...tagFacets];
|
|
3495
|
+
}
|
|
3496
|
+
return [
|
|
3497
|
+
...tagFacets,
|
|
3498
|
+
fallbackTagFacets.find((facet) => facet.tag === selectedTag) ?? {
|
|
3499
|
+
tag: selectedTag,
|
|
3500
|
+
count: 0
|
|
3501
|
+
}
|
|
3502
|
+
];
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
// src/components/templates/useTemplateBrowseState.ts
|
|
3367
3506
|
import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
|
|
3368
|
-
import {
|
|
3369
|
-
Dialog as Dialog4,
|
|
3370
|
-
DialogContent as DialogContent4,
|
|
3371
|
-
DialogDescription as DialogDescription3,
|
|
3372
|
-
DialogHeader as DialogHeader3,
|
|
3373
|
-
DialogTitle as DialogTitle3
|
|
3374
|
-
} from "@contractspec/lib.ui-kit-web/ui/dialog";
|
|
3375
|
-
import { useMemo, useState as useState2 } from "react";
|
|
3376
|
-
import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
|
|
3507
|
+
import { useEffect, useMemo, useState as useState2 } from "react";
|
|
3377
3508
|
"use client";
|
|
3378
3509
|
var REGISTRY_URL = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL;
|
|
3379
|
-
|
|
3510
|
+
function useTemplateBrowseState() {
|
|
3380
3511
|
const [selectedTag, setSelectedTag] = useState2(null);
|
|
3381
3512
|
const [search, setSearch] = useState2("");
|
|
3382
|
-
const [previewTemplateId, setPreviewTemplateId] = useState2(null);
|
|
3383
|
-
const [studioSignupModalOpen, setStudioSignupModalOpen] = useState2(false);
|
|
3384
|
-
const [selectedTemplateId, setSelectedTemplateId] = useState2(null);
|
|
3385
3513
|
const [source, setSource] = useState2("local");
|
|
3514
|
+
const [showAllTags, setShowAllTags] = useState2(false);
|
|
3386
3515
|
const registryConfigured = isRegistryConfigured(REGISTRY_URL);
|
|
3387
3516
|
const availableSources = getAvailableTemplateSources(REGISTRY_URL);
|
|
3388
3517
|
const localTemplates = useMemo(() => buildLocalTemplateCatalog(), []);
|
|
3389
3518
|
const localTemplateById = useMemo(() => new Map(localTemplates.map((template) => [template.id, template])), [localTemplates]);
|
|
3390
|
-
const availableTags = useMemo(() => Array.from(new Set(localTemplates.flatMap((template) => template.tags))).sort((left, right) => left.localeCompare(right)), [localTemplates]);
|
|
3391
3519
|
const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
|
|
3392
|
-
const
|
|
3393
|
-
|
|
3520
|
+
const localFilterState = useMemo(() => buildTemplateFilterState(localTemplates, search, selectedTag, (template) => ({
|
|
3521
|
+
title: template.title,
|
|
3522
|
+
description: template.description,
|
|
3523
|
+
tags: template.tags
|
|
3524
|
+
})), [localTemplates, search, selectedTag]);
|
|
3525
|
+
const registryFilterState = useMemo(() => buildTemplateFilterState(registryTemplates, search, selectedTag, (template) => ({
|
|
3394
3526
|
title: template.name,
|
|
3395
3527
|
description: template.description,
|
|
3396
3528
|
tags: template.tags
|
|
3397
|
-
}
|
|
3398
|
-
|
|
3529
|
+
})), [registryTemplates, search, selectedTag]);
|
|
3530
|
+
const activeFilterState = source === "registry" ? registryFilterState : localFilterState;
|
|
3531
|
+
const suppressTagRail = source === "registry" && (registryLoading || registryTemplates.length === 0);
|
|
3532
|
+
const { visibleTagFacets, hiddenTagFacets } = useMemo(() => getVisibleTemplateTagFacets(activeFilterState.tagFacets, selectedTag, showAllTags), [activeFilterState.tagFacets, selectedTag, showAllTags]);
|
|
3533
|
+
const showTagFilters = !suppressTagRail && (visibleTagFacets.length > 0 || hiddenTagFacets.length > 0);
|
|
3534
|
+
useEffect(() => {
|
|
3535
|
+
setShowAllTags(false);
|
|
3536
|
+
}, [search, showTagFilters, source]);
|
|
3537
|
+
return {
|
|
3538
|
+
selectedTag,
|
|
3539
|
+
setSelectedTag,
|
|
3540
|
+
search,
|
|
3541
|
+
setSearch,
|
|
3542
|
+
source,
|
|
3543
|
+
setSource,
|
|
3544
|
+
showAllTags,
|
|
3545
|
+
setShowAllTags,
|
|
3546
|
+
registryConfigured,
|
|
3547
|
+
availableSources,
|
|
3548
|
+
localTemplates,
|
|
3549
|
+
localTemplateById,
|
|
3550
|
+
registryTemplates,
|
|
3551
|
+
registryLoading,
|
|
3552
|
+
localFilterState,
|
|
3553
|
+
registryFilterState,
|
|
3554
|
+
visibleTagFacets,
|
|
3555
|
+
hiddenTagFacets,
|
|
3556
|
+
showTagFilters
|
|
3557
|
+
};
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
// src/components/templates/TemplatesClientPage.tsx
|
|
3561
|
+
import {
|
|
3562
|
+
analyticsEventNames as analyticsEventNames3,
|
|
3563
|
+
captureAnalyticsEvent as captureAnalyticsEvent3
|
|
3564
|
+
} from "@contractspec/bundle.library/libs/posthog/client";
|
|
3565
|
+
import { useState as useState3 } from "react";
|
|
3566
|
+
import { jsxDEV as jsxDEV20, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
3567
|
+
"use client";
|
|
3568
|
+
var TemplatesPage = () => {
|
|
3569
|
+
const [previewTemplateId, setPreviewTemplateId] = useState3(null);
|
|
3570
|
+
const [studioSignupModalOpen, setStudioSignupModalOpen] = useState3(false);
|
|
3571
|
+
const [selectedTemplateId, setSelectedTemplateId] = useState3(null);
|
|
3572
|
+
const {
|
|
3573
|
+
selectedTag,
|
|
3574
|
+
setSelectedTag,
|
|
3575
|
+
search,
|
|
3576
|
+
setSearch,
|
|
3577
|
+
source,
|
|
3578
|
+
setSource,
|
|
3579
|
+
showAllTags,
|
|
3580
|
+
setShowAllTags,
|
|
3581
|
+
registryConfigured,
|
|
3582
|
+
availableSources,
|
|
3583
|
+
localTemplates,
|
|
3584
|
+
localTemplateById,
|
|
3585
|
+
registryTemplates,
|
|
3586
|
+
registryLoading,
|
|
3587
|
+
localFilterState,
|
|
3588
|
+
registryFilterState,
|
|
3589
|
+
visibleTagFacets,
|
|
3590
|
+
hiddenTagFacets,
|
|
3591
|
+
showTagFilters
|
|
3592
|
+
} = useTemplateBrowseState();
|
|
3593
|
+
return /* @__PURE__ */ jsxDEV20(Fragment2, {
|
|
3399
3594
|
children: [
|
|
3400
|
-
/* @__PURE__ */
|
|
3595
|
+
/* @__PURE__ */ jsxDEV20("main", {
|
|
3401
3596
|
children: [
|
|
3402
|
-
/* @__PURE__ */
|
|
3597
|
+
/* @__PURE__ */ jsxDEV20(TemplatesHeroSection, {
|
|
3403
3598
|
localTemplateCount: localTemplates.length,
|
|
3404
3599
|
sourceCount: availableSources.length
|
|
3405
3600
|
}, undefined, false, undefined, this),
|
|
3406
|
-
/* @__PURE__ */
|
|
3601
|
+
/* @__PURE__ */ jsxDEV20(TemplatesBrowseControls, {
|
|
3407
3602
|
registryConfigured,
|
|
3408
3603
|
availableSources,
|
|
3409
3604
|
source,
|
|
@@ -3412,14 +3607,19 @@ var TemplatesPage = () => {
|
|
|
3412
3607
|
onSearchChange: setSearch,
|
|
3413
3608
|
selectedTag,
|
|
3414
3609
|
onTagChange: setSelectedTag,
|
|
3415
|
-
|
|
3610
|
+
showTagFilters,
|
|
3611
|
+
visibleTagFacets,
|
|
3612
|
+
hiddenTagFacets,
|
|
3613
|
+
showAllTags,
|
|
3614
|
+
onShowAllTagsChange: setShowAllTags
|
|
3416
3615
|
}, undefined, false, undefined, this),
|
|
3417
|
-
/* @__PURE__ */
|
|
3616
|
+
/* @__PURE__ */ jsxDEV20(TemplatesCatalogSection, {
|
|
3418
3617
|
source,
|
|
3419
3618
|
registryConfigured,
|
|
3420
3619
|
registryLoading,
|
|
3421
|
-
|
|
3422
|
-
|
|
3620
|
+
registryHasTemplates: registryTemplates.length > 0,
|
|
3621
|
+
localTemplates: localFilterState.finalTemplates,
|
|
3622
|
+
registryTemplates: registryFilterState.finalTemplates,
|
|
3423
3623
|
localTemplateById,
|
|
3424
3624
|
onPreview: setPreviewTemplateId,
|
|
3425
3625
|
onUseTemplate: (templateId, templateSource) => {
|
|
@@ -3429,40 +3629,20 @@ var TemplatesPage = () => {
|
|
|
3429
3629
|
source: templateSource
|
|
3430
3630
|
});
|
|
3431
3631
|
setSelectedTemplateId(templateId);
|
|
3432
|
-
}
|
|
3632
|
+
},
|
|
3633
|
+
hasSearch: search.trim().length > 0,
|
|
3634
|
+
selectedTag
|
|
3433
3635
|
}, undefined, false, undefined, this),
|
|
3434
|
-
/* @__PURE__ */
|
|
3636
|
+
/* @__PURE__ */ jsxDEV20(TemplatesNextStepsSection, {}, undefined, false, undefined, this)
|
|
3435
3637
|
]
|
|
3436
3638
|
}, undefined, true, undefined, this),
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
|
|
3445
|
-
className: "max-h-[90vh] max-w-2xl overflow-y-auto",
|
|
3446
|
-
children: [
|
|
3447
|
-
/* @__PURE__ */ jsxDEV19(DialogHeader3, {
|
|
3448
|
-
children: [
|
|
3449
|
-
/* @__PURE__ */ jsxDEV19(DialogTitle3, {
|
|
3450
|
-
children: "Deploy in Studio"
|
|
3451
|
-
}, undefined, false, undefined, this),
|
|
3452
|
-
/* @__PURE__ */ jsxDEV19(DialogDescription3, {
|
|
3453
|
-
children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
|
|
3454
|
-
}, undefined, false, undefined, this)
|
|
3455
|
-
]
|
|
3456
|
-
}, undefined, true, undefined, this),
|
|
3457
|
-
/* @__PURE__ */ jsxDEV19(StudioSignupSection, {
|
|
3458
|
-
variant: "compact"
|
|
3459
|
-
}, undefined, false, undefined, this)
|
|
3460
|
-
]
|
|
3461
|
-
}, undefined, true, undefined, this)
|
|
3462
|
-
}, undefined, false, undefined, this),
|
|
3463
|
-
/* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
|
|
3464
|
-
templateId: selectedTemplateId,
|
|
3465
|
-
onClose: () => setSelectedTemplateId(null),
|
|
3639
|
+
/* @__PURE__ */ jsxDEV20(TemplatesOverlays, {
|
|
3640
|
+
previewTemplateId,
|
|
3641
|
+
onPreviewClose: () => setPreviewTemplateId(null),
|
|
3642
|
+
studioSignupModalOpen,
|
|
3643
|
+
onStudioSignupModalOpenChange: setStudioSignupModalOpen,
|
|
3644
|
+
selectedTemplateId,
|
|
3645
|
+
onTemplateCommandClose: () => setSelectedTemplateId(null),
|
|
3466
3646
|
onDeployStudio: () => {
|
|
3467
3647
|
setSelectedTemplateId(null);
|
|
3468
3648
|
setStudioSignupModalOpen(true);
|
|
@@ -3486,8 +3666,8 @@ import {
|
|
|
3486
3666
|
} from "@contractspec/lib.design-system";
|
|
3487
3667
|
import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
3488
3668
|
import { listTemplates as listTemplates2 } from "@contractspec/module.examples";
|
|
3489
|
-
import { useMemo as useMemo2, useState as
|
|
3490
|
-
import { jsxDEV as
|
|
3669
|
+
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
3670
|
+
import { jsxDEV as jsxDEV21, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
3491
3671
|
"use client";
|
|
3492
3672
|
function matchesQuery(t, query) {
|
|
3493
3673
|
const q = query.trim().toLowerCase();
|
|
@@ -3497,38 +3677,38 @@ function matchesQuery(t, query) {
|
|
|
3497
3677
|
return hay.includes(q);
|
|
3498
3678
|
}
|
|
3499
3679
|
function TemplatesMarketingPage() {
|
|
3500
|
-
const [query, setQuery] =
|
|
3680
|
+
const [query, setQuery] = useState4("");
|
|
3501
3681
|
const templates = useMemo2(() => listTemplates2(), []);
|
|
3502
3682
|
const filtered = useMemo2(() => templates.filter((t) => matchesQuery(t, query)), [templates, query]);
|
|
3503
|
-
return /* @__PURE__ */
|
|
3683
|
+
return /* @__PURE__ */ jsxDEV21(Fragment3, {
|
|
3504
3684
|
children: [
|
|
3505
|
-
/* @__PURE__ */
|
|
3685
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3506
3686
|
tone: "default",
|
|
3507
|
-
children: /* @__PURE__ */
|
|
3687
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3508
3688
|
as: "header",
|
|
3509
3689
|
gap: "lg",
|
|
3510
3690
|
align: "center",
|
|
3511
3691
|
children: [
|
|
3512
|
-
/* @__PURE__ */
|
|
3692
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3513
3693
|
gap: "sm",
|
|
3514
3694
|
align: "center",
|
|
3515
3695
|
children: [
|
|
3516
|
-
/* @__PURE__ */
|
|
3696
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3517
3697
|
href: "/docs",
|
|
3518
3698
|
variant: "ghost",
|
|
3519
3699
|
children: "Docs"
|
|
3520
3700
|
}, undefined, false, undefined, this),
|
|
3521
|
-
/* @__PURE__ */
|
|
3701
|
+
/* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3522
3702
|
href: "/sandbox",
|
|
3523
3703
|
variant: "ghost",
|
|
3524
3704
|
children: "Open Sandbox"
|
|
3525
3705
|
}, undefined, false, undefined, this)
|
|
3526
3706
|
]
|
|
3527
3707
|
}, undefined, true, undefined, this),
|
|
3528
|
-
/* @__PURE__ */
|
|
3708
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3529
3709
|
gap: "sm",
|
|
3530
3710
|
align: "center",
|
|
3531
|
-
children: /* @__PURE__ */
|
|
3711
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3532
3712
|
href: "/templates",
|
|
3533
3713
|
variant: "default",
|
|
3534
3714
|
children: "Templates"
|
|
@@ -3537,25 +3717,25 @@ function TemplatesMarketingPage() {
|
|
|
3537
3717
|
]
|
|
3538
3718
|
}, undefined, true, undefined, this)
|
|
3539
3719
|
}, undefined, false, undefined, this),
|
|
3540
|
-
/* @__PURE__ */
|
|
3720
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3541
3721
|
tone: "muted",
|
|
3542
|
-
children: /* @__PURE__ */
|
|
3722
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3543
3723
|
gap: "lg",
|
|
3544
3724
|
children: [
|
|
3545
|
-
/* @__PURE__ */
|
|
3725
|
+
/* @__PURE__ */ jsxDEV21(VStack, {
|
|
3546
3726
|
gap: "sm",
|
|
3547
|
-
children: /* @__PURE__ */
|
|
3727
|
+
children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3548
3728
|
href: "/templates",
|
|
3549
3729
|
variant: "ghost",
|
|
3550
3730
|
children: "Browse all examples"
|
|
3551
3731
|
}, undefined, false, undefined, this)
|
|
3552
3732
|
}, undefined, false, undefined, this),
|
|
3553
|
-
/* @__PURE__ */
|
|
3733
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3554
3734
|
gap: "md",
|
|
3555
3735
|
align: "center",
|
|
3556
3736
|
justify: "between",
|
|
3557
3737
|
wrap: "wrap",
|
|
3558
|
-
children: /* @__PURE__ */
|
|
3738
|
+
children: /* @__PURE__ */ jsxDEV21(Input2, {
|
|
3559
3739
|
"aria-label": "Search templates and examples",
|
|
3560
3740
|
placeholder: "Search templates and examples…",
|
|
3561
3741
|
value: query,
|
|
@@ -3565,52 +3745,52 @@ function TemplatesMarketingPage() {
|
|
|
3565
3745
|
]
|
|
3566
3746
|
}, undefined, true, undefined, this)
|
|
3567
3747
|
}, undefined, false, undefined, this),
|
|
3568
|
-
/* @__PURE__ */
|
|
3748
|
+
/* @__PURE__ */ jsxDEV21(MarketingSection, {
|
|
3569
3749
|
tone: "default",
|
|
3570
|
-
children: /* @__PURE__ */
|
|
3750
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3571
3751
|
gap: "lg",
|
|
3572
|
-
children: /* @__PURE__ */
|
|
3752
|
+
children: /* @__PURE__ */ jsxDEV21(HStack, {
|
|
3573
3753
|
gap: "md",
|
|
3574
3754
|
wrap: "wrap",
|
|
3575
|
-
children: filtered.map((t) => /* @__PURE__ */
|
|
3755
|
+
children: filtered.map((t) => /* @__PURE__ */ jsxDEV21(MarketingCard, {
|
|
3576
3756
|
className: "w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]",
|
|
3577
3757
|
children: [
|
|
3578
|
-
/* @__PURE__ */
|
|
3758
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardHeader, {
|
|
3579
3759
|
children: [
|
|
3580
|
-
/* @__PURE__ */
|
|
3760
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardTitle, {
|
|
3581
3761
|
children: [
|
|
3582
3762
|
t.icon,
|
|
3583
3763
|
" ",
|
|
3584
3764
|
t.name
|
|
3585
3765
|
]
|
|
3586
3766
|
}, undefined, true, undefined, this),
|
|
3587
|
-
/* @__PURE__ */
|
|
3767
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardDescription, {
|
|
3588
3768
|
children: t.description
|
|
3589
3769
|
}, undefined, false, undefined, this)
|
|
3590
3770
|
]
|
|
3591
3771
|
}, undefined, true, undefined, this),
|
|
3592
|
-
/* @__PURE__ */
|
|
3593
|
-
children: /* @__PURE__ */
|
|
3772
|
+
/* @__PURE__ */ jsxDEV21(MarketingCardContent, {
|
|
3773
|
+
children: /* @__PURE__ */ jsxDEV21(VStack, {
|
|
3594
3774
|
gap: "md",
|
|
3595
3775
|
children: [
|
|
3596
|
-
/* @__PURE__ */
|
|
3776
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3597
3777
|
gap: "sm",
|
|
3598
3778
|
wrap: "wrap",
|
|
3599
|
-
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */
|
|
3779
|
+
children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3600
3780
|
href: `/templates?tag=${encodeURIComponent(tag)}`,
|
|
3601
3781
|
variant: "ghost",
|
|
3602
3782
|
children: tag
|
|
3603
3783
|
}, `${t.id}-${tag}`, false, undefined, this))
|
|
3604
3784
|
}, undefined, false, undefined, this),
|
|
3605
|
-
/* @__PURE__ */
|
|
3785
|
+
/* @__PURE__ */ jsxDEV21(HStack, {
|
|
3606
3786
|
gap: "sm",
|
|
3607
3787
|
justify: "between",
|
|
3608
3788
|
wrap: "wrap",
|
|
3609
3789
|
children: [
|
|
3610
|
-
/* @__PURE__ */
|
|
3790
|
+
/* @__PURE__ */ jsxDEV21(ButtonLinkToSandbox, {
|
|
3611
3791
|
templateId: t.id
|
|
3612
3792
|
}, undefined, false, undefined, this),
|
|
3613
|
-
/* @__PURE__ */
|
|
3793
|
+
/* @__PURE__ */ jsxDEV21(Button3, {
|
|
3614
3794
|
variant: "outline",
|
|
3615
3795
|
onClick: () => {
|
|
3616
3796
|
return;
|
|
@@ -3632,7 +3812,7 @@ function TemplatesMarketingPage() {
|
|
|
3632
3812
|
}, undefined, true, undefined, this);
|
|
3633
3813
|
}
|
|
3634
3814
|
function ButtonLinkToSandbox({ templateId }) {
|
|
3635
|
-
return /* @__PURE__ */
|
|
3815
|
+
return /* @__PURE__ */ jsxDEV21(ButtonLink, {
|
|
3636
3816
|
href: `/sandbox?template=${encodeURIComponent(templateId)}`,
|
|
3637
3817
|
variant: "default",
|
|
3638
3818
|
children: "Preview"
|