keystone-design-bootstrap 1.0.3 → 1.0.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/package.json +1 -1
- package/src/design_system/sections/about-home.aman.tsx +9 -22
- package/src/design_system/sections/about-home.tsx +8 -14
- package/src/design_system/sections/blog-gallery.aman.tsx +0 -8
- package/src/design_system/sections/blog-gallery.tsx +12 -14
- package/src/design_system/sections/blog-home.aman.tsx +2 -9
- package/src/design_system/sections/blog-home.tsx +12 -10
- package/src/design_system/sections/blog-post.aman.tsx +0 -4
- package/src/design_system/sections/blog-post.tsx +0 -7
- package/src/design_system/sections/blog-section.aman.tsx +4 -11
- package/src/design_system/sections/blog-section.tsx +11 -27
- package/src/design_system/sections/contact-home.tsx +9 -8
- package/src/design_system/sections/contact-section.aman.tsx +4 -21
- package/src/design_system/sections/contact-section.tsx +2 -2
- package/src/design_system/sections/faq-grid.aman.tsx +4 -11
- package/src/design_system/sections/faq-grid.tsx +16 -13
- package/src/design_system/sections/faq-home.aman.tsx +4 -12
- package/src/design_system/sections/faq-home.tsx +6 -14
- package/src/design_system/sections/hero-faq.aman.tsx +4 -10
- package/src/design_system/sections/hero-faq.tsx +8 -9
- package/src/design_system/sections/hero-generic-text.aman.tsx +2 -20
- package/src/design_system/sections/hero-generic-text.tsx +10 -15
- package/src/design_system/sections/hero-home.aman.tsx +7 -19
- package/src/design_system/sections/hero-home.tsx +21 -18
- package/src/design_system/sections/hero-location-detail.aman.tsx +0 -3
- package/src/design_system/sections/hero-location-detail.tsx +0 -4
- package/src/design_system/sections/hero-service-detail.aman.tsx +0 -4
- package/src/design_system/sections/hero-service-detail.tsx +0 -4
- package/src/design_system/sections/hero-social-media.aman.tsx +4 -14
- package/src/design_system/sections/hero-social-media.tsx +8 -9
- package/src/design_system/sections/hero-testimonials.aman.tsx +4 -10
- package/src/design_system/sections/hero-testimonials.tsx +8 -9
- package/src/design_system/sections/job-gallery.aman.tsx +4 -11
- package/src/design_system/sections/job-gallery.tsx +10 -22
- package/src/design_system/sections/location-details-section.aman.tsx +0 -3
- package/src/design_system/sections/location-details-section.tsx +8 -15
- package/src/design_system/sections/location-grid.aman.tsx +2 -9
- package/src/design_system/sections/location-grid.tsx +8 -16
- package/src/design_system/sections/services-grid.aman.tsx +2 -9
- package/src/design_system/sections/services-grid.tsx +8 -12
- package/src/design_system/sections/services-home.aman.tsx +1 -1
- package/src/design_system/sections/services-home.tsx +2 -2
- package/src/design_system/sections/social-media-grid.aman.tsx +3 -10
- package/src/design_system/sections/social-media-grid.tsx +4 -7
- package/src/design_system/sections/statistics-section.aman.tsx +3 -25
- package/src/design_system/sections/statistics-section.tsx +4 -21
- package/src/design_system/sections/team-grid.aman.tsx +6 -12
- package/src/design_system/sections/team-grid.tsx +10 -14
- package/src/design_system/sections/testimonials-home.aman.tsx +4 -13
- package/src/design_system/sections/testimonials-home.tsx +6 -15
- package/src/design_system/sections/values-section.aman.tsx +12 -11
- package/src/design_system/sections/values-section.tsx +21 -29
- package/src/lib/server-api.ts +4 -0
- package/src/types/api/company-information.ts +1 -0
package/package.json
CHANGED
|
@@ -5,7 +5,6 @@ import type { CompanyInformation } from '../../types/api/company-information';
|
|
|
5
5
|
import type { WebsitePhotos } from '../../types/api/website-photos';
|
|
6
6
|
|
|
7
7
|
interface AboutHomeProps {
|
|
8
|
-
config?: any;
|
|
9
8
|
companyInformation?: CompanyInformation | null;
|
|
10
9
|
websitePhotos?: WebsitePhotos | null;
|
|
11
10
|
title?: string;
|
|
@@ -14,25 +13,13 @@ interface AboutHomeProps {
|
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export const AboutHome = ({
|
|
17
|
-
config,
|
|
18
16
|
companyInformation,
|
|
19
17
|
websitePhotos,
|
|
20
|
-
title,
|
|
21
|
-
subtitle,
|
|
22
|
-
ctaText,
|
|
18
|
+
title = "",
|
|
19
|
+
subtitle = "",
|
|
20
|
+
ctaText = "",
|
|
23
21
|
}: AboutHomeProps) => {
|
|
24
|
-
|
|
25
|
-
const homePageConfig = config?.pages?.find((p: any) =>
|
|
26
|
-
p.library_reference_name === 'Home' || p.slug === 'home'
|
|
27
|
-
);
|
|
28
|
-
const aboutSection = homePageConfig?.sections?.home_page_section_3_about;
|
|
29
|
-
|
|
30
|
-
// Use config values, then props, then defaults
|
|
31
|
-
const displayTitle = title || aboutSection?.title || '*TR* About Us';
|
|
32
|
-
const displaySubtitle = subtitle || aboutSection?.subtitle || '*TR* Learn more about our company';
|
|
33
|
-
const displayCtaText = ctaText || aboutSection?.cta_text || 'Learn more';
|
|
34
|
-
|
|
35
|
-
const description = (companyInformation as any)?.about_text_markdown || aboutSection?.description || '';
|
|
22
|
+
const description = (companyInformation as any)?.about_text_markdown || '';
|
|
36
23
|
|
|
37
24
|
// Use brand photo for about section, fallback to about photo
|
|
38
25
|
const aboutImage = (websitePhotos as any)?.brand || websitePhotos?.about;
|
|
@@ -51,12 +38,12 @@ export const AboutHome = ({
|
|
|
51
38
|
|
|
52
39
|
<div className="order-1 lg:order-2 flex flex-col justify-center">
|
|
53
40
|
<h2 className="font-display text-4xl font-normal leading-tight text-fg-primary md:text-5xl">
|
|
54
|
-
{
|
|
41
|
+
{title}
|
|
55
42
|
</h2>
|
|
56
43
|
|
|
57
|
-
{
|
|
44
|
+
{subtitle && (
|
|
58
45
|
<p className="mt-4 font-body text-md text-tertiary uppercase tracking-wide">
|
|
59
|
-
{
|
|
46
|
+
{subtitle}
|
|
60
47
|
</p>
|
|
61
48
|
)}
|
|
62
49
|
|
|
@@ -66,13 +53,13 @@ export const AboutHome = ({
|
|
|
66
53
|
</p>
|
|
67
54
|
)}
|
|
68
55
|
|
|
69
|
-
{
|
|
56
|
+
{ctaText && (
|
|
70
57
|
<a
|
|
71
58
|
href="/about"
|
|
72
59
|
className="mt-8 inline-block font-body text-base underline underline-offset-4 hover:no-underline w-fit transition-colors"
|
|
73
60
|
style={{ color: 'var(--color-text-brand-accent)' }}
|
|
74
61
|
>
|
|
75
|
-
{
|
|
62
|
+
{ctaText}
|
|
76
63
|
</a>
|
|
77
64
|
)}
|
|
78
65
|
</div>
|
|
@@ -14,28 +14,22 @@ interface Value {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
interface AboutHomeProps {
|
|
17
|
-
config: {
|
|
18
|
-
pages?: any[];
|
|
19
|
-
};
|
|
20
17
|
companyInformation?: CompanyInformation | null;
|
|
18
|
+
title?: string;
|
|
19
|
+
subtitle?: string;
|
|
20
|
+
values?: Value[];
|
|
21
|
+
ctaText?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
export const AboutHome = ({
|
|
25
|
-
config,
|
|
26
26
|
companyInformation,
|
|
27
|
+
title = "",
|
|
28
|
+
subtitle = "",
|
|
29
|
+
values = [],
|
|
30
|
+
ctaText = "",
|
|
27
31
|
}: AboutHomeProps) => {
|
|
28
|
-
// Extract values from config
|
|
29
|
-
const title = '';
|
|
30
|
-
const subtitle = undefined;
|
|
31
32
|
const description = (companyInformation as any)?.about_text_markdown || '';
|
|
32
|
-
const values = (undefined || []).map((v: any, index: number) => ({
|
|
33
|
-
id: index.toString(),
|
|
34
|
-
title: v.title,
|
|
35
|
-
description: v.description,
|
|
36
|
-
icon: v.icon,
|
|
37
|
-
}));
|
|
38
|
-
const ctaText = undefined;
|
|
39
33
|
|
|
40
34
|
const firstValue = values && values.length > 0 ? values[0] : null;
|
|
41
35
|
const FirstValueIcon = firstValue?.icon ? mapIcon(firstValue.icon) : null;
|
|
@@ -4,19 +4,11 @@ import { PhotoWithFallback } from '../elements';
|
|
|
4
4
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
5
5
|
|
|
6
6
|
interface BlogGalleryProps {
|
|
7
|
-
config: {
|
|
8
|
-
pages?: any[];
|
|
9
|
-
};
|
|
10
7
|
blogPosts?: BlogPost[] | null;
|
|
11
|
-
pageName?: string;
|
|
12
|
-
sectionKey?: string;
|
|
13
8
|
}
|
|
14
9
|
|
|
15
10
|
export const BlogGallery = ({
|
|
16
|
-
config,
|
|
17
11
|
blogPosts: postsData,
|
|
18
|
-
pageName = 'Blog',
|
|
19
|
-
sectionKey = 'blog_page_section_2_gallery',
|
|
20
12
|
}: BlogGalleryProps) => {
|
|
21
13
|
const posts = Array.isArray(postsData) ? postsData : [];
|
|
22
14
|
|
|
@@ -10,10 +10,13 @@ import { getAvatarUrl } from '../../utils/photo-helpers';
|
|
|
10
10
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
11
11
|
|
|
12
12
|
interface BlogGalleryProps {
|
|
13
|
-
config: {
|
|
14
|
-
pages?: any[];
|
|
15
|
-
};
|
|
16
13
|
blogPosts?: BlogPost[] | null;
|
|
14
|
+
label?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
subtitle?: string;
|
|
17
|
+
postsPerPage?: number;
|
|
18
|
+
backgroundColor?: string;
|
|
19
|
+
className?: string;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const defaultSortByOptions = [
|
|
@@ -23,20 +26,15 @@ const defaultSortByOptions = [
|
|
|
23
26
|
];
|
|
24
27
|
|
|
25
28
|
export const BlogGallery = ({
|
|
26
|
-
config,
|
|
27
29
|
blogPosts: postsData,
|
|
30
|
+
label = "",
|
|
31
|
+
title = "",
|
|
32
|
+
subtitle = "",
|
|
33
|
+
postsPerPage = 12,
|
|
34
|
+
backgroundColor = "bg-primary",
|
|
35
|
+
className = "",
|
|
28
36
|
}: BlogGalleryProps) => {
|
|
29
|
-
const blogPage = config.pages?.find((p: any) => p.library_reference_name === 'Blog');
|
|
30
|
-
const blogPageSection = blogPage?.sections?.blog_page_section_2_blog;
|
|
31
|
-
const heroSection = blogPage?.sections?.blog_page_section_1_hero;
|
|
32
|
-
|
|
33
|
-
const label = undefined;
|
|
34
|
-
const title = 'Latest Articles';
|
|
35
|
-
const subtitle = 'Browse our collection of articles below.';
|
|
36
|
-
const postsPerPage = 12;
|
|
37
37
|
const sortByOptions = defaultSortByOptions;
|
|
38
|
-
const backgroundColor = "bg-primary";
|
|
39
|
-
const className = "";
|
|
40
38
|
|
|
41
39
|
const posts = Array.isArray(postsData) ? postsData : [];
|
|
42
40
|
const isDesktop = useBreakpoint("lg");
|
|
@@ -4,22 +4,15 @@ import { PhotoWithFallback } from '../elements';
|
|
|
4
4
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
5
5
|
|
|
6
6
|
interface BlogHomeProps {
|
|
7
|
-
config: {
|
|
8
|
-
pages?: any[];
|
|
9
|
-
};
|
|
10
7
|
blogPosts?: BlogPost[] | null;
|
|
11
|
-
|
|
12
|
-
sectionKey?: string;
|
|
8
|
+
title?: string;
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
export const BlogHome = ({
|
|
16
|
-
config,
|
|
17
12
|
blogPosts: postsData,
|
|
18
|
-
|
|
19
|
-
sectionKey = 'blog_page_section_1_posts',
|
|
13
|
+
title = "",
|
|
20
14
|
}: BlogHomeProps) => {
|
|
21
15
|
const posts = Array.isArray(postsData) ? postsData : [];
|
|
22
|
-
const title = 'Latest Posts';
|
|
23
16
|
|
|
24
17
|
return (
|
|
25
18
|
<section>
|
|
@@ -7,22 +7,24 @@ import { cx } from '../../utils/cx';
|
|
|
7
7
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
8
8
|
|
|
9
9
|
interface BlogHomeProps {
|
|
10
|
-
config: {
|
|
11
|
-
pages?: any[];
|
|
12
|
-
};
|
|
13
10
|
blogPosts?: BlogPost[] | null;
|
|
11
|
+
label?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
subtitle?: string;
|
|
14
|
+
maxPosts?: number;
|
|
15
|
+
viewAllHref?: string;
|
|
16
|
+
viewAllText?: string;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export const BlogHome = ({
|
|
17
|
-
config,
|
|
18
20
|
blogPosts: postsData,
|
|
21
|
+
label = "",
|
|
22
|
+
title = "",
|
|
23
|
+
subtitle = "",
|
|
24
|
+
maxPosts = 6,
|
|
25
|
+
viewAllHref = "/blog",
|
|
26
|
+
viewAllText = "View all posts",
|
|
19
27
|
}: BlogHomeProps) => {
|
|
20
|
-
const label = "Latest posts";
|
|
21
|
-
const title = "Latest posts";
|
|
22
|
-
const subtitle = "";
|
|
23
|
-
const maxPosts = 6;
|
|
24
|
-
const viewAllHref = "/blog";
|
|
25
|
-
const viewAllText = "View all posts";
|
|
26
28
|
|
|
27
29
|
const posts = Array.isArray(postsData) ? postsData.slice(0, maxPosts) : [];
|
|
28
30
|
|
|
@@ -5,14 +5,10 @@ import MarkdownRenderer from '../elements/markdown-renderer/MarkdownRenderer';
|
|
|
5
5
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
6
6
|
|
|
7
7
|
interface BlogPostSectionProps {
|
|
8
|
-
config: {
|
|
9
|
-
pages?: any[];
|
|
10
|
-
};
|
|
11
8
|
blogPost?: BlogPost | null;
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
export const BlogPostSection = ({
|
|
15
|
-
config,
|
|
16
12
|
blogPost,
|
|
17
13
|
}: BlogPostSectionProps) => {
|
|
18
14
|
if (!blogPost) {
|
|
@@ -7,18 +7,11 @@ import { extractTableOfContents } from '../../utils/markdown-toc';
|
|
|
7
7
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
8
8
|
|
|
9
9
|
interface BlogPostSectionProps {
|
|
10
|
-
// Config data - component extracts all values from it
|
|
11
|
-
config: {
|
|
12
|
-
pages?: any[];
|
|
13
|
-
};
|
|
14
|
-
// Blog post data from SSR
|
|
15
10
|
blogPost?: BlogPost | null;
|
|
16
|
-
// Related posts
|
|
17
11
|
relatedPosts?: BlogPost[] | null;
|
|
18
12
|
}
|
|
19
13
|
|
|
20
14
|
export const BlogPostSection = ({
|
|
21
|
-
config,
|
|
22
15
|
blogPost,
|
|
23
16
|
relatedPosts: relatedPostsData,
|
|
24
17
|
}: BlogPostSectionProps) => {
|
|
@@ -5,23 +5,16 @@ import { PhotoWithFallback } from '../elements';
|
|
|
5
5
|
import type { BlogPost } from '../../types/api/blog-post';
|
|
6
6
|
|
|
7
7
|
interface BlogSectionProps {
|
|
8
|
-
config: {
|
|
9
|
-
pages?: any[];
|
|
10
|
-
};
|
|
11
8
|
blogPosts?: BlogPost[] | null;
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
title?: string;
|
|
10
|
+
maxPosts?: number;
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
export const BlogSection = ({
|
|
17
|
-
config,
|
|
18
14
|
blogPosts: postsData,
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
title = "",
|
|
16
|
+
maxPosts = 3,
|
|
21
17
|
}: BlogSectionProps) => {
|
|
22
|
-
const blogSection = pageName === 'Home'
|
|
23
|
-
const title = "Latest posts";
|
|
24
|
-
const maxPosts = 3;
|
|
25
18
|
|
|
26
19
|
const postsArray = Array.isArray(postsData) ? postsData.slice(0, maxPosts) : [];
|
|
27
20
|
|
|
@@ -10,41 +10,25 @@ import type { BlogPost } from '../../types/api/blog-post';
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
interface BlogSectionProps {
|
|
13
|
-
config: {
|
|
14
|
-
pages?: any[];
|
|
15
|
-
};
|
|
16
13
|
blogPosts: BlogPost[];
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
title?: string;
|
|
15
|
+
subtitle?: string;
|
|
16
|
+
maxPosts?: number;
|
|
17
|
+
backgroundColor?: string;
|
|
18
|
+
showViewAll?: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export const BlogSection = ({
|
|
22
|
-
config,
|
|
23
22
|
blogPosts: postsData,
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
title = "",
|
|
24
|
+
subtitle = "",
|
|
25
|
+
maxPosts = 8,
|
|
26
|
+
backgroundColor = "bg-primary",
|
|
27
|
+
showViewAll = true,
|
|
26
28
|
}: BlogSectionProps) => {
|
|
27
|
-
// Extract values from config
|
|
28
|
-
const blogSection = pageName === 'Home'
|
|
29
|
-
const title = "Latest posts";
|
|
30
|
-
const subtitle = "Interviews, tips, guides, industry best practices, and news.";
|
|
31
|
-
const maxPosts = 8;
|
|
32
|
-
const backgroundColor = "bg-primary";
|
|
33
|
-
const showViewAll = undefined !== false;
|
|
34
29
|
|
|
35
30
|
let postsArray = Array.isArray(postsData) ? postsData : [];
|
|
36
|
-
|
|
37
|
-
// If this is a BlogPost page and use_related is true, filter to related posts
|
|
38
|
-
if (pageName === 'BlogPost' && undefined) {
|
|
39
|
-
const currentPath = typeof window !== 'undefined' ? window.location.pathname : '';
|
|
40
|
-
const currentSlug = currentPath.split('/').pop();
|
|
41
|
-
|
|
42
|
-
postsArray = postsArray
|
|
43
|
-
.filter((post: BlogPost) => post.slug !== currentSlug)
|
|
44
|
-
.slice(0, maxPosts);
|
|
45
|
-
} else {
|
|
46
|
-
postsArray = postsArray.slice(0, maxPosts);
|
|
47
|
-
}
|
|
31
|
+
postsArray = postsArray.slice(0, maxPosts);
|
|
48
32
|
|
|
49
33
|
const formatDate = (dateString: string) => {
|
|
50
34
|
if (!dateString) return 'Recent';
|
|
@@ -4,20 +4,21 @@ import ContactSection from "./contact-section";
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
interface ContactHomeProps {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
7
|
+
websitePhotos?: any;
|
|
8
|
+
title?: string;
|
|
9
|
+
subtitle?: string;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export const ContactHome = ({
|
|
14
|
-
|
|
13
|
+
websitePhotos,
|
|
14
|
+
title = "",
|
|
15
|
+
subtitle = "",
|
|
15
16
|
}: ContactHomeProps) => {
|
|
16
|
-
// Extract values from config
|
|
17
|
-
|
|
18
17
|
return (
|
|
19
18
|
<ContactSection
|
|
20
|
-
|
|
19
|
+
websitePhotos={websitePhotos}
|
|
20
|
+
title={title}
|
|
21
|
+
subtitle={subtitle}
|
|
21
22
|
/>
|
|
22
23
|
);
|
|
23
24
|
};
|
|
@@ -5,37 +5,20 @@ import { Form, PhotoWithFallback } from '../elements';
|
|
|
5
5
|
import type { WebsitePhotos } from '../../types/api/website-photos';
|
|
6
6
|
|
|
7
7
|
interface ContactSectionProps {
|
|
8
|
-
config?: any;
|
|
9
|
-
pageName?: string;
|
|
10
|
-
sectionKey?: string;
|
|
11
8
|
websitePhotos?: WebsitePhotos | null;
|
|
12
9
|
title?: string;
|
|
13
10
|
subtitle?: string;
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
const ContactSection = ({
|
|
17
|
-
config,
|
|
18
|
-
pageName,
|
|
19
|
-
sectionKey,
|
|
20
14
|
websitePhotos,
|
|
21
|
-
title,
|
|
22
|
-
subtitle,
|
|
15
|
+
title = "",
|
|
16
|
+
subtitle = "",
|
|
23
17
|
}: ContactSectionProps) => {
|
|
24
18
|
const [selectedCountryPhone, setSelectedCountryPhone] = useState("US");
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
p.library_reference_name === pageName ||
|
|
29
|
-
p.library_reference_name === 'Home' ||
|
|
30
|
-
p.slug === 'home'
|
|
31
|
-
);
|
|
32
|
-
const contactSection = sectionKey
|
|
33
|
-
? pageConfig?.sections?.[sectionKey]
|
|
34
|
-
: pageConfig?.sections?.home_page_section_7_contact || pageConfig?.sections?.home_page_section_6_contact;
|
|
35
|
-
|
|
36
|
-
// Use config values, then props, then defaults
|
|
37
|
-
const displayTitle = title || contactSection?.title || '*TR* Get in Touch';
|
|
38
|
-
const displaySubtitle = subtitle || contactSection?.subtitle || '*TR* We would love to hear from you';
|
|
20
|
+
const displayTitle = title;
|
|
21
|
+
const displaySubtitle = subtitle;
|
|
39
22
|
|
|
40
23
|
const contactPhoto = websitePhotos?.contact;
|
|
41
24
|
const contactImageUrl = contactPhoto?.url;
|
|
@@ -14,8 +14,8 @@ interface ContactSectionProps {
|
|
|
14
14
|
|
|
15
15
|
const ContactSection = ({
|
|
16
16
|
websitePhotos,
|
|
17
|
-
title = "
|
|
18
|
-
subtitle = "
|
|
17
|
+
title = "",
|
|
18
|
+
subtitle = "",
|
|
19
19
|
}: ContactSectionProps) => {
|
|
20
20
|
const [selectedCountryPhone, setSelectedCountryPhone] = useState("US");
|
|
21
21
|
|
|
@@ -4,24 +4,17 @@ import { useState } from 'react';
|
|
|
4
4
|
import type { FaqQuestion } from '../../types/api/faq';
|
|
5
5
|
|
|
6
6
|
interface FAQGridProps {
|
|
7
|
-
config: {
|
|
8
|
-
pages?: any[];
|
|
9
|
-
};
|
|
10
7
|
faqs: FaqQuestion[];
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
title?: string;
|
|
9
|
+
maxItems?: number;
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
export const FAQGrid = ({
|
|
16
|
-
config,
|
|
17
13
|
faqs: faqsData,
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
title = "",
|
|
15
|
+
maxItems,
|
|
20
16
|
}: FAQGridProps) => {
|
|
21
17
|
const faqs = Array.isArray(faqsData) ? faqsData : [];
|
|
22
|
-
|
|
23
|
-
const title = 'Frequently Asked Questions';
|
|
24
|
-
const maxItems = undefined;
|
|
25
18
|
const displayFaqs = maxItems ? faqs.slice(0, maxItems) : faqs;
|
|
26
19
|
|
|
27
20
|
const [openIndex, setOpenIndex] = useState<number | null>(null);
|
|
@@ -5,10 +5,15 @@ import { Button } from '../elements';
|
|
|
5
5
|
import type { FaqQuestion } from '../../types/api/faq';
|
|
6
6
|
|
|
7
7
|
interface FAQGridProps {
|
|
8
|
-
config: {
|
|
9
|
-
pages?: any[];
|
|
10
|
-
};
|
|
11
8
|
faqs?: FaqQuestion[] | null;
|
|
9
|
+
title?: string;
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
ctaTitle?: string;
|
|
12
|
+
ctaSubtitle?: string;
|
|
13
|
+
ctaButtonText?: string;
|
|
14
|
+
ctaButtonHref?: string;
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
className?: string;
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
// Simple markdown renderer - converts basic markdown to HTML
|
|
@@ -23,20 +28,18 @@ const renderMarkdown = (content: string) => {
|
|
|
23
28
|
};
|
|
24
29
|
|
|
25
30
|
export const FAQGrid = ({
|
|
26
|
-
config,
|
|
27
31
|
faqs: faqsData,
|
|
32
|
+
title = "",
|
|
33
|
+
subtitle = "",
|
|
34
|
+
ctaTitle = "",
|
|
35
|
+
ctaSubtitle = "",
|
|
36
|
+
ctaButtonText = "",
|
|
37
|
+
ctaButtonHref = "/contact",
|
|
38
|
+
backgroundColor = "bg-primary",
|
|
39
|
+
className = "",
|
|
28
40
|
}: FAQGridProps) => {
|
|
29
41
|
const faqs = Array.isArray(faqsData) ? faqsData : [];
|
|
30
42
|
|
|
31
|
-
const title = "Frequently asked questions";
|
|
32
|
-
const subtitle = "";
|
|
33
|
-
const ctaTitle = "Still have questions?";
|
|
34
|
-
const ctaSubtitle = "Can't find the answer you're looking for? Please chat to our friendly team.";
|
|
35
|
-
const ctaButtonText = "Get in touch";
|
|
36
|
-
const ctaButtonHref = "/contact";
|
|
37
|
-
const backgroundColor = "bg-primary";
|
|
38
|
-
const className = "";
|
|
39
|
-
|
|
40
43
|
return (
|
|
41
44
|
<section className={`${backgroundColor} py-16 md:py-24 ${className}`} id="faq">
|
|
42
45
|
<div className="mx-auto w-full max-w-container px-4 md:px-8">
|
|
@@ -5,25 +5,17 @@ import { motion } from 'framer-motion';
|
|
|
5
5
|
import type { FaqQuestion } from '../../types/api/faq';
|
|
6
6
|
|
|
7
7
|
interface FAQHomeProps {
|
|
8
|
-
config: {
|
|
9
|
-
pages?: any[];
|
|
10
|
-
};
|
|
11
8
|
faqs: FaqQuestion[];
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
title?: string;
|
|
10
|
+
maxItems?: number;
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
export const FAQHome = ({
|
|
17
|
-
config,
|
|
18
14
|
faqs: faqsData,
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
title = "",
|
|
16
|
+
maxItems,
|
|
21
17
|
}: FAQHomeProps) => {
|
|
22
18
|
const faqs = Array.isArray(faqsData) ? faqsData : [];
|
|
23
|
-
|
|
24
|
-
const faqSection = pageName === 'Home'
|
|
25
|
-
const title = 'Frequently Asked Questions';
|
|
26
|
-
const maxItems = undefined;
|
|
27
19
|
const displayFaqs = maxItems ? faqs.slice(0, maxItems) : faqs;
|
|
28
20
|
|
|
29
21
|
const [openIndex, setOpenIndex] = useState<number | null>(null);
|
|
@@ -7,27 +7,19 @@ import type { FaqQuestion } from '../../types/api/faq';
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
interface FAQHomeProps {
|
|
10
|
-
config: {
|
|
11
|
-
pages?: any[];
|
|
12
|
-
};
|
|
13
10
|
faqs: FaqQuestion[];
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
title?: string;
|
|
12
|
+
subtitle?: string;
|
|
13
|
+
maxItems?: number;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
export const FAQHome = ({
|
|
19
|
-
config,
|
|
20
17
|
faqs: faqsData,
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
title = "",
|
|
19
|
+
subtitle = "",
|
|
20
|
+
maxItems,
|
|
23
21
|
}: FAQHomeProps) => {
|
|
24
22
|
const items = Array.isArray(faqsData) ? faqsData : [];
|
|
25
|
-
|
|
26
|
-
// Extract values from config
|
|
27
|
-
const faqSection = pageName === 'Home'
|
|
28
|
-
const title = "Frequently asked questions";
|
|
29
|
-
const subtitle = "";
|
|
30
|
-
const maxItems = undefined;
|
|
31
23
|
const [openQuestions, setOpenQuestions] = useState<Set<number>>(new Set([0]));
|
|
32
24
|
|
|
33
25
|
const handleToggle = (index: number) => {
|
|
@@ -2,20 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
interface FAQHeroProps {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
pageName?: string;
|
|
9
|
-
sectionKey?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
10
7
|
}
|
|
11
8
|
|
|
12
9
|
export const FAQHero = ({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
sectionKey = 'faq_page_section_1_hero',
|
|
10
|
+
title = "",
|
|
11
|
+
subtitle = "",
|
|
16
12
|
}: FAQHeroProps) => {
|
|
17
|
-
const title = 'Frequently Asked Questions';
|
|
18
|
-
const subtitle = '';
|
|
19
13
|
|
|
20
14
|
return (
|
|
21
15
|
<section className="py-24 md:py-32">
|
|
@@ -4,24 +4,23 @@ import { SearchLg } from '@untitledui/icons';
|
|
|
4
4
|
import { Input } from '../elements';
|
|
5
5
|
|
|
6
6
|
interface FAQHeroProps {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
7
|
+
title?: string;
|
|
8
|
+
subtitle?: string;
|
|
9
|
+
label?: string;
|
|
11
10
|
// Optional search props
|
|
12
11
|
searchTerm?: string;
|
|
13
12
|
onSearchChange?: (value: string) => void;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export const FAQHero = ({
|
|
17
|
-
|
|
16
|
+
title = "",
|
|
17
|
+
subtitle = "",
|
|
18
|
+
label = "",
|
|
18
19
|
searchTerm,
|
|
19
20
|
onSearchChange,
|
|
20
21
|
}: FAQHeroProps) => {
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const headline = "Frequently Asked Questions";
|
|
24
|
-
const subhead = "";
|
|
22
|
+
const headline = title;
|
|
23
|
+
const subhead = subtitle;
|
|
25
24
|
return (
|
|
26
25
|
<section className="bg-primary py-16 md:py-24">
|
|
27
26
|
<div className="mx-auto max-w-container px-4 md:px-8">
|