@deneb-ui/create-template 2.0.60 → 2.0.62
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/template/README.md +23 -0
- package/template/fivora-template.json +1 -1
- package/template/package.json +2 -2
- package/template/src/app/globals.css +31 -0
- package/template/src/app/page.tsx +59 -0
- package/template/src/app/products/detail/page.tsx +7 -0
- package/template/src/data/site-data.json +3 -3
- package/template/src/lib/siteDataContext.tsx +1 -0
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -79,6 +79,29 @@ When you run **`npm run lab`**, you can click directly on any element with a `da
|
|
|
79
79
|
|
|
80
80
|
The root layout wraps your application with `<SiteDataProvider>`, which automatically connects to the Fivora backend (`api.catalogUrl`) on live sites and listens to live visual editing updates in the Lab.
|
|
81
81
|
|
|
82
|
+
For product detail navigation in a static export, always use the stable exported
|
|
83
|
+
page `/products/detail/?id=PRODUCT_ID`. Do not generate `/products/PRODUCT_ID`
|
|
84
|
+
links for live catalog rows: products added after the build do not have a
|
|
85
|
+
corresponding static directory and will 404. The package owns the URL parsing,
|
|
86
|
+
live lookup, retries, and fallback states:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// src/app/products/detail/page.tsx
|
|
90
|
+
'use client';
|
|
91
|
+
|
|
92
|
+
import { PlatformProductDetail } from '@deneb-ui/ui';
|
|
93
|
+
|
|
94
|
+
export default function ProductDetailPage() {
|
|
95
|
+
return <PlatformProductDetail />;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Use `platformProductDetailHref(product.id)` for card links. To preserve a
|
|
100
|
+
template-specific visual design, pass `renderProduct={(product, context) =>
|
|
101
|
+
<YourProductDetail product={product} index={context.productIndex} />}` or use
|
|
102
|
+
the lower-level `usePlatformProductDetail()` hook. Always verify that the export
|
|
103
|
+
contains `products/detail/index.html`.
|
|
104
|
+
|
|
82
105
|
Import hooks from `@/lib/siteDataContext` or `@deneb-ui/ui`:
|
|
83
106
|
|
|
84
107
|
```tsx
|
package/template/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"next": "15.5.23",
|
|
19
19
|
"react": "19.2.8",
|
|
20
20
|
"react-dom": "19.2.8",
|
|
21
|
-
"@deneb-ui/ui": "^2.0.
|
|
21
|
+
"@deneb-ui/ui": "^2.0.62"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@eslint/eslintrc": "3.3.6",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"eslint": "9.39.5",
|
|
29
29
|
"eslint-config-next": "15.5.23",
|
|
30
30
|
"typescript": "5.8.3",
|
|
31
|
-
"@deneb-ui/cli": "^2.0.
|
|
31
|
+
"@deneb-ui/cli": "^2.0.62",
|
|
32
32
|
"tailwindcss": "^3.4.17",
|
|
33
33
|
"postcss": "8.5.26",
|
|
34
34
|
"autoprefixer": "^10.4.20"
|
|
@@ -273,6 +273,37 @@ h3 {
|
|
|
273
273
|
aspect-ratio: 16 / 10;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
.product-section-header {
|
|
277
|
+
max-width: 44rem;
|
|
278
|
+
margin: 0 auto 2.5rem;
|
|
279
|
+
text-align: center;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.product-section-header > p {
|
|
283
|
+
margin: 0.75rem auto 0;
|
|
284
|
+
color: color-mix(in srgb, var(--page-text) 72%, transparent);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.product-detail-link {
|
|
288
|
+
display: inline-flex;
|
|
289
|
+
width: 100%;
|
|
290
|
+
min-height: 2.75rem;
|
|
291
|
+
align-items: center;
|
|
292
|
+
justify-content: center;
|
|
293
|
+
border-radius: 0.75rem;
|
|
294
|
+
background: var(--brand-color);
|
|
295
|
+
color: #ffffff;
|
|
296
|
+
font-size: 0.875rem;
|
|
297
|
+
font-weight: 800;
|
|
298
|
+
text-decoration: none;
|
|
299
|
+
transition: filter 160ms ease, transform 160ms ease;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.product-detail-link:hover {
|
|
303
|
+
filter: brightness(1.08);
|
|
304
|
+
transform: translateY(-1px);
|
|
305
|
+
}
|
|
306
|
+
|
|
276
307
|
.contact-grid {
|
|
277
308
|
display: grid;
|
|
278
309
|
grid-template-columns: 1fr 1.35fr;
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
contentList,
|
|
5
5
|
contentObject,
|
|
6
6
|
contentText,
|
|
7
|
+
platformProductDetailHref,
|
|
7
8
|
useSiteData,
|
|
8
9
|
useProducts,
|
|
9
10
|
} from '@/lib/siteDataContext';
|
|
@@ -203,6 +204,64 @@ export default function HomePage() {
|
|
|
203
204
|
}}
|
|
204
205
|
</EditableList>
|
|
205
206
|
</section>
|
|
207
|
+
|
|
208
|
+
<section
|
|
209
|
+
className="page-section"
|
|
210
|
+
data-design-section="home-products"
|
|
211
|
+
>
|
|
212
|
+
<div className="section-header product-section-header">
|
|
213
|
+
<EditableText
|
|
214
|
+
variant="h2"
|
|
215
|
+
size="3xl"
|
|
216
|
+
weight="bold"
|
|
217
|
+
align="center"
|
|
218
|
+
color="heading"
|
|
219
|
+
className="section-title"
|
|
220
|
+
data-preview-field-path="home.productsHeading"
|
|
221
|
+
defaultValue={contentText(home.productsHeading)}
|
|
222
|
+
/>
|
|
223
|
+
<EditableText
|
|
224
|
+
variant="lead"
|
|
225
|
+
align="center"
|
|
226
|
+
color="muted"
|
|
227
|
+
data-preview-field-path="home.productsSummary"
|
|
228
|
+
defaultValue={contentText(home.productsSummary)}
|
|
229
|
+
/>
|
|
230
|
+
</div>
|
|
231
|
+
|
|
232
|
+
<EditableList
|
|
233
|
+
data-preview-list-path="products"
|
|
234
|
+
items={products}
|
|
235
|
+
className="card-grid"
|
|
236
|
+
itemAs={false}
|
|
237
|
+
>
|
|
238
|
+
{(rawProduct, index, itemPath) => {
|
|
239
|
+
const product = contentObject(rawProduct);
|
|
240
|
+
const productId =
|
|
241
|
+
typeof product.id === 'string' || typeof product.id === 'number'
|
|
242
|
+
? product.id
|
|
243
|
+
: null;
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<EditableProductCard
|
|
247
|
+
key={productId ?? index}
|
|
248
|
+
itemPath={itemPath}
|
|
249
|
+
product={product}
|
|
250
|
+
currency={contentText(product.currency) || 'LKR'}
|
|
251
|
+
actionSlot={
|
|
252
|
+
<a
|
|
253
|
+
href={platformProductDetailHref(productId)}
|
|
254
|
+
className="product-detail-link"
|
|
255
|
+
data-preview-static="Open the stable live product detail page"
|
|
256
|
+
>
|
|
257
|
+
View details
|
|
258
|
+
</a>
|
|
259
|
+
}
|
|
260
|
+
/>
|
|
261
|
+
);
|
|
262
|
+
}}
|
|
263
|
+
</EditableList>
|
|
264
|
+
</section>
|
|
206
265
|
</div>
|
|
207
266
|
);
|
|
208
267
|
}
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"products": [
|
|
168
168
|
{
|
|
169
169
|
"id": "prod-1",
|
|
170
|
-
"
|
|
170
|
+
"name": "Minimalist Ceramic Cup",
|
|
171
171
|
"description": "Handcrafted matte ceramic cup for your daily espresso or pour-over brew.",
|
|
172
172
|
"price": 3200,
|
|
173
173
|
"compareAtPrice": 4000,
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
},
|
|
180
180
|
{
|
|
181
181
|
"id": "prod-2",
|
|
182
|
-
"
|
|
182
|
+
"name": "Artisan Linen Apron",
|
|
183
183
|
"description": "Durable pure washed linen apron with deep front utility pockets.",
|
|
184
184
|
"price": 5400,
|
|
185
185
|
"compareAtPrice": 6200,
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
},
|
|
192
192
|
{
|
|
193
193
|
"id": "prod-3",
|
|
194
|
-
"
|
|
194
|
+
"name": "Botanical Room Spray",
|
|
195
195
|
"description": "Natural essential oil room mist infused with wild lavender and cedarwood.",
|
|
196
196
|
"price": 2800,
|
|
197
197
|
"compareAtPrice": null,
|