payaza-storefront-layouts 1.0.39 → 1.0.41

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.
Files changed (28) hide show
  1. package/dist/components/ui/alert-modal.d.ts +1 -0
  2. package/dist/components/ui/alert-modal.d.ts.map +1 -1
  3. package/dist/components/ui/alert-modal.js +1 -1
  4. package/dist/editor/payaza-form/PayazaFormEditor.d.ts.map +1 -1
  5. package/dist/editor/payaza-form/PayazaFormEditor.js +177 -17
  6. package/dist/editor/payaza-form/PayazaFormEditorFullPage.d.ts +3 -0
  7. package/dist/editor/payaza-form/PayazaFormEditorFullPage.d.ts.map +1 -1
  8. package/dist/editor/payaza-form/PayazaFormEditorFullPage.js +2 -1
  9. package/dist/editor/payaza-form/components/SectionField.js +1 -1
  10. package/dist/editor/payaza-form/data-merger.d.ts +6 -2
  11. package/dist/editor/payaza-form/data-merger.d.ts.map +1 -1
  12. package/dist/editor/payaza-form/data-merger.js +64 -51
  13. package/dist/editor/shared/AIGenerateModal.js +1 -1
  14. package/dist/editor/shared/EditorHeader.d.ts +7 -0
  15. package/dist/editor/shared/EditorHeader.d.ts.map +1 -1
  16. package/dist/editor/shared/EditorHeader.js +45 -9
  17. package/dist/editor/shared/IframePreview.d.ts.map +1 -1
  18. package/dist/editor/shared/IframePreview.js +5 -1
  19. package/dist/editor/types.d.ts +12 -0
  20. package/dist/editor/types.d.ts.map +1 -1
  21. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.d.ts.map +1 -1
  22. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.js +8 -3
  23. package/dist/layouts/shared/components/BaseStoreLayout.d.ts.map +1 -1
  24. package/dist/layouts/shared/components/BaseStoreLayout.js +3 -2
  25. package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -1
  26. package/dist/layouts/shared/components/StoreHeader.js +24 -7
  27. package/dist/styles/index.css +41 -29
  28. package/package.json +1 -1
@@ -12,6 +12,7 @@ interface AlertModalContextType {
12
12
  showAlert: (message: string, type?: AlertType, options?: AlertOptions) => void;
13
13
  hideAlert: () => void;
14
14
  }
15
+ export declare const AlertModalContext: React.Context<AlertModalContextType>;
15
16
  export declare function AlertModalProvider({ children }: {
16
17
  children: React.ReactNode;
17
18
  }): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"alert-modal.d.ts","sourceRoot":"","sources":["../../../src/components/ui/alert-modal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAYhF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AASD,UAAU,qBAAqB;IAC7B,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAID,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CA6C7E;AAED,wBAAgB,aAAa,0BAM5B"}
