@umituz/web-canvas 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/CanvasConfig-pzoE0RHD.d.mts +310 -0
  2. package/dist/CanvasConfig-pzoE0RHD.d.ts +310 -0
  3. package/dist/application/index.d.mts +78 -0
  4. package/dist/application/index.d.ts +78 -0
  5. package/dist/application/index.js +1083 -0
  6. package/dist/application/index.mjs +11 -0
  7. package/dist/chunk-BN7JTXL7.mjs +346 -0
  8. package/dist/chunk-MC6PNV2F.mjs +34 -0
  9. package/dist/chunk-SF6WND7M.mjs +547 -0
  10. package/dist/chunk-TZGTTYTZ.mjs +0 -0
  11. package/dist/chunk-WMKPCJFI.mjs +661 -0
  12. package/dist/chunk-Z6IB4BQV.mjs +31 -0
  13. package/dist/domain/config/index.d.mts +87 -0
  14. package/dist/domain/config/index.d.ts +87 -0
  15. package/dist/domain/config/index.js +92 -0
  16. package/dist/domain/config/index.mjs +15 -0
  17. package/dist/domain/index.d.mts +79 -0
  18. package/dist/domain/index.d.ts +79 -0
  19. package/dist/domain/index.js +137 -0
  20. package/dist/domain/index.mjs +55 -0
  21. package/dist/index.d.mts +6 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +1633 -0
  24. package/dist/index.mjs +38 -0
  25. package/dist/infrastructure/index.d.mts +174 -0
  26. package/dist/infrastructure/index.d.ts +174 -0
  27. package/dist/infrastructure/index.js +714 -0
  28. package/dist/infrastructure/index.mjs +13 -0
  29. package/dist/presentation/index.d.mts +108 -0
  30. package/dist/presentation/index.d.ts +108 -0
  31. package/dist/presentation/index.js +1617 -0
  32. package/dist/presentation/index.mjs +14 -0
  33. package/package.json +86 -0
  34. package/src/application/index.ts +7 -0
  35. package/src/application/services/ReportService.ts +200 -0
  36. package/src/application/services/ScreenshotStudioService.ts +243 -0
  37. package/src/domain/config/CanvasConfig.ts +36 -0
  38. package/src/domain/config/DeviceConfig.ts +47 -0
  39. package/src/domain/config/ScreenshotStudioConfig.ts +82 -0
  40. package/src/domain/config/index.ts +8 -0
  41. package/src/domain/index.ts +7 -0
  42. package/src/domain/types/canvas.types.ts +85 -0
  43. package/src/domain/types/index.ts +8 -0
  44. package/src/domain/types/report.types.ts +83 -0
  45. package/src/domain/types/screenshot.types.ts +238 -0
  46. package/src/index.ts +102 -0
  47. package/src/infrastructure/index.ts +9 -0
  48. package/src/infrastructure/renderers/CanvasRenderer.ts +287 -0
  49. package/src/infrastructure/renderers/PatternRenderer.ts +160 -0
  50. package/src/infrastructure/renderers/ScreenshotRenderer.ts +331 -0
  51. package/src/infrastructure/services/DeviceConfigService.ts +144 -0
  52. package/src/presentation/hooks/useCanvasExport.ts +162 -0
  53. package/src/presentation/hooks/useReportExport.ts +161 -0
  54. package/src/presentation/hooks/useScreenshotStudio.ts +480 -0
  55. package/src/presentation/index.ts +8 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * useReportExport Hook
