astro-tractstack 2.3.4 → 2.3.5

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/dist/index.js CHANGED
@@ -2341,13 +2341,23 @@ async function y(t, e, c) {
2341
2341
  protected: !0
2342
2342
  },
2343
2343
  {
2344
- src: t("../templates/src/utils/customHelpers.ts"),
2345
- dest: "src/utils/customHelpers.ts",
2344
+ src: t("../templates/custom/customHelpers.ts"),
2345
+ dest: "src/custom/customHelpers.ts",
2346
2346
  protected: !0
2347
2347
  },
2348
2348
  {
2349
- src: t("../templates/src/utils/booking/appointmentMode.ts"),
2350
- dest: "src/utils/booking/appointmentMode.ts",
2349
+ src: t("../templates/custom/shopify/shopifyCustomHelper.ts"),
2350
+ dest: "src/custom/shopify/shopifyCustomHelper.ts",
2351
+ protected: !0
2352
+ },
2353
+ {
2354
+ src: t("../templates/custom/shopify/shopifyHelpers.ts"),
2355
+ dest: "src/custom/shopify/shopifyHelpers.ts",
2356
+ protected: !0
2357
+ },
2358
+ {
2359
+ src: t("../templates/custom/shopify/appointmentMode.ts"),
2360
+ dest: "src/custom/shopify/appointmentMode.ts",
2351
2361
  protected: !0
2352
2362
  },
2353
2363
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-tractstack",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
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",
@@ -0,0 +1,45 @@
1
+ // URL Helper: Strip category prefix from slug
2
+ // e.g., "people-bleako" -> "bleako"
3
+ export function getCleanSlug(categorySlug: string, fullSlug: string): string {
4
+ const prefix = `${categorySlug}-`;
5
+ return fullSlug.startsWith(prefix) ? fullSlug.slice(prefix.length) : fullSlug;
6
+ }
7
+
8
+ // Build proper URL for resource
9
+ // e.g., category="people", slug="people-bleako" -> "/people/bleako"
10
+ export function getResourceUrl(categorySlug: string, fullSlug: string): string {
11
+ const cleanSlug = getCleanSlug(categorySlug, fullSlug);
12
+ return `/${categorySlug}/${cleanSlug}`;
13
+ }
14
+
15
+ // Image Helper: Placeholder implementation
16
+ export function getResourceImage(
17
+ id: string,
18
+ slug: string,
19
+ category: string
20
+ ): string {
21
+ console.log(`please define getResourceImage`, id, slug, category);
22
+ return '/static.jpg';
23
+ }
24
+
25
+ export function getResourceDescription(
26
+ id: string,
27
+ slug: string,
28
+ category: string
29
+ ): string | null {
30
+ console.log(`please define getResourceDescription`, id, slug, category);
31
+ return null;
32
+ }
33
+
34
+ // Initialize search data - override in custom implementation
35
+ export function initSearch(): void {
36
+ // Default implementation does nothing
37
+ // Override this function in your custom implementation to load search data
38
+ }
39
+
40
+ // Field Visibility Controls for ResourceForm
41
+ export const resourceFormHideFields = ['shopifyImage'];
42
+
43
+ // Field Formatting Controls for ResourceForm
44
+ // Fields listed here will be treated as JSON objects but rendered as stringified text areas
45
+ export const resourceJsonifyFields = ['shopifyData', 'shopifyImage'];
@@ -12,14 +12,14 @@ import {
12
12
  type CartItemState,
13
13
  } from '@/stores/shopify';
14
14
  import { getShopifyImage } from '@/utils/helpers';
15
- import { deriveAppointmentConstraints } from '@/utils/booking/appointmentMode';
15
+ import { deriveAppointmentConstraints } from '@/custom/shopify/appointmentMode';
16
16
  import {
17
17
  getServiceLinkedProduct,
18
18
  getServiceVariantIdFromCanonicalProduct,
19
19
  getSharedFeeChargeLineSummary,
20
20
  isSharedFeeService,
21
21
  parsePrimaryShopifyProductData,
22
- } from '@/utils/customHelpers';
22
+ } from '@/custom/shopify/shopifyHelpers';
23
23
  import type { ResourceNode } from '@/types/compositorTypes';
