storefront-layouts 1.0.17 → 1.0.19

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 (101) hide show
  1. package/dist/components/ui/category-tree.d.ts +5 -1
  2. package/dist/components/ui/category-tree.d.ts.map +1 -1
  3. package/dist/components/ui/category-tree.js +36 -12
  4. package/dist/components/ui/product-card.d.ts +1 -1
  5. package/dist/components/ui/product-card.d.ts.map +1 -1
  6. package/dist/components/ui/product-card.js +15 -15
  7. package/dist/editor/alignment-schemas/booking.d.ts.map +1 -1
  8. package/dist/editor/alignment-schemas/booking.js +104 -61
  9. package/dist/editor/alignment-schemas/clothing-minimal.d.ts.map +1 -1
  10. package/dist/editor/alignment-schemas/clothing-minimal.js +74 -30
  11. package/dist/editor/alignment-schemas/clothing.d.ts.map +1 -1
  12. package/dist/editor/alignment-schemas/clothing.js +87 -32
  13. package/dist/editor/alignment-schemas/food.d.ts.map +1 -1
  14. package/dist/editor/alignment-schemas/food.js +103 -48
  15. package/dist/editor/payaza-form/PayazaFormEditor.d.ts.map +1 -1
  16. package/dist/editor/payaza-form/PayazaFormEditor.js +13 -1
  17. package/dist/editor/payaza-form/components/ImageField.d.ts.map +1 -1
  18. package/dist/editor/payaza-form/components/ImageField.js +1 -1
  19. package/dist/editor/payaza-form/components/ToggleField.d.ts.map +1 -1
  20. package/dist/editor/payaza-form/components/ToggleField.js +2 -1
  21. package/dist/editor/payaza-form/data-merger.d.ts.map +1 -1
  22. package/dist/editor/payaza-form/data-merger.js +61 -9
  23. package/dist/editor/shared/EditorHeader.d.ts.map +1 -1
  24. package/dist/editor/shared/EditorHeader.js +20 -25
  25. package/dist/editor/shared/IframePreview.d.ts.map +1 -1
  26. package/dist/editor/shared/IframePreview.js +46 -22
  27. package/dist/hooks/use-payaza-checkout.d.ts.map +1 -1
  28. package/dist/hooks/use-payaza-checkout.js +0 -2
  29. package/dist/layouts/booking/components/booking-about-defaults.d.ts +16 -0
  30. package/dist/layouts/booking/components/booking-about-defaults.d.ts.map +1 -1
  31. package/dist/layouts/booking/components/booking-about-defaults.js +171 -1
  32. package/dist/layouts/booking/components/booking-footer-defaults.d.ts +2 -2
  33. package/dist/layouts/booking/components/booking-footer-defaults.d.ts.map +1 -1
  34. package/dist/layouts/booking/components/booking-footer-defaults.js +5 -8
  35. package/dist/layouts/booking/pages/AboutPage.d.ts.map +1 -1
  36. package/dist/layouts/booking/pages/AboutPage.js +51 -35
  37. package/dist/layouts/booking/pages/ContactPage.d.ts.map +1 -1
  38. package/dist/layouts/booking/pages/ContactPage.js +2 -2
  39. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts.map +1 -1
  40. package/dist/layouts/booking-agenda/pages/AboutPage.js +22 -30
  41. package/dist/layouts/booking-agenda/pages/ContactPage.d.ts.map +1 -1
  42. package/dist/layouts/booking-agenda/pages/ContactPage.js +2 -2
  43. package/dist/layouts/clothing/pages/AboutPage.d.ts.map +1 -1
  44. package/dist/layouts/clothing/pages/AboutPage.js +40 -17
  45. package/dist/layouts/clothing/pages/ContactPage.d.ts.map +1 -1
  46. package/dist/layouts/clothing/pages/ContactPage.js +3 -3
  47. package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -1
  48. package/dist/layouts/clothing/pages/ProductsPage.js +18 -4
  49. package/dist/layouts/clothing/styles/clothing.css +28 -1
  50. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts.map +1 -1
  51. package/dist/layouts/clothing-minimal/pages/AboutPage.js +41 -34
  52. package/dist/layouts/clothing-minimal/pages/ContactPage.d.ts.map +1 -1
  53. package/dist/layouts/clothing-minimal/pages/ContactPage.js +2 -2
  54. package/dist/layouts/electronics/components/ElectronicsStoreFooter.d.ts.map +1 -1
  55. package/dist/layouts/electronics/components/ElectronicsStoreFooter.js +1 -1
  56. package/dist/layouts/electronics/pages/AboutPage.d.ts.map +1 -1
  57. package/dist/layouts/electronics/pages/AboutPage.js +13 -25
  58. package/dist/layouts/electronics/pages/ContactPage.d.ts.map +1 -1
  59. package/dist/layouts/electronics/pages/ContactPage.js +2 -2
  60. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -1
  61. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +1 -1
  62. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts.map +1 -1
  63. package/dist/layouts/electronics-grid/pages/AboutPage.js +13 -25
  64. package/dist/layouts/electronics-grid/pages/ContactPage.d.ts.map +1 -1
  65. package/dist/layouts/electronics-grid/pages/ContactPage.js +2 -2
  66. package/dist/layouts/food/pages/AboutPage.d.ts.map +1 -1
  67. package/dist/layouts/food/pages/AboutPage.js +48 -52
  68. package/dist/layouts/food/pages/ContactPage.d.ts.map +1 -1
  69. package/dist/layouts/food/pages/ContactPage.js +2 -2
  70. package/dist/layouts/food-modern/pages/AboutPage.d.ts.map +1 -1
  71. package/dist/layouts/food-modern/pages/AboutPage.js +16 -26
  72. package/dist/layouts/food-modern/pages/ContactPage.d.ts.map +1 -1
  73. package/dist/layouts/food-modern/pages/ContactPage.js +2 -2
  74. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts.map +1 -1
  75. package/dist/layouts/motivational-speaker/pages/AboutPage.js +15 -25
  76. package/dist/layouts/motivational-speaker/pages/ContactPage.d.ts.map +1 -1
  77. package/dist/layouts/motivational-speaker/pages/ContactPage.js +2 -2
  78. package/dist/layouts/shared/about-story-media.d.ts +27 -0
  79. package/dist/layouts/shared/about-story-media.d.ts.map +1 -0
  80. package/dist/layouts/shared/about-story-media.js +46 -0
  81. package/dist/layouts/shared/components/StoreFooter.d.ts.map +1 -1
  82. package/dist/layouts/shared/components/StoreFooter.js +4 -6
  83. package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -1
  84. package/dist/layouts/shared/components/StoreHeader.js +60 -6
  85. package/dist/layouts/shared/pages/CheckoutPage.d.ts.map +1 -1
  86. package/dist/layouts/shared/pages/CheckoutPage.js +0 -78
  87. package/dist/layouts/shared/wrappers/ClothingLayout.d.ts.map +1 -1
  88. package/dist/layouts/shared/wrappers/ClothingLayout.js +17 -0
  89. package/dist/lib/mock-stores.js +1 -1
  90. package/dist/lib/payaza-checkout.d.ts.map +1 -1
  91. package/dist/lib/payaza-checkout.js +0 -33
  92. package/dist/lib/preview-data.d.ts.map +1 -1
  93. package/dist/lib/preview-data.js +3 -2
  94. package/dist/lib/utils/category-tree.d.ts +2 -0
  95. package/dist/lib/utils/category-tree.d.ts.map +1 -1
  96. package/dist/lib/utils/category-tree.js +15 -0
  97. package/dist/lib/utils/footer-nav-defaults.d.ts +11 -2
  98. package/dist/lib/utils/footer-nav-defaults.d.ts.map +1 -1
  99. package/dist/lib/utils/footer-nav-defaults.js +29 -22
  100. package/dist/styles/index.css +203 -212
  101. package/package.json +1 -1