3
+ * React hook for report export operations
4
+ */
5
+
6
+ import { useState, useCallback } from 'react';
7
+ import type { ReportData } from '../../domain/types/report.types';
8
+ import type {
9
+ PDFExportOptions,
10
+ ExcelExportOptions,
11
+ } from '../../domain/types/report.types';
12
+ import { ReportService } from '../../application/services/ReportService';
13
+
14
+ /**
15
+ * useReportExport hook return
16
+ */
17
+ export interface UseReportExportReturn {
18
+ isExporting: boolean;
19
+ error: string | null;
20
+ exportToPDF: (
21
+ elementId: string,
22
+ options?: PDFExportOptions
23
+ ) => Promise<void>;
24
+ exportCanvasToPDF: (
25
+ canvas: HTMLCanvasElement,
26
+ options?: PDFExportOptions
27
+ ) => Promise<void>;
28
+ exportMultipleToPDF: (
29
+ elementIds: string[],
30
+ options?: PDFExportOptions
31
+ ) => Promise<void>;
32
+ exportToExcel: (
33
+ data: ReportData,
34
+ options?: ExcelExportOptions
35
+ ) => Promise<void>;
36
+ exportToCSV: (
37
+ data: ReportData,
38
+ filename?: string,
39
+ delimiter?: ',' | ';'
40
+ ) => void;
41
+ }
42
+
43
+ /**
44
+ * useReportExport hook
45
+ */
46
+ export function useReportExport(): UseReportExportReturn {
47
+ const [isExporting, setIsExporting] = useState(false);
48
+ const [error, setError] = useState<string | null>(null);
49
+
50
+ const reportService = ReportService.getInstance();
51
+
52
+ const exportToPDF = useCallback(
53
+ async (elementId: string, options?: PDFExportOptions): Promise<void> => {
54
+ setIsExporting(true);
55
+ setError(null);
56
+
57
+ try {
58
+ await reportService.exportToPDF(elementId, options);
59
+ } catch (err) {
60
+ const errorMessage =
61
+ err instanceof Error ? err.message : 'PDF export failed';
62
+ setError(errorMessage);
63
+ throw err;
64
+ } finally {
65
+ setIsExporting(false);
66
+ }
67
+ },
68
+ [reportService]
69
+ );
70
+
71
+ const exportCanvasToPDF = useCallback(
72
+ async (
73
+ canvas: HTMLCanvasElement,
74
+ options?: PDFExportOptions
75
+ ): Promise<void> => {
76
+ setIsExporting(true);
77
+ setError(null);
78
+
79
+ try {
80
+ await reportService.exportCanvasToPDF(canvas, options);
81
+ } catch (err) {
82
+ const errorMessage =
83
+ err instanceof Error ? err.message : 'Canvas PDF export failed';
84
+ setError(errorMessage);
85
+ throw err;
86
+ } finally {
87
+ setIsExporting(false);
88
+ }
89
+ },
90
+ [reportService]
91
+ );
92
+
93
+ const exportMultipleToPDF = useCallback(
94
+ async (
95
+ elementIds: string[],
96
+ options?: PDFExportOptions
97
+ ): Promise<void> => {
98
+ setIsExporting(true);
99
+ setError(null);
100
+
101
+ try {
102
+ await reportService.exportMultipleToPDF(elementIds, options);
103
+ } catch (err) {
104
+ const errorMessage =
105
+ err instanceof Error ? err.message : 'Multi-page PDF export failed';
106
+ setError(errorMessage);
107
+ throw err;
108
+ } finally {
109
+ setIsExporting(false);
110
+ }
111
+ },
112
+ [reportService]
113
+ );
114
+
115
+ const exportToExcel = useCallback(
116
+ async (data: ReportData, options?: ExcelExportOptions): Promise<void> => {
117
+ setIsExporting(true);
118
+ setError(null);
119
+
120
+ try {
121
+ await reportService.exportToExcel(data, options);
122
+ } catch (err) {
123
+ const errorMessage =
124
+ err instanceof Error ? err.message : 'Excel export failed';
125
+ setError(errorMessage);
126
+ throw err;
127
+ } finally {
128
+ setIsExporting(false);
129
+ }
130
+ },
131
+ [reportService]
132
+ );
133
+
134
+ const exportToCSV = useCallback(
135
+ (
136
+ data: ReportData,
137
+ filename?: string,
138
+ delimiter?: ',' | ';'
139
+ ): void => {
140
+ try {
141
+ reportService.exportToCSV(data, filename, delimiter);
142
+ } catch (err) {
143
+ const errorMessage =
144
+ err instanceof Error ? err.message : 'CSV export failed';
145
+ setError(errorMessage);
146
+ throw err;
147
+ }
148
+ },
149
+ [reportService]
150
+ );
151
+
152
+ return {
153
+ isExporting,
154
+ error,
155
+ exportToPDF,
156
+ exportCanvasToPDF,
157
+ exportMultipleToPDF,
158
+ exportToExcel,
159
+ exportToCSV,
160
+ };
161
+ }
@@ -0,0 +1,480 @@
1
+ /**
2
+ * useScreenshotStudio Hook
3
+ * React hook for screenshot studio functionality
4
+ */
5
+
6
+ import { useState, useCallback, useRef } from 'react';
7
+ import type {
8
+ ScreenshotContent,
9
+ ScreenshotDesign,
10
+ Language,
11
+ DeviceType,
12
+ LayoutStyle,
13
+ FrameStyle,
14
+ AppStoreMetadata,
15
+ ScreenshotProject,
16
+ ScreenshotFormat,
17
+ ScreenshotTemplate,
18
+ } from '../../domain/types/screenshot.types';
19
+ import type { ScreenshotStudioConfig } from '../../domain/config/ScreenshotStudioConfig';
20
+ import { DEFAULT_SCREENSHOT_STUDIO_CONFIG } from '../../domain/config/ScreenshotStudioConfig';
21
+ import { ScreenshotStudioService } from '../../application/services/ScreenshotStudioService';
22
+
23
+ /**
24
+ * useScreenshotStudio hook options
25
+ */
26
+ export interface UseScreenshotStudioOptions {
27
+ config?: Partial<ScreenshotStudioConfig>;
28
+ onShowToast?: (title: string, description?: string) => void;
29
+ }
30
+
31
+ /**
32
+ * useScreenshotStudio hook return
33
+ */
34
+ export interface UseScreenshotStudioReturn {
35
+ // State
36
+ screens: ScreenshotContent[];
37
+ design: ScreenshotDesign;
38
+ currentLanguage: Language;
39
+ selectedScreenId: string;
40
+ activeScreen: ScreenshotContent;
41
+ isProcessing: boolean;
42
+ isAnalyzing: boolean;
43
+ appMetadata: AppStoreMetadata;
44
+ appIcon: string | null;
45
+ projectId: string | null;
46
+
47
+ // Design management
48
+ updateDesign: (updates: Partial<ScreenshotDesign>) => void;
49
+ updateActiveScreen: (updates: Partial<ScreenshotContent>) => void;
50
+ setSelectedScreenId: (screenId: string) => void;
51
+
52
+ // Language management
53
+ changeLanguage: (newLanguage: Language) => void;
54
+
55
+ // Screen management
56
+ addScreen: () => void;
57
+ removeScreen: (screenId: string) => void;
58
+ duplicateScreen: (screenId: string) => void;
59
+
60
+ // Template management
61
+ applyTemplate: (template: ScreenshotTemplate) => void;
62
+
63
+ // Generation
64
+ generateDesignedScreenshot: (
65
+ screenId: string
66
+ ) => Promise<{ url: string; id: string } | undefined>;
67
+
68
+ // Export
69
+ exportAllScreensAsZip: (
70
+ format?: ScreenshotFormat
71
+ ) => Promise<void>;
72
+
73
+ // AI features (if available)
74
+ handleAIMagic?: (screenId: string) => Promise<void>;
75
+ handleTranslate?: (
76
+ screenId: string,
77
+ targetLang: Language
78
+ ) => Promise<void>;
79
+ handleGenerateMetadata?: () => Promise<void>;
80
+
81
+ // Project management
82
+ setAppMetadata: (metadata: AppStoreMetadata) => void;
83
+ setAppIcon: (icon: string | null) => void;
84
+ setProjectId: (id: string | null) => void;
85
+ _getProjectState: () => ScreenshotProject;
86
+ _loadProjectState: (state: Partial<ScreenshotProject>) => void;
87
+ }
88
+
89
+ /**
90
+ * Default screens
91
+ */
92
+ const DEFAULT_SCREENS: ScreenshotContent[] = [
93
+ {
94
+ id: '1',
95
+ title: 'APPGROWTHFACTORY *MODERN*',
96
+ subtitle: 'Create content with AI power',
97
+ screenshot: null,
98
+ translations: {
99
+ 'en-US': {
100
+ title: 'APPGROWTHFACTORY *MODERN*',
101
+ subtitle: 'Create content with AI power',
102
+ },
103
+ 'tr-TR': {
104
+ title: 'APPGROWTHFACTORY *MODERN*',
105
+ subtitle: 'Yapay zeka gücüyle içerik üret',
106
+ },
107
+ },
108
+ imageFit: 'cover',
109
+ imageZoom: 1,
110
+ imageAnchorX: 50,
111
+ imageAnchorY: 50,
112
+ },
113
+ {
114
+ id: '2',
115
+ title: 'CONNECT *GLOBAL*',
116
+ subtitle: 'Post to all platforms instantly',
117
+ screenshot: null,
118
+ translations: {
119
+ 'en-US': {
120
+ title: 'CONNECT *GLOBAL*',
121
+ subtitle: 'Post to all platforms instantly',
122
+ },
123
+ 'tr-TR': {
124
+ title: 'BAĞLAN *KÜRESEL*',
125
+ subtitle: 'Tüm platformlara anında gönder',
126
+ },
127
+ },
128
+ imageFit: 'cover',
129
+ imageZoom: 1,
130
+ imageAnchorX: 50,
131
+ imageAnchorY: 50,
132
+ },
133
+ ];
134
+
135
+ /**
136
+ * Default design
137
+ */
138
+ const DEFAULT_DESIGN: ScreenshotDesign = {
139
+ backgroundColor: '#6366f1',
140
+ backgroundGradientEnd: '#a855f7',
141
+ backgroundImage: null,
142
+ backgroundBlur: 0,
143
+ backgroundOverlayOpacity: 0,
144
+ backgroundPattern: 'none',
145
+ textColor: '#ffffff',
146
+ highlightColor: '#fbbf24',
147
+ textAlign: 'center',
148
+ deviceColor: '#1f2937',
149
+ deviceType: 'iphone-15-pro' as DeviceType,
150
+ frameStyle: 'realistic',
151
+ layout: 'text-top',
152
+ scale: 0.85,
153
+ fontFamily: 'Inter',
154
+ titleFontSize: 60,
155
+ subtitleFontSize: 24,
156
+ titleFontWeight: '900',
157
+ subtitleFontWeight: '500',
158
+ textCase: 'uppercase',
159
+ lineHeight: 0.9,
160
+ letterSpacing: -1,
161
+ rotation: 0,
162
+ rotationX: 0,
163
+ rotationY: 0,
164
+ rotationZ: 0,
165
+ offsetY: 0,
166
+ shadowIntensity: 0.5,
167
+ padding: 40,
168
+ gap: 20,
169
+ isPanoramic: false,
170
+ };
171
+
172
+ /**
173
+ * Default app metadata
174
+ */
175
+ const DEFAULT_APP_METADATA: AppStoreMetadata = {
176
+ appName: 'Growdo',
177
+ subtitle: 'AI Content Generator',
178
+ promotionalText: 'Unlock your creative potential',
179
+ keywords: 'ai, content, marketing, automation, generator',
180
+ description:
181
+ 'The ultimate tool for AI-powered marketing content.',
182
+ whatsNew: 'New Design Studio integration!',
183
+ };
184
+
185
+ /**
186
+ * useScreenshotStudio hook
187
+ */
188
+ export function useScreenshotStudio(
189
+ options: UseScreenshotStudioOptions = {}
190
+ ): UseScreenshotStudioReturn {
191
+ const {
192
+ config = {},
193
+ onShowToast = () => {},
194
+ } = options;
195
+
196
+ const fullConfig = {
197
+ ...DEFAULT_SCREENSHOT_STUDIO_CONFIG,
198
+ ...config,
199
+ };
200
+
201
+ const serviceRef = useRef(
202
+ new ScreenshotStudioService(fullConfig)
203
+ );
204
+
205
+ const [screens, setScreens] = useState<ScreenshotContent[]>(DEFAULT_SCREENS);
206
+ const [design, setDesign] = useState<ScreenshotDesign>(DEFAULT_DESIGN);
207
+ const [currentLanguage, setCurrentLanguage] = useState<Language>(
208
+ fullConfig.defaultLanguage || 'en-US'
209
+ );
210
+ const [selectedScreenId, setSelectedScreenId] = useState<string>('1');
211
+ const [isProcessing, setIsProcessing] = useState(false);
212
+ const [isAnalyzing, setIsAnalyzing] = useState(false);
213
+ const [appMetadata, setAppMetadata] = useState<AppStoreMetadata>(
214
+ DEFAULT_APP_METADATA
215
+ );
216
+ const [appIcon, setAppIcon] = useState<string | null>(null);
217
+ const [projectId, setProjectId] = useState<string | null>(null);
218
+
219
+ const activeScreen =
220
+ screens.find((s) => s.id === selectedScreenId) || screens[0];
221
+
222
+ const updateDesign = useCallback((updates: Partial<ScreenshotDesign>) => {
223
+ setDesign((prev) => ({ ...prev, ...updates }));
224
+ }, []);
225
+
226
+ const updateActiveScreen = useCallback(
227
+ (updates: Partial<ScreenshotContent>) => {
228
+ setScreens((prev) =>
229
+ prev.map((screen) => {
230
+ if (screen.id !== selectedScreenId) return screen;
231
+ const updatedScreen = { ...screen, ...updates };
232
+
233
+ if (updates.title || updates.subtitle) {
234
+ updatedScreen.translations = {
235
+ ...updatedScreen.translations,
236
+ [currentLanguage]: {
237
+ title: updatedScreen.title,
238
+ subtitle: updatedScreen.subtitle,
239
+ },
240
+ };
241
+ }
242
+ return updatedScreen;
243
+ })
244
+ );
245
+ },
246
+ [selectedScreenId, currentLanguage]
247
+ );
248
+
249
+ const changeLanguage = useCallback(
250
+ (newLanguage: Language) => {
251
+ setCurrentLanguage(newLanguage);
252
+ setScreens((prev) =>
253
+ prev.map((screen) => {
254
+ const translation =
255
+ screen.translations[newLanguage] ||
256
+ screen.translations['en-US'] ||
257
+ { title: screen.title, subtitle: screen.subtitle };
258
+ return {
259
+ ...screen,
260
+ title: translation.title,
261
+ subtitle: translation.subtitle,
262
+ };
263
+ })
264
+ );
265
+ onShowToast('Language Changed', `Switched to ${newLanguage}`);
266
+ },
267
+ [onShowToast]
268
+ );
269
+
270
+ const addScreen = useCallback(() => {
271
+ const newScreen: ScreenshotContent = {
272
+ id: Date.now().toString(),
273
+ title: 'NEW *POST*',
274
+ subtitle: 'Engage your audience',
275
+ screenshot: null,
276
+ translations: {
277
+ [currentLanguage]: {
278
+ title: 'NEW *POST*',
279
+ subtitle: 'Engage your audience',
280
+ },
281
+ },
282
+ imageFit: 'cover',
283
+ imageZoom: 1,
284
+ imageAnchorX: 50,
285
+ imageAnchorY: 50,
286
+ };
287
+
288
+ setScreens((prev) => [...prev, newScreen]);
289
+ setSelectedScreenId(newScreen.id);
290
+ onShowToast('Success', 'New screen added');
291
+ }, [currentLanguage, onShowToast]);
292
+
293
+ const removeScreen = useCallback(
294
+ (screenId: string) => {
295
+ if (screens.length <= 1) return;
296
+
297
+ setScreens((prev) => {
298
+ const newScreens = prev.filter((s) => s.id !== screenId);
299
+ if (selectedScreenId === screenId) {
300
+ setSelectedScreenId(newScreens[0].id);
301
+ }
302
+ return newScreens;
303
+ });
304
+
305
+ onShowToast('Info', 'Screen removed');
306
+ },
307
+ [screens.length, selectedScreenId, onShowToast]
308
+ );
309
+
310
+ const duplicateScreen = useCallback(
311
+ (screenId: string) => {
312
+ const screenToDuplicate = screens.find((s) => s.id === screenId);
313
+ if (!screenToDuplicate) return;
314
+
315
+ const newScreen: ScreenshotContent = {
316
+ ...screenToDuplicate,
317
+ id: Date.now().toString(),
318
+ title: `${screenToDuplicate.title} (Copy)`,
319
+ translations: { ...screenToDuplicate.translations },
320
+ };
321
+
322
+ setScreens((prev) => {
323
+ const index = prev.findIndex((s) => s.id === screenId);
324
+ const newScreens = [...prev];
325
+ newScreens.splice(index + 1, 0, newScreen);
326
+ return newScreens;
327
+ });
328
+
329
+ setSelectedScreenId(newScreen.id);
330
+ onShowToast('Success', 'Screen duplicated');
331
+ },
332
+ [screens, onShowToast]
333
+ );
334
+
335
+ const applyTemplate = useCallback(
336
+ (template: ScreenshotTemplate) => {
337
+ setDesign((prev) => ({ ...prev, ...template.design }));
338
+ onShowToast('Template Applied', template.name);
339
+ },
340
+ [onShowToast]
341
+ );
342
+
343
+ const generateDesignedScreenshot = useCallback(
344
+ async (screenId: string) => {
345
+ const screen = screens.find((s) => s.id === screenId);
346
+ if (!screen) return;
347
+
348
+ setIsProcessing(true);
349
+ try {
350
+ const result = await serviceRef.current.generateDesignedScreenshot(
351
+ screen,
352
+ design
353
+ );
354
+ onShowToast('Success', 'Screenshot generated');
355
+ return { url: result.url, id: result.id };
356
+ } catch {
357
+ onShowToast('Error', 'Screenshot generation failed');
358
+ } finally {
359
+ setIsProcessing(false);
360
+ }
361
+ },
362
+ [screens, design, onShowToast]
363
+ );
364
+
365
+ const exportAllScreensAsZip = useCallback(
366
+ async (format: ScreenshotFormat = 'png') => {
367
+ setIsProcessing(true);
368
+ try {
369
+ const project: ScreenshotProject = {
370
+ id: projectId || 'default-project',
371
+ name: 'Export Project',
372
+ design,
373
+ screens,
374
+ currentLanguage,
375
+ selectedScreenId,
376
+ appMetadata,
377
+ appIcon,
378
+ createdAt: new Date(),
379
+ updatedAt: new Date(),
380
+ };
381
+
382
+ const blob = await serviceRef.current.exportProjectAsZip(project);
383
+ const url = URL.createObjectURL(blob);
384
+ const link = document.createElement('a');
385
+ link.href = url;
386
+ link.download = `Studio_${currentLanguage}_${Date.now()}.zip`;
387
+ link.click();
388
+ URL.revokeObjectURL(url);
389
+
390
+ onShowToast(
391
+ 'Success',
392
+ `Exported ${screens.length} screens in ZIP archive.`
393
+ );
394
+ } catch {
395
+ onShowToast('Error', 'ZIP export failed');
396
+ } finally {
397
+ setIsProcessing(false);
398
+ }
399
+ },
400
+ [
401
+ screens,
402
+ design,
403
+ currentLanguage,
404
+ appMetadata,
405
+ appIcon,
406
+ projectId,
407
+ selectedScreenId,
408
+ onShowToast,
409
+ ]
410
+ );
411
+
412
+ const _getProjectState = useCallback((): ScreenshotProject => {
413
+ return {
414
+ id: projectId || 'appgrowthfactory_main_project',
415
+ name: 'Default Project',
416
+ design,
417
+ screens,
418
+ currentLanguage,
419
+ selectedScreenId,
420
+ appMetadata,
421
+ appIcon,
422
+ createdAt: new Date(),
423
+ updatedAt: new Date(),
424
+ };
425
+ }, [
426
+ design,
427
+ screens,
428
+ currentLanguage,
429
+ selectedScreenId,
430
+ appMetadata,
431
+ appIcon,
432
+ projectId,
433
+ ]);
434
+
435
+ const _loadProjectState = useCallback(
436
+ (state: Partial<ScreenshotProject>) => {
437
+ if (!state) return;
438
+ if (state.screens) setScreens(state.screens);
439
+ if (state.design) setDesign(state.design);
440
+ if (state.currentLanguage) setCurrentLanguage(state.currentLanguage);
441
+ if (
442
+ state.selectedScreenId &&
443
+ state.screens?.find((s) => s.id === state.selectedScreenId)
444
+ ) {
445
+ setSelectedScreenId(state.selectedScreenId);
446
+ }
447
+ if (state.appMetadata) setAppMetadata(state.appMetadata);
448
+ if (state.appIcon !== undefined) setAppIcon(state.appIcon);
449
+ },
450
+ []
451
+ );
452
+
453
+ return {
454
+ screens,
455
+ design,
456
+ currentLanguage,
457
+ selectedScreenId,
458
+ activeScreen,
459
+ isProcessing,
460
+ isAnalyzing,
461
+ appMetadata,
462
+ appIcon,
463
+ projectId,
464
+ updateDesign,
465
+ updateActiveScreen,
466
+ setSelectedScreenId,
467
+ changeLanguage,
468
+ applyTemplate,
469
+ addScreen,
470
+ removeScreen,
471
+ duplicateScreen,
472
+ generateDesignedScreenshot,
473
+ exportAllScreensAsZip,
474
+ setAppMetadata,
475
+ setAppIcon,
476
+ setProjectId,
477
+ _getProjectState,
478
+ _loadProjectState,
479
+ };
480
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Presentation Layer Index
3
+ * Export all presentation hooks
4
+ */
5
+
6
+ export * from './hooks/useScreenshotStudio';
7
+ export * from './hooks/useCanvasExport';
8
+ export * from './hooks/useReportExport';