astro-tractstack 2.3.4 → 2.4.0

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.
Files changed (64) hide show
  1. package/bin/create-tractstack.js +38 -59
  2. package/dist/index.js +74 -40
  3. package/package.json +46 -9
  4. package/templates/custom/customHelpers.ts +45 -0
  5. package/templates/custom/minimal/codehooks.ts +13 -0
  6. package/templates/custom/shopify/Cart.tsx +2 -2
  7. package/templates/custom/shopify/CartIcon.tsx +1 -1
  8. package/templates/custom/shopify/CheckoutModal.tsx +3 -3
  9. package/templates/custom/shopify/ShopifyCartManager.tsx +3 -3
  10. package/templates/custom/shopify/ShopifyCheckout.tsx +1 -1
  11. package/templates/custom/shopify/ShopifyProductGrid.tsx +5 -5
  12. package/templates/custom/shopify/ShopifyServiceList.tsx +5 -5
  13. package/templates/custom/shopify/shopifyCustomHelper.ts +10 -0
  14. package/templates/{src/utils/customHelpers.ts → custom/shopify/shopifyHelpers.ts} +0 -74
  15. package/templates/custom/with-examples/codehooks.ts +15 -0
  16. package/templates/src/components/Header.astro +1 -1
  17. package/templates/src/components/codehooks/EpinetDurationSelector.tsx +38 -23
  18. package/templates/src/components/codehooks/EpinetTableView.tsx +5 -2
  19. package/templates/src/components/codehooks/EpinetWrapper.tsx +10 -5
  20. package/templates/src/components/codehooks/FeaturedArticle.astro +3 -3
  21. package/templates/src/components/codehooks/ListContent.astro +3 -3
  22. package/templates/src/components/codehooks/SearchWidget.tsx +1 -1
  23. package/templates/src/components/compositor/Node.tsx +13 -2
  24. package/templates/src/components/compositor/nodes/Pane.tsx +2 -14
  25. package/templates/src/components/edit/pane/AddPanePanel.tsx +3 -2
  26. package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +35 -14
  27. package/templates/src/components/edit/pane/ConfigPanePanel.tsx +1 -1
  28. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +2 -2
  29. package/templates/src/components/search/SearchResults.tsx +1 -1
  30. package/templates/src/components/search/SearchWrapper.tsx +1 -1
  31. package/templates/src/components/storykeep/Dashboard_Analytics.tsx +8 -4
  32. package/templates/src/components/storykeep/controls/content/ContentBrowser.tsx +5 -2
  33. package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +1 -1
  34. package/templates/src/components/storykeep/shopify/ShopifyDashboard_Sales.tsx +1 -1
  35. package/templates/src/components/storykeep/state/FetchAnalytics.tsx +8 -4
  36. package/templates/src/components/storykeep/widgets/Wizard.tsx +4 -2
  37. package/templates/src/lib/codeHookHelper.ts +156 -0
  38. package/templates/src/lib/resources.ts +41 -0
  39. package/templates/src/lib/storyData.ts +1 -2
  40. package/templates/src/pages/[...slug]/edit.astro +3 -3
  41. package/templates/src/pages/[...slug].astro +76 -70
  42. package/templates/src/pages/codehooks/[...hookId].astro +18 -0
  43. package/templates/src/pages/codehooks/bunny-video.astro +9 -0
  44. package/templates/src/pages/codehooks/custom-hero.astro +6 -0
  45. package/templates/src/pages/codehooks/epinet.astro +15 -0
  46. package/templates/src/pages/codehooks/featured-article.astro +13 -0
  47. package/templates/src/pages/codehooks/get-crafting.astro +8 -0
  48. package/templates/src/pages/codehooks/list-content.astro +13 -0
  49. package/templates/src/pages/codehooks/search-widget.astro +13 -0
  50. package/templates/src/pages/codehooks/shopify-product-grid.astro +25 -0
  51. package/templates/src/pages/codehooks/shopify-service-list.astro +25 -0
  52. package/templates/src/pages/context/[...contextSlug]/edit.astro +3 -3
  53. package/templates/src/pages/context/[...contextSlug].astro +47 -10
  54. package/templates/src/pages/sandbox.astro +3 -14
  55. package/templates/src/stores/analytics.ts +77 -107
  56. package/utils/inject-files.ts +76 -41
  57. package/templates/custom/minimal/CodeHook.astro +0 -72
  58. package/templates/custom/with-examples/CodeHook.astro +0 -81
  59. package/templates/custom/with-examples/ProductCard.astro +0 -29
  60. package/templates/custom/with-examples/ProductCardWrapper.astro +0 -43
  61. package/templates/custom/with-examples/ProductGrid.astro +0 -64
  62. package/templates/src/components/codehooks/ProductCardSetup.tsx +0 -157
  63. package/templates/src/components/codehooks/ProductGridSetup.tsx +0 -279
  64. /package/templates/{src/utils/booking → custom/shopify}/appointmentMode.ts +0 -0
