@sudobility/building_blocks 0.0.17 β 0.0.21
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.
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React, { type ComponentType, type ReactNode } from 'react';
|
|
2
|
+
import type { LinkComponentProps } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for a single sitemap link
|
|
5
|
+
*/
|
|
6
|
+
export interface SitemapLink {
|
|
7
|
+
/** URL path */
|
|
8
|
+
path: string;
|
|
9
|
+
/** Display label */
|
|
10
|
+
label: string;
|
|
11
|
+
/** Optional description */
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for a sitemap section
|
|
16
|
+
*/
|
|
17
|
+
export interface SitemapSection {
|
|
18
|
+
/** Section title */
|
|
19
|
+
title: string;
|
|
20
|
+
/** Section icon type (optional) */
|
|
21
|
+
icon?: 'home' | 'document' | 'envelope' | 'cog' | 'language';
|
|
22
|
+
/** Links in this section */
|
|
23
|
+
links: SitemapLink[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for a language option
|
|
27
|
+
*/
|
|
28
|
+
export interface LanguageOption {
|
|
29
|
+
/** Language code (e.g., 'en', 'es') */
|
|
30
|
+
code: string;
|
|
31
|
+
/** Display name */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Flag emoji */
|
|
34
|
+
flag: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for quick action buttons
|
|
38
|
+
*/
|
|
39
|
+
export interface QuickLink {
|
|
40
|
+
/** URL path */
|
|
41
|
+
path: string;
|
|
42
|
+
/** Display label */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Button variant */
|
|
45
|
+
variant: 'primary' | 'secondary' | 'outline';
|
|
46
|
+
/** Optional icon */
|
|
47
|
+
icon?: 'envelope' | 'document';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Text content for the sitemap page
|
|
51
|
+
*/
|
|
52
|
+
export interface SitemapPageText {
|
|
53
|
+
/** Page title */
|
|
54
|
+
title: string;
|
|
55
|
+
/** Page subtitle */
|
|
56
|
+
subtitle: string;
|
|
57
|
+
/** Languages section title */
|
|
58
|
+
languagesSectionTitle: string;
|
|
59
|
+
/** Languages section description */
|
|
60
|
+
languagesDescription: string;
|
|
61
|
+
/** Quick links section title */
|
|
62
|
+
quickLinksTitle: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Props for AppSitemapPage component
|
|
66
|
+
*/
|
|
67
|
+
export interface AppSitemapPageProps {
|
|
68
|
+
/** All text content (must be provided by consumer) */
|
|
69
|
+
text: SitemapPageText;
|
|
70
|
+
/** Sitemap sections */
|
|
71
|
+
sections: SitemapSection[];
|
|
72
|
+
/** Available languages */
|
|
73
|
+
languages: LanguageOption[];
|
|
74
|
+
/** Quick action links */
|
|
75
|
+
quickLinks?: QuickLink[];
|
|
76
|
+
/** Custom Link component for navigation */
|
|
77
|
+
LinkComponent: ComponentType<LinkComponentProps & {
|
|
78
|
+
language?: string;
|
|
79
|
+
}>;
|
|
80
|
+
/** Optional wrapper component for the page layout */
|
|
81
|
+
PageWrapper?: ComponentType<{
|
|
82
|
+
children: ReactNode;
|
|
83
|
+
}>;
|
|
84
|
+
/** Optional className for the container */
|
|
85
|
+
className?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* AppSitemapPage - A reusable sitemap page component
|
|
89
|
+
*
|
|
90
|
+
* Displays a comprehensive sitemap with:
|
|
91
|
+
* - Language selector
|
|
92
|
+
* - Organized sections with links
|
|
93
|
+
* - Quick action buttons
|
|
94
|
+
*
|
|
95
|
+
* All text content must be provided by the consumer app.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```tsx
|
|
99
|
+
* <AppSitemapPage
|
|
100
|
+
* text={{
|
|
101
|
+
* title: "Sitemap",
|
|
102
|
+
* subtitle: "Explore all pages",
|
|
103
|
+
* languagesSectionTitle: "Languages",
|
|
104
|
+
* languagesDescription: "Available in multiple languages",
|
|
105
|
+
* quickLinksTitle: "Quick Links"
|
|
106
|
+
* }}
|
|
107
|
+
* sections={[
|
|
108
|
+
* { title: "Main", icon: "home", links: [{ path: "/", label: "Home" }] }
|
|
109
|
+
* ]}
|
|
110
|
+
* languages={[{ code: "en", name: "English", flag: "πΊπΈ" }]}
|
|
111
|
+
* LinkComponent={LocalizedLink}
|
|
112
|
+
* />
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare const AppSitemapPage: React.FC<AppSitemapPageProps>;
|
|
116
|
+
export default AppSitemapPage;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import React, { type ReactNode, type ComponentType } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for a text section with paragraph content
|
|
4
|
+
*/
|
|
5
|
+
export interface TextSectionWithContent {
|
|
6
|
+
/** Section title */
|
|
7
|
+
title: string;
|
|
8
|
+
/** Paragraph content */
|
|
9
|
+
content: string;
|
|
10
|
+
/** Whether content contains HTML that should be rendered */
|
|
11
|
+
isHtml?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for a text section with a list
|
|
15
|
+
*/
|
|
16
|
+
export interface TextSectionWithList {
|
|
17
|
+
/** Section title */
|
|
18
|
+
title: string;
|
|
19
|
+
/** Optional description before the list */
|
|
20
|
+
description?: string;
|
|
21
|
+
/** List items */
|
|
22
|
+
items: string[];
|
|
23
|
+
/** Optional additional content after the list */
|
|
24
|
+
additionalContent?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for a text section with subsections (e.g., "Information You Provide" and "Information Collected Automatically")
|
|
28
|
+
*/
|
|
29
|
+
export interface TextSectionWithSubsections {
|
|
30
|
+
/** Section title */
|
|
31
|
+
title: string;
|
|
32
|
+
/** Subsections, each with a title and list items */
|
|
33
|
+
subsections: Array<{
|
|
34
|
+
title: string;
|
|
35
|
+
items: string[];
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Union type for all section types
|
|
40
|
+
*/
|
|
41
|
+
export type TextSection = TextSectionWithContent | TextSectionWithList | TextSectionWithSubsections;
|
|
42
|
+
/**
|
|
43
|
+
* Contact information configuration
|
|
44
|
+
*/
|
|
45
|
+
export interface TextPageContactInfo {
|
|
46
|
+
/** Email label (e.g., "Email:") */
|
|
47
|
+
emailLabel: string;
|
|
48
|
+
/** Email address */
|
|
49
|
+
email: string;
|
|
50
|
+
/** Website label (e.g., "Website:") */
|
|
51
|
+
websiteLabel: string;
|
|
52
|
+
/** Website URL */
|
|
53
|
+
websiteUrl: string;
|
|
54
|
+
/** Data Protection Officer label (optional, for privacy pages) */
|
|
55
|
+
dpoLabel?: string;
|
|
56
|
+
/** DPO email (optional, for privacy pages) */
|
|
57
|
+
dpoEmail?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* GDPR notice configuration (optional, for privacy pages)
|
|
61
|
+
*/
|
|
62
|
+
export interface GdprNotice {
|
|
63
|
+
/** GDPR section title */
|
|
64
|
+
title: string;
|
|
65
|
+
/** GDPR section content */
|
|
66
|
+
content: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Contact section configuration
|
|
70
|
+
*/
|
|
71
|
+
export interface TextPageContact {
|
|
72
|
+
/** Section title */
|
|
73
|
+
title: string;
|
|
74
|
+
/** Section description */
|
|
75
|
+
description: string;
|
|
76
|
+
/** Whether description contains HTML */
|
|
77
|
+
isHtml?: boolean;
|
|
78
|
+
/** Contact details */
|
|
79
|
+
info: TextPageContactInfo;
|
|
80
|
+
/** Optional GDPR notice (for privacy pages) */
|
|
81
|
+
gdprNotice?: GdprNotice;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* All text content for the text page
|
|
85
|
+
*/
|
|
86
|
+
export interface TextPageContent {
|
|
87
|
+
/** Page title */
|
|
88
|
+
title: string;
|
|
89
|
+
/** Last updated text (use {{date}} as placeholder for the date) */
|
|
90
|
+
lastUpdated?: string;
|
|
91
|
+
/** All sections in order */
|
|
92
|
+
sections: TextSection[];
|
|
93
|
+
/** Contact information (optional) */
|
|
94
|
+
contact?: TextPageContact;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Props for AppTextPage component
|
|
98
|
+
*/
|
|
99
|
+
export interface AppTextPageProps {
|
|
100
|
+
/** All text content (must be provided by consumer) */
|
|
101
|
+
text: TextPageContent;
|
|
102
|
+
/** Current date for "last updated" display */
|
|
103
|
+
lastUpdatedDate?: string;
|
|
104
|
+
/** Optional wrapper component for the page layout */
|
|
105
|
+
PageWrapper?: ComponentType<{
|
|
106
|
+
children: ReactNode;
|
|
107
|
+
}>;
|
|
108
|
+
/** Optional className for the container */
|
|
109
|
+
className?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* AppTextPage - A reusable text page component for legal/informational pages
|
|
113
|
+
*
|
|
114
|
+
* Displays a text-heavy page with:
|
|
115
|
+
* - Flexible section structure (content, list, or subsections)
|
|
116
|
+
* - Optional contact information
|
|
117
|
+
* - Optional GDPR notice
|
|
118
|
+
*
|
|
119
|
+
* Use this for Privacy Policy, Terms of Service, Cookie Policy, etc.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* <AppTextPage
|
|
124
|
+
* text={{
|
|
125
|
+
* title: "Privacy Policy",
|
|
126
|
+
* lastUpdated: "Last updated: {{date}}",
|
|
127
|
+
* sections: [
|
|
128
|
+
* { title: "Introduction", content: "We respect your privacy..." },
|
|
129
|
+
* { title: "Data We Collect", items: ["Email", "Usage data"] },
|
|
130
|
+
* {
|
|
131
|
+
* title: "Information We Collect",
|
|
132
|
+
* subsections: [
|
|
133
|
+
* { title: "You Provide", items: ["Email", "Name"] },
|
|
134
|
+
* { title: "Automatic", items: ["IP", "Browser"] }
|
|
135
|
+
* ]
|
|
136
|
+
* }
|
|
137
|
+
* ],
|
|
138
|
+
* contact: {
|
|
139
|
+
* title: "Contact",
|
|
140
|
+
* description: "Questions?",
|
|
141
|
+
* info: { emailLabel: "Email:", email: "support@example.com", ... }
|
|
142
|
+
* }
|
|
143
|
+
* }}
|
|
144
|
+
* lastUpdatedDate="January 1, 2025"
|
|
145
|
+
* />
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export declare const AppTextPage: React.FC<AppTextPageProps>;
|
|
149
|
+
export default AppTextPage;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AppSitemapPage } from './app-sitemap-page';
|
|
2
|
+
export type { AppSitemapPageProps, SitemapPageText, SitemapSection, SitemapLink, LanguageOption, QuickLink, } from './app-sitemap-page';
|
|
3
|
+
export { AppTextPage } from './app-text-page';
|
|
4
|
+
export type { AppTextPageProps, TextPageContent, TextSection, TextSectionWithContent, TextSectionWithList, TextSectionWithSubsections, TextPageContact, TextPageContactInfo, GdprNotice, } from './app-text-page';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import React, { useState, useRef, useMemo, useCallback, useEffect, createContext
|
|
|
3
3
|
import { TopbarProvider, Topbar, TopbarLeft, TopbarNavigation, TopbarLogo, Logo, TopbarCenter, TopbarRight, TopbarActions, TopbarMobileContent, BreadcrumbSection, Footer, FooterCompact, FooterCompactLeft, FooterVersion, FooterCopyright, FooterCompactRight, FooterGrid, FooterLinkSection, FooterLink, FooterBottom, FooterBrand, FooterSocialLinks, LayoutProvider, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Card, CardContent, Button } from "@sudobility/components";
|
|
4
4
|
import { clsx } from "clsx";
|
|
5
5
|
import { twMerge } from "tailwind-merge";
|
|
6
|
-
import { ChevronDownIcon, CalendarDaysIcon, PaintBrushIcon, ChevronLeftIcon } from "@heroicons/react/24/outline";
|
|
6
|
+
import { ChevronDownIcon, CalendarDaysIcon, PaintBrushIcon, ChevronLeftIcon, LanguageIcon, ChevronRightIcon, EnvelopeIcon, DocumentTextIcon, CogIcon, HomeIcon } from "@heroicons/react/24/outline";
|
|
7
7
|
import { GRADIENT_CLASSES, textVariants } from "@sudobility/design";
|
|
8
8
|
import { cva } from "class-variance-authority";
|
|
9
9
|
function cn(...inputs) {
|
|
@@ -4619,7 +4619,7 @@ function AppPricingPage({
|
|
|
4619
4619
|
{
|
|
4620
4620
|
options: billingPeriodOptions,
|
|
4621
4621
|
value: billingPeriod,
|
|
4622
|
-
onChange: setBillingPeriod
|
|
4622
|
+
onChange: (value) => setBillingPeriod(value)
|
|
4623
4623
|
}
|
|
4624
4624
|
) }),
|
|
4625
4625
|
/* @__PURE__ */ jsxs(
|
|
@@ -4736,13 +4736,231 @@ function AppPricingPage({
|
|
|
4736
4736
|
] }) })
|
|
4737
4737
|
] });
|
|
4738
4738
|
}
|
|
4739
|
+
const getIcon = (icon) => {
|
|
4740
|
+
switch (icon) {
|
|
4741
|
+
case "home":
|
|
4742
|
+
return /* @__PURE__ */ jsx(HomeIcon, { className: "w-5 h-5 mr-2" });
|
|
4743
|
+
case "document":
|
|
4744
|
+
return /* @__PURE__ */ jsx(DocumentTextIcon, { className: "w-5 h-5 mr-2" });
|
|
4745
|
+
case "envelope":
|
|
4746
|
+
return /* @__PURE__ */ jsx(EnvelopeIcon, { className: "w-5 h-5 mr-2" });
|
|
4747
|
+
case "cog":
|
|
4748
|
+
return /* @__PURE__ */ jsx(CogIcon, { className: "w-5 h-5 mr-2" });
|
|
4749
|
+
case "language":
|
|
4750
|
+
return /* @__PURE__ */ jsx(LanguageIcon, { className: "w-5 h-5 mr-2" });
|
|
4751
|
+
default:
|
|
4752
|
+
return null;
|
|
4753
|
+
}
|
|
4754
|
+
};
|
|
4755
|
+
const AppSitemapPage = ({
|
|
4756
|
+
text,
|
|
4757
|
+
sections,
|
|
4758
|
+
languages,
|
|
4759
|
+
quickLinks = [],
|
|
4760
|
+
LinkComponent,
|
|
4761
|
+
PageWrapper,
|
|
4762
|
+
className
|
|
4763
|
+
}) => {
|
|
4764
|
+
const content = /* @__PURE__ */ jsxs("div", { className: `max-w-7xl mx-auto px-4 py-12 ${className || ""}`, children: [
|
|
4765
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-12", children: [
|
|
4766
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold text-gray-900 dark:text-white mb-4", children: text.title }),
|
|
4767
|
+
/* @__PURE__ */ jsx("p", { className: "text-xl text-gray-600 dark:text-gray-300", children: text.subtitle })
|
|
4768
|
+
] }),
|
|
4769
|
+
languages.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-12 p-6 bg-blue-50 dark:bg-blue-900/20 rounded-lg", children: [
|
|
4770
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-4 flex items-center", children: [
|
|
4771
|
+
/* @__PURE__ */ jsx(LanguageIcon, { className: "w-6 h-6 mr-2" }),
|
|
4772
|
+
text.languagesSectionTitle
|
|
4773
|
+
] }),
|
|
4774
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600 dark:text-gray-300 mb-6", children: text.languagesDescription }),
|
|
4775
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4", children: languages.map((lang) => /* @__PURE__ */ jsxs(
|
|
4776
|
+
LinkComponent,
|
|
4777
|
+
{
|
|
4778
|
+
href: "/",
|
|
4779
|
+
language: lang.code,
|
|
4780
|
+
className: "flex items-center space-x-2 p-3 bg-white dark:bg-gray-800 rounded-lg hover:shadow-md transition-shadow",
|
|
4781
|
+
children: [
|
|
4782
|
+
/* @__PURE__ */ jsx("span", { className: "text-2xl", children: lang.flag }),
|
|
4783
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-900 dark:text-white", children: lang.name })
|
|
4784
|
+
]
|
|
4785
|
+
},
|
|
4786
|
+
lang.code
|
|
4787
|
+
)) })
|
|
4788
|
+
] }),
|
|
4789
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8", children: sections.map((section, index) => /* @__PURE__ */ jsxs(
|
|
4790
|
+
"div",
|
|
4791
|
+
{
|
|
4792
|
+
className: "bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6",
|
|
4793
|
+
children: [
|
|
4794
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-4 flex items-center", children: [
|
|
4795
|
+
getIcon(section.icon),
|
|
4796
|
+
section.title
|
|
4797
|
+
] }),
|
|
4798
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-2", children: section.links.map((link, linkIndex) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
4799
|
+
LinkComponent,
|
|
4800
|
+
{
|
|
4801
|
+
href: link.path,
|
|
4802
|
+
className: "group flex items-start text-sm hover:text-blue-600 dark:hover:text-blue-400 transition-colors",
|
|
4803
|
+
children: [
|
|
4804
|
+
/* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-4 h-4 mt-0.5 mr-2 flex-shrink-0 text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-400" }),
|
|
4805
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4806
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-700 dark:text-gray-300 group-hover:text-blue-600 dark:group-hover:text-blue-400", children: link.label }),
|
|
4807
|
+
link.description && /* @__PURE__ */ jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-0.5", children: link.description })
|
|
4808
|
+
] })
|
|
4809
|
+
]
|
|
4810
|
+
}
|
|
4811
|
+
) }, linkIndex)) })
|
|
4812
|
+
]
|
|
4813
|
+
},
|
|
4814
|
+
index
|
|
4815
|
+
)) }),
|
|
4816
|
+
quickLinks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-12 p-6 bg-gray-50 dark:bg-gray-900 rounded-lg", children: [
|
|
4817
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-4", children: text.quickLinksTitle }),
|
|
4818
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3", children: quickLinks.map((link, index) => {
|
|
4819
|
+
const baseClasses = "inline-flex items-center px-4 py-2 rounded-lg transition-colors";
|
|
4820
|
+
const variantClasses = link.variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700" : link.variant === "secondary" ? "bg-gray-600 text-white hover:bg-gray-700" : "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800";
|
|
4821
|
+
return /* @__PURE__ */ jsxs(
|
|
4822
|
+
LinkComponent,
|
|
4823
|
+
{
|
|
4824
|
+
href: link.path,
|
|
4825
|
+
className: `${baseClasses} ${variantClasses}`,
|
|
4826
|
+
children: [
|
|
4827
|
+
link.icon === "envelope" && /* @__PURE__ */ jsx(EnvelopeIcon, { className: "w-5 h-5 mr-2" }),
|
|
4828
|
+
link.icon === "document" && /* @__PURE__ */ jsx(DocumentTextIcon, { className: "w-5 h-5 mr-2" }),
|
|
4829
|
+
link.label
|
|
4830
|
+
]
|
|
4831
|
+
},
|
|
4832
|
+
index
|
|
4833
|
+
);
|
|
4834
|
+
}) })
|
|
4835
|
+
] })
|
|
4836
|
+
] });
|
|
4837
|
+
if (PageWrapper) {
|
|
4838
|
+
return /* @__PURE__ */ jsx(PageWrapper, { children: content });
|
|
4839
|
+
}
|
|
4840
|
+
return content;
|
|
4841
|
+
};
|
|
4842
|
+
function isSectionWithList(section) {
|
|
4843
|
+
return "items" in section && Array.isArray(section.items);
|
|
4844
|
+
}
|
|
4845
|
+
function isSectionWithSubsections(section) {
|
|
4846
|
+
return "subsections" in section && Array.isArray(section.subsections);
|
|
4847
|
+
}
|
|
4848
|
+
const SectionHeading = ({ children }) => /* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-gray-900 dark:text-gray-100 mt-8 mb-4", children });
|
|
4849
|
+
const SubsectionHeading = ({ children }) => /* @__PURE__ */ jsx("h3", { className: "text-xl font-semibold text-gray-900 dark:text-gray-100 mt-6 mb-3", children });
|
|
4850
|
+
const Paragraph = ({
|
|
4851
|
+
children,
|
|
4852
|
+
className = ""
|
|
4853
|
+
}) => /* @__PURE__ */ jsx("p", { className: `text-gray-600 dark:text-gray-300 mb-6 ${className}`, children });
|
|
4854
|
+
const List = ({ items }) => /* @__PURE__ */ jsx("ul", { className: "list-disc list-inside text-gray-600 dark:text-gray-300 mb-6 space-y-1", children: items.map((item, index) => /* @__PURE__ */ jsx("li", { dangerouslySetInnerHTML: { __html: item } }, index)) });
|
|
4855
|
+
const AppTextPage = ({
|
|
4856
|
+
text,
|
|
4857
|
+
lastUpdatedDate = (/* @__PURE__ */ new Date()).toLocaleDateString(),
|
|
4858
|
+
PageWrapper,
|
|
4859
|
+
className
|
|
4860
|
+
}) => {
|
|
4861
|
+
const content = /* @__PURE__ */ jsxs("div", { className: `max-w-7xl mx-auto px-4 py-12 ${className || ""}`, children: [
|
|
4862
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold text-gray-900 dark:text-gray-100 mb-8", children: text.title }),
|
|
4863
|
+
/* @__PURE__ */ jsxs("div", { className: "prose prose-lg dark:prose-invert max-w-none", children: [
|
|
4864
|
+
text.lastUpdated && /* @__PURE__ */ jsx(Paragraph, { className: "mb-6", children: text.lastUpdated.replace("{{date}}", lastUpdatedDate) }),
|
|
4865
|
+
text.sections.map((section, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
4866
|
+
/* @__PURE__ */ jsx(SectionHeading, { children: section.title }),
|
|
4867
|
+
isSectionWithSubsections(section) ? (
|
|
4868
|
+
// Section with subsections (h3 + lists)
|
|
4869
|
+
/* @__PURE__ */ jsx(Fragment, { children: section.subsections.map((subsection, subIndex) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
4870
|
+
/* @__PURE__ */ jsx(SubsectionHeading, { children: subsection.title }),
|
|
4871
|
+
/* @__PURE__ */ jsx(List, { items: subsection.items })
|
|
4872
|
+
] }, subIndex)) })
|
|
4873
|
+
) : isSectionWithList(section) ? (
|
|
4874
|
+
// Section with list
|
|
4875
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4876
|
+
section.description && /* @__PURE__ */ jsx(Paragraph, { className: "mb-4", children: section.description }),
|
|
4877
|
+
/* @__PURE__ */ jsx(List, { items: section.items }),
|
|
4878
|
+
section.additionalContent && /* @__PURE__ */ jsx(Paragraph, { children: section.additionalContent })
|
|
4879
|
+
] })
|
|
4880
|
+
) : section.isHtml ? (
|
|
4881
|
+
// Section with HTML content
|
|
4882
|
+
/* @__PURE__ */ jsx(Paragraph, { children: /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: section.content } }) })
|
|
4883
|
+
) : (
|
|
4884
|
+
// Section with plain text content
|
|
4885
|
+
/* @__PURE__ */ jsx(Paragraph, { children: section.content })
|
|
4886
|
+
)
|
|
4887
|
+
] }, index)),
|
|
4888
|
+
text.contact && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4889
|
+
/* @__PURE__ */ jsx(SectionHeading, { children: text.contact.title }),
|
|
4890
|
+
text.contact.isHtml ? /* @__PURE__ */ jsx(Paragraph, { children: /* @__PURE__ */ jsx(
|
|
4891
|
+
"span",
|
|
4892
|
+
{
|
|
4893
|
+
dangerouslySetInnerHTML: { __html: text.contact.description }
|
|
4894
|
+
}
|
|
4895
|
+
) }) : /* @__PURE__ */ jsx(Paragraph, { children: text.contact.description }),
|
|
4896
|
+
/* @__PURE__ */ jsx("div", { className: "bg-gray-50 dark:bg-gray-800 p-4 rounded-lg", children: /* @__PURE__ */ jsxs("p", { className: "text-gray-700 dark:text-gray-300", children: [
|
|
4897
|
+
text.contact.info.emailLabel,
|
|
4898
|
+
" ",
|
|
4899
|
+
/* @__PURE__ */ jsx(
|
|
4900
|
+
"a",
|
|
4901
|
+
{
|
|
4902
|
+
href: `mailto:${text.contact.info.email}`,
|
|
4903
|
+
className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
4904
|
+
children: text.contact.info.email
|
|
4905
|
+
}
|
|
4906
|
+
),
|
|
4907
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
4908
|
+
text.contact.info.websiteLabel,
|
|
4909
|
+
" ",
|
|
4910
|
+
/* @__PURE__ */ jsx(
|
|
4911
|
+
"a",
|
|
4912
|
+
{
|
|
4913
|
+
href: text.contact.info.websiteUrl,
|
|
4914
|
+
className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
4915
|
+
children: text.contact.info.websiteUrl
|
|
4916
|
+
}
|
|
4917
|
+
),
|
|
4918
|
+
text.contact.info.dpoLabel && text.contact.info.dpoEmail && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4919
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
4920
|
+
text.contact.info.dpoLabel,
|
|
4921
|
+
" ",
|
|
4922
|
+
/* @__PURE__ */ jsx(
|
|
4923
|
+
"a",
|
|
4924
|
+
{
|
|
4925
|
+
href: `mailto:${text.contact.info.dpoEmail}`,
|
|
4926
|
+
className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
4927
|
+
children: text.contact.info.dpoEmail
|
|
4928
|
+
}
|
|
4929
|
+
)
|
|
4930
|
+
] })
|
|
4931
|
+
] }) }),
|
|
4932
|
+
text.contact.gdprNotice && /* @__PURE__ */ jsxs("div", { className: "mt-8 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg", children: [
|
|
4933
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-blue-900 dark:text-blue-200 mb-2", children: text.contact.gdprNotice.title }),
|
|
4934
|
+
/* @__PURE__ */ jsxs("p", { className: "text-blue-800 dark:text-blue-300", children: [
|
|
4935
|
+
text.contact.gdprNotice.content,
|
|
4936
|
+
" ",
|
|
4937
|
+
text.contact.info.dpoEmail && /* @__PURE__ */ jsx(
|
|
4938
|
+
"a",
|
|
4939
|
+
{
|
|
4940
|
+
href: `mailto:${text.contact.info.dpoEmail}`,
|
|
4941
|
+
className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
4942
|
+
children: text.contact.info.dpoEmail
|
|
4943
|
+
}
|
|
4944
|
+
)
|
|
4945
|
+
] })
|
|
4946
|
+
] })
|
|
4947
|
+
] })
|
|
4948
|
+
] })
|
|
4949
|
+
] });
|
|
4950
|
+
if (PageWrapper) {
|
|
4951
|
+
return /* @__PURE__ */ jsx(PageWrapper, { children: content });
|
|
4952
|
+
}
|
|
4953
|
+
return content;
|
|
4954
|
+
};
|
|
4739
4955
|
export {
|
|
4740
4956
|
AppBreadcrumbs,
|
|
4741
4957
|
AppFooter,
|
|
4742
4958
|
AppFooterForHomePage,
|
|
4743
4959
|
AppPageLayout,
|
|
4744
4960
|
AppPricingPage,
|
|
4961
|
+
AppSitemapPage,
|
|
4745
4962
|
AppSubscriptionsPage,
|
|
4963
|
+
AppTextPage,
|
|
4746
4964
|
AppTopBar,
|
|
4747
4965
|
AppTopBarWithFirebaseAuth,
|
|
4748
4966
|
AppTopBarWithWallet,
|