keystone-design-bootstrap 1.0.61 → 1.0.63

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.
@@ -1,4 +1,4 @@
1
- import { S as Service, F as FormDefinition, P as Package, C as CompanyInformation } from '../../package-CB1tENyG.js';
1
+ import { S as Service, F as FormDefinition, P as Package, C as CompanyInformation } from '../../package-ByCAZw9u.js';
2
2
  import * as React from 'react';
3
3
  import React__default, { ComponentProps, ReactNode, FC } from 'react';
4
4
  export { Theme } from '../../themes/index.js';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
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
- import { C as CompanyInformation } from './package-CB1tENyG.js';
3
+ import { C as CompanyInformation } from './package-ByCAZw9u.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';
@@ -1,4 +1,4 @@
1
- import { C as CompanyInformation, F as FormDefinition, P as Package, S as Service } from '../package-CB1tENyG.js';
1
+ import { C as CompanyInformation, F as FormDefinition, P as Package, S as Service } from '../package-ByCAZw9u.js';
2
2
  import { W as WebsitePhotos } from '../website-photos-Cl1YqAno.js';
3
3
  import '../photos-CmBdWiuZ.js';
4
4
 
@@ -86,6 +86,8 @@ interface CompanyInformation {
86
86
  external_management_url?: string;
87
87
  /** Member portal URL for this account. When set, used as the primary CTA instead of external_management_url. */
88
88
  portal_url?: string | null;
89
+ terms_of_service_markdown?: string;
90
+ privacy_policy_markdown?: string;
89
91
  created_at: string;
90
92
  updated_at: string;
91
93
  photo_attachments?: PhotoAttachment[];
@@ -1,6 +1,6 @@
1
1
  import { Theme } from '../themes/index.js';
2
2
  export { B as BlogPost, a as BlogPostAuthor, b as BlogPostParams, c as BlogPostResponse, d as BlogPostTag } from '../blog-post-vWzW8yFb.js';
3
- export { C as CompanyInformation, a as CompanyInformationResponse, F as FormDefinition, b as FormFieldDefinition, c as FormFieldItem, d as FormType, O as OfferPublic, P as Package, e as PackageItem, S as Service, f as ServiceItem, g as ServiceParams, h as ServiceResponse } from '../package-CB1tENyG.js';
3
+ export { C as CompanyInformation, a as CompanyInformationResponse, F as FormDefinition, b as FormFieldDefinition, c as FormFieldItem, d as FormType, O as OfferPublic, P as Package, e as PackageItem, S as Service, f as ServiceItem, g as ServiceParams, h as ServiceResponse } from '../package-ByCAZw9u.js';
4
4
  import { P as PhotoAttachment } from '../photos-CmBdWiuZ.js';
5
5
  export { a as Photo } from '../photos-CmBdWiuZ.js';
6
6
  export { a as WebsitePhoto, W as WebsitePhotos, b as WebsitePhotosResponse } from '../website-photos-Cl1YqAno.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keystone-design-bootstrap",
3
- "version": "1.0.61",
3
+ "version": "1.0.63",
4
4
  "description": "Keystone Design Bootstrap - Sections, Elements, and Theme System for customer websites",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -154,7 +154,7 @@ function LockButton({ label = 'View price' }: { label?: string }) {
154
154
  );
155
155
  }
156
156
 
