astro-tractstack 2.0.20 → 2.0.21

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.
@@ -1,4 +1,4 @@
1
- import { useState, useMemo } from 'react';
1
+ import { useState, useEffect, useMemo, useRef } from 'react';
2
2
  import { useStore } from '@nanostores/react';
3
3
  import {
4
4
  Dialog,
@@ -59,7 +59,6 @@ const TemplatePreviewItem = ({
59
59
  } | null>(null);
60
60
 
61
61
  const fragmentRequest = useMemo((): PanePreviewRequest[] => {
62
- // This preview logic is correct: it creates a *temporary* context.
63
62
  const ctx = new NodesContext();
64
63
  ctx.addNode(createEmptyStorykeep('tmp'));
65
64
  ctx.addTemplatePane('tmp', template);
@@ -145,6 +144,7 @@ export const RestylePaneModal = () => {
145
144
  keys: ['isRestyleModalOpen', 'paneToRestyleId'],
146
145
  });
147
146
  const designLibrary = brandConfigStore.get()?.DESIGN_LIBRARY || [];
147
+ const contentRef = useRef<HTMLDivElement>(null);
148
148
 
149
149
  const [selectedCategory, setSelectedCategory] = useState<string>('all');
150
150
  const [searchTerm, setSearchTerm] = useState('');
@@ -157,6 +157,33 @@ export const RestylePaneModal = () => {
157
157
  return ['all', ...Array.from(allCategories)];
158
158
  }, [designLibrary]);
159
159
 
160
+ const [targetMarkdownCount, setTargetMarkdownCount] = useState<number>(0);
161
+
162
+ useEffect(() => {
163
+ if (!paneToRestyleId || !isRestyleModalOpen) {
164
+ setTargetMarkdownCount(0);
165
+ return;
166
+ }
167
+ const paneChildIds = ctx.getChildNodeIDs(paneToRestyleId);
168
+ const nodesMap = ctx.allNodes.get();
169
+ const gridNodeId = paneChildIds.find(
170
+ (id) => nodesMap.get(id)?.nodeType === 'GridLayoutNode'
171
+ );
172
+ if (gridNodeId) {
173
+ const columns = ctx.getChildNodeIDs(gridNodeId);
174
+ setTargetMarkdownCount(columns.length);
175
+ return;
176
+ }
177
+ const markdownNodeId = paneChildIds.find(
178
+ (id) => nodesMap.get(id)?.nodeType === 'Markdown'
179
+ );
180
+ if (markdownNodeId) {
181
+ setTargetMarkdownCount(1);
182
+ return;
183
+ }
184
+ setTargetMarkdownCount(0);
185
+ }, [paneToRestyleId, isRestyleModalOpen]);
186
+
160
187
  const originalPaneData = useMemo(() => {
161
188
  if (!paneToRestyleId) return null;
162
189
  const paneNode = ctx.allNodes.get().get(paneToRestyleId) as PaneNode;
@@ -183,9 +210,10 @@ export const RestylePaneModal = () => {
183
210
  return designLibrary.filter(
184
211
  (entry: DesignLibraryEntry) =>
185
212
  (selectedCategory === 'all' || entry.category === selectedCategory) &&
186
- entry.title.toLowerCase().includes(searchTerm.toLowerCase())
213
+ entry.title.toLowerCase().includes(searchTerm.toLowerCase()) &&
214
+ entry.markdownCount === targetMarkdownCount
187
215
  );
188
- }, [designLibrary, selectedCategory, searchTerm]);
216
+ }, [designLibrary, selectedCategory, searchTerm, targetMarkdownCount]);
189
217
 
190
218
  const paginatedEntries = useMemo(() => {
191
219
  const start = (currentPage - 1) * PAGE_SIZE;
@@ -224,123 +252,64 @@ export const RestylePaneModal = () => {
224
252
  setSelectedCategory('all');
225
253
  };
226
254
 
227
- const handleSelectTemplate = (template: TemplatePane) => {
228
- if (VERBOSE)
229
- console.log(
230
- '%cDEBUG: handleSelectTemplate CLICKED (Hollow & Replace)',
231
- 'color: #00A; font-weight: bold;',
232
- {
233
- templateToApply: template,
234
- originalPaneData: originalPaneData,
235
- }
236
- );
255
+ const handleDialogStateChange = (details: { open: boolean }) => {
256
+ if (!details.open) {
257
+ handleClose();
258
+ }
259
+ };
237
260
 
261
+ const handleSelectTemplate = (template: TemplatePane) => {
238
262
  if (!originalPaneData) {
239
- console.error(
240
- '%cDEBUG: handleSelectTemplate FAILED: originalPaneData is null.',
241
- 'color: red; font-weight: bold;'
242
- );
243
263
  return;
244
264
  }
245
265
 
246
266
  const originalPane = originalPaneData.paneNode;
247
267
  const originalPaneId = originalPane.id;
248
268
 
249
- if (VERBOSE)
250
- console.log(
251
- `%cDEBUG: STEP 1 - HOLLOWING OUT original pane ${originalPaneId}`,
252
- 'color: #A0A; font-weight: bold;'
253
- );
254
- const oldChildrenNodes = ctx
255
- .getChildNodeIDs(originalPaneId)
256
- .map((id) => ctx.allNodes.get().get(id));
257
- if (VERBOSE)
258
- console.log(
259
- '%cDEBUG: Original pane children BEFORE delete:',
260
- oldChildrenNodes
261
- );
262
-
263
- const deletedChildren = ctx.deleteChildren(originalPaneId); // This deletes *children*, not the pane itself
264
-
265
- const childrenAfterDelete = ctx.getChildNodeIDs(originalPaneId);
266
- if (VERBOSE) {
267
- console.log(
268
- `%cDEBUG: Deleted ${deletedChildren.length} old child nodes.`,
269
- 'color: #A0A;'
270
- );
271
- console.log(
272
- `%cDEBUG: Original pane children IDs AFTER delete: [${childrenAfterDelete.join(', ')}]`,
273
- 'color: #A0A;'
274
- );
275
- console.log(
276
- `%cDEBUG: STEP 2 - REFILLING pane with new nodes...`,
277
- 'color: #0A0; font-weight: bold;'
278
- );
279
- }
269
+ ctx.deleteChildren(originalPaneId);
280
270
 
281
271
  const newNodesToAdd: BaseNode[] = [];
282
272
  const newMarkdown = template.markdown as TemplateMarkdown | undefined;
273
+ const newGridLayout = template.gridLayout;
283
274
  const newBgPane = template.bgPane;
284
275
 
285
276
  if (newMarkdown) {
286
- // Re-parent the new Markdown node to the original pane
287
277
  newMarkdown.parentId = originalPaneId;
288
278
  newNodesToAdd.push(newMarkdown);
289
-
290
- // The markdown.nodes are already parented to the newMarkdown.id, which is correct.
291
- // We just need to add them to the context.
292
279
  if (newMarkdown.nodes) {
293
280
  newNodesToAdd.push(...newMarkdown.nodes);
294
281
  }
295
- if (VERBOSE) {
296
- console.log(`%cDEBUG: Prepared new Markdown node:`, newMarkdown);
297
- console.log(
298
- `%cDEBUG: Prepared ${newMarkdown.nodes?.length || 0} new markdown sub-nodes:`,
299
- newMarkdown.nodes
300
- );
282
+ }
283
+
284
+ if (newGridLayout) {
285
+ newGridLayout.parentId = originalPaneId;
286
+ newNodesToAdd.push(newGridLayout);
287
+
288
+ if (newGridLayout.nodes) {
289
+ newGridLayout.nodes.forEach((column) => {
290
+ column.parentId = newGridLayout.id;
291
+ newNodesToAdd.push(column);
292
+
293
+ if (column.nodes) {
294
+ newNodesToAdd.push(...column.nodes);
295
+ }
296
+ });
301
297
  }
302
298
  }
303
299
 
304
300
  if (newBgPane) {
305
- // Re-parent the new BgPane node to the original pane
306
301
  newBgPane.parentId = originalPaneId;
307
302
  newNodesToAdd.push(newBgPane);
308
- if (VERBOSE) console.log(`%cDEBUG: Prepared new BgPane:`, newBgPane);
309
303
  }
310
304
 
311
- ctx.addNodes(newNodesToAdd); // This adds all nodes AND links them in parentNodes map
305
+ ctx.addNodes(newNodesToAdd);
312
306
 
313
- const childrenAfterAdd = ctx.getChildNodeIDs(originalPaneId);
314
- const childrenNodesAfterAdd = childrenAfterAdd.map((id) =>
315
- ctx.allNodes.get().get(id)
316
- );
317
- if (VERBOSE) {
318
- console.log(
319
- `%cDEBUG: Original pane children IDs AFTER add: [${childrenAfterAdd.join(', ')}]`,
320
- 'color: #0A0;'
321
- );
322
- console.log(
323
- `%cDEBUG: Original pane children nodes AFTER add:`,
324
- childrenNodesAfterAdd
325
- );
326
- console.log(
327
- `%cDEBUG: STEP 3 - UPDATING original pane properties...`,
328
- 'color: #00F; font-weight: bold;'
329
- );
330
- }
331
-
332
- // We must get a fresh reference from the store to modify
333
307
  const paneToUpdate = ctx.allNodes.get().get(originalPaneId) as PaneNode;
334
308
 
335
309
  if (!paneToUpdate) {
336
- console.error(
337
- `%cDEBUG: FAILED TO FIND PANE ${originalPaneId} IN STORE FOR FINAL UPDATE.`,
338
- 'color: red; font-weight: bold;'
339
- );
340
310
  return;
341
311
  }
342
312
 
343
- // Copy all style/config properties from the template, but keep the original ID, parentId, slug, title
344
313
  paneToUpdate.bgColour = template.bgColour;
345
314
  paneToUpdate.isDecorative = template.isDecorative;
346
315
  paneToUpdate.heightOffsetDesktop = template.heightOffsetDesktop;
@@ -349,25 +318,9 @@ export const RestylePaneModal = () => {
349
318
  paneToUpdate.heightRatioDesktop = template.heightRatioDesktop;
350
319
  paneToUpdate.heightRatioMobile = template.heightRatioMobile;
351
320
  paneToUpdate.heightRatioTablet = template.heightRatioTablet;
352
- paneToUpdate.isChanged = true; // Mark as dirty
353
-
354
- if (VERBOSE)
355
- console.log(
356
- `%cDEBUG: Calling modifyNodes with this pane object:`,
357
- paneToUpdate
358
- );
359
- ctx.modifyNodes([paneToUpdate]); // This will save the changes and notify the UI
321
+ paneToUpdate.isChanged = true;
360
322
 
361
- if (VERBOSE) {
362
- console.log(
363
- '%cDEBUG: handleSelectTemplate FINISHED.',
364
- 'color: #00A; font-weight: bold;'
365
- );
366
- console.log(
367
- '%cDEBUG: Notifying ROOT_NODE to force re-render.',
368
- 'color: green; font-weight: bold;'
369
- );
370
- }
323
+ ctx.modifyNodes([paneToUpdate]);
371
324
  ctx.notifyNode('root');
372
325
 
373
326
  handleClose();
@@ -394,176 +347,179 @@ export const RestylePaneModal = () => {
394
347
  );
395
348
 
396
349
  return (
397
- <Dialog.Root open={isRestyleModalOpen} onOpenChange={handleClose} modal>
398
- <Portal>
399
- <Dialog.Backdrop className="z-103 fixed inset-0 bg-black/70" />
400
- <Dialog.Positioner className="z-104 fixed inset-0 flex items-center justify-center">
401
- <Dialog.Content
402
- className="flex flex-col rounded-lg bg-white shadow-2xl"
403
- style={{ maxHeight: '90vw', width: '90vw' }}
404
- >
405
- <header className="flex items-center justify-between border-b p-4">
406
- <Dialog.Title className="text-xl font-bold">
407
- Restyle Pane from Design Library
408
- </Dialog.Title>
409
- <Dialog.CloseTrigger
410
- type="button"
411
- className="rounded-full p-1 text-gray-600 hover:bg-gray-100"
412
- >
413
- <XMarkIcon className="h-6 w-6" />
414
- </Dialog.CloseTrigger>
415
- </header>
416
-
417
- <nav className="flex items-center gap-x-4 border-b bg-gray-50 p-4">
418
- <Select.Root
419
- collection={selectCollection}
420
- value={[selectedCategory]}
421
- onValueChange={(details: SelectValueChangeDetails) =>
422
- setSelectedCategory(details.value[0])
350
+ <Dialog.Root
351
+ open={isRestyleModalOpen}
352
+ onOpenChange={handleDialogStateChange}
353
+ modal={false}
354
+ >
355
+ <Dialog.Backdrop className="z-103 fixed inset-0 bg-black/70" />
356
+ <Dialog.Positioner className="z-104 fixed inset-0 flex items-center justify-center">
357
+ <Dialog.Content
358
+ ref={contentRef}
359
+ className="flex flex-col rounded-lg bg-white shadow-2xl"
360
+ style={{ maxHeight: '90vw', width: '90vw' }}
361
+ >
362
+ <header className="flex items-center justify-between border-b p-4">
363
+ <Dialog.Title className="text-xl font-bold">
364
+ Restyle Pane from Design Library
365
+ </Dialog.Title>
366
+ <Dialog.CloseTrigger
367
+ type="button"
368
+ className="rounded-full p-1 text-gray-600 hover:bg-gray-100"
369
+ >
370
+ <XMarkIcon className="h-6 w-6" />
371
+ </Dialog.CloseTrigger>
372
+ </header>
373
+
374
+ <nav className="flex items-center gap-x-4 border-b bg-gray-50 p-4">
375
+ <Select.Root
376
+ collection={selectCollection}
377
+ value={[selectedCategory]}
378
+ onValueChange={(details: SelectValueChangeDetails) =>
379
+ setSelectedCategory(details.value[0])
380
+ }
381
+ className="w-48"
382
+ positioning={{ gutter: 4 }}
383
+ >
384
+ <Select.Label className="mb-1 text-sm font-bold">
385
+ Category
386
+ </Select.Label>
387
+ <Select.Control>
388
+ <Select.Trigger className="flex w-full items-center justify-between rounded border bg-white p-2 text-left">
389
+ <Select.ValueText />
390
+ <Select.Indicator>▼</Select.Indicator>
391
+ </Select.Trigger>
392
+ </Select.Control>
393
+ <Portal>
394
+ <Select.Positioner>
395
+ <Select.Content className="z-105 rounded border bg-white shadow-lg">
396
+ {categories.map((c) => (
397
+ <Select.Item
398
+ key={c}
399
+ item={{ label: c, value: c }}
400
+ className="cursor-pointer p-2 hover:bg-gray-100"
401
+ >
402
+ <Select.ItemText>{c}</Select.ItemText>
403
+ </Select.Item>
404
+ ))}
405
+ </Select.Content>
406
+ </Select.Positioner>
407
+ </Portal>
408
+ </Select.Root>
409
+
410
+ <Combobox.Root
411
+ collection={comboboxCollection}
412
+ onInputValueChange={(e: ComboboxInputValueChangeDetails) =>
413
+ setSearchTerm(e.inputValue)
414
+ }
415
+ className="flex-1"
416
+ positioning={{ gutter: 4 }}
417
+ >
418
+ <Combobox.Label className="mb-1 text-sm font-bold">
419
+ Filter by Title
420
+ </Combobox.Label>
421
+ <Combobox.Control>
422
+ <Combobox.Input
423
+ placeholder="Search by title..."
424
+ className="w-full rounded border p-2"
425
+ />
426
+ </Combobox.Control>
427
+ <Portal>
428
+ <Combobox.Positioner>
429
+ <Combobox.Content className="z-105 rounded border bg-white shadow-lg">
430
+ {filteredEntries.map((entry: DesignLibraryEntry) => (
431
+ <Combobox.Item
432
+ key={entry.title}
433
+ item={entry}
434
+ className="cursor-pointer p-2 hover:bg-gray-100"
435
+ >
436
+ <Combobox.ItemText>{entry.title}</Combobox.ItemText>
437
+ </Combobox.Item>
438
+ ))}
439
+ </Combobox.Content>
440
+ </Combobox.Positioner>
441
+ </Portal>
442
+ </Combobox.Root>
443
+ </nav>
444
+
445
+ <main className="flex-1 overflow-y-auto bg-gray-100 p-6">
446
+ {mergedTemplates.length === 0 ? (
447
+ <div className="flex h-full items-center justify-center">
448
+ <p className="text-gray-500">No designs found.</p>
449
+ </div>
450
+ ) : (
451
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
452
+ {mergedTemplates.map(({ template }) => (
453
+ <TemplatePreviewItem
454
+ key={template.id}
455
+ template={template}
456
+ onClick={() => handleSelectTemplate(template)}
457
+ />
458
+ ))}
459
+ </div>
460
+ )}
461
+ </main>
462
+
463
+ {totalPages > 1 && (
464
+ <footer className="flex items-center justify-center border-t p-4">
465
+ <Pagination.Root
466
+ count={totalPages * PAGE_SIZE}
467
+ pageSize={PAGE_SIZE}
468
+ siblingCount={1}
469
+ page={currentPage}
470
+ onPageChange={(details: PaginationPageChangeDetails) =>
471
+ setCurrentPage(details.page)
423
472
  }
424
- className="w-48"
425
- positioning={{ gutter: 4 }}
473
+ className="flex items-center gap-x-2"
426
474
  >
427
- <Select.Label className="mb-1 text-sm font-bold">
428
- Category
429
- </Select.Label>
430
- <Select.Control>
431
- <Select.Trigger className="flex w-full items-center justify-between rounded border bg-white p-2 text-left">
432
- <Select.ValueText />
433
- <Select.Indicator>▼</Select.Indicator>
434
- </Select.Trigger>
435
- </Select.Control>
436
- <Portal>
437
- <Select.Positioner>
438
- <Select.Content className="z-105 rounded border bg-white shadow-lg">
439
- {categories.map((c) => (
440
- <Select.Item
441
- key={c}
442
- item={{ label: c, value: c }}
443
- className="cursor-pointer p-2 hover:bg-gray-100"
475
+ <Pagination.PrevTrigger
476
+ type="button"
477
+ className="rounded p-2 text-sm hover:bg-gray-100 disabled:text-gray-400"
478
+ disabled={currentPage === 1}
479
+ >
480
+ Previous
481
+ </Pagination.PrevTrigger>
482
+ <Pagination.Context>
483
+ {(pagination) =>
484
+ pagination.pages.map((page, index: number) =>
485
+ page.type === 'page' ? (
486
+ <Pagination.Item
487
+ key={index}
488
+ {...page}
489
+ type="page"
490
+ className={classNames(
491
+ 'flex h-9 w-9 items-center justify-center rounded text-sm',
492
+ page.value === currentPage
493
+ ? 'bg-blue-600 font-bold text-white'
494
+ : 'hover:bg-gray-100'
495
+ )}
444
496
  >
445
- <Select.ItemText>{c}</Select.ItemText>
446
- </Select.Item>
447
- ))}
448
- </Select.Content>
449
- </Select.Positioner>
450
- </Portal>
451
- </Select.Root>
452
-
453
- <Combobox.Root
454
- collection={comboboxCollection}
455
- onInputValueChange={(e: ComboboxInputValueChangeDetails) =>
456
- setSearchTerm(e.inputValue)
457
- }
458
- className="flex-1"
459
- positioning={{ gutter: 4 }}
460
- >
461
- <Combobox.Label className="mb-1 text-sm font-bold">
462
- Filter by Title
463
- </Combobox.Label>
464
- <Combobox.Control>
465
- <Combobox.Input
466
- placeholder="Search by title..."
467
- className="w-full rounded border p-2"
468
- />
469
- </Combobox.Control>
470
- <Portal>
471
- <Combobox.Positioner>
472
- <Combobox.Content className="z-105 rounded border bg-white shadow-lg">
473
- {filteredEntries.map((entry: DesignLibraryEntry) => (
474
- <Combobox.Item
475
- key={entry.title}
476
- item={entry}
477
- className="cursor-pointer p-2 hover:bg-gray-100"
497
+ {page.value}
498
+ </Pagination.Item>
499
+ ) : (
500
+ <Pagination.Ellipsis
501
+ key={index}
502
+ index={index}
503
+ className="px-2 text-sm"
478
504
  >
479
- <Combobox.ItemText>{entry.title}</Combobox.ItemText>
480
- </Combobox.Item>
481
- ))}
482
- </Combobox.Content>
483
- </Combobox.Positioner>
484
- </Portal>
485
- </Combobox.Root>
486
- </nav>
487
-
488
- <main className="flex-1 overflow-y-auto bg-gray-100 p-6">
489
- {mergedTemplates.length === 0 ? (
490
- <div className="flex h-full items-center justify-center">
491
- <p className="text-gray-500">No designs found.</p>
492
- </div>
493
- ) : (
494
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
495
- {mergedTemplates.map(({ template }) => (
496
- <TemplatePreviewItem
497
- key={template.id}
498
- template={template}
499
- onClick={() => handleSelectTemplate(template)}
500
- />
501
- ))}
502
- </div>
503
- )}
504
- </main>
505
-
506
- {totalPages > 1 && (
507
- <footer className="flex items-center justify-center border-t p-4">
508
- <Pagination.Root
509
- count={totalPages * PAGE_SIZE}
510
- pageSize={PAGE_SIZE}
511
- siblingCount={1}
512
- page={currentPage}
513
- onPageChange={(details: PaginationPageChangeDetails) =>
514
- setCurrentPage(details.page)
505
+ ...
506
+ </Pagination.Ellipsis>
507
+ )
508
+ )
515
509
  }
516
- className="flex items-center gap-x-2"
510
+ </Pagination.Context>
511
+ <Pagination.NextTrigger
512
+ type="button"
513
+ className="rounded p-2 text-sm hover:bg-gray-100 disabled:text-gray-400"
514
+ disabled={currentPage === totalPages}
517
515
  >
518
- <Pagination.PrevTrigger
519
- type="button"
520
- className="rounded p-2 text-sm hover:bg-gray-100 disabled:text-gray-400"
521
- disabled={currentPage === 1}
522
- >
523
- Previous
524
- </Pagination.PrevTrigger>
525
- <Pagination.Context>
526
- {(pagination) =>
527
- pagination.pages.map((page, index: number) =>
528
- page.type === 'page' ? (
529
- <Pagination.Item
530
- key={index}
531
- {...page}
532
- type="page"
533
- className={classNames(
534
- 'flex h-9 w-9 items-center justify-center rounded text-sm',
535
- page.value === currentPage
536
- ? 'bg-blue-600 font-bold text-white'
537
- : 'hover:bg-gray-100'
538
- )}
539
- >
540
- {page.value}
541
- </Pagination.Item>
542
- ) : (
543
- <Pagination.Ellipsis
544
- key={index}
545
- index={index}
546
- className="px-2 text-sm"
547
- >
548
- ...
549
- </Pagination.Ellipsis>
550
- )
551
- )
552
- }
553
- </Pagination.Context>
554
- <Pagination.NextTrigger
555
- type="button"
556
- className="rounded p-2 text-sm hover:bg-gray-100 disabled:text-gray-400"
557
- disabled={currentPage === totalPages}
558
- >
559
- Next
560
- </Pagination.NextTrigger>
561
- </Pagination.Root>
562
- </footer>
563
- )}
564
- </Dialog.Content>
565
- </Dialog.Positioner>
566
- </Portal>
516
+ Next
517
+ </Pagination.NextTrigger>
518
+ </Pagination.Root>
519
+ </footer>
520
+ )}
521
+ </Dialog.Content>
522
+ </Dialog.Positioner>
567
523
  </Dialog.Root>
568
524
  );
569
525
  };
@@ -30,7 +30,6 @@ import { classNames } from '@/utils/helpers';
30
30
 
31
31
  const PAGE_SIZE = 12;
32
32
 
33
- // --- Sub-component for rendering a single preview item ---
34
33
  interface TemplatePreviewItemProps {
35
34
  storageTemplate: StoragePane;
36
35
  onClick: () => void;
@@ -224,7 +223,6 @@ export const DesignLibraryStep = ({ onSelect }: DesignLibraryStepProps) => {
224
223
  2. Choose a Design
225
224
  </label>
226
225
 
227
- {/* --- Filters --- */}
228
226
  <nav className="flex items-center gap-x-4 rounded-md border bg-white p-3">
229
227
  <Select.Root
230
228
  collection={selectCollection}
@@ -1,6 +1,7 @@
1
1
  import { useState, useMemo, useEffect } from 'react';
2
2
  import { CheckIcon } from '@heroicons/react/20/solid';
3
3
  import { savePaneToLibrary } from '@/utils/compositor/designLibraryHelper';
4
+ import { convertToBackendFormat } from '@/utils/api/brandHelpers';
4
5
  import StringInput from '@/components/form/StringInput';
5
6
  import { brandConfigStore } from '@/stores/storykeep';
6
7
 
@@ -87,8 +88,9 @@ export function SaveToLibraryModal({
87
88
  formData
88
89
  );
89
90
  if (newBrandConfig) {
91
+ const backendDTO = convertToBackendFormat(newBrandConfig);
90
92
  brandConfigStore.set({
91
- ...newBrandConfig,
93
+ ...backendDTO, // Use the converted DTO
92
94
  TENANT_ID: brandConfig.TENANT_ID,
93
95
  });
94
96
  setSaveState('saved');