@deneb-ui/create-template 2.0.0
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/README.md +65 -0
- package/bin/index.js +127 -0
- package/package.json +37 -0
- package/template/README.md +126 -0
- package/template/_gitignore +13 -0
- package/template/eslint.config.mjs +13 -0
- package/template/fivora-template.json +259 -0
- package/template/next-env.d.ts +6 -0
- package/template/next.config.ts +17 -0
- package/template/package.json +35 -0
- package/template/public/fivora-icon.svg +29 -0
- package/template/public/fivora-logo.png +0 -0
- package/template/public/placeholder.svg +12 -0
- package/template/src/app/about_us/page.tsx +26 -0
- package/template/src/app/contact/page.tsx +79 -0
- package/template/src/app/globals.css +487 -0
- package/template/src/app/layout.tsx +26 -0
- package/template/src/app/page.tsx +244 -0
- package/template/src/app/services/page.tsx +51 -0
- package/template/src/components/SiteChrome.tsx +22 -0
- package/template/src/data/site-data.json +99 -0
- package/template/src/lib/siteDataContext.tsx +55 -0
- package/template/src/lib/utils.ts +14 -0
- package/template/tsconfig.json +41 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
contentList,
|
|
5
|
+
contentObject,
|
|
6
|
+
contentText,
|
|
7
|
+
useSiteData,
|
|
8
|
+
} from '@/lib/siteDataContext';
|
|
9
|
+
import { pageRoute, withBasePath } from '@/lib/utils';
|
|
10
|
+
import {
|
|
11
|
+
EditableText,
|
|
12
|
+
EditableImage,
|
|
13
|
+
EditableList,
|
|
14
|
+
EditableCard,
|
|
15
|
+
EditableBox,
|
|
16
|
+
EditableGrid,
|
|
17
|
+
} from '@deneb-ui/ui';
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
function navigate(pageKey: string) {
|
|
21
|
+
window.location.href = withBasePath(pageRoute(pageKey));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default function HomePage() {
|
|
25
|
+
const siteData = useSiteData();
|
|
26
|
+
const content = contentObject(siteData.content);
|
|
27
|
+
const home = contentObject(content.home);
|
|
28
|
+
const features = contentList(home.features);
|
|
29
|
+
const selectedPages =
|
|
30
|
+
siteData.requirements?.requiredPages ??
|
|
31
|
+
siteData.template?.structure?.pages ??
|
|
32
|
+
[];
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div data-preview-page-key="home">
|
|
36
|
+
<section className="hero" data-design-section="home-hero">
|
|
37
|
+
<div className="hero-copy">
|
|
38
|
+
<EditableText
|
|
39
|
+
variant="eyebrow"
|
|
40
|
+
color="primary"
|
|
41
|
+
className="eyebrow"
|
|
42
|
+
data-preview-field-path="home.heroEyebrow"
|
|
43
|
+
defaultValue={contentText(home.heroEyebrow)}
|
|
44
|
+
/>
|
|
45
|
+
<EditableText
|
|
46
|
+
variant="h1"
|
|
47
|
+
size="5xl"
|
|
48
|
+
weight="bold"
|
|
49
|
+
align="left"
|
|
50
|
+
color="heading"
|
|
51
|
+
data-preview-field-path="home.heroTitle"
|
|
52
|
+
defaultValue={contentText(home.heroTitle)}
|
|
53
|
+
/>
|
|
54
|
+
<EditableText
|
|
55
|
+
variant="lead"
|
|
56
|
+
color="muted"
|
|
57
|
+
data-preview-field-path="home.heroSummary"
|
|
58
|
+
defaultValue={contentText(home.heroSummary)}
|
|
59
|
+
/>
|
|
60
|
+
<div className="cta-row">
|
|
61
|
+
{selectedPages.includes('contact') ? (
|
|
62
|
+
<button
|
|
63
|
+
type="button"
|
|
64
|
+
data-target-page="contact"
|
|
65
|
+
className="button-primary"
|
|
66
|
+
onClick={() => navigate('contact')}
|
|
67
|
+
>
|
|
68
|
+
<span data-preview-field-path="home.primaryCtaLabel">
|
|
69
|
+
{contentText(home.primaryCtaLabel)}
|
|
70
|
+
</span>
|
|
71
|
+
</button>
|
|
72
|
+
) : (
|
|
73
|
+
<span
|
|
74
|
+
data-target-page="contact"
|
|
75
|
+
className="button-primary unavailable"
|
|
76
|
+
data-preview-field-path="home.primaryCtaLabel"
|
|
77
|
+
>
|
|
78
|
+
{contentText(home.primaryCtaLabel)}
|
|
79
|
+
</span>
|
|
80
|
+
)}
|
|
81
|
+
{selectedPages.includes('about_us') ? (
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
data-target-page="about_us"
|
|
85
|
+
className="button-secondary"
|
|
86
|
+
onClick={() => navigate('about_us')}
|
|
87
|
+
>
|
|
88
|
+
<span data-preview-field-path="home.secondaryCtaLabel">
|
|
89
|
+
{contentText(home.secondaryCtaLabel)}
|
|
90
|
+
</span>
|
|
91
|
+
</button>
|
|
92
|
+
) : (
|
|
93
|
+
<span
|
|
94
|
+
data-target-page="about_us"
|
|
95
|
+
className="button-secondary unavailable"
|
|
96
|
+
data-preview-field-path="home.secondaryCtaLabel"
|
|
97
|
+
>
|
|
98
|
+
{contentText(home.secondaryCtaLabel)}
|
|
99
|
+
</span>
|
|
100
|
+
)}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div className="hero-fivora-wrap">
|
|
104
|
+
<img
|
|
105
|
+
className="hero-image"
|
|
106
|
+
src={withBasePath(
|
|
107
|
+
contentText(home.bannerImageUrl) || '/fivora-icon.svg',
|
|
108
|
+
)}
|
|
109
|
+
alt="Fivora"
|
|
110
|
+
data-preview-field-path="home.bannerImageUrl"
|
|
111
|
+
/>
|
|
112
|
+
</div>
|
|
113
|
+
</section>
|
|
114
|
+
|
|
115
|
+
<section
|
|
116
|
+
className="page-section dev-guide-section"
|
|
117
|
+
data-design-section="home-developer-guide"
|
|
118
|
+
>
|
|
119
|
+
<div className="dev-guide-header">
|
|
120
|
+
<span className="dev-badge" data-preview-static="dev-guidance">
|
|
121
|
+
⚡ Template Developer Quickstart
|
|
122
|
+
</span>
|
|
123
|
+
<h2 data-preview-static="dev-guidance">
|
|
124
|
+
Build, Test, and Package with Fivora
|
|
125
|
+
</h2>
|
|
126
|
+
<p data-preview-static="dev-guidance">
|
|
127
|
+
Run these commands directly in your template terminal:
|
|
128
|
+
</p>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div className="dev-command-grid">
|
|
132
|
+
<div className="dev-cmd-card">
|
|
133
|
+
<div className="cmd-header">
|
|
134
|
+
<span className="cmd-tag" data-preview-static="dev-tag">Development</span>
|
|
135
|
+
<code data-preview-static="dev-command">npm run dev</code>
|
|
136
|
+
</div>
|
|
137
|
+
<p data-preview-static="dev-description">Hot-reloading local development with Next.js & React 19.</p>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<div className="dev-cmd-card">
|
|
141
|
+
<div className="cmd-header">
|
|
142
|
+
<span className="cmd-tag" data-preview-static="dev-tag">Simulate</span>
|
|
143
|
+
<code data-preview-static="dev-command">npm run lab</code>
|
|
144
|
+
</div>
|
|
145
|
+
<p data-preview-static="dev-description">Visual Editing Lab simulating merchant field clicks & edits.</p>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div className="dev-cmd-card">
|
|
149
|
+
<div className="cmd-header">
|
|
150
|
+
<span className="cmd-tag" data-preview-static="dev-tag">Compliance</span>
|
|
151
|
+
<code data-preview-static="dev-command">npm run validate</code>
|
|
152
|
+
</div>
|
|
153
|
+
<p data-preview-static="dev-description">Runs fivora preflight contract tests & empty states.</p>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<div className="dev-cmd-card">
|
|
157
|
+
<div className="cmd-header">
|
|
158
|
+
<span className="cmd-tag" data-preview-static="dev-tag">1-Click Upload</span>
|
|
159
|
+
<code data-preview-static="dev-command">npm run zip</code>
|
|
160
|
+
</div>
|
|
161
|
+
<p data-preview-static="dev-description">Automatically packages clean ZIP excluding caches & junk files.</p>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</section>
|
|
165
|
+
|
|
166
|
+
<section
|
|
167
|
+
className="page-section"
|
|
168
|
+
data-design-section="home-introduction"
|
|
169
|
+
>
|
|
170
|
+
<div className="home-intro-copy">
|
|
171
|
+
<EditableText
|
|
172
|
+
variant="h2"
|
|
173
|
+
size="3xl"
|
|
174
|
+
weight="bold"
|
|
175
|
+
align="center"
|
|
176
|
+
color="heading"
|
|
177
|
+
data-preview-field-path="home.introTitle"
|
|
178
|
+
defaultValue={contentText(home.introTitle)}
|
|
179
|
+
/>
|
|
180
|
+
<EditableText
|
|
181
|
+
variant="lead"
|
|
182
|
+
align="center"
|
|
183
|
+
color="muted"
|
|
184
|
+
data-preview-field-path="home.introBody"
|
|
185
|
+
defaultValue={contentText(home.introBody)}
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
</section>
|
|
189
|
+
|
|
190
|
+
<section
|
|
191
|
+
className="page-section alt"
|
|
192
|
+
data-design-section="home-features"
|
|
193
|
+
>
|
|
194
|
+
<div className="section-header">
|
|
195
|
+
<EditableText
|
|
196
|
+
variant="h2"
|
|
197
|
+
size="3xl"
|
|
198
|
+
weight="bold"
|
|
199
|
+
align="center"
|
|
200
|
+
color="heading"
|
|
201
|
+
className="section-title"
|
|
202
|
+
data-preview-field-path="home.featuresHeading"
|
|
203
|
+
defaultValue={contentText(home.featuresHeading)}
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
<EditableList
|
|
207
|
+
data-preview-list-path="home.features"
|
|
208
|
+
items={features}
|
|
209
|
+
className="card-grid"
|
|
210
|
+
itemAs={false}
|
|
211
|
+
>
|
|
212
|
+
{(rawFeature, index) => {
|
|
213
|
+
const feature = contentObject(rawFeature);
|
|
214
|
+
return (
|
|
215
|
+
<EditableCard
|
|
216
|
+
className="card"
|
|
217
|
+
key={index}
|
|
218
|
+
itemPath={`home.features[${index}]`}
|
|
219
|
+
data-preview-item-path={`home.features[${index}]`}
|
|
220
|
+
item={feature as any}
|
|
221
|
+
balance
|
|
222
|
+
minHeight="220px"
|
|
223
|
+
radius="16px"
|
|
224
|
+
>
|
|
225
|
+
<EditableText
|
|
226
|
+
variant="h3"
|
|
227
|
+
color="heading"
|
|
228
|
+
data-preview-field-path={`home.features[${index}].title`}
|
|
229
|
+
defaultValue={contentText(feature.title)}
|
|
230
|
+
/>
|
|
231
|
+
<EditableText
|
|
232
|
+
variant="p"
|
|
233
|
+
color="muted"
|
|
234
|
+
data-preview-field-path={`home.features[${index}].body`}
|
|
235
|
+
defaultValue={contentText(feature.body)}
|
|
236
|
+
/>
|
|
237
|
+
</EditableCard>
|
|
238
|
+
);
|
|
239
|
+
}}
|
|
240
|
+
</EditableList>
|
|
241
|
+
</section>
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { contentList, contentObject, contentText, useSiteData } from '@/lib/siteDataContext';
|
|
4
|
+
import { withBasePath } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
export default function ServicesPage() {
|
|
7
|
+
const siteData = useSiteData();
|
|
8
|
+
const content = contentObject(siteData.content);
|
|
9
|
+
const page = contentObject(content.servicesPage);
|
|
10
|
+
const services = contentList(content.services);
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div data-preview-page-key="services">
|
|
14
|
+
<section className="page-section page-heading" data-design-section="services-heading">
|
|
15
|
+
<h1 data-preview-field-path="servicesPage.heading">{contentText(page.heading)}</h1>
|
|
16
|
+
<p data-preview-field-path="servicesPage.intro">{contentText(page.intro)}</p>
|
|
17
|
+
</section>
|
|
18
|
+
<section className="page-section alt" data-design-section="services-list">
|
|
19
|
+
<div className="card-grid" data-preview-list-path="services">
|
|
20
|
+
{services.map((rawService, index) => {
|
|
21
|
+
const service = contentObject(rawService);
|
|
22
|
+
const features = contentList(service.features);
|
|
23
|
+
return (
|
|
24
|
+
<article className="card" key={contentText(service.id) || index} data-preview-item-path={`services[${index}]`}>
|
|
25
|
+
<img
|
|
26
|
+
className="card-image"
|
|
27
|
+
src={withBasePath(contentText(service.imageUrl) || '/placeholder.svg')}
|
|
28
|
+
alt=""
|
|
29
|
+
data-preview-field-path={`services[${index}].imageUrl`}
|
|
30
|
+
/>
|
|
31
|
+
<h2 data-preview-field-path={`services[${index}].name`}>{contentText(service.name)}</h2>
|
|
32
|
+
<p data-preview-field-path={`services[${index}].description`}>{contentText(service.description)}</p>
|
|
33
|
+
<ul data-preview-list-path={`services[${index}].features`}>
|
|
34
|
+
{features.map((feature, featureIndex) => (
|
|
35
|
+
<li
|
|
36
|
+
key={featureIndex}
|
|
37
|
+
data-preview-item-path={`services[${index}].features[${featureIndex}]`}
|
|
38
|
+
data-preview-field-path={`services[${index}].features[${featureIndex}]`}
|
|
39
|
+
>
|
|
40
|
+
{contentText(feature)}
|
|
41
|
+
</li>
|
|
42
|
+
))}
|
|
43
|
+
</ul>
|
|
44
|
+
</article>
|
|
45
|
+
);
|
|
46
|
+
})}
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
import { usePathname } from 'next/navigation';
|
|
5
|
+
import { useSiteData } from '@/lib/siteDataContext';
|
|
6
|
+
import { Navbar, Footer, getThemeCssProperties } from '@deneb-ui/ui';
|
|
7
|
+
|
|
8
|
+
export default function SiteChrome({ children }: { children: ReactNode }) {
|
|
9
|
+
const siteData = useSiteData();
|
|
10
|
+
const pathname = usePathname();
|
|
11
|
+
const themeStyle = getThemeCssProperties(
|
|
12
|
+
siteData?.template?.structure?.theme as any,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="site-shell" style={themeStyle}>
|
|
17
|
+
<Navbar activeRoute={pathname} />
|
|
18
|
+
<main>{children}</main>
|
|
19
|
+
<Footer />
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": { "id": "starter-demo", "title": "Fivora Starter Demo", "status": "APPROVED" },
|
|
3
|
+
"merchant": {
|
|
4
|
+
"businessName": "Fivora Store",
|
|
5
|
+
"description": "A modern high-converting digital storefront built on the Fivora platform."
|
|
6
|
+
},
|
|
7
|
+
"template": {
|
|
8
|
+
"id": "starter-template",
|
|
9
|
+
"name": "Fivora Starter",
|
|
10
|
+
"engine": "NEXT_STATIC_EXPORT",
|
|
11
|
+
"structure": {
|
|
12
|
+
"pages": ["home", "about_us", "services", "contact"],
|
|
13
|
+
"theme": {
|
|
14
|
+
"primaryColor": "#016a7e",
|
|
15
|
+
"secondaryColor": "#0a1931",
|
|
16
|
+
"accentColor": "#00adb5",
|
|
17
|
+
"backgroundColor": "#ffffff",
|
|
18
|
+
"textColor": "#0f172a",
|
|
19
|
+
"headingFont": "Inter",
|
|
20
|
+
"bodyFont": "Inter",
|
|
21
|
+
"baseSize": "16px",
|
|
22
|
+
"heroMinHeight": "72vh",
|
|
23
|
+
"sectionPadding": "5rem"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"requirements": {
|
|
28
|
+
"requiredPages": ["home", "about_us", "services", "contact"],
|
|
29
|
+
"requiredFeatures": []
|
|
30
|
+
},
|
|
31
|
+
"content": {
|
|
32
|
+
"common": {
|
|
33
|
+
"websiteTitle": "Fivora Store",
|
|
34
|
+
"shortDescription": "Next-generation commerce templates built for the Fivora with reusable components and strict visual editing.",
|
|
35
|
+
"logoUrl": "/fivora-logo.png",
|
|
36
|
+
"headerCtaLabel": "Contact Us",
|
|
37
|
+
"navLabels": {
|
|
38
|
+
"home": "Home",
|
|
39
|
+
"about_us": "About",
|
|
40
|
+
"services": "Services",
|
|
41
|
+
"contact": "Contact"
|
|
42
|
+
},
|
|
43
|
+
"footerHeading": "Build something extraordinary with Fivora.",
|
|
44
|
+
"copyright": "Fivora. All rights reserved."
|
|
45
|
+
},
|
|
46
|
+
"home": {
|
|
47
|
+
"heroEyebrow": "⚡ Fivora Template Starter",
|
|
48
|
+
"heroTitle": "Design Stores That Captivate",
|
|
49
|
+
"heroSummary": "Built with @fivora/editable-components. Hot-reload locally, simulate merchant visual editing in the Lab, validate preflight contracts, and package with 1-click.",
|
|
50
|
+
"bannerImageUrl": "/fivora-icon.svg",
|
|
51
|
+
"primaryCtaLabel": "Explore Services",
|
|
52
|
+
"secondaryCtaLabel": "About This Starter",
|
|
53
|
+
"introTitle": "Engineered for high conversion and effortless editing",
|
|
54
|
+
"introBody": "Every editable value comes directly from Fivora site data with auto-balancing layouts, responsive typography, and strict contract validation out of the box.",
|
|
55
|
+
"featuresHeading": "Why build with the Fivora Authoring Kit?",
|
|
56
|
+
"features": [
|
|
57
|
+
{ "title": "Auto-Balancing Layouts", "body": "Cards, grids, and containers automatically balance and fill space seamlessly across all screen sizes." },
|
|
58
|
+
{ "title": "Strict Visual Editing", "body": "Direct bindings enable merchants to click, edit, and preview changes without breaking template styles." },
|
|
59
|
+
{ "title": "1-Click Clean Packaging", "body": "Built-in zip command strips heavy caches, node_modules, and git files so uploads pass instantly." }
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"about": {
|
|
63
|
+
"heading": "Built for the next generation of online storefronts",
|
|
64
|
+
"body": "The Fivora connects businesses with high-converting, beautifully crafted templates. This starter template demonstrates clean monorepo architecture, responsive typography, and auto-balancing components.",
|
|
65
|
+
"imageUrl": "/placeholder.svg"
|
|
66
|
+
},
|
|
67
|
+
"servicesPage": {
|
|
68
|
+
"heading": "Template Services & Capabilities",
|
|
69
|
+
"intro": "Each service card is an atomic component featuring an image, heading, description, and repeatable checklist."
|
|
70
|
+
},
|
|
71
|
+
"services": [
|
|
72
|
+
{
|
|
73
|
+
"id": "visual-editing",
|
|
74
|
+
"name": "Visual Editing Lab",
|
|
75
|
+
"description": "Simulate how merchants customize your template in real time with the built-in local development lab.",
|
|
76
|
+
"imageUrl": "/placeholder.svg",
|
|
77
|
+
"features": ["Zero-server static preview", "Field focus bridge", "Instant feedback"]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "clean-packaging",
|
|
81
|
+
"name": "Automated Packager",
|
|
82
|
+
"description": "Automatically produce clean, upload-ready ZIP archives excluding junk and cache files.",
|
|
83
|
+
"imageUrl": "/placeholder.svg",
|
|
84
|
+
"features": ["Excludes node_modules", "Excludes .next and .git", "100% preflight compliant"]
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"contact": {
|
|
88
|
+
"heading": "Get in touch with our team",
|
|
89
|
+
"intro": "Have questions about building or customizing Fivora templates? Contact us today.",
|
|
90
|
+
"phone": "+94 11 234 5678",
|
|
91
|
+
"email": "developer@fivora.lk",
|
|
92
|
+
"address": "Colombo, Sri Lanka",
|
|
93
|
+
"formTitle": "Send an enquiry",
|
|
94
|
+
"submitLabel": "Send Message"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"media": {},
|
|
98
|
+
"seo": null
|
|
99
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import {
|
|
5
|
+
SiteDataProvider as BaseSiteDataProvider,
|
|
6
|
+
useSiteData,
|
|
7
|
+
contentText,
|
|
8
|
+
contentObject,
|
|
9
|
+
contentList,
|
|
10
|
+
type SiteData,
|
|
11
|
+
type SiteDataProviderProps,
|
|
12
|
+
PREVIEW_DATA_MESSAGE,
|
|
13
|
+
LEGACY_PREVIEW_DATA_MESSAGE,
|
|
14
|
+
PREVIEW_READY_MESSAGE,
|
|
15
|
+
LEGACY_PREVIEW_READY_MESSAGE,
|
|
16
|
+
PREVIEW_FOCUS_MESSAGE,
|
|
17
|
+
LEGACY_PREVIEW_FOCUS_MESSAGE,
|
|
18
|
+
PREVIEW_FIELD_ATTRIBUTE,
|
|
19
|
+
} from '@deneb-ui/ui';
|
|
20
|
+
|
|
21
|
+
import initialSiteData from '@/data/site-data.json';
|
|
22
|
+
|
|
23
|
+
export function SiteDataProvider({
|
|
24
|
+
children,
|
|
25
|
+
initialSiteData: providedInitialData,
|
|
26
|
+
...props
|
|
27
|
+
}: {
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
initialSiteData?: SiteData;
|
|
30
|
+
}) {
|
|
31
|
+
return (
|
|
32
|
+
<BaseSiteDataProvider
|
|
33
|
+
initialSiteData={providedInitialData ?? (initialSiteData as SiteData)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</BaseSiteDataProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
useSiteData,
|
|
43
|
+
contentText,
|
|
44
|
+
contentObject,
|
|
45
|
+
contentList,
|
|
46
|
+
PREVIEW_DATA_MESSAGE,
|
|
47
|
+
LEGACY_PREVIEW_DATA_MESSAGE,
|
|
48
|
+
PREVIEW_READY_MESSAGE,
|
|
49
|
+
LEGACY_PREVIEW_READY_MESSAGE,
|
|
50
|
+
PREVIEW_FOCUS_MESSAGE,
|
|
51
|
+
LEGACY_PREVIEW_FOCUS_MESSAGE,
|
|
52
|
+
PREVIEW_FIELD_ATTRIBUTE,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type { SiteData, SiteDataProviderProps };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function withBasePath(value?: string | null) {
|
|
2
|
+
const url = value?.trim() ?? '';
|
|
3
|
+
if (!url || /^(?:[a-z][a-z0-9+.-]*:|\/\/|#)/i.test(url)) return url;
|
|
4
|
+
const basePath = (process.env.NEXT_PUBLIC_SITE_BASE_PATH ?? '').replace(
|
|
5
|
+
/\/$/,
|
|
6
|
+
'',
|
|
7
|
+
);
|
|
8
|
+
const path = url.startsWith('/') ? url : `/${url}`;
|
|
9
|
+
return `${basePath}${path}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function pageRoute(pageKey: string) {
|
|
13
|
+
return pageKey === 'home' ? '/' : `/${pageKey}`;
|
|
14
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": [
|
|
5
|
+
"dom",
|
|
6
|
+
"dom.iterable",
|
|
7
|
+
"esnext"
|
|
8
|
+
],
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"moduleResolution": "bundler",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"isolatedModules": true,
|
|
18
|
+
"jsx": "preserve",
|
|
19
|
+
"incremental": true,
|
|
20
|
+
"plugins": [
|
|
21
|
+
{
|
|
22
|
+
"name": "next"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"paths": {
|
|
26
|
+
"@/*": [
|
|
27
|
+
"./src/*"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"next-env.d.ts",
|
|
33
|
+
"**/*.ts",
|
|
34
|
+
"**/*.tsx",
|
|
35
|
+
".next/types/**/*.ts",
|
|
36
|
+
".next/dev/types/**/*.ts"
|
|
37
|
+
],
|
|
38
|
+
"exclude": [
|
|
39
|
+
"node_modules"
|
|
40
|
+
]
|
|
41
|
+
}
|