payaza-storefront-layouts 1.0.39 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor/payaza-form/PayazaFormEditor.d.ts.map +1 -1
- package/dist/editor/payaza-form/PayazaFormEditor.js +177 -17
- package/dist/editor/payaza-form/PayazaFormEditorFullPage.d.ts +3 -0
- package/dist/editor/payaza-form/PayazaFormEditorFullPage.d.ts.map +1 -1
- package/dist/editor/payaza-form/PayazaFormEditorFullPage.js +2 -1
- package/dist/editor/payaza-form/components/SectionField.js +1 -1
- package/dist/editor/payaza-form/data-merger.d.ts +6 -2
- package/dist/editor/payaza-form/data-merger.d.ts.map +1 -1
- package/dist/editor/payaza-form/data-merger.js +64 -51
- package/dist/editor/shared/AIGenerateModal.js +1 -1
- package/dist/editor/shared/EditorHeader.d.ts +7 -0
- package/dist/editor/shared/EditorHeader.d.ts.map +1 -1
- package/dist/editor/shared/EditorHeader.js +45 -9
- package/dist/editor/shared/IframePreview.d.ts.map +1 -1
- package/dist/editor/shared/IframePreview.js +5 -1
- package/dist/editor/types.d.ts +12 -0
- package/dist/editor/types.d.ts.map +1 -1
- package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -1
- package/dist/layouts/shared/components/StoreHeader.js +24 -7
- package/dist/styles/index.css +41 -29
- package/package.json +1 -1
|
@@ -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;
|
|
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
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
267
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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-
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
//
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
|
318
|
-
//
|
|
319
|
-
|
|
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
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
mergedPageData[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
|
|
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,
|
|
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 {
|
|
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-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
}
|
package/dist/editor/types.d.ts
CHANGED
|
@@ -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":"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,
|
|
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
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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-
|
|
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);
|
package/dist/styles/index.css
CHANGED
|
@@ -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));
|