24
24
 
25
25
  interface CartProps {
@@ -1,6 +1,6 @@
1
1
  import { useStore } from '@nanostores/react';
2
2
  import { cartStore } from '@/stores/shopify';
3
- import { getCartIconCount } from '@/utils/customHelpers';
3
+ import { getCartIconCount } from '@/custom/shopify/shopifyHelpers';
4
4
  import type { ResourceNode } from '@/types/compositorTypes';
5
5
 
6
6
  interface CartIconProps {
@@ -24,7 +24,8 @@ import { bookingHelpers } from '@/utils/api/bookingHelpers';
24
24
  import {
25
25
  deriveAppointmentConstraints,
26
26
  pickInitialAppointmentMode,
27
- } from '@/utils/booking/appointmentMode';
27
+ type AppointmentMode,
28
+ } from '@/custom/shopify/appointmentMode';
28
29
  import { NativeBookingCalendar } from './NativeBookingCalendar';
29
30
  import { ProfileStorage } from '@/utils/profileStorage';
30
31
  import {
@@ -35,7 +36,7 @@ import {
35
36
  hasGidBackedCheckout,
36
37
  isSharedFeeService,
37
38
  parsePrimaryShopifyProductData,
38
- } from '@/utils/customHelpers';
39
+ } from '@/custom/shopify/shopifyHelpers';
39
40
  import type { ResourceNode } from '@/types/compositorTypes';
40
41
 
41
42
  type CheckoutState =
@@ -45,7 +46,6 @@ type CheckoutState =
45
46
  | 'SUMMARY'
46
47
  | 'PROCESSING'
47
48
  | 'SUCCESS';
48
- type AppointmentMode = 'IN_PERSON' | 'REMOTE';
49
49
 
50
50
  interface CheckoutModalProps {
51
51
  maxLength: number;
@@ -7,13 +7,13 @@ import {
7
7
  transactionTraceId,
8
8
  } from '@/stores/shopify';
9
9
  import { bookingHelpers } from '@/utils/api/bookingHelpers';
10
+ import { RESTRICTION_MESSAGES } from '@/custom/shopify/shopifyCustomHelper';
10
11
  import {
11
- RESTRICTION_MESSAGES,
12
12
  calculateCartDuration,
13
13
  getCartItemKey,
14
14
  isSharedFeeService,
15
- } from '@/utils/customHelpers';
16
- import { wouldCartHaveImpossibleRemoteMix } from '@/utils/booking/appointmentMode';
15
+ } from '@/custom/shopify/shopifyHelpers';
16
+ import { wouldCartHaveImpossibleRemoteMix } from '@/custom/shopify/appointmentMode';
17
17
  import type { ResourceNode } from '@/types/compositorTypes';
18
18
  import type { CartItemState } from '@/stores/shopify';
19
19
  import type { BrandConfigState } from '@/types/tractstack';
@@ -6,7 +6,7 @@ import {
6
6
  CART_STATES,
7
7
  isShopifyHandoff,
8
8
  } from '@/stores/shopify';
9
- import { buildShopifyCheckoutLines } from '@/utils/customHelpers';
9
+ import { buildShopifyCheckoutLines } from '@/custom/shopify/shopifyHelpers';
10
10
  import type { ResourceNode } from '@/types/compositorTypes';
11
11
 
12
12
  interface ShopifyCheckoutProps {
@@ -1,7 +1,7 @@
1
1
  import { useState } from 'react';
2
2
  import { useStore } from '@nanostores/react';
3
3
  import { cartStore, addQueue, type CartAction } from '@/stores/shopify';
4
- import { collectServiceGids } from '@/utils/customHelpers';
4
+ import { collectServiceGids } from '@/custom/shopify/shopifyHelpers';
5
5
  import { getShopifyImage } from '@/utils/helpers';
6
6
  import type { ResourceNode } from '@/types/compositorTypes';
7
7
 
@@ -4,7 +4,7 @@ import {
4
4
  getCartItemKey,
5
5
  getServiceVariantIdFromCanonicalProduct,
6
6
  isSharedFeeService,
7
- } from '@/utils/customHelpers';
7
+ } from '@/custom/shopify/shopifyHelpers';
8
8
  import type { ResourceNode } from '@/types/compositorTypes';
9
9
 
10
10
  interface Props {
@@ -0,0 +1,10 @@
1
+ export const RESTRICTION_MESSAGES = {
2
+ BOOKING: (duration: number) =>
3
+ `This is a ${duration} minute service. On checkout we'll help you book at your convenience.`,
4
+ TERMS: 'Please review the terms for this item before adding it to your cart.',
5
+ MAX_DURATION: (max: number) =>
6
+ `You cannot book more than ${max} minutes of services in one session.`,
7
+ INCOMPATIBLE_REMOTE:
8
+ 'This service cannot be combined with the services already in your cart. Some require remote-only delivery while others can only be delivered in person.',
9
+ DEFAULT_ADD: (title: string) => `${title} has been added to your cart.`,
10
+ };
@@ -2,52 +2,6 @@ import { getCartItemKey as baseGetCartItemKey } from '@/stores/shopify';
2
2
  import type { CartItemState, CartKeyParams } from '@/stores/shopify';
3
3
  import type { ResourceNode } from '@/types/compositorTypes';
4
4
 
5
- // URL Helper: Strip category prefix from slug
6
- // e.g., "people-bleako" -> "bleako"
7
- export function getCleanSlug(categorySlug: string, fullSlug: string): string {
8
- const prefix = `${categorySlug}-`;
9
- return fullSlug.startsWith(prefix) ? fullSlug.slice(prefix.length) : fullSlug;
10
- }
11
-
12
- // Build proper URL for resource
13
- // e.g., category="people", slug="people-bleako" -> "/people/bleako"
14
- export function getResourceUrl(categorySlug: string, fullSlug: string): string {
15
- const cleanSlug = getCleanSlug(categorySlug, fullSlug);
16
- return `/${categorySlug}/${cleanSlug}`;
17
- }
18
-
19
- // Image Helper: Placeholder implementation
20
- export function getResourceImage(
21
- id: string,
22
- slug: string,
23
- category: string
24
- ): string {
25
- console.log(`please define getResourceImage`, id, slug, category);
26
- return '/static.jpg';
27
- }
28
-
29
- export function getResourceDescription(
30
- id: string,
31
- slug: string,
32
- category: string
33
- ): string | null {
34
- console.log(`please define getResourceDescription`, id, slug, category);
35
- return null;
36
- }
37
-
38
- // Initialize search data - override in custom implementation
39
- export function initSearch(): void {
40
- // Default implementation does nothing
41
- // Override this function in your custom implementation to load search data
42
- }
43
-
44
- // Field Visibility Controls for ResourceForm
45
- export const resourceFormHideFields = ['shopifyImage'];
46
-
47
- // Field Formatting Controls for ResourceForm
48
- // Fields listed here will be treated as JSON objects but rendered as stringified text areas
49
- export const resourceJsonifyFields = ['shopifyData', 'shopifyImage'];
50
-
51
5
  const SERVICES_ATTR_LIMIT = 255;
52
6
 
53
7
  type CheckoutLineAttribute = { key: string; value: string };
@@ -70,34 +24,6 @@ export type SharedFeeChargeLineSummary = DepositSummary & {
70
24
  description?: string;
71
25
  };
72
26
 
73
- export const RESTRICTION_MESSAGES = {
74
- BOOKING: (duration: number) =>
75
- `This is a ${duration} minute service. On checkout we'll help you book at your convenience.`,
76
- TERMS: 'Please review the terms for this item before adding it to your cart.',
77
- MAX_DURATION: (max: number) =>
78
- `You cannot book more than ${max} minutes of services in one session.`,
79
- INCOMPATIBLE_REMOTE:
80
- 'This service cannot be combined with the services already in your cart. Some require remote-only delivery while others can only be delivered in person.',
81
- DEFAULT_ADD: (title: string) => `${title} has been added to your cart.`,
82
- };
83
-
84
- // For CartModal.tsx
85
- export function checkRestrictions(resource: ResourceNode): boolean {
86
- // 1. Service / Booking Requirement
87
- // We check for the explicit option payload value used by services
88
- if (resource.optionsPayload?.bookingLengthMinutes) {
89
- return true;
90
- }
91
-
92
- // 2. Final Sale / Terms Check
93
- // Placeholder: In the future, check for flags like resource.optionsPayload?.finalSale
94
- // if (resource.optionsPayload?.finalSale) {
95
- // return true;
96
- // }
97
-
98
- return false;
99
- }
100
-
101
27
  export function calculateCartDuration(
102
28
  cart: Record<string, CartItemState>,
103
29
  resources: ResourceNode[]
@@ -141,7 +141,7 @@ if (hasShopify) {
141
141
  <div
142
142
  class="flex flex-row flex-nowrap justify-between bg-mywhite px-4 pb-3 pt-4 shadow-inner md:px-8"
143
143
  >
144
- <h1 class="truncate text-xl text-mydarkgrey">{title}</h1>
144
+ <h1 class="truncate text-2xl text-mydarkgrey">{title}</h1>
145
145
  <div class="flex flex-row flex-nowrap items-center gap-x-2">
146
146
  {
147
147
  !isHome ? (
@@ -16,7 +16,7 @@ import {
16
16
  getResourceUrl,
17
17
  getResourceImage,
18
18
  getResourceDescription,
19
- } from '@/utils/customHelpers';
19
+ } from '@/custom/customHelpers';
20
20
 
21
21
  // --- TYPES ---
22
22
  interface SearchWidgetProps {
@@ -8,7 +8,7 @@ import {
8
8
  getResourceUrl,
9
9
  getResourceImage,
10
10
  getResourceDescription,
11
- } from '@/utils/customHelpers';
11
+ } from '@/custom/customHelpers';
12
12
 
13
13
  const VERBOSE = false;
14
14
 
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon';
3
- import { initSearch } from '@/utils/customHelpers';
3
+ import { initSearch } from '@/custom/customHelpers';
4
4
  import SearchModal from './SearchModal';
5
5
  import type { FullContentMapItem } from '@/types/tractstack';
6
6
 
@@ -13,7 +13,7 @@ import EnumSelect from '@/components/form/EnumSelect';
13
13
  import {
14
14
  resourceFormHideFields,
15
15
  resourceJsonifyFields,
16
- } from '@/utils/customHelpers';
16
+ } from '@/custom/customHelpers';
17
17
  import type {
18
18
  ResourceConfig,
19
19
  ResourceState,
@@ -8,7 +8,7 @@ import {
8
8
  getServiceLinkedProduct,
9
9
  isSharedFeeService,
10
10
  parsePrimaryShopifyProductData,
11
- } from '@/utils/customHelpers';
11
+ } from '@/custom/shopify/shopifyHelpers';
12
12
 
13
13
  interface ShopifyDashboardSalesProps {
14
14
  existingResources: ResourceNode[];
@@ -2385,13 +2385,23 @@ export async function injectTemplateFiles(
2385
2385
  protected: true,
2386
2386
  },
2387
2387
  {
2388
- src: resolve('../templates/src/utils/customHelpers.ts'),
2389
- dest: 'src/utils/customHelpers.ts',
2388
+ src: resolve('../templates/custom/customHelpers.ts'),
2389
+ dest: 'src/custom/customHelpers.ts',
2390
2390
  protected: true,
2391
2391
  },
2392
2392
  {
2393
- src: resolve('../templates/src/utils/booking/appointmentMode.ts'),
2394
- dest: 'src/utils/booking/appointmentMode.ts',
2393
+ src: resolve('../templates/custom/shopify/shopifyCustomHelper.ts'),
2394
+ dest: 'src/custom/shopify/shopifyCustomHelper.ts',
2395
+ protected: true,
2396
+ },
2397
+ {
2398
+ src: resolve('../templates/custom/shopify/shopifyHelpers.ts'),
2399
+ dest: 'src/custom/shopify/shopifyHelpers.ts',
2400
+ protected: true,
2401
+ },
2402
+ {
2403
+ src: resolve('../templates/custom/shopify/appointmentMode.ts'),
2404
+ dest: 'src/custom/shopify/appointmentMode.ts',
2395
2405
  protected: true,
2396
2406
  },
2397
2407
  {