157
- function LoginWall({ message, cta = 'Sign in' }: { message: string; cta?: string }) {
157
+ function LoginWall({ message, cta }: { message: string; cta: string }) {
158
158
  return (
159
159
  <div className="flex flex-col items-center justify-center py-20 text-center">
160
160
  <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-secondary">
@@ -515,7 +515,7 @@ function BookPanel({
515
515
  isLoggedIn: boolean;
516
516
  }) {
517
517
  if (!isLoggedIn) {
518
- return <LoginWall message="Sign in to view booking options." />;
518
+ return <LoginWall message="Continue to view booking options." cta="View Booking Options" />;
519
519
  }
520
520
 
521
521
  if (bookingAllowsIframe) {
@@ -724,7 +724,13 @@ export async function PortalPage({
724
724
  {tab === 'packages' && (
725
725
  <PackagesPanel packages={packageList} isLoggedIn={isLoggedIn} portalHref={portalHref} />
726
726
  )}
727
- {tab === 'specials' && <SpecialsPanel specials={specials} />}
727
+ {tab === 'specials' && (
728
+ isLoggedIn ? (
729
+ <SpecialsPanel specials={specials} />
730
+ ) : (
731
+ <LoginWall message="Continue to view specials." cta="View Specials" />
732
+ )
733
+ )}
728
734
  {tab === 'messages' && (
729
735
  isLoggedIn ? (
730
736
  <MessagesPanel
@@ -734,7 +740,7 @@ export async function PortalPage({
734
740
  businessName={businessName}
735
741
  />
736
742
  ) : (
737
- <LoginWall message="Sign in to view your messages." />
743
+ <LoginWall message="Continue to view your messages." cta="View Messages" />
738
744
  )
739
745
  )}
740
746
  {tab === 'book' && (
@@ -2,12 +2,9 @@ import React from 'react';
2
2
  import { GenericTextHero, PolicyDocumentSection } from '../../design_system/sections';
3
3
  import { getCompanyInformation, getLocations } from '../../lib/server-api';
4
4
  import { buildLegalPlaceholders, replaceLegalPlaceholders } from './placeholders';
5
- import { DEFAULT_PRIVACY_POLICY_MARKDOWN } from './privacy-policy.default';
6
5
  import type { Location } from '../../types/api/location';
7
6
 
8
7
  export async function PrivacyPolicyPage(props?: { markdownOverride?: string }) {
9
- const markdownOverride = props?.markdownOverride;
10
-
11
8
  const [companyInformation, locationsData] = await Promise.all([getCompanyInformation(), getLocations()]);
12
9
  const locations = Array.isArray(locationsData) ? (locationsData as Location[]) : [];
13
10
  const primaryLocation = locations.find((l) => l.is_primary) ?? locations[0];
@@ -20,10 +17,10 @@ export async function PrivacyPolicyPage(props?: { markdownOverride?: string }) {
20
17
  primaryLocation?.email
21
18
  );
22
19
 
23
- const markdown = replaceLegalPlaceholders(
24
- (markdownOverride ?? DEFAULT_PRIVACY_POLICY_MARKDOWN).trim(),
25
- placeholders
26
- );
20
+ // Priority: explicit prop override → API-stored markdown
21
+ const resolvedMarkdown = props?.markdownOverride ?? companyInformation?.privacy_policy_markdown ?? '';
22
+
23
+ const markdown = replaceLegalPlaceholders(resolvedMarkdown.trim(), placeholders);
27
24
  const effectiveDate = `January 1, ${placeholders.effectiveYear}`;
28
25
 
29
26
  return (
@@ -33,4 +30,3 @@ export async function PrivacyPolicyPage(props?: { markdownOverride?: string }) {
33
30
  </main>
34
31
  );
35
32
  }
36
-
@@ -2,12 +2,9 @@ import React from 'react';
2
2
  import { GenericTextHero, PolicyDocumentSection } from '../../design_system/sections';
3
3
  import { getCompanyInformation, getLocations } from '../../lib/server-api';
4
4
  import { buildLegalPlaceholders, replaceLegalPlaceholders } from './placeholders';
5
- import { DEFAULT_TERMS_OF_SERVICE_MARKDOWN } from './terms-of-service.default';
6
5
  import type { Location } from '../../types/api/location';
7
6
 
8
7
  export async function TermsOfServicePage(props?: { markdownOverride?: string }) {
9
- const markdownOverride = props?.markdownOverride;
10
-
11
8
  const [companyInformation, locationsData] = await Promise.all([getCompanyInformation(), getLocations()]);
12
9
  const locations = Array.isArray(locationsData) ? (locationsData as Location[]) : [];
13
10
  const primaryLocation = locations.find((l) => l.is_primary) ?? locations[0];
@@ -20,10 +17,10 @@ export async function TermsOfServicePage(props?: { markdownOverride?: string })
20
17
  primaryLocation?.email
21
18
  );
22
19
 
23
- const markdown = replaceLegalPlaceholders(
24
- (markdownOverride ?? DEFAULT_TERMS_OF_SERVICE_MARKDOWN).trim(),
25
- placeholders
26
- );
20
+ // Priority: explicit prop override → API-stored markdown
21
+ const resolvedMarkdown = props?.markdownOverride ?? companyInformation?.terms_of_service_markdown ?? '';
22
+
23
+ const markdown = replaceLegalPlaceholders(resolvedMarkdown.trim(), placeholders);
27
24
  const effectiveDate = `January 1, ${placeholders.effectiveYear}`;
28
25
 
29
26
  return (
@@ -33,4 +30,3 @@ export async function TermsOfServicePage(props?: { markdownOverride?: string })
33
30
  </main>
34
31
  );
35
32
  }
36
-
@@ -38,6 +38,8 @@ export interface CompanyInformation {
38
38
  external_management_url?: string;
39
39
  /** Member portal URL for this account. When set, used as the primary CTA instead of external_management_url. */
40
40
  portal_url?: string | null;
41
+ terms_of_service_markdown?: string;
42
+ privacy_policy_markdown?: string;
41
43
  created_at: string;
42
44
  updated_at: string;
43
45
  photo_attachments?: PhotoAttachment[];
@@ -1,95 +0,0 @@
1
- /**
2
- * Default Privacy Policy markdown. Generic for local businesses (retail, restaurant, salon, etc.).
3
- * Businesses may override by providing a markdown string. Placeholders are replaced at render time.
4
- */
5
- export const DEFAULT_PRIVACY_POLICY_MARKDOWN = `
6
- ## Introduction
7
-
8
- {{business.name}} ("we," "us," or "our") respects your privacy and is committed to protecting your personal information. This Privacy Policy describes how we collect, use, disclose, and safeguard information when you visit our website, use our services, visit our location(s), or otherwise interact with us. It applies to information collected through this website, in person, by phone, or through third-party platforms we use to run our business (e.g., booking or payment processors). By using our website or services, you consent to the practices described in this policy.
9
-
10
- ---
11
-
12
- ## 1. Information We Collect
13
-
14
- We may collect the following categories of information:
15
-
16
- **Information you provide**
17
-
18
- - **Contact and account information** – Name, email address, phone number, mailing address, and similar details when you fill out forms, make a purchase, make a reservation or appointment, sign up for our newsletter or other communications, or contact us.
19
- - **Transaction information** – Details of purchases, orders, reservations, or appointments; payment information (e.g., card type and last four digits; full payment details are typically processed by our payment providers and not stored by us beyond what is necessary for the transaction).
20
- - **Preferences and feedback** – Service preferences, dietary or accessibility needs (e.g., for restaurants or events), feedback, reviews, and other information you choose to provide.
21
-
22
- **Information collected automatically**
23
-
24
- - **Usage and device information** – IP address, browser type, device type, operating system, pages visited, referring URL, and similar technical data when you use our website.
25
- - **Cookies and similar technologies** – We use cookies and similar technologies as described in the Cookies section below.
26
-
27
- **Information from other sources**
28
-
29
- - We may receive information from third-party services we use (e.g., reservation or payment platforms, analytics providers) in accordance with their policies and applicable law.
30
-
31
- ---
32
-
33
- ## 2. How We Use Your Information
34
-
35
- We use the information we collect to:
36
-
37
- - Provide, operate, and improve our products and services.
38
- - Process and fulfill orders, reservations, and appointments.
39
- - Communicate with you about your orders, reservations, appointments, inquiries, and customer service.
40
- - Send you marketing or promotional communications where you have opted in or where permitted by law; you may opt out at any time.
41
- - Improve our website, user experience, and business operations.
42
- - Comply with legal obligations, protect our rights, and prevent fraud or abuse.
43
- - Maintain records of your preferences and consent (e.g., for marketing or text messaging).
44
-
45
- ---
46
-
47
- ## 3. Information Sharing and Disclosure
48
-
49
- We do not sell your personal information. We may share information in the following circumstances:
50
-
51
- **Service providers** – We may share information with third parties who perform services on our behalf (e.g., payment processing, reservation or booking systems, email delivery, website hosting, analytics). These providers are contractually required to protect your information and use it only for the purposes we specify.
52
-
53
- **Legal and safety** – We may disclose information when required by law, court order, or legal process, or when we believe in good faith that disclosure is necessary to protect our rights, your safety, or the safety of others, to investigate fraud, or to respond to government requests.
54
-
55
- **Business transfers** – In the event of a merger, acquisition, sale of assets, or similar transaction, your information may be transferred; we will require the recipient to honor this Privacy Policy with respect to your information.
56
-
57
- **With your consent** – We may share information for other purposes with your consent.
58
-
59
- ---
60
-
61
- ## 4. Cookies and Similar Technologies
62
-
63
- We may use cookies and similar technologies to operate and improve our website and to understand how visitors interact with our Site. You can usually set your browser to refuse cookies or to alert you when cookies are being sent. If you disable cookies, some features of the Site may not function properly.
64
-
65
- ---
66
-
67
- ## 5. Data Retention
68
-
69
- We retain personal information only as long as necessary to fulfill the purposes described in this Privacy Policy, unless a longer retention period is required or permitted by law.
70
-
71
- ---
72
-
73
- ## 6. Your Choices
74
-
75
- Depending on your location and applicable law, you may have certain rights regarding your personal information, such as requesting access, correction, deletion, or opting out of certain uses. To make a request, contact us {{business.contact}}.
76
-
77
- ---
78
-
79
- ## 7. Children's Privacy
80
-
81
- Our services are not directed to children under 13 (or other age as required by law), and we do not knowingly collect personal information from children.
82
-
83
- ---
84
-
85
- ## 8. Contact Us
86
-
87
- If you have questions about this Privacy Policy, please contact {{business.name}} {{business.contact}}.
88
-
89
- ---
90
-
91
- ## Effective Date
92
-
93
- This Privacy Policy is effective as of {{right_now.year}}.
94
- `;
95
-
@@ -1,80 +0,0 @@
1
- /**
2
- * Default Terms of Service markdown. Generic for local businesses (retail, restaurant, salon, etc.).
3
- * Businesses may override by providing a markdown string. Placeholders are replaced at render time.
4
- */
5
- export const DEFAULT_TERMS_OF_SERVICE_MARKDOWN = `
6
- ## Agreement to Terms
7
-
8
- This website (the "Site") is owned and operated by **{{business.name}}** ("Company," "we," or "us"). By accessing or using the Site, you agree to be bound by these Terms of Service and to use the Site in accordance with them, our [Privacy Policy](/privacy-policy), and any additional terms that apply to specific areas of the Site or to products or services offered through the Site or by {{business.name}}. Any access or use of the Site, whether automated or otherwise, constitutes use and your agreement to these Terms of Service.
9
-
10
- We reserve the right to change these Terms of Service or to impose new conditions on use of the Site from time to time. We will post the revised Terms of Service on this website and indicate the effective date. Your continued use of the Site after we post any such changes constitutes your acceptance of the Terms of Service as modified.
11
-
12
- ---
13
-
14
- ## Use of the Site and Our Services
15
-
16
- The Site provides information about {{business.name}}, our products and services, and may allow you to contact us, make reservations or appointments, place orders, sign up for communications, or otherwise interact with our business. You agree to use the Site only for lawful purposes and in accordance with these Terms. You may not use the Site in any way that could damage, disable, or overburden the Site or interfere with any other party's use of the Site. You may not attempt to gain unauthorized access to any part of the Site, other accounts, or any systems or networks connected to the Site.
17
-
18
- ---
19
-
20
- ## Orders, Reservations, and Appointments
21
-
22
- If you place an order, make a reservation, or book an appointment through the Site or through links or tools we provide, the terms of that transaction may be subject to additional policies or instructions provided at the time of booking. We reserve the right to refuse or cancel any order, reservation, or appointment at our discretion, including due to availability, errors in pricing or information, or suspected fraud. You are responsible for providing accurate contact and other information so we can fulfill your request or reach you regarding your order, reservation, or appointment.
23
-
24
- ---
25
-
26
- ## Payments and Refunds
27
-
28
- Where payments are accepted through the Site or in connection with our services, you agree to provide current, complete, and accurate payment information. Refund and cancellation policies depend on the type of product or service; we will communicate any specific refund or cancellation terms at the time of purchase or booking. Unless otherwise stated, our general policy is to handle refunds and cancellations in accordance with applicable law and our business practices. For questions about a specific transaction, contact us {{business.contact}}.
29
-
30
- ---
31
-
32
- ## Intellectual Property Rights
33
-
34
- **Our limited license to you.** This Site and all materials available on the Site (including text, graphics, logos, images, and software) are the property of {{business.name}} and/or our affiliates or licensors and are protected by copyright, trademark, and other intellectual property laws. The Site is provided for your personal, non-commercial use. You may not use the Site or its materials in any manner that infringes our rights or that has not been authorized by us. Unless we have explicitly authorized you in writing, you may not modify, copy, reproduce, republish, upload, post, transmit, translate, sell, create derivative works from, exploit, or distribute in any manner or medium any material from the Site. You may download or print one copy of individual pages for your personal, non-commercial use, provided you keep intact all copyright and other proprietary notices.
35
-
36
- **Your license to us.** By posting or submitting any material (including comments, reviews, photos, or other content) to us via the Site, contact forms, or related channels, you represent that you own the material or have the necessary rights and permissions. You grant us a royalty-free, perpetual, irrevocable, non-exclusive, worldwide license to use, modify, display, and distribute such material in connection with our business and the Site (e.g., for marketing, testimonials, or improvement of our services), subject to our [Privacy Policy](/privacy-policy).
37
-
38
- ---
39
-
40
- ## Disclaimers
41
-
42
- The information, products, and services offered on or through the Site are provided "as is" and without warranties of any kind, either express or implied. To the fullest extent permitted by applicable law, we disclaim all warranties, including implied warranties of merchantability and fitness for a particular purpose. We do not warrant that the Site will be uninterrupted or error-free. We may provide links to third-party websites; our linking to such sites does not imply endorsement of those sites or their content, products, or services. Your use of third-party sites is at your own risk.
43
-
44
- ---
45
-
46
- ## Limitation of Liability
47
-
48
- To the fullest extent permitted by applicable law, {{business.name}}, its affiliates, and their respective officers, directors, employees, and agents shall not be liable for any indirect, incidental, special, consequential, or punitive damages, or any loss of profits or revenues, whether incurred directly or indirectly, or any loss of data, use, or goodwill, arising out of or related to your use of the Site or our services. Our total liability for any claims arising from or related to these Terms or the Site shall not exceed the amount you paid to us, if any, in the twelve (12) months preceding the claim, or one hundred dollars ($100), whichever is greater. Some jurisdictions do not allow the exclusion or limitation of certain damages; in such jurisdictions, our liability will be limited to the maximum extent permitted by law.
49
-
50
- ---
51
-
52
- ## Indemnification
53
-
54
- You agree to indemnify and hold harmless {{business.name}}, its affiliates, and their respective officers, directors, agents, and employees from any claims, causes of action, damages, liabilities, costs, and expenses (including reasonable attorneys' fees) arising out of or related to your use of the Site, your violation of these Terms of Service, or your violation of any rights of another party.
55
-
56
- ---
57
-
58
- ## Termination
59
-
60
- We reserve the right to terminate or suspend your access to the Site, without prior notice, if we determine that you have violated these Terms of Service or have engaged in conduct we deem inappropriate or unlawful. Upon termination, you must cease all use of the Site and any content obtained from it.
61
-
62
- ---
63
-
64
- ## Governing Law
65
-
66
- These Terms are governed by the laws of the jurisdiction in which {{business.name}} operates, without regard to its conflict of laws principles.
67
-
68
- ---
69
-
70
- ## Contact Us
71
-
72
- If you have any questions about these Terms of Service, please contact {{business.name}} {{business.contact}}.
73
-
74
- ---
75
-
76
- ## Effective Date
77
-
78
- These Terms of Service are effective as of {{right_now.year}}.
79
- `;
80
-