1
+ {"version":3,"file":"alert-modal.d.ts","sourceRoot":"","sources":["../../../src/components/ui/alert-modal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAYhF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AASD,UAAU,qBAAqB;IAC7B,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,eAAO,MAAM,iBAAiB,sCAA8D,CAAC;AAE7F,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CA6C7E;AAED,wBAAgB,aAAa,0BAM5B"}
@@ -4,7 +4,7 @@ import { createContext, useContext, useState, useCallback } from 'react';
4
4
  import { CheckCircle2, AlertCircle, Info, AlertTriangle } from 'lucide-react';
5
5
  import { cn } from '../../lib/utils';
6
6
  import { Button } from './button';
7
- const AlertModalContext = createContext(undefined);
7
+ export const AlertModalContext = createContext(undefined);
8
8
  export function AlertModalProvider({ children }) {
9
9
  const [alert, setAlert] = useState({
10
10
  isOpen: false,
@@ -1 +1 @@
1
- {"version":3,"file":"PayazaFormEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAU/C,OAAO,EAA4B,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAM5F,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+mB5D,CAAC"}
1
+ {"version":3,"file":"PayazaFormEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAU/C,OAAO,EAA4B,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAO5F,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA8xB5D,CAAC"}
@@ -13,10 +13,18 @@ import { mergeRequirementWithActualData, mergeAllPagesWithActualData } from './d
13
13
  import { Info, Search, X } from 'lucide-react';
14
14
  import { useDebounce } from '../../hooks/use-debounce';
15
15
  import { AIGenerateModal } from '../shared/AIGenerateModal';
16
- export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, onSave, onPublish, onBack, title, className = '', customWidgets, storeName, storeDescription, assets, }) => {
16
+ import { useAlertModal } from '../../components/ui/alert-modal';
17
+ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, onSave, onPublish, onBack, onBackToSettings, onOpenAssets, onBackToTheme, title, className = '', customWidgets, storeName, storeDescription, assets, }) => {
17
18
  const [activePageId, setActivePageId] = useState('home');
18
19
  const [data, setData] = useState(initialData);
19
20
  const dataRef = useRef(initialData);
21
+ // Undo/Redo State
22
+ const [history, setHistory] = useState([initialData]);
23
+ const [historyIndex, setHistoryIndex] = useState(0);
24
+ const isInternalChange = useRef(false);
25
+ const MAX_HISTORY = 50;
26
+ // Track last published data to disable publish button if no changes
27
+ const [lastPublishedData, setLastPublishedData] = useState(initialData);
20
28
  // Debounce the data for preview to prevent excessive iframe updates and RAM spikes
21
29
  const debouncedData = useDebounce(data, 400);
22
30
  const [viewMode, setViewMode] = useState('desktop');
@@ -29,10 +37,78 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
29
37
  const [loading, setLoading] = useState(true);
30
38
  const [searchQuery, setSearchQuery] = useState('');
31
39
  const [selectedSection, setSelectedSection] = useState(null);
40
+ const { showAlert } = useAlertModal();
32
41
  // Keep dataRef in sync with data state
33
42
  useEffect(() => {
34
43
  dataRef.current = data;
44
+ // Add to history if not an internal change (undo/redo)
45
+ if (!isInternalChange.current) {
46
+ setHistory(prev => {
47
+ const newHistory = prev.slice(0, historyIndex + 1);
48
+ // Only add if data is different from the last entry
49
+ if (JSON.stringify(newHistory[newHistory.length - 1]) !== JSON.stringify(data)) {
50
+ const updatedHistory = [...newHistory, data];
51
+ if (updatedHistory.length > MAX_HISTORY) {
52
+ return updatedHistory.slice(1);
53
+ }
54
+ return updatedHistory;
55
+ }
56
+ return prev;
57
+ });
58
+ setHistoryIndex(prev => {
59
+ const newIndex = Math.min(historyIndex + 1, MAX_HISTORY - 1);
60
+ // We need to re-calculate based on what setHistory actually does
61
+ return historyIndex + 1;
62
+ });
63
+ }
64
+ isInternalChange.current = false;
35
65
  }, [data]);
66
+ // Fix the history index after history update
67
+ useEffect(() => {
68
+ if (history.length > 0 && historyIndex >= history.length) {
69
+ setHistoryIndex(history.length - 1);
70
+ }
71
+ }, [history]);
72
+ const handleUndo = () => {
73
+ if (historyIndex > 0) {
74
+ isInternalChange.current = true;
75
+ const prevData = history[historyIndex - 1];
76
+ setHistoryIndex(historyIndex - 1);
77
+ setData(prevData);
78
+ onChange?.(prevData);
79
+ }
80
+ };
81
+ const handleRedo = () => {
82
+ if (historyIndex < history.length - 1) {
83
+ isInternalChange.current = true;
84
+ const nextData = history[historyIndex + 1];
85
+ setHistoryIndex(historyIndex + 1);
86
+ setData(nextData);
87
+ onChange?.(nextData);
88
+ }
89
+ };
90
+ // Keyboard Shortcuts
91
+ useEffect(() => {
92
+ const handleKeyDown = (e) => {
93
+ // Undo: Ctrl+Z or Cmd+Z
94
+ if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {
95
+ e.preventDefault();
96
+ handleUndo();
97
+ }
98
+ // Redo: Ctrl+Y or Cmd+Shift+Z
99
+ if (((e.ctrlKey || e.metaKey) && e.key === 'y') || ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'z')) {
100
+ e.preventDefault();
101
+ handleRedo();
102
+ }
103
+ // Save: Ctrl+S or Cmd+S
104
+ if ((e.ctrlKey || e.metaKey) && e.key === 's') {
105
+ e.preventDefault();
106
+ handleSave();
107
+ }
108
+ };
109
+ window.addEventListener('keydown', handleKeyDown);
110
+ return () => window.removeEventListener('keydown', handleKeyDown);
111
+ }, [historyIndex, history, data]); // Dependencies ensure latest state is used
36
112
  // Initialize custom widgets if provided
37
113
  useEffect(() => {
38
114
  if (customWidgets) {
@@ -233,11 +309,15 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
233
309
  setIsPublishing(true);
234
310
  try {
235
311
  await onPublish?.(data);
312
+ setLastPublishedData(data);
236
313
  }
237
314
  finally {
238
315
  setIsPublishing(false);
239
316
  }
240
317
  };
318
+ const hasChangesSincePublish = useMemo(() => {
319
+ return JSON.stringify(data) !== JSON.stringify(lastPublishedData);
320
+ }, [data, lastPublishedData]);
241
321
  const handleAIGenerate = async (context) => {
242
322
  if (!layoutJson)
243
323
  return;
@@ -245,17 +325,24 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
245
325
  // Use a local variable to track if this specific request should still update state
246
326
  let shouldUpdate = true;
247
327
  try {
248
- const response = await fetch('/api/ai/generate', {
249
- method: 'POST',
250
- headers: { 'Content-Type': 'application/json' },
251
- body: JSON.stringify({
252
- ...context,
253
- layoutId,
254
- alignmentSchema: layoutJson,
255
- existingData: data,
256
- assets: assets || context.assets
257
- })
258
- });
328
+ let response;
329
+ try {
330
+ response = await fetch('/api/ai/generate', {
331
+ method: 'POST',
332
+ headers: { 'Content-Type': 'application/json' },
333
+ body: JSON.stringify({
334
+ ...context,
335
+ layoutId,
336
+ alignmentSchema: layoutJson,
337
+ existingData: data,
338
+ assets: assets || context.assets
339
+ })
340
+ });
341
+ }
342
+ catch (fetchError) {
343
+ // Handle network errors, CORS errors, etc.
344
+ throw new Error(fetchError.message || 'Network request failed. Please check your connection and try again.');
345
+ }
259
346
  const contentType = response.headers.get('content-type');
260
347
  if (!contentType || !contentType.includes('application/json')) {
261
348
  const text = await response.text();
@@ -263,8 +350,16 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
263
350
  throw new Error('The server returned an invalid response. Please ensure the AI endpoint is correctly configured.');
264
351
  }
265
352
  if (!response.ok) {
266
- const error = await response.json();
267
- throw new Error(error.error || 'Failed to generate content');
353
+ let errorMessage = 'Failed to generate content';
354
+ try {
355
+ const error = await response.json();
356
+ errorMessage = error.error || error.message || errorMessage;
357
+ }
358
+ catch {
359
+ // If response is not JSON, use status text
360
+ errorMessage = response.statusText || `Server returned ${response.status} error`;
361
+ }
362
+ throw new Error(errorMessage);
268
363
  }
269
364
  const generatedData = await response.json();
270
365
  if (!shouldUpdate)
@@ -283,7 +378,8 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
283
378
  setLayoutJson(updatedLayout);
284
379
  // CRITICAL: Merge ALL pages from the updated AI layout into the StoreConfig
285
380
  // to ensure the StoreConfig is fully updated for all pages.
286
- const updatedStoreConfig = mergeAllPagesWithActualData(updatedLayout, data);
381
+ // We set actualDataPrecedence to false so AI data takes precedence.
382
+ const updatedStoreConfig = mergeAllPagesWithActualData(updatedLayout, data, { actualDataPrecedence: false });
287
383
  setData(updatedStoreConfig);
288
384
  onChange?.(updatedStoreConfig);
289
385
  // Optional: Add a small delay and a "polishing" step for specific layouts like food
@@ -300,7 +396,71 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
300
396
  catch (error) {
301
397
  if (shouldUpdate) {
302
398
  console.error('AI Generation Error:', error);
303
- alert(`AI Generation failed: ${error.message}`);
399
+ // Determine error type and message
400
+ let errorTitle = 'AI Generation Failed';
401
+ let errorMessage = 'We encountered an issue while generating content.';
402
+ let actionableMessage = 'Please try again. If the problem persists, you can continue editing manually.';
403
+ // Extract error message from various error types
404
+ let errorText = '';
405
+ if (error instanceof Error) {
406
+ errorText = error.message.toLowerCase();
407
+ }
408
+ else if (typeof error === 'string') {
409
+ errorText = error.toLowerCase();
410
+ }
411
+ else if (error && typeof error === 'object' && 'message' in error) {
412
+ errorText = String(error.message).toLowerCase();
413
+ }
414
+ // Handle specific error cases
415
+ if (errorText.includes('network') || errorText.includes('fetch') || errorText.includes('failed to fetch') ||
416
+ errorText.includes('ai generation fetch failed') || errorText.includes('network request failed')) {
417
+ errorTitle = 'Connection Problem';
418
+ errorMessage = 'Unable to connect to the AI service.';
419
+ actionableMessage = 'Please check your internet connection and try again.';
420
+ }
421
+ else if (errorText.includes('timeout') || errorText.includes('aborted')) {
422
+ errorTitle = 'Request Timed Out';
423
+ errorMessage = 'The AI service is taking longer than expected to respond.';
424
+ actionableMessage = 'Please try again in a moment. The service may be experiencing high demand.';
425
+ }
426
+ else if (errorText.includes('500') || errorText.includes('server error') || errorText.includes('internal server')) {
427
+ errorTitle = 'Service Temporarily Unavailable';
428
+ errorMessage = 'The AI service is experiencing technical difficulties.';
429
+ actionableMessage = 'Please try again in a few moments. If the issue continues, contact support.';
430
+ }
431
+ else if (errorText.includes('400') || errorText.includes('bad request')) {
432
+ errorTitle = 'Invalid Request';
433
+ errorMessage = 'There was an issue with the generation request.';
434
+ actionableMessage = 'Please try again with different content or contact support if the issue persists.';
435
+ }
436
+ else if (errorText.includes('api key') || errorText.includes('unauthorized') || errorText.includes('403') || errorText.includes('401')) {
437
+ errorTitle = 'Service Unavailable';
438
+ errorMessage = 'The AI service is temporarily unavailable.';
439
+ actionableMessage = 'Please try again later or contact support for assistance.';
440
+ }
441
+ else if (errorText.includes('quota') || errorText.includes('429') || errorText.includes('rate limit')) {
442
+ errorTitle = 'Service Limit Reached';
443
+ errorMessage = 'The AI service has reached its usage limit.';
444
+ actionableMessage = 'Please try again later or contact support to increase your service limits.';
445
+ }
446
+ else if (error instanceof Error) {
447
+ errorMessage = error.message || 'An unexpected error occurred.';
448
+ }
449
+ else if (typeof error === 'string') {
450
+ errorMessage = error;
451
+ }
452
+ showAlert(`${errorMessage} ${actionableMessage}`, 'error', {
453
+ title: errorTitle,
454
+ confirmText: 'Try Again',
455
+ cancelText: 'Continue Editing',
456
+ showCancel: true,
457
+ onConfirm: () => {
458
+ setIsAIModalOpen(true);
459
+ },
460
+ onCancel: () => {
461
+ setIsAIModalOpen(false);
462
+ }
463
+ });
304
464
  }
305
465
  }
306
466
  finally {
@@ -318,7 +478,7 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
318
478
  if (!layoutJson || !pageSchema) {
319
479
  return (_jsx("div", { className: "flex items-center justify-center h-full", children: _jsx("div", { className: "text-slate-400", children: "Layout not found" }) }));
320
480
  }
321
- return (_jsxs("div", { className: `flex flex-col h-full bg-white ${className} font-sans antialiased text-slate-900`, children: [_jsx(EditorHeader, { layoutName: layoutJson.layoutName || layoutId, storeName: storeName, activePage: activePageId, pages: pages, onPageSwitch: setActivePageId, onSave: handleSave, onPublish: onPublish ? handlePublish : undefined, onBack: onBack, viewMode: viewMode, onViewModeChange: setViewMode, editorType: "payaza-form", isSaving: isSaving, isPublishing: isPublishing, onGenerateAI: () => setIsAIModalOpen(true), isGeneratingAI: isGeneratingAI }), _jsx(AIGenerateModal, { isOpen: isAIModalOpen, onClose: () => setIsAIModalOpen(false), onGenerate: handleAIGenerate, initialContext: {
481
+ return (_jsxs("div", { className: `flex flex-col h-full bg-white ${className} font-sans antialiased text-slate-900`, children: [_jsx(EditorHeader, { layoutName: layoutJson.layoutName || layoutId, storeName: storeName, activePage: activePageId, pages: pages, onPageSwitch: setActivePageId, onSave: handleSave, onPublish: onPublish && hasChangesSincePublish ? handlePublish : undefined, onBack: onBack, onBackToSettings: onBackToSettings, onOpenAssets: onOpenAssets, onBackToTheme: onBackToTheme, onUndo: handleUndo, onRedo: handleRedo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1, viewMode: viewMode, onViewModeChange: setViewMode, editorType: "payaza-form", isSaving: isSaving, isPublishing: isPublishing, onGenerateAI: () => setIsAIModalOpen(true), isGeneratingAI: isGeneratingAI }), _jsx(AIGenerateModal, { isOpen: isAIModalOpen, onClose: () => setIsAIModalOpen(false), onGenerate: handleAIGenerate, initialContext: {
322
482
  storeName: storeName || data?.name || '',
323
483
  storeDescription: storeDescription || data?.description || '',
324
484
  assets: assets || [],
@@ -1,6 +1,9 @@
1
1
  import React from 'react';
2
2
  import { PayazaFormEditorProps } from './PayazaFormEditor';
3
3
  export interface PayazaFormEditorFullPageProps extends PayazaFormEditorProps {
4
+ onBackToSettings?: () => void;
5
+ onOpenAssets?: () => void;
6
+ onBackToTheme?: () => void;
4
7
  }
5
8
  export declare const PayazaFormEditorFullPage: React.FC<PayazaFormEditorFullPageProps>;
6
9
  //# sourceMappingURL=PayazaFormEditorFullPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PayazaFormEditorFullPage.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditorFullPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAoB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,MAAM,WAAW,6BAA8B,SAAQ,qBAAqB;CAAG;AAE/E,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CAQ5E,CAAC"}
1
+ {"version":3,"file":"PayazaFormEditorFullPage.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditorFullPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAoB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAG7E,MAAM,WAAW,6BAA8B,SAAQ,qBAAqB;IAE1E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CAU5E,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { PayazaFormEditor } from './PayazaFormEditor';
3
+ import { AlertModalProvider } from '../../components/ui/alert-modal';
3
4
  export const PayazaFormEditorFullPage = (props) => {
4
- return (_jsx("div", { className: "fixed inset-0 z-50 flex flex-col bg-slate-50", children: _jsx("main", { className: "flex-1 overflow-hidden", children: _jsx(PayazaFormEditor, { ...props }) }) }));
5
+ return (_jsx(AlertModalProvider, { children: _jsx("div", { className: "fixed inset-0 z-50 flex flex-col bg-slate-50", children: _jsx("main", { className: "flex-1 overflow-hidden", children: _jsx(PayazaFormEditor, { ...props }) }) }) }));
5
6
  };
@@ -15,7 +15,7 @@ export const SectionField = ({ label, description, children, defaultExpanded = f
15
15
  const isAllHidden = !visibility.desktop && !visibility.tablet && !visibility.mobile;
16
16
  return (_jsxs("div", { className: `mb-4 overflow-hidden rounded-2xl border transition-all duration-300 ${isExpanded
17
17
  ? 'border-slate-300 bg-white shadow-[0_8px_30px_rgb(0,0,0,0.04)] scale-[1.01]'
18
- : 'border-slate-200 bg-slate-50/50 hover:bg-white hover:border-slate-300 hover:shadow-[0_4px_20px_rgb(0,0,0,0.02)]'} ${isAllHidden ? 'opacity-60 grayscale' : 'opacity-100'}`, children: [_jsxs("div", { className: "flex items-center w-full relative", children: [_jsxs("button", { type: "button", onClick: () => setIsExpanded(!isExpanded), className: "flex-1 flex items-center justify-between py-5 px-6 text-left transition-colors group", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: `text-[12px] font-black tracking-tight transition-colors ${isExpanded ? 'text-slate-900' : 'text-slate-700'}`, children: label }), !isExpanded && (_jsxs("div", { className: "flex items-center gap-1.5 ml-1", children: [!isAllVisible && !isAllHidden && (_jsxs("div", { className: "flex items-center gap-1 p-1 bg-slate-100/50 rounded-md", children: [visibility.desktop && _jsx(Monitor, { size: 10, className: "text-slate-400" }), visibility.tablet && _jsx(Tablet, { size: 10, className: "text-slate-400" }), visibility.mobile && _jsx(Smartphone, { size: 10, className: "text-slate-400" })] })), isAllHidden && (_jsxs("div", { className: "flex items-center gap-1 px-1.5 py-0.5 bg-red-50 rounded-md", children: [_jsx(EyeOff, { size: 10, className: "text-red-400" }), _jsx("span", { className: "text-[8px] font-bold text-red-400 uppercase tracking-tighter", children: "Hidden" })] }))] }))] }), description && !isExpanded && (_jsx("span", { className: "text-[10px] text-slate-400 font-bold uppercase tracking-widest truncate max-w-[180px]", children: description }))] }), _jsx("div", { className: `transition-all duration-300 rounded-full p-1.5 ${isExpanded ? 'rotate-180 bg-slate-100 text-slate-900' : 'text-slate-300 group-hover:text-slate-500 bg-transparent'}`, children: _jsx(ChevronDown, { className: "w-4 h-4", strokeWidth: 2.5 }) })] }), !isExpanded && (_jsx("div", { className: "absolute right-[52px] top-1/2 -translate-y-1/2 flex items-center opacity-0 group-hover:opacity-100 transition-opacity pr-2 border-r border-slate-100 mr-2", children: _jsx("button", { onClick: (e) => {
18
+ : 'border-slate-200 bg-slate-50/50 hover:bg-white hover:border-slate-300/80 hover:shadow-sm'} ${isAllHidden ? 'opacity-60 grayscale' : 'opacity-100'}`, children: [_jsxs("div", { className: "flex items-center w-full relative", children: [_jsxs("button", { type: "button", onClick: () => setIsExpanded(!isExpanded), className: "flex-1 flex items-center justify-between py-5 px-6 text-left transition-colors group", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: `text-[11px] font-bold uppercase tracking-wider transition-colors ${isExpanded ? 'text-slate-900' : 'text-slate-900'}`, children: label }), !isExpanded && (_jsxs("div", { className: "flex items-center gap-1.5 ml-1", children: [!isAllVisible && !isAllHidden && (_jsxs("div", { className: "flex items-center gap-1 p-1 bg-slate-100/50 rounded-md", children: [visibility.desktop && _jsx(Monitor, { size: 10, className: "text-slate-400" }), visibility.tablet && _jsx(Tablet, { size: 10, className: "text-slate-400" }), visibility.mobile && _jsx(Smartphone, { size: 10, className: "text-slate-400" })] })), isAllHidden && (_jsxs("div", { className: "flex items-center gap-1 px-1.5 py-0.5 bg-red-50 rounded-md", children: [_jsx(EyeOff, { size: 10, className: "text-red-400" }), _jsx("span", { className: "text-[8px] font-bold text-red-400 uppercase tracking-tighter", children: "Hidden" })] }))] }))] }), description && !isExpanded && (_jsx("span", { className: "text-[10px] text-slate-400 font-bold uppercase tracking-widest truncate max-w-[180px]", children: description }))] }), _jsx("div", { className: `transition-all duration-300 rounded-full p-1.5 ${isExpanded ? 'rotate-180 bg-slate-100 text-slate-900' : 'text-slate-300 group-hover:text-slate-500 bg-transparent'}`, children: _jsx(ChevronDown, { className: "w-4 h-4", strokeWidth: 2.5 }) })] }), !isExpanded && (_jsx("div", { className: "absolute right-[52px] top-1/2 -translate-y-1/2 flex items-center opacity-0 group-hover:opacity-100 transition-opacity pr-2 border-r border-slate-100 mr-2", children: _jsx("button", { onClick: (e) => {
19
19
  e.stopPropagation();
20
20
  const nextHidden = !isAllHidden;
21
21
  setVisibility({
@@ -8,10 +8,14 @@ export declare function extractActualPageData(storeConfig: StoreConfig, pageId:
8
8
  * Merge requirement schema with actual layout data
9
9
  * Actual data takes precedence, but requirement provides structure and defaults
10
10
  */
11
- export declare function mergeRequirementWithActualData(requirement: OverlayLayoutJSON, storeConfig: StoreConfig, pageId: string): OverlayLayoutJSON;
11
+ export declare function mergeRequirementWithActualData(requirement: OverlayLayoutJSON, storeConfig: StoreConfig, pageId: string, options?: {
12
+ actualDataPrecedence?: boolean;
13
+ }): OverlayLayoutJSON;
12
14
  /**
13
15
  * Merge ALL pages in a requirement with actual data from StoreConfig
14
16
  * This ensures the StoreConfig is fully populated with defaults for all pages
15
17
  */
16
- export declare function mergeAllPagesWithActualData(requirement: OverlayLayoutJSON, storeConfig: StoreConfig): StoreConfig;
18
+ export declare function mergeAllPagesWithActualData(requirement: OverlayLayoutJSON, storeConfig: StoreConfig, options?: {
19
+ actualDataPrecedence?: boolean;
20
+ }): StoreConfig;
17
21
  //# sourceMappingURL=data-merger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-merger.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/data-merger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AA6GpD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,iBAAiB,GAC9B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAoLrB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,GACb,iBAAiB,CAwFnB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,GACvB,WAAW,CAWb"}
1
+ {"version":3,"file":"data-merger.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/data-merger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AA6GpD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,iBAAiB,GAC9B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAoLrB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAmC,GAC3E,iBAAiB,CAoGnB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAmC,GAC3E,WAAW,CAWb"}
@@ -281,7 +281,7 @@ export function extractActualPageData(storeConfig, pageId, requirement) {
281
281
  * Merge requirement schema with actual layout data
282
282
  * Actual data takes precedence, but requirement provides structure and defaults
283
283
  */
284
- export function mergeRequirementWithActualData(requirement, storeConfig, pageId) {
284
+ export function mergeRequirementWithActualData(requirement, storeConfig, pageId, options = { actualDataPrecedence: true }) {
285
285
  // Find the page in requirement
286
286
  const requirementPage = requirement.pages.find(p => p.id === pageId);
287
287
  if (!requirementPage) {
@@ -292,60 +292,73 @@ export function mergeRequirementWithActualData(requirement, storeConfig, pageId)
292
292
  const actualPageData = extractActualPageData(storeConfig, pageId, requirement);
293
293
  // Create merged page data - start with requirement defaults
294
294
  const mergedPageData = { ...requirementPage.data };
295
- // First, merge all sections that exist in requirement
296
- for (const sectionKey in requirementPage.data) {
297
- const requirementSection = requirementPage.data[sectionKey];
298
- const actualSection = actualPageData[sectionKey];
299
- if (actualSection) {
300
- // Special handling for hero section to ensure sliders are preserved
301
- if (sectionKey === 'hero' &&
302
- typeof requirementSection === 'object' &&
303
- typeof actualSection === 'object' &&
304
- !Array.isArray(requirementSection) &&
305
- !Array.isArray(actualSection)) {
306
- // For hero section, start with actual data (it has the real values)
307
- // Then merge requirement defaults for any missing properties
308
- const mergedHero = {
309
- ...requirementSection, // Start with requirement defaults
310
- ...actualSection, // Override with actual data (takes precedence)
311
- };
312
- // Explicitly preserve sliders from actual data if they exist and have items
313
- // Otherwise, use requirement sliders if actual has none
314
- if (actualSection.sliders && Array.isArray(actualSection.sliders) && actualSection.sliders.length > 0) {
315
- mergedHero.sliders = [...actualSection.sliders]; // Deep copy
295
+ // If we want actual data to take precedence (normal loading)
296
+ if (options.actualDataPrecedence) {
297
+ // First, merge all sections that exist in requirement
298
+ for (const sectionKey in requirementPage.data) {
299
+ const requirementSection = requirementPage.data[sectionKey];
300
+ const actualSection = actualPageData[sectionKey];
301
+ if (actualSection) {
302
+ // Special handling for hero section to ensure sliders are preserved
303
+ if (sectionKey === 'hero' &&
304
+ typeof requirementSection === 'object' &&
305
+ typeof actualSection === 'object' &&
306
+ !Array.isArray(requirementSection) &&
307
+ !Array.isArray(actualSection)) {
308
+ // For hero section, start with actual data (it has the real values)
309
+ // Then merge requirement defaults for any missing properties
310
+ const mergedHero = {
311
+ ...requirementSection, // Start with requirement defaults
312
+ ...actualSection, // Override with actual data (takes precedence)
313
+ };
314
+ // Explicitly preserve sliders from actual data if they exist and have items
315
+ // Otherwise, use requirement sliders if actual has none
316
+ if (actualSection.sliders && Array.isArray(actualSection.sliders) && actualSection.sliders.length > 0) {
317
+ mergedHero.sliders = [...actualSection.sliders]; // Deep copy
318
+ }
319
+ else if (requirementSection.sliders && Array.isArray(requirementSection.sliders)) {
320
+ // Use requirement sliders if actual has none
321
+ mergedHero.sliders = [...requirementSection.sliders];
322
+ }
323
+ mergedPageData[sectionKey] = mergedHero;
316
324
  }
317
- else if (requirementSection.sliders && Array.isArray(requirementSection.sliders)) {
318
- // Use requirement sliders if actual has none
319
- mergedHero.sliders = [...requirementSection.sliders];
325
+ else if (Array.isArray(requirementSection) && Array.isArray(actualSection)) {
326
+ // Merge arrays
327
+ mergedPageData[sectionKey] = mergeArrays(requirementSection, actualSection);
328
+ }
329
+ else if (typeof requirementSection === 'object' &&
330
+ requirementSection !== null &&
331
+ !Array.isArray(requirementSection) &&
332
+ typeof actualSection === 'object' &&
333
+ actualSection !== null &&
334
+ !Array.isArray(actualSection)) {
335
+ // Deep merge objects
336
+ mergedPageData[sectionKey] = deepMerge(requirementSection, actualSection);
337
+ }
338
+ else {
339
+ // Use actual value
340
+ mergedPageData[sectionKey] = actualSection;
320
341
  }
321
- mergedPageData[sectionKey] = mergedHero;
322
- }
323
- else if (Array.isArray(requirementSection) && Array.isArray(actualSection)) {
324
- // Merge arrays
325
- mergedPageData[sectionKey] = mergeArrays(requirementSection, actualSection);
326
- }
327
- else if (typeof requirementSection === 'object' &&
328
- requirementSection !== null &&
329
- !Array.isArray(requirementSection) &&
330
- typeof actualSection === 'object' &&
331
- actualSection !== null &&
332
- !Array.isArray(actualSection)) {
333
- // Deep merge objects
334
- mergedPageData[sectionKey] = deepMerge(requirementSection, actualSection);
335
342
  }
336
- else {
337
- // Use actual value
338
- mergedPageData[sectionKey] = actualSection;
343
+ // If no actual section, keep requirement default
344
+ }
345
+ // Also add any sections from actual data that don't exist in requirement
346
+ // This ensures we don't lose any sections that exist in the store but not in requirement
347
+ for (const sectionKey in actualPageData) {
348
+ if (!mergedPageData[sectionKey] && actualPageData[sectionKey]) {
349
+ // Section exists in actual data but not in requirement - add it
350
+ mergedPageData[sectionKey] = actualPageData[sectionKey];
339
351
  }
340
352
  }
341
- // If no actual section, keep requirement default
342
353
  }
343
- // Also add any sections from actual data that don't exist in requirement
344
- // This ensures we don't lose any sections that exist in the store but not in requirement
345
- for (const sectionKey in actualPageData) {
346
- if (!mergedPageData[sectionKey] && actualPageData[sectionKey]) {
347
- // Section exists in actual data but not in requirement - add it
348
- mergedPageData[sectionKey] = actualPageData[sectionKey];
354
+ else {
355
+ // AI Precedence mode: requirementPage.data (AI data) already contains the updates.
356
+ // We just want to make sure we don't lose sections that WEREN'T updated by AI
357
+ // but exist in actualPageData.
358
+ for (const sectionKey in actualPageData) {
359
+ if (mergedPageData[sectionKey] === undefined && actualPageData[sectionKey]) {
360
+ mergedPageData[sectionKey] = actualPageData[sectionKey];
361
+ }
349
362
  }
350
363
  }
351
364
  // Create merged page - preserve schema from requirement
@@ -366,12 +379,12 @@ export function mergeRequirementWithActualData(requirement, storeConfig, pageId)
366
379
  * Merge ALL pages in a requirement with actual data from StoreConfig
367
380
  * This ensures the StoreConfig is fully populated with defaults for all pages
368
381
  */
369
- export function mergeAllPagesWithActualData(requirement, storeConfig) {
382
+ export function mergeAllPagesWithActualData(requirement, storeConfig, options = { actualDataPrecedence: true }) {
370
383
  let currentStoreConfig = { ...storeConfig };
371
384
  // Iterate through all pages in the requirement and merge them one by one
372
385
  // transformToStoreConfig handles the projection back to StoreConfig
373
386
  requirement.pages.forEach(page => {
374
- const mergedLayout = mergeRequirementWithActualData(requirement, currentStoreConfig, page.id);
387
+ const mergedLayout = mergeRequirementWithActualData(requirement, currentStoreConfig, page.id, options);
375
388
  currentStoreConfig = transformToStoreConfig(mergedLayout, page.id, currentStoreConfig);
376
389
  });
377
390
  return currentStoreConfig;
@@ -53,7 +53,7 @@ export const AIGenerateModal = ({ isOpen, onClose, onGenerate, initialContext, i
53
53
  duration: 2,
54
54
  repeat: Infinity,
55
55
  ease: "easeInOut"
56
- }, className: "w-full h-full bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500" }) }), _jsx("p", { className: "text-[10px] text-slate-400 font-bold uppercase tracking-widest animate-pulse mt-4", children: "This usually takes about 5-10 seconds" })] })] })) }), _jsxs("div", { className: "px-8 py-6 border-b border-slate-100 flex items-center justify-between bg-slate-50/50", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "w-12 h-12 bg-slate-900 rounded-2xl flex items-center justify-center shadow-lg shadow-slate-200", children: _jsx(Sparkles, { className: "w-6 h-6 text-white", strokeWidth: 2.5 }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-xl font-black text-slate-900 tracking-tight", children: "AI Magic Generator" }), _jsx("p", { className: "text-[11px] font-bold text-slate-400 uppercase tracking-widest mt-0.5", children: "Powered by Gemini AI" })] })] }), _jsx("button", { onClick: onClose, className: "w-10 h-10 flex items-center justify-center rounded-xl hover:bg-slate-100 text-slate-400 hover:text-slate-600 transition-all", children: _jsx(X, { size: 20, strokeWidth: 2.5 }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-8", children: [_jsx("div", { className: "bg-blue-50/50 border border-blue-100 rounded-2xl p-5 mb-8", children: _jsxs("div", { className: "flex gap-4", children: [_jsx("div", { className: "w-10 h-10 bg-blue-100 rounded-xl flex-shrink-0 flex items-center justify-center", children: _jsx(Sparkles, { className: "w-5 h-5 text-blue-600" }) }), _jsx("p", { className: "text-[13px] text-blue-800 font-medium leading-relaxed", children: hasDefaultContext
56
+ }, className: "w-full h-full bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500" }) }), _jsx("p", { className: "text-[10px] text-slate-400 font-bold uppercase tracking-widest animate-pulse mt-4", children: "This may take a moment while AI crafts your store" })] })] })) }), _jsxs("div", { className: "px-8 py-6 border-b border-slate-100 flex items-center justify-between bg-slate-50/50", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "w-12 h-12 bg-slate-900 rounded-2xl flex items-center justify-center shadow-lg shadow-slate-200", children: _jsx(Sparkles, { className: "w-6 h-6 text-white", strokeWidth: 2.5 }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-xl font-black text-slate-900 tracking-tight", children: "AI Magic Generator" }), _jsx("p", { className: "text-[11px] font-bold text-slate-400 uppercase tracking-widest mt-0.5", children: "Powered by Gemini AI" })] })] }), _jsx("button", { onClick: onClose, className: "w-10 h-10 flex items-center justify-center rounded-xl hover:bg-slate-100 text-slate-400 hover:text-slate-600 transition-all", children: _jsx(X, { size: 20, strokeWidth: 2.5 }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-8", children: [_jsx("div", { className: "bg-blue-50/50 border border-blue-100 rounded-2xl p-5 mb-8", children: _jsxs("div", { className: "flex gap-4", children: [_jsx("div", { className: "w-10 h-10 bg-blue-100 rounded-xl flex-shrink-0 flex items-center justify-center", children: _jsx(Sparkles, { className: "w-5 h-5 text-blue-600" }) }), _jsx("p", { className: "text-[13px] text-blue-800 font-medium leading-relaxed", children: hasDefaultContext
57
57
  ? "We've detected your store details. The AI will use these and your assets to populate your layout. You can add more context below."
58
58
  : "Our AI will use your store name, description, and assets to automatically populate your entire layout with high-quality content." })] }) }), _jsxs("form", { id: "ai-generate-form", onSubmit: handleSubmit, className: "space-y-6", children: [!hasDefaultContext && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-[11px] font-black text-slate-900 uppercase tracking-widest flex items-center gap-2", children: [_jsx(Store, { size: 14, className: "text-slate-400" }), "Store Name"] }), _jsx("input", { type: "text", value: context.storeName, onChange: (e) => setContext({ ...context, storeName: e.target.value }), placeholder: "e.g. Fashion Hub", className: "w-full h-12 px-4 bg-slate-50 border border-slate-200 rounded-xl text-sm font-bold text-slate-700 focus:outline-none focus:ring-4 focus:ring-slate-900/5 focus:border-slate-900/20 transition-all", required: true })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-[11px] font-black text-slate-900 uppercase tracking-widest flex items-center gap-2", children: [_jsx(FileText, { size: 14, className: "text-slate-400" }), "Store Description"] }), _jsx("textarea", { value: context.storeDescription, onChange: (e) => setContext({ ...context, storeDescription: e.target.value }), placeholder: "Briefly describe what your store sells...", rows: 3, className: "w-full p-4 bg-slate-50 border border-slate-200 rounded-xl text-sm font-bold text-slate-700 focus:outline-none focus:ring-4 focus:ring-slate-900/5 focus:border-slate-900/20 transition-all resize-none", required: true })] })] })), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-[11px] font-black text-slate-900 uppercase tracking-widest flex items-center gap-2", children: [_jsx(PlusCircle, { size: 14, className: "text-slate-400" }), "Additional Context (Optional)"] }), _jsx("textarea", { value: context.additionalContext, onChange: (e) => setContext({ ...context, additionalContext: e.target.value }), placeholder: "e.g. Target audience, preferred color scheme, specific sections to highlight...", rows: 4, className: "w-full p-4 bg-slate-50 border border-slate-200 rounded-xl text-sm font-bold text-slate-700 focus:outline-none focus:ring-4 focus:ring-slate-900/5 focus:border-slate-900/20 transition-all resize-none" })] }), context.assets && context.assets.length > 0 && (_jsxs("div", { className: "flex items-center gap-3 p-4 bg-green-50 rounded-2xl border border-green-100", children: [_jsx(ImageIcon, { className: "w-5 h-5 text-green-600" }), _jsxs("div", { className: "flex-1", children: [_jsxs("p", { className: "text-[11px] font-black text-slate-900 uppercase tracking-tight", children: [context.assets.length, " Assets Detected"] }), _jsx("p", { className: "text-[10px] text-slate-500 font-bold uppercase tracking-widest", children: "AI will prioritize using your uploaded images" })] })] })), _jsxs("div", { className: "flex items-center gap-3 p-4 bg-slate-50 rounded-2xl border border-slate-100", children: [_jsx(Sparkles, { className: "w-5 h-5 text-slate-400" }), _jsxs("div", { className: "flex-1", children: [_jsx("p", { className: "text-[11px] font-black text-slate-900 uppercase tracking-tight", children: "Auto-Sourcing Enabled" }), _jsx("p", { className: "text-[10px] text-slate-400 font-bold uppercase tracking-widest", children: "AI will source high-quality images for missing assets" })] })] })] })] }), _jsxs("div", { className: "px-8 py-6 border-t border-slate-100 bg-slate-50/50 flex gap-4", children: [_jsx("button", { onClick: onClose, className: "flex-1 h-12 rounded-2xl border border-slate-200 bg-white font-black text-[12px] uppercase tracking-widest text-slate-600 hover:bg-slate-50 transition-all active:scale-[0.98]", disabled: isGenerating, children: "Cancel" }), _jsx("button", { type: "submit", form: "ai-generate-form", className: "flex-[2] h-12 rounded-2xl bg-slate-900 font-black text-[12px] uppercase tracking-widest text-white hover:bg-black transition-all shadow-xl shadow-slate-200 flex items-center justify-center gap-3 active:scale-[0.98] disabled:opacity-70", disabled: isGenerating, children: isGenerating ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "w-4 h-4 animate-spin" }), "Generating Magic..."] })) : (_jsxs(_Fragment, { children: [_jsx(Sparkles, { className: "w-4 h-4" }), "Generate Layout"] })) })] })] }) }));
59
59
  };
@@ -8,6 +8,13 @@ interface EditorHeaderProps {
8
8
  onSave: () => void;
9
9
  onPublish?: () => void;
10
10
  onBack?: () => void;
11
+ onBackToSettings?: () => void;
12
+ onOpenAssets?: () => void;
13
+ onBackToTheme?: () => void;
14
+ onUndo?: () => void;
15
+ onRedo?: () => void;
16
+ canUndo?: boolean;
17
+ canRedo?: boolean;
11
18
  onGenerateAI?: () => void;
12
19
  isGeneratingAI?: boolean;
13
20
  pages: {
@@ -1 +1 @@
1
- {"version":3,"file":"EditorHeader.d.ts","sourceRoot":"","sources":["../../../src/editor/shared/EditorHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAsB3D,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;IACnE,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAWD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAyQpD,CAAC"}
1
+ {"version":3,"file":"EditorHeader.d.ts","sourceRoot":"","sources":["../../../src/editor/shared/EditorHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AA+ExE,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;IACnE,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAWD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwWpD,CAAC"}
@@ -1,6 +1,28 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef, useEffect, useState } from 'react';
3
- import { ChevronLeft, ChevronRight, Layout, Save, Smartphone, Monitor, Tablet, Eye, Home, ShoppingBag, ShoppingCart, FileText, Send, Sparkles } from 'lucide-react';
3
+ import { motion, AnimatePresence } from 'framer-motion';
4
+ import { ChevronLeft, Layout, Save, Smartphone, Monitor, Tablet, ChevronDown, Home, ShoppingBag, ShoppingCart, FileText, Settings, Undo2, Redo2, Send, Sparkles, Image as ImageIcon, Palette, Check } from 'lucide-react';
5
+ const Tooltip = ({ text, children }) => {
6
+ const [isVisible, setIsVisible] = useState(false);
7
+ const timeoutRef = useRef(null);
8
+ const showTooltip = () => {
9
+ if (timeoutRef.current)
10
+ clearTimeout(timeoutRef.current);
11
+ timeoutRef.current = setTimeout(() => setIsVisible(true), 400);
12
+ };
13
+ const hideTooltip = () => {
14
+ if (timeoutRef.current)
15
+ clearTimeout(timeoutRef.current);
16
+ setIsVisible(false);
17
+ };
18
+ useEffect(() => {
19
+ return () => {
20
+ if (timeoutRef.current)
21
+ clearTimeout(timeoutRef.current);
22
+ };
23
+ }, []);
24
+ return (_jsxs("div", { className: "relative flex items-center justify-center", onMouseEnter: showTooltip, onMouseLeave: hideTooltip, children: [children, _jsx(AnimatePresence, { children: isVisible && (_jsx(motion.div, { initial: { opacity: 0, y: 8, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 8, scale: 0.95 }, transition: { duration: 0.15, ease: [0.23, 1, 0.32, 1] }, className: "absolute top-full pt-2 left-1/2 -translate-x-1/2 z-[9999] pointer-events-none", children: _jsxs("div", { className: "relative", children: [_jsx("div", { className: "bg-slate-900 text-white text-[10px] font-bold uppercase tracking-wider px-2.5 py-1.5 rounded-md shadow-2xl border border-white/10 whitespace-nowrap", children: text }), _jsx("div", { className: "absolute -top-1 left-1/2 -translate-x-1/2 w-2 h-2 bg-slate-900 rotate-45 border-l border-t border-white/10", style: { zIndex: -1 } })] }) })) })] }));
25
+ };
4
26
  const getPageIcon = (pageId) => {
5
27
  switch (pageId) {
6
28
  case 'home': return _jsx(Home, { className: "w-3.5 h-3.5" });
@@ -9,7 +31,8 @@ const getPageIcon = (pageId) => {
9
31
  default: return _jsx(FileText, { className: "w-3.5 h-3.5" });
10
32
  }
11
33
  };
12
- export const EditorHeader = ({ layoutName, storeName, activePage, isSaving, isPublishing, onSave, onPublish, onBack, onGenerateAI, isGeneratingAI, pages, onPageSwitch, viewMode = 'desktop', onViewModeChange, editorType }) => {
34
+ export const EditorHeader = ({ layoutName, storeName, activePage, isSaving, isPublishing, onSave, onPublish, onBack, onBackToSettings, onOpenAssets, onBackToTheme, onUndo, onRedo, canUndo, canRedo, onGenerateAI, isGeneratingAI, pages, onPageSwitch, viewMode = 'desktop', onViewModeChange, editorType }) => {
35
+ const [isPageSwitcherOpen, setIsPageSwitcherOpen] = useState(false);
13
36
  const scrollContainerRef = useRef(null);
14
37
  const [canScrollLeft, setCanScrollLeft] = useState(false);
15
38
  const [canScrollRight, setCanScrollRight] = useState(false);
@@ -20,6 +43,20 @@ export const EditorHeader = ({ layoutName, storeName, activePage, isSaving, isPu
20
43
  setCanScrollLeft(container.scrollLeft > 0);
21
44
  setCanScrollRight(container.scrollLeft < container.scrollWidth - container.clientWidth - 1);
22
45
  };
46
+ useEffect(() => {
47
+ const handleClickOutside = (event) => {
48
+ const target = event.target;
49
+ if (!target.closest('.page-switcher-container')) {
50
+ setIsPageSwitcherOpen(false);
51
+ }
52
+ };
53
+ if (isPageSwitcherOpen) {
54
+ document.addEventListener('mousedown', handleClickOutside);
55
+ }
56
+ return () => {
57
+ document.removeEventListener('mousedown', handleClickOutside);
58
+ };
59
+ }, [isPageSwitcherOpen]);
23
60
  useEffect(() => {
24
61
  checkScrollability();
25
62
  const container = scrollContainerRef.current;
@@ -64,13 +101,12 @@ export const EditorHeader = ({ layoutName, storeName, activePage, isSaving, isPu
64
101
  : container.scrollLeft + scrollAmount;
65
102
  container.scrollTo({ left: newScrollLeft, behavior: 'smooth' });
66
103
  };
67
- return (_jsxs("div", { className: "border-b border-slate-200 bg-white sticky top-0 z-[100] h-16 shadow-[0_2px_8px_rgba(0,0,0,0.04)] font-sans", children: [_jsxs("div", { className: "flex items-center justify-between px-6 h-full w-full mx-auto gap-4", children: [_jsxs("div", { className: "flex items-center flex-shrink-0", children: [onBack && (_jsx("button", { onClick: onBack, className: "h-10 w-10 flex items-center justify-center rounded-xl hover:bg-slate-50 border border-slate-100 transition-all active:scale-95 shadow-sm", children: _jsx(ChevronLeft, { className: "h-5 w-5 text-slate-600", strokeWidth: 2.5 }) })), _jsx("div", { className: "h-8 w-px bg-slate-100 mx-3" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "w-10 h-10 bg-slate-900 flex items-center justify-center rounded-xl shadow-lg shadow-slate-200", children: _jsx(Layout, { className: "w-5 h-5 text-white", strokeWidth: 2.5 }) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("h1", { className: "text-[12px] font-black leading-tight tracking-tight uppercase text-slate-900 whitespace-nowrap", children: storeName || layoutName }), _jsxs("div", { className: "flex items-center gap-1.5 mt-0.5", children: [_jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.5)] animate-pulse" }), _jsx("span", { className: "text-[9px] uppercase font-black text-slate-400 tracking-[0.15em]", children: "Live Studio" })] })] })] })] }), _jsxs("div", { className: "flex items-center gap-4 flex-1 min-w-0 justify-center max-w-[500px]", children: [_jsxs("div", { className: "flex items-center bg-slate-50/80 backdrop-blur-sm rounded-xl p-1 border border-slate-200/60 relative w-full max-w-[380px] shadow-inner", children: [canScrollLeft && (_jsx("button", { onClick: () => scroll('left'), className: "absolute left-1 z-10 h-6 w-6 flex items-center justify-center rounded-lg bg-white border border-slate-200 shadow-md hover:bg-slate-50 transition-all text-slate-600 hover:text-slate-900", "aria-label": "Scroll left", children: _jsx(ChevronLeft, { className: "w-3 h-3", strokeWidth: 3 }) })), _jsx("div", { ref: scrollContainerRef, className: "flex items-center gap-0.5 overflow-x-auto scroll-smooth flex-1 min-w-0 no-scrollbar", style: {
68
- scrollbarWidth: 'none',
69
- msOverflowStyle: 'none',
70
- WebkitOverflowScrolling: 'touch'
71
- }, children: _jsx("div", { className: "flex items-center gap-1 px-6", children: pages.map((page) => (_jsxs("button", { "data-page-id": page.id, onClick: () => onPageSwitch(page.id), className: `flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[10px] font-black transition-all whitespace-nowrap flex-shrink-0 ${activePage === page.id
72
- ? 'text-slate-900 bg-white shadow-sm border border-slate-100'
73
- : 'text-slate-400 hover:text-slate-600 hover:bg-white/50'}`, children: [_jsx("div", { className: activePage === page.id ? 'text-slate-900' : 'text-slate-300', children: getPageIcon(page.id) }), page.name] }, page.id))) }) }), canScrollRight && (_jsx("button", { onClick: () => scroll('right'), className: "absolute right-1.5 z-10 h-6 w-6 flex items-center justify-center rounded-lg bg-white border border-slate-200 shadow-md hover:bg-slate-50 transition-all text-slate-600 hover:text-slate-900", "aria-label": "Scroll right", children: _jsx(ChevronRight, { className: "w-3 h-3", strokeWidth: 3 }) }))] }), _jsx("div", { className: "h-4 w-px bg-slate-200" }), _jsxs("div", { className: "flex items-center bg-slate-50 rounded-lg p-0.5 border border-slate-100 shadow-sm", children: [_jsx("button", { onClick: () => onViewModeChange?.('desktop'), className: `p-1.5 rounded-md transition-all ${viewMode === 'desktop' ? 'bg-white shadow-sm text-slate-900 border border-slate-100' : 'text-slate-400 hover:text-slate-600'}`, title: "Desktop View", children: _jsx(Monitor, { size: 14, strokeWidth: 2.5 }) }), _jsx("button", { onClick: () => onViewModeChange?.('tablet'), className: `p-1.5 rounded-md transition-all ${viewMode === 'tablet' ? 'bg-white shadow-sm text-slate-900 border border-slate-100' : 'text-slate-400 hover:text-slate-600'}`, title: "Tablet View", children: _jsx(Tablet, { size: 14, strokeWidth: 2.5 }) }), _jsx("button", { onClick: () => onViewModeChange?.('mobile'), className: `p-1.5 rounded-md transition-all ${viewMode === 'mobile' ? 'bg-white shadow-sm text-slate-900 border border-slate-100' : 'text-slate-400 hover:text-slate-600'}`, title: "Mobile View", children: _jsx(Smartphone, { size: 14, strokeWidth: 2.5 }) })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [onGenerateAI && (_jsx("button", { onClick: onGenerateAI, disabled: isGeneratingAI, title: "AI Generate", className: "h-9 w-9 bg-gradient-to-r from-indigo-600 to-violet-600 text-white rounded-xl font-black flex items-center justify-center hover:from-indigo-700 hover:to-violet-700 transition-all shadow-md shadow-indigo-100 active:scale-[0.98] disabled:opacity-50", children: isGeneratingAI ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" })) : (_jsx(Sparkles, { className: "w-3.5 h-3.5" })) })), _jsxs("button", { className: "h-9 px-4 flex items-center gap-2 rounded-xl text-slate-600 hover:bg-slate-50 transition-all font-black text-[9px] uppercase tracking-widest border border-transparent hover:border-slate-200", children: [_jsx(Eye, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }), "Preview"] }), _jsxs("button", { onClick: onSave, disabled: isSaving, className: "h-9 px-4 bg-white text-slate-900 border border-slate-200 rounded-xl font-black text-[9px] uppercase tracking-[0.1em] flex items-center gap-2 hover:bg-slate-50 hover:shadow-md hover:shadow-slate-100 transition-all active:scale-[0.98] disabled:opacity-50", children: [isSaving ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-slate-200 border-t-slate-800 rounded-full animate-spin" })) : (_jsx(Save, { className: "w-3.5 h-3.5", strokeWidth: 2.5 })), "Save Draft"] }), onPublish && (_jsxs("button", { onClick: onPublish, disabled: isPublishing, className: "h-9 px-5 bg-slate-900 text-white rounded-xl font-black text-[9px] uppercase tracking-[0.12em] flex items-center gap-2 hover:bg-black transition-all shadow-lg shadow-slate-200 active:scale-[0.98] disabled:opacity-50", children: [isPublishing ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" })) : (_jsx(Send, { className: "w-3.5 h-3.5", strokeWidth: 2.5 })), "Publish"] }))] })] }), _jsx("style", { dangerouslySetInnerHTML: { __html: `
104
+ return (_jsxs("div", { className: "border-b border-slate-200 bg-white sticky top-0 z-[100] h-16 shadow-[0_2px_8px_rgba(0,0,0,0.04)] font-sans", children: [_jsxs("div", { className: "flex items-center justify-between px-6 h-full w-full mx-auto gap-4", children: [_jsxs("div", { className: "flex items-center flex-shrink-0 gap-2", children: [onBack && (_jsx(Tooltip, { text: "Go Back", children: _jsx("button", { onClick: onBack, className: "h-9 w-9 flex items-center justify-center rounded-xl hover:bg-slate-50 border border-slate-100 transition-all active:scale-95 shadow-sm", children: _jsx(ChevronLeft, { className: "h-4 w-4 text-slate-600", strokeWidth: 2.5 }) }) })), _jsx("div", { className: "h-8 w-px bg-slate-100 mx-1" }), _jsxs("div", { className: "flex items-center gap-3 ml-1", children: [_jsx(Tooltip, { text: "Layout Info", children: _jsx("div", { className: "w-10 h-10 bg-slate-900 flex items-center justify-center rounded-xl shadow-lg shadow-slate-200", children: _jsx(Layout, { className: "w-5 h-5 text-white", strokeWidth: 2.5 }) }) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("h1", { className: "text-[12px] font-black leading-tight tracking-tight uppercase text-slate-900 whitespace-nowrap", children: storeName || layoutName }), _jsxs("div", { className: "flex items-center gap-1.5 mt-0.5", children: [_jsx("div", { className: "w-1.5 h-1.5 rounded-full bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.5)] animate-pulse" }), _jsx("span", { className: "text-[9px] uppercase font-black text-slate-400 tracking-[0.15em]", children: "Live Studio" })] })] })] })] }), _jsx("div", { className: "flex items-center gap-4 flex-1 min-w-0 justify-center", children: _jsxs("div", { className: "relative page-switcher-container", children: [_jsxs("button", { onClick: () => setIsPageSwitcherOpen(!isPageSwitcherOpen), className: "flex items-center gap-2 px-4 py-2 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-xl transition-all group", children: [_jsx("div", { className: "text-slate-900", children: getPageIcon(activePage) }), _jsx("span", { className: "text-[10px] font-black uppercase tracking-widest text-slate-900", children: pages.find(p => p.id === activePage)?.name || activePage }), _jsx(ChevronDown, { className: `w-3.5 h-3.5 text-slate-400 transition-transform duration-200 ${isPageSwitcherOpen ? 'rotate-180' : ''}`, strokeWidth: 3 })] }), _jsx(AnimatePresence, { children: isPageSwitcherOpen && (_jsxs(motion.div, { initial: { opacity: 0, y: 10, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 10, scale: 0.95 }, className: "absolute top-full left-0 mt-2 w-56 bg-white border border-slate-200 rounded-2xl shadow-2xl z-[200] p-2", children: [_jsx("div", { className: "px-3 py-2 border-b border-slate-50 mb-1", children: _jsx("span", { className: "text-[9px] font-black uppercase tracking-[0.2em] text-slate-400", children: "Switch Page" }) }), _jsx("div", { className: "space-y-0.5", children: pages.map((page) => (_jsxs("button", { onClick: () => {
105
+ onPageSwitch(page.id);
106
+ setIsPageSwitcherOpen(false);
107
+ }, className: `w-full flex items-center justify-between px-3 py-2.5 rounded-xl transition-all ${activePage === page.id
108
+ ? 'bg-slate-900 text-white shadow-lg shadow-slate-200'
109
+ : 'text-slate-600 hover:bg-slate-50'}`, children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: activePage === page.id ? 'text-white' : 'text-slate-400', children: getPageIcon(page.id) }), _jsx("span", { className: `text-[10px] font-black uppercase tracking-widest`, children: page.name })] }), activePage === page.id && _jsx(Check, { className: "w-3.5 h-3.5", strokeWidth: 3 })] }, page.id))) })] })) })] }) }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsxs("div", { className: "flex items-center mr-2", children: [_jsx(Tooltip, { text: "Desktop View", children: _jsx("button", { onClick: () => onViewModeChange?.('desktop'), className: `p-2 rounded-xl transition-all ${viewMode === 'desktop' ? 'bg-slate-100 text-slate-900' : 'text-slate-400 hover:text-slate-600 hover:bg-slate-50'}`, children: _jsx(Monitor, { size: 18, strokeWidth: 2.5 }) }) }), _jsx(Tooltip, { text: "Tablet View", children: _jsx("button", { onClick: () => onViewModeChange?.('tablet'), className: `p-2 rounded-xl transition-all ${viewMode === 'tablet' ? 'bg-slate-100 text-slate-900' : 'text-slate-400 hover:text-slate-600 hover:bg-slate-50'}`, children: _jsx(Tablet, { size: 18, strokeWidth: 2.5 }) }) }), _jsx(Tooltip, { text: "Mobile View", children: _jsx("button", { onClick: () => onViewModeChange?.('mobile'), className: `p-2 rounded-xl transition-all ${viewMode === 'mobile' ? 'bg-slate-100 text-slate-900' : 'text-slate-400 hover:text-slate-600 hover:bg-slate-50'}`, children: _jsx(Smartphone, { size: 18, strokeWidth: 2.5 }) }) })] }), _jsx("div", { className: "h-8 w-px bg-slate-100 mx-1" }), _jsxs("div", { className: "flex items-center mr-2", children: [_jsx(Tooltip, { text: "Undo (Ctrl+Z)", children: _jsx("button", { onClick: onUndo, disabled: !canUndo, className: `p-2 rounded-xl transition-all ${canUndo ? 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' : 'text-slate-200 cursor-not-allowed'}`, children: _jsx(Undo2, { size: 18, strokeWidth: 2.5 }) }) }), _jsx(Tooltip, { text: "Redo (Ctrl+Y)", children: _jsx("button", { onClick: onRedo, disabled: !canRedo, className: `p-2 rounded-xl transition-all ${canRedo ? 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' : 'text-slate-200 cursor-not-allowed'}`, children: _jsx(Redo2, { size: 18, strokeWidth: 2.5 }) }) })] }), _jsx("div", { className: "h-8 w-px bg-slate-100 mx-1" }), _jsxs("div", { className: "flex items-center mr-2", children: [onBackToSettings && (_jsx(Tooltip, { text: "Store Settings", children: _jsx("button", { onClick: onBackToSettings, className: "p-2 rounded-xl text-slate-600 hover:text-slate-900 hover:bg-slate-50 transition-all", children: _jsx(Settings, { size: 18, strokeWidth: 2.5 }) }) })), onOpenAssets && (_jsx(Tooltip, { text: "Assets Library", children: _jsx("button", { onClick: onOpenAssets, className: "p-2 rounded-xl text-slate-600 hover:text-slate-900 hover:bg-slate-50 transition-all", children: _jsx(ImageIcon, { size: 18, strokeWidth: 2.5 }) }) })), onBackToTheme && (_jsx(Tooltip, { text: "Theme Selector", children: _jsx("button", { onClick: onBackToTheme, className: "p-2 rounded-xl text-slate-600 hover:text-slate-900 hover:bg-slate-50 transition-all", children: _jsx(Palette, { size: 18, strokeWidth: 2.5 }) }) }))] }), _jsx("div", { className: "h-8 w-px bg-slate-100 mx-1" }), onGenerateAI && (_jsx(Tooltip, { text: "AI Magic Generator", children: _jsx("button", { onClick: onGenerateAI, disabled: isGeneratingAI, className: "h-9 w-9 bg-gradient-to-r from-indigo-600 to-violet-600 text-white rounded-xl font-black flex items-center justify-center hover:from-indigo-700 hover:to-violet-700 transition-all shadow-md shadow-indigo-100 active:scale-[0.98] disabled:opacity-50", children: isGeneratingAI ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" })) : (_jsx(Sparkles, { className: "w-3.5 h-3.5" })) }) })), _jsx(Tooltip, { text: "Save Changes", children: _jsxs("button", { onClick: onSave, disabled: isSaving, className: "h-9 px-4 bg-white text-slate-900 border border-slate-200 rounded-xl font-black text-[9px] uppercase tracking-[0.1em] flex items-center gap-2 hover:bg-slate-50 hover:shadow-md hover:shadow-slate-100 transition-all active:scale-[0.98] disabled:opacity-50", children: [isSaving ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-slate-200 border-t-slate-800 rounded-full animate-spin" })) : (_jsx(Save, { className: "w-3.5 h-3.5", strokeWidth: 2.5 })), "Save Draft"] }) }), _jsx(Tooltip, { text: !onPublish ? "No changes to publish" : "Publish to Store", children: _jsxs("button", { onClick: onPublish, disabled: isPublishing || !onPublish, className: "h-9 px-5 bg-slate-900 text-white rounded-xl font-black text-[9px] uppercase tracking-[0.12em] flex items-center gap-2 hover:bg-black transition-all shadow-lg shadow-slate-200 active:scale-[0.98] disabled:opacity-50 disabled:bg-slate-200 disabled:text-slate-400 disabled:shadow-none", children: [isPublishing ? (_jsx("span", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" })) : (_jsx(Send, { className: "w-3.5 h-3.5", strokeWidth: 2.5 })), "Publish"] }) })] })] }), _jsx("style", { dangerouslySetInnerHTML: { __html: `
74
110
  .overflow-x-auto::-webkit-scrollbar {
75
111
  display: none;
76
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IframePreview.d.ts","sourceRoot":"","sources":["../../../src/editor/shared/IframePreview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAoLtD,CAAC"}
1
+ {"version":3,"file":"IframePreview.d.ts","sourceRoot":"","sources":["../../../src/editor/shared/IframePreview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwLtD,CAAC"}
@@ -70,7 +70,11 @@ export const IframePreview = ({ layoutId, config, activePageId, viewMode, select
70
70
  // In standalone store-layout-preview, it's just /preview/
71
71
  let basePath = '/preview';
72
72
  if (typeof window !== 'undefined') {
73
- if (window.location.pathname.includes('/dashboard/layout-content')) {
73
+ const pathname = window.location.pathname;
74
+ // Check for any dashboard route that uses the layout-content preview system
75
+ if (pathname.includes('/dashboard/layout-content') ||
76
+ pathname.includes('/dashboard/store-setup-v3') ||
77
+ pathname.includes('/dashboard/store-setup')) {
74
78
  basePath = '/dashboard/layout-content/preview';
75
79
  }
76
80
  }
@@ -70,6 +70,18 @@ export interface FullPageEditorProps extends BaseEditorProps {
70
70
  * Callback triggered when the back button is clicked
71
71
  */
72
72
  onBack?: () => void;
73
+ /**
74
+ * Callback triggered to go back to store settings step
75
+ */
76
+ onBackToSettings?: () => void;
77
+ /**
78
+ * Callback triggered to open assets library
79
+ */
80
+ onOpenAssets?: () => void;
81
+ /**
82
+ * Callback triggered to go back to theme selector set
83
+ */
84
+ onBackToTheme?: () => void;
73
85
  /**
74
86
  * Optional store name passed from host app
75
87
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/editor/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/editor/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MotivationalHomePage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/motivational-speaker/components/MotivationalHomePage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAahD,UAAU,yBAAyB;IAC/B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,yBAAyB,2CAkqB7F"}
1
+ {"version":3,"file":"MotivationalHomePage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/motivational-speaker/components/MotivationalHomePage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAahD,UAAU,yBAAyB;IAC/B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,yBAAyB,2CAwqB7F"}
@@ -7,15 +7,20 @@ import Image from 'next/image';
7
7
  import { formatCurrency, filterActiveServices } from '../../../lib/utils';
8
8
  import { getBannerImage, getServiceImage, getTextContent } from '../../../lib/utils/asset-helpers';
9
9
  import { motion, useScroll, useTransform } from 'framer-motion';
10
- import { useRef, useState } from 'react';
10
+ import { useRef, useState, useContext } from 'react';
11
11
  import { useAuth } from '../../../lib/auth-context';
12
12
  import { useStore } from '../../../lib/store-context';
13
- import { useAlertModal } from '../../../lib/../index';
13
+ import { AlertModalContext } from '../../../components/ui/alert-modal';
14
14
  export function MotivationalHomePage({ storeConfig: initialConfig }) {
15
15
  const { store } = useStore();
16
16
  const storeConfig = store || initialConfig;
17
17
  const { isAuthenticated } = useAuth();
18
- const { showAlert } = useAlertModal();
18
+ // Safely get alert modal context with fallback
19
+ const alertContext = useContext(AlertModalContext);
20
+ const showAlert = alertContext?.showAlert || ((message, type, options) => {
21
+ // Fallback: log to console if provider is not available
22
+ console.log(`[Alert] ${type || 'info'}: ${message}`, options);
23
+ });
19
24
  // In preview mode, use mock content if none are available
20
25
  const isPreview = (typeof window !== 'undefined' && window.__IS_PREVIEW__) || storeConfig.layoutConfig?.isPreview;
21
26
  const rawContent = storeConfig.services || [];
@@ -1 +1 @@
1
- {"version":3,"file":"BaseStoreLayout.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/BaseStoreLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAUvD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,oBAAoB,2CA4E7F"}
1
+ {"version":3,"file":"BaseStoreLayout.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/BaseStoreLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAWvD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,oBAAoB,2CAgF7F"}
@@ -8,6 +8,7 @@ import { usePathname } from 'next/navigation';
8
8
  import { useStore } from '../../../lib/store-context';
9
9
  import { useLoading } from '../../../lib/loading-context';
10
10
  import { getThemeColor } from '../../../lib/utils/asset-helpers';
11
+ import { AlertModalProvider } from '../../../components/ui/alert-modal';
11
12
  export function BaseStoreLayout({ children, storeConfig: initialConfig }) {
12
13
  const pathname = usePathname();
13
14
  const { store, cartCount } = useStore();
@@ -54,7 +55,7 @@ export function BaseStoreLayout({ children, storeConfig: initialConfig }) {
54
55
  ...(accentFocus ? { '--theme-accent-focus': accentFocus } : {}),
55
56
  };
56
57
  if (shouldHideStandardHeader) {
57
- return (_jsx("div", { className: "min-h-screen flex flex-col", style: cssVariables, children: _jsxs("main", { className: "flex-1 relative", children: [isBackendLoading && _jsx(PageContentLoader, {}), _jsx(PageAnimateWrapper, { children: children })] }) }));
58
+ return (_jsx(AlertModalProvider, { children: _jsx("div", { className: "min-h-screen flex flex-col", style: cssVariables, children: _jsxs("main", { className: "flex-1 relative", children: [isBackendLoading && _jsx(PageContentLoader, {}), _jsx(PageAnimateWrapper, { children: children })] }) }) }));
58
59
  }
59
- return (_jsxs("div", { className: "min-h-screen flex flex-col", style: cssVariables, children: [_jsx(StoreHeader, { storeConfig: storeConfig, cartItemCount: cartCount }), _jsxs("main", { className: "flex-1 relative", children: [isBackendLoading && _jsx(PageContentLoader, {}), _jsx(PageAnimateWrapper, { children: children })] }), _jsx(StoreFooter, { storeConfig: storeConfig })] }));
60
+ return (_jsx(AlertModalProvider, { children: _jsxs("div", { className: "min-h-screen flex flex-col", style: cssVariables, children: [_jsx(StoreHeader, { storeConfig: storeConfig, cartItemCount: cartCount }), _jsxs("main", { className: "flex-1 relative", children: [isBackendLoading && _jsx(PageContentLoader, {}), _jsx(PageAnimateWrapper, { children: children })] }), _jsx(StoreFooter, { storeConfig: storeConfig })] }) }));
60
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/StoreHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AA4BvD,UAAU,gBAAgB;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,aAAiB,EAAE,EAAE,gBAAgB,2CAkb9F"}
1
+ {"version":3,"file":"StoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/StoreHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AA4BvD,UAAU,gBAAgB;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,aAAiB,EAAE,EAAE,gBAAgB,2CA6d9F"}
@@ -72,14 +72,31 @@ export function StoreHeader({ storeConfig: initialConfig, cartItemCount = 0 }) {
72
72
  const headerBg = isDarkTheme
73
73
  ? scrolled ? 'rgba(0, 0, 0, 0.9)' : 'rgba(0, 0, 0, 0.7)'
74
74
  : scrolled ? 'rgba(255, 255, 255, 0.98)' : 'rgba(255, 255, 255, 0.9)';
75
- return (_jsxs(_Fragment, { children: [_jsx("header", { "data-section": "header", className: cn("sticky top-0 z-[60] w-full transition-all duration-500 backdrop-blur-xl border-b", scrolled ? "shadow-lg border-gray-100 dark:border-white/5 py-1" : "border-transparent py-2.5"), style: { backgroundColor: headerBg }, children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "relative flex h-16 items-center justify-between", children: [_jsx("div", { className: "flex items-center flex-shrink-0 z-20", children: _jsxs(Link, { href: `/${storeConfig.slug}`, className: "flex items-center gap-3 group", children: [_jsx(StoreLogo, { storeConfig: storeConfig, className: "h-10 w-10 transition-transform duration-500 group-hover:scale-105", alt: storeConfig.name }), !getLogoUrl(storeConfig) && (_jsx("span", { className: cn("text-xl font-bold tracking-tight transition-colors hidden sm:block", isDarkTheme ? "text-white" : "text-gray-900"), children: storeConfig.name }))] }) }), _jsxs("nav", { className: "hidden lg:flex items-center gap-1 absolute left-1/2 -translate-x-1/2", children: [storeConfig.navigation.main.map((item, index) => {
76
- const Icon = item.icon ? (item.icon === 'BookOpen' ? BookOpen : item.icon === 'GraduationCap' ? GraduationCap : item.icon === 'Info' ? Info : getNavIcon(item.label)) : getNavIcon(item.label);
77
- return (_jsxs(Link, { href: `/${storeConfig.slug}${item.href}`, className: cn("px-5 py-2.5 text-[11px] font-bold uppercase tracking-[0.15em] transition-all rounded-full flex items-center gap-2.5 group/nav", isDarkTheme
78
- ? "text-gray-400 hover:text-white hover:bg-white/10"
79
- : "text-gray-600 hover:text-black hover:bg-gray-100"), children: [Icon && _jsx(Icon, { className: "w-4 h-4 transition-transform group-hover/nav:scale-110" }), item.label] }, `${index}-${item.href}`));
80
- }), parentCategories.length > 0 && (_jsxs("div", { className: "relative group", onMouseEnter: () => setIsCatalogueOpen(true), onMouseLeave: () => setIsCatalogueOpen(false), children: [_jsxs("button", { className: cn("px-5 py-2.5 text-[11px] font-bold uppercase tracking-[0.15em] transition-all rounded-full flex items-center gap-2 group/nav", isDarkTheme
75
+ return (_jsxs(_Fragment, { children: [_jsx("header", { "data-section": "header", className: cn("sticky top-0 z-[60] w-full transition-all duration-500 backdrop-blur-xl border-b", scrolled ? "shadow-lg border-gray-100 dark:border-white/5 py-1" : "border-transparent py-2.5"), style: { backgroundColor: headerBg }, children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "relative flex h-16 items-center justify-between", children: [_jsx("div", { className: "flex items-center flex-shrink-0 z-20", children: _jsxs(Link, { href: `/${storeConfig.slug}`, className: "flex items-center gap-3 group", children: [_jsx(StoreLogo, { storeConfig: storeConfig, className: "h-10 w-10 transition-transform duration-500 group-hover:scale-105", alt: storeConfig.name }), !getLogoUrl(storeConfig) && (_jsx("span", { className: cn("text-xl font-bold tracking-tight transition-colors hidden xl:block", isDarkTheme ? "text-white" : "text-gray-900"), children: storeConfig.name }))] }) }), _jsx("nav", { className: "hidden lg:flex items-center gap-1 absolute left-1/2 -translate-x-1/2", children: (() => {
76
+ const menuItems = storeConfig.navigation.main;
77
+ const categories = parentCategories;
78
+ // Logic to determine how many categories to show directly
79
+ // Max total top-level items (menu + categories)
80
+ const maxTotalItems = storeConfig.layout === 'motivational-speaker' ? 5 : 6;
81
+ // How many categories can we fit?
82
+ const categoriesToShowCount = Math.max(0, maxTotalItems - menuItems.length);
83
+ const categoriesToDisplay = categories.slice(0, categoriesToShowCount);
84
+ const overflowCategories = categories.slice(categoriesToShowCount);
85
+ return (_jsxs(_Fragment, { children: [menuItems.map((item, index) => {
86
+ const Icon = item.icon ?
87
+ (item.icon === 'BookOpen' ? BookOpen :
88
+ item.icon === 'GraduationCap' ? GraduationCap :
89
+ item.icon === 'Info' ? Info : getNavIcon(item.label)) :
90
+ getNavIcon(item.label);
91
+ return (_jsxs(Link, { href: `/${storeConfig.slug}${item.href}`, className: cn("px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-all rounded-full flex items-center gap-2 group/nav whitespace-nowrap", isDarkTheme
92
+ ? "text-gray-400 hover:text-white hover:bg-white/10"
93
+ : "text-gray-600 hover:text-black hover:bg-gray-100"), children: [Icon && _jsx(Icon, { className: "w-3.5 h-3.5 transition-transform group-hover/nav:scale-110" }), item.label] }, `nav-${index}-${item.href}`));
94
+ }), categoriesToDisplay.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-all rounded-full flex items-center gap-2 group/nav whitespace-nowrap", isDarkTheme
81
95
  ? "text-gray-400 hover:text-white hover:bg-white/10"
82
- : "text-gray-600 hover:text-black hover:bg-gray-100"), children: [_jsx(LayoutGrid, { className: "w-4 h-4 transition-transform group-hover/nav:scale-110" }), "Catalogue", _jsx(ChevronDown, { className: cn("w-3.5 h-3.5 transition-transform duration-300", isCatalogueOpen && "rotate-180") })] }), _jsx(AnimatePresence, { children: isCatalogueOpen && (_jsx(motion.div, { initial: { opacity: 0, y: 10, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 10, scale: 0.95 }, transition: { duration: 0.2 }, className: cn("absolute top-full left-1/2 -translate-x-1/2 mt-2 w-64 p-3 rounded-2xl shadow-2xl border backdrop-blur-2xl z-50", isDarkTheme ? "bg-black/90 border-white/10" : "bg-white/95 border-gray-100"), children: _jsx("div", { className: "grid gap-1", children: parentCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("flex items-center justify-between px-4 py-3 rounded-xl transition-all group/item", isDarkTheme ? "hover:bg-white/5" : "hover:bg-gray-50"), onClick: () => setIsCatalogueOpen(false), children: [_jsx("span", { className: cn("text-sm font-medium", isDarkTheme ? "text-gray-300 group-hover/item:text-white" : "text-gray-600 group-hover/item:text-black"), children: cat.name }), _jsx(ChevronRight, { className: "w-4 h-4 opacity-0 -translate-x-2 group-hover/item:opacity-100 group-hover/item:translate-x-0 transition-all text-gray-400" })] }, cat.id))) }) })) })] }))] }), _jsxs("div", { className: "flex items-center gap-1 sm:gap-2 z-20", children: [_jsx(Button, { variant: "ghost", size: "icon", className: cn("h-10 w-10 rounded-full transition-all relative", isDarkTheme ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-100 text-gray-600", searchOpen && "bg-transparent shadow-none"), onClick: () => setSearchOpen(true), children: _jsx(Search, { className: "h-5 w-5" }) }), storeConfig.features.wishlist && (_jsx(Link, { href: `/${storeConfig.slug}/wishlist`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 relative rounded-full group hover:bg-red-50 dark:hover:bg-red-900/10", children: [_jsx(Heart, { className: cn("h-5 w-5 transition-all group-hover:scale-110", wishlistCount > 0 && "fill-red-500 text-red-500") }), wishlistCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: wishlistCount }))] }) })), storeConfig.layout === 'motivational-speaker' && isAuthenticated && (_jsx(Link, { href: `/${storeConfig.slug}/account?tab=learning`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: cn("h-10 w-10 relative rounded-full group transition-all", isDarkTheme ? "hover:bg-blue-900/20 text-blue-400" : "hover:bg-blue-50 text-blue-600"), children: [_jsx(BookOpen, { className: "h-5 w-5 transition-all group-hover:scale-110" }), _jsx("span", { className: "sr-only", children: "My Learning" })] }) })), storeConfig.features.cart && (_jsx(Link, { href: `/${storeConfig.slug}/cart`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 relative rounded-full group hover:bg-gray-100 dark:hover:bg-white/10", children: [_jsx(ShoppingCart, { className: "h-5 w-5 group-hover:scale-110 transition-all" }), cartItemCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: cartItemCount }))] }) })), isAuthenticated ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 rounded-full overflow-hidden border-2 border-transparent hover:border-gray-200 transition-all", children: _jsx(AvatarImage, { src: user?.avatar, alt: "User", size: 32 }) }) })) : (_jsx(Link, { href: `/auth/login?callbackUrl=/${storeConfig.slug}`, className: "ml-1 hidden sm:block", children: _jsx(Button, { className: "h-10 px-6 rounded-full font-bold text-xs uppercase tracking-widest transition-all shadow-md hover:shadow-lg active:scale-95", style: { backgroundColor: primaryColor, color: 'white' }, children: "Log In" }) })), _jsx(Button, { variant: "ghost", size: "icon", className: "lg:hidden h-10 w-10 rounded-full ml-1", onClick: () => setMobileMenuOpen(true), children: _jsx(Menu, { className: "h-6 w-6" }) })] })] }) }) }), _jsx(AnimatePresence, { children: searchOpen && (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, className: "fixed inset-0 z-[100] flex flex-col items-center justify-start pt-24 px-4 bg-white/80 dark:bg-black/80 backdrop-blur-2xl", children: _jsxs(motion.div, { initial: { y: -20, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: -20, opacity: 0 }, className: "w-full max-w-3xl relative", children: [_jsxs("div", { className: "relative flex items-center group", children: [_jsx(Search, { className: "absolute left-6 h-6 w-6 text-gray-400 group-focus-within:text-black dark:group-focus-within:text-white transition-colors" }), _jsx("input", { ref: searchInputRef, type: "text", placeholder: "Search products, categories, guides...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: cn("w-full pl-16 pr-24 py-6 text-2xl md:text-3xl font-light bg-transparent border-b-2 border-gray-200 dark:border-white/10 focus:outline-none focus:border-black dark:focus:border-white transition-all", isDarkTheme ? "text-white placeholder-gray-600" : "text-black placeholder-gray-300"), onKeyDown: (e) => e.key === 'Escape' && setSearchOpen(false) }), _jsxs("div", { className: "absolute right-0 flex items-center gap-2", children: [searchQuery && (_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setSearchQuery(''), className: "h-10 w-10 rounded-full", children: _jsx(X, { className: "h-5 w-5 text-gray-400" }) })), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSearchOpen(false), className: "text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-black dark:hover:text-white", children: "Esc" })] })] }), _jsxs("div", { className: "mt-12 grid grid-cols-1 md:grid-cols-2 gap-12", children: [_jsxs("div", { className: "space-y-6", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Quick Links" }), _jsx("div", { className: "flex flex-wrap gap-2", children: ['Courses', 'Mentorship', 'Free Guides', 'Memberships', 'Contact'].map((tag) => (_jsx("button", { className: cn("px-4 py-2 rounded-full text-sm border transition-all", isDarkTheme
96
+ : "text-gray-600 hover:text-black hover:bg-gray-100"), children: [_jsx(LayoutGrid, { className: "w-3.5 h-3.5 transition-transform group-hover/nav:scale-110" }), cat.name] }, `cat-direct-${cat.id}`))), overflowCategories.length > 0 && (_jsxs("div", { className: "relative group", onMouseEnter: () => setIsCatalogueOpen(true), onMouseLeave: () => setIsCatalogueOpen(false), children: [_jsxs("button", { className: cn("px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-all rounded-full flex items-center gap-2 group/nav whitespace-nowrap", isDarkTheme
97
+ ? "text-gray-400 hover:text-white hover:bg-white/10"
98
+ : "text-gray-600 hover:text-black hover:bg-gray-100"), children: [_jsx(LayoutGrid, { className: "w-3.5 h-3.5 transition-transform group-hover/nav:scale-110" }), categoriesToDisplay.length > 0 ? "More" : "Catalogue", _jsx(ChevronDown, { className: cn("w-3.5 h-3.5 transition-transform duration-300", isCatalogueOpen && "rotate-180") })] }), _jsx(AnimatePresence, { children: isCatalogueOpen && (_jsx(motion.div, { initial: { opacity: 0, y: 10, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 10, scale: 0.95 }, transition: { duration: 0.2 }, className: cn("absolute top-full left-1/2 -translate-x-1/2 mt-2 w-64 p-3 rounded-2xl shadow-2xl border backdrop-blur-2xl z-50", isDarkTheme ? "bg-black/90 border-white/10" : "bg-white/95 border-gray-100"), children: _jsx("div", { className: "grid gap-1 overflow-y-auto max-h-[70vh]", children: overflowCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("flex items-center justify-between px-4 py-3 rounded-xl transition-all group/item", isDarkTheme ? "hover:bg-white/5" : "hover:bg-gray-50"), onClick: () => setIsCatalogueOpen(false), children: [_jsx("span", { className: cn("text-sm font-medium", isDarkTheme ? "text-gray-300 group-hover/item:text-white" : "text-gray-600 group-hover/item:text-black"), children: cat.name }), _jsx(ChevronRight, { className: "w-4 h-4 opacity-0 -translate-x-2 group-hover/item:opacity-100 group-hover/item:translate-x-0 transition-all text-gray-400" })] }, `cat-overflow-${cat.id}`))) }) })) })] }))] }));
99
+ })() }), _jsxs("div", { className: "flex items-center gap-1 sm:gap-2 z-20", children: [_jsx(Button, { variant: "ghost", size: "icon", className: cn("h-10 w-10 rounded-full transition-all relative", isDarkTheme ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-100 text-gray-600", searchOpen && "bg-transparent shadow-none"), onClick: () => setSearchOpen(true), children: _jsx(Search, { className: "h-5 w-5" }) }), storeConfig.features.wishlist && (_jsx(Link, { href: `/${storeConfig.slug}/wishlist`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 relative rounded-full group hover:bg-red-50 dark:hover:bg-red-900/10", children: [_jsx(Heart, { className: cn("h-5 w-5 transition-all group-hover:scale-110", wishlistCount > 0 && "fill-red-500 text-red-500") }), wishlistCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: wishlistCount }))] }) })), storeConfig.layout === 'motivational-speaker' && isAuthenticated && (_jsx(Link, { href: `/${storeConfig.slug}/account?tab=learning`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: cn("h-10 w-10 relative rounded-full group transition-all", isDarkTheme ? "hover:bg-blue-900/20 text-blue-400" : "hover:bg-blue-50 text-blue-600"), children: [_jsx(BookOpen, { className: "h-5 w-5 transition-all group-hover:scale-110" }), _jsx("span", { className: "sr-only", children: "My Learning" })] }) })), storeConfig.features.cart && (_jsx(Link, { href: `/${storeConfig.slug}/cart`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 relative rounded-full group hover:bg-gray-100 dark:hover:bg-white/10", children: [_jsx(ShoppingCart, { className: "h-5 w-5 group-hover:scale-110 transition-all" }), cartItemCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: cartItemCount }))] }) })), isAuthenticated ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-10 w-10 rounded-full overflow-hidden border-2 border-transparent hover:border-gray-200 transition-all", children: _jsx(AvatarImage, { src: user?.avatar, alt: "User", size: 32 }) }) })) : (_jsx(Link, { href: `/auth/login?callbackUrl=/${storeConfig.slug}`, className: "ml-1 hidden sm:block", children: _jsx(Button, { className: "h-10 px-6 rounded-full font-bold text-xs uppercase tracking-widest transition-all shadow-md hover:shadow-lg active:scale-95", style: { backgroundColor: primaryColor, color: 'white' }, children: "Log In" }) })), _jsx(Button, { variant: "ghost", size: "icon", className: "lg:hidden h-10 w-10 rounded-full ml-1", onClick: () => setMobileMenuOpen(true), children: _jsx(Menu, { className: "h-6 w-6" }) })] })] }) }) }), _jsx(AnimatePresence, { children: searchOpen && (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, className: "fixed inset-0 z-[100] flex flex-col items-center justify-start pt-24 px-4 bg-white/80 dark:bg-black/80 backdrop-blur-2xl", children: _jsxs(motion.div, { initial: { y: -20, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: -20, opacity: 0 }, className: "w-full max-w-3xl relative", children: [_jsxs("div", { className: "relative flex items-center group", children: [_jsx(Search, { className: "absolute left-6 h-6 w-6 text-gray-400 group-focus-within:text-black dark:group-focus-within:text-white transition-colors" }), _jsx("input", { ref: searchInputRef, type: "text", placeholder: "Search products, categories, guides...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: cn("w-full pl-16 pr-24 py-6 text-2xl md:text-3xl font-light bg-transparent border-b-2 border-gray-200 dark:border-white/10 focus:outline-none focus:border-black dark:focus:border-white transition-all", isDarkTheme ? "text-white placeholder-gray-600" : "text-black placeholder-gray-300"), onKeyDown: (e) => e.key === 'Escape' && setSearchOpen(false) }), _jsxs("div", { className: "absolute right-0 flex items-center gap-2", children: [searchQuery && (_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setSearchQuery(''), className: "h-10 w-10 rounded-full", children: _jsx(X, { className: "h-5 w-5 text-gray-400" }) })), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSearchOpen(false), className: "text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-black dark:hover:text-white", children: "Esc" })] })] }), _jsxs("div", { className: "mt-12 grid grid-cols-1 md:grid-cols-2 gap-12", children: [_jsxs("div", { className: "space-y-6", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Quick Links" }), _jsx("div", { className: "flex flex-wrap gap-2", children: ['Courses', 'Mentorship', 'Free Guides', 'Memberships', 'Contact'].map((tag) => (_jsx("button", { className: cn("px-4 py-2 rounded-full text-sm border transition-all", isDarkTheme
83
100
  ? "border-white/10 hover:border-white text-gray-400 hover:text-white"
84
101
  : "border-gray-200 hover:border-black text-gray-600 hover:text-black"), children: tag }, tag))) })] }), _jsxs("div", { className: "space-y-6", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Popular Categories" }), _jsx("div", { className: "grid gap-3", children: parentCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: "flex items-center gap-3 group", onClick: () => setSearchOpen(false), children: [_jsx("div", { className: "w-10 h-10 rounded-lg bg-gray-100 dark:bg-white/5 flex items-center justify-center group-hover:scale-110 transition-transform", children: _jsx(ChevronRight, { className: "w-4 h-4 text-gray-400" }) }), _jsx("span", { className: "text-lg font-medium text-gray-500 group-hover:text-black dark:group-hover:text-white transition-colors", children: cat.name })] }, cat.id))) })] })] })] }) })) }), _jsx(AnimatePresence, { children: mobileMenuOpen && (_jsxs("div", { className: "fixed inset-0 z-[100] lg:hidden", children: [_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, className: "absolute inset-0 bg-black/60 backdrop-blur-md", onClick: () => setMobileMenuOpen(false) }), _jsxs(motion.nav, { initial: { x: '100%' }, animate: { x: 0 }, exit: { x: '100%' }, transition: { type: "spring", damping: 25, stiffness: 200 }, className: cn("absolute right-0 top-0 bottom-0 w-[300px] shadow-2xl p-8 flex flex-col", isDarkTheme ? "bg-black text-white" : "bg-white text-black"), children: [_jsxs("div", { className: "flex items-center justify-between mb-12", children: [_jsx(StoreLogo, { storeConfig: storeConfig, className: "h-8 w-8" }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => setMobileMenuOpen(false), children: _jsx(X, { className: "h-6 w-6" }) })] }), _jsxs("div", { className: "flex flex-col gap-8", children: [storeConfig.navigation.main.map((item, i) => {
85
102
  const Icon = item.icon ? (item.icon === 'BookOpen' ? BookOpen : item.icon === 'GraduationCap' ? GraduationCap : item.icon === 'Info' ? Info : getNavIcon(item.label)) : getNavIcon(item.label);
@@ -513,9 +513,6 @@
513
513
  .right-1 {
514
514
  right: calc(var(--spacing) * 1);
515
515
  }
516
- .right-1\.5 {
517
- right: calc(var(--spacing) * 1.5);
518
- }
519
516
  .right-1\/4 {
520
517
  right: calc(1/4 * 100%);
521
518
  }
@@ -762,9 +759,6 @@
762
759
  .mx-1 {
763
760
  margin-inline: calc(var(--spacing) * 1);
764
761
  }
765
- .mx-3 {
766
- margin-inline: calc(var(--spacing) * 3);
767
- }
768
762
  .mx-4 {
769
763
  margin-inline: calc(var(--spacing) * 4);
770
764
  }
@@ -1188,6 +1182,9 @@
1188
1182
  .max-h-\[48px\] {
1189
1183
  max-height: 48px;
1190
1184
  }
1185
+ .max-h-\[70vh\] {
1186
+ max-height: 70vh;
1187
+ }
1191
1188
  .max-h-\[85vh\] {
1192
1189
  max-height: 85vh;
1193
1190
  }
@@ -1428,12 +1425,6 @@
1428
1425
  .max-w-\[300px\] {
1429
1426
  max-width: 300px;
1430
1427
  }
1431
- .max-w-\[380px\] {
1432
- max-width: 380px;
1433
- }
1434
- .max-w-\[500px\] {
1435
- max-width: 500px;
1436
- }
1437
1428
  .max-w-\[1600px\] {
1438
1429
  max-width: 1600px;
1439
1430
  }
@@ -1848,6 +1839,13 @@
1848
1839
  margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));
1849
1840
  }
1850
1841
  }
1842
+ .space-y-0\.5 {
1843
+ :where(& > :not(:last-child)) {
1844
+ --tw-space-y-reverse: 0;
1845
+ margin-block-start: calc(calc(var(--spacing) * 0.5) * var(--tw-space-y-reverse));
1846
+ margin-block-end: calc(calc(var(--spacing) * 0.5) * calc(1 - var(--tw-space-y-reverse)));
1847
+ }
1848
+ }
1851
1849
  .space-y-1 {
1852
1850
  :where(& > :not(:last-child)) {
1853
1851
  --tw-space-y-reverse: 0;
@@ -2818,12 +2816,6 @@
2818
2816
  background-color: color-mix(in oklab, var(--color-slate-50) 50%, transparent);
2819
2817
  }
2820
2818
  }
2821
- .bg-slate-50\/80 {
2822
- background-color: color-mix(in srgb, oklch(98.4% 0.003 247.858) 80%, transparent);
2823
- @supports (color: color-mix(in lab, red, red)) {
2824
- background-color: color-mix(in oklab, var(--color-slate-50) 80%, transparent);
2825
- }
2826
- }
2827
2819
  .bg-slate-100 {
2828
2820
  background-color: var(--color-slate-100);
2829
2821
  }
@@ -3485,9 +3477,6 @@
3485
3477
  .p-0 {
3486
3478
  padding: calc(var(--spacing) * 0);
3487
3479
  }
3488
- .p-0\.5 {
3489
- padding: calc(var(--spacing) * 0.5);
3490
- }
3491
3480
  .p-1 {
3492
3481
  padding: calc(var(--spacing) * 1);
3493
3482
  }
@@ -6063,6 +6052,16 @@
6063
6052
  }
6064
6053
  }
6065
6054
  }
6055
+ .hover\:border-slate-300\/80 {
6056
+ &:hover {
6057
+ @media (hover: hover) {
6058
+ border-color: color-mix(in srgb, oklch(86.9% 0.022 252.894) 80%, transparent);
6059
+ @supports (color: color-mix(in lab, red, red)) {
6060
+ border-color: color-mix(in oklab, var(--color-slate-300) 80%, transparent);
6061
+ }
6062
+ }
6063
+ }
6064
+ }
6066
6065
  .hover\:border-slate-900 {
6067
6066
  &:hover {
6068
6067
  @media (hover: hover) {
@@ -6787,14 +6786,6 @@
6787
6786
  }
6788
6787
  }
6789
6788
  }
6790
- .hover\:shadow-\[0_4px_20px_rgb\(0\,0\,0\,0\.02\)\] {
6791
- &:hover {
6792
- @media (hover: hover) {
6793
- --tw-shadow: 0 4px 20px var(--tw-shadow-color, rgb(0,0,0,0.02));
6794
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
6795
- }
6796
- }
6797
- }
6798
6789
  .hover\:shadow-\[0_20px_50px_rgba\(0\,0\,0\,0\.08\)\] {
6799
6790
  &:hover {
6800
6791
  @media (hover: hover) {
@@ -7236,6 +7227,16 @@
7236
7227
  cursor: not-allowed;
7237
7228
  }
7238
7229
  }
7230
+ .disabled\:bg-slate-200 {
7231
+ &:disabled {
7232
+ background-color: var(--color-slate-200);
7233
+ }
7234
+ }
7235
+ .disabled\:text-slate-400 {
7236
+ &:disabled {
7237
+ color: var(--color-slate-400);
7238
+ }
7239
+ }
7239
7240
  .disabled\:opacity-50 {
7240
7241
  &:disabled {
7241
7242
  opacity: 50%;
@@ -7246,6 +7247,12 @@
7246
7247
  opacity: 70%;
7247
7248
  }
7248
7249
  }
7250
+ .disabled\:shadow-none {
7251
+ &:disabled {
7252
+ --tw-shadow: 0 0 #0000;
7253
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
7254
+ }
7255
+ }
7249
7256
  .disabled\:hover\:translate-y-0 {
7250
7257
  &:disabled {
7251
7258
  &:hover {
@@ -8265,6 +8272,11 @@
8265
8272
  line-height: var(--tw-leading, var(--text-9xl--line-height));
8266
8273
  }
8267
8274
  }
8275
+ .xl\:block {
8276
+ @media (width >= 80rem) {
8277
+ display: block;
8278
+ }
8279
+ }
8268
8280
  .xl\:grid-cols-4 {
8269
8281
  @media (width >= 80rem) {
8270
8282
  grid-template-columns: repeat(4, minmax(0, 1fr));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payaza-storefront-layouts",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "type": "module",
5
5
  "description": "Shared layout components for StoreFront applications",
6
6
  "main": "dist/index.js",