@opensite/ui 3.12.2 → 3.14.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.
- package/dist/hero-event-registration.cjs +71 -58
- package/dist/hero-event-registration.js +68 -55
- package/dist/registry.cjs +95 -70
- package/dist/registry.js +95 -70
- package/dist/testimonials-grid-add-review.cjs +7 -1
- package/dist/testimonials-grid-add-review.js +7 -1
- package/dist/testimonials-images-helpful.cjs +2 -3
- package/dist/testimonials-images-helpful.js +2 -3
- package/dist/testimonials-list-verified.cjs +2 -3
- package/dist/testimonials-list-verified.js +2 -3
- package/dist/testimonials-parallax-number.cjs +2 -5
- package/dist/testimonials-parallax-number.js +2 -5
- package/dist/testimonials-stats-header.cjs +7 -1
- package/dist/testimonials-stats-header.js +7 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var React4 = require('react');
|
|
5
5
|
var clsx = require('clsx');
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
7
|
var icon = require('@page-speed/icon');
|
|
@@ -29,14 +29,14 @@ function _interopNamespace(e) {
|
|
|
29
29
|
return Object.freeze(n);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var
|
|
32
|
+
var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
|
|
33
33
|
|
|
34
34
|
// components/blocks/hero/hero-event-registration.tsx
|
|
35
35
|
function cn(...inputs) {
|
|
36
36
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
37
37
|
}
|
|
38
38
|
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
39
|
-
var DynamicIcon =
|
|
39
|
+
var DynamicIcon = React4__namespace.memo(function DynamicIcon2({
|
|
40
40
|
apiKey,
|
|
41
41
|
name,
|
|
42
42
|
...props
|
|
@@ -89,7 +89,7 @@ var maxWidthStyles = {
|
|
|
89
89
|
"4xl": "max-w-[1536px]",
|
|
90
90
|
full: "max-w-full"
|
|
91
91
|
};
|
|
92
|
-
var Container =
|
|
92
|
+
var Container = React4__namespace.default.forwardRef(
|
|
93
93
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
94
94
|
const Component = as;
|
|
95
95
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -395,7 +395,7 @@ var spacingStyles = {
|
|
|
395
395
|
};
|
|
396
396
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
397
397
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
398
|
-
var Section =
|
|
398
|
+
var Section = React4__namespace.default.forwardRef(
|
|
399
399
|
({
|
|
400
400
|
id,
|
|
401
401
|
title,
|
|
@@ -610,14 +610,15 @@ function HeroEventRegistration({
|
|
|
610
610
|
logoClassName,
|
|
611
611
|
directionConfig = { desktop: "mediaRight", mobile: "mediaTop" }
|
|
612
612
|
}) {
|
|
613
|
-
const renderBadge =
|
|
613
|
+
const renderBadge = React4.useMemo(() => {
|
|
614
614
|
if (badgeSlot) return badgeSlot;
|
|
615
|
+
if (!badgeText && !badgeIcon) return null;
|
|
615
616
|
return /* @__PURE__ */ jsxRuntime.jsxs(Badge, { className: "px-4 py-1 gap-2", children: [
|
|
616
617
|
badgeIcon && /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: badgeIcon, size: 18 }),
|
|
617
618
|
badgeText
|
|
618
619
|
] });
|
|
619
620
|
}, [badgeSlot, badgeIcon, badgeText]);
|
|
620
|
-
const renderStats =
|
|
621
|
+
const renderStats = React4.useMemo(() => {
|
|
621
622
|
if (statsSlot) return statsSlot;
|
|
622
623
|
if (!stats || stats.length === 0) return null;
|
|
623
624
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -627,7 +628,7 @@ function HeroEventRegistration({
|
|
|
627
628
|
"flex flex-col md:flex-row items-center gap-4 md:gap-6 pt-8 md:pt-12 w-full md:w-fit",
|
|
628
629
|
statsClassName
|
|
629
630
|
),
|
|
630
|
-
children: stats.map((stat, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
631
|
+
children: stats.map((stat, index) => /* @__PURE__ */ jsxRuntime.jsxs(React4__namespace.Fragment, { children: [
|
|
631
632
|
index > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-12 w-px bg-border hidden md:flex" }),
|
|
632
633
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 justify-between flex-row md:flex-col text-left md:text-center w-full md:w-fit border md:border-none rounded-xl md:rounded-none p-4 md:p-0", children: [
|
|
633
634
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -658,57 +659,67 @@ function HeroEventRegistration({
|
|
|
658
659
|
}
|
|
659
660
|
);
|
|
660
661
|
}, [statsSlot, stats, statsClassName]);
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
"div",
|
|
678
|
-
{
|
|
679
|
-
className: cn(
|
|
680
|
-
"flex items-center justify-center shrink-0",
|
|
681
|
-
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
682
|
-
),
|
|
683
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
684
|
-
}
|
|
662
|
+
const buildLocation = React4__namespace.useCallback(
|
|
663
|
+
(positioned) => {
|
|
664
|
+
if (locationSlot) return locationSlot;
|
|
665
|
+
if (!locationLabel && !locationSublabel) return null;
|
|
666
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
667
|
+
"div",
|
|
668
|
+
{
|
|
669
|
+
className: cn(
|
|
670
|
+
"bg-card text-card-foreground",
|
|
671
|
+
"rounded-2xl p-2 md:p-4 shadow-lg",
|
|
672
|
+
"ring-4 ring-primary",
|
|
673
|
+
positioned ? cn(
|
|
674
|
+
"absolute bottom-0 translate-y-1/2",
|
|
675
|
+
"left-1/2 -translate-x-1/2 w-[90%]",
|
|
676
|
+
"md:-left-4 md:translate-x-0 md:w-auto"
|
|
677
|
+
) : "w-full md:w-fit"
|
|
685
678
|
),
|
|
686
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
)
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
679
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
681
|
+
"div",
|
|
682
|
+
{
|
|
683
|
+
className: cn(
|
|
684
|
+
"flex items-center justify-center shrink-0",
|
|
685
|
+
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
686
|
+
),
|
|
687
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
688
|
+
}
|
|
689
|
+
),
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
691
|
+
"div",
|
|
692
|
+
{
|
|
693
|
+
className: cn(
|
|
694
|
+
"flex flex-col items-start justify-center",
|
|
695
|
+
"text-card-foreground gap-0 pr-0 md:pr-2"
|
|
696
|
+
),
|
|
697
|
+
children: [
|
|
698
|
+
locationLabel && (typeof locationLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm md:text-base text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal font-semibold", children: locationLabel }) : locationLabel),
|
|
699
|
+
locationSublabel && (typeof locationSublabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
700
|
+
"div",
|
|
701
|
+
{
|
|
702
|
+
className: cn(
|
|
703
|
+
"text-xs md:text-sm text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal"
|
|
704
|
+
),
|
|
705
|
+
children: locationSublabel
|
|
706
|
+
}
|
|
707
|
+
) : locationSublabel)
|
|
708
|
+
]
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
] })
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
},
|
|
715
|
+
[locationSlot, locationLabel, locationSublabel]
|
|
716
|
+
);
|
|
717
|
+
const renderLocation = React4.useMemo(() => buildLocation(true), [buildLocation]);
|
|
718
|
+
const renderInlineLocation = React4.useMemo(
|
|
719
|
+
() => buildLocation(false),
|
|
720
|
+
[buildLocation]
|
|
721
|
+
);
|
|
722
|
+
const renderImage = React4.useMemo(() => {
|
|
712
723
|
if (imageSlot) return imageSlot;
|
|
713
724
|
if (!image) return null;
|
|
714
725
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full md:w-[50%]", children: [
|
|
@@ -736,6 +747,7 @@ function HeroEventRegistration({
|
|
|
736
747
|
}, [imageSlot, image, imageClassName, optixFlowConfig, renderLocation]);
|
|
737
748
|
const desktopOrder = directionConfig.desktop === "mediaRight" ? "md:flex-row" : "md:flex-row-reverse";
|
|
738
749
|
const mobileOrder = directionConfig.mobile === "mediaTop" ? "flex-col-reverse" : "flex-col";
|
|
750
|
+
const locationInImage = !imageSlot && Boolean(image);
|
|
739
751
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
740
752
|
Section,
|
|
741
753
|
{
|
|
@@ -784,6 +796,7 @@ function HeroEventRegistration({
|
|
|
784
796
|
}
|
|
785
797
|
) : heading),
|
|
786
798
|
description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-lg text-balance", descriptionClassName), children: description }) : description),
|
|
799
|
+
!locationInImage && renderInlineLocation,
|
|
787
800
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
788
801
|
BlockActions,
|
|
789
802
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React4 from 'react';
|
|
3
|
+
import React4__default, { useMemo } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { Icon } from '@page-speed/icon';
|
|
@@ -15,7 +15,7 @@ function cn(...inputs) {
|
|
|
15
15
|
return twMerge(clsx(inputs));
|
|
16
16
|
}
|
|
17
17
|
var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
|
|
18
|
-
var DynamicIcon =
|
|
18
|
+
var DynamicIcon = React4.memo(function DynamicIcon2({
|
|
19
19
|
apiKey,
|
|
20
20
|
name,
|
|
21
21
|
...props
|
|
@@ -68,7 +68,7 @@ var maxWidthStyles = {
|
|
|
68
68
|
"4xl": "max-w-[1536px]",
|
|
69
69
|
full: "max-w-full"
|
|
70
70
|
};
|
|
71
|
-
var Container =
|
|
71
|
+
var Container = React4__default.forwardRef(
|
|
72
72
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
73
73
|
const Component = as;
|
|
74
74
|
return /* @__PURE__ */ jsx(
|
|
@@ -374,7 +374,7 @@ var spacingStyles = {
|
|
|
374
374
|
};
|
|
375
375
|
var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
|
|
376
376
|
var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
|
|
377
|
-
var Section =
|
|
377
|
+
var Section = React4__default.forwardRef(
|
|
378
378
|
({
|
|
379
379
|
id,
|
|
380
380
|
title,
|
|
@@ -591,6 +591,7 @@ function HeroEventRegistration({
|
|
|
591
591
|
}) {
|
|
592
592
|
const renderBadge = useMemo(() => {
|
|
593
593
|
if (badgeSlot) return badgeSlot;
|
|
594
|
+
if (!badgeText && !badgeIcon) return null;
|
|
594
595
|
return /* @__PURE__ */ jsxs(Badge, { className: "px-4 py-1 gap-2", children: [
|
|
595
596
|
badgeIcon && /* @__PURE__ */ jsx(DynamicIcon, { name: badgeIcon, size: 18 }),
|
|
596
597
|
badgeText
|
|
@@ -606,7 +607,7 @@ function HeroEventRegistration({
|
|
|
606
607
|
"flex flex-col md:flex-row items-center gap-4 md:gap-6 pt-8 md:pt-12 w-full md:w-fit",
|
|
607
608
|
statsClassName
|
|
608
609
|
),
|
|
609
|
-
children: stats.map((stat, index) => /* @__PURE__ */ jsxs(
|
|
610
|
+
children: stats.map((stat, index) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
610
611
|
index > 0 && /* @__PURE__ */ jsx("div", { className: "h-12 w-px bg-border hidden md:flex" }),
|
|
611
612
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-between flex-row md:flex-col text-left md:text-center w-full md:w-fit border md:border-none rounded-xl md:rounded-none p-4 md:p-0", children: [
|
|
612
613
|
/* @__PURE__ */ jsxs(
|
|
@@ -637,56 +638,66 @@ function HeroEventRegistration({
|
|
|
637
638
|
}
|
|
638
639
|
);
|
|
639
640
|
}, [statsSlot, stats, statsClassName]);
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
"div",
|
|
657
|
-
{
|
|
658
|
-
className: cn(
|
|
659
|
-
"flex items-center justify-center shrink-0",
|
|
660
|
-
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
661
|
-
),
|
|
662
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
663
|
-
}
|
|
641
|
+
const buildLocation = React4.useCallback(
|
|
642
|
+
(positioned) => {
|
|
643
|
+
if (locationSlot) return locationSlot;
|
|
644
|
+
if (!locationLabel && !locationSublabel) return null;
|
|
645
|
+
return /* @__PURE__ */ jsx(
|
|
646
|
+
"div",
|
|
647
|
+
{
|
|
648
|
+
className: cn(
|
|
649
|
+
"bg-card text-card-foreground",
|
|
650
|
+
"rounded-2xl p-2 md:p-4 shadow-lg",
|
|
651
|
+
"ring-4 ring-primary",
|
|
652
|
+
positioned ? cn(
|
|
653
|
+
"absolute bottom-0 translate-y-1/2",
|
|
654
|
+
"left-1/2 -translate-x-1/2 w-[90%]",
|
|
655
|
+
"md:-left-4 md:translate-x-0 md:w-auto"
|
|
656
|
+
) : "w-full md:w-fit"
|
|
664
657
|
),
|
|
665
|
-
/* @__PURE__ */ jsxs(
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
)
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
658
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
659
|
+
/* @__PURE__ */ jsx(
|
|
660
|
+
"div",
|
|
661
|
+
{
|
|
662
|
+
className: cn(
|
|
663
|
+
"flex items-center justify-center shrink-0",
|
|
664
|
+
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
665
|
+
),
|
|
666
|
+
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
667
|
+
}
|
|
668
|
+
),
|
|
669
|
+
/* @__PURE__ */ jsxs(
|
|
670
|
+
"div",
|
|
671
|
+
{
|
|
672
|
+
className: cn(
|
|
673
|
+
"flex flex-col items-start justify-center",
|
|
674
|
+
"text-card-foreground gap-0 pr-0 md:pr-2"
|
|
675
|
+
),
|
|
676
|
+
children: [
|
|
677
|
+
locationLabel && (typeof locationLabel === "string" ? /* @__PURE__ */ jsx("div", { className: "text-sm md:text-base text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal font-semibold", children: locationLabel }) : locationLabel),
|
|
678
|
+
locationSublabel && (typeof locationSublabel === "string" ? /* @__PURE__ */ jsx(
|
|
679
|
+
"div",
|
|
680
|
+
{
|
|
681
|
+
className: cn(
|
|
682
|
+
"text-xs md:text-sm text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal"
|
|
683
|
+
),
|
|
684
|
+
children: locationSublabel
|
|
685
|
+
}
|
|
686
|
+
) : locationSublabel)
|
|
687
|
+
]
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
] })
|
|
691
|
+
}
|
|
692
|
+
);
|
|
693
|
+
},
|
|
694
|
+
[locationSlot, locationLabel, locationSublabel]
|
|
695
|
+
);
|
|
696
|
+
const renderLocation = useMemo(() => buildLocation(true), [buildLocation]);
|
|
697
|
+
const renderInlineLocation = useMemo(
|
|
698
|
+
() => buildLocation(false),
|
|
699
|
+
[buildLocation]
|
|
700
|
+
);
|
|
690
701
|
const renderImage = useMemo(() => {
|
|
691
702
|
if (imageSlot) return imageSlot;
|
|
692
703
|
if (!image) return null;
|
|
@@ -715,6 +726,7 @@ function HeroEventRegistration({
|
|
|
715
726
|
}, [imageSlot, image, imageClassName, optixFlowConfig, renderLocation]);
|
|
716
727
|
const desktopOrder = directionConfig.desktop === "mediaRight" ? "md:flex-row" : "md:flex-row-reverse";
|
|
717
728
|
const mobileOrder = directionConfig.mobile === "mediaTop" ? "flex-col-reverse" : "flex-col";
|
|
729
|
+
const locationInImage = !imageSlot && Boolean(image);
|
|
718
730
|
return /* @__PURE__ */ jsx(
|
|
719
731
|
Section,
|
|
720
732
|
{
|
|
@@ -763,6 +775,7 @@ function HeroEventRegistration({
|
|
|
763
775
|
}
|
|
764
776
|
) : heading),
|
|
765
777
|
description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-lg text-balance", descriptionClassName), children: description }) : description),
|
|
778
|
+
!locationInImage && renderInlineLocation,
|
|
766
779
|
/* @__PURE__ */ jsx(
|
|
767
780
|
BlockActions,
|
|
768
781
|
{
|
package/dist/registry.cjs
CHANGED
|
@@ -44444,10 +44444,9 @@ function TestimonialsListVerified({
|
|
|
44444
44444
|
] }),
|
|
44445
44445
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-base flex-col items-start", children: [
|
|
44446
44446
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
44447
|
-
review.verified && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44447
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44448
44448
|
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
44449
|
-
|
|
44450
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
44449
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
44451
44450
|
] })
|
|
44452
44451
|
] })
|
|
44453
44452
|
]
|
|
@@ -44632,10 +44631,9 @@ function TestimonialsImagesHelpful({
|
|
|
44632
44631
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-0", children: [
|
|
44633
44632
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-col md:flex-row", children: [
|
|
44634
44633
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
44635
|
-
review.verified && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44634
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44636
44635
|
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
44637
|
-
|
|
44638
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
44636
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
44639
44637
|
] })
|
|
44640
44638
|
] }),
|
|
44641
44639
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
@@ -45786,7 +45784,13 @@ function TestimonialsGridAddReview({
|
|
|
45786
45784
|
const avatarSrc = getAvatarSrc(testimonial);
|
|
45787
45785
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
45788
45786
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
45789
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
45787
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
45788
|
+
StarRating,
|
|
45789
|
+
{
|
|
45790
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
45791
|
+
size: 20
|
|
45792
|
+
}
|
|
45793
|
+
),
|
|
45790
45794
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
45791
45795
|
"p",
|
|
45792
45796
|
{
|
|
@@ -46748,7 +46752,13 @@ function TestimonialsStatsHeader({
|
|
|
46748
46752
|
),
|
|
46749
46753
|
children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
46750
46754
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
46751
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46755
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46756
|
+
StarRating,
|
|
46757
|
+
{
|
|
46758
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
46759
|
+
size: 20
|
|
46760
|
+
}
|
|
46761
|
+
),
|
|
46752
46762
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
46753
46763
|
"p",
|
|
46754
46764
|
{
|
|
@@ -48325,7 +48335,7 @@ function TestimonialsParallaxNumber({
|
|
|
48325
48335
|
),
|
|
48326
48336
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex", children: [
|
|
48327
48337
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center border-r-0 md:border-r border-border/30 pr-4 md:pr-16", children: [
|
|
48328
|
-
/* @__PURE__ */ jsxRuntime.
|
|
48338
|
+
verticalLabel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
48329
48339
|
framerMotion.motion.span,
|
|
48330
48340
|
{
|
|
48331
48341
|
className: "text-sm tracking-widest uppercase",
|
|
@@ -48333,10 +48343,7 @@ function TestimonialsParallaxNumber({
|
|
|
48333
48343
|
initial: { opacity: 0 },
|
|
48334
48344
|
animate: { opacity: 1 },
|
|
48335
48345
|
transition: { delay: 0.3 },
|
|
48336
|
-
children:
|
|
48337
|
-
verticalLabel && (typeof verticalLabel === "string" ? verticalLabel : verticalLabel),
|
|
48338
|
-
!verticalLabel && "Testimonials"
|
|
48339
|
-
]
|
|
48346
|
+
children: verticalLabel
|
|
48340
48347
|
}
|
|
48341
48348
|
),
|
|
48342
48349
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mt-8 h-32 w-4 bg-muted ring-2 ring-primary rounded", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -61957,6 +61964,7 @@ function HeroEventRegistration({
|
|
|
61957
61964
|
}) {
|
|
61958
61965
|
const renderBadge = React30.useMemo(() => {
|
|
61959
61966
|
if (badgeSlot) return badgeSlot;
|
|
61967
|
+
if (!badgeText && !badgeIcon) return null;
|
|
61960
61968
|
return /* @__PURE__ */ jsxRuntime.jsxs(Badge, { className: "px-4 py-1 gap-2", children: [
|
|
61961
61969
|
badgeIcon && /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: badgeIcon, size: 18 }),
|
|
61962
61970
|
badgeText
|
|
@@ -62003,56 +62011,66 @@ function HeroEventRegistration({
|
|
|
62003
62011
|
}
|
|
62004
62012
|
);
|
|
62005
62013
|
}, [statsSlot, stats, statsClassName]);
|
|
62006
|
-
const
|
|
62007
|
-
|
|
62008
|
-
|
|
62009
|
-
|
|
62010
|
-
|
|
62011
|
-
|
|
62012
|
-
|
|
62013
|
-
|
|
62014
|
-
|
|
62015
|
-
|
|
62016
|
-
|
|
62017
|
-
|
|
62018
|
-
|
|
62019
|
-
|
|
62020
|
-
|
|
62021
|
-
|
|
62022
|
-
"div",
|
|
62023
|
-
{
|
|
62024
|
-
className: cn(
|
|
62025
|
-
"flex items-center justify-center shrink-0",
|
|
62026
|
-
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
62027
|
-
),
|
|
62028
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
62029
|
-
}
|
|
62014
|
+
const buildLocation = React30__namespace.useCallback(
|
|
62015
|
+
(positioned) => {
|
|
62016
|
+
if (locationSlot) return locationSlot;
|
|
62017
|
+
if (!locationLabel && !locationSublabel) return null;
|
|
62018
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
62019
|
+
"div",
|
|
62020
|
+
{
|
|
62021
|
+
className: cn(
|
|
62022
|
+
"bg-card text-card-foreground",
|
|
62023
|
+
"rounded-2xl p-2 md:p-4 shadow-lg",
|
|
62024
|
+
"ring-4 ring-primary",
|
|
62025
|
+
positioned ? cn(
|
|
62026
|
+
"absolute bottom-0 translate-y-1/2",
|
|
62027
|
+
"left-1/2 -translate-x-1/2 w-[90%]",
|
|
62028
|
+
"md:-left-4 md:translate-x-0 md:w-auto"
|
|
62029
|
+
) : "w-full md:w-fit"
|
|
62030
62030
|
),
|
|
62031
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
62032
|
-
|
|
62033
|
-
|
|
62034
|
-
|
|
62035
|
-
|
|
62036
|
-
|
|
62037
|
-
|
|
62038
|
-
|
|
62039
|
-
|
|
62040
|
-
|
|
62041
|
-
|
|
62042
|
-
|
|
62043
|
-
|
|
62044
|
-
|
|
62045
|
-
|
|
62046
|
-
|
|
62047
|
-
|
|
62048
|
-
)
|
|
62049
|
-
|
|
62050
|
-
|
|
62051
|
-
|
|
62052
|
-
|
|
62053
|
-
|
|
62054
|
-
|
|
62055
|
-
|
|
62031
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
62032
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62033
|
+
"div",
|
|
62034
|
+
{
|
|
62035
|
+
className: cn(
|
|
62036
|
+
"flex items-center justify-center shrink-0",
|
|
62037
|
+
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
62038
|
+
),
|
|
62039
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
62040
|
+
}
|
|
62041
|
+
),
|
|
62042
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
62043
|
+
"div",
|
|
62044
|
+
{
|
|
62045
|
+
className: cn(
|
|
62046
|
+
"flex flex-col items-start justify-center",
|
|
62047
|
+
"text-card-foreground gap-0 pr-0 md:pr-2"
|
|
62048
|
+
),
|
|
62049
|
+
children: [
|
|
62050
|
+
locationLabel && (typeof locationLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm md:text-base text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal font-semibold", children: locationLabel }) : locationLabel),
|
|
62051
|
+
locationSublabel && (typeof locationSublabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
62052
|
+
"div",
|
|
62053
|
+
{
|
|
62054
|
+
className: cn(
|
|
62055
|
+
"text-xs md:text-sm text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal"
|
|
62056
|
+
),
|
|
62057
|
+
children: locationSublabel
|
|
62058
|
+
}
|
|
62059
|
+
) : locationSublabel)
|
|
62060
|
+
]
|
|
62061
|
+
}
|
|
62062
|
+
)
|
|
62063
|
+
] })
|
|
62064
|
+
}
|
|
62065
|
+
);
|
|
62066
|
+
},
|
|
62067
|
+
[locationSlot, locationLabel, locationSublabel]
|
|
62068
|
+
);
|
|
62069
|
+
const renderLocation = React30.useMemo(() => buildLocation(true), [buildLocation]);
|
|
62070
|
+
const renderInlineLocation = React30.useMemo(
|
|
62071
|
+
() => buildLocation(false),
|
|
62072
|
+
[buildLocation]
|
|
62073
|
+
);
|
|
62056
62074
|
const renderImage = React30.useMemo(() => {
|
|
62057
62075
|
if (imageSlot2) return imageSlot2;
|
|
62058
62076
|
if (!image) return null;
|
|
@@ -62081,6 +62099,7 @@ function HeroEventRegistration({
|
|
|
62081
62099
|
}, [imageSlot2, image, imageClassName, optixFlowConfig, renderLocation]);
|
|
62082
62100
|
const desktopOrder = directionConfig.desktop === "mediaRight" ? "md:flex-row" : "md:flex-row-reverse";
|
|
62083
62101
|
const mobileOrder = directionConfig.mobile === "mediaTop" ? "flex-col-reverse" : "flex-col";
|
|
62102
|
+
const locationInImage = !imageSlot2 && Boolean(image);
|
|
62084
62103
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
62085
62104
|
Section,
|
|
62086
62105
|
{
|
|
@@ -62129,6 +62148,7 @@ function HeroEventRegistration({
|
|
|
62129
62148
|
}
|
|
62130
62149
|
) : heading),
|
|
62131
62150
|
description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-lg text-balance", descriptionClassName), children: description }) : description),
|
|
62151
|
+
!locationInImage && renderInlineLocation,
|
|
62132
62152
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62133
62153
|
BlockActions,
|
|
62134
62154
|
{
|
|
@@ -113896,6 +113916,7 @@ var NAVBAR_BLOCK_CONTRACTS = {
|
|
|
113896
113916
|
};
|
|
113897
113917
|
var TESTIMONIALS_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
113898
113918
|
var TESTIMONIALS_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
113919
|
+
var TESTIMONIALS_FEED_NOTE = "Dynamic feeds (Phase 2): this block can carry a block-level dataSource of type 'testimonials_feed', hydrated at routing-build time into TestimonialItem[]. Bind target (dataSource.bindTo) defaults to 'testimonials'; use 'reviews' for testimonials-list-verified, testimonials-images-helpful, and testimonials-grid-add-review; single-item 'testimonial' (an object \u2014 the hydrator binds items[0]) for testimonials-company-logo, testimonials-large-quote, and testimonials-split-image. Wire mapping: content -> quote, reviewer_name -> author, rating -> rating (only when numeric; never fabricate), profile_url + platform -> linkConfig. Avatars are intentionally NOT mapped in Phase 2 because review avatar URLs are hotlinked and rot-prone. The reviews_or_testimonials capability is satisfied by live reviews OR authored static quotes, so octane does not hard-drop testimonials blocks on the capability alone.";
|
|
113899
113920
|
var testimonialsCapabilities = (...capabilities) => capabilities;
|
|
113900
113921
|
var img = TESTIMONIALS_EXAMPLE_IMAGE_URL;
|
|
113901
113922
|
var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
@@ -113939,7 +113960,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
113939
113960
|
background="white"
|
|
113940
113961
|
/>
|
|
113941
113962
|
`.trim(),
|
|
113942
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. Each review needs a rating (1\u20135), a title, content, and an author. The verified flag should only be set when the review platform actually verifies purchases. avatarSrc must be an absolute image URL.",
|
|
113963
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. Each review needs a rating (1\u20135), a title, content, and an author. The verified flag should only be set when the review platform actually verifies purchases. avatarSrc must be an absolute image URL. The verified indicator renders ONLY when verifiedPurchaseLabel is supplied \u2014 there is NO fallback wording; choose a label that fits the client's industry (e.g. 'Verified' / 'Verified Diner' / 'Verified Guest') or omit the prop to hide the indicator entirely.",
|
|
113943
113964
|
usageRequirements: {
|
|
113944
113965
|
requiredProps: ["reviews"],
|
|
113945
113966
|
propConstraints: {
|
|
@@ -114011,7 +114032,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
114011
114032
|
exampleUsage: `
|
|
114012
114033
|
<TestimonialsImagesHelpful
|
|
114013
114034
|
heading="Customer Reviews"
|
|
114014
|
-
verifiedPurchaseLabel="Verified
|
|
114035
|
+
verifiedPurchaseLabel="Verified"
|
|
114015
114036
|
reviews={[
|
|
114016
114037
|
{
|
|
114017
114038
|
rating: 5,
|
|
@@ -114037,7 +114058,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
114037
114058
|
]}
|
|
114038
114059
|
/>
|
|
114039
114060
|
`.trim(),
|
|
114040
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. The images[] array holds supplementary review photos from the reviewer \u2014 these must be real product/experience photos, not stock imagery. helpful counts must reflect actual platform data.",
|
|
114061
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. The images[] array holds supplementary review photos from the reviewer \u2014 these must be real product/experience photos, not stock imagery. helpful counts must reflect actual platform data. The verified indicator renders ONLY when verifiedPurchaseLabel is supplied \u2014 there is NO fallback wording; choose a label that fits the client's industry (e.g. 'Verified' / 'Verified Diner' / 'Verified Guest') or omit the prop to hide the indicator entirely.",
|
|
114041
114062
|
usageRequirements: {
|
|
114042
114063
|
requiredProps: ["reviews"],
|
|
114043
114064
|
propConstraints: {
|
|
@@ -114077,7 +114098,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
114077
114098
|
},
|
|
114078
114099
|
exampleProps: {
|
|
114079
114100
|
heading: "Customer Reviews",
|
|
114080
|
-
verifiedPurchaseLabel: "Verified
|
|
114101
|
+
verifiedPurchaseLabel: "Verified",
|
|
114081
114102
|
reviews: [
|
|
114082
114103
|
{
|
|
114083
114104
|
rating: 5,
|
|
@@ -115361,7 +115382,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
115361
115382
|
spacing="xl"
|
|
115362
115383
|
/>
|
|
115363
115384
|
`.trim(),
|
|
115364
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. backgroundIcon is a decorative Iconify icon ID (e.g., 'lucide/rocket') rendered as a large watermark behind the testimonial number \u2014 use icons that complement the testimonial theme. backgroundLabel is optional decorative text.",
|
|
115385
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. backgroundIcon is a decorative Iconify icon ID (e.g., 'lucide/rocket') rendered as a large watermark behind the testimonial number \u2014 use icons that complement the testimonial theme. backgroundLabel is optional decorative text. The vertical side label renders ONLY when verticalLabel is supplied \u2014 there is NO fallback wording; choose industry-appropriate text or omit the prop to hide it.",
|
|
115365
115386
|
usageRequirements: {
|
|
115366
115387
|
requiredProps: ["testimonials"],
|
|
115367
115388
|
propConstraints: {
|
|
@@ -115503,6 +115524,9 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
115503
115524
|
}
|
|
115504
115525
|
}
|
|
115505
115526
|
};
|
|
115527
|
+
for (const contract of Object.values(TESTIMONIALS_BLOCK_CONTRACTS)) {
|
|
115528
|
+
contract.importantUsageNotes = contract.importantUsageNotes ? `${contract.importantUsageNotes} ${TESTIMONIALS_FEED_NOTE}` : TESTIMONIALS_FEED_NOTE;
|
|
115529
|
+
}
|
|
115506
115530
|
var FEATURES_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
115507
115531
|
var FEATURES_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
115508
115532
|
var featuresCapabilities = (...capabilities) => capabilities;
|
|
@@ -117507,6 +117531,7 @@ var CONTACT_BLOCK_CONTRACTS = {
|
|
|
117507
117531
|
};
|
|
117508
117532
|
var HERO_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
117509
117533
|
var HERO_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
117534
|
+
var EVENTS_FEED_NOTE = "Dynamic feeds (Phase 4): this block can carry a block-level dataSource of type 'events_feed' (expands: true) \u2014 ONE symbolic block hydrates at routing-build time into N hero-event-registration instances, one per event occurrence (dataSource.limit default 6, hard cap 12). Wire mapping (\xA74.1d; never fabricate \u2014 omit any field with no real data): title -> heading, description -> description (omitted when blank), starts_at -> badgeText (short date badge, e.g. 'JUL 18'), starts_at in the event timezone -> locationLabel, location_name or custom_address -> locationSublabel (whichever is real; omitted when neither), image_url -> image ({src, alt: title}, only when an image exists), price_from -> stats[{value: '$X', label: 'From'}], recurring_summary -> stats[{value, label: 'Schedule'}], registration_url -> actions[{label: 'Register', href}]. stats, actions, and image are OMITTED entirely when no real data exists (the block null-guards every region; the propConstraints minItems/maxItems are AI-authoring constraints, not runtime requirements). The 'events' capability is SOFT: hero-event-registration is dual-use and remains legitimate for authored single-event / catering usage, so octane must NOT hard-drop the block on the capability alone \u2014 only feed-driven usage is gated.";
|
|
117510
117535
|
var heroCapabilities = (...capabilities) => capabilities;
|
|
117511
117536
|
var EXAMPLE_VIDEO_0 = {
|
|
117512
117537
|
masterPlaylistUrl: "https://cdn.ing/assets/video/uploads/283393/hls/38865/master.m3u8",
|
|
@@ -121070,7 +121095,7 @@ var HERO_BLOCK_CONTRACTS = {
|
|
|
121070
121095
|
background="dark"
|
|
121071
121096
|
/>
|
|
121072
121097
|
`.trim(),
|
|
121073
|
-
importantUsageNotes: `Only use if you have real event details. Only supply real stats and location data \u2014 do not fabricate.
|
|
121098
|
+
importantUsageNotes: `Only use if you have real event details. Only supply real stats and location data \u2014 do not fabricate. Image strongly preferred; omit when none exists \u2014 never use a stock/unrelated image. Do not exceed 50 characters for 'heading'. Do not exceed 130 characters for 'description'. ${HERO_MEDIA_NOTE} ${EVENTS_FEED_NOTE}`,
|
|
121074
121099
|
usageRequirements: {
|
|
121075
121100
|
requiredProps: ["heading"],
|
|
121076
121101
|
propConstraints: {
|
|
@@ -135807,7 +135832,7 @@ function createBuilderContractBundle({
|
|
|
135807
135832
|
symbolic: true,
|
|
135808
135833
|
hydrationOwner: "dashtrack-ai",
|
|
135809
135834
|
hydrationPhase: "routing-build",
|
|
135810
|
-
canonicalPayloadExpectation: "Keep testimonials feed requests symbolic in canonical page JSON until routing-build hydration resolves them.",
|
|
135835
|
+
canonicalPayloadExpectation: "Keep testimonials feed requests symbolic in canonical page JSON until routing-build hydration resolves them into TestimonialItem[] (or a single TestimonialItem for single-bind blocks). Wire mapping: content -> quote, reviewer_name -> author, rating -> rating (only when numeric; never fabricated), profile_url + platform -> linkConfig; avatars are intentionally left unmapped in Phase 2 because review avatar URLs are hotlinked and rot-prone.",
|
|
135811
135836
|
requiredFields: ["type"],
|
|
135812
135837
|
optionalFields: ["limit", "minRating", "platforms", "locationId", "bindTo"]
|
|
135813
135838
|
},
|
|
@@ -135825,7 +135850,7 @@ function createBuilderContractBundle({
|
|
|
135825
135850
|
symbolic: true,
|
|
135826
135851
|
hydrationOwner: "dashtrack-ai",
|
|
135827
135852
|
hydrationPhase: "routing-build",
|
|
135828
|
-
canonicalPayloadExpectation: "Keep events feed requests symbolic in canonical page JSON until routing-build hydration resolves them.",
|
|
135853
|
+
canonicalPayloadExpectation: "Keep events feed requests symbolic in canonical page JSON until routing-build hydration resolves them. events_feed is the first EXPANDING source (expands: true): ONE symbolic block hydrates into N hero-event-registration block instances, one per event occurrence (limit default 6, hard cap 12). Wire mapping (\xA74.1d; never fabricate \u2014 omit any field with no real data): title -> heading, description -> description (omitted when blank), starts_at -> badgeText (short date badge, e.g. 'JUL 18'), starts_at in the event timezone -> locationLabel, location_name or custom_address -> locationSublabel, image_url -> image ({src, alt: title}, only when present), price_from -> stats[{value: '$X', label: 'From'}], recurring_summary -> stats[{value, label: 'Schedule'}], registration_url -> actions[{label: 'Register', href}]. stats, actions, and image are omitted entirely when no real data exists. The 'events' capability is soft: hero-event-registration is dual-use (authored single-event/catering usage stays legitimate), so octane must not hard-drop on the capability alone.",
|
|
135829
135854
|
requiredFields: ["type"],
|
|
135830
135855
|
optionalFields: ["limit", "upcomingOnly", "locationIds", "bindTo"],
|
|
135831
135856
|
expands: true
|
package/dist/registry.js
CHANGED
|
@@ -44404,10 +44404,9 @@ function TestimonialsListVerified({
|
|
|
44404
44404
|
] }),
|
|
44405
44405
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-base flex-col items-start", children: [
|
|
44406
44406
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
44407
|
-
review.verified && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44407
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44408
44408
|
/* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
44409
|
-
|
|
44410
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
44409
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
44411
44410
|
] })
|
|
44412
44411
|
] })
|
|
44413
44412
|
]
|
|
@@ -44592,10 +44591,9 @@ function TestimonialsImagesHelpful({
|
|
|
44592
44591
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-0", children: [
|
|
44593
44592
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-col md:flex-row", children: [
|
|
44594
44593
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
44595
|
-
review.verified && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44594
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
44596
44595
|
/* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
44597
|
-
|
|
44598
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
44596
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
44599
44597
|
] })
|
|
44600
44598
|
] }),
|
|
44601
44599
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
@@ -45746,7 +45744,13 @@ function TestimonialsGridAddReview({
|
|
|
45746
45744
|
const avatarSrc = getAvatarSrc(testimonial);
|
|
45747
45745
|
return /* @__PURE__ */ jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
45748
45746
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
45749
|
-
/* @__PURE__ */ jsx(
|
|
45747
|
+
/* @__PURE__ */ jsx(
|
|
45748
|
+
StarRating,
|
|
45749
|
+
{
|
|
45750
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
45751
|
+
size: 20
|
|
45752
|
+
}
|
|
45753
|
+
),
|
|
45750
45754
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs(
|
|
45751
45755
|
"p",
|
|
45752
45756
|
{
|
|
@@ -46708,7 +46712,13 @@ function TestimonialsStatsHeader({
|
|
|
46708
46712
|
),
|
|
46709
46713
|
children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
46710
46714
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
46711
|
-
/* @__PURE__ */ jsx(
|
|
46715
|
+
/* @__PURE__ */ jsx(
|
|
46716
|
+
StarRating,
|
|
46717
|
+
{
|
|
46718
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
46719
|
+
size: 20
|
|
46720
|
+
}
|
|
46721
|
+
),
|
|
46712
46722
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs(
|
|
46713
46723
|
"p",
|
|
46714
46724
|
{
|
|
@@ -48285,7 +48295,7 @@ function TestimonialsParallaxNumber({
|
|
|
48285
48295
|
),
|
|
48286
48296
|
/* @__PURE__ */ jsxs("div", { className: "relative flex", children: [
|
|
48287
48297
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center border-r-0 md:border-r border-border/30 pr-4 md:pr-16", children: [
|
|
48288
|
-
/* @__PURE__ */
|
|
48298
|
+
verticalLabel && /* @__PURE__ */ jsx(
|
|
48289
48299
|
motion.span,
|
|
48290
48300
|
{
|
|
48291
48301
|
className: "text-sm tracking-widest uppercase",
|
|
@@ -48293,10 +48303,7 @@ function TestimonialsParallaxNumber({
|
|
|
48293
48303
|
initial: { opacity: 0 },
|
|
48294
48304
|
animate: { opacity: 1 },
|
|
48295
48305
|
transition: { delay: 0.3 },
|
|
48296
|
-
children:
|
|
48297
|
-
verticalLabel && (typeof verticalLabel === "string" ? verticalLabel : verticalLabel),
|
|
48298
|
-
!verticalLabel && "Testimonials"
|
|
48299
|
-
]
|
|
48306
|
+
children: verticalLabel
|
|
48300
48307
|
}
|
|
48301
48308
|
),
|
|
48302
48309
|
/* @__PURE__ */ jsx("div", { className: "relative mt-8 h-32 w-4 bg-muted ring-2 ring-primary rounded", children: /* @__PURE__ */ jsx(
|
|
@@ -61917,6 +61924,7 @@ function HeroEventRegistration({
|
|
|
61917
61924
|
}) {
|
|
61918
61925
|
const renderBadge = useMemo(() => {
|
|
61919
61926
|
if (badgeSlot) return badgeSlot;
|
|
61927
|
+
if (!badgeText && !badgeIcon) return null;
|
|
61920
61928
|
return /* @__PURE__ */ jsxs(Badge, { className: "px-4 py-1 gap-2", children: [
|
|
61921
61929
|
badgeIcon && /* @__PURE__ */ jsx(DynamicIcon, { name: badgeIcon, size: 18 }),
|
|
61922
61930
|
badgeText
|
|
@@ -61963,56 +61971,66 @@ function HeroEventRegistration({
|
|
|
61963
61971
|
}
|
|
61964
61972
|
);
|
|
61965
61973
|
}, [statsSlot, stats, statsClassName]);
|
|
61966
|
-
const
|
|
61967
|
-
|
|
61968
|
-
|
|
61969
|
-
|
|
61970
|
-
|
|
61971
|
-
|
|
61972
|
-
|
|
61973
|
-
|
|
61974
|
-
|
|
61975
|
-
|
|
61976
|
-
|
|
61977
|
-
|
|
61978
|
-
|
|
61979
|
-
|
|
61980
|
-
|
|
61981
|
-
|
|
61982
|
-
"div",
|
|
61983
|
-
{
|
|
61984
|
-
className: cn(
|
|
61985
|
-
"flex items-center justify-center shrink-0",
|
|
61986
|
-
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
61987
|
-
),
|
|
61988
|
-
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
61989
|
-
}
|
|
61974
|
+
const buildLocation = React30.useCallback(
|
|
61975
|
+
(positioned) => {
|
|
61976
|
+
if (locationSlot) return locationSlot;
|
|
61977
|
+
if (!locationLabel && !locationSublabel) return null;
|
|
61978
|
+
return /* @__PURE__ */ jsx(
|
|
61979
|
+
"div",
|
|
61980
|
+
{
|
|
61981
|
+
className: cn(
|
|
61982
|
+
"bg-card text-card-foreground",
|
|
61983
|
+
"rounded-2xl p-2 md:p-4 shadow-lg",
|
|
61984
|
+
"ring-4 ring-primary",
|
|
61985
|
+
positioned ? cn(
|
|
61986
|
+
"absolute bottom-0 translate-y-1/2",
|
|
61987
|
+
"left-1/2 -translate-x-1/2 w-[90%]",
|
|
61988
|
+
"md:-left-4 md:translate-x-0 md:w-auto"
|
|
61989
|
+
) : "w-full md:w-fit"
|
|
61990
61990
|
),
|
|
61991
|
-
/* @__PURE__ */ jsxs(
|
|
61992
|
-
|
|
61993
|
-
|
|
61994
|
-
|
|
61995
|
-
|
|
61996
|
-
|
|
61997
|
-
|
|
61998
|
-
|
|
61999
|
-
|
|
62000
|
-
|
|
62001
|
-
|
|
62002
|
-
|
|
62003
|
-
|
|
62004
|
-
|
|
62005
|
-
|
|
62006
|
-
|
|
62007
|
-
|
|
62008
|
-
)
|
|
62009
|
-
|
|
62010
|
-
|
|
62011
|
-
|
|
62012
|
-
|
|
62013
|
-
|
|
62014
|
-
|
|
62015
|
-
|
|
61991
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
61992
|
+
/* @__PURE__ */ jsx(
|
|
61993
|
+
"div",
|
|
61994
|
+
{
|
|
61995
|
+
className: cn(
|
|
61996
|
+
"flex items-center justify-center shrink-0",
|
|
61997
|
+
"size-12 rounded-xl bg-primary text-primary-foreground"
|
|
61998
|
+
),
|
|
61999
|
+
children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/map-pin", size: 24 })
|
|
62000
|
+
}
|
|
62001
|
+
),
|
|
62002
|
+
/* @__PURE__ */ jsxs(
|
|
62003
|
+
"div",
|
|
62004
|
+
{
|
|
62005
|
+
className: cn(
|
|
62006
|
+
"flex flex-col items-start justify-center",
|
|
62007
|
+
"text-card-foreground gap-0 pr-0 md:pr-2"
|
|
62008
|
+
),
|
|
62009
|
+
children: [
|
|
62010
|
+
locationLabel && (typeof locationLabel === "string" ? /* @__PURE__ */ jsx("div", { className: "text-sm md:text-base text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal font-semibold", children: locationLabel }) : locationLabel),
|
|
62011
|
+
locationSublabel && (typeof locationSublabel === "string" ? /* @__PURE__ */ jsx(
|
|
62012
|
+
"div",
|
|
62013
|
+
{
|
|
62014
|
+
className: cn(
|
|
62015
|
+
"text-xs md:text-sm text-balance leading-tight md:leading-normal tracking-tighter md:tracking-normal"
|
|
62016
|
+
),
|
|
62017
|
+
children: locationSublabel
|
|
62018
|
+
}
|
|
62019
|
+
) : locationSublabel)
|
|
62020
|
+
]
|
|
62021
|
+
}
|
|
62022
|
+
)
|
|
62023
|
+
] })
|
|
62024
|
+
}
|
|
62025
|
+
);
|
|
62026
|
+
},
|
|
62027
|
+
[locationSlot, locationLabel, locationSublabel]
|
|
62028
|
+
);
|
|
62029
|
+
const renderLocation = useMemo(() => buildLocation(true), [buildLocation]);
|
|
62030
|
+
const renderInlineLocation = useMemo(
|
|
62031
|
+
() => buildLocation(false),
|
|
62032
|
+
[buildLocation]
|
|
62033
|
+
);
|
|
62016
62034
|
const renderImage = useMemo(() => {
|
|
62017
62035
|
if (imageSlot2) return imageSlot2;
|
|
62018
62036
|
if (!image) return null;
|
|
@@ -62041,6 +62059,7 @@ function HeroEventRegistration({
|
|
|
62041
62059
|
}, [imageSlot2, image, imageClassName, optixFlowConfig, renderLocation]);
|
|
62042
62060
|
const desktopOrder = directionConfig.desktop === "mediaRight" ? "md:flex-row" : "md:flex-row-reverse";
|
|
62043
62061
|
const mobileOrder = directionConfig.mobile === "mediaTop" ? "flex-col-reverse" : "flex-col";
|
|
62062
|
+
const locationInImage = !imageSlot2 && Boolean(image);
|
|
62044
62063
|
return /* @__PURE__ */ jsx(
|
|
62045
62064
|
Section,
|
|
62046
62065
|
{
|
|
@@ -62089,6 +62108,7 @@ function HeroEventRegistration({
|
|
|
62089
62108
|
}
|
|
62090
62109
|
) : heading),
|
|
62091
62110
|
description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-lg text-balance", descriptionClassName), children: description }) : description),
|
|
62111
|
+
!locationInImage && renderInlineLocation,
|
|
62092
62112
|
/* @__PURE__ */ jsx(
|
|
62093
62113
|
BlockActions,
|
|
62094
62114
|
{
|
|
@@ -113856,6 +113876,7 @@ var NAVBAR_BLOCK_CONTRACTS = {
|
|
|
113856
113876
|
};
|
|
113857
113877
|
var TESTIMONIALS_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
113858
113878
|
var TESTIMONIALS_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
113879
|
+
var TESTIMONIALS_FEED_NOTE = "Dynamic feeds (Phase 2): this block can carry a block-level dataSource of type 'testimonials_feed', hydrated at routing-build time into TestimonialItem[]. Bind target (dataSource.bindTo) defaults to 'testimonials'; use 'reviews' for testimonials-list-verified, testimonials-images-helpful, and testimonials-grid-add-review; single-item 'testimonial' (an object \u2014 the hydrator binds items[0]) for testimonials-company-logo, testimonials-large-quote, and testimonials-split-image. Wire mapping: content -> quote, reviewer_name -> author, rating -> rating (only when numeric; never fabricate), profile_url + platform -> linkConfig. Avatars are intentionally NOT mapped in Phase 2 because review avatar URLs are hotlinked and rot-prone. The reviews_or_testimonials capability is satisfied by live reviews OR authored static quotes, so octane does not hard-drop testimonials blocks on the capability alone.";
|
|
113859
113880
|
var testimonialsCapabilities = (...capabilities) => capabilities;
|
|
113860
113881
|
var img = TESTIMONIALS_EXAMPLE_IMAGE_URL;
|
|
113861
113882
|
var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
@@ -113899,7 +113920,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
113899
113920
|
background="white"
|
|
113900
113921
|
/>
|
|
113901
113922
|
`.trim(),
|
|
113902
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. Each review needs a rating (1\u20135), a title, content, and an author. The verified flag should only be set when the review platform actually verifies purchases. avatarSrc must be an absolute image URL.",
|
|
113923
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. Each review needs a rating (1\u20135), a title, content, and an author. The verified flag should only be set when the review platform actually verifies purchases. avatarSrc must be an absolute image URL. The verified indicator renders ONLY when verifiedPurchaseLabel is supplied \u2014 there is NO fallback wording; choose a label that fits the client's industry (e.g. 'Verified' / 'Verified Diner' / 'Verified Guest') or omit the prop to hide the indicator entirely.",
|
|
113903
113924
|
usageRequirements: {
|
|
113904
113925
|
requiredProps: ["reviews"],
|
|
113905
113926
|
propConstraints: {
|
|
@@ -113971,7 +113992,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
113971
113992
|
exampleUsage: `
|
|
113972
113993
|
<TestimonialsImagesHelpful
|
|
113973
113994
|
heading="Customer Reviews"
|
|
113974
|
-
verifiedPurchaseLabel="Verified
|
|
113995
|
+
verifiedPurchaseLabel="Verified"
|
|
113975
113996
|
reviews={[
|
|
113976
113997
|
{
|
|
113977
113998
|
rating: 5,
|
|
@@ -113997,7 +114018,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
113997
114018
|
]}
|
|
113998
114019
|
/>
|
|
113999
114020
|
`.trim(),
|
|
114000
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. The images[] array holds supplementary review photos from the reviewer \u2014 these must be real product/experience photos, not stock imagery. helpful counts must reflect actual platform data.",
|
|
114021
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. The images[] array holds supplementary review photos from the reviewer \u2014 these must be real product/experience photos, not stock imagery. helpful counts must reflect actual platform data. The verified indicator renders ONLY when verifiedPurchaseLabel is supplied \u2014 there is NO fallback wording; choose a label that fits the client's industry (e.g. 'Verified' / 'Verified Diner' / 'Verified Guest') or omit the prop to hide the indicator entirely.",
|
|
114001
114022
|
usageRequirements: {
|
|
114002
114023
|
requiredProps: ["reviews"],
|
|
114003
114024
|
propConstraints: {
|
|
@@ -114037,7 +114058,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
114037
114058
|
},
|
|
114038
114059
|
exampleProps: {
|
|
114039
114060
|
heading: "Customer Reviews",
|
|
114040
|
-
verifiedPurchaseLabel: "Verified
|
|
114061
|
+
verifiedPurchaseLabel: "Verified",
|
|
114041
114062
|
reviews: [
|
|
114042
114063
|
{
|
|
114043
114064
|
rating: 5,
|
|
@@ -115321,7 +115342,7 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
115321
115342
|
spacing="xl"
|
|
115322
115343
|
/>
|
|
115323
115344
|
`.trim(),
|
|
115324
|
-
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. backgroundIcon is a decorative Iconify icon ID (e.g., 'lucide/rocket') rendered as a large watermark behind the testimonial number \u2014 use icons that complement the testimonial theme. backgroundLabel is optional decorative text.",
|
|
115345
|
+
importantUsageNotes: "Testimonials must come from real, sourced reviews or testimonials. Do not fabricate quotes, names, or company affiliations. backgroundIcon is a decorative Iconify icon ID (e.g., 'lucide/rocket') rendered as a large watermark behind the testimonial number \u2014 use icons that complement the testimonial theme. backgroundLabel is optional decorative text. The vertical side label renders ONLY when verticalLabel is supplied \u2014 there is NO fallback wording; choose industry-appropriate text or omit the prop to hide it.",
|
|
115325
115346
|
usageRequirements: {
|
|
115326
115347
|
requiredProps: ["testimonials"],
|
|
115327
115348
|
propConstraints: {
|
|
@@ -115463,6 +115484,9 @@ var TESTIMONIALS_BLOCK_CONTRACTS = {
|
|
|
115463
115484
|
}
|
|
115464
115485
|
}
|
|
115465
115486
|
};
|
|
115487
|
+
for (const contract of Object.values(TESTIMONIALS_BLOCK_CONTRACTS)) {
|
|
115488
|
+
contract.importantUsageNotes = contract.importantUsageNotes ? `${contract.importantUsageNotes} ${TESTIMONIALS_FEED_NOTE}` : TESTIMONIALS_FEED_NOTE;
|
|
115489
|
+
}
|
|
115466
115490
|
var FEATURES_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
115467
115491
|
var FEATURES_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
115468
115492
|
var featuresCapabilities = (...capabilities) => capabilities;
|
|
@@ -117467,6 +117491,7 @@ var CONTACT_BLOCK_CONTRACTS = {
|
|
|
117467
117491
|
};
|
|
117468
117492
|
var HERO_EXAMPLE_IMAGE_URL = "https://cdn.ing/assets/i/r/308196/g6bbn73f7gxal82uu49m9prfd0u8/workplace-in-cafe.webp";
|
|
117469
117493
|
var HERO_MEDIA_NOTE = "All media src values must be absolute URLs to real assets; relative paths and placeholder media variables are not allowed.";
|
|
117494
|
+
var EVENTS_FEED_NOTE = "Dynamic feeds (Phase 4): this block can carry a block-level dataSource of type 'events_feed' (expands: true) \u2014 ONE symbolic block hydrates at routing-build time into N hero-event-registration instances, one per event occurrence (dataSource.limit default 6, hard cap 12). Wire mapping (\xA74.1d; never fabricate \u2014 omit any field with no real data): title -> heading, description -> description (omitted when blank), starts_at -> badgeText (short date badge, e.g. 'JUL 18'), starts_at in the event timezone -> locationLabel, location_name or custom_address -> locationSublabel (whichever is real; omitted when neither), image_url -> image ({src, alt: title}, only when an image exists), price_from -> stats[{value: '$X', label: 'From'}], recurring_summary -> stats[{value, label: 'Schedule'}], registration_url -> actions[{label: 'Register', href}]. stats, actions, and image are OMITTED entirely when no real data exists (the block null-guards every region; the propConstraints minItems/maxItems are AI-authoring constraints, not runtime requirements). The 'events' capability is SOFT: hero-event-registration is dual-use and remains legitimate for authored single-event / catering usage, so octane must NOT hard-drop the block on the capability alone \u2014 only feed-driven usage is gated.";
|
|
117470
117495
|
var heroCapabilities = (...capabilities) => capabilities;
|
|
117471
117496
|
var EXAMPLE_VIDEO_0 = {
|
|
117472
117497
|
masterPlaylistUrl: "https://cdn.ing/assets/video/uploads/283393/hls/38865/master.m3u8",
|
|
@@ -121030,7 +121055,7 @@ var HERO_BLOCK_CONTRACTS = {
|
|
|
121030
121055
|
background="dark"
|
|
121031
121056
|
/>
|
|
121032
121057
|
`.trim(),
|
|
121033
|
-
importantUsageNotes: `Only use if you have real event details. Only supply real stats and location data \u2014 do not fabricate.
|
|
121058
|
+
importantUsageNotes: `Only use if you have real event details. Only supply real stats and location data \u2014 do not fabricate. Image strongly preferred; omit when none exists \u2014 never use a stock/unrelated image. Do not exceed 50 characters for 'heading'. Do not exceed 130 characters for 'description'. ${HERO_MEDIA_NOTE} ${EVENTS_FEED_NOTE}`,
|
|
121034
121059
|
usageRequirements: {
|
|
121035
121060
|
requiredProps: ["heading"],
|
|
121036
121061
|
propConstraints: {
|
|
@@ -135767,7 +135792,7 @@ function createBuilderContractBundle({
|
|
|
135767
135792
|
symbolic: true,
|
|
135768
135793
|
hydrationOwner: "dashtrack-ai",
|
|
135769
135794
|
hydrationPhase: "routing-build",
|
|
135770
|
-
canonicalPayloadExpectation: "Keep testimonials feed requests symbolic in canonical page JSON until routing-build hydration resolves them.",
|
|
135795
|
+
canonicalPayloadExpectation: "Keep testimonials feed requests symbolic in canonical page JSON until routing-build hydration resolves them into TestimonialItem[] (or a single TestimonialItem for single-bind blocks). Wire mapping: content -> quote, reviewer_name -> author, rating -> rating (only when numeric; never fabricated), profile_url + platform -> linkConfig; avatars are intentionally left unmapped in Phase 2 because review avatar URLs are hotlinked and rot-prone.",
|
|
135771
135796
|
requiredFields: ["type"],
|
|
135772
135797
|
optionalFields: ["limit", "minRating", "platforms", "locationId", "bindTo"]
|
|
135773
135798
|
},
|
|
@@ -135785,7 +135810,7 @@ function createBuilderContractBundle({
|
|
|
135785
135810
|
symbolic: true,
|
|
135786
135811
|
hydrationOwner: "dashtrack-ai",
|
|
135787
135812
|
hydrationPhase: "routing-build",
|
|
135788
|
-
canonicalPayloadExpectation: "Keep events feed requests symbolic in canonical page JSON until routing-build hydration resolves them.",
|
|
135813
|
+
canonicalPayloadExpectation: "Keep events feed requests symbolic in canonical page JSON until routing-build hydration resolves them. events_feed is the first EXPANDING source (expands: true): ONE symbolic block hydrates into N hero-event-registration block instances, one per event occurrence (limit default 6, hard cap 12). Wire mapping (\xA74.1d; never fabricate \u2014 omit any field with no real data): title -> heading, description -> description (omitted when blank), starts_at -> badgeText (short date badge, e.g. 'JUL 18'), starts_at in the event timezone -> locationLabel, location_name or custom_address -> locationSublabel, image_url -> image ({src, alt: title}, only when present), price_from -> stats[{value: '$X', label: 'From'}], recurring_summary -> stats[{value, label: 'Schedule'}], registration_url -> actions[{label: 'Register', href}]. stats, actions, and image are omitted entirely when no real data exists. The 'events' capability is soft: hero-event-registration is dual-use (authored single-event/catering usage stays legitimate), so octane must not hard-drop on the capability alone.",
|
|
135789
135814
|
requiredFields: ["type"],
|
|
135790
135815
|
optionalFields: ["limit", "upcomingOnly", "locationIds", "bindTo"],
|
|
135791
135816
|
expands: true
|
|
@@ -669,7 +669,13 @@ function TestimonialsGridAddReview({
|
|
|
669
669
|
const avatarSrc = getAvatarSrc(testimonial);
|
|
670
670
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
671
671
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
672
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
673
|
+
StarRating,
|
|
674
|
+
{
|
|
675
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
676
|
+
size: 20
|
|
677
|
+
}
|
|
678
|
+
),
|
|
673
679
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
674
680
|
"p",
|
|
675
681
|
{
|
|
@@ -647,7 +647,13 @@ function TestimonialsGridAddReview({
|
|
|
647
647
|
const avatarSrc = getAvatarSrc(testimonial);
|
|
648
648
|
return /* @__PURE__ */ jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
649
649
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
650
|
-
/* @__PURE__ */ jsx(
|
|
650
|
+
/* @__PURE__ */ jsx(
|
|
651
|
+
StarRating,
|
|
652
|
+
{
|
|
653
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
654
|
+
size: 20
|
|
655
|
+
}
|
|
656
|
+
),
|
|
651
657
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs(
|
|
652
658
|
"p",
|
|
653
659
|
{
|
|
@@ -636,10 +636,9 @@ function TestimonialsImagesHelpful({
|
|
|
636
636
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-0", children: [
|
|
637
637
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-col md:flex-row", children: [
|
|
638
638
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
639
|
-
review.verified && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
639
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
640
640
|
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
641
|
-
|
|
642
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
641
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
643
642
|
] })
|
|
644
643
|
] }),
|
|
645
644
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
@@ -613,10 +613,9 @@ function TestimonialsImagesHelpful({
|
|
|
613
613
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-0", children: [
|
|
614
614
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-col md:flex-row", children: [
|
|
615
615
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
616
|
-
review.verified && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
616
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
617
617
|
/* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
618
|
-
|
|
619
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
618
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
620
619
|
] })
|
|
621
620
|
] }),
|
|
622
621
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
@@ -558,10 +558,9 @@ function TestimonialsListVerified({
|
|
|
558
558
|
] }),
|
|
559
559
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-base flex-col items-start", children: [
|
|
560
560
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
561
|
-
review.verified && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
561
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
562
562
|
/* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
563
|
-
|
|
564
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
563
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
565
564
|
] })
|
|
566
565
|
] })
|
|
567
566
|
]
|
|
@@ -535,10 +535,9 @@ function TestimonialsListVerified({
|
|
|
535
535
|
] }),
|
|
536
536
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-base flex-col items-start", children: [
|
|
537
537
|
review.author && (typeof review.author === "string" ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: review.author }) : review.author),
|
|
538
|
-
review.verified && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
538
|
+
review.verified && verifiedPurchaseLabel && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
539
539
|
/* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/badge-check", size: 18 }),
|
|
540
|
-
|
|
541
|
-
!verifiedPurchaseLabel && /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Verified Purchase" })
|
|
540
|
+
typeof verifiedPurchaseLabel === "string" ? /* @__PURE__ */ jsx("span", { className: "text-sm", children: verifiedPurchaseLabel }) : verifiedPurchaseLabel
|
|
542
541
|
] })
|
|
543
542
|
] })
|
|
544
543
|
]
|
|
@@ -554,7 +554,7 @@ function TestimonialsParallaxNumber({
|
|
|
554
554
|
),
|
|
555
555
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex", children: [
|
|
556
556
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center border-r-0 md:border-r border-border/30 pr-4 md:pr-16", children: [
|
|
557
|
-
/* @__PURE__ */ jsxRuntime.
|
|
557
|
+
verticalLabel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
558
558
|
framerMotion.motion.span,
|
|
559
559
|
{
|
|
560
560
|
className: "text-sm tracking-widest uppercase",
|
|
@@ -562,10 +562,7 @@ function TestimonialsParallaxNumber({
|
|
|
562
562
|
initial: { opacity: 0 },
|
|
563
563
|
animate: { opacity: 1 },
|
|
564
564
|
transition: { delay: 0.3 },
|
|
565
|
-
children:
|
|
566
|
-
verticalLabel && (typeof verticalLabel === "string" ? verticalLabel : verticalLabel),
|
|
567
|
-
!verticalLabel && "Testimonials"
|
|
568
|
-
]
|
|
565
|
+
children: verticalLabel
|
|
569
566
|
}
|
|
570
567
|
),
|
|
571
568
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mt-8 h-32 w-4 bg-muted ring-2 ring-primary rounded", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -533,7 +533,7 @@ function TestimonialsParallaxNumber({
|
|
|
533
533
|
),
|
|
534
534
|
/* @__PURE__ */ jsxs("div", { className: "relative flex", children: [
|
|
535
535
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center border-r-0 md:border-r border-border/30 pr-4 md:pr-16", children: [
|
|
536
|
-
/* @__PURE__ */
|
|
536
|
+
verticalLabel && /* @__PURE__ */ jsx(
|
|
537
537
|
motion.span,
|
|
538
538
|
{
|
|
539
539
|
className: "text-sm tracking-widest uppercase",
|
|
@@ -541,10 +541,7 @@ function TestimonialsParallaxNumber({
|
|
|
541
541
|
initial: { opacity: 0 },
|
|
542
542
|
animate: { opacity: 1 },
|
|
543
543
|
transition: { delay: 0.3 },
|
|
544
|
-
children:
|
|
545
|
-
verticalLabel && (typeof verticalLabel === "string" ? verticalLabel : verticalLabel),
|
|
546
|
-
!verticalLabel && "Testimonials"
|
|
547
|
-
]
|
|
544
|
+
children: verticalLabel
|
|
548
545
|
}
|
|
549
546
|
),
|
|
550
547
|
/* @__PURE__ */ jsx("div", { className: "relative mt-8 h-32 w-4 bg-muted ring-2 ring-primary rounded", children: /* @__PURE__ */ jsx(
|
|
@@ -689,7 +689,13 @@ function TestimonialsStatsHeader({
|
|
|
689
689
|
),
|
|
690
690
|
children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
691
691
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
692
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
692
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
693
|
+
StarRating,
|
|
694
|
+
{
|
|
695
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
696
|
+
size: 20
|
|
697
|
+
}
|
|
698
|
+
),
|
|
693
699
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
694
700
|
"p",
|
|
695
701
|
{
|
|
@@ -667,7 +667,13 @@ function TestimonialsStatsHeader({
|
|
|
667
667
|
),
|
|
668
668
|
children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-12 justify-between", children: [
|
|
669
669
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
670
|
-
/* @__PURE__ */ jsx(
|
|
670
|
+
/* @__PURE__ */ jsx(
|
|
671
|
+
StarRating,
|
|
672
|
+
{
|
|
673
|
+
rating: typeof testimonial.rating === "number" ? testimonial.rating : 5,
|
|
674
|
+
size: 20
|
|
675
|
+
}
|
|
676
|
+
),
|
|
671
677
|
testimonial.quote && (typeof testimonial.quote === "string" ? /* @__PURE__ */ jsxs(
|
|
672
678
|
"p",
|
|
673
679
|
{
|