@@ -1,6 +1,12 @@
1
1
  ---
2
2
  import Layout from '@/layouts/Layout.astro';
3
3
  import { getBrandConfig } from '@/utils/api/brandConfig';
4
+ import { getFullContentMap } from '@/stores/analytics';
5
+ import {
6
+ buildCodeHookBladePath,
7
+ fetchCodeHookBladeHtml,
8
+ resolveSSRFetchOrigin,
9
+ } from '@/lib/codeHookHelper';
4
10
  import { handleFailedResponse } from '@/utils/backend';
5
11
  import { preHealthCheck } from '@/utils/backend';
6
12
 
@@ -56,6 +62,8 @@ try {
56
62
 
57
63
  const paneId = contextPaneData.id;
58
64
  const paneTitle = contextPaneData.title || 'Context';
65
+ const codeHookTarget = contextPaneData.codeHookTarget;
66
+ const codeHookOptions = contextPaneData.codeHookPayload?.options;
59
67
 
60
68
  // Get rendered fragment for the context pane
61
69
  let fragmentData = '';
@@ -94,6 +102,23 @@ const brandConfig = await getBrandConfig(tenantId);
94
102
  if (!brandConfig.SITE_INIT) {
95
103
  return Astro.redirect('/storykeep');
96
104
  }
105
+
106
+ // Warm the in-process content-map store before SSR-fetching the codehook blade.
107
+ await getFullContentMap(tenantId);
108
+
109
+ let codeHookBladeHtml = '';
110
+ if (codeHookTarget) {
111
+ const bladePath = buildCodeHookBladePath(codeHookTarget, {
112
+ paneId,
113
+ tenantId,
114
+ optionsStr: codeHookOptions || '',
115
+ });
116
+ codeHookBladeHtml = await fetchCodeHookBladeHtml(
117
+ bladePath,
118
+ Astro.request,
119
+ resolveSSRFetchOrigin(Astro.url, brandConfig.SITE_URL)
120
+ );
121
+ }
97
122
  ---
98
123
 
99
124
  <Layout
@@ -108,16 +133,28 @@ if (!brandConfig.SITE_INIT) {
108
133
  storyfragmentId={paneId}
109
134
  >
110
135
  <main id="main-content" class="w-full">
111
- <div
112
- id={`pane-${paneId}`}
113
- data-pane-id={paneId}
114
- class="context-pane-container"
115
- hx-get={`/api/v1/fragments/panes/${paneId}`}
116
- hx-trigger="refresh"
117
- hx-swap="innerHTML scroll:none"
118
- >
119
- <Fragment set:html={fragmentData} />
120
- </div>
136
+ {
137
+ codeHookTarget ? (
138
+ <div
139
+ id={`pane-${paneId}`}
140
+ data-pane-id={paneId}
141
+ class="context-pane-container"
142
+ >
143
+ <Fragment set:html={codeHookBladeHtml} />
144
+ </div>
145
+ ) : (
146
+ <div
147
+ id={`pane-${paneId}`}
148
+ data-pane-id={paneId}
149
+ class="context-pane-container"
150
+ hx-get={`/api/v1/fragments/panes/${paneId}`}
151
+ hx-trigger="refresh"
152
+ hx-swap="innerHTML scroll:none"
153
+ >
154
+ <Fragment set:html={fragmentData} />
155
+ </div>
156
+ )
157
+ }
121
158
 
122
159
  <div class="py-12 text-center text-2xl md:text-3xl">
123
160
  <button
@@ -5,9 +5,7 @@ import Layout from '@/layouts/Layout.astro';
5
5
  import Header from '@/components/Header.astro';
6
6
  import { getFullContentMap } from '@/stores/analytics';
7
7
  import { getBrandConfig } from '@/utils/api/brandConfig';
8
- import CodeHook, {
9
- components as codeHookComponents,
10
- } from '@/custom/CodeHook.astro';
8
+ import { availableCodeHookIds } from '@/custom/codehooks';
11
9
  import StoryKeepHeader from '@/components/edit/Header';
12
10
  import StoryKeepToolBar from '@/components/edit/ToolBar';
13
11
  import StoryKeepToolMode from '@/components/edit/ToolMode';
@@ -64,15 +62,6 @@ const sandboxToken = `${timestamp}.${signature}`;
64
62
  isStoryKeep={true}
65
63
  isEditor={true}
66
64
  >
67
- <CodeHook
68
- target="get-tractstack"
69
- options={{
70
- params: {
71
- options: JSON.stringify({ isEmbedded: false }),
72
- },
73
- }}
74
- />
75
-
76
65
  <Header
77
66
  title={title}
78
67
  slug="sandbox"
@@ -115,7 +104,7 @@ const sandboxToken = `${timestamp}.${signature}`;
115
104
  fullContentMap={fullContentMap}
116
105
  fullCanonicalURL="/sandbox"
117
106
  urlParams={urlParams}
118
- availableCodeHooks={Object.keys(codeHookComponents)}
107
+ availableCodeHooks={availableCodeHookIds}
119
108
  isSandboxMode={true}
120
109
  sandboxToken={sandboxToken}
121
110
  client:only="react"
@@ -137,7 +126,7 @@ const sandboxToken = `${timestamp}.${signature}`;
137
126
 
138
127
  <div class="pointer-events-auto max-h-full">
139
128
  <SettingsPanel
140
- availableCodeHooks={Object.keys(codeHookComponents)}
129
+ availableCodeHooks={availableCodeHookIds}
141
130
  client:only="react"
142
131
  />
143
132
  </div>
@@ -1,4 +1,4 @@
1
- import { atom } from 'nanostores';
1
+ import { atom, computed } from 'nanostores';
2
2
  import { TractStackAPI } from '@/utils/api';
3
3
 
4
4
  interface AvailableFilter {
@@ -11,43 +11,38 @@ export interface AppliedFilter {
11
11
  value: string;
12
12
  }
13
13
 
14
- const tenantEpinetCustomFilters = atom<
15
- Record<
14
+ export interface EpinetFiltersState {
15
+ enabled: boolean;
16
+ visitorType: 'all' | 'anonymous' | 'known';
17
+ selectedUserId: string | null;
18
+ startTimeUTC: string | null;
19
+ endTimeUTC: string | null;
20
+ userCounts: Array<{ id: string; count: number; isKnown: boolean }>;
21
+ hourlyNodeActivity: Record<
16
22
  string,
17
- {
18
- enabled: boolean;
19
- visitorType: 'all' | 'anonymous' | 'known';
20
- selectedUserId: string | null;
21
- startTimeUTC: string | null;
22
- endTimeUTC: string | null;
23
- userCounts: Array<{ id: string; count: number; isKnown: boolean }>;
24
- hourlyNodeActivity: Record<
25
- string,
26
- Record<
27
- string,
28
- {
29
- events: Record<string, number>;
30
- visitorIds: string[];
31
- }
32
- >
33
- >;
34
- availableFilters: AvailableFilter[];
35
- appliedFilters: AppliedFilter[];
36
- }
37
- >
38
- >({});
23
+ Record<
24
+ string,
25
+ {
26
+ events: Record<string, number>;
27
+ visitorIds: string[];
28
+ }
29
+ >
30
+ >;
31
+ availableFilters: AvailableFilter[];
32
+ appliedFilters: AppliedFilter[];
33
+ }
39
34
 
40
- const tenantFullContentMaps = atom<
41
- Record<
42
- string,
43
- {
44
- data: any[];
45
- lastUpdated: number;
46
- }
47
- >
48
- >({});
35
+ export interface TenantFullContentMapState {
36
+ data: any[];
37
+ lastUpdated: number;
38
+ }
39
+
40
+ const tenantEpinetCustomFilters = atom<Record<string, EpinetFiltersState>>({});
41
+
42
+ const tenantFullContentMaps = atom<Record<string, TenantFullContentMapState>>(
43
+ {}
44
+ );
49
45
 
50
- // Helper to get current tenant ID
51
46
  function getCurrentTenantId(): string {
52
47
  const resolvedTenantId =
53
48
  (typeof window !== 'undefined' && window.TRACTSTACK_CONFIG?.tenantId) ||
@@ -56,9 +51,9 @@ function getCurrentTenantId(): string {
56
51
  return resolvedTenantId;
57
52
  }
58
53
 
59
- const defaultEpinetFilters = {
54
+ const defaultEpinetFilters: EpinetFiltersState = {
60
55
  enabled: false,
61
- visitorType: 'all' as 'all' | 'anonymous' | 'known',
56
+ visitorType: 'all',
62
57
  selectedUserId: null,
63
58
  startTimeUTC: null,
64
59
  endTimeUTC: null,
@@ -68,81 +63,56 @@ const defaultEpinetFilters = {
68
63
  appliedFilters: [],
69
64
  };
70
65
 
71
- const createEpinetFiltersStore = () => {
72
- const store = {
73
- get: () => {
74
- const tenantId = getCurrentTenantId();
75
- return tenantEpinetCustomFilters.get()[tenantId] || defaultEpinetFilters;
76
- },
77
-
78
- set: (tenantId: string, updates: any) => {
79
- const currentFilters =
80
- tenantEpinetCustomFilters.get()[tenantId] || defaultEpinetFilters;
81
- tenantEpinetCustomFilters.set({
82
- ...tenantEpinetCustomFilters.get(),
83
- [tenantId]: {
84
- ...currentFilters,
85
- ...updates,
86
- },
87
- });
88
- },
89
-
90
- subscribe: (callback: (value: any) => void) => {
91
- const tenantId = getCurrentTenantId();
92
- return tenantEpinetCustomFilters.subscribe((filters) => {
93
- callback(filters[tenantId] || defaultEpinetFilters);
94
- });
95
- },
96
- lc: 0,
97
- listen: function (callback: any) {
98
- return this.subscribe(callback);
99
- },
100
- notify: function () {},
101
- off: function () {},
102
- get value() {
103
- return this.get();
104
- },
105
- };
106
-
107
- return store;
108
- };
109
-
110
- const createFullContentMapStore = () => {
111
- const store = {
112
- get: () => {
113
- const tenantId = getCurrentTenantId();
114
- return tenantFullContentMaps.get()[tenantId] || null;
115
- },
66
+ export const epinetCustomFilters = computed(
67
+ tenantEpinetCustomFilters,
68
+ (filters) => {
69
+ const tenantId = getCurrentTenantId();
70
+ return filters[tenantId] || defaultEpinetFilters;
71
+ }
72
+ );
116
73
 
117
- set: (tenantId: string, data: { data: any[]; lastUpdated: number }) => {
118
- tenantFullContentMaps.set({
119
- ...tenantFullContentMaps.get(),
120
- [tenantId]: data,
121
- });
122
- },
74
+ export function getEpinetCustomFilters(): EpinetFiltersState {
75
+ return epinetCustomFilters.get();
76
+ }
123
77
 
124
- subscribe: (callback: (value: any) => void) => {
125
- const tenantId = getCurrentTenantId();
126
- return tenantFullContentMaps.subscribe((maps) => {
127
- callback(maps[tenantId] || null);
128
- });
129
- },
130
- lc: 0,
131
- listen: function (callback: any) {
132
- return this.subscribe(callback);
133
- },
134
- notify: function () {},
135
- off: function () {},
136
- get value() {
137
- return this.get();
78
+ export function setEpinetCustomFilters(
79
+ tenantId: string,
80
+ updates: Partial<EpinetFiltersState>
81
+ ): void {
82
+ const currentFilters =
83
+ tenantEpinetCustomFilters.get()[tenantId] || defaultEpinetFilters;
84
+ tenantEpinetCustomFilters.set({
85
+ ...tenantEpinetCustomFilters.get(),
86
+ [tenantId]: {
87
+ ...currentFilters,
88
+ ...updates,
138
89
  },
139
- };
90
+ });
91
+ }
140
92
 
141
- return store;
142
- };
93
+ export const fullContentMapStore = computed(tenantFullContentMaps, (maps) => {
94
+ const tenantId = getCurrentTenantId();
95
+ return maps[tenantId] || null;
96
+ });
97
+
98
+ export function setTenantFullContentMap(
99
+ tenantId: string,
100
+ data: TenantFullContentMapState
101
+ ): void {
102
+ tenantFullContentMaps.set({
103
+ ...tenantFullContentMaps.get(),
104
+ [tenantId]: data,
105
+ });
106
+ }
143
107
 
144
- export const epinetCustomFilters = createEpinetFiltersStore();
145
- export const fullContentMapStore = createFullContentMapStore();
108
+ // Synchronous in-process accessor for the warm content-map atom, keyed on an
109
+ // explicit tenantId (unlike fullContentMapStore.get(), which keys on
110
+ // getCurrentTenantId() and resolves the wrong tenant during SSR sub-requests).
111
+ // Returns [] on a cold miss; codehook blades fall back to the async
112
+ // getFullContentMap(tenantId) when this is empty.
113
+ export function getCachedFullContentMap(tenantId: string): any[] {
114
+ return tenantFullContentMaps.get()[tenantId]?.data ?? [];
115
+ }
146
116
 
147
117
  export async function getFullContentMap(tenantId: string): Promise<any[]> {
148
118
  const api = new TractStackAPI(tenantId);
@@ -1518,18 +1518,6 @@ export async function injectTemplateFiles(
1518
1518
  ),
1519
1519
  dest: 'src/components/codehooks/ListContentSetup.tsx',
1520
1520
  },
1521
- {
1522
- src: resolve(
1523
- '../templates/src/components/codehooks/ProductCardSetup.tsx'
1524
- ),
1525
- dest: 'src/components/codehooks/ProductCardSetup.tsx',
1526
- },
1527
- {
1528
- src: resolve(
1529
- '../templates/src/components/codehooks/ProductGridSetup.tsx'
1530
- ),
1531
- dest: 'src/components/codehooks/ProductGridSetup.tsx',
1532
- },
1533
1521
  {
1534
1522
  src: resolve(
1535
1523
  '../templates/src/components/codehooks/BunnyVideoWrapper.astro'
@@ -1541,6 +1529,32 @@ export async function injectTemplateFiles(
1541
1529
  dest: 'src/components/codehooks/BunnyVideoSetup.tsx',
1542
1530
  },
1543
1531
 
1532
+ // CodeHook Blades (partial routes; core hooks overwritable)
1533
+ {
1534
+ src: resolve('../templates/src/pages/codehooks/featured-article.astro'),
1535
+ dest: 'src/pages/codehooks/featured-article.astro',
1536
+ },
1537
+ {
1538
+ src: resolve('../templates/src/pages/codehooks/list-content.astro'),
1539
+ dest: 'src/pages/codehooks/list-content.astro',
1540
+ },
1541
+ {
1542
+ src: resolve('../templates/src/pages/codehooks/search-widget.astro'),
1543
+ dest: 'src/pages/codehooks/search-widget.astro',
1544
+ },
1545
+ {
1546
+ src: resolve('../templates/src/pages/codehooks/bunny-video.astro'),
1547
+ dest: 'src/pages/codehooks/bunny-video.astro',
1548
+ },
1549
+ {
1550
+ src: resolve('../templates/src/pages/codehooks/epinet.astro'),
1551
+ dest: 'src/pages/codehooks/epinet.astro',
1552
+ },
1553
+ {
1554
+ src: resolve('../templates/src/pages/codehooks/[...hookId].astro'),
1555
+ dest: 'src/pages/codehooks/[...hookId].astro',
1556
+ },
1557
+
1544
1558
  // Widget Components
1545
1559
  {
1546
1560
  src: resolve('../templates/src/components/widgets/Impression.tsx'),
@@ -1568,6 +1582,10 @@ export async function injectTemplateFiles(
1568
1582
  src: resolve('../templates/src/lib/resources.ts'),
1569
1583
  dest: 'src/lib/resources.ts',
1570
1584
  },
1585
+ {
1586
+ src: resolve('../templates/src/lib/codeHookHelper.ts'),
1587
+ dest: 'src/lib/codeHookHelper.ts',
1588
+ },
1571
1589
 
1572
1590
  // Client Scripts
1573
1591
  {
@@ -2357,15 +2375,6 @@ export async function injectTemplateFiles(
2357
2375
  },
2358
2376
 
2359
2377
  // Custom Components (Conditional)
2360
- {
2361
- src: resolve(
2362
- config?.includeExamples
2363
- ? '../templates/custom/with-examples/CodeHook.astro'
2364
- : '../templates/custom/minimal/CodeHook.astro'
2365
- ),
2366
- dest: 'src/custom/CodeHook.astro',
2367
- protected: true,
2368
- },
2369
2378
  {
2370
2379
  src: resolve(
2371
2380
  config?.includeExamples
@@ -2376,22 +2385,28 @@ export async function injectTemplateFiles(
2376
2385
  protected: true,
2377
2386
  },
2378
2387
  {
2379
- src: resolve(
2380
- config?.includeExamples
2381
- ? '../templates/custom/with-examples/HeaderWidget.astro'
2382
- : '../templates/custom/minimal/HeaderWidget.astro'
2383
- ),
2388
+ src: resolve('../templates/custom/minimal/HeaderWidget.astro'),
2384
2389
  dest: 'src/custom/HeaderWidget.astro',
2385
2390
  protected: true,
2386
2391
  },
2387
2392
  {
2388
- src: resolve('../templates/src/utils/customHelpers.ts'),
2389
- dest: 'src/utils/customHelpers.ts',
2393
+ src: resolve('../templates/custom/customHelpers.ts'),
2394
+ dest: 'src/custom/customHelpers.ts',
2395
+ protected: true,
2396
+ },
2397
+ {
2398
+ src: resolve('../templates/custom/shopify/shopifyCustomHelper.ts'),
2399
+ dest: 'src/custom/shopify/shopifyCustomHelper.ts',
2390
2400
  protected: true,
2391
2401
  },
2392
2402
  {
2393
- src: resolve('../templates/src/utils/booking/appointmentMode.ts'),
2394
- dest: 'src/utils/booking/appointmentMode.ts',
2403
+ src: resolve('../templates/custom/shopify/shopifyHelpers.ts'),
2404
+ dest: 'src/custom/shopify/shopifyHelpers.ts',
2405
+ protected: true,
2406
+ },
2407
+ {
2408
+ src: resolve('../templates/custom/shopify/appointmentMode.ts'),
2409
+ dest: 'src/custom/shopify/appointmentMode.ts',
2395
2410
  protected: true,
2396
2411
  },
2397
2412
  {
@@ -2440,6 +2455,33 @@ export async function injectTemplateFiles(
2440
2455
  protected: true,
2441
2456
  },
2442
2457
 
2458
+ // CodeHook manifest (frontend capability list; hand-maintained, protected)
2459
+ {
2460
+ src: resolve(
2461
+ config?.includeExamples
2462
+ ? '../templates/custom/with-examples/codehooks.ts'
2463
+ : '../templates/custom/minimal/codehooks.ts'
2464
+ ),
2465
+ dest: 'src/custom/codehooks.ts',
2466
+ protected: true,
2467
+ },
2468
+
2469
+ // CodeHook Blades (userland hooks; protected once installed)
2470
+ {
2471
+ src: resolve(
2472
+ '../templates/src/pages/codehooks/shopify-product-grid.astro'
2473
+ ),
2474
+ dest: 'src/pages/codehooks/shopify-product-grid.astro',
2475
+ protected: true,
2476
+ },
2477
+ {
2478
+ src: resolve(
2479
+ '../templates/src/pages/codehooks/shopify-service-list.astro'
2480
+ ),
2481
+ dest: 'src/pages/codehooks/shopify-service-list.astro',
2482
+ protected: true,
2483
+ },
2484
+
2443
2485
  // Example Components (Conditional)
2444
2486
  ...(config?.includeExamples
2445
2487
  ? [
@@ -2456,20 +2498,13 @@ export async function injectTemplateFiles(
2456
2498
  protected: true,
2457
2499
  },
2458
2500
  {
2459
- src: resolve('../templates/custom/with-examples/ProductGrid.astro'),
2460
- dest: 'src/custom/ProductGrid.astro',
2461
- protected: true,
2462
- },
2463
- {
2464
- src: resolve(
2465
- '../templates/custom/with-examples/ProductCardWrapper.astro'
2466
- ),
2467
- dest: 'src/custom/ProductCardWrapper.astro',
2501
+ src: resolve('../templates/src/pages/codehooks/custom-hero.astro'),
2502
+ dest: 'src/pages/codehooks/custom-hero.astro',
2468
2503
  protected: true,
2469
2504
  },
2470
2505
  {
2471
- src: resolve('../templates/custom/with-examples/ProductCard.astro'),
2472
- dest: 'src/custom/ProductCard.astro',
2506
+ src: resolve('../templates/src/pages/codehooks/get-crafting.astro'),
2507
+ dest: 'src/pages/codehooks/get-crafting.astro',
2473
2508
  protected: true,
2474
2509
  },
2475
2510
  {
@@ -1,72 +0,0 @@
1
- ---
2
- import FeaturedArticle from '@/components/codehooks/FeaturedArticle.astro';
3
- import ListContent from '@/components/codehooks/ListContent.astro';
4
- import SearchWidget from '@/components/codehooks/SearchWidget.tsx';
5
- import BunnyVideoWrapper from '@/components/codehooks/BunnyVideoWrapper.astro';
6
- import EpinetWrapper from '@/components/codehooks/EpinetWrapper';
7
- import ShopifyProductGrid from '@/custom/shopify/ShopifyProductGrid';
8
- import ShopifyServiceList from '@/custom/shopify/ShopifyServiceList';
9
- import type { FullContentMapItem } from '@/types/tractstack';
10
- import type { ResourceNode } from '@/types/compositorTypes';
11
- // import CustomHero from './CustomHero.astro';
12
- // Uncomment to add custom components
13
-
14
- export interface Props {
15
- target: string;
16
- paneId: string;
17
- fullContentMap: FullContentMapItem[];
18
- resourcesPayload?: Record<string, ResourceNode[]>;
19
- options?: {
20
- params?: {
21
- options?: string;
22
- };
23
- };
24
- }
25
-
26
- const { target, options, fullContentMap, resourcesPayload = {} } = Astro.props;
27
-
28
- export const components = {
29
- 'featured-article': true,
30
- 'featured-content': true,
31
- 'list-content': true,
32
- 'search-widget': true,
33
- 'bunny-video': import.meta.env.PUBLIC_ENABLE_BUNNY === 'true',
34
- epinet: true,
35
- 'shopify-product-grid': true,
36
- 'shopify-service-list': true,
37
- // "custom-hero": true, // Uncomment when you create CustomHero.astro
38
- };
39
- ---
40
-
41
- {
42
- target === 'list-content' ? (
43
- <ListContent options={options} contentMap={fullContentMap} />
44
- ) : target === 'featured-article' ? (
45
- <FeaturedArticle options={options} contentMap={fullContentMap} />
46
- ) : target === 'search-widget' ? (
47
- <SearchWidget fullContentMap={fullContentMap} client:load />
48
- ) : target === 'bunny-video' && import.meta.env.PUBLIC_ENABLE_BUNNY ? (
49
- <BunnyVideoWrapper options={options} />
50
- ) : target === 'epinet' ? (
51
- <EpinetWrapper fullContentMap={fullContentMap} client:only="react" />
52
- ) : target === 'shopify-product-grid' ? (
53
- <ShopifyProductGrid
54
- options={options}
55
- resources={resourcesPayload}
56
- client:only="react"
57
- />
58
- ) : target === 'shopify-service-list' ? (
59
- <ShopifyServiceList
60
- options={options}
61
- resources={resourcesPayload}
62
- client:only="react"
63
- />
64
- ) : (
65
- /* : target === "custom-hero" ? (
66
- <CustomHero />
67
- ) */
68
- <div class="rounded-lg bg-gray-50 p-8 text-center">
69
- <p class="text-gray-600">CodeHook target "{target}" not found</p>
70
- </div>
71
- )
72
- }
@@ -1,81 +0,0 @@
1
- ---
2
- import CustomHero from './CustomHero.astro';
3
- import SearchWidget from '@/components/codehooks/SearchWidget.tsx';
4
- import FeaturedArticle from '@/components/codehooks/FeaturedArticle.astro';
5
- import ListContent from '@/components/codehooks/ListContent.astro';
6
- import BunnyVideoWrapper from '@/components/codehooks/BunnyVideoWrapper.astro';
7
- import EpinetWrapper from '@/components/codehooks/EpinetWrapper';
8
- import ProductCardWrapper from './ProductCardWrapper.astro';
9
- import ProductGrid from './ProductGrid.astro';
10
- import SandboxLauncher from './SandboxLauncher';
11
- import ShopifyProductGrid from '@/custom/shopify/ShopifyProductGrid';
12
- import ShopifyServiceList from '@/custom/shopify/ShopifyServiceList';
13
- import type { FullContentMapItem } from '@/types/tractstack';
14
- import type { ResourceNode } from '@/types/compositorTypes';
15
-
16
- export interface Props {
17
- target: string;
18
- paneId: string;
19
- fullContentMap: FullContentMapItem[];
20
- resourcesPayload?: Record<string, ResourceNode[]>;
21
- options?: {
22
- params?: {
23
- options?: string;
24
- };
25
- };
26
- }
27
-
28
- const { target, options, fullContentMap, resourcesPayload = {} } = Astro.props;
29
-
30
- export const components = {
31
- 'custom-hero': true,
32
- 'featured-article': true,
33
- 'list-content': true,
34
- 'search-widget': true,
35
- 'product-card': true,
36
- 'product-grid': true,
37
- 'get-crafting': true,
38
- 'bunny-video': import.meta.env.PUBLIC_ENABLE_BUNNY === 'true',
39
- epinet: true,
40
- 'shopify-product-grid': true,
41
- 'shopify-service-list': true,
42
- };
43
- ---
44
-
45
- {
46
- target === 'product-card' ? (
47
- <ProductCardWrapper options={options} resourcesPayload={resourcesPayload} />
48
- ) : target === 'product-grid' ? (
49
- <ProductGrid options={options} resourcesPayload={resourcesPayload} />
50
- ) : target === 'list-content' ? (
51
- <ListContent options={options} contentMap={fullContentMap} />
52
- ) : target === 'featured-article' ? (
53
- <FeaturedArticle options={options} contentMap={fullContentMap} />
54
- ) : target === 'search-widget' ? (
55
- <SearchWidget fullContentMap={fullContentMap} client:load />
56
- ) : target === 'bunny-video' && import.meta.env.PUBLIC_ENABLE_BUNNY ? (
57
- <BunnyVideoWrapper options={options} />
58
- ) : target === 'get-crafting' ? (
59
- <SandboxLauncher client:only="react" />
60
- ) : target === 'custom-hero' ? (
61
- <CustomHero />
62
- ) : target === 'epinet' ? (
63
- <EpinetWrapper fullContentMap={fullContentMap} client:only="react" />
64
- ) : target === 'shopify-product-grid' ? (
65
- <ShopifyProductGrid
66
- options={options}
67
- resources={resourcesPayload}
68
- client:only="react"
69
- />
70
- ) : target === 'shopify-service-list' ? (
71
- <ShopifyServiceList
72
- options={options}
73
- resources={resourcesPayload}
74
- client:only="react"
75
- />
76
- ) : (
77
- <div class="rounded-lg bg-gray-50 p-8 text-center">
78
- <p class="text-gray-600">CodeHook target "{target}" not found</p>
79
- </div>
80
- )
81
- }