astro-tractstack 2.3.5 → 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.
- package/bin/create-tractstack.js +38 -59
- package/dist/index.js +60 -36
- package/package.json +46 -9
- package/templates/custom/minimal/codehooks.ts +13 -0
- package/templates/custom/shopify/ShopifyProductGrid.tsx +4 -4
- package/templates/custom/shopify/ShopifyServiceList.tsx +4 -4
- package/templates/custom/with-examples/codehooks.ts +15 -0
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +38 -23
- package/templates/src/components/codehooks/EpinetTableView.tsx +5 -2
- package/templates/src/components/codehooks/EpinetWrapper.tsx +10 -5
- package/templates/src/components/codehooks/FeaturedArticle.astro +3 -3
- package/templates/src/components/codehooks/ListContent.astro +3 -3
- package/templates/src/components/compositor/Node.tsx +13 -2
- package/templates/src/components/compositor/nodes/Pane.tsx +2 -14
- package/templates/src/components/edit/pane/AddPanePanel.tsx +3 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +35 -14
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +1 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +2 -2
- package/templates/src/components/storykeep/Dashboard_Analytics.tsx +8 -4
- package/templates/src/components/storykeep/controls/content/ContentBrowser.tsx +5 -2
- package/templates/src/components/storykeep/state/FetchAnalytics.tsx +8 -4
- package/templates/src/components/storykeep/widgets/Wizard.tsx +4 -2
- package/templates/src/lib/codeHookHelper.ts +156 -0
- package/templates/src/lib/resources.ts +41 -0
- package/templates/src/lib/storyData.ts +1 -2
- package/templates/src/pages/[...slug]/edit.astro +3 -3
- package/templates/src/pages/[...slug].astro +76 -70
- package/templates/src/pages/codehooks/[...hookId].astro +18 -0
- package/templates/src/pages/codehooks/bunny-video.astro +9 -0
- package/templates/src/pages/codehooks/custom-hero.astro +6 -0
- package/templates/src/pages/codehooks/epinet.astro +15 -0
- package/templates/src/pages/codehooks/featured-article.astro +13 -0
- package/templates/src/pages/codehooks/get-crafting.astro +8 -0
- package/templates/src/pages/codehooks/list-content.astro +13 -0
- package/templates/src/pages/codehooks/search-widget.astro +13 -0
- package/templates/src/pages/codehooks/shopify-product-grid.astro +25 -0
- package/templates/src/pages/codehooks/shopify-service-list.astro +25 -0
- package/templates/src/pages/context/[...contextSlug]/edit.astro +3 -3
- package/templates/src/pages/context/[...contextSlug].astro +47 -10
- package/templates/src/pages/sandbox.astro +3 -14
- package/templates/src/stores/analytics.ts +77 -107
- package/utils/inject-files.ts +62 -37
- package/templates/custom/minimal/CodeHook.astro +0 -72
- package/templates/custom/with-examples/CodeHook.astro +0 -81
- package/templates/custom/with-examples/ProductCard.astro +0 -29
- package/templates/custom/with-examples/ProductCardWrapper.astro +0 -43
- package/templates/custom/with-examples/ProductGrid.astro +0 -64
- package/templates/src/components/codehooks/ProductCardSetup.tsx +0 -157
- package/templates/src/components/codehooks/ProductGridSetup.tsx +0 -279
package/bin/create-tractstack.js
CHANGED
|
@@ -7,14 +7,33 @@ import {
|
|
|
7
7
|
writeFileSync,
|
|
8
8
|
existsSync,
|
|
9
9
|
} from 'fs';
|
|
10
|
-
import { resolve } from 'path';
|
|
10
|
+
import { dirname, resolve } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
11
12
|
import { homedir } from 'os';
|
|
12
13
|
import { execSync } from 'child_process';
|
|
13
14
|
import prompts from 'prompts';
|
|
14
15
|
import kleur from 'kleur';
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
|
|
19
|
+
function loadInstallManifest() {
|
|
20
|
+
const pkg = JSON.parse(
|
|
21
|
+
readFileSync(resolve(__dirname, '../package.json'), 'utf-8')
|
|
22
|
+
);
|
|
23
|
+
const manifest = pkg.tractstackInstall;
|
|
24
|
+
if (!manifest?.dependencies) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
'astro-tractstack package.json is missing tractstackInstall.dependencies'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return manifest;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function formatPackageSpecs(deps) {
|
|
33
|
+
return Object.entries(deps)
|
|
34
|
+
.map(([name, version]) => (version ? `${name}@${version}` : name))
|
|
35
|
+
.join(' ');
|
|
36
|
+
}
|
|
18
37
|
|
|
19
38
|
// Detect package manager
|
|
20
39
|
function detectPackageManager() {
|
|
@@ -332,67 +351,27 @@ PUBLIC_ENABLE_BUNNY="${finalResponses.enableBunny ? 'true' : 'false'}"
|
|
|
332
351
|
packageManager === 'pnpm' ? 'pnpm add' : `${packageManager} add`;
|
|
333
352
|
|
|
334
353
|
console.log(kleur.cyan('\nInstalling dependencies...'));
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
);
|
|
341
|
-
console.log(kleur.green('✅ React and Node adapter installed'));
|
|
342
|
-
|
|
343
|
-
// Install core dependencies
|
|
344
|
-
execSync(
|
|
345
|
-
`${addCommand} @nanostores/react@^1.0.0 nanostores@^1.0.1 @nanostores/persistent ulid@^3.0.1`,
|
|
346
|
-
{
|
|
347
|
-
stdio: 'inherit',
|
|
348
|
-
}
|
|
349
|
-
);
|
|
350
|
-
console.log(kleur.green('✅ State management installed'));
|
|
351
|
-
|
|
352
|
-
// Install UI components
|
|
353
|
-
execSync(
|
|
354
|
-
`${addCommand} @ark-ui/react@^5.30.0 @heroicons/react@^2.1.1 @internationalized/date@${INTL_DATE_VERSION}`,
|
|
355
|
-
{
|
|
356
|
-
stdio: 'inherit',
|
|
357
|
-
}
|
|
358
|
-
);
|
|
359
|
-
console.log(kleur.green('✅ UI components installed'));
|
|
360
|
-
|
|
361
|
-
// Install visualization dependencies
|
|
362
|
-
execSync(
|
|
363
|
-
`${addCommand} d3@^7.9.0 d3-sankey@^0.12.3 recharts@^3.1.2 player.js@^0.1.0 tinycolor2@^1.6.0 html-to-image@^1.11.13`,
|
|
364
|
-
{
|
|
365
|
-
stdio: 'inherit',
|
|
366
|
-
}
|
|
367
|
-
);
|
|
368
|
-
console.log(kleur.green('✅ Visualization dependencies installed'));
|
|
354
|
+
const installManifest = loadInstallManifest();
|
|
355
|
+
const dependencySpecs = formatPackageSpecs(installManifest.dependencies);
|
|
356
|
+
const devDependencySpecs = formatPackageSpecs(
|
|
357
|
+
installManifest.devDependencies || {}
|
|
358
|
+
);
|
|
369
359
|
|
|
370
|
-
|
|
371
|
-
execSync(
|
|
372
|
-
|
|
373
|
-
{ stdio: 'inherit' }
|
|
374
|
-
);
|
|
375
|
-
console.log(kleur.green('✅ Additional dependencies installed'));
|
|
360
|
+
try {
|
|
361
|
+
execSync(`${addCommand} ${dependencySpecs}`, { stdio: 'inherit' });
|
|
362
|
+
console.log(kleur.green('✅ TractStack dependencies installed'));
|
|
376
363
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
);
|
|
382
|
-
console.log(kleur.green('✅ Dev dependencies installed'));
|
|
364
|
+
if (devDependencySpecs) {
|
|
365
|
+
execSync(`${addCommand} -D ${devDependencySpecs}`, { stdio: 'inherit' });
|
|
366
|
+
console.log(kleur.green('✅ Dev dependencies installed'));
|
|
367
|
+
}
|
|
383
368
|
} catch (error) {
|
|
384
369
|
console.log(kleur.red('❌ Failed to install dependencies'));
|
|
385
370
|
console.log('Please run manually:');
|
|
386
|
-
console.log(
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
);
|
|
391
|
-
console.log(
|
|
392
|
-
kleur.cyan(
|
|
393
|
-
`${addCommand} -D @types/node@^22.18.0 @types/react@^19.0.0 @types/react-dom@^19.0.0 @types/d3@^7.4.3 @types/d3-sankey@^0.12.3 prettier@^3.7.4 prettier-plugin-astro@^0.14.1 prettier-plugin-tailwindcss@^0.7.2 typescript@^5.9.3 @types/tinycolor2@^1.4.6 @mhsdesign/jit-browser-tailwindcss@^0.4.2`
|
|
394
|
-
)
|
|
395
|
-
);
|
|
371
|
+
console.log(kleur.cyan(`${addCommand} ${dependencySpecs}`));
|
|
372
|
+
if (devDependencySpecs) {
|
|
373
|
+
console.log(kleur.cyan(`${addCommand} -D ${devDependencySpecs}`));
|
|
374
|
+
}
|
|
396
375
|
process.exit(1);
|
|
397
376
|
}
|
|
398
377
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fileURLToPath as d } from "node:url";
|
|
2
2
|
import { dirname as i, resolve as l } from "node:path";
|
|
3
|
-
import { existsSync as n, mkdirSync as
|
|
3
|
+
import { existsSync as n, mkdirSync as k, copyFileSync as x, writeFileSync as u } from "node:fs";
|
|
4
4
|
import { resolve as a } from "path";
|
|
5
5
|
function g(t) {
|
|
6
6
|
const e = i(d(t));
|
|
@@ -1497,18 +1497,6 @@ async function y(t, e, c) {
|
|
|
1497
1497
|
),
|
|
1498
1498
|
dest: "src/components/codehooks/ListContentSetup.tsx"
|
|
1499
1499
|
},
|
|
1500
|
-
{
|
|
1501
|
-
src: t(
|
|
1502
|
-
"../templates/src/components/codehooks/ProductCardSetup.tsx"
|
|
1503
|
-
),
|
|
1504
|
-
dest: "src/components/codehooks/ProductCardSetup.tsx"
|
|
1505
|
-
},
|
|
1506
|
-
{
|
|
1507
|
-
src: t(
|
|
1508
|
-
"../templates/src/components/codehooks/ProductGridSetup.tsx"
|
|
1509
|
-
),
|
|
1510
|
-
dest: "src/components/codehooks/ProductGridSetup.tsx"
|
|
1511
|
-
},
|
|
1512
1500
|
{
|
|
1513
1501
|
src: t(
|
|
1514
1502
|
"../templates/src/components/codehooks/BunnyVideoWrapper.astro"
|
|
@@ -1519,6 +1507,31 @@ async function y(t, e, c) {
|
|
|
1519
1507
|
src: t("../templates/src/components/codehooks/BunnyVideoSetup.tsx"),
|
|
1520
1508
|
dest: "src/components/codehooks/BunnyVideoSetup.tsx"
|
|
1521
1509
|
},
|
|
1510
|
+
// CodeHook Blades (partial routes; core hooks overwritable)
|
|
1511
|
+
{
|
|
1512
|
+
src: t("../templates/src/pages/codehooks/featured-article.astro"),
|
|
1513
|
+
dest: "src/pages/codehooks/featured-article.astro"
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
src: t("../templates/src/pages/codehooks/list-content.astro"),
|
|
1517
|
+
dest: "src/pages/codehooks/list-content.astro"
|
|
1518
|
+
},
|
|
1519
|
+
{
|
|
1520
|
+
src: t("../templates/src/pages/codehooks/search-widget.astro"),
|
|
1521
|
+
dest: "src/pages/codehooks/search-widget.astro"
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
src: t("../templates/src/pages/codehooks/bunny-video.astro"),
|
|
1525
|
+
dest: "src/pages/codehooks/bunny-video.astro"
|
|
1526
|
+
},
|
|
1527
|
+
{
|
|
1528
|
+
src: t("../templates/src/pages/codehooks/epinet.astro"),
|
|
1529
|
+
dest: "src/pages/codehooks/epinet.astro"
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
src: t("../templates/src/pages/codehooks/[...hookId].astro"),
|
|
1533
|
+
dest: "src/pages/codehooks/[...hookId].astro"
|
|
1534
|
+
},
|
|
1522
1535
|
// Widget Components
|
|
1523
1536
|
{
|
|
1524
1537
|
src: t("../templates/src/components/widgets/Impression.tsx"),
|
|
@@ -1545,6 +1558,10 @@ async function y(t, e, c) {
|
|
|
1545
1558
|
src: t("../templates/src/lib/resources.ts"),
|
|
1546
1559
|
dest: "src/lib/resources.ts"
|
|
1547
1560
|
},
|
|
1561
|
+
{
|
|
1562
|
+
src: t("../templates/src/lib/codeHookHelper.ts"),
|
|
1563
|
+
dest: "src/lib/codeHookHelper.ts"
|
|
1564
|
+
},
|
|
1548
1565
|
// Client Scripts
|
|
1549
1566
|
{
|
|
1550
1567
|
src: t("../templates/src/client/htmx.min.js"),
|
|
@@ -2319,13 +2336,6 @@ async function y(t, e, c) {
|
|
|
2319
2336
|
dest: "src/pages/storykeep/init.astro"
|
|
2320
2337
|
},
|
|
2321
2338
|
// Custom Components (Conditional)
|
|
2322
|
-
{
|
|
2323
|
-
src: t(
|
|
2324
|
-
c?.includeExamples ? "../templates/custom/with-examples/CodeHook.astro" : "../templates/custom/minimal/CodeHook.astro"
|
|
2325
|
-
),
|
|
2326
|
-
dest: "src/custom/CodeHook.astro",
|
|
2327
|
-
protected: !0
|
|
2328
|
-
},
|
|
2329
2339
|
{
|
|
2330
2340
|
src: t(
|
|
2331
2341
|
c?.includeExamples ? "../templates/custom/with-examples/CustomRoutes.astro" : "../templates/custom/minimal/CustomRoutes.astro"
|
|
@@ -2334,9 +2344,7 @@ async function y(t, e, c) {
|
|
|
2334
2344
|
protected: !0
|
|
2335
2345
|
},
|
|
2336
2346
|
{
|
|
2337
|
-
src: t(
|
|
2338
|
-
c?.includeExamples ? "../templates/custom/with-examples/HeaderWidget.astro" : "../templates/custom/minimal/HeaderWidget.astro"
|
|
2339
|
-
),
|
|
2347
|
+
src: t("../templates/custom/minimal/HeaderWidget.astro"),
|
|
2340
2348
|
dest: "src/custom/HeaderWidget.astro",
|
|
2341
2349
|
protected: !0
|
|
2342
2350
|
},
|
|
@@ -2405,6 +2413,29 @@ async function y(t, e, c) {
|
|
|
2405
2413
|
dest: "src/custom/shopify/NativeBookingCalendar.tsx",
|
|
2406
2414
|
protected: !0
|
|
2407
2415
|
},
|
|
2416
|
+
// CodeHook manifest (frontend capability list; hand-maintained, protected)
|
|
2417
|
+
{
|
|
2418
|
+
src: t(
|
|
2419
|
+
c?.includeExamples ? "../templates/custom/with-examples/codehooks.ts" : "../templates/custom/minimal/codehooks.ts"
|
|
2420
|
+
),
|
|
2421
|
+
dest: "src/custom/codehooks.ts",
|
|
2422
|
+
protected: !0
|
|
2423
|
+
},
|
|
2424
|
+
// CodeHook Blades (userland hooks; protected once installed)
|
|
2425
|
+
{
|
|
2426
|
+
src: t(
|
|
2427
|
+
"../templates/src/pages/codehooks/shopify-product-grid.astro"
|
|
2428
|
+
),
|
|
2429
|
+
dest: "src/pages/codehooks/shopify-product-grid.astro",
|
|
2430
|
+
protected: !0
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
src: t(
|
|
2434
|
+
"../templates/src/pages/codehooks/shopify-service-list.astro"
|
|
2435
|
+
),
|
|
2436
|
+
dest: "src/pages/codehooks/shopify-service-list.astro",
|
|
2437
|
+
protected: !0
|
|
2438
|
+
},
|
|
2408
2439
|
// Example Components (Conditional)
|
|
2409
2440
|
...c?.includeExamples ? [
|
|
2410
2441
|
{
|
|
@@ -2420,20 +2451,13 @@ async function y(t, e, c) {
|
|
|
2420
2451
|
protected: !0
|
|
2421
2452
|
},
|
|
2422
2453
|
{
|
|
2423
|
-
src: t("../templates/custom
|
|
2424
|
-
dest: "src/custom
|
|
2425
|
-
protected: !0
|
|
2426
|
-
},
|
|
2427
|
-
{
|
|
2428
|
-
src: t(
|
|
2429
|
-
"../templates/custom/with-examples/ProductCardWrapper.astro"
|
|
2430
|
-
),
|
|
2431
|
-
dest: "src/custom/ProductCardWrapper.astro",
|
|
2454
|
+
src: t("../templates/src/pages/codehooks/custom-hero.astro"),
|
|
2455
|
+
dest: "src/pages/codehooks/custom-hero.astro",
|
|
2432
2456
|
protected: !0
|
|
2433
2457
|
},
|
|
2434
2458
|
{
|
|
2435
|
-
src: t("../templates/
|
|
2436
|
-
dest: "src/
|
|
2459
|
+
src: t("../templates/src/pages/codehooks/get-crafting.astro"),
|
|
2460
|
+
dest: "src/pages/codehooks/get-crafting.astro",
|
|
2437
2461
|
protected: !0
|
|
2438
2462
|
},
|
|
2439
2463
|
{
|
|
@@ -2453,11 +2477,11 @@ async function y(t, e, c) {
|
|
|
2453
2477
|
for (const s of o)
|
|
2454
2478
|
try {
|
|
2455
2479
|
const p = i(s.dest);
|
|
2456
|
-
n(p) ||
|
|
2480
|
+
n(p) || k(p, { recursive: !0 });
|
|
2457
2481
|
const r = !s.protected && (s.dest === "tailwind.config.cjs" || s.dest.startsWith("src/components/codehooks/") || s.dest.startsWith("src/components/widgets/") || s.dest.startsWith("src/") || s.dest.startsWith("public/client/") || s.dest === ".gitignore");
|
|
2458
2482
|
if (!n(s.dest) || r)
|
|
2459
2483
|
if (n(s.src))
|
|
2460
|
-
|
|
2484
|
+
x(s.src, s.dest), e.info(`Updated ${s.dest}`);
|
|
2461
2485
|
else {
|
|
2462
2486
|
const m = f(s.dest);
|
|
2463
2487
|
u(s.dest, m), e.info(`Created placeholder ${s.dest}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-tractstack",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Astro integration for TractStack - the free web press by At Risk Media",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,19 +50,57 @@
|
|
|
50
50
|
"react": "^19.0.0",
|
|
51
51
|
"react-dom": "^19.0.0"
|
|
52
52
|
},
|
|
53
|
+
"tractstackInstall": {
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"react": "^19.0.0",
|
|
56
|
+
"react-dom": "^19.0.0",
|
|
57
|
+
"astro": "^5.16.6",
|
|
58
|
+
"@astrojs/react": "^4.4.2",
|
|
59
|
+
"@astrojs/node": "^9.4.3",
|
|
60
|
+
"@nanostores/react": "^1.1.0",
|
|
61
|
+
"nanostores": "^1.3.0",
|
|
62
|
+
"@nanostores/persistent": "^1.3.4",
|
|
63
|
+
"ulid": "^3.0.2",
|
|
64
|
+
"@ark-ui/react": "^5.37.2",
|
|
65
|
+
"@internationalized/date": "^3.12.0",
|
|
66
|
+
"@heroicons/react": "^2.2.0",
|
|
67
|
+
"d3": "^7.9.0",
|
|
68
|
+
"d3-sankey": "^0.12.3",
|
|
69
|
+
"recharts": "^3.8.1",
|
|
70
|
+
"player.js": "^0.1.0",
|
|
71
|
+
"tinycolor2": "^1.6.0",
|
|
72
|
+
"html-to-image": "^1.11.13",
|
|
73
|
+
"path-to-regexp": "^8.4.2",
|
|
74
|
+
"postcss": "^8.5.15",
|
|
75
|
+
"postcss-selector-parser": "^7.1.4"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@types/node": "^22.20.0",
|
|
79
|
+
"@types/react": "^19.2.17",
|
|
80
|
+
"@types/react-dom": "^19.2.3",
|
|
81
|
+
"@types/d3": "^7.4.3",
|
|
82
|
+
"@types/d3-sankey": "^0.12.5",
|
|
83
|
+
"prettier": "^3.8.4",
|
|
84
|
+
"prettier-plugin-astro": "^0.14.1",
|
|
85
|
+
"prettier-plugin-tailwindcss": "^0.7.4",
|
|
86
|
+
"typescript": "^5.9.3",
|
|
87
|
+
"@types/tinycolor2": "^1.4.6",
|
|
88
|
+
"@mhsdesign/jit-browser-tailwindcss": "^0.4.2"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
53
91
|
"dependencies": {
|
|
54
92
|
"@calcom/embed-react": "^1.5.3",
|
|
55
93
|
"kleur": "^4.1.5",
|
|
56
94
|
"prompts": "^2.4.2"
|
|
57
95
|
},
|
|
58
96
|
"devDependencies": {
|
|
59
|
-
"@ark-ui/react": "^5.
|
|
97
|
+
"@ark-ui/react": "^5.37.2",
|
|
60
98
|
"@astrojs/react": "^4.4.2",
|
|
61
|
-
"@heroicons/react": "^2.
|
|
62
|
-
"@internationalized/date": "^3.
|
|
99
|
+
"@heroicons/react": "^2.2.0",
|
|
100
|
+
"@internationalized/date": "^3.12.0",
|
|
63
101
|
"@mhsdesign/jit-browser-tailwindcss": "^0.4.2",
|
|
64
|
-
"@nanostores/persistent": "^1.3.
|
|
65
|
-
"@nanostores/react": "^1.
|
|
102
|
+
"@nanostores/persistent": "^1.3.4",
|
|
103
|
+
"@nanostores/react": "^1.1.0",
|
|
66
104
|
"@types/d3": "^7.4.3",
|
|
67
105
|
"@types/d3-sankey": "^0.12.5",
|
|
68
106
|
"@types/node": "^22.18.0",
|
|
@@ -74,7 +112,7 @@
|
|
|
74
112
|
"d3": "^7.9.0",
|
|
75
113
|
"d3-sankey": "^0.12.3",
|
|
76
114
|
"html-to-image": "^1.11.13",
|
|
77
|
-
"nanostores": "^1.
|
|
115
|
+
"nanostores": "^1.3.0",
|
|
78
116
|
"player.js": "^0.1.0",
|
|
79
117
|
"postcss": "^8.5.6",
|
|
80
118
|
"postcss-selector-parser": "^7.1.1",
|
|
@@ -96,8 +134,7 @@
|
|
|
96
134
|
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0",
|
|
97
135
|
"pnpm": {
|
|
98
136
|
"overrides": {
|
|
99
|
-
"esbuild@<=0.24.2": ">=0.25.0"
|
|
100
|
-
"@internationalized/date": "3.10.1"
|
|
137
|
+
"esbuild@<=0.24.2": ">=0.25.0"
|
|
101
138
|
}
|
|
102
139
|
}
|
|
103
140
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Static, hand-maintained per-install manifest of available codehook ids.
|
|
2
|
+
// The backend never sees this; it is a frontend build capability list only.
|
|
3
|
+
// To add/remove a hook, edit this array AND add/remove the matching blade at
|
|
4
|
+
// src/pages/codehooks/{id}.astro. Not regenerated automatically.
|
|
5
|
+
export const availableCodeHookIds: string[] = [
|
|
6
|
+
'featured-article',
|
|
7
|
+
'list-content',
|
|
8
|
+
'search-widget',
|
|
9
|
+
'bunny-video',
|
|
10
|
+
'epinet',
|
|
11
|
+
'shopify-product-grid',
|
|
12
|
+
'shopify-service-list',
|
|
13
|
+
];
|
|
@@ -6,7 +6,7 @@ import { getShopifyImage } from '@/utils/helpers';
|
|
|
6
6
|
import type { ResourceNode } from '@/types/compositorTypes';
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
9
|
-
resources:
|
|
9
|
+
resources: ResourceNode[];
|
|
10
10
|
options?: {
|
|
11
11
|
params?: {
|
|
12
12
|
options?: string;
|
|
@@ -218,9 +218,9 @@ function ProductCard({ resource, allServices }: ProductCardProps) {
|
|
|
218
218
|
|
|
219
219
|
const HEX_BG_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
220
220
|
|
|
221
|
-
export default function ShopifyProductGrid({ resources =
|
|
222
|
-
let products = resources
|
|
223
|
-
const services = resources
|
|
221
|
+
export default function ShopifyProductGrid({ resources = [], options }: Props) {
|
|
222
|
+
let products = resources.filter((r) => r.categorySlug === 'product');
|
|
223
|
+
const services = resources.filter((r) => r.categorySlug === 'service');
|
|
224
224
|
|
|
225
225
|
let group = '';
|
|
226
226
|
let title = '';
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import type { ResourceNode } from '@/types/compositorTypes';
|
|
9
9
|
|
|
10
10
|
interface Props {
|
|
11
|
-
resources:
|
|
11
|
+
resources: ResourceNode[];
|
|
12
12
|
options?: {
|
|
13
13
|
params?: {
|
|
14
14
|
options?: string;
|
|
@@ -18,11 +18,11 @@ interface Props {
|
|
|
18
18
|
|
|
19
19
|
const HEX_BG_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
20
20
|
|
|
21
|
-
export default function ShopifyServiceList({ resources =
|
|
21
|
+
export default function ShopifyServiceList({ resources = [], options }: Props) {
|
|
22
22
|
const cart = useStore(cartStore);
|
|
23
23
|
|
|
24
|
-
const products = resources
|
|
25
|
-
let services = resources
|
|
24
|
+
const products = resources.filter((r) => r.categorySlug === 'product');
|
|
25
|
+
let services = resources.filter((r) => r.categorySlug === 'service');
|
|
26
26
|
|
|
27
27
|
let group = '';
|
|
28
28
|
let title = '';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Static, hand-maintained per-install manifest of available codehook ids.
|
|
2
|
+
// The backend never sees this; it is a frontend build capability list only.
|
|
3
|
+
// To add/remove a hook, edit this array AND add/remove the matching blade at
|
|
4
|
+
// src/pages/codehooks/{id}.astro. Not regenerated automatically.
|
|
5
|
+
export const availableCodeHookIds: string[] = [
|
|
6
|
+
'featured-article',
|
|
7
|
+
'list-content',
|
|
8
|
+
'search-widget',
|
|
9
|
+
'bunny-video',
|
|
10
|
+
'epinet',
|
|
11
|
+
'shopify-product-grid',
|
|
12
|
+
'shopify-service-list',
|
|
13
|
+
'custom-hero',
|
|
14
|
+
'get-crafting',
|
|
15
|
+
];
|
|
@@ -11,7 +11,10 @@ import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
|
|
|
11
11
|
import CheckCircleIcon from '@heroicons/react/24/outline/CheckCircleIcon';
|
|
12
12
|
import ChevronLeftIcon from '@heroicons/react/24/outline/ChevronLeftIcon';
|
|
13
13
|
import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
epinetCustomFilters,
|
|
16
|
+
setEpinetCustomFilters,
|
|
17
|
+
} from '@/stores/analytics';
|
|
15
18
|
import EpinetTableView from './EpinetTableView';
|
|
16
19
|
import { MAX_ANALYTICS_HOURS } from '@/constants';
|
|
17
20
|
import type { AppliedFilter } from '@/stores/analytics';
|
|
@@ -220,7 +223,7 @@ const EpinetDurationSelector = ({
|
|
|
220
223
|
}
|
|
221
224
|
setIsApplying(true);
|
|
222
225
|
try {
|
|
223
|
-
|
|
226
|
+
setEpinetCustomFilters(window.TRACTSTACK_CONFIG?.tenantId || 'default', {
|
|
224
227
|
...$epinetCustomFilters,
|
|
225
228
|
visitorType: localFilters.visitorType,
|
|
226
229
|
selectedUserId: localFilters.selectedUserId,
|
|
@@ -794,10 +797,16 @@ const EpinetDurationSelector = ({
|
|
|
794
797
|
collection={createListCollection({
|
|
795
798
|
items: [
|
|
796
799
|
{ value: '', label: 'Select user' },
|
|
797
|
-
...paginatedUserCounts.map(
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
800
|
+
...paginatedUserCounts.map(
|
|
801
|
+
(user: {
|
|
802
|
+
id: string;
|
|
803
|
+
count: number;
|
|
804
|
+
isKnown: boolean;
|
|
805
|
+
}) => ({
|
|
806
|
+
value: user.id,
|
|
807
|
+
label: `${user.id} (${user.count} events)`,
|
|
808
|
+
})
|
|
809
|
+
),
|
|
801
810
|
],
|
|
802
811
|
})}
|
|
803
812
|
value={
|
|
@@ -844,23 +853,29 @@ const EpinetDurationSelector = ({
|
|
|
844
853
|
Select user
|
|
845
854
|
</Select.ItemText>
|
|
846
855
|
</Select.Item>,
|
|
847
|
-
...paginatedUserCounts.map(
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
856
|
+
...paginatedUserCounts.map(
|
|
857
|
+
(user: {
|
|
858
|
+
id: string;
|
|
859
|
+
count: number;
|
|
860
|
+
isKnown: boolean;
|
|
861
|
+
}) => (
|
|
862
|
+
<Select.Item
|
|
863
|
+
key={user.id}
|
|
864
|
+
item={{
|
|
865
|
+
value: user.id,
|
|
866
|
+
label: `${user.id} (${user.count} events)`,
|
|
867
|
+
}}
|
|
868
|
+
className="epinet-user-select-item cursor-pointer select-none p-2 text-sm text-gray-700 hover:bg-slate-100"
|
|
869
|
+
>
|
|
870
|
+
<Select.ItemText>
|
|
871
|
+
{user.id}{' '}
|
|
872
|
+
<span className="text-xs text-gray-500">
|
|
873
|
+
({user.count} events)
|
|
874
|
+
</span>
|
|
875
|
+
</Select.ItemText>
|
|
876
|
+
</Select.Item>
|
|
877
|
+
)
|
|
878
|
+
),
|
|
864
879
|
]
|
|
865
880
|
) : (
|
|
866
881
|
<div className="p-2 text-sm text-gray-500">
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
2
|
import { useStore } from '@nanostores/react';
|
|
3
3
|
import { classNames } from '@/utils/helpers';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
epinetCustomFilters,
|
|
6
|
+
setEpinetCustomFilters,
|
|
7
|
+
} from '@/stores/analytics';
|
|
5
8
|
import { Accordion } from '@ark-ui/react';
|
|
6
9
|
import ChevronLeftIcon from '@heroicons/react/24/outline/ChevronLeftIcon';
|
|
7
10
|
import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon';
|
|
@@ -176,7 +179,7 @@ const EpinetTableView = ({
|
|
|
176
179
|
const endTimeUTC = new Date(
|
|
177
180
|
Date.UTC(year, month - 1, day, hour, 59, 59, 999)
|
|
178
181
|
);
|
|
179
|
-
|
|
182
|
+
setEpinetCustomFilters(window.TRACTSTACK_CONFIG?.tenantId || 'default', {
|
|
180
183
|
...$epinetCustomFilters,
|
|
181
184
|
startTimeUTC: startTimeUTC.toISOString(),
|
|
182
185
|
endTimeUTC: endTimeUTC.toISOString(),
|
|
@@ -6,7 +6,12 @@ import {
|
|
|
6
6
|
type ReactNode,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import { useStore } from '@nanostores/react';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
epinetCustomFilters,
|
|
11
|
+
getEpinetCustomFilters,
|
|
12
|
+
setEpinetCustomFilters,
|
|
13
|
+
type AppliedFilter,
|
|
14
|
+
} from '@/stores/analytics';
|
|
10
15
|
import { TractStackAPI } from '@/utils/api';
|
|
11
16
|
import SankeyDiagram from './SankeyDiagram';
|
|
12
17
|
import EpinetDurationSelector from './EpinetDurationSelector';
|
|
@@ -97,7 +102,7 @@ const EpinetWrapper = ({
|
|
|
97
102
|
useEffect(() => {
|
|
98
103
|
const nowUTC = new Date();
|
|
99
104
|
const oneWeekAgoUTC = new Date(nowUTC.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
100
|
-
|
|
105
|
+
setEpinetCustomFilters(window.TRACTSTACK_CONFIG?.tenantId || 'default', {
|
|
101
106
|
enabled: true,
|
|
102
107
|
visitorType: 'all',
|
|
103
108
|
selectedUserId: null,
|
|
@@ -133,7 +138,7 @@ const EpinetWrapper = ({
|
|
|
133
138
|
|
|
134
139
|
const handleBeliefFilterChange = (beliefSlug: string, value: string) => {
|
|
135
140
|
const tenantId = window.TRACTSTACK_CONFIG?.tenantId || 'default';
|
|
136
|
-
const currentFilters =
|
|
141
|
+
const currentFilters = getEpinetCustomFilters();
|
|
137
142
|
let newFilters: AppliedFilter[] = [
|
|
138
143
|
...(currentFilters.appliedFilters || []),
|
|
139
144
|
];
|
|
@@ -151,7 +156,7 @@ const EpinetWrapper = ({
|
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
158
|
|
|
154
|
-
|
|
159
|
+
setEpinetCustomFilters(tenantId, {
|
|
155
160
|
...currentFilters,
|
|
156
161
|
appliedFilters: newFilters,
|
|
157
162
|
});
|
|
@@ -229,7 +234,7 @@ const EpinetWrapper = ({
|
|
|
229
234
|
error: null,
|
|
230
235
|
isLoading: false,
|
|
231
236
|
});
|
|
232
|
-
|
|
237
|
+
setEpinetCustomFilters(
|
|
233
238
|
window.TRACTSTACK_CONFIG?.tenantId || 'default',
|
|
234
239
|
{
|
|
235
240
|
...$epinetCustomFilters,
|
|
@@ -7,10 +7,10 @@ export interface Props {
|
|
|
7
7
|
options?: string;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
fullContentMap: FullContentMapItem[];
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const { options,
|
|
13
|
+
const { options, fullContentMap } = Astro.props;
|
|
14
14
|
|
|
15
15
|
let parsedOptions;
|
|
16
16
|
try {
|
|
@@ -22,7 +22,7 @@ try {
|
|
|
22
22
|
|
|
23
23
|
const slug = parsedOptions.slug || '';
|
|
24
24
|
|
|
25
|
-
const featuredStory =
|
|
25
|
+
const featuredStory = fullContentMap.find(
|
|
26
26
|
(item: FullContentMapItem) =>
|
|
27
27
|
item.slug === slug &&
|
|
28
28
|
item.type === 'StoryFragment' &&
|
|
@@ -7,10 +7,10 @@ export interface Props {
|
|
|
7
7
|
options?: string;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
fullContentMap: FullContentMapItem[];
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const { options,
|
|
13
|
+
const { options, fullContentMap } = Astro.props;
|
|
14
14
|
|
|
15
15
|
// Parse component options
|
|
16
16
|
let parsedOptions;
|
|
@@ -36,7 +36,7 @@ const title = parsedOptions.title;
|
|
|
36
36
|
const bgColor = parsedOptions.bgColor || '';
|
|
37
37
|
|
|
38
38
|
// Filter for valid stories to display
|
|
39
|
-
const validPages =
|
|
39
|
+
const validPages = fullContentMap.filter(
|
|
40
40
|
(item: FullContentMapItem): boolean =>
|
|
41
41
|
item.type === 'StoryFragment' &&
|
|
42
42
|
typeof item.description === 'string' &&
|