keystone-design-bootstrap 1.0.86 → 1.0.87
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/company-information-C1pP-SvU.d.ts +50 -0
- package/dist/config-C_XBZixg.d.ts +21 -0
- package/dist/consumer-BWjQawiO.d.ts +48 -0
- package/dist/design_system/portal/index.d.ts +52 -0
- package/dist/design_system/portal/index.js +3113 -0
- package/dist/design_system/portal/index.js.map +1 -0
- package/dist/design_system/sections/index.d.ts +2 -1
- package/dist/index.d.ts +5 -24
- package/dist/lib/consumer-session.d.ts +16 -0
- package/dist/lib/consumer-session.js +85 -0
- package/dist/lib/consumer-session.js.map +1 -0
- package/dist/lib/cta-urls.d.ts +34 -0
- package/dist/lib/cta-urls.js +33 -0
- package/dist/lib/cta-urls.js.map +1 -0
- package/dist/lib/server-api.d.ts +2 -1
- package/dist/lib/server-api.js +1 -1
- package/dist/lib/server-api.js.map +1 -1
- package/dist/next/contexts/form-definitions.d.ts +17 -0
- package/dist/next/contexts/form-definitions.js +21 -0
- package/dist/next/contexts/form-definitions.js.map +1 -0
- package/dist/next/gallery/design-gallery.d.ts +103 -0
- package/dist/next/gallery/design-gallery.js +19301 -0
- package/dist/next/gallery/design-gallery.js.map +1 -0
- package/dist/next/layouts/root-layout.d.ts +55 -0
- package/dist/next/layouts/root-layout.js +19713 -0
- package/dist/next/layouts/root-layout.js.map +1 -0
- package/dist/next/legal/privacy-policy.d.ts +7 -0
- package/dist/next/legal/privacy-policy.js +18949 -0
- package/dist/next/legal/privacy-policy.js.map +1 -0
- package/dist/next/legal/terms-of-service.d.ts +7 -0
- package/dist/next/legal/terms-of-service.js +18949 -0
- package/dist/next/legal/terms-of-service.js.map +1 -0
- package/dist/next/providers/ssr-provider.d.ts +12 -0
- package/dist/next/providers/ssr-provider.js +12 -0
- package/dist/next/providers/ssr-provider.js.map +1 -0
- package/dist/next/routes/chat.d.ts +26 -0
- package/dist/next/routes/chat.js +160 -0
- package/dist/next/routes/chat.js.map +1 -0
- package/dist/next/routes/consumer-auth.d.ts +33 -0
- package/dist/next/routes/consumer-auth.js +254 -0
- package/dist/next/routes/consumer-auth.js.map +1 -0
- package/dist/next/routes/form.d.ts +37 -0
- package/dist/next/routes/form.js +97 -0
- package/dist/next/routes/form.js.map +1 -0
- package/dist/package-IU_GpDA0.d.ts +74 -0
- package/dist/types/index.d.ts +6 -68
- package/package.json +28 -28
- package/src/design_system/portal/PortalPage.tsx +3 -2
- package/src/lib/server-api.ts +2 -1
- package/src/types/rails-actioncable.d.ts +16 -0
- package/dist/package-DeHKpQp7.d.ts +0 -121
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { AboutHome, BlogCardFullWidthHorizontal, BlogCardFullWidthHorizontalAlt, BlogCardFullWidthHorizontalCompact, BlogCardFullWidthHorizontalMinimal, BlogCardFullWidthVertical, BlogCardFullWidthVerticalAlt, BlogCardFullWidthVerticalCompact, BlogCardFullWidthVerticalMinimal, BlogCardHorizontal, BlogCardHorizontalBadge, BlogCardHorizontalCompact, BlogCardHorizontalMinimal, BlogCardVertical, BlogCardVerticalBadge, BlogCardVerticalCompact, BlogCardVerticalMinimal, BlogGallery, BlogHome, BlogPostSection, BlogSection, ContactHome, ContactSection, EmailSignupSection, EmailSignupSectionProps, FAQGrid, FAQHero, FAQHome, FeatureTabHorizontal, FeatureTabVertical, FeatureTextCentered, FeatureTextFeaturedIconBox, FeatureTextFeaturedIconCard, FeatureTextFeaturedIconLeft, FeatureTextFeaturedIconTopCentered, FeatureTextFeaturedIconTopCenteredBrand, FeatureTextFeaturedIconTopLeft, FeatureTextFeaturedIconTopLeftBrand, FeatureTextIconCard, FeatureTextIconLeft, FeatureTextIconTopCentered, FeatureTextIconTopLeft, FeatureTextIntegrationIconBox, FeatureTextIntegrationIconLeft, FeatureTextIntegrationIconTopCentered, FeatureTextIntegrationIconTopLeft, FeatureTextLeft, FeatureTextLeftBrand, FooterHome, GenericHeaderComponent, GenericTextHero, HeaderNavigation, HeroHome, HomeHeroComponent, JobApplicationForm, JobDetailHero, JobDetailSection, JobGallery, LocationDetailHero, LocationDetailsSection, LocationGrid, PackageForMenu, PolicyDocumentSection, ServiceDetailContent, ServiceDetailHero, ServiceMenuSection, ServiceMenuSectionProps, ServicesGrid, ServicesHome, SocialMediaGrid, SocialMediaHero, StatisticsSection, TeamGrid, TestimonialsGrid, TestimonialsHero, TestimonialsHome, ValuesSection, getBlogPostData } from './design_system/sections/index.js';
|
|
2
2
|
export { Avatar, AvatarLabelGroup, Badge, BadgeGroup, BadgeWithDot, Breadcrumb, Button, ButtonGroup, Carousel, CarouselContext, CarouselSectionWrapper, ComboBox, FeaturedIcon, Form, FormContainer, GoogleMap, HintText, Input, InputBase, InputGroup, Label, MarkdownRenderer, Modal, ModalProps, NativeSelect, Pagination, PaginationPageDefault, PaginationPageMinimalCenter, PhotoWithFallback, PrivacyCheckbox, RatingBadge, RatingStars, RoundButton, Select, SelectItem, SocialIcon, StarIcon, Textarea, Tooltip, VerifiedTick, VideoModal, VideoPlayButton, Wreath, getSocialIcon, getStarProgress, useCarousel } from './design_system/elements/index.js';
|
|
3
|
-
|
|
3
|
+
export { ResolvedCtaUrls, isExternalCtaUrl, resolveCtaUrls } from './lib/cta-urls.js';
|
|
4
4
|
export { ThemeProvider, useTheme } from './contexts/index.js';
|
|
5
5
|
import React__default from 'react';
|
|
6
6
|
export { Theme } from './themes/index.js';
|
|
7
|
-
import './
|
|
7
|
+
import './package-IU_GpDA0.js';
|
|
8
8
|
import './photos-CmBdWiuZ.js';
|
|
9
|
+
import './blog-post-vWzW8yFb.js';
|
|
9
10
|
import './form-C94A_PX_.js';
|
|
10
11
|
import './website-photos-Cl1YqAno.js';
|
|
12
|
+
import './company-information-C1pP-SvU.js';
|
|
11
13
|
import 'react-aria-components';
|
|
12
14
|
import 'embla-carousel-react';
|
|
13
15
|
|
|
@@ -21,27 +23,6 @@ interface ContactFormResult {
|
|
|
21
23
|
declare function submitContactFormAction(formData: FormData): Promise<ContactFormResult>;
|
|
22
24
|
declare function submitLeadFormAction(formData: FormData): Promise<ContactFormResult>;
|
|
23
25
|
|
|
24
|
-
/**
|
|
25
|
-
* Resolves the primary and secondary CTA hrefs used across the site.
|
|
26
|
-
*
|
|
27
|
-
* Resolution order for primaryHref:
|
|
28
|
-
* 1. portal_url — set by backend when account has consumer portal enabled
|
|
29
|
-
* 2. external_management_url — booking platform URL from the API
|
|
30
|
-
* 3. /contact — final fallback
|
|
31
|
-
*
|
|
32
|
-
* No per-site configuration needed. Enable the portal in the admin console and
|
|
33
|
-
* every CTA across the site automatically routes to the portal.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
/** True when the href is absolute (external); use for target="_blank" and rel="noopener noreferrer". */
|
|
37
|
-
declare function isExternalCtaUrl(href: string): boolean;
|
|
38
|
-
interface ResolvedCtaUrls {
|
|
39
|
-
primaryHref: string;
|
|
40
|
-
secondaryHref: string;
|
|
41
|
-
hasSecondary: boolean;
|
|
42
|
-
}
|
|
43
|
-
declare function resolveCtaUrls(companyInformation?: CompanyInformation | null): ResolvedCtaUrls;
|
|
44
|
-
|
|
45
26
|
interface TeamMember {
|
|
46
27
|
id: number;
|
|
47
28
|
name: string;
|
|
@@ -67,4 +48,4 @@ interface ChatWidgetProps {
|
|
|
67
48
|
}
|
|
68
49
|
declare function ChatWidget({ position, primaryColor, sessionId: providedSessionId, contactId, displayName: providedDisplayName, teamMembers }: ChatWidgetProps): React__default.JSX.Element;
|
|
69
50
|
|
|
70
|
-
export { ChatWidget,
|
|
51
|
+
export { ChatWidget, submitContactFormAction, submitLeadFormAction };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { C as ConversationSummary, a as Consumer, M as Message, b as ContactSummary } from '../consumer-BWjQawiO.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Server-side consumer session helpers.
|
|
5
|
+
* Runs on the server only — accepts the JWT token read from cookies by the page component.
|
|
6
|
+
*/
|
|
7
|
+
declare const CONSUMER_TOKEN_COOKIE = "ks_consumer_token";
|
|
8
|
+
|
|
9
|
+
declare function fetchConsumerMe(token: string): Promise<Consumer | null>;
|
|
10
|
+
declare function fetchConsumerConversations(token: string): Promise<ConversationSummary[]>;
|
|
11
|
+
declare function fetchConsumerMessages(token: string, contactId: number): Promise<{
|
|
12
|
+
messages: Message[];
|
|
13
|
+
contact: ContactSummary | null;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export { CONSUMER_TOKEN_COOKIE, Consumer, ContactSummary, ConversationSummary, Message, fetchConsumerConversations, fetchConsumerMe, fetchConsumerMessages };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/lib/consumer-session.ts
|
|
19
|
+
var CONSUMER_TOKEN_COOKIE = "ks_consumer_token";
|
|
20
|
+
function getApiUrl() {
|
|
21
|
+
return process.env.API_URL || "http://localhost:3000/api/v1";
|
|
22
|
+
}
|
|
23
|
+
async function consumerFetch(path, token) {
|
|
24
|
+
var _a;
|
|
25
|
+
try {
|
|
26
|
+
const res = await fetch(`${getApiUrl()}${path}`, {
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Authorization: `Bearer ${token}`
|
|
30
|
+
},
|
|
31
|
+
cache: "no-store"
|
|
32
|
+
});
|
|
33
|
+
if (!res.ok) return null;
|
|
34
|
+
const json = await res.json();
|
|
35
|
+
return (_a = json.data) != null ? _a : json;
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function fetchConsumerMe(token) {
|
|
41
|
+
return consumerFetch("/consumer/me", token);
|
|
42
|
+
}
|
|
43
|
+
async function fetchConsumerConversations(token) {
|
|
44
|
+
var _a;
|
|
45
|
+
const apiKey = process.env.API_KEY;
|
|
46
|
+
const headers = __spreadValues({
|
|
47
|
+
"Content-Type": "application/json",
|
|
48
|
+
Authorization: `Bearer ${token}`
|
|
49
|
+
}, apiKey ? { "X-API-Key": apiKey } : {});
|
|
50
|
+
try {
|
|
51
|
+
const res = await fetch(`${getApiUrl()}/consumer/me/conversations`, { headers, cache: "no-store" });
|
|
52
|
+
if (!res.ok) return [];
|
|
53
|
+
const json = await res.json();
|
|
54
|
+
return (_a = json.data) != null ? _a : [];
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function fetchConsumerMessages(token, contactId) {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
try {
|
|
62
|
+
const res = await fetch(
|
|
63
|
+
`${getApiUrl()}/consumer/me/contacts/${contactId}/messages?per_page=100`,
|
|
64
|
+
{
|
|
65
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
66
|
+
cache: "no-store"
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
if (!res.ok) return { messages: [], contact: null };
|
|
70
|
+
const json = await res.json();
|
|
71
|
+
return {
|
|
72
|
+
messages: (_a = json.data) != null ? _a : [],
|
|
73
|
+
contact: (_b = json.contact) != null ? _b : null
|
|
74
|
+
};
|
|
75
|
+
} catch (e) {
|
|
76
|
+
return { messages: [], contact: null };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
CONSUMER_TOKEN_COOKIE,
|
|
81
|
+
fetchConsumerConversations,
|
|
82
|
+
fetchConsumerMe,
|
|
83
|
+
fetchConsumerMessages
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=consumer-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/consumer-session.ts"],"sourcesContent":["/**\n * Server-side consumer session helpers.\n * Runs on the server only — accepts the JWT token read from cookies by the page component.\n */\n\nexport const CONSUMER_TOKEN_COOKIE = 'ks_consumer_token';\n\nimport type { Consumer, ConversationSummary, Message, ContactSummary } from '../types/api/consumer';\nexport type { Consumer, ConversationSummary, Message, ContactSummary };\n\nfunction getApiUrl(): string {\n return process.env.API_URL || 'http://localhost:3000/api/v1';\n}\n\nasync function consumerFetch<T>(path: string, token: string): Promise<T | null> {\n try {\n const res = await fetch(`${getApiUrl()}${path}`, {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n cache: 'no-store',\n });\n if (!res.ok) return null;\n const json = await res.json();\n return (json.data ?? json) as T;\n } catch {\n return null;\n }\n}\n\nexport async function fetchConsumerMe(token: string): Promise<Consumer | null> {\n return consumerFetch<Consumer>('/consumer/me', token);\n}\n\nexport async function fetchConsumerConversations(token: string): Promise<ConversationSummary[]> {\n const apiKey = process.env.API_KEY;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n ...(apiKey ? { 'X-API-Key': apiKey } : {}),\n };\n try {\n const res = await fetch(`${getApiUrl()}/consumer/me/conversations`, { headers, cache: 'no-store' });\n if (!res.ok) return [];\n const json = await res.json();\n return (json.data ?? []) as ConversationSummary[];\n } catch {\n return [];\n }\n}\n\nexport async function fetchConsumerMessages(\n token: string,\n contactId: number\n): Promise<{ messages: Message[]; contact: ContactSummary | null }> {\n try {\n const res = await fetch(\n `${getApiUrl()}/consumer/me/contacts/${contactId}/messages?per_page=100`,\n {\n headers: { Authorization: `Bearer ${token}` },\n cache: 'no-store',\n }\n );\n if (!res.ok) return { messages: [], contact: null };\n const json = await res.json();\n return {\n messages: (json.data ?? []) as Message[],\n contact: (json.contact ?? null) as ContactSummary | null,\n };\n } catch {\n return { messages: [], contact: null };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAKO,IAAM,wBAAwB;AAKrC,SAAS,YAAoB;AAC3B,SAAO,QAAQ,IAAI,WAAW;AAChC;AAEA,eAAe,cAAiB,MAAc,OAAkC;AAdhF;AAeE,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,IAAI,IAAI;AAAA,MAC/C,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAQ,UAAK,SAAL,YAAa;AAAA,EACvB,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAgB,OAAyC;AAC7E,SAAO,cAAwB,gBAAgB,KAAK;AACtD;AAEA,eAAsB,2BAA2B,OAA+C;AAnChG;AAoCE,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,eAAe,UAAU,KAAK;AAAA,KAC1B,SAAS,EAAE,aAAa,OAAO,IAAI,CAAC;AAE1C,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,8BAA8B,EAAE,SAAS,OAAO,WAAW,CAAC;AAClG,QAAI,CAAC,IAAI,GAAI,QAAO,CAAC;AACrB,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAQ,UAAK,SAAL,YAAa,CAAC;AAAA,EACxB,SAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,sBACpB,OACA,WACkE;AAvDpE;AAwDE,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAG,UAAU,CAAC,yBAAyB,SAAS;AAAA,MAChD;AAAA,QACE,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,QAC5C,OAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,CAAC,IAAI,GAAI,QAAO,EAAE,UAAU,CAAC,GAAG,SAAS,KAAK;AAClD,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,WAAO;AAAA,MACL,WAAW,UAAK,SAAL,YAAa,CAAC;AAAA,MACzB,UAAU,UAAK,YAAL,YAAgB;AAAA,IAC5B;AAAA,EACF,SAAQ;AACN,WAAO,EAAE,UAAU,CAAC,GAAG,SAAS,KAAK;AAAA,EACvC;AACF;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { C as CompanyInformation } from '../company-information-C1pP-SvU.js';
|
|
2
|
+
import '../photos-CmBdWiuZ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the primary and secondary CTA hrefs used across the site.
|
|
6
|
+
*
|
|
7
|
+
* Resolution order for primaryHref:
|
|
8
|
+
* 1. portal_url — set by backend when account has consumer portal enabled
|
|
9
|
+
* 2. external_management_url — booking platform URL from the API
|
|
10
|
+
* 3. /contact — final fallback
|
|
11
|
+
*
|
|
12
|
+
* No per-site configuration needed. Enable the portal in the admin console and
|
|
13
|
+
* every CTA across the site automatically routes to the portal.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** True when the href is absolute (external); use for target="_blank" and rel="noopener noreferrer". */
|
|
17
|
+
declare function isExternalCtaUrl(href: string): boolean;
|
|
18
|
+
interface ResolvedCtaUrls {
|
|
19
|
+
primaryHref: string;
|
|
20
|
+
secondaryHref: string;
|
|
21
|
+
hasSecondary: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extracts the pathname from portal_url for use in client-side route comparisons.
|
|
25
|
+
* Handles both absolute URLs (https://domain.com/portal → /portal) and relative paths (/portal).
|
|
26
|
+
*
|
|
27
|
+
* Returns null when:
|
|
28
|
+
* - portal_url is not set
|
|
29
|
+
* - the URL cannot be resolved to a non-root pathname (would otherwise match every page)
|
|
30
|
+
*/
|
|
31
|
+
declare function resolvePortalPath(companyInformation?: CompanyInformation | null): string | null;
|
|
32
|
+
declare function resolveCtaUrls(companyInformation?: CompanyInformation | null): ResolvedCtaUrls;
|
|
33
|
+
|
|
34
|
+
export { type ResolvedCtaUrls, isExternalCtaUrl, resolveCtaUrls, resolvePortalPath };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/lib/cta-urls.ts
|
|
2
|
+
var CONTACT_PATH = "/contact";
|
|
3
|
+
function isExternalCtaUrl(href) {
|
|
4
|
+
return href.startsWith("http://") || href.startsWith("https://");
|
|
5
|
+
}
|
|
6
|
+
function resolvePortalPath(companyInformation) {
|
|
7
|
+
var _a;
|
|
8
|
+
const url = (_a = companyInformation == null ? void 0 : companyInformation.portal_url) == null ? void 0 : _a.trim();
|
|
9
|
+
if (!url) return null;
|
|
10
|
+
let pathname = null;
|
|
11
|
+
try {
|
|
12
|
+
pathname = new URL(url).pathname;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
pathname = url.startsWith("/") ? url : null;
|
|
15
|
+
}
|
|
16
|
+
if (!pathname || pathname === "/") return null;
|
|
17
|
+
return pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
18
|
+
}
|
|
19
|
+
function resolveCtaUrls(companyInformation) {
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
const portalUrl = ((_a = companyInformation == null ? void 0 : companyInformation.portal_url) == null ? void 0 : _a.trim()) || null;
|
|
22
|
+
const externalUrl = ((_b = companyInformation == null ? void 0 : companyInformation.external_management_url) == null ? void 0 : _b.trim()) || null;
|
|
23
|
+
const primaryHref = (_c = portalUrl != null ? portalUrl : externalUrl) != null ? _c : CONTACT_PATH;
|
|
24
|
+
const secondaryHref = CONTACT_PATH;
|
|
25
|
+
const hasSecondary = primaryHref !== CONTACT_PATH;
|
|
26
|
+
return { primaryHref, secondaryHref, hasSecondary };
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
isExternalCtaUrl,
|
|
30
|
+
resolveCtaUrls,
|
|
31
|
+
resolvePortalPath
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=cta-urls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/cta-urls.ts"],"sourcesContent":["/**\n * Resolves the primary and secondary CTA hrefs used across the site.\n *\n * Resolution order for primaryHref:\n * 1. portal_url — set by backend when account has consumer portal enabled\n * 2. external_management_url — booking platform URL from the API\n * 3. /contact — final fallback\n *\n * No per-site configuration needed. Enable the portal in the admin console and\n * every CTA across the site automatically routes to the portal.\n */\n\nimport type { CompanyInformation } from '../types/api/company-information';\n\nconst CONTACT_PATH = '/contact';\n\n/** True when the href is absolute (external); use for target=\"_blank\" and rel=\"noopener noreferrer\". */\nexport function isExternalCtaUrl(href: string): boolean {\n return href.startsWith('http://') || href.startsWith('https://');\n}\n\nexport interface ResolvedCtaUrls {\n primaryHref: string;\n secondaryHref: string;\n hasSecondary: boolean;\n}\n\n/**\n * Extracts the pathname from portal_url for use in client-side route comparisons.\n * Handles both absolute URLs (https://domain.com/portal → /portal) and relative paths (/portal).\n *\n * Returns null when:\n * - portal_url is not set\n * - the URL cannot be resolved to a non-root pathname (would otherwise match every page)\n */\nexport function resolvePortalPath(\n companyInformation?: CompanyInformation | null\n): string | null {\n const url = companyInformation?.portal_url?.trim();\n if (!url) return null;\n\n let pathname: string | null = null;\n try {\n pathname = new URL(url).pathname;\n } catch {\n pathname = url.startsWith('/') ? url : null;\n }\n\n if (!pathname || pathname === '/') return null;\n\n // Normalize trailing slash so startsWith comparisons are consistent.\n return pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;\n}\n\nexport function resolveCtaUrls(\n companyInformation?: CompanyInformation | null\n): ResolvedCtaUrls {\n const portalUrl = companyInformation?.portal_url?.trim() || null;\n const externalUrl = companyInformation?.external_management_url?.trim() || null;\n const primaryHref = portalUrl ?? externalUrl ?? CONTACT_PATH;\n const secondaryHref = CONTACT_PATH;\n const hasSecondary = primaryHref !== CONTACT_PATH;\n\n return { primaryHref, secondaryHref, hasSecondary };\n}\n"],"mappings":";AAcA,IAAM,eAAe;AAGd,SAAS,iBAAiB,MAAuB;AACtD,SAAO,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,UAAU;AACjE;AAgBO,SAAS,kBACd,oBACe;AArCjB;AAsCE,QAAM,OAAM,8DAAoB,eAApB,mBAAgC;AAC5C,MAAI,CAAC,IAAK,QAAO;AAEjB,MAAI,WAA0B;AAC9B,MAAI;AACF,eAAW,IAAI,IAAI,GAAG,EAAE;AAAA,EAC1B,SAAQ;AACN,eAAW,IAAI,WAAW,GAAG,IAAI,MAAM;AAAA,EACzC;AAEA,MAAI,CAAC,YAAY,aAAa,IAAK,QAAO;AAG1C,SAAO,SAAS,SAAS,GAAG,IAAI,SAAS,MAAM,GAAG,EAAE,IAAI;AAC1D;AAEO,SAAS,eACd,oBACiB;AAxDnB;AAyDE,QAAM,cAAY,8DAAoB,eAApB,mBAAgC,WAAU;AAC5D,QAAM,gBAAc,8DAAoB,4BAApB,mBAA6C,WAAU;AAC3E,QAAM,eAAc,qCAAa,gBAAb,YAA4B;AAChD,QAAM,gBAAgB;AACtB,QAAM,eAAe,gBAAgB;AAErC,SAAO,EAAE,aAAa,eAAe,aAAa;AACpD;","names":[]}
|
package/dist/lib/server-api.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { F as FormDefinition } from '../form-C94A_PX_.js';
|
|
2
|
-
import { C as CompanyInformation
|
|
2
|
+
import { C as CompanyInformation } from '../company-information-C1pP-SvU.js';
|
|
3
|
+
import { P as Package, S as Service } from '../package-IU_GpDA0.js';
|
|
3
4
|
import { W as WebsitePhotos } from '../website-photos-Cl1YqAno.js';
|
|
4
5
|
import '../photos-CmBdWiuZ.js';
|
|
5
6
|
|
package/dist/lib/server-api.js
CHANGED
|
@@ -100,7 +100,7 @@ async function getJobPosting(slug) {
|
|
|
100
100
|
return serverFetch(`/public/job_postings/by_slug/${slug}`, defaultOptions);
|
|
101
101
|
}
|
|
102
102
|
async function getSocialPosts() {
|
|
103
|
-
return serverFetch("/public/social_posts",
|
|
103
|
+
return serverFetch("/public/social_posts", { cache: "no-store" });
|
|
104
104
|
}
|
|
105
105
|
async function getPackages() {
|
|
106
106
|
return serverFetch("/public/packages", defaultOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/server-api.ts"],"sourcesContent":["/**\n * Server-side API client for SSR\n * API key is stored securely on the server - never exposed to browser\n */\n\nimport type { CompanyInformation } from '../types/api/company-information';\nimport type { Service } from '../types/api/service';\nimport type { Package } from '../types/api/package';\nimport type { WebsitePhotos } from '../types/api/website-photos';\n\nconst API_URL = process.env.API_URL || 'http://localhost:3000/api/v1';\nconst API_KEY = process.env.API_KEY || '';\n\ninterface FetchOptions {\n cache?: RequestCache;\n revalidate?: number;\n}\n\nasync function serverFetch<T>(endpoint: string, options: FetchOptions = {}): Promise<T | null> {\n const url = `${API_URL}${endpoint}`;\n \n try {\n const fetchOptions: RequestInit & { next?: { revalidate?: number } } = {\n headers: {\n 'X-API-Key': API_KEY,\n 'Content-Type': 'application/json',\n },\n cache: options.cache,\n };\n \n if (options.revalidate) {\n fetchOptions.next = { revalidate: options.revalidate };\n }\n \n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n console.error(`[Server API] Error ${response.status} for ${endpoint}`);\n return null;\n }\n\n const json = await response.json();\n \n // Rails API returns { data: [...], meta: {...} }\n return json.data ?? json;\n } catch (error) {\n console.error(`[Server API] Failed to fetch ${endpoint}:`, error);\n return null;\n }\n}\n\n/**\n * Generic serverApi object for flexible endpoint access\n */\nexport const serverApi = {\n get: <T = unknown>(endpoint: string, options?: FetchOptions): Promise<T | null> => {\n return serverFetch<T>(endpoint, options || { revalidate: 60 });\n }\n};\n\n// Revalidate data every 60 seconds (ISR)\nconst defaultOptions: FetchOptions = { revalidate: 60 };\n\nexport async function getCompanyInformation(): Promise<CompanyInformation | null> {\n return serverFetch<CompanyInformation>('/public/company_information', defaultOptions);\n}\n\n/** Ads config (e.g. Meta Pixel). Returns { meta_pixel_id?: string } or {}. Only present when account has connected Meta Ads. */\nexport async function getAdsConfig(): Promise<{ meta_pixel_id?: string } | null> {\n const data = await serverFetch<{ meta_pixel_id?: string }>('/public/ads_config', defaultOptions);\n return data ?? null;\n}\n\n/** Extract Meta Pixel ID from ads config for use with <MetaPixel pixelId={...} />. Only returns a value when present and valid (numeric). */\nexport function getMetaPixelId(adsConfig: { meta_pixel_id?: string } | null | undefined): string | null {\n const id = adsConfig && typeof adsConfig === 'object' && 'meta_pixel_id' in adsConfig && adsConfig.meta_pixel_id;\n const str = id != null && id !== '' ? String(id).trim() : '';\n return str !== '' && str !== 'null' && /^\\d+$/.test(str) ? str : null;\n}\n\nexport type AnalyticsConfig = {\n /** PostHog project API key — platform-wide, from POSTHOG_API_KEY env var on the Rails server. */\n posthog_api_key?: string;\n /** Per-site GTM container ID (e.g. GTM-ABC123), provisioned by Keystone. */\n gtm_container_public_id?: string;\n /**\n * Environment identifier from KEYSTONE_ENV on the Rails server (e.g. \"production\", \"staging\",\n * \"development\"). Registered as a PostHog super property on every event so the sync job can\n * filter by environment and avoid cross-environment data contamination.\n */\n environment?: string;\n};\n\n/** Analytics config for customer sites. Returns platform-wide analytics keys (e.g. PostHog). */\nexport async function getAnalyticsConfig(): Promise<AnalyticsConfig | null> {\n const data = await serverFetch<AnalyticsConfig>('/public/analytics_config', defaultOptions);\n return data ?? null;\n}\n\n/** Extract PostHog API key from analytics config for use with <PostHogProvider apiKey={...} />. */\nexport function getPostHogApiKey(analyticsConfig: AnalyticsConfig | null | undefined): string | null {\n const key = analyticsConfig?.posthog_api_key;\n const str = key != null && key !== '' ? String(key).trim() : '';\n return str !== '' && str !== 'null' ? str : null;\n}\n\n/** Extract GTM container ID from analytics config for use with <GoogleTagManager containerId={...} />. */\nexport function getGtmContainerPublicId(analyticsConfig: AnalyticsConfig | null | undefined): string | null {\n const value = analyticsConfig?.gtm_container_public_id;\n const str = value != null && value !== '' ? String(value).trim() : '';\n return str !== '' && str !== 'null' && /^GTM-[A-Z0-9]+$/i.test(str) ? str : null;\n}\n\n/** Extract environment string from analytics config for use with <PostHogProvider environment={...} />. */\nexport function getKeystoneEnvironment(analyticsConfig: AnalyticsConfig | null | undefined): string {\n return analyticsConfig?.environment?.trim() || 'development';\n}\n\nexport async function getServices(): Promise<Service[] | null> {\n return serverFetch<Service[]>('/public/services', defaultOptions);\n}\n\nexport async function getService(slug: string): Promise<Service | null> {\n return serverFetch<Service>(`/public/services/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getLocations() {\n return serverFetch('/public/locations', defaultOptions);\n}\n\nexport async function getLocation(slug: string) {\n return serverFetch(`/public/locations/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getReviews() {\n return serverFetch('/public/reviews', defaultOptions);\n}\n\nexport async function getFAQs() {\n return serverFetch('/public/faq_questions', defaultOptions);\n}\n\nexport async function getBlogPosts() {\n return serverFetch('/public/blog_posts', defaultOptions);\n}\n\nexport async function getBlogPost(slug: string) {\n return serverFetch(`/public/blog_posts/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getTeamMembers() {\n return serverFetch('/public/team_members', defaultOptions);\n}\n\nexport async function getWebsitePhotos(): Promise<WebsitePhotos | null> {\n return serverFetch<WebsitePhotos>('/public/website_photos', defaultOptions);\n}\n\nexport async function getJobPostings() {\n return serverFetch('/public/job_postings', defaultOptions);\n}\n\nexport async function getJobPosting(slug: string) {\n return serverFetch(`/public/job_postings/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getSocialPosts() {\n return serverFetch('/public/social_posts', defaultOptions);\n}\n\n/** Packages (bundles of service items). */\nexport async function getPackages(): Promise<Package[] | null> {\n return serverFetch<Package[]>('/public/packages', defaultOptions);\n}\n\nexport async function getPackage(slug: string): Promise<Package | null> {\n return serverFetch<Package>(`/public/packages/by_slug/${encodeURIComponent(slug)}`, defaultOptions);\n}\n\n// Alias for testimonials (API uses \"reviews\")\nexport async function getTestimonials() {\n return getReviews();\n}\n\n/** Form definition for dynamic form rendering, fetched by form_type. */\nexport async function getForm(formType: string) {\n type FormDefinition = import('../types/api/form').FormDefinition;\n return serverFetch<FormDefinition>(`/public/forms/${encodeURIComponent(formType)}`, defaultOptions);\n}\n\n/** Form definition for dynamic form rendering, fetched by numeric ID. */\nexport async function getFormById(id: number | string) {\n type FormDefinition = import('../types/api/form').FormDefinition;\n return serverFetch<FormDefinition>(`/public/form_by_id/${encodeURIComponent(id)}`, defaultOptions);\n}\n\n"],"mappings":";AAUA,IAAM,UAAU,QAAQ,IAAI,WAAW;AACvC,IAAM,UAAU,QAAQ,IAAI,WAAW;AAOvC,eAAe,YAAe,UAAkB,UAAwB,CAAC,GAAsB;AAlB/F;AAmBE,QAAM,MAAM,GAAG,OAAO,GAAG,QAAQ;AAEjC,MAAI;AACF,UAAM,eAAiE;AAAA,MACrE,SAAS;AAAA,QACP,aAAa;AAAA,QACb,gBAAgB;AAAA,MAClB;AAAA,MACA,OAAO,QAAQ;AAAA,IACjB;AAEA,QAAI,QAAQ,YAAY;AACtB,mBAAa,OAAO,EAAE,YAAY,QAAQ,WAAW;AAAA,IACvD;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK,YAAY;AAE9C,QAAI,CAAC,SAAS,IAAI;AAChB,cAAQ,MAAM,sBAAsB,SAAS,MAAM,QAAQ,QAAQ,EAAE;AACrE,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,YAAO,UAAK,SAAL,YAAa;AAAA,EACtB,SAAS,OAAO;AACd,YAAQ,MAAM,gCAAgC,QAAQ,KAAK,KAAK;AAChE,WAAO;AAAA,EACT;AACF;AAKO,IAAM,YAAY;AAAA,EACvB,KAAK,CAAc,UAAkB,YAA8C;AACjF,WAAO,YAAe,UAAU,WAAW,EAAE,YAAY,GAAG,CAAC;AAAA,EAC/D;AACF;AAGA,IAAM,iBAA+B,EAAE,YAAY,GAAG;AAEtD,eAAsB,wBAA4D;AAChF,SAAO,YAAgC,+BAA+B,cAAc;AACtF;AAGA,eAAsB,eAA2D;AAC/E,QAAM,OAAO,MAAM,YAAwC,sBAAsB,cAAc;AAC/F,SAAO,sBAAQ;AACjB;AAGO,SAAS,eAAe,WAAyE;AACtG,QAAM,KAAK,aAAa,OAAO,cAAc,YAAY,mBAAmB,aAAa,UAAU;AACnG,QAAM,MAAM,MAAM,QAAQ,OAAO,KAAK,OAAO,EAAE,EAAE,KAAK,IAAI;AAC1D,SAAO,QAAQ,MAAM,QAAQ,UAAU,QAAQ,KAAK,GAAG,IAAI,MAAM;AACnE;AAgBA,eAAsB,qBAAsD;AAC1E,QAAM,OAAO,MAAM,YAA6B,4BAA4B,cAAc;AAC1F,SAAO,sBAAQ;AACjB;AAGO,SAAS,iBAAiB,iBAAoE;AACnG,QAAM,MAAM,mDAAiB;AAC7B,QAAM,MAAM,OAAO,QAAQ,QAAQ,KAAK,OAAO,GAAG,EAAE,KAAK,IAAI;AAC7D,SAAO,QAAQ,MAAM,QAAQ,SAAS,MAAM;AAC9C;AAGO,SAAS,wBAAwB,iBAAoE;AAC1G,QAAM,QAAQ,mDAAiB;AAC/B,QAAM,MAAM,SAAS,QAAQ,UAAU,KAAK,OAAO,KAAK,EAAE,KAAK,IAAI;AACnE,SAAO,QAAQ,MAAM,QAAQ,UAAU,mBAAmB,KAAK,GAAG,IAAI,MAAM;AAC9E;AAGO,SAAS,uBAAuB,iBAA6D;AAlHpG;AAmHE,WAAO,wDAAiB,gBAAjB,mBAA8B,WAAU;AACjD;AAEA,eAAsB,cAAyC;AAC7D,SAAO,YAAuB,oBAAoB,cAAc;AAClE;AAEA,eAAsB,WAAW,MAAuC;AACtE,SAAO,YAAqB,4BAA4B,IAAI,IAAI,cAAc;AAChF;AAEA,eAAsB,eAAe;AACnC,SAAO,YAAY,qBAAqB,cAAc;AACxD;AAEA,eAAsB,YAAY,MAAc;AAC9C,SAAO,YAAY,6BAA6B,IAAI,IAAI,cAAc;AACxE;AAEA,eAAsB,aAAa;AACjC,SAAO,YAAY,mBAAmB,cAAc;AACtD;AAEA,eAAsB,UAAU;AAC9B,SAAO,YAAY,yBAAyB,cAAc;AAC5D;AAEA,eAAsB,eAAe;AACnC,SAAO,YAAY,sBAAsB,cAAc;AACzD;AAEA,eAAsB,YAAY,MAAc;AAC9C,SAAO,YAAY,8BAA8B,IAAI,IAAI,cAAc;AACzE;AAEA,eAAsB,iBAAiB;AACrC,SAAO,YAAY,wBAAwB,cAAc;AAC3D;AAEA,eAAsB,mBAAkD;AACtE,SAAO,YAA2B,0BAA0B,cAAc;AAC5E;AAEA,eAAsB,iBAAiB;AACrC,SAAO,YAAY,wBAAwB,cAAc;AAC3D;AAEA,eAAsB,cAAc,MAAc;AAChD,SAAO,YAAY,gCAAgC,IAAI,IAAI,cAAc;AAC3E;AAEA,eAAsB,iBAAiB;AACrC,SAAO,YAAY,wBAAwB,cAAc;AAC3D;AAGA,eAAsB,cAAyC;AAC7D,SAAO,YAAuB,oBAAoB,cAAc;AAClE;AAEA,eAAsB,WAAW,MAAuC;AACtE,SAAO,YAAqB,4BAA4B,mBAAmB,IAAI,CAAC,IAAI,cAAc;AACpG;AAGA,eAAsB,kBAAkB;AACtC,SAAO,WAAW;AACpB;AAGA,eAAsB,QAAQ,UAAkB;AAE9C,SAAO,YAA4B,iBAAiB,mBAAmB,QAAQ,CAAC,IAAI,cAAc;AACpG;AAGA,eAAsB,YAAY,IAAqB;AAErD,SAAO,YAA4B,sBAAsB,mBAAmB,EAAE,CAAC,IAAI,cAAc;AACnG;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/server-api.ts"],"sourcesContent":["/**\n * Server-side API client for SSR\n * API key is stored securely on the server - never exposed to browser\n */\n\nimport type { CompanyInformation } from '../types/api/company-information';\nimport type { Service } from '../types/api/service';\nimport type { Package } from '../types/api/package';\nimport type { WebsitePhotos } from '../types/api/website-photos';\n\nconst API_URL = process.env.API_URL || 'http://localhost:3000/api/v1';\nconst API_KEY = process.env.API_KEY || '';\n\ninterface FetchOptions {\n cache?: RequestCache;\n revalidate?: number;\n}\n\nasync function serverFetch<T>(endpoint: string, options: FetchOptions = {}): Promise<T | null> {\n const url = `${API_URL}${endpoint}`;\n \n try {\n const fetchOptions: RequestInit & { next?: { revalidate?: number } } = {\n headers: {\n 'X-API-Key': API_KEY,\n 'Content-Type': 'application/json',\n },\n cache: options.cache,\n };\n \n if (options.revalidate) {\n fetchOptions.next = { revalidate: options.revalidate };\n }\n \n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n console.error(`[Server API] Error ${response.status} for ${endpoint}`);\n return null;\n }\n\n const json = await response.json();\n \n // Rails API returns { data: [...], meta: {...} }\n return json.data ?? json;\n } catch (error) {\n console.error(`[Server API] Failed to fetch ${endpoint}:`, error);\n return null;\n }\n}\n\n/**\n * Generic serverApi object for flexible endpoint access\n */\nexport const serverApi = {\n get: <T = unknown>(endpoint: string, options?: FetchOptions): Promise<T | null> => {\n return serverFetch<T>(endpoint, options || { revalidate: 60 });\n }\n};\n\n// Revalidate data every 60 seconds (ISR)\nconst defaultOptions: FetchOptions = { revalidate: 60 };\n\nexport async function getCompanyInformation(): Promise<CompanyInformation | null> {\n return serverFetch<CompanyInformation>('/public/company_information', defaultOptions);\n}\n\n/** Ads config (e.g. Meta Pixel). Returns { meta_pixel_id?: string } or {}. Only present when account has connected Meta Ads. */\nexport async function getAdsConfig(): Promise<{ meta_pixel_id?: string } | null> {\n const data = await serverFetch<{ meta_pixel_id?: string }>('/public/ads_config', defaultOptions);\n return data ?? null;\n}\n\n/** Extract Meta Pixel ID from ads config for use with <MetaPixel pixelId={...} />. Only returns a value when present and valid (numeric). */\nexport function getMetaPixelId(adsConfig: { meta_pixel_id?: string } | null | undefined): string | null {\n const id = adsConfig && typeof adsConfig === 'object' && 'meta_pixel_id' in adsConfig && adsConfig.meta_pixel_id;\n const str = id != null && id !== '' ? String(id).trim() : '';\n return str !== '' && str !== 'null' && /^\\d+$/.test(str) ? str : null;\n}\n\nexport type AnalyticsConfig = {\n /** PostHog project API key — platform-wide, from POSTHOG_API_KEY env var on the Rails server. */\n posthog_api_key?: string;\n /** Per-site GTM container ID (e.g. GTM-ABC123), provisioned by Keystone. */\n gtm_container_public_id?: string;\n /**\n * Environment identifier from KEYSTONE_ENV on the Rails server (e.g. \"production\", \"staging\",\n * \"development\"). Registered as a PostHog super property on every event so the sync job can\n * filter by environment and avoid cross-environment data contamination.\n */\n environment?: string;\n};\n\n/** Analytics config for customer sites. Returns platform-wide analytics keys (e.g. PostHog). */\nexport async function getAnalyticsConfig(): Promise<AnalyticsConfig | null> {\n const data = await serverFetch<AnalyticsConfig>('/public/analytics_config', defaultOptions);\n return data ?? null;\n}\n\n/** Extract PostHog API key from analytics config for use with <PostHogProvider apiKey={...} />. */\nexport function getPostHogApiKey(analyticsConfig: AnalyticsConfig | null | undefined): string | null {\n const key = analyticsConfig?.posthog_api_key;\n const str = key != null && key !== '' ? String(key).trim() : '';\n return str !== '' && str !== 'null' ? str : null;\n}\n\n/** Extract GTM container ID from analytics config for use with <GoogleTagManager containerId={...} />. */\nexport function getGtmContainerPublicId(analyticsConfig: AnalyticsConfig | null | undefined): string | null {\n const value = analyticsConfig?.gtm_container_public_id;\n const str = value != null && value !== '' ? String(value).trim() : '';\n return str !== '' && str !== 'null' && /^GTM-[A-Z0-9]+$/i.test(str) ? str : null;\n}\n\n/** Extract environment string from analytics config for use with <PostHogProvider environment={...} />. */\nexport function getKeystoneEnvironment(analyticsConfig: AnalyticsConfig | null | undefined): string {\n return analyticsConfig?.environment?.trim() || 'development';\n}\n\nexport async function getServices(): Promise<Service[] | null> {\n return serverFetch<Service[]>('/public/services', defaultOptions);\n}\n\nexport async function getService(slug: string): Promise<Service | null> {\n return serverFetch<Service>(`/public/services/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getLocations() {\n return serverFetch('/public/locations', defaultOptions);\n}\n\nexport async function getLocation(slug: string) {\n return serverFetch(`/public/locations/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getReviews() {\n return serverFetch('/public/reviews', defaultOptions);\n}\n\nexport async function getFAQs() {\n return serverFetch('/public/faq_questions', defaultOptions);\n}\n\nexport async function getBlogPosts() {\n return serverFetch('/public/blog_posts', defaultOptions);\n}\n\nexport async function getBlogPost(slug: string) {\n return serverFetch(`/public/blog_posts/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getTeamMembers() {\n return serverFetch('/public/team_members', defaultOptions);\n}\n\nexport async function getWebsitePhotos(): Promise<WebsitePhotos | null> {\n return serverFetch<WebsitePhotos>('/public/website_photos', defaultOptions);\n}\n\nexport async function getJobPostings() {\n return serverFetch('/public/job_postings', defaultOptions);\n}\n\nexport async function getJobPosting(slug: string) {\n return serverFetch(`/public/job_postings/by_slug/${slug}`, defaultOptions);\n}\n\nexport async function getSocialPosts() {\n // Social payloads can exceed Next's data-cache item size; avoid noisy build warnings.\n return serverFetch('/public/social_posts', { cache: 'no-store' });\n}\n\n/** Packages (bundles of service items). */\nexport async function getPackages(): Promise<Package[] | null> {\n return serverFetch<Package[]>('/public/packages', defaultOptions);\n}\n\nexport async function getPackage(slug: string): Promise<Package | null> {\n return serverFetch<Package>(`/public/packages/by_slug/${encodeURIComponent(slug)}`, defaultOptions);\n}\n\n// Alias for testimonials (API uses \"reviews\")\nexport async function getTestimonials() {\n return getReviews();\n}\n\n/** Form definition for dynamic form rendering, fetched by form_type. */\nexport async function getForm(formType: string) {\n type FormDefinition = import('../types/api/form').FormDefinition;\n return serverFetch<FormDefinition>(`/public/forms/${encodeURIComponent(formType)}`, defaultOptions);\n}\n\n/** Form definition for dynamic form rendering, fetched by numeric ID. */\nexport async function getFormById(id: number | string) {\n type FormDefinition = import('../types/api/form').FormDefinition;\n return serverFetch<FormDefinition>(`/public/form_by_id/${encodeURIComponent(id)}`, defaultOptions);\n}\n\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { F as FormDefinition } from '../../form-C94A_PX_.js';
|
|
3
|
+
|
|
4
|
+
type FormDefinitionsContextValue = {
|
|
5
|
+
leadFormDefinition: FormDefinition | null;
|
|
6
|
+
jobApplicationFormDefinition: FormDefinition | null;
|
|
7
|
+
marketingListSignupFormDefinition: FormDefinition | null;
|
|
8
|
+
};
|
|
9
|
+
declare function FormDefinitionsProvider(props: {
|
|
10
|
+
leadFormDefinition: FormDefinition | null;
|
|
11
|
+
jobApplicationFormDefinition: FormDefinition | null;
|
|
12
|
+
marketingListSignupFormDefinition: FormDefinition | null;
|
|
13
|
+
children: React__default.ReactNode;
|
|
14
|
+
}): React__default.JSX.Element;
|
|
15
|
+
declare function useFormDefinitions(): FormDefinitionsContextValue;
|
|
16
|
+
|
|
17
|
+
export { type FormDefinitionsContextValue, FormDefinitionsProvider, useFormDefinitions };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/next/contexts/form-definitions.tsx
|
|
4
|
+
import React, { createContext, useContext } from "react";
|
|
5
|
+
var FormDefinitionsContext = createContext({
|
|
6
|
+
leadFormDefinition: null,
|
|
7
|
+
jobApplicationFormDefinition: null,
|
|
8
|
+
marketingListSignupFormDefinition: null
|
|
9
|
+
});
|
|
10
|
+
function FormDefinitionsProvider(props) {
|
|
11
|
+
const { leadFormDefinition, jobApplicationFormDefinition, marketingListSignupFormDefinition, children } = props;
|
|
12
|
+
return /* @__PURE__ */ React.createElement(FormDefinitionsContext.Provider, { value: { leadFormDefinition, jobApplicationFormDefinition, marketingListSignupFormDefinition } }, children);
|
|
13
|
+
}
|
|
14
|
+
function useFormDefinitions() {
|
|
15
|
+
return useContext(FormDefinitionsContext);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
FormDefinitionsProvider,
|
|
19
|
+
useFormDefinitions
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=form-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/next/contexts/form-definitions.tsx"],"sourcesContent":["'use client';\n\nimport React, { createContext, useContext } from 'react';\nimport type { FormDefinition } from '../../types/api/form';\n\nexport type FormDefinitionsContextValue = {\n leadFormDefinition: FormDefinition | null;\n jobApplicationFormDefinition: FormDefinition | null;\n marketingListSignupFormDefinition: FormDefinition | null;\n};\n\nconst FormDefinitionsContext = createContext<FormDefinitionsContextValue>({\n leadFormDefinition: null,\n jobApplicationFormDefinition: null,\n marketingListSignupFormDefinition: null,\n});\n\nexport function FormDefinitionsProvider(props: {\n leadFormDefinition: FormDefinition | null;\n jobApplicationFormDefinition: FormDefinition | null;\n marketingListSignupFormDefinition: FormDefinition | null;\n children: React.ReactNode;\n}) {\n const { leadFormDefinition, jobApplicationFormDefinition, marketingListSignupFormDefinition, children } = props;\n return (\n <FormDefinitionsContext.Provider value={{ leadFormDefinition, jobApplicationFormDefinition, marketingListSignupFormDefinition }}>\n {children}\n </FormDefinitionsContext.Provider>\n );\n}\n\nexport function useFormDefinitions(): FormDefinitionsContextValue {\n return useContext(FormDefinitionsContext);\n}\n\n"],"mappings":";;;AAEA,OAAO,SAAS,eAAe,kBAAkB;AASjD,IAAM,yBAAyB,cAA2C;AAAA,EACxE,oBAAoB;AAAA,EACpB,8BAA8B;AAAA,EAC9B,mCAAmC;AACrC,CAAC;AAEM,SAAS,wBAAwB,OAKrC;AACD,QAAM,EAAE,oBAAoB,8BAA8B,mCAAmC,SAAS,IAAI;AAC1G,SACE,oCAAC,uBAAuB,UAAvB,EAAgC,OAAO,EAAE,oBAAoB,8BAA8B,kCAAkC,KAC3H,QACH;AAEJ;AAEO,SAAS,qBAAkD;AAChE,SAAO,WAAW,sBAAsB;AAC1C;","names":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Theme } from '../../themes/index.js';
|
|
3
|
+
|
|
4
|
+
type GallerySection = "colors" | "fonts" | "elements" | "sections" | "pages";
|
|
5
|
+
/** Per-page hero overrides so each page shows the correct header (mock data has "About Us" in hero_generic). */
|
|
6
|
+
type HeroOverrides = {
|
|
7
|
+
genericTextHero?: {
|
|
8
|
+
label?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
};
|
|
12
|
+
faqHero?: {
|
|
13
|
+
label?: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
subtitle?: string;
|
|
16
|
+
};
|
|
17
|
+
testimonialsHero?: {
|
|
18
|
+
title?: string;
|
|
19
|
+
subtitle?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/** Page definitions mirroring customer-site-template: label, section order, and hero text per route. */
|
|
23
|
+
declare const GALLERY_PAGES: {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
sectionNames: string[];
|
|
27
|
+
heroOverrides?: HeroOverrides;
|
|
28
|
+
}[];
|
|
29
|
+
interface SectionMockData {
|
|
30
|
+
faqs?: unknown[] | null;
|
|
31
|
+
statistics?: {
|
|
32
|
+
title?: string;
|
|
33
|
+
subtitle?: string;
|
|
34
|
+
statistics?: Array<{
|
|
35
|
+
number?: string;
|
|
36
|
+
value?: string;
|
|
37
|
+
label: string;
|
|
38
|
+
icon?: string;
|
|
39
|
+
}>;
|
|
40
|
+
} | null;
|
|
41
|
+
values?: {
|
|
42
|
+
title?: string;
|
|
43
|
+
subtitle?: string;
|
|
44
|
+
values?: Array<{
|
|
45
|
+
title: string;
|
|
46
|
+
description: string;
|
|
47
|
+
icon?: string;
|
|
48
|
+
color?: string;
|
|
49
|
+
}>;
|
|
50
|
+
} | null;
|
|
51
|
+
aboutSection?: {
|
|
52
|
+
title?: string;
|
|
53
|
+
subtitle?: string;
|
|
54
|
+
ctaText?: string;
|
|
55
|
+
values?: Array<{
|
|
56
|
+
id?: string;
|
|
57
|
+
title: string;
|
|
58
|
+
description: string;
|
|
59
|
+
icon?: string;
|
|
60
|
+
}>;
|
|
61
|
+
} | null;
|
|
62
|
+
heroGeneric?: {
|
|
63
|
+
label?: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
subtitle?: string;
|
|
66
|
+
} | null;
|
|
67
|
+
heroHome?: {
|
|
68
|
+
headline?: string;
|
|
69
|
+
subhead?: string;
|
|
70
|
+
} | null;
|
|
71
|
+
faqHero?: {
|
|
72
|
+
label?: string;
|
|
73
|
+
title?: string;
|
|
74
|
+
subtitle?: string;
|
|
75
|
+
} | null;
|
|
76
|
+
faqHome?: {
|
|
77
|
+
title?: string;
|
|
78
|
+
subtitle?: string;
|
|
79
|
+
maxItems?: number;
|
|
80
|
+
} | null;
|
|
81
|
+
companyInformation?: unknown | null;
|
|
82
|
+
websitePhotos?: unknown[] | null;
|
|
83
|
+
services?: unknown[] | null;
|
|
84
|
+
testimonials?: unknown[] | null;
|
|
85
|
+
blogPosts?: unknown[] | null;
|
|
86
|
+
}
|
|
87
|
+
interface DesignGalleryProps {
|
|
88
|
+
theme: Theme;
|
|
89
|
+
onThemeChange: (theme: Theme) => void;
|
|
90
|
+
activeSection: GallerySection;
|
|
91
|
+
onSectionChange: (section: GallerySection) => void;
|
|
92
|
+
sectionData?: SectionMockData | null;
|
|
93
|
+
/** When activeSection is "pages", which page to show. */
|
|
94
|
+
activePage?: string;
|
|
95
|
+
onPageChange?: (pageId: string) => void;
|
|
96
|
+
/** When activeSection is "sections", which section to scroll to (slug). */
|
|
97
|
+
activeSectionSlug?: string;
|
|
98
|
+
onSectionSlugChange?: (slug: string) => void;
|
|
99
|
+
}
|
|
100
|
+
/** Renders the design gallery. When used inside the Next app, pass state from the app so hooks run in the same React tree (avoids useState-in-null context). */
|
|
101
|
+
declare function DesignGallery(props: DesignGalleryProps): React.JSX.Element;
|
|
102
|
+
|
|
103
|
+
export { DesignGallery, type DesignGalleryProps, GALLERY_PAGES, type GallerySection, type HeroOverrides, type SectionMockData };
|