@@ -4,6 +4,13 @@ const sectionStyleSupports = {
4
4
  border: true,
5
5
  typography: true,
6
6
  };
7
+ /** About page blocks use field controls + layout classes; section CSS overrides are not applied. */
8
+ const clothingAboutSectionStyleSupports = {
9
+ spacing: false,
10
+ colors: false,
11
+ border: false,
12
+ typography: false,
13
+ };
7
14
  export const ClothingSchema = {
8
15
  home: {
9
16
  hero: {
@@ -279,46 +286,63 @@ export const ClothingSchema = {
279
286
  type: 'section',
280
287
  label: 'Mission Banner',
281
288
  description: 'The hero section of the about page with your brand mission statement.',
282
- _styleSupports: sectionStyleSupports,
289
+ _styleSupports: clothingAboutSectionStyleSupports,
283
290
  _sourcePath: 'layoutConfig.pages.about.hero',
284
291
  fields: {
285
292
  show: { type: 'toggle', label: 'Display Header', defaultValue: true },
293
+ badgeText: {
294
+ type: 'text',
295
+ label: 'Badge Text',
296
+ description: 'Short label above the headline',
297
+ defaultValue: 'Est. 2024',
298
+ },
299
+ badgeTextColor: {
300
+ type: 'color',
301
+ label: 'Badge Text Colour',
302
+ defaultValue: '#ffffff',
303
+ },
286
304
  heroImage: { type: 'image', label: 'Mission Image', description: 'Large inspirational image for the about page.', defaultValue: 'https://images.unsplash.com/photo-1558769132-cb1aea458c5e?q=80&w=2074&auto=format&fit=crop' },
305
+ imageOverlayColor: {
306
+ type: 'color',
307
+ label: 'Mission Image Overlay',
308
+ description: 'Dark tint over the mission image behind the text.',
309
+ defaultValue: '#000000',
310
+ },
287
311
  title: { type: 'text', label: 'Mission Headline', defaultValue: 'Crafting Experiences, Delivering Joy.' },
288
- missionStatement: { type: 'multiline_text', label: 'Core Mission', description: 'Your brand\'s reason for existence.', defaultValue: 'Empowering individuals through style.' }
312
+ titleColor: {
313
+ type: 'color',
314
+ label: 'Mission Headline Colour',
315
+ defaultValue: '#ffffff',
316
+ },
317
+ missionStatement: { type: 'multiline_text', label: 'Core Mission', description: 'Your brand\'s reason for existence.', defaultValue: 'Empowering individuals through style.' },
318
+ missionStatementColor: {
319
+ type: 'color',
320
+ label: 'Core Mission Colour',
321
+ defaultValue: '#e5e7eb',
322
+ },
289
323
  }
290
324
  },
291
325
  story: {
292
326
  type: 'section',
293
327
  label: 'Brand Journey',
294
328
  description: 'A detailed section for telling your brand\'s history and story.',
295
- _styleSupports: sectionStyleSupports,
329
+ _styleSupports: clothingAboutSectionStyleSupports,
296
330
  _sourcePath: 'layoutConfig.pages.about.story',
297
331
  fields: {
298
332
  show: { type: 'toggle', label: 'Display Story', defaultValue: true },
299
333
  sectionLabel: { type: 'text', label: 'Section Label', description: 'Small label above the title (e.g. "Who We Are").', defaultValue: 'Who We Are' },
300
334
  title: { type: 'text', label: 'Section Title', description: 'Main heading for the story section (e.g. "Our Journey").', defaultValue: 'Our Journey' },
301
335
  content: { type: 'multiline_text', label: 'The Narrative', description: 'Your brand story text.', defaultValue: 'Fashion Hub was born from a desire to create clothing that looks good and feels even better. We believe in sustainable fashion and ethical production practices.' },
302
- storyImage: { type: 'image', label: 'Story / Team Image', description: 'The image shown in the story section when no gallery images are set.', defaultValue: 'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?q=80&w=2071&auto=format&fit=crop' },
336
+ storyImage: { type: 'image', label: 'Story / Team Image', description: 'Image alongside your brand story.', defaultValue: 'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?q=80&w=2071&auto=format&fit=crop' },
303
337
  teamTitle: { type: 'text', label: 'Image Caption Title', description: 'Bold caption over the story image (e.g. "The Dream Team").', defaultValue: 'The Dream Team' },
304
- teamSubtitle: { type: 'text', label: 'Image Caption Subtitle', description: 'Subtitle caption beneath the team title.', defaultValue: 'Working together to serve you better' },
305
- gallerySection: {
306
- type: 'array',
307
- label: 'Brand Gallery',
308
- description: 'A collection of images that represent your brand heritage or workspace. When set, replaces the single story image.',
309
- defaultValue: [],
310
- itemSchema: {
311
- image: { type: 'image', label: 'Gallery Image' },
312
- caption: { type: 'text', label: 'Brief Caption' }
313
- }
314
- }
338
+ teamSubtitle: { type: 'text', label: 'Image Caption Subtitle', description: 'Subtitle caption beneath the team title.', defaultValue: 'Working together to serve you better' }
315
339
  }
316
340
  },
317
341
  stats: {
318
342
  type: 'section',
319
343
  label: 'Milestones & Impact',
320
344
  description: 'Numeric highlights of your brand\'s success and reach.',
321
- _styleSupports: sectionStyleSupports,
345
+ _styleSupports: clothingAboutSectionStyleSupports,
322
346
  _sourcePath: 'layoutConfig.pages.about.stats',
323
347
  fields: {
324
348
  show: { type: 'toggle', label: 'Display Metrics', defaultValue: true },
@@ -326,6 +350,7 @@ export const ClothingSchema = {
326
350
  type: 'array',
327
351
  label: 'Milestone Items',
328
352
  description: 'Each milestone with a value and label.',
353
+ maxSlides: 4,
329
354
  defaultValue: [
330
355
  { value: '20k+', label: 'Style Lovers' },
331
356
  { value: '100+', label: 'New Arrivals' },
@@ -343,30 +368,60 @@ export const ClothingSchema = {
343
368
  type: 'section',
344
369
  label: 'Location & Availability',
345
370
  description: 'Quick reference cards for your store\'s physical presence and hours.',
346
- _styleSupports: sectionStyleSupports,
371
+ _styleSupports: clothingAboutSectionStyleSupports,
347
372
  _sourcePath: 'layoutConfig.pages.about.contact-info',
348
373
  fields: {
349
- show: { type: 'toggle', label: 'Display Section', defaultValue: true },
350
- title: { type: 'text', label: 'Headline', defaultValue: 'Get in Touch' },
351
- description: { type: 'multiline_text', label: 'Supporting Text', defaultValue: "Have questions? We'd love to hear from you. Reach out to our team via email, phone, or visit us at our store." },
352
- visitTitle: { type: 'text', label: 'Visit Card Title', defaultValue: 'Visit Us' },
353
- visitIcon: { type: 'icon', label: 'Visit Card Icon', defaultValue: 'MapPin' },
354
- emailTitle: { type: 'text', label: 'Email Card Title', defaultValue: 'Email Us' },
355
- emailIcon: { type: 'icon', label: 'Email Card Icon', defaultValue: 'Mail' },
356
- hoursTitle: { type: 'text', label: 'Hours Card Title', defaultValue: 'Opening Hours' },
357
- hoursIcon: { type: 'icon', label: 'Hours Card Icon', defaultValue: 'Clock' },
358
- address: { type: 'multiline_text', label: 'Store Address', defaultValue: '123 Store Street\nCommerce City, ST 12345' },
359
- email: { type: 'text', label: 'Primary Email' },
360
- emailSecondary: { type: 'text', label: 'Support Email' },
361
- phone: { type: 'text', label: 'Contact Phone' },
362
- hours: { type: 'multiline_text', label: 'Business Hours', defaultValue: 'Mon - Fri: 9am - 6pm\nSat - Sun: 10am - 4pm' }
374
+ show: { type: 'toggle', label: 'Display section', defaultValue: true },
375
+ title: { type: 'text', label: 'Section headline', defaultValue: 'Get in Touch' },
376
+ description: {
377
+ type: 'multiline_text',
378
+ label: 'Section introduction',
379
+ defaultValue: "Have questions? We'd love to hear from you. Reach out to our team via email, phone, or visit us at our store.",
380
+ },
381
+ visitCard: {
382
+ type: 'object',
383
+ label: 'Visit card',
384
+ fields: {
385
+ title: { type: 'text', label: 'Card title', defaultValue: 'Visit Us' },
386
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'MapPin' },
387
+ address: {
388
+ type: 'multiline_text',
389
+ label: 'Address',
390
+ defaultValue: '123 Store Street\nCommerce City, ST 12345',
391
+ },
392
+ },
393
+ },
394
+ emailCard: {
395
+ type: 'object',
396
+ label: 'Email card',
397
+ fields: {
398
+ title: { type: 'text', label: 'Card title', defaultValue: 'Email Us' },
399
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'Mail' },
400
+ email: { type: 'text', label: 'Primary email' },
401
+ emailSecondary: { type: 'text', label: 'Support email' },
402
+ phone: { type: 'text', label: 'Phone number' },
403
+ },
404
+ },
405
+ hoursCard: {
406
+ type: 'object',
407
+ label: 'Hours card',
408
+ fields: {
409
+ title: { type: 'text', label: 'Card title', defaultValue: 'Opening Hours' },
410
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'Clock' },
411
+ hours: {
412
+ type: 'multiline_text',
413
+ label: 'Opening hours',
414
+ defaultValue: 'Mon - Fri: 9am - 6pm\nSat - Sun: 10am - 4pm',
415
+ },
416
+ },
417
+ },
363
418
  }
364
419
  },
365
420
  values: {
366
421
  type: 'section',
367
422
  label: 'Brand Pillars',
368
423
  description: 'The core values that drive your business decisions.',
369
- _styleSupports: sectionStyleSupports,
424
+ _styleSupports: clothingAboutSectionStyleSupports,
370
425
  _sourcePath: 'layoutConfig.pages.about.values',
371
426
  fields: {
372
427
  show: { type: 'toggle', label: 'Display Values', defaultValue: true },
@@ -1 +1 @@
1
- {"version":3,"file":"food.d.ts","sourceRoot":"","sources":["../../../src/editor/alignment-schemas/food.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AASrE,eAAO,MAAM,UAAU,EAAE,qBAsexB,CAAC"}
1
+ {"version":3,"file":"food.d.ts","sourceRoot":"","sources":["../../../src/editor/alignment-schemas/food.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAgBrE,eAAO,MAAM,UAAU,EAAE,qBAwhBxB,CAAC"}
@@ -4,6 +4,12 @@ const sectionStyleSupports = {
4
4
  border: true,
5
5
  typography: true,
6
6
  };
7
+ const aboutSectionStyleSupports = {
8
+ spacing: false,
9
+ colors: false,
10
+ border: false,
11
+ typography: false,
12
+ };
7
13
  export const FoodSchema = {
8
14
  home: {
9
15
  hero: {
@@ -329,49 +335,57 @@ export const FoodSchema = {
329
335
  about: {
330
336
  aboutHero: {
331
337
  type: 'section',
332
- label: 'About Hero',
333
- description: 'Top banner section of the About page.',
334
- _styleSupports: sectionStyleSupports,
338
+ label: 'Mission banner',
339
+ description: 'Top banner on the about page.',
340
+ _styleSupports: aboutSectionStyleSupports,
335
341
  _sourcePath: 'layoutConfig.pages.about.aboutHero',
336
342
  fields: {
337
- show: { type: 'toggle', label: 'Show Section', defaultValue: true },
338
- title: { type: 'text', label: 'Page Title' },
339
- subtitle: { type: 'multiline_text', label: 'Subtitle / Tagline' },
340
- backgroundImage: { type: 'image', label: 'Hero Background Image' },
341
- showBadge: { type: 'toggle', label: 'Show Badge', defaultValue: true },
342
- badgeText: { type: 'text', label: 'Badge Text', defaultValue: 'Est. 2024' }
343
- }
343
+ show: { type: 'toggle', label: 'Display header', defaultValue: true },
344
+ badgeText: {
345
+ type: 'text',
346
+ label: 'Badge text',
347
+ description: 'Short label above the headline',
348
+ defaultValue: 'Est. 2024',
349
+ },
350
+ badgeTextColor: { type: 'color', label: 'Badge text colour', defaultValue: '#ffffff' },
351
+ title: { type: 'text', label: 'Mission headline' },
352
+ subtitle: { type: 'multiline_text', label: 'Core mission' },
353
+ titleColor: { type: 'color', label: 'Headline colour', defaultValue: '#ffffff' },
354
+ subtitleColor: { type: 'color', label: 'Mission text colour', defaultValue: '#e5e7eb' },
355
+ backgroundImage: { type: 'image', label: 'Mission image' },
356
+ imageOverlayColor: {
357
+ type: 'color',
358
+ label: 'Image overlay',
359
+ defaultValue: '#000000',
360
+ },
361
+ showBadge: { type: 'toggle', label: 'Show badge', defaultValue: true },
362
+ },
344
363
  },
345
364
  ourStory: {
346
365
  type: 'section',
347
- label: 'Our Story',
348
- description: 'Main narrative content for the About page.',
349
- _styleSupports: sectionStyleSupports,
366
+ label: 'Brand journey',
367
+ description: 'Main narrative on the about page.',
368
+ _styleSupports: aboutSectionStyleSupports,
350
369
  _sourcePath: 'layoutConfig.pages.about.ourStory',
351
370
  fields: {
352
- show: { type: 'toggle', label: 'Show Section', defaultValue: true },
353
- label: { type: 'text', label: 'Section Label (e.g. Who We Are)' },
354
- title: { type: 'text', label: 'Main Title' },
355
- content: { type: 'multiline_text', label: 'Story Content' },
356
- image: { type: 'image', label: 'Story / Team Image' },
357
- showGallery: { type: 'toggle', label: 'Show Image Gallery (instead of single image)', defaultValue: false },
358
- galleryImages: {
359
- type: 'array',
360
- label: 'Gallery Images',
361
- itemSchema: {
362
- image: { type: 'image', label: 'Gallery Image' },
363
- caption: { type: 'text', label: 'Caption (optional)' }
364
- }
371
+ show: { type: 'toggle', label: 'Display story', defaultValue: true },
372
+ label: { type: 'text', label: 'Section label', defaultValue: 'Who We Are' },
373
+ title: { type: 'text', label: 'Section title', defaultValue: 'Our Journey' },
374
+ content: { type: 'multiline_text', label: 'The narrative' },
375
+ image: { type: 'image', label: 'Story / team image' },
376
+ teamBadgeTitle: { type: 'text', label: 'Image caption title', defaultValue: 'The Dream Team' },
377
+ teamBadgeSubtitle: {
378
+ type: 'text',
379
+ label: 'Image caption subtitle',
380
+ defaultValue: 'Working together to serve you better',
365
381
  },
366
- teamBadgeTitle: { type: 'text', label: 'Team Badge Title', defaultValue: 'The Dream Team' },
367
- teamBadgeSubtitle: { type: 'text', label: 'Team Badge Subtitle', defaultValue: 'Working together to serve you better' }
368
- }
382
+ },
369
383
  },
370
384
  values: {
371
385
  type: 'section',
372
- label: 'Our Values',
373
- description: 'Core pillars that define your restaurant brand.',
374
- _styleSupports: sectionStyleSupports,
386
+ label: 'Brand pillars',
387
+ description: 'Core pillars beside your story.',
388
+ _styleSupports: aboutSectionStyleSupports,
375
389
  _sourcePath: 'layoutConfig.pages.about.values',
376
390
  fields: {
377
391
  show: { type: 'toggle', label: 'Show Section', defaultValue: true },
@@ -394,15 +408,16 @@ export const FoodSchema = {
394
408
  },
395
409
  statsSection: {
396
410
  type: 'section',
397
- label: 'Key Stats',
398
- description: 'Numeric highlights such as happy customers, menu items, and years of experience.',
399
- _styleSupports: sectionStyleSupports,
411
+ label: 'Milestones & impact',
412
+ description: 'Numeric highlights for your restaurant.',
413
+ _styleSupports: aboutSectionStyleSupports,
400
414
  _sourcePath: 'layoutConfig.pages.about.statsSection',
401
415
  fields: {
402
- show: { type: 'toggle', label: 'Show Section', defaultValue: true },
416
+ show: { type: 'toggle', label: 'Display metrics', defaultValue: true },
403
417
  items: {
404
418
  type: 'array',
405
- label: 'Stat Items',
419
+ label: 'Milestone items',
420
+ maxSlides: 4,
406
421
  defaultValue: [
407
422
  { label: 'Happy Foodies', value: '15k+' },
408
423
  { label: 'Menu Items', value: '40+' },
@@ -418,19 +433,59 @@ export const FoodSchema = {
418
433
  },
419
434
  contactInfoSection: {
420
435
  type: 'section',
421
- label: 'Quick Contact',
422
- description: 'Contact reference cards showing address, email, and opening hours.',
423
- _styleSupports: sectionStyleSupports,
436
+ label: 'Location & availability',
437
+ description: 'Contact cards for address, email, and hours.',
438
+ _styleSupports: aboutSectionStyleSupports,
424
439
  _sourcePath: 'layoutConfig.pages.about.contactInfoSection',
425
440
  fields: {
426
- show: { type: 'toggle', label: 'Show Section', defaultValue: true },
427
- title: { type: 'text', label: 'Section Heading', defaultValue: 'Get in Touch' },
428
- description: { type: 'multiline_text', label: 'Section Description', defaultValue: "Have questions? We'd love to hear from you. Reach out to our team via email, phone, or visit us at our store." },
429
- showAddress: { type: 'toggle', label: 'Show Address Card', defaultValue: true },
430
- showEmail: { type: 'toggle', label: 'Show Email / Phone Card', defaultValue: true },
431
- showHours: { type: 'toggle', label: 'Show Opening Hours Card', defaultValue: true }
432
- }
433
- }
441
+ show: { type: 'toggle', label: 'Display section', defaultValue: true },
442
+ title: { type: 'text', label: 'Section headline', defaultValue: 'Get in Touch' },
443
+ description: {
444
+ type: 'multiline_text',
445
+ label: 'Section introduction',
446
+ defaultValue: "Have questions? We'd love to hear from you. Reach out to our team via email, phone, or visit us at our store.",
447
+ },
448
+ visitCard: {
449
+ type: 'object',
450
+ label: 'Visit card',
451
+ fields: {
452
+ title: { type: 'text', label: 'Card title', defaultValue: 'Visit Us' },
453
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'MapPin' },
454
+ address: {
455
+ type: 'multiline_text',
456
+ label: 'Address',
457
+ defaultValue: '123 Store Street\nCommerce City, ST 12345',
458
+ },
459
+ },
460
+ },
461
+ emailCard: {
462
+ type: 'object',
463
+ label: 'Email card',
464
+ fields: {
465
+ title: { type: 'text', label: 'Card title', defaultValue: 'Email Us' },
466
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'Mail' },
467
+ email: { type: 'text', label: 'Primary email' },
468
+ emailSecondary: { type: 'text', label: 'Support email' },
469
+ phone: { type: 'text', label: 'Phone number', defaultValue: '+1 (555) 123-4567' },
470
+ ctaLabel: { type: 'text', label: 'Button text', defaultValue: 'Send a message' },
471
+ ctaLink: { type: 'text', label: 'Button link', defaultValue: '/contact' },
472
+ },
473
+ },
474
+ hoursCard: {
475
+ type: 'object',
476
+ label: 'Hours card',
477
+ fields: {
478
+ title: { type: 'text', label: 'Card title', defaultValue: 'Opening Hours' },
479
+ icon: { type: 'icon', label: 'Icon', defaultValue: 'Clock' },
480
+ hours: {
481
+ type: 'multiline_text',
482
+ label: 'Opening hours',
483
+ defaultValue: 'Mon - Fri: 9am - 6pm\nSat - Sun: 10am - 4pm',
484
+ },
485
+ },
486
+ },
487
+ },
488
+ },
434
489
  },
435
490
  contact: {
436
491
  contactHeader: {
@@ -1 +1 @@
1
- {"version":3,"file":"PayazaFormEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAoB/C,OAAO,EAA4B,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AA0F5F,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,CAqzD5D,CAAC"}
1
+ {"version":3,"file":"PayazaFormEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/payaza-form/PayazaFormEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAoB/C,OAAO,EAA4B,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AA2F5F,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,CAi0D5D,CAAC"}
@@ -23,6 +23,7 @@ import { IframePreviewMessageBridge } from './IframePreviewMessageBridge.js';
23
23
  import { EditorCanvasPreview } from './EditorCanvasPreview.js';
24
24
  import { awaitPreviewFlushAck } from '../../preview/canvas/preview-flush-await.js';
25
25
  import { BlockStylesInspector } from './components/BlockStylesInspector.js';
26
+ import { resolveStyleSupports } from './payaza-style-sanitize.js';
26
27
  import { CanvasGranularInspector } from './components/CanvasGranularInspector.js';
27
28
  import { SectionSchemaInspector } from './components/SectionSchemaInspector.js';
28
29
  import { isLayoutPageEditable } from '../alignment-schemas/metadata.js';
@@ -658,6 +659,17 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
658
659
  return undefined;
659
660
  return sch._styleSupports;
660
661
  }, [pageSchema, selectedSection]);
662
+ const selectedSectionHasStyleControls = useMemo(() => {
663
+ if (!selectedSection)
664
+ return false;
665
+ const sup = resolveStyleSupports(selectedSectionStyleSupports);
666
+ return Boolean(sup.spacing || sup.colors || sup.border || sup.typography);
667
+ }, [selectedSection, selectedSectionStyleSupports]);
668
+ useEffect(() => {
669
+ if (!selectedSectionHasStyleControls && blockSubTab === 'styles') {
670
+ setBlockSubTab('settings');
671
+ }
672
+ }, [selectedSectionHasStyleControls, blockSubTab]);
661
673
  const selectedBlockStyleEntries = useMemo(() => selectedSection
662
674
  ? getPayazaSectionStyleEntries(data, activePageId, selectedSection)
663
675
  : {}, [data, activePageId, selectedSection]);
@@ -1138,7 +1150,7 @@ export const PayazaFormEditor = ({ layoutId, initialData, inventory, onChange, o
1138
1150
  // Inspector inner content — shared between desktop ResizableSidebar and mobile overlay
1139
1151
  const inspectorContent = (_jsxs("div", { className: "relative flex h-full flex-col bg-[#fbfbfc]", id: "tour-editor-sidebar", children: [_jsxs("div", { "data-payaza-sidebar": "inspector", className: "sticky top-0 z-30 bg-[#fbfbfc]", children: [!isMobileView && (_jsxs("div", { className: "flex min-h-[48px] items-center gap-2 border-b border-[#dcdcde] px-3 py-2", children: [_jsx(Box, { className: `h-4 w-4 shrink-0 ${selectedSection ? 'text-[#440066]' : 'text-[#c3c4c7]'}`, strokeWidth: 2, "aria-hidden": true }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: `truncate text-[12px] font-semibold leading-tight ${selectedSection ? 'text-[#1b0029]' : 'text-[#787c82]'}`, children: selectedSection ? (selectedSectionLabel ?? selectedSection) : 'Block Inspector' }), selectedSection && (_jsx("p", { className: "truncate text-[11px] leading-tight text-[#787c82]", children: pages.find((p) => p.id === activePageId)?.name ?? activePageId }))] })] })), _jsxs("div", { "data-payaza-sidebar-tabs": true, className: "-mb-px flex border-b border-[#dcdcde]", role: "tablist", "aria-label": "Block inspector", children: [_jsxs("button", { type: "button", role: "tab", "aria-selected": blockSubTab === 'settings', title: "Settings", onClick: () => setBlockSubTab('settings'), className: `relative mb-[-1px] flex items-center justify-center gap-1.5 border-b-[3px] px-3 py-2.5 text-[12px] font-semibold transition-colors ${blockSubTab === 'settings'
1140
1152
  ? 'border-[#440066] font-bold text-[#1b0029]'
1141
- : 'border-transparent font-medium text-[#646970] hover:bg-white/70 hover:text-[#1b0029]'}`, children: [_jsx(Settings2, { size: 17, strokeWidth: 2, "aria-hidden": true }), _jsx("span", { children: "Settings" })] }), !isMobileView && (_jsxs("button", { type: "button", role: "tab", "aria-selected": blockSubTab === 'styles', title: "Styles", onClick: () => setBlockSubTab('styles'), className: `relative mb-[-1px] flex items-center justify-center gap-1.5 border-b-[3px] px-3 py-2.5 text-[12px] font-semibold transition-colors ${blockSubTab === 'styles'
1153
+ : 'border-transparent font-medium text-[#646970] hover:bg-white/70 hover:text-[#1b0029]'}`, children: [_jsx(Settings2, { size: 17, strokeWidth: 2, "aria-hidden": true }), _jsx("span", { children: "Settings" })] }), !isMobileView && selectedSectionHasStyleControls && (_jsxs("button", { type: "button", role: "tab", "aria-selected": blockSubTab === 'styles', title: "Styles", onClick: () => setBlockSubTab('styles'), className: `relative mb-[-1px] flex items-center justify-center gap-1.5 border-b-[3px] px-3 py-2.5 text-[12px] font-semibold transition-colors ${blockSubTab === 'styles'
1142
1154
  ? 'border-[#440066] font-bold text-[#1b0029]'
1143
1155
  : 'border-transparent font-medium text-[#646970] hover:bg-white/70 hover:text-[#1b0029]'}`, children: [_jsx(Palette, { size: 17, strokeWidth: 2, "aria-hidden": true }), _jsx("span", { children: "Styles" })] }))] })] }), _jsx("div", { className: "payaza-form-editor custom-scrollbar isolate min-h-0 flex-1 overflow-y-auto scroll-pt-1 bg-white px-2 py-0", children: !selectedSection ? (_jsxs("div", { className: "flex flex-col items-center justify-center px-5 py-16 text-center", children: [_jsx(Box, { className: "mb-3 h-8 w-8 text-[#dcdcde]", strokeWidth: 1.5, "aria-hidden": true }), _jsx("p", { className: "text-[13px] font-semibold text-[#50575e]", children: "No block selected" }), _jsx("p", { className: "mt-1.5 max-w-[200px] text-[12px] leading-relaxed text-[#787c82]", children: "Click on any section in the canvas or select one from the List View." })] })) : blockSubTab === 'styles' && !isMobileView ? (canvasElementFocus?.elementKind === 'group' ? (_jsx(BlockStylesInspector, { supports: { spacing: true, colors: true, border: true, typography: true }, value: rawGroupStyle, onChange: (next) => {
1144
1156
  if (canvasElementFocus) {
@@ -1 +1 @@
1
- {"version":3,"file":"ImageField.d.ts","sourceRoot":"","sources":["../../../../src/editor/payaza-form/components/ImageField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAiHhD,CAAC"}
1
+ {"version":3,"file":"ImageField.d.ts","sourceRoot":"","sources":["../../../../src/editor/payaza-form/components/ImageField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA4GhD,CAAC"}
@@ -19,7 +19,7 @@ export const ImageField = ({ label, value, onChange, placeholder, }) => {
19
19
  onChange(url.trim());
20
20
  }
21
21
  }, [isAssetLibraryAvailable, onOpenAssetSelect, onChange]);
22
- return (_jsxs("div", { className: "group/field flex flex-col gap-2.5", children: [_jsxs("div", { className: "flex items-center justify-between px-0.5", children: [_jsx("label", { className: "text-[11px] font-semibold uppercase tracking-[0.06em] text-[#1b0029]/45 transition-colors group-focus-within/field:text-[#1b0029]/70", children: label }), hasImage && (_jsx("span", { className: "rounded border border-[#440066]/20 bg-[#440066]/08 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wider text-[#440066]", children: "Set" }))] }), _jsxs("div", { className: "space-y-3", children: [hasImage ? (_jsxs("div", { className: "group/img relative flex aspect-[16/9] items-center justify-center overflow-hidden rounded-md border border-black/[0.1] bg-[#fafafa] shadow-[0_1px_2px_rgba(27,0,41,0.04)] transition-colors hover:border-black/[0.14]", onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [_jsx("img", { src: value, alt: label, className: "h-full w-full object-cover transition-transform duration-500 group-hover/img:scale-[1.02]", onError: (e) => {
22
+ return (_jsxs("div", { className: "group/field flex flex-col gap-2.5", children: [_jsx("div", { className: "flex items-center justify-between px-0.5", children: _jsx("label", { className: "text-[11px] font-semibold uppercase tracking-[0.06em] text-[#1b0029]/45 transition-colors group-focus-within/field:text-[#1b0029]/70", children: label }) }), _jsxs("div", { className: "space-y-3", children: [hasImage ? (_jsxs("div", { className: "group/img relative flex aspect-[16/9] items-center justify-center overflow-hidden rounded-md border border-black/[0.1] bg-[#fafafa] shadow-[0_1px_2px_rgba(27,0,41,0.04)] transition-colors hover:border-black/[0.14]", onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [_jsx("img", { src: value, alt: label, className: "h-full w-full object-cover transition-transform duration-500 group-hover/img:scale-[1.02]", onError: (e) => {
23
23
  e.target.style.display = 'none';
24
24
  } }), _jsx("div", { className: `absolute inset-0 flex flex-col items-center justify-center gap-2 bg-[#1b0029]/45 backdrop-blur-[2px] transition-opacity duration-200 ${isHovered ? 'opacity-100' : 'opacity-0'}`, children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onChange(''), className: "flex h-9 w-9 items-center justify-center rounded-md border border-white/40 bg-white/15 text-white transition-colors hover:bg-[#D16253]/90", title: "Remove image", children: _jsx(X, { size: 16, strokeWidth: 2.5 }) }), _jsxs("button", { type: "button", onClick: handleReplace, className: "flex items-center gap-2 rounded-md bg-white px-4 py-2 text-[11px] font-semibold text-[#1b0029] shadow-sm transition-transform hover:scale-[1.02] active:scale-[0.98]", title: isAssetLibraryAvailable ? 'Replace from library' : 'Replace', children: [_jsx(Upload, { size: 14, strokeWidth: 2.5 }), "Replace"] })] }) })] })) : (_jsxs("button", { type: "button", onClick: () => {
25
25
  if (isAssetLibraryAvailable)
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleField.d.ts","sourceRoot":"","sources":["../../../../src/editor/payaza-form/components/ToggleField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAE3C,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAOD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAqCjD,CAAC"}
1
+ {"version":3,"file":"ToggleField.d.ts","sourceRoot":"","sources":["../../../../src/editor/payaza-form/components/ToggleField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAOD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuCjD,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { memo, useId } from 'react';
3
+ import { cn } from '../../../lib/utils/index.js';
3
4
  function coerceBoolean(v) {
4
5
  if (v === true || v === 'true' || v === 1 || v === '1')
5
6
  return true;
@@ -11,5 +12,5 @@ function coerceBoolean(v) {
11
12
  export const ToggleField = memo(({ label, value, onChange }) => {
12
13
  const on = coerceBoolean(value);
13
14
  const id = useId();
14
- return (_jsxs("div", { className: `flex w-full select-none items-center justify-between gap-4 rounded-md border px-3 py-3 transition-colors ${on ? 'border-[#440066]/25 bg-white' : 'border-black/[0.06] bg-[#fafafa] hover:border-black/[0.1]'}`, children: [_jsx("span", { className: "min-w-0 flex-1 text-[12px] font-medium leading-snug text-[#1b0029]", children: label }), _jsxs("label", { htmlFor: id, className: "relative inline-flex h-[22px] w-[38px] shrink-0 cursor-pointer rounded-full outline-none ring-offset-2 focus-within:ring-2 focus-within:ring-[#440066]/40", children: [_jsx("input", { id: id, type: "checkbox", className: "sr-only", checked: on, onChange: (e) => onChange(e.target.checked) }), _jsx("span", { className: `pointer-events-none absolute inset-0 rounded-full transition-colors ${on ? 'bg-[#440066]' : 'bg-[#1b0029]/15'}`, "aria-hidden": true }), _jsx("span", { className: `pointer-events-none absolute top-[2px] left-[3px] h-[18px] w-[18px] rounded-full bg-white shadow-sm transition-transform duration-200 ${on ? 'translate-x-[17px]' : 'translate-x-0'}`, "aria-hidden": true })] })] }));
15
+ return (_jsxs("div", { "data-payaza-toggle": true, className: `flex w-full select-none items-center justify-between gap-4 rounded-md border px-3 py-3 transition-colors ${on ? 'border-[#440066]/25 bg-white' : 'border-black/[0.06] bg-[#fafafa] hover:border-black/[0.1]'}`, children: [_jsx("span", { className: "min-w-0 flex-1 text-[12px] font-medium leading-snug text-[#1b0029]", children: label }), _jsxs("label", { htmlFor: id, "data-payaza-switch": true, className: cn('inline-flex h-6 w-11 shrink-0 cursor-pointer items-center overflow-hidden rounded-full p-0.5 transition-colors outline-none', 'ring-offset-2 focus-within:ring-2 focus-within:ring-[#440066]/40', on ? 'bg-[#440066]' : 'bg-[#1b0029]/15'), children: [_jsx("input", { id: id, type: "checkbox", className: "sr-only", checked: on, onChange: (e) => onChange(e.target.checked) }), _jsx("span", { "data-payaza-switch-thumb": true, className: cn('block h-5 w-5 shrink-0 rounded-full bg-white shadow-sm transition-[margin] duration-200 ease-out', on ? 'ml-auto' : 'ml-0'), "aria-hidden": true })] })] }));
15
16
  });
@@ -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;AA4TpD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,iBAAiB,GAC9B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqerB;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,CAyLnB;AAED;;;GAGG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAmC,GAC3E,iBAAiB,CAMnB;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"}
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;AAoUpD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,iBAAiB,GAC9B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqgBrB;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,CA6NnB;AAED;;;GAGG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,iBAAiB,EAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAmC,GAC3E,iBAAiB,CAMnB;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"}
@@ -2,7 +2,7 @@ import { deepClone } from '../../lib/utils/index.js';
2
2
  import { transformToStoreConfig } from './data-transformer.js';
3
3
  import { ensureClothingMinimalHomeBlocksInPageData } from '../blocks/migrate-clothing-minimal.js';
4
4
  import { BOOKING_DEFAULT_TESTIMONIALS, normalizeBookingTestimonialItems, } from '../../layouts/booking/components/booking-testimonial-defaults.js';
5
- import { BOOKING_DEFAULT_ABOUT_STATS, BOOKING_DEFAULT_ABOUT_VALUES, mergeBookingAboutItemsSection, } from '../../layouts/booking/components/booking-about-defaults.js';
5
+ import { BOOKING_DEFAULT_ABOUT_STATS, BOOKING_DEFAULT_ABOUT_VALUES, CLOTHING_DEFAULT_ABOUT_STATS, CLOTHING_DEFAULT_ABOUT_VALUES, CLOTHING_MINIMAL_DEFAULT_ABOUT_STATS, CLOTHING_MINIMAL_DEFAULT_ABOUT_VALUES, FOOD_DEFAULT_ABOUT_STATS, FOOD_DEFAULT_ABOUT_VALUES, mergeBookingAboutItemsSection, normalizeAboutContactInfoCards, } from '../../layouts/booking/components/booking-about-defaults.js';
6
6
  import { mergeBookingFooterSection } from '../../layouts/booking/components/booking-footer-defaults.js';
7
7
  function sliderHasUsableContent(slider) {
8
8
  if (!slider)
@@ -307,6 +307,21 @@ export function extractActualPageData(storeConfig, pageId, requirement) {
307
307
  (sectionKey === 'hero' || sectionKey === 'team' || sectionKey === 'promoBanner')) {
308
308
  pageDataMap[sectionKey] = enrichBookingSectionImages(sectionKey, deepClone(value), layoutConfig);
309
309
  }
310
+ else if (pageId === 'about' &&
311
+ sectionKey === 'contact-info' &&
312
+ (requirement.layoutId === 'clothing' || requirement.layoutId === 'booking')) {
313
+ pageDataMap[sectionKey] = normalizeAboutContactInfoCards(deepClone(value));
314
+ }
315
+ else if (pageId === 'about' &&
316
+ sectionKey === 'contactInfoSection' &&
317
+ requirement.layoutId === 'food') {
318
+ pageDataMap[sectionKey] = normalizeAboutContactInfoCards(deepClone(value));
319
+ }
320
+ else if (pageId === 'about' &&
321
+ sectionKey === 'contactSection' &&
322
+ requirement.layoutId === 'clothing-minimal') {
323
+ pageDataMap[sectionKey] = normalizeAboutContactInfoCards(deepClone(value));
324
+ }
310
325
  else {
311
326
  pageDataMap[sectionKey] = deepClone(value);
312
327
  }
@@ -605,10 +620,15 @@ export function extractActualPageData(storeConfig, pageId, requirement) {
605
620
  }
606
621
  // Contact-info section (note: key has hyphen, so use bracket notation)
607
622
  if (aboutPage['contact-info'] || layoutSections['contact-info']) {
608
- pageDataMap['contact-info'] = {
623
+ const contactRaw = {
609
624
  show: true,
610
- ...(aboutPage['contact-info'] || layoutSections['contact-info'] || {}),
625
+ ...(layoutSections['contact-info'] || {}),
626
+ ...(aboutPage['contact-info'] || {}),
611
627
  };
628
+ pageDataMap['contact-info'] =
629
+ requirement?.layoutId === 'clothing' || requirement?.layoutId === 'booking'
630
+ ? normalizeAboutContactInfoCards(contactRaw)
631
+ : contactRaw;
612
632
  }
613
633
  // Values section
614
634
  if (aboutPage.values || layoutSections.values) {
@@ -629,7 +649,10 @@ export function extractActualPageData(storeConfig, pageId, requirement) {
629
649
  pageDataMap.statsSection = { show: true, ...aboutPage.statsSection };
630
650
  }
631
651
  if (aboutPage.contactInfoSection) {
632
- pageDataMap.contactInfoSection = { show: true, ...aboutPage.contactInfoSection };
652
+ pageDataMap.contactInfoSection = normalizeAboutContactInfoCards({
653
+ show: true,
654
+ ...(aboutPage.contactInfoSection || {}),
655
+ });
633
656
  }
634
657
  // Clothing-minimal section keys
635
658
  if (aboutPage.aboutHeader || layoutSections.aboutHeader) {
@@ -647,11 +670,11 @@ export function extractActualPageData(storeConfig, pageId, requirement) {
647
670
  };
648
671
  }
649
672
  if (aboutPage.contactSection || layoutSections.contactSection) {
650
- pageDataMap.contactSection = {
673
+ pageDataMap.contactSection = normalizeAboutContactInfoCards({
651
674
  show: true,
652
675
  ...(layoutSections.contactSection || {}),
653
676
  ...(aboutPage.contactSection || {}),
654
- };
677
+ });
655
678
  }
656
679
  // Legacy support for old structure
657
680
  if (layoutSections.aboutHeader)
@@ -771,14 +794,27 @@ export function mergeRequirementWithActualData(requirement, storeConfig, pageId,
771
794
  typeof actualSection === 'object' &&
772
795
  !Array.isArray(requirementSection) &&
773
796
  !Array.isArray(actualSection)) {
774
- mergedPageData[sectionKey] = mergeBookingAboutItemsSection(actualSection, requirementSection, BOOKING_DEFAULT_ABOUT_VALUES);
797
+ mergedPageData[sectionKey] = mergeBookingAboutItemsSection(actualSection, requirementSection, requirement.layoutId === 'clothing'
798
+ ? CLOTHING_DEFAULT_ABOUT_VALUES
799
+ : requirement.layoutId === 'food'
800
+ ? FOOD_DEFAULT_ABOUT_VALUES
801
+ : requirement.layoutId === 'clothing-minimal'
802
+ ? CLOTHING_MINIMAL_DEFAULT_ABOUT_VALUES
803
+ : BOOKING_DEFAULT_ABOUT_VALUES);
775
804
  }
776
- else if (sectionKey === 'stats' &&
805
+ else if ((sectionKey === 'stats' || sectionKey === 'statsSection') &&
777
806
  typeof requirementSection === 'object' &&
778
807
  typeof actualSection === 'object' &&
779
808
  !Array.isArray(requirementSection) &&
780
809
  !Array.isArray(actualSection)) {
781
- mergedPageData[sectionKey] = mergeBookingAboutItemsSection(actualSection, requirementSection, BOOKING_DEFAULT_ABOUT_STATS);
810
+ const statDefaults = requirement.layoutId === 'clothing'
811
+ ? CLOTHING_DEFAULT_ABOUT_STATS
812
+ : requirement.layoutId === 'food'
813
+ ? FOOD_DEFAULT_ABOUT_STATS
814
+ : requirement.layoutId === 'clothing-minimal'
815
+ ? CLOTHING_MINIMAL_DEFAULT_ABOUT_STATS
816
+ : BOOKING_DEFAULT_ABOUT_STATS;
817
+ mergedPageData[sectionKey] = mergeBookingAboutItemsSection(actualSection, requirementSection, statDefaults);
782
818
  }
783
819
  else if (sectionKey === 'footer' &&
784
820
  typeof requirementSection === 'object' &&
@@ -794,6 +830,22 @@ export function mergeRequirementWithActualData(requirement, storeConfig, pageId,
794
830
  !Array.isArray(actualSection)) {
795
831
  mergedPageData[sectionKey] = mergeLookbookImagesWithDefaults(actualSection, requirementSection);
796
832
  }
833
+ else if (sectionKey === 'contact-info' &&
834
+ (requirement.layoutId === 'clothing' || requirement.layoutId === 'booking') &&
835
+ typeof requirementSection === 'object' &&
836
+ typeof actualSection === 'object' &&
837
+ !Array.isArray(requirementSection) &&
838
+ !Array.isArray(actualSection)) {
839
+ mergedPageData[sectionKey] = normalizeAboutContactInfoCards(deepMerge(requirementSection, actualSection));
840
+ }
841
+ else if ((sectionKey === 'contactInfoSection' || sectionKey === 'contactSection') &&
842
+ (requirement.layoutId === 'food' || requirement.layoutId === 'clothing-minimal') &&
843
+ typeof requirementSection === 'object' &&
844
+ typeof actualSection === 'object' &&
845
+ !Array.isArray(requirementSection) &&
846
+ !Array.isArray(actualSection)) {
847
+ mergedPageData[sectionKey] = normalizeAboutContactInfoCards(deepMerge(requirementSection, actualSection));
848
+ }
797
849
  else if (Array.isArray(requirementSection) && Array.isArray(actualSection)) {
798
850
  // Merge arrays
799
851
  mergedPageData[sectionKey] = mergeArrays(requirementSection, actualSection);