payaza-storefront-layouts 1.0.7 → 1.0.9
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/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/layouts/food/components/FoodHomePage.js +3 -3
- package/dist/lib/preview-data.d.ts +6 -0
- package/dist/lib/preview-data.d.ts.map +1 -1
- package/dist/lib/preview-data.js +25 -0
- package/dist/lib/utils/asset-helpers.d.ts +7 -0
- package/dist/lib/utils/asset-helpers.d.ts.map +1 -1
- package/dist/lib/utils/asset-helpers.js +43 -0
- package/dist/preview/LayoutPreview.d.ts +3 -8
- package/dist/preview/LayoutPreview.d.ts.map +1 -1
- package/dist/preview/LayoutPreview.js +149 -29
- package/dist/preview/PreviewRouter.d.ts +15 -0
- package/dist/preview/PreviewRouter.d.ts.map +1 -0
- package/dist/preview/PreviewRouter.js +461 -0
- package/dist/preview/ShadowDOMWrapper.d.ts +21 -0
- package/dist/preview/ShadowDOMWrapper.d.ts.map +1 -0
- package/dist/preview/ShadowDOMWrapper.js +213 -0
- package/dist/preview/index.d.ts +2 -0
- package/dist/preview/index.d.ts.map +1 -1
- package/dist/preview/index.js +2 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -118,5 +118,7 @@ export { StoreProvider, useStore } from './lib/store-context';
|
|
|
118
118
|
export { LoadingProvider, useLoading } from './lib/loading-context';
|
|
119
119
|
export { AuthProvider, useAuth } from './lib/auth-context';
|
|
120
120
|
export { LayoutPreview } from './preview';
|
|
121
|
-
export {
|
|
121
|
+
export { ShadowDOMWrapper } from './preview/ShadowDOMWrapper';
|
|
122
|
+
export { PreviewRouter } from './preview/PreviewRouter';
|
|
123
|
+
export { getFoodPreviewData, getClothingPreviewData, getBookingPreviewData, getFoodModernPreviewData, getClothingMinimalPreviewData, getBookingAgendaPreviewData, getElectronicsGridPreviewData, getElectronicsPreviewData, getMotivationalSpeakerPreviewData, getPreviewDataByLayout, getLayoutIdByStoreSlug, } from './lib/preview-data';
|
|
122
124
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrF,OAAO,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AACpG,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrF,OAAO,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGlF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AACzF,OAAO,EAAE,YAAY,IAAI,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClG,OAAO,EAAE,iBAAiB,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjH,OAAO,EAAE,YAAY,IAAI,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClG,OAAO,EAAE,cAAc,IAAI,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACxG,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AACtF,OAAO,EAAE,SAAS,IAAI,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,WAAW,IAAI,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAG/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClF,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,IAAI,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAC5G,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7F,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACnG,OAAO,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,WAAW,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAG1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,+DAA+D,CAAC;AACxG,OAAO,EAAE,YAAY,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC5G,OAAO,EAAE,iBAAiB,IAAI,gCAAgC,EAAE,MAAM,oDAAoD,CAAC;AAC3H,OAAO,EAAE,YAAY,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC5G,OAAO,EAAE,cAAc,IAAI,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAClH,OAAO,EAAE,SAAS,IAAI,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACnG,OAAO,EAAE,WAAW,IAAI,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAGzG,OAAO,EAAE,eAAe,EAAE,MAAM,8CAA8C,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,iBAAiB,IAAI,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAC1G,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAGxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,EAAE,YAAY,IAAI,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxG,OAAO,EAAE,iBAAiB,IAAI,8BAA8B,EAAE,MAAM,kDAAkD,CAAC;AACvH,OAAO,EAAE,YAAY,IAAI,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxG,OAAO,EAAE,cAAc,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC9G,OAAO,EAAE,SAAS,IAAI,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,WAAW,IAAI,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AAGrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,sDAAsD,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,0DAA0D,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAAE,MAAM,4DAA4D,CAAC;AACvG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yDAAyD,CAAC;AACjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yDAAyD,CAAC;AACjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yDAAyD,CAAC;AACjG,OAAO,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AACzG,OAAO,EAAE,YAAY,IAAI,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AACvG,OAAO,EAAE,iBAAiB,IAAI,4BAA4B,EAAE,MAAM,+CAA+C,CAAC;AAClH,OAAO,EAAE,YAAY,IAAI,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EAAE,cAAc,IAAI,6BAA6B,EAAE,MAAM,4CAA4C,CAAC;AAC7G,OAAO,EAAE,SAAS,IAAI,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,WAAW,IAAI,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAChG,OAAO,EAAE,cAAc,IAAI,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACzG,OAAO,EAAE,iBAAiB,IAAI,4BAA4B,EAAE,MAAM,+CAA+C,CAAC;AAClH,OAAO,EAAE,mBAAmB,IAAI,8BAA8B,EAAE,MAAM,iDAAiD,CAAC;AACxH,OAAO,EAAE,SAAS,IAAI,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,cAAc,IAAI,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAGzG,OAAO,EAAE,0BAA0B,IAAI,8BAA8B,EAAE,MAAM,kEAAkE,CAAC;AAChJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,+DAA+D,CAAC;AACxG,OAAO,EAAE,6BAA6B,EAAE,MAAM,gEAAgE,CAAC;AAC/G,OAAO,EAAE,YAAY,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC5G,OAAO,EAAE,iBAAiB,IAAI,gCAAgC,EAAE,MAAM,oDAAoD,CAAC;AAC3H,OAAO,EAAE,YAAY,IAAI,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC5G,OAAO,EAAE,cAAc,IAAI,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AACtH,OAAO,EAAE,SAAS,IAAI,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACnG,OAAO,EAAE,WAAW,IAAI,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AACzG,OAAO,EAAE,cAAc,IAAI,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAClH,OAAO,EAAE,iBAAiB,IAAI,gCAAgC,EAAE,MAAM,oDAAoD,CAAC;AAC3H,OAAO,EAAE,mBAAmB,IAAI,kCAAkC,EAAE,MAAM,sDAAsD,CAAC;AACjI,OAAO,EAAE,SAAS,IAAI,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACnG,OAAO,EAAE,cAAc,IAAI,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAGlH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,MAAM,mEAAmE,CAAC;AAC5G,OAAO,EAAE,YAAY,IAAI,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,wDAAwD,CAAC;AAC3F,OAAO,EAAE,YAAY,IAAI,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7G,OAAO,EAAE,gBAAgB,EAAE,MAAM,uDAAuD,CAAC;AACzF,OAAO,EAAE,YAAY,IAAI,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAC7G,OAAO,EAAE,SAAS,IAAI,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACpG,OAAO,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,kDAAkD,CAAC;AAG1G,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -131,4 +131,6 @@ export { LoadingProvider, useLoading } from './lib/loading-context';
|
|
|
131
131
|
export { AuthProvider, useAuth } from './lib/auth-context';
|
|
132
132
|
// Preview Components and Data
|
|
133
133
|
export { LayoutPreview } from './preview';
|
|
134
|
-
export {
|
|
134
|
+
export { ShadowDOMWrapper } from './preview/ShadowDOMWrapper';
|
|
135
|
+
export { PreviewRouter } from './preview/PreviewRouter';
|
|
136
|
+
export { getFoodPreviewData, getClothingPreviewData, getBookingPreviewData, getFoodModernPreviewData, getClothingMinimalPreviewData, getBookingAgendaPreviewData, getElectronicsGridPreviewData, getElectronicsPreviewData, getMotivationalSpeakerPreviewData, getPreviewDataByLayout, getLayoutIdByStoreSlug, } from './lib/preview-data';
|
|
@@ -8,7 +8,7 @@ import Link from 'next/link';
|
|
|
8
8
|
import Image from 'next/image';
|
|
9
9
|
import { useState, useEffect } from 'react';
|
|
10
10
|
import { formatCurrency } from '../../../lib/utils';
|
|
11
|
-
import { getLayoutText, getBannerImage, getTextContent } from '../../../lib/utils/asset-helpers';
|
|
11
|
+
import { getLayoutText, getBannerImage, getTextContent, normalizeStoreImageUrl } from '../../../lib/utils/asset-helpers';
|
|
12
12
|
import { shouldUseAPI } from '../../../lib/utils/demo-detection';
|
|
13
13
|
import { TestimonialCard } from '../../shared/components/TestimonialCard';
|
|
14
14
|
import { PromoBanner } from '../../shared/components/PromoBanner';
|
|
@@ -68,7 +68,7 @@ export function FoodHomePage({ storeConfig }) {
|
|
|
68
68
|
const showBadges = layoutConfig?.sections?.hero?.showBadges !== false &&
|
|
69
69
|
(layoutConfig?.hero?.showBadges !== false || layoutConfig?.sections?.hero?.showBadges === undefined);
|
|
70
70
|
return {
|
|
71
|
-
image: slider.image || '',
|
|
71
|
+
image: normalizeStoreImageUrl(slider.image) || '',
|
|
72
72
|
badge: (showBadges && slider.badge && slider.badge.trim() !== '') ? slider.badge : "#1 Food Delivery in Town",
|
|
73
73
|
title: slider.title || "Taste the",
|
|
74
74
|
highlight: slider.highlight || "Extraordinary", // Food layout specific
|
|
@@ -93,7 +93,7 @@ export function FoodHomePage({ storeConfig }) {
|
|
|
93
93
|
const showBadges = layoutConfig?.sections?.hero?.showBadges !== false &&
|
|
94
94
|
(layoutConfig?.hero?.showBadges !== false || layoutConfig?.sections?.hero?.showBadges === undefined);
|
|
95
95
|
return {
|
|
96
|
-
image: slider.image || '',
|
|
96
|
+
image: normalizeStoreImageUrl(slider.image) || '',
|
|
97
97
|
badge: (showBadges && slider.badge && slider.badge.trim() !== '') ? slider.badge : "#1 Food Delivery in Town",
|
|
98
98
|
title: slider.title || "Taste the",
|
|
99
99
|
highlight: slider.highlight || "Extraordinary", // Food layout specific
|
|
@@ -49,4 +49,10 @@ export declare function getMotivationalSpeakerPreviewData(): StoreConfig;
|
|
|
49
49
|
* Helper function to get preview data by layout type
|
|
50
50
|
*/
|
|
51
51
|
export declare function getPreviewDataByLayout(layout: string): StoreConfig | null;
|
|
52
|
+
/**
|
|
53
|
+
* Get layout ID by store slug from preview data
|
|
54
|
+
* Returns the layout ID (e.g., 'food-modern') for a given store slug (e.g., 'modern-eats')
|
|
55
|
+
* Returns null if slug not found in preview data
|
|
56
|
+
*/
|
|
57
|
+
export declare function getLayoutIdByStoreSlug(storeSlug: string): string | null;
|
|
52
58
|
//# sourceMappingURL=preview-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-data.d.ts","sourceRoot":"","sources":["../../src/lib/preview-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;GASG;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CA6IhD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,WAAW,CAgSpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,CAqInD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,WAAW,CA+EtD;AAGD;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,WAAW,CAmK3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,WAAW,CA4HzD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,WAAW,CA4c3D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,WAAW,CAqPvD;AAED;;GAEG;AACH,wBAAgB,iCAAiC,IAAI,WAAW,CA6N/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAuBzE"}
|
|
1
|
+
{"version":3,"file":"preview-data.d.ts","sourceRoot":"","sources":["../../src/lib/preview-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;GASG;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CA6IhD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,WAAW,CAgSpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,CAqInD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,WAAW,CA+EtD;AAGD;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,WAAW,CAmK3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,WAAW,CA4HzD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,WAAW,CA4c3D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,WAAW,CAqPvD;AAED;;GAEG;AACH,wBAAgB,iCAAiC,IAAI,WAAW,CA6N/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAuBzE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBvE"}
|
package/dist/lib/preview-data.js
CHANGED
|
@@ -1925,3 +1925,28 @@ export function getPreviewDataByLayout(layout) {
|
|
|
1925
1925
|
return null;
|
|
1926
1926
|
}
|
|
1927
1927
|
}
|
|
1928
|
+
/**
|
|
1929
|
+
* Get layout ID by store slug from preview data
|
|
1930
|
+
* Returns the layout ID (e.g., 'food-modern') for a given store slug (e.g., 'modern-eats')
|
|
1931
|
+
* Returns null if slug not found in preview data
|
|
1932
|
+
*/
|
|
1933
|
+
export function getLayoutIdByStoreSlug(storeSlug) {
|
|
1934
|
+
const layouts = [
|
|
1935
|
+
'food',
|
|
1936
|
+
'food-modern',
|
|
1937
|
+
'clothing',
|
|
1938
|
+
'clothing-minimal',
|
|
1939
|
+
'booking',
|
|
1940
|
+
'booking-agenda',
|
|
1941
|
+
'electronics',
|
|
1942
|
+
'electronics-grid',
|
|
1943
|
+
'motivational-speaker',
|
|
1944
|
+
];
|
|
1945
|
+
for (const layout of layouts) {
|
|
1946
|
+
const previewData = getPreviewDataByLayout(layout);
|
|
1947
|
+
if (previewData && previewData.slug === storeSlug) {
|
|
1948
|
+
return layout;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
return null;
|
|
1952
|
+
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { StoreConfig } from '../../lib/store-types';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes store image URLs to absolute URLs
|
|
4
|
+
* Handles both absolute URLs (R2/Cloudflare/etc.) and relative paths
|
|
5
|
+
* @param raw - The raw image URL (can be relative or absolute)
|
|
6
|
+
* @returns Normalized absolute URL or null if invalid
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeStoreImageUrl(raw: unknown): string | null;
|
|
2
9
|
/**
|
|
3
10
|
* Gets text content from backend assignedText for real stores, or returns fallback for demo stores
|
|
4
11
|
* @param storeConfig - The store configuration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/asset-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"asset-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/asset-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYhD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAuClE;AAUD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,MAAM,CAuBR;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,EAAE,CAkEV;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,CAoBR;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,CAsDR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,CA8BR;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EACvC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,WAAW,EAAE,MAAM,GAClB,MAAM,CAcR;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,MAAM,CAwCR;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,MAAM,CA+BR;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAC1C,MAAM,GAAG,IAAI,CAoBf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,QAAQ,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,gBAAgB,EACrF,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,MAAM,CAgDR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7D,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,QAAQ,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG;QAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,gBAAgB,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAAE,GACrJ,CAAC,CAWH"}
|
|
@@ -10,6 +10,49 @@ function normalizeAssetUrl(url) {
|
|
|
10
10
|
return null;
|
|
11
11
|
return trimmed;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Normalizes store image URLs to absolute URLs
|
|
15
|
+
* Handles both absolute URLs (R2/Cloudflare/etc.) and relative paths
|
|
16
|
+
* @param raw - The raw image URL (can be relative or absolute)
|
|
17
|
+
* @returns Normalized absolute URL or null if invalid
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeStoreImageUrl(raw) {
|
|
20
|
+
// Handle null, undefined, or non-string values
|
|
21
|
+
if (raw === null || raw === undefined)
|
|
22
|
+
return null;
|
|
23
|
+
if (typeof raw !== 'string')
|
|
24
|
+
return null;
|
|
25
|
+
const trimmed = raw.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
return null;
|
|
28
|
+
if (trimmed === 'undefined' || trimmed === 'null' || trimmed === '')
|
|
29
|
+
return null;
|
|
30
|
+
// Absolute URLs (R2/Cloudflare/etc.) - return as-is
|
|
31
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
32
|
+
return trimmed;
|
|
33
|
+
}
|
|
34
|
+
// Backend-served uploads (relative path)
|
|
35
|
+
// Try to get API base URL from environment or use default
|
|
36
|
+
const apiBase = typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_API_URL
|
|
37
|
+
? process.env.NEXT_PUBLIC_API_URL
|
|
38
|
+
: (typeof window !== 'undefined'
|
|
39
|
+
? window.location.origin.replace(/:\d+$/, ':4002') // Try to infer from current origin
|
|
40
|
+
: 'http://localhost:4002');
|
|
41
|
+
// Handle paths starting with /uploads/
|
|
42
|
+
if (trimmed.startsWith('/uploads/')) {
|
|
43
|
+
return `${apiBase}${trimmed}`;
|
|
44
|
+
}
|
|
45
|
+
// Handle paths starting with uploads/ (no leading slash)
|
|
46
|
+
if (trimmed.startsWith('uploads/')) {
|
|
47
|
+
return `${apiBase}/${trimmed}`;
|
|
48
|
+
}
|
|
49
|
+
// Handle paths starting with / (other backend paths)
|
|
50
|
+
if (trimmed.startsWith('/')) {
|
|
51
|
+
return `${apiBase}${trimmed}`;
|
|
52
|
+
}
|
|
53
|
+
// As a last resort, return as-is (could already be a resolvable relative asset)
|
|
54
|
+
return trimmed;
|
|
55
|
+
}
|
|
13
56
|
function pickFirstAssetUrl(...candidates) {
|
|
14
57
|
for (const c of candidates) {
|
|
15
58
|
const normalized = normalizeAssetUrl(c);
|
|
@@ -2,14 +2,9 @@ import { StoreLayoutType } from '../lib/store-types';
|
|
|
2
2
|
interface LayoutPreviewProps {
|
|
3
3
|
layout: StoreLayoutType | string;
|
|
4
4
|
className?: string;
|
|
5
|
+
initialRoute?: string;
|
|
6
|
+
onRouteChange?: (route: string) => void;
|
|
5
7
|
}
|
|
6
|
-
|
|
7
|
-
* LayoutPreview Component
|
|
8
|
-
*
|
|
9
|
-
* Renders a layout component with embedded preview data.
|
|
10
|
-
* This component is used to preview layouts in standalone applications
|
|
11
|
-
* and demonstrates that layouts are self-sustaining with embedded data.
|
|
12
|
-
*/
|
|
13
|
-
export declare function LayoutPreview({ layout, className }: LayoutPreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function LayoutPreview(props: LayoutPreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
14
9
|
export {};
|
|
15
10
|
//# sourceMappingURL=LayoutPreview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayoutPreview.d.ts","sourceRoot":"","sources":["../../src/preview/LayoutPreview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAe,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"LayoutPreview.d.ts","sourceRoot":"","sources":["../../src/preview/LayoutPreview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAe,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAuBjE,UAAU,kBAAkB;IAC1B,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAoND,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAEtD"}
|
|
@@ -1,17 +1,150 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState, useCallback } from 'react';
|
|
3
4
|
import { getPreviewDataByLayout } from '../lib/preview-data';
|
|
4
|
-
import {
|
|
5
|
+
import { ToastProvider, StoreProvider, LoadingProvider, AuthProvider, } from '../index';
|
|
6
|
+
import { ShadowDOMWrapper } from './ShadowDOMWrapper';
|
|
7
|
+
import { PreviewRouter } from './PreviewRouter';
|
|
8
|
+
// Try to import Next.js router hooks - will throw if not in Next.js context
|
|
9
|
+
let useRouter;
|
|
10
|
+
let usePathname;
|
|
11
|
+
try {
|
|
12
|
+
const nextNavigation = require('next/navigation');
|
|
13
|
+
useRouter = nextNavigation.useRouter;
|
|
14
|
+
usePathname = nextNavigation.usePathname;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
// Not in Next.js context, will use fallback
|
|
18
|
+
}
|
|
5
19
|
/**
|
|
6
20
|
* LayoutPreview Component
|
|
7
21
|
*
|
|
8
|
-
* Renders a layout component with embedded preview data.
|
|
22
|
+
* Renders a layout component with embedded preview data and client-side routing.
|
|
23
|
+
* Uses Shadow DOM for complete style/DOM isolation and handles routing via URL query params.
|
|
9
24
|
* This component is used to preview layouts in standalone applications
|
|
10
25
|
* and demonstrates that layouts are self-sustaining with embedded data.
|
|
11
26
|
*/
|
|
12
|
-
|
|
27
|
+
// Inner component that uses Next.js router if available
|
|
28
|
+
function LayoutPreviewWithRouter({ layout, className, initialRoute, onRouteChange }) {
|
|
29
|
+
const [currentRoute, setCurrentRoute] = useState(initialRoute || '/');
|
|
30
|
+
const [isClient, setIsClient] = useState(false);
|
|
31
|
+
// Use Next.js router hooks if available (must be called unconditionally if defined)
|
|
32
|
+
const router = useRouter ? useRouter() : undefined;
|
|
33
|
+
const pathname = usePathname ? usePathname() : undefined;
|
|
13
34
|
// Get preview data for the specified layout
|
|
14
35
|
const previewData = getPreviewDataByLayout(layout);
|
|
36
|
+
// Helper function to normalize and decode route from URL
|
|
37
|
+
const getRouteFromUrl = useCallback(() => {
|
|
38
|
+
if (typeof window === 'undefined')
|
|
39
|
+
return '/';
|
|
40
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
41
|
+
const routeFromUrl = urlParams.get('route');
|
|
42
|
+
if (routeFromUrl) {
|
|
43
|
+
try {
|
|
44
|
+
// Decode the route parameter (handles %2Fcontact -> /contact)
|
|
45
|
+
const decoded = decodeURIComponent(routeFromUrl);
|
|
46
|
+
// Normalize route (ensure it starts with /)
|
|
47
|
+
return decoded.startsWith('/') ? decoded : `/${decoded}`;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
// If decoding fails, use the raw value
|
|
51
|
+
return routeFromUrl.startsWith('/') ? routeFromUrl : `/${routeFromUrl}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return '/';
|
|
55
|
+
}, []);
|
|
56
|
+
// Initialize client-side and read route from URL
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
setIsClient(true);
|
|
59
|
+
// Read route from URL query param (prioritize URL over initialRoute prop)
|
|
60
|
+
if (typeof window !== 'undefined') {
|
|
61
|
+
const routeFromUrl = getRouteFromUrl();
|
|
62
|
+
// If URL has a route, use it (it's the source of truth)
|
|
63
|
+
if (routeFromUrl && routeFromUrl !== '/') {
|
|
64
|
+
setCurrentRoute(routeFromUrl);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Fallback to initialRoute prop if URL doesn't have a route
|
|
69
|
+
if (initialRoute) {
|
|
70
|
+
// Normalize initialRoute (Next.js searchParams already decodes it)
|
|
71
|
+
const normalized = initialRoute.startsWith('/') ? initialRoute : `/${initialRoute}`;
|
|
72
|
+
setCurrentRoute(normalized);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
setCurrentRoute('/');
|
|
76
|
+
}
|
|
77
|
+
}, [initialRoute, getRouteFromUrl]);
|
|
78
|
+
// Listen for URL changes (for browser back/forward and programmatic navigation)
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (typeof window === 'undefined' || !isClient)
|
|
81
|
+
return;
|
|
82
|
+
const handlePopState = () => {
|
|
83
|
+
const route = getRouteFromUrl();
|
|
84
|
+
setCurrentRoute(route);
|
|
85
|
+
onRouteChange?.(route);
|
|
86
|
+
};
|
|
87
|
+
window.addEventListener('popstate', handlePopState);
|
|
88
|
+
return () => window.removeEventListener('popstate', handlePopState);
|
|
89
|
+
}, [isClient, onRouteChange, getRouteFromUrl]);
|
|
90
|
+
// Watch for URL query parameter changes (for direct navigation or redirects)
|
|
91
|
+
// This effect syncs the component state with the URL when it changes externally
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (typeof window === 'undefined' || !isClient)
|
|
94
|
+
return;
|
|
95
|
+
// Check URL on window focus to catch external changes (browser back/forward, direct URL navigation)
|
|
96
|
+
const checkUrlChange = () => {
|
|
97
|
+
const route = getRouteFromUrl();
|
|
98
|
+
setCurrentRoute((prevRoute) => {
|
|
99
|
+
if (route !== prevRoute) {
|
|
100
|
+
onRouteChange?.(route);
|
|
101
|
+
return route;
|
|
102
|
+
}
|
|
103
|
+
return prevRoute;
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
// Check on window focus (handles browser back/forward and direct URL changes)
|
|
107
|
+
window.addEventListener('focus', checkUrlChange);
|
|
108
|
+
// Also listen for hashchange (in case routing uses hash)
|
|
109
|
+
window.addEventListener('hashchange', checkUrlChange);
|
|
110
|
+
return () => {
|
|
111
|
+
window.removeEventListener('focus', checkUrlChange);
|
|
112
|
+
window.removeEventListener('hashchange', checkUrlChange);
|
|
113
|
+
};
|
|
114
|
+
}, [isClient, onRouteChange, getRouteFromUrl]);
|
|
115
|
+
// Link click handler - passed to ShadowDOMWrapper to handle clicks inside Shadow DOM
|
|
116
|
+
const handleLinkClick = useCallback((route) => {
|
|
117
|
+
// Normalize route (ensure it starts with /)
|
|
118
|
+
const normalizedRoute = route.startsWith('/') ? route : `/${route}`;
|
|
119
|
+
// Update URL with query param
|
|
120
|
+
if (typeof window !== 'undefined') {
|
|
121
|
+
// Use Next.js router if available for proper page re-renders
|
|
122
|
+
if (router && pathname) {
|
|
123
|
+
try {
|
|
124
|
+
// Build the new URL with route query param
|
|
125
|
+
const newUrl = new URL(window.location.href);
|
|
126
|
+
newUrl.searchParams.set('route', normalizedRoute);
|
|
127
|
+
// Use Next.js router to navigate (triggers page re-render)
|
|
128
|
+
// This ensures the Next.js page component re-renders with new searchParams
|
|
129
|
+
router.push(newUrl.pathname + newUrl.search);
|
|
130
|
+
// Update state immediately for instant UI update
|
|
131
|
+
setCurrentRoute(normalizedRoute);
|
|
132
|
+
onRouteChange?.(normalizedRoute);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
console.warn('[LayoutPreview] Failed to use Next.js router, falling back to pushState:', e);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Fallback to pushState if Next.js router not available
|
|
140
|
+
const newUrl = new URL(window.location.href);
|
|
141
|
+
// Encode the route for URL (handles /contact -> %2Fcontact)
|
|
142
|
+
newUrl.searchParams.set('route', normalizedRoute);
|
|
143
|
+
window.history.pushState({ route: normalizedRoute }, '', newUrl.toString());
|
|
144
|
+
setCurrentRoute(normalizedRoute);
|
|
145
|
+
onRouteChange?.(normalizedRoute);
|
|
146
|
+
}
|
|
147
|
+
}, [onRouteChange, router, pathname]);
|
|
15
148
|
if (!previewData) {
|
|
16
149
|
return (_jsx("div", { className: `flex items-center justify-center p-8 ${className || ''}`, children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-semibold text-gray-600", children: "Layout not found" }), _jsxs("p", { className: "text-sm text-gray-500 mt-2", children: ["Layout type: ", layout] })] }) }));
|
|
17
150
|
}
|
|
@@ -21,30 +154,17 @@ export function LayoutPreview({ layout, className }) {
|
|
|
21
154
|
'--store-secondary': previewData.branding.secondaryColor || previewData.branding.primaryColor,
|
|
22
155
|
'--store-accent': previewData.branding.accentColor || previewData.branding.primaryColor,
|
|
23
156
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
case 'booking-agenda':
|
|
38
|
-
return _jsx(BookingHomePageAgenda, { storeConfig: previewData });
|
|
39
|
-
case 'electronics':
|
|
40
|
-
return _jsx(ElectronicsHomePage, { storeConfig: previewData });
|
|
41
|
-
case 'electronics-grid':
|
|
42
|
-
return _jsx(ElectronicsHomePageGrid, { storeConfig: previewData });
|
|
43
|
-
case 'motivational-speaker':
|
|
44
|
-
return _jsx(MotivationalHomePage, { storeConfig: previewData });
|
|
45
|
-
default:
|
|
46
|
-
return (_jsx("div", { className: `flex items-center justify-center p-8 ${className || ''}`, children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-semibold text-gray-600", children: "Unsupported layout" }), _jsxs("p", { className: "text-sm text-gray-500 mt-2", children: ["Layout type: ", layout] })] }) }));
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
return (_jsx("div", { style: style, className: `min-h-screen w-full ${className || ''}`, children: _jsx(ToastProvider, { children: _jsx(StoreProvider, { initialConfig: previewData, storeSlug: previewData.slug, children: _jsx(LoadingProvider, { children: _jsx(AuthProvider, { children: renderLayout() }) }) }) }) }));
|
|
157
|
+
if (!isClient) {
|
|
158
|
+
return (_jsx("div", { className: `flex items-center justify-center p-8 ${className || ''}`, children: _jsx("div", { className: "text-center", children: _jsx("p", { className: "text-sm text-gray-500", children: "Loading preview..." }) }) }));
|
|
159
|
+
}
|
|
160
|
+
return (_jsx("div", { style: style, className: `min-h-screen w-full ${className || ''}`, children: _jsx(ShadowDOMWrapper, { onLinkClick: handleLinkClick, storeSlug: previewData.slug, children: _jsx(ToastProvider, { children: _jsx(StoreProvider, { initialConfig: previewData, storeSlug: previewData.slug, children: _jsx(LoadingProvider, { children: _jsx(AuthProvider, { children: _jsx(PreviewRouter, { storeConfig: previewData, route: currentRoute.startsWith('/') ? currentRoute : `/${currentRoute}`, onNavigate: (route) => {
|
|
161
|
+
const normalized = route.startsWith('/') ? route : `/${route}`;
|
|
162
|
+
setCurrentRoute(normalized);
|
|
163
|
+
onRouteChange?.(normalized);
|
|
164
|
+
} }) }) }) }) }) }) }));
|
|
165
|
+
}
|
|
166
|
+
// Main component - always uses the same implementation
|
|
167
|
+
// Router hooks are called conditionally inside, but component structure is consistent
|
|
168
|
+
export function LayoutPreview(props) {
|
|
169
|
+
return _jsx(LayoutPreviewWithRouter, { ...props });
|
|
50
170
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StoreConfig } from '../lib/store-types';
|
|
2
|
+
interface PreviewRouterProps {
|
|
3
|
+
storeConfig: StoreConfig;
|
|
4
|
+
route: string;
|
|
5
|
+
onNavigate?: (route: string) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* PreviewRouter Component
|
|
9
|
+
*
|
|
10
|
+
* Handles client-side routing for layout previews.
|
|
11
|
+
* Renders the appropriate page component based on the current route.
|
|
12
|
+
*/
|
|
13
|
+
export declare function PreviewRouter({ storeConfig, route, onNavigate }: PreviewRouterProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=PreviewRouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreviewRouter.d.ts","sourceRoot":"","sources":["../../src/preview/PreviewRouter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAsGhD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAkHD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,kBAAkB,2CAsgBnF"}
|
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
// Shared components
|
|
5
|
+
CartPage, WishlistPage, CheckoutPage, AccountPage, TeamPage, PortfolioPage, HelpCenterPage, ShippingReturnsPage, TrackOrderPage, TermsPage, PrivacyPolicyPage, CookiePolicyPage, SizeGuidePage, GenericPageWrapper,
|
|
6
|
+
// Electronics components
|
|
7
|
+
ElectronicsCategoriesPage, ElectronicsPageWrapper,
|
|
8
|
+
// Motivational speaker components
|
|
9
|
+
ServiceDetailPage, SubscriptionPage, MotivationalPageWrapper,
|
|
10
|
+
// Food layout
|
|
11
|
+
FoodProductsPage, FoodProductDetailPage, FoodCategoryPage, FoodCategoriesPage, MenuPage as FoodMenuPage, FoodAboutPage, FoodContactPage,
|
|
12
|
+
// Food-modern layout
|
|
13
|
+
FoodModernProductsPage, FoodModernProductDetailPage, FoodModernCategoryPage, FoodModernCategoriesPage, FoodModernMenuPage, FoodModernAboutPage, FoodModernContactPage,
|
|
14
|
+
// Clothing layout
|
|
15
|
+
ClothingProductsPage, ClothingProductDetailPage, ClothingCategoryPage, ClothingCategoriesPage, ClothingAboutPage, ClothingContactPage,
|
|
16
|
+
// Clothing-minimal layout
|
|
17
|
+
ClothingMinimalProductsPage, ClothingMinimalProductDetailPage, ClothingMinimalCategoryPage, ClothingMinimalCategoriesPage, ClothingMinimalAboutPage, ClothingMinimalContactPage,
|
|
18
|
+
// Booking layout
|
|
19
|
+
BookingBookPage, BookingServicesPage, BookingProductDetailPage, BookingCategoryPage, BookingCategoriesPage, BookingAboutPage, BookingContactPage,
|
|
20
|
+
// Booking-agenda layout
|
|
21
|
+
BookingAgendaBookPage, BookingAgendaServicesPage, BookingAgendaProductDetailPage, BookingAgendaCategoryPage, BookingAgendaCategoriesPage, BookingAgendaAboutPage, BookingAgendaContactPage, ElectronicsProductsPagePage as ElectronicsProductsPageGeneric, ElectronicsProductDetailPage, ElectronicsCategoryPage, ElectronicsCategoriesPagePage as ElectronicsCategoriesPageGeneric, ElectronicsAboutPage, ElectronicsContactPage,
|
|
22
|
+
// Electronics-grid layout
|
|
23
|
+
ElectronicsGridProductDetailPage, ElectronicsGridCategoryPage, ElectronicsGridCategoriesPagePage as ElectronicsGridCategoriesPage, ElectronicsGridAboutPage, ElectronicsGridContactPage,
|
|
24
|
+
// Motivational-speaker layout
|
|
25
|
+
MotivationalProductsPage, MotivationalCategoryPage, MotivationalServicesPage, MotivationalAboutPage, MotivationalContactPage,
|
|
26
|
+
// Home pages
|
|
27
|
+
FoodHomePage, FoodHomePageModern, ClothingHomePage, ClothingHomePageMinimal, BookingHomePage, BookingHomePageAgenda, ElectronicsHomePage, ElectronicsHomePageGrid, MotivationalHomePage, } from '../index';
|
|
28
|
+
// Helper function to get layout-specific page components
|
|
29
|
+
function getLayoutPages(storeConfig) {
|
|
30
|
+
const layout = storeConfig.layout;
|
|
31
|
+
switch (layout) {
|
|
32
|
+
case 'food':
|
|
33
|
+
return {
|
|
34
|
+
HomePage: FoodHomePage,
|
|
35
|
+
ProductsPage: FoodProductsPage,
|
|
36
|
+
ProductDetailPage: FoodProductDetailPage,
|
|
37
|
+
CategoryPage: FoodCategoryPage,
|
|
38
|
+
CategoriesPage: FoodCategoriesPage,
|
|
39
|
+
MenuPage: FoodMenuPage,
|
|
40
|
+
AboutPage: FoodAboutPage,
|
|
41
|
+
ContactPage: FoodContactPage,
|
|
42
|
+
};
|
|
43
|
+
case 'food-modern':
|
|
44
|
+
return {
|
|
45
|
+
HomePage: FoodHomePageModern,
|
|
46
|
+
ProductsPage: FoodModernProductsPage,
|
|
47
|
+
ProductDetailPage: FoodModernProductDetailPage,
|
|
48
|
+
CategoryPage: FoodModernCategoryPage,
|
|
49
|
+
CategoriesPage: FoodModernCategoriesPage,
|
|
50
|
+
MenuPage: FoodModernMenuPage,
|
|
51
|
+
AboutPage: FoodModernAboutPage,
|
|
52
|
+
ContactPage: FoodModernContactPage,
|
|
53
|
+
};
|
|
54
|
+
case 'clothing':
|
|
55
|
+
return {
|
|
56
|
+
HomePage: ClothingHomePage,
|
|
57
|
+
ProductsPage: ClothingProductsPage,
|
|
58
|
+
ProductDetailPage: ClothingProductDetailPage,
|
|
59
|
+
CategoryPage: ClothingCategoryPage,
|
|
60
|
+
CategoriesPage: ClothingCategoriesPage,
|
|
61
|
+
AboutPage: ClothingAboutPage,
|
|
62
|
+
ContactPage: ClothingContactPage,
|
|
63
|
+
};
|
|
64
|
+
case 'clothing-minimal':
|
|
65
|
+
return {
|
|
66
|
+
HomePage: ClothingHomePageMinimal,
|
|
67
|
+
ProductsPage: ClothingMinimalProductsPage,
|
|
68
|
+
ProductDetailPage: ClothingMinimalProductDetailPage,
|
|
69
|
+
CategoryPage: ClothingMinimalCategoryPage,
|
|
70
|
+
CategoriesPage: ClothingMinimalCategoriesPage,
|
|
71
|
+
AboutPage: ClothingMinimalAboutPage,
|
|
72
|
+
ContactPage: ClothingMinimalContactPage,
|
|
73
|
+
};
|
|
74
|
+
case 'booking':
|
|
75
|
+
return {
|
|
76
|
+
HomePage: BookingHomePage,
|
|
77
|
+
BookPage: BookingBookPage,
|
|
78
|
+
ServicesPage: BookingServicesPage,
|
|
79
|
+
ProductDetailPage: BookingProductDetailPage,
|
|
80
|
+
CategoryPage: BookingCategoryPage,
|
|
81
|
+
CategoriesPage: BookingCategoriesPage,
|
|
82
|
+
AboutPage: BookingAboutPage,
|
|
83
|
+
ContactPage: BookingContactPage,
|
|
84
|
+
};
|
|
85
|
+
case 'booking-agenda':
|
|
86
|
+
return {
|
|
87
|
+
HomePage: BookingHomePageAgenda,
|
|
88
|
+
BookPage: BookingAgendaBookPage,
|
|
89
|
+
ServicesPage: BookingAgendaServicesPage,
|
|
90
|
+
ProductDetailPage: BookingAgendaProductDetailPage,
|
|
91
|
+
CategoryPage: BookingAgendaCategoryPage,
|
|
92
|
+
CategoriesPage: BookingAgendaCategoriesPage,
|
|
93
|
+
AboutPage: BookingAgendaAboutPage,
|
|
94
|
+
ContactPage: BookingAgendaContactPage,
|
|
95
|
+
};
|
|
96
|
+
case 'electronics':
|
|
97
|
+
return {
|
|
98
|
+
HomePage: ElectronicsHomePage,
|
|
99
|
+
ProductsPage: ElectronicsProductsPageGeneric,
|
|
100
|
+
ProductDetailPage: ElectronicsProductDetailPage,
|
|
101
|
+
CategoryPage: ElectronicsCategoryPage,
|
|
102
|
+
CategoriesPage: ElectronicsCategoriesPageGeneric,
|
|
103
|
+
AboutPage: ElectronicsAboutPage,
|
|
104
|
+
ContactPage: ElectronicsContactPage,
|
|
105
|
+
};
|
|
106
|
+
case 'electronics-grid':
|
|
107
|
+
return {
|
|
108
|
+
HomePage: ElectronicsHomePageGrid,
|
|
109
|
+
ProductDetailPage: ElectronicsGridProductDetailPage,
|
|
110
|
+
CategoryPage: ElectronicsGridCategoryPage,
|
|
111
|
+
CategoriesPage: ElectronicsGridCategoriesPage,
|
|
112
|
+
AboutPage: ElectronicsGridAboutPage,
|
|
113
|
+
ContactPage: ElectronicsGridContactPage,
|
|
114
|
+
};
|
|
115
|
+
case 'motivational-speaker':
|
|
116
|
+
return {
|
|
117
|
+
HomePage: MotivationalHomePage,
|
|
118
|
+
ProductsPage: MotivationalProductsPage,
|
|
119
|
+
CategoryPage: MotivationalCategoryPage,
|
|
120
|
+
ServicesPage: MotivationalServicesPage,
|
|
121
|
+
AboutPage: MotivationalAboutPage,
|
|
122
|
+
ContactPage: MotivationalContactPage,
|
|
123
|
+
};
|
|
124
|
+
default:
|
|
125
|
+
// Fallback to food layout
|
|
126
|
+
return {
|
|
127
|
+
HomePage: FoodHomePage,
|
|
128
|
+
ProductsPage: FoodProductsPage,
|
|
129
|
+
ProductDetailPage: FoodProductDetailPage,
|
|
130
|
+
CategoryPage: FoodCategoryPage,
|
|
131
|
+
CategoriesPage: FoodCategoriesPage,
|
|
132
|
+
MenuPage: FoodMenuPage,
|
|
133
|
+
AboutPage: FoodAboutPage,
|
|
134
|
+
ContactPage: FoodContactPage,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* PreviewRouter Component
|
|
140
|
+
*
|
|
141
|
+
* Handles client-side routing for layout previews.
|
|
142
|
+
* Renders the appropriate page component based on the current route.
|
|
143
|
+
*/
|
|
144
|
+
export function PreviewRouter({ storeConfig, route, onNavigate }) {
|
|
145
|
+
const path = route.startsWith('/') ? route : `/${route}`;
|
|
146
|
+
const pathSegments = path.split('/').filter(Boolean);
|
|
147
|
+
const [firstSegment, secondSegment, thirdSegment] = pathSegments;
|
|
148
|
+
const isElectronics = storeConfig.layout === 'electronics' || storeConfig.layout === 'electronics-grid';
|
|
149
|
+
const isMotivational = storeConfig.layout === 'motivational-speaker';
|
|
150
|
+
const isBooking = storeConfig.layout === 'booking' || storeConfig.layout === 'booking-agenda';
|
|
151
|
+
const layoutPages = getLayoutPages(storeConfig);
|
|
152
|
+
// Homepage route
|
|
153
|
+
if (!firstSegment || path === '/') {
|
|
154
|
+
const HomePage = layoutPages.HomePage;
|
|
155
|
+
if (HomePage) {
|
|
156
|
+
return _jsx(HomePage, { storeConfig: storeConfig });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Route: /account/certificates/[id]
|
|
160
|
+
if (firstSegment === 'account' && secondSegment === 'certificates' && thirdSegment && isMotivational) {
|
|
161
|
+
// For now, return a placeholder - CertificateViewer would need to be passed as prop
|
|
162
|
+
return (_jsx("div", { className: "min-h-screen flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-semibold", children: "Certificate Viewer" }), _jsxs("p", { className: "text-sm text-gray-500", children: ["Certificate ID: ", thirdSegment] })] }) }));
|
|
163
|
+
}
|
|
164
|
+
// Route: /products
|
|
165
|
+
if (firstSegment === 'products' && !secondSegment) {
|
|
166
|
+
if (isElectronics) {
|
|
167
|
+
// Use ElectronicsProductsPageGeneric for electronics layouts
|
|
168
|
+
return _jsx(ElectronicsProductsPageGeneric, { storeConfig: storeConfig });
|
|
169
|
+
}
|
|
170
|
+
const ProductsPage = layoutPages.ProductsPage;
|
|
171
|
+
if (ProductsPage) {
|
|
172
|
+
return _jsx(ProductsPage, { storeConfig: storeConfig });
|
|
173
|
+
}
|
|
174
|
+
return _jsx("div", { children: "Products page not available" });
|
|
175
|
+
}
|
|
176
|
+
// Route: /products/[id]
|
|
177
|
+
if (firstSegment === 'products' && secondSegment) {
|
|
178
|
+
if (isElectronics) {
|
|
179
|
+
const ProductDetail = layoutPages.ProductDetailPage;
|
|
180
|
+
if (ProductDetail) {
|
|
181
|
+
return _jsx(ProductDetail, { storeConfig: storeConfig, productSlug: secondSegment });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const ProductDetail = layoutPages.ProductDetailPage;
|
|
185
|
+
if (ProductDetail) {
|
|
186
|
+
return _jsx(ProductDetail, { storeConfig: storeConfig, productSlug: secondSegment });
|
|
187
|
+
}
|
|
188
|
+
return _jsx("div", { children: "Product not found" });
|
|
189
|
+
}
|
|
190
|
+
// Route: /categories
|
|
191
|
+
if (firstSegment === 'categories' && !secondSegment) {
|
|
192
|
+
if (isElectronics) {
|
|
193
|
+
return _jsx(ElectronicsCategoriesPage, { storeConfig: storeConfig });
|
|
194
|
+
}
|
|
195
|
+
const CategoriesPage = layoutPages.CategoriesPage;
|
|
196
|
+
if (CategoriesPage) {
|
|
197
|
+
return _jsx(CategoriesPage, { storeConfig: storeConfig });
|
|
198
|
+
}
|
|
199
|
+
return _jsx("div", { children: "Categories page not available" });
|
|
200
|
+
}
|
|
201
|
+
// Route: /categories/[slug]
|
|
202
|
+
if (firstSegment === 'categories' && secondSegment) {
|
|
203
|
+
if (isElectronics) {
|
|
204
|
+
const CategoryPage = layoutPages.CategoryPage;
|
|
205
|
+
if (CategoryPage) {
|
|
206
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(CategoryPage, { storeConfig: storeConfig, categorySlug: secondSegment }) }));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const CategoryPage = layoutPages.CategoryPage;
|
|
210
|
+
if (CategoryPage) {
|
|
211
|
+
return _jsx(CategoryPage, { storeConfig: storeConfig, categorySlug: secondSegment });
|
|
212
|
+
}
|
|
213
|
+
return _jsx("div", { children: "Category not found" });
|
|
214
|
+
}
|
|
215
|
+
// Route: /menu (for food stores)
|
|
216
|
+
if (firstSegment === 'menu') {
|
|
217
|
+
const MenuPage = layoutPages.MenuPage;
|
|
218
|
+
if (MenuPage) {
|
|
219
|
+
return _jsx(MenuPage, { storeConfig: storeConfig, categorySlug: secondSegment });
|
|
220
|
+
}
|
|
221
|
+
return _jsx("div", { children: "Menu page not available" });
|
|
222
|
+
}
|
|
223
|
+
// Route: /cart
|
|
224
|
+
if (firstSegment === 'cart') {
|
|
225
|
+
if (isElectronics) {
|
|
226
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(CartPage, { storeConfig: storeConfig }) }));
|
|
227
|
+
}
|
|
228
|
+
if (isMotivational) {
|
|
229
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(CartPage, { storeConfig: storeConfig }) }));
|
|
230
|
+
}
|
|
231
|
+
return _jsx(CartPage, { storeConfig: storeConfig });
|
|
232
|
+
}
|
|
233
|
+
// Route: /wishlist
|
|
234
|
+
if (firstSegment === 'wishlist') {
|
|
235
|
+
if (isElectronics) {
|
|
236
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(WishlistPage, { storeConfig: storeConfig }) }));
|
|
237
|
+
}
|
|
238
|
+
if (isMotivational) {
|
|
239
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(WishlistPage, { storeConfig: storeConfig }) }));
|
|
240
|
+
}
|
|
241
|
+
return _jsx(WishlistPage, { storeConfig: storeConfig });
|
|
242
|
+
}
|
|
243
|
+
// Route: /checkout
|
|
244
|
+
if (firstSegment === 'checkout') {
|
|
245
|
+
if (isElectronics) {
|
|
246
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(CheckoutPage, { storeConfig: storeConfig }) }));
|
|
247
|
+
}
|
|
248
|
+
if (isMotivational) {
|
|
249
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(CheckoutPage, { storeConfig: storeConfig }) }));
|
|
250
|
+
}
|
|
251
|
+
return _jsx(CheckoutPage, { storeConfig: storeConfig });
|
|
252
|
+
}
|
|
253
|
+
// Route: /book (for booking stores)
|
|
254
|
+
if (firstSegment === 'book') {
|
|
255
|
+
const BookPage = layoutPages.BookPage;
|
|
256
|
+
if (BookPage) {
|
|
257
|
+
return _jsx(BookPage, { storeConfig: storeConfig, serviceSlug: secondSegment });
|
|
258
|
+
}
|
|
259
|
+
return _jsx("div", { children: "Book page not available" });
|
|
260
|
+
}
|
|
261
|
+
// Route: /services
|
|
262
|
+
if (firstSegment === 'services') {
|
|
263
|
+
if (storeConfig.pageFeatures?.servicesPage !== false) {
|
|
264
|
+
// For motivational speaker layout, use ServiceDetailPage if slug provided
|
|
265
|
+
if (isMotivational && secondSegment) {
|
|
266
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(ServiceDetailPage, { storeConfig: storeConfig, serviceSlug: secondSegment }) }));
|
|
267
|
+
}
|
|
268
|
+
// Otherwise use ServicesPage (list view)
|
|
269
|
+
const ServicesPage = layoutPages.ServicesPage;
|
|
270
|
+
if (ServicesPage) {
|
|
271
|
+
return _jsx(ServicesPage, { storeConfig: storeConfig });
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return _jsx("div", { children: "Services page not available" });
|
|
275
|
+
}
|
|
276
|
+
// Route: /mentorship (for motivational speaker layout)
|
|
277
|
+
if (firstSegment === 'mentorship' && isMotivational) {
|
|
278
|
+
const ServicesPage = layoutPages.ServicesPage;
|
|
279
|
+
if (ServicesPage) {
|
|
280
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(ServicesPage, { storeConfig: storeConfig, initialCategory: "mentorship", titleOverride: "Premium Mentorship" }) }));
|
|
281
|
+
}
|
|
282
|
+
return _jsx("div", { children: "Mentorship page not available" });
|
|
283
|
+
}
|
|
284
|
+
// Route: /course/[slug] - Alternative route for services (backward compatibility)
|
|
285
|
+
if (firstSegment === 'course' && secondSegment && isMotivational) {
|
|
286
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(ServiceDetailPage, { storeConfig: storeConfig, serviceSlug: secondSegment }) }));
|
|
287
|
+
}
|
|
288
|
+
// Route: /subscription - Subscription page for motivational speaker
|
|
289
|
+
if (firstSegment === 'subscription' && isMotivational) {
|
|
290
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(SubscriptionPage, { storeConfig: storeConfig }) }));
|
|
291
|
+
}
|
|
292
|
+
// Route: /team
|
|
293
|
+
if (firstSegment === 'team') {
|
|
294
|
+
if (storeConfig.pageFeatures?.teamPage === true) {
|
|
295
|
+
if (isElectronics) {
|
|
296
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(TeamPage, { storeConfig: storeConfig }) }));
|
|
297
|
+
}
|
|
298
|
+
if (isMotivational) {
|
|
299
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(TeamPage, { storeConfig: storeConfig }) }));
|
|
300
|
+
}
|
|
301
|
+
return _jsx(TeamPage, { storeConfig: storeConfig });
|
|
302
|
+
}
|
|
303
|
+
return _jsx("div", { children: "Team page not available" });
|
|
304
|
+
}
|
|
305
|
+
// Route: /portfolio
|
|
306
|
+
if (firstSegment === 'portfolio') {
|
|
307
|
+
if (storeConfig.pageFeatures?.portfolioPage === true) {
|
|
308
|
+
if (isElectronics) {
|
|
309
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(PortfolioPage, { storeConfig: storeConfig }) }));
|
|
310
|
+
}
|
|
311
|
+
if (isMotivational) {
|
|
312
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(PortfolioPage, { storeConfig: storeConfig }) }));
|
|
313
|
+
}
|
|
314
|
+
return _jsx(PortfolioPage, { storeConfig: storeConfig });
|
|
315
|
+
}
|
|
316
|
+
return _jsx("div", { children: "Portfolio page not available" });
|
|
317
|
+
}
|
|
318
|
+
// Route: /help-center
|
|
319
|
+
if (firstSegment === 'help-center') {
|
|
320
|
+
if (storeConfig.pageFeatures?.helpCenterPage !== false) {
|
|
321
|
+
if (isElectronics) {
|
|
322
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(HelpCenterPage, { storeConfig: storeConfig }) }));
|
|
323
|
+
}
|
|
324
|
+
if (isMotivational) {
|
|
325
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(HelpCenterPage, { storeConfig: storeConfig }) }));
|
|
326
|
+
}
|
|
327
|
+
return _jsx(HelpCenterPage, { storeConfig: storeConfig });
|
|
328
|
+
}
|
|
329
|
+
return _jsx("div", { children: "Help center page not available" });
|
|
330
|
+
}
|
|
331
|
+
// Route: /shipping-returns
|
|
332
|
+
if (firstSegment === 'shipping-returns') {
|
|
333
|
+
if (storeConfig.pageFeatures?.shippingReturnsPage !== false) {
|
|
334
|
+
if (isElectronics) {
|
|
335
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(ShippingReturnsPage, { storeConfig: storeConfig }) }));
|
|
336
|
+
}
|
|
337
|
+
if (isMotivational) {
|
|
338
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(ShippingReturnsPage, { storeConfig: storeConfig }) }));
|
|
339
|
+
}
|
|
340
|
+
return _jsx(ShippingReturnsPage, { storeConfig: storeConfig });
|
|
341
|
+
}
|
|
342
|
+
return _jsx("div", { children: "Shipping & returns page not available" });
|
|
343
|
+
}
|
|
344
|
+
// Route: /track-order
|
|
345
|
+
if (firstSegment === 'track-order') {
|
|
346
|
+
if (storeConfig.pageFeatures?.trackOrderPage !== false) {
|
|
347
|
+
if (isElectronics) {
|
|
348
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(TrackOrderPage, { storeConfig: storeConfig }) }));
|
|
349
|
+
}
|
|
350
|
+
if (isMotivational) {
|
|
351
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(TrackOrderPage, { storeConfig: storeConfig }) }));
|
|
352
|
+
}
|
|
353
|
+
return _jsx(TrackOrderPage, { storeConfig: storeConfig });
|
|
354
|
+
}
|
|
355
|
+
return _jsx("div", { children: "Track order page not available" });
|
|
356
|
+
}
|
|
357
|
+
// Route: /about
|
|
358
|
+
if (firstSegment === 'about') {
|
|
359
|
+
if (storeConfig.pageFeatures?.aboutPage !== false) {
|
|
360
|
+
if (isElectronics) {
|
|
361
|
+
const AboutPage = layoutPages.AboutPage;
|
|
362
|
+
if (AboutPage) {
|
|
363
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(AboutPage, { storeConfig: storeConfig }) }));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (isMotivational) {
|
|
367
|
+
const AboutPage = layoutPages.AboutPage;
|
|
368
|
+
if (AboutPage) {
|
|
369
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(AboutPage, { storeConfig: storeConfig }) }));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const AboutPage = layoutPages.AboutPage;
|
|
373
|
+
if (AboutPage) {
|
|
374
|
+
return (_jsx(GenericPageWrapper, { storeConfig: storeConfig, children: _jsx(AboutPage, { storeConfig: storeConfig }) }));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return _jsx("div", { children: "About page not available" });
|
|
378
|
+
}
|
|
379
|
+
// Route: /contact
|
|
380
|
+
if (firstSegment === 'contact') {
|
|
381
|
+
if (storeConfig.pageFeatures?.contactPage !== false) {
|
|
382
|
+
if (isElectronics) {
|
|
383
|
+
const ContactPage = layoutPages.ContactPage;
|
|
384
|
+
if (ContactPage) {
|
|
385
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(ContactPage, { storeConfig: storeConfig }) }));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (isMotivational) {
|
|
389
|
+
const ContactPage = layoutPages.ContactPage;
|
|
390
|
+
if (ContactPage) {
|
|
391
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(ContactPage, { storeConfig: storeConfig }) }));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const ContactPage = layoutPages.ContactPage;
|
|
395
|
+
if (ContactPage) {
|
|
396
|
+
return (_jsx(GenericPageWrapper, { storeConfig: storeConfig, children: _jsx(ContactPage, { storeConfig: storeConfig }) }));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return _jsx("div", { children: "Contact page not available" });
|
|
400
|
+
}
|
|
401
|
+
// Route: /account
|
|
402
|
+
if (firstSegment === 'account') {
|
|
403
|
+
if (isElectronics) {
|
|
404
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(AccountPage, { storeConfig: storeConfig }) }));
|
|
405
|
+
}
|
|
406
|
+
if (isMotivational) {
|
|
407
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(AccountPage, { storeConfig: storeConfig }) }));
|
|
408
|
+
}
|
|
409
|
+
return _jsx(AccountPage, { storeConfig: storeConfig });
|
|
410
|
+
}
|
|
411
|
+
// Route: /terms
|
|
412
|
+
if (firstSegment === 'terms') {
|
|
413
|
+
if (isElectronics) {
|
|
414
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(TermsPage, { storeConfig: storeConfig }) }));
|
|
415
|
+
}
|
|
416
|
+
if (isMotivational) {
|
|
417
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(TermsPage, { storeConfig: storeConfig }) }));
|
|
418
|
+
}
|
|
419
|
+
return _jsx(TermsPage, { storeConfig: storeConfig });
|
|
420
|
+
}
|
|
421
|
+
// Route: /privacy
|
|
422
|
+
if (firstSegment === 'privacy') {
|
|
423
|
+
if (isElectronics) {
|
|
424
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(PrivacyPolicyPage, { storeConfig: storeConfig }) }));
|
|
425
|
+
}
|
|
426
|
+
if (isMotivational) {
|
|
427
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(PrivacyPolicyPage, { storeConfig: storeConfig }) }));
|
|
428
|
+
}
|
|
429
|
+
return _jsx(PrivacyPolicyPage, { storeConfig: storeConfig });
|
|
430
|
+
}
|
|
431
|
+
// Route: /cookie-policy
|
|
432
|
+
if (firstSegment === 'cookie-policy') {
|
|
433
|
+
if (isElectronics) {
|
|
434
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(CookiePolicyPage, { storeConfig: storeConfig }) }));
|
|
435
|
+
}
|
|
436
|
+
if (isMotivational) {
|
|
437
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(CookiePolicyPage, { storeConfig: storeConfig }) }));
|
|
438
|
+
}
|
|
439
|
+
return _jsx(CookiePolicyPage, { storeConfig: storeConfig });
|
|
440
|
+
}
|
|
441
|
+
// Route: /size-guide
|
|
442
|
+
if (firstSegment === 'size-guide') {
|
|
443
|
+
if (isElectronics) {
|
|
444
|
+
return (_jsx(ElectronicsPageWrapper, { storeConfig: storeConfig, children: _jsx(SizeGuidePage, { storeConfig: storeConfig }) }));
|
|
445
|
+
}
|
|
446
|
+
if (isMotivational) {
|
|
447
|
+
return (_jsx(MotivationalPageWrapper, { storeConfig: storeConfig, children: _jsx(SizeGuidePage, { storeConfig: storeConfig }) }));
|
|
448
|
+
}
|
|
449
|
+
return _jsx(SizeGuidePage, { storeConfig: storeConfig });
|
|
450
|
+
}
|
|
451
|
+
// Fallback for generic pages - show 404 for now
|
|
452
|
+
if (firstSegment) {
|
|
453
|
+
return (_jsx("div", { className: "min-h-screen flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-semibold text-gray-600", children: "Page not found" }), _jsxs("p", { className: "text-sm text-gray-500 mt-2", children: ["Route: ", route] })] }) }));
|
|
454
|
+
}
|
|
455
|
+
// Default: show homepage
|
|
456
|
+
const HomePage = layoutPages.HomePage;
|
|
457
|
+
if (HomePage) {
|
|
458
|
+
return _jsx(HomePage, { storeConfig: storeConfig });
|
|
459
|
+
}
|
|
460
|
+
return (_jsx("div", { className: "min-h-screen flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-semibold text-gray-600", children: "Page not found" }), _jsxs("p", { className: "text-sm text-gray-500 mt-2", children: ["Route: ", route] })] }) }));
|
|
461
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
interface ShadowDOMWrapperProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
onReady?: () => void;
|
|
6
|
+
onLinkClick?: (href: string) => void;
|
|
7
|
+
storeSlug?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* ShadowDOMWrapper Component
|
|
11
|
+
*
|
|
12
|
+
* Wraps children in a Shadow DOM for complete style and DOM isolation.
|
|
13
|
+
* This prevents layout styles from affecting the parent application.
|
|
14
|
+
*
|
|
15
|
+
* Note: Tailwind CSS classes will not work inside Shadow DOM by default.
|
|
16
|
+
* For full Tailwind support, styles need to be injected or components
|
|
17
|
+
* should use inline styles or CSS-in-JS solutions.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ShadowDOMWrapper({ children, className, onReady, onLinkClick, storeSlug }: ShadowDOMWrapperProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=ShadowDOMWrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShadowDOMWrapper.d.ts","sourceRoot":"","sources":["../../src/preview/ShadowDOMWrapper.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAqB,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrD,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CAyO/G"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
5
|
+
/**
|
|
6
|
+
* ShadowDOMWrapper Component
|
|
7
|
+
*
|
|
8
|
+
* Wraps children in a Shadow DOM for complete style and DOM isolation.
|
|
9
|
+
* This prevents layout styles from affecting the parent application.
|
|
10
|
+
*
|
|
11
|
+
* Note: Tailwind CSS classes will not work inside Shadow DOM by default.
|
|
12
|
+
* For full Tailwind support, styles need to be injected or components
|
|
13
|
+
* should use inline styles or CSS-in-JS solutions.
|
|
14
|
+
*/
|
|
15
|
+
export function ShadowDOMWrapper({ children, className, onReady, onLinkClick, storeSlug }) {
|
|
16
|
+
const shadowHostRef = useRef(null);
|
|
17
|
+
const shadowRootRef = useRef(null);
|
|
18
|
+
const reactRootRef = useRef(null);
|
|
19
|
+
const containerRef = useRef(null);
|
|
20
|
+
const childrenRef = useRef(children);
|
|
21
|
+
// Keep children ref updated
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
childrenRef.current = children;
|
|
24
|
+
}, [children]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!shadowHostRef.current)
|
|
27
|
+
return;
|
|
28
|
+
// Check if shadow root already exists
|
|
29
|
+
const existingShadowRoot = shadowHostRef.current.shadowRoot;
|
|
30
|
+
if (existingShadowRoot) {
|
|
31
|
+
shadowRootRef.current = existingShadowRoot;
|
|
32
|
+
// Update content if shadow root already exists
|
|
33
|
+
const container = existingShadowRoot.getElementById('shadow-preview-container');
|
|
34
|
+
if (container && reactRootRef.current) {
|
|
35
|
+
reactRootRef.current.render(childrenRef.current);
|
|
36
|
+
}
|
|
37
|
+
onReady?.();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
// Create shadow root
|
|
42
|
+
const shadowRoot = shadowHostRef.current.attachShadow({ mode: 'open' });
|
|
43
|
+
shadowRootRef.current = shadowRoot;
|
|
44
|
+
// Inject basic reset styles
|
|
45
|
+
const styleElement = document.createElement('style');
|
|
46
|
+
styleElement.textContent = `
|
|
47
|
+
* {
|
|
48
|
+
box-sizing: border-box;
|
|
49
|
+
margin: 0;
|
|
50
|
+
padding: 0;
|
|
51
|
+
}
|
|
52
|
+
#shadow-preview-container {
|
|
53
|
+
width: 100%;
|
|
54
|
+
min-height: 100%;
|
|
55
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
56
|
+
}
|
|
57
|
+
/* Allow Tailwind classes to work by importing styles */
|
|
58
|
+
/* Note: Full Tailwind support requires injecting compiled CSS */
|
|
59
|
+
`;
|
|
60
|
+
shadowRoot.appendChild(styleElement);
|
|
61
|
+
// Create container for React app
|
|
62
|
+
const container = document.createElement('div');
|
|
63
|
+
container.id = 'shadow-preview-container';
|
|
64
|
+
container.style.width = '100%';
|
|
65
|
+
container.style.minHeight = '100%';
|
|
66
|
+
shadowRoot.appendChild(container);
|
|
67
|
+
containerRef.current = container;
|
|
68
|
+
// Create React root and render children
|
|
69
|
+
const root = createRoot(container);
|
|
70
|
+
reactRootRef.current = root;
|
|
71
|
+
root.render(childrenRef.current);
|
|
72
|
+
// Set up link click interception inside Shadow DOM
|
|
73
|
+
if (onLinkClick) {
|
|
74
|
+
const handleClick = (e) => {
|
|
75
|
+
const target = e.target;
|
|
76
|
+
const link = target.closest('a[href]');
|
|
77
|
+
if (!link || !link.href)
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
const url = new URL(link.href, window.location.origin);
|
|
81
|
+
const pathname = url.pathname;
|
|
82
|
+
// Only intercept internal links
|
|
83
|
+
if (url.origin !== window.location.origin) {
|
|
84
|
+
return; // External link, allow default behavior
|
|
85
|
+
}
|
|
86
|
+
// Extract route from href (remove store slug prefix if present)
|
|
87
|
+
let route = pathname;
|
|
88
|
+
// Check if pathname starts with store slug (e.g., /modern-eats/contact)
|
|
89
|
+
if (storeSlug && pathname.startsWith(`/${storeSlug}`)) {
|
|
90
|
+
// Remove the store slug prefix: /modern-eats/contact -> /contact
|
|
91
|
+
route = pathname.slice(storeSlug.length + 1);
|
|
92
|
+
// If route is empty after removing slug, it's the homepage
|
|
93
|
+
if (!route || route === '') {
|
|
94
|
+
route = '/';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (pathname === '/' || pathname === '') {
|
|
98
|
+
// Homepage link
|
|
99
|
+
route = '/';
|
|
100
|
+
}
|
|
101
|
+
// Normalize route (ensure it starts with /)
|
|
102
|
+
if (route && !route.startsWith('/')) {
|
|
103
|
+
route = `/${route}`;
|
|
104
|
+
}
|
|
105
|
+
// Ensure route is not empty
|
|
106
|
+
if (!route) {
|
|
107
|
+
route = '/';
|
|
108
|
+
}
|
|
109
|
+
// Note: We don't preserve query string and hash here because
|
|
110
|
+
// the route is stored as a query param. Query strings and hash
|
|
111
|
+
// should be handled separately if needed.
|
|
112
|
+
// Prevent default navigation and call handler
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
e.stopPropagation();
|
|
115
|
+
onLinkClick(route);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
// If URL parsing fails, allow default behavior
|
|
119
|
+
console.warn('[ShadowDOMWrapper] Failed to parse link URL:', err, link.href);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
// Handler will be set up in separate useEffect to handle prop changes
|
|
123
|
+
}
|
|
124
|
+
onReady?.();
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
console.error('[ShadowDOMWrapper] Failed to create shadow root:', err);
|
|
128
|
+
}
|
|
129
|
+
return () => {
|
|
130
|
+
// Cleanup
|
|
131
|
+
if (reactRootRef.current) {
|
|
132
|
+
try {
|
|
133
|
+
reactRootRef.current.unmount();
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
console.warn('[ShadowDOMWrapper] Cleanup warning:', e);
|
|
137
|
+
}
|
|
138
|
+
reactRootRef.current = null;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}, [onReady]);
|
|
142
|
+
// Update content when children change
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
if (reactRootRef.current && containerRef.current) {
|
|
145
|
+
reactRootRef.current.render(childrenRef.current);
|
|
146
|
+
}
|
|
147
|
+
}, [children]);
|
|
148
|
+
// Set up link click handler when shadow root and props are ready
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const shadowRoot = shadowRootRef.current;
|
|
151
|
+
if (!shadowRoot || !onLinkClick)
|
|
152
|
+
return;
|
|
153
|
+
// Remove existing handler if any
|
|
154
|
+
const existingHandler = shadowRoot.__linkClickHandler;
|
|
155
|
+
if (existingHandler) {
|
|
156
|
+
shadowRoot.removeEventListener('click', existingHandler, true);
|
|
157
|
+
}
|
|
158
|
+
const handleClick = (e) => {
|
|
159
|
+
const target = e.target;
|
|
160
|
+
const link = target.closest('a[href]');
|
|
161
|
+
if (!link || !link.href)
|
|
162
|
+
return;
|
|
163
|
+
try {
|
|
164
|
+
const url = new URL(link.href, window.location.origin);
|
|
165
|
+
const pathname = url.pathname;
|
|
166
|
+
// Only intercept internal links
|
|
167
|
+
if (url.origin !== window.location.origin) {
|
|
168
|
+
return; // External link, allow default behavior
|
|
169
|
+
}
|
|
170
|
+
// Extract route from href (remove store slug prefix if present)
|
|
171
|
+
let route = pathname;
|
|
172
|
+
// Check if pathname starts with store slug (e.g., /modern-eats/contact)
|
|
173
|
+
if (storeSlug && pathname.startsWith(`/${storeSlug}`)) {
|
|
174
|
+
// Remove the store slug prefix: /modern-eats/contact -> /contact
|
|
175
|
+
route = pathname.slice(storeSlug.length + 1);
|
|
176
|
+
// If route is empty after removing slug, it's the homepage
|
|
177
|
+
if (!route || route === '') {
|
|
178
|
+
route = '/';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else if (pathname === '/' || pathname === '') {
|
|
182
|
+
// Homepage link
|
|
183
|
+
route = '/';
|
|
184
|
+
}
|
|
185
|
+
// Normalize route (ensure it starts with /)
|
|
186
|
+
if (route && !route.startsWith('/')) {
|
|
187
|
+
route = `/${route}`;
|
|
188
|
+
}
|
|
189
|
+
// Ensure route is not empty
|
|
190
|
+
if (!route) {
|
|
191
|
+
route = '/';
|
|
192
|
+
}
|
|
193
|
+
// Note: We don't preserve query string and hash here because
|
|
194
|
+
// the route is stored as a query param. Query strings and hash
|
|
195
|
+
// should be handled separately if needed.
|
|
196
|
+
// Prevent default navigation and call handler
|
|
197
|
+
e.preventDefault();
|
|
198
|
+
e.stopPropagation();
|
|
199
|
+
onLinkClick(route);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
console.warn('[ShadowDOMWrapper] Failed to parse link URL:', err, link.href);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
shadowRoot.addEventListener('click', handleClick, true);
|
|
206
|
+
shadowRoot.__linkClickHandler = handleClick;
|
|
207
|
+
return () => {
|
|
208
|
+
shadowRoot.removeEventListener('click', handleClick, true);
|
|
209
|
+
delete shadowRoot.__linkClickHandler;
|
|
210
|
+
};
|
|
211
|
+
}, [onLinkClick, storeSlug]);
|
|
212
|
+
return (_jsx("div", { ref: shadowHostRef, className: className, style: { width: '100%', minHeight: '100%' } }));
|
|
213
|
+
}
|
package/dist/preview/index.d.ts
CHANGED
|
@@ -6,5 +6,7 @@
|
|
|
6
6
|
* and can work independently with embedded preview data.
|
|
7
7
|
*/
|
|
8
8
|
export { LayoutPreview } from './LayoutPreview';
|
|
9
|
+
export { ShadowDOMWrapper } from './ShadowDOMWrapper';
|
|
10
|
+
export { PreviewRouter } from './PreviewRouter';
|
|
9
11
|
export * from '../lib/preview-data';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/preview/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/preview/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,cAAc,oBAAoB,CAAC"}
|
package/dist/preview/index.js
CHANGED