@reblu/site-blocks 0.19.0 → 0.20.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/CHANGELOG.md +16 -0
- package/README.md +56 -2
- package/dist/client.cjs +237 -45
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +51 -2
- package/dist/client.d.ts +51 -2
- package/dist/client.js +234 -44
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +24 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +24 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { ShopProductListItem, DataRequestType, DataRequestInput, DataRequestSubmission } from '@reblu/site-contracts';
|
|
4
|
+
import { ShopProductListItem, AcademyModulePublic, AcademyLessonPublic, DataRequestType, DataRequestInput, DataRequestSubmission } from '@reblu/site-contracts';
|
|
5
5
|
export { DATA_REQUEST_TYPES } from '@reblu/site-contracts';
|
|
6
6
|
import { H as HeadingLevel } from './_heading-BsNbc1wc.js';
|
|
7
7
|
|
|
@@ -305,6 +305,55 @@ declare function ProductCarousel<T extends {
|
|
|
305
305
|
id: string | number;
|
|
306
306
|
} = ShopProductListItem>(props: ProductCarouselProps<T>): react_jsx_runtime.JSX.Element | null;
|
|
307
307
|
|
|
308
|
+
/**
|
|
309
|
+
* `CourseSyllabus` — the drop-in programme of a public course page, over
|
|
310
|
+
* `AcademyCourseDetail.modules` (`client.academy.bySlug()`), REB-1134.
|
|
311
|
+
*
|
|
312
|
+
* - The header reads the heading, then «N módulos · M lecciones».
|
|
313
|
+
* - Each module with lessons is a `<button>` with `aria-expanded` and
|
|
314
|
+
* `aria-controls`, showing its lesson count and, when every lesson has one,
|
|
315
|
+
* the module's total duration. Expanding it lists the lessons in the order
|
|
316
|
+
* the API returns them, with their duration and the free-preview flag.
|
|
317
|
+
* - A module without lessons is a plain row (title only), never a button.
|
|
318
|
+
*
|
|
319
|
+
* It renders only what the API serves. The API returns published lessons only
|
|
320
|
+
* and no video, playback or attachment data, so nothing here can leak it.
|
|
321
|
+
*
|
|
322
|
+
* Client Component: it holds the open/closed state of each module. Every prop
|
|
323
|
+
* is serialisable (copy is plain strings), so a Server Component page can
|
|
324
|
+
* render it directly.
|
|
325
|
+
*/
|
|
326
|
+
interface CourseSyllabusLabels {
|
|
327
|
+
heading: string;
|
|
328
|
+
moduleSingular: string;
|
|
329
|
+
modulePlural: string;
|
|
330
|
+
lessonSingular: string;
|
|
331
|
+
lessonPlural: string;
|
|
332
|
+
/** Badge on a lesson with `isFreePreview`. */
|
|
333
|
+
freePreview: string;
|
|
334
|
+
/** Hours unit in durations («1 h 15 min»). */
|
|
335
|
+
hours: string;
|
|
336
|
+
/** Minutes unit in durations. */
|
|
337
|
+
minutes: string;
|
|
338
|
+
}
|
|
339
|
+
declare const DEFAULT_COURSE_SYLLABUS_LABELS: CourseSyllabusLabels;
|
|
340
|
+
/** A module as served. `lessons` is optional so an older payload still renders. */
|
|
341
|
+
type CourseSyllabusModule = Pick<AcademyModulePublic, 'id' | 'title'> & {
|
|
342
|
+
description?: string | null;
|
|
343
|
+
lessons?: readonly AcademyLessonPublic[];
|
|
344
|
+
};
|
|
345
|
+
interface CourseSyllabusProps {
|
|
346
|
+
/** `AcademyCourseDetail.modules`, in the order the API returns them. */
|
|
347
|
+
modules: readonly CourseSyllabusModule[];
|
|
348
|
+
labels?: Partial<CourseSyllabusLabels>;
|
|
349
|
+
/** Level of the heading. Default `2`. */
|
|
350
|
+
headingLevel?: HeadingLevel;
|
|
351
|
+
/** Replaces the heading's default typography (see the className rule in the README). */
|
|
352
|
+
headingClassName?: string;
|
|
353
|
+
className?: string;
|
|
354
|
+
}
|
|
355
|
+
declare function CourseSyllabus({ modules, labels: labelOverrides, headingLevel, headingClassName, className, }: CourseSyllabusProps): react_jsx_runtime.JSX.Element | null;
|
|
356
|
+
|
|
308
357
|
/**
|
|
309
358
|
* `DataRequestForm` — drop-in public GDPR rights form (REB-980) over
|
|
310
359
|
* `POST /api/site/data-requests` (REB-77). The visitor picks the right they
|
|
@@ -384,4 +433,4 @@ interface DataRequestFormProps {
|
|
|
384
433
|
}
|
|
385
434
|
declare function DataRequestForm({ getCaptchaToken, submit, endpoint, onInteract, onSubmitted, requestTypes, labels, locale, className, }: DataRequestFormProps): react_jsx_runtime.JSX.Element;
|
|
386
435
|
|
|
387
|
-
export { AddToCartButton, type AddToCartButtonLabels, type AddToCartButtonProps, type AddToCartButtonStatus, CartIcon, type CartIconLabels, type CartIconProps, Collection, type CollectionFacet, type CollectionFacetOption, type CollectionFilter, type CollectionLabels, type CollectionProps, DATA_REQUEST_FIELD_LIMITS, DEFAULT_DATA_REQUEST_FORM_LABELS, DEFAULT_PRODUCT_CAROUSEL_LABELS, DataRequestForm, type DataRequestFormLabels, type DataRequestFormProps, type DataRequestSubmitResult, ProductCarousel, type ProductCarouselCustomCardProps, type ProductCarouselDefaultCardProps, type ProductCarouselLabels, type ProductCarouselProps, ShareButtons, type ShareButtonsLabels, type ShareButtonsProps, type UseCollectionOptions, type UseCollectionResult, useCollection };
|
|
436
|
+
export { AddToCartButton, type AddToCartButtonLabels, type AddToCartButtonProps, type AddToCartButtonStatus, CartIcon, type CartIconLabels, type CartIconProps, Collection, type CollectionFacet, type CollectionFacetOption, type CollectionFilter, type CollectionLabels, type CollectionProps, CourseSyllabus, type CourseSyllabusLabels, type CourseSyllabusModule, type CourseSyllabusProps, DATA_REQUEST_FIELD_LIMITS, DEFAULT_COURSE_SYLLABUS_LABELS, DEFAULT_DATA_REQUEST_FORM_LABELS, DEFAULT_PRODUCT_CAROUSEL_LABELS, DataRequestForm, type DataRequestFormLabels, type DataRequestFormProps, type DataRequestSubmitResult, ProductCarousel, type ProductCarouselCustomCardProps, type ProductCarouselDefaultCardProps, type ProductCarouselLabels, type ProductCarouselProps, ShareButtons, type ShareButtonsLabels, type ShareButtonsProps, type UseCollectionOptions, type UseCollectionResult, useCollection };
|
package/dist/client.js
CHANGED
|
@@ -415,7 +415,7 @@ import { cn as cn4 } from "@reblu/site-ui/utils";
|
|
|
415
415
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
416
416
|
var DEFAULT_LABELS4 = {
|
|
417
417
|
cart: "Carrito",
|
|
418
|
-
itemsSuffix: (
|
|
418
|
+
itemsSuffix: (count2) => `${count2} art\xEDculo${count2 === 1 ? "" : "s"}`
|
|
419
419
|
};
|
|
420
420
|
var BUMP_DURATION_MS = 400;
|
|
421
421
|
function CartIcon({ itemCount, href, hydrated, bumpOnAdd, labels, className }) {
|
|
@@ -687,13 +687,201 @@ function ProductCarousel(props) {
|
|
|
687
687
|
] });
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
-
// src/components/
|
|
691
|
-
import {
|
|
690
|
+
// src/components/course-syllabus.tsx
|
|
691
|
+
import { useId as useId2, useState as useState6 } from "react";
|
|
692
|
+
import { cn as cn8 } from "@reblu/site-ui/utils";
|
|
693
|
+
|
|
694
|
+
// src/lib/slot-class-name.ts
|
|
692
695
|
import { cn as cn7 } from "@reblu/site-ui/utils";
|
|
696
|
+
var MERGE_SAFE_TEXT = /(?:^|:)!?text-(?:left|center|right|justify|start|end|wrap|nowrap|balance|pretty|ellipsis|clip)$/;
|
|
697
|
+
var TEXT_UTILITY = /(?:^|:)!?-?text-/;
|
|
698
|
+
function bypassesMerge(token) {
|
|
699
|
+
return TEXT_UTILITY.test(token) && !MERGE_SAFE_TEXT.test(token);
|
|
700
|
+
}
|
|
701
|
+
function slotClassName(structural, defaults, consumer) {
|
|
702
|
+
if (consumer === void 0 || consumer.trim() === "") return cn7(structural, defaults);
|
|
703
|
+
const tokens = consumer.split(/\s+/).filter(Boolean);
|
|
704
|
+
const verbatim = tokens.filter(bypassesMerge);
|
|
705
|
+
const merged = cn7(structural, tokens.filter((token) => !bypassesMerge(token)));
|
|
706
|
+
return [merged, ...verbatim].filter(Boolean).join(" ");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// src/components/course-syllabus.tsx
|
|
710
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
711
|
+
var DEFAULT_COURSE_SYLLABUS_LABELS = {
|
|
712
|
+
heading: "Programa",
|
|
713
|
+
moduleSingular: "m\xF3dulo",
|
|
714
|
+
modulePlural: "m\xF3dulos",
|
|
715
|
+
lessonSingular: "lecci\xF3n",
|
|
716
|
+
lessonPlural: "lecciones",
|
|
717
|
+
freePreview: "Vista previa gratuita",
|
|
718
|
+
hours: "h",
|
|
719
|
+
minutes: "min"
|
|
720
|
+
};
|
|
721
|
+
var SEPARATOR = " \xB7 ";
|
|
722
|
+
function count(n, singular, plural) {
|
|
723
|
+
return `${n} ${n === 1 ? singular : plural}`;
|
|
724
|
+
}
|
|
725
|
+
function formatDuration(seconds, labels) {
|
|
726
|
+
const totalMinutes = Math.max(1, Math.round(seconds / 60));
|
|
727
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
728
|
+
const minutes = totalMinutes % 60;
|
|
729
|
+
if (hours === 0) return `${minutes} ${labels.minutes}`;
|
|
730
|
+
return minutes === 0 ? `${hours} ${labels.hours}` : `${hours} ${labels.hours} ${minutes} ${labels.minutes}`;
|
|
731
|
+
}
|
|
732
|
+
function moduleSeconds(lessons) {
|
|
733
|
+
let total = 0;
|
|
734
|
+
for (const l of lessons) {
|
|
735
|
+
if (typeof l.durationSeconds !== "number" || l.durationSeconds <= 0) return null;
|
|
736
|
+
total += l.durationSeconds;
|
|
737
|
+
}
|
|
738
|
+
return total;
|
|
739
|
+
}
|
|
740
|
+
function CourseSyllabus({
|
|
741
|
+
modules,
|
|
742
|
+
labels: labelOverrides,
|
|
743
|
+
headingLevel = 2,
|
|
744
|
+
headingClassName,
|
|
745
|
+
className
|
|
746
|
+
}) {
|
|
747
|
+
const labels = { ...DEFAULT_COURSE_SYLLABUS_LABELS, ...labelOverrides };
|
|
748
|
+
const baseId = useId2();
|
|
749
|
+
const [open, setOpen] = useState6(() => /* @__PURE__ */ new Set());
|
|
750
|
+
if (modules.length === 0) return null;
|
|
751
|
+
const totalLessons = modules.reduce((sum, m) => sum + (m.lessons?.length ?? 0), 0);
|
|
752
|
+
const summary = [count(modules.length, labels.moduleSingular, labels.modulePlural)];
|
|
753
|
+
if (totalLessons > 0)
|
|
754
|
+
summary.push(count(totalLessons, labels.lessonSingular, labels.lessonPlural));
|
|
755
|
+
const headingId = `${baseId}-heading`;
|
|
756
|
+
const Tag = `h${headingLevel}`;
|
|
757
|
+
function toggle(id) {
|
|
758
|
+
setOpen((prev) => {
|
|
759
|
+
const next = new Set(prev);
|
|
760
|
+
if (next.has(id)) next.delete(id);
|
|
761
|
+
else next.add(id);
|
|
762
|
+
return next;
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
return /* @__PURE__ */ jsxs6(
|
|
766
|
+
"section",
|
|
767
|
+
{
|
|
768
|
+
"data-slot": "course-syllabus",
|
|
769
|
+
"aria-labelledby": headingId,
|
|
770
|
+
className: cn8("space-y-4", className),
|
|
771
|
+
children: [
|
|
772
|
+
/* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
|
|
773
|
+
/* @__PURE__ */ jsx8(
|
|
774
|
+
Tag,
|
|
775
|
+
{
|
|
776
|
+
id: headingId,
|
|
777
|
+
className: slotClassName("", "text-xl font-semibold", headingClassName),
|
|
778
|
+
children: labels.heading
|
|
779
|
+
}
|
|
780
|
+
),
|
|
781
|
+
/* @__PURE__ */ jsx8("p", { "data-slot": "course-syllabus-summary", className: "text-sm text-muted-foreground", children: summary.join(SEPARATOR) })
|
|
782
|
+
] }),
|
|
783
|
+
/* @__PURE__ */ jsx8("ol", { className: "flex list-none flex-col gap-2.5 p-0", children: modules.map((module, index) => {
|
|
784
|
+
const lessons = module.lessons ?? [];
|
|
785
|
+
const number = /* @__PURE__ */ jsx8(
|
|
786
|
+
"span",
|
|
787
|
+
{
|
|
788
|
+
"aria-hidden": "true",
|
|
789
|
+
className: "flex size-7 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-semibold text-primary",
|
|
790
|
+
children: index + 1
|
|
791
|
+
}
|
|
792
|
+
);
|
|
793
|
+
if (lessons.length === 0) {
|
|
794
|
+
return /* @__PURE__ */ jsxs6(
|
|
795
|
+
"li",
|
|
796
|
+
{
|
|
797
|
+
"data-slot": "course-syllabus-module",
|
|
798
|
+
className: "flex items-center gap-3.5 rounded-lg border border-border bg-card px-4 py-3.5",
|
|
799
|
+
children: [
|
|
800
|
+
number,
|
|
801
|
+
/* @__PURE__ */ jsx8("span", { className: "font-semibold leading-snug", children: module.title })
|
|
802
|
+
]
|
|
803
|
+
},
|
|
804
|
+
module.id
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
const isOpen = open.has(module.id);
|
|
808
|
+
const panelId = `${baseId}-module-${index}`;
|
|
809
|
+
const seconds = moduleSeconds(lessons);
|
|
810
|
+
const meta = [count(lessons.length, labels.lessonSingular, labels.lessonPlural)];
|
|
811
|
+
if (seconds !== null) meta.push(formatDuration(seconds, labels));
|
|
812
|
+
return /* @__PURE__ */ jsxs6(
|
|
813
|
+
"li",
|
|
814
|
+
{
|
|
815
|
+
"data-slot": "course-syllabus-module",
|
|
816
|
+
className: "rounded-lg border border-border bg-card",
|
|
817
|
+
children: [
|
|
818
|
+
/* @__PURE__ */ jsxs6(
|
|
819
|
+
"button",
|
|
820
|
+
{
|
|
821
|
+
type: "button",
|
|
822
|
+
"aria-expanded": isOpen,
|
|
823
|
+
"aria-controls": panelId,
|
|
824
|
+
onClick: () => toggle(module.id),
|
|
825
|
+
className: "flex w-full cursor-pointer items-center gap-3.5 rounded-lg px-4 py-3.5 text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
|
|
826
|
+
children: [
|
|
827
|
+
number,
|
|
828
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
829
|
+
/* @__PURE__ */ jsx8("span", { className: "font-semibold leading-snug", children: module.title }),
|
|
830
|
+
/* @__PURE__ */ jsx8("span", { className: "text-sm text-muted-foreground", children: meta.join(SEPARATOR) })
|
|
831
|
+
] }),
|
|
832
|
+
/* @__PURE__ */ jsx8(
|
|
833
|
+
"span",
|
|
834
|
+
{
|
|
835
|
+
"aria-hidden": "true",
|
|
836
|
+
className: cn8(
|
|
837
|
+
"shrink-0 text-muted-foreground transition-transform motion-reduce:transition-none",
|
|
838
|
+
isOpen && "rotate-180"
|
|
839
|
+
),
|
|
840
|
+
children: "\u25BE"
|
|
841
|
+
}
|
|
842
|
+
)
|
|
843
|
+
]
|
|
844
|
+
}
|
|
845
|
+
),
|
|
846
|
+
/* @__PURE__ */ jsx8(
|
|
847
|
+
"ol",
|
|
848
|
+
{
|
|
849
|
+
id: panelId,
|
|
850
|
+
hidden: !isOpen,
|
|
851
|
+
"data-slot": "course-syllabus-lessons",
|
|
852
|
+
className: "list-none space-y-2 border-t border-border px-4 py-3 pl-[3.75rem]",
|
|
853
|
+
children: lessons.map((lesson) => /* @__PURE__ */ jsxs6(
|
|
854
|
+
"li",
|
|
855
|
+
{
|
|
856
|
+
"data-slot": "course-syllabus-lesson",
|
|
857
|
+
className: "flex flex-wrap items-baseline gap-x-3 gap-y-1 text-sm",
|
|
858
|
+
children: [
|
|
859
|
+
/* @__PURE__ */ jsx8("span", { "data-slot": "course-syllabus-lesson-title", className: "flex-1", children: lesson.title }),
|
|
860
|
+
lesson.isFreePreview && /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-muted px-2 py-0.5 text-xs font-medium", children: labels.freePreview }),
|
|
861
|
+
typeof lesson.durationSeconds === "number" && lesson.durationSeconds > 0 && /* @__PURE__ */ jsx8("span", { className: "text-muted-foreground tabular-nums", children: formatDuration(lesson.durationSeconds, labels) })
|
|
862
|
+
]
|
|
863
|
+
},
|
|
864
|
+
lesson.id
|
|
865
|
+
))
|
|
866
|
+
}
|
|
867
|
+
)
|
|
868
|
+
]
|
|
869
|
+
},
|
|
870
|
+
module.id
|
|
871
|
+
);
|
|
872
|
+
}) })
|
|
873
|
+
]
|
|
874
|
+
}
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// src/components/data-request-form.tsx
|
|
879
|
+
import { useEffect as useEffect4, useId as useId3, useRef as useRef4, useState as useState7 } from "react";
|
|
880
|
+
import { cn as cn9 } from "@reblu/site-ui/utils";
|
|
693
881
|
import {
|
|
694
882
|
DATA_REQUEST_TYPES
|
|
695
883
|
} from "@reblu/site-contracts";
|
|
696
|
-
import { Fragment, jsx as
|
|
884
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
697
885
|
var DATA_REQUEST_FIELD_LIMITS = Object.freeze({ name: 200, email: 320, details: 5e3 });
|
|
698
886
|
var DEFAULT_DATA_REQUEST_FORM_LABELS = {
|
|
699
887
|
requestTypeLabel: "Derecho que quieres ejercer",
|
|
@@ -719,7 +907,7 @@ var DEFAULT_DATA_REQUEST_FORM_LABELS = {
|
|
|
719
907
|
nameRequired: "Indica tu nombre.",
|
|
720
908
|
emailInvalid: "Introduce un email v\xE1lido.",
|
|
721
909
|
consentRequired: "Debes aceptar el tratamiento de tus datos para gestionar la solicitud.",
|
|
722
|
-
success: (deadline) => /* @__PURE__ */
|
|
910
|
+
success: (deadline) => /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
723
911
|
"Hemos recibido tu solicitud. Te responderemos como m\xE1ximo el ",
|
|
724
912
|
deadline,
|
|
725
913
|
"."
|
|
@@ -768,16 +956,16 @@ function DataRequestForm({
|
|
|
768
956
|
...labels,
|
|
769
957
|
requestTypes: { ...DEFAULT_DATA_REQUEST_FORM_LABELS.requestTypes, ...labels?.requestTypes }
|
|
770
958
|
};
|
|
771
|
-
const id =
|
|
772
|
-
const [requestType, setRequestType] =
|
|
773
|
-
const [name, setName] =
|
|
774
|
-
const [email, setEmail] =
|
|
775
|
-
const [details, setDetails] =
|
|
776
|
-
const [consent, setConsent] =
|
|
777
|
-
const [errors, setErrors] =
|
|
778
|
-
const [formError, setFormError] =
|
|
779
|
-
const [submitting, setSubmitting] =
|
|
780
|
-
const [ack, setAck] =
|
|
959
|
+
const id = useId3();
|
|
960
|
+
const [requestType, setRequestType] = useState7("");
|
|
961
|
+
const [name, setName] = useState7("");
|
|
962
|
+
const [email, setEmail] = useState7("");
|
|
963
|
+
const [details, setDetails] = useState7("");
|
|
964
|
+
const [consent, setConsent] = useState7(false);
|
|
965
|
+
const [errors, setErrors] = useState7({});
|
|
966
|
+
const [formError, setFormError] = useState7(null);
|
|
967
|
+
const [submitting, setSubmitting] = useState7(false);
|
|
968
|
+
const [ack, setAck] = useState7(null);
|
|
781
969
|
const statusRef = useRef4(null);
|
|
782
970
|
useEffect4(() => {
|
|
783
971
|
if (ack) statusRef.current?.focus();
|
|
@@ -830,21 +1018,21 @@ function DataRequestForm({
|
|
|
830
1018
|
dateStyle: "long",
|
|
831
1019
|
timeStyle: "short"
|
|
832
1020
|
}).format(new Date(ack.slaDueAt));
|
|
833
|
-
return /* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ jsx9(
|
|
834
1022
|
"div",
|
|
835
1023
|
{
|
|
836
1024
|
ref: statusRef,
|
|
837
1025
|
tabIndex: -1,
|
|
838
1026
|
role: "status",
|
|
839
1027
|
"data-slot": "data-request-form-success",
|
|
840
|
-
className:
|
|
1028
|
+
className: cn9("rounded-lg border border-border p-6 text-sm", className),
|
|
841
1029
|
children: t.success(deadline)
|
|
842
1030
|
}
|
|
843
1031
|
);
|
|
844
1032
|
}
|
|
845
1033
|
const errorId = (field) => errors[field] ? `${id}-${field}-error` : void 0;
|
|
846
|
-
const fieldError = (field) => errors[field] ? /* @__PURE__ */
|
|
847
|
-
return /* @__PURE__ */
|
|
1034
|
+
const fieldError = (field) => errors[field] ? /* @__PURE__ */ jsx9("p", { id: `${id}-${field}-error`, className: "text-xs text-destructive", children: errors[field] }) : null;
|
|
1035
|
+
return /* @__PURE__ */ jsxs7(
|
|
848
1036
|
"form",
|
|
849
1037
|
{
|
|
850
1038
|
noValidate: true,
|
|
@@ -852,11 +1040,11 @@ function DataRequestForm({
|
|
|
852
1040
|
onFocusCapture: onInteract,
|
|
853
1041
|
onPointerDown: onInteract,
|
|
854
1042
|
"data-slot": "data-request-form",
|
|
855
|
-
className:
|
|
1043
|
+
className: cn9("space-y-4", className),
|
|
856
1044
|
children: [
|
|
857
|
-
/* @__PURE__ */
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
1045
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1046
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: `${id}-type`, className: "text-sm font-medium", children: t.requestTypeLabel }),
|
|
1047
|
+
/* @__PURE__ */ jsxs7(
|
|
860
1048
|
"select",
|
|
861
1049
|
{
|
|
862
1050
|
id: `${id}-type`,
|
|
@@ -864,18 +1052,18 @@ function DataRequestForm({
|
|
|
864
1052
|
onChange: (e) => setRequestType(e.target.value),
|
|
865
1053
|
"aria-invalid": errors.requestType ? true : void 0,
|
|
866
1054
|
"aria-describedby": errorId("requestType"),
|
|
867
|
-
className:
|
|
1055
|
+
className: cn9(FIELD_CLASS, errors.requestType ? "border-destructive" : "border-border"),
|
|
868
1056
|
children: [
|
|
869
|
-
/* @__PURE__ */
|
|
870
|
-
requestTypes.map((type) => /* @__PURE__ */
|
|
1057
|
+
/* @__PURE__ */ jsx9("option", { value: "", children: t.requestTypePlaceholder }),
|
|
1058
|
+
requestTypes.map((type) => /* @__PURE__ */ jsx9("option", { value: type, children: t.requestTypes[type] }, type))
|
|
871
1059
|
]
|
|
872
1060
|
}
|
|
873
1061
|
),
|
|
874
1062
|
fieldError("requestType")
|
|
875
1063
|
] }),
|
|
876
|
-
/* @__PURE__ */
|
|
877
|
-
/* @__PURE__ */
|
|
878
|
-
/* @__PURE__ */
|
|
1064
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1065
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: `${id}-name`, className: "text-sm font-medium", children: t.nameLabel }),
|
|
1066
|
+
/* @__PURE__ */ jsx9(
|
|
879
1067
|
"input",
|
|
880
1068
|
{
|
|
881
1069
|
id: `${id}-name`,
|
|
@@ -886,14 +1074,14 @@ function DataRequestForm({
|
|
|
886
1074
|
onChange: (e) => setName(e.target.value),
|
|
887
1075
|
"aria-invalid": errors.name ? true : void 0,
|
|
888
1076
|
"aria-describedby": errorId("name"),
|
|
889
|
-
className:
|
|
1077
|
+
className: cn9(FIELD_CLASS, errors.name ? "border-destructive" : "border-border")
|
|
890
1078
|
}
|
|
891
1079
|
),
|
|
892
1080
|
fieldError("name")
|
|
893
1081
|
] }),
|
|
894
|
-
/* @__PURE__ */
|
|
895
|
-
/* @__PURE__ */
|
|
896
|
-
/* @__PURE__ */
|
|
1082
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1083
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: `${id}-email`, className: "text-sm font-medium", children: t.emailLabel }),
|
|
1084
|
+
/* @__PURE__ */ jsx9(
|
|
897
1085
|
"input",
|
|
898
1086
|
{
|
|
899
1087
|
id: `${id}-email`,
|
|
@@ -904,14 +1092,14 @@ function DataRequestForm({
|
|
|
904
1092
|
onChange: (e) => setEmail(e.target.value),
|
|
905
1093
|
"aria-invalid": errors.email ? true : void 0,
|
|
906
1094
|
"aria-describedby": errorId("email"),
|
|
907
|
-
className:
|
|
1095
|
+
className: cn9(FIELD_CLASS, errors.email ? "border-destructive" : "border-border")
|
|
908
1096
|
}
|
|
909
1097
|
),
|
|
910
1098
|
fieldError("email")
|
|
911
1099
|
] }),
|
|
912
|
-
/* @__PURE__ */
|
|
913
|
-
/* @__PURE__ */
|
|
914
|
-
/* @__PURE__ */
|
|
1100
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1101
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: `${id}-details`, className: "text-sm font-medium", children: t.detailsLabel }),
|
|
1102
|
+
/* @__PURE__ */ jsx9(
|
|
915
1103
|
"textarea",
|
|
916
1104
|
{
|
|
917
1105
|
id: `${id}-details`,
|
|
@@ -920,13 +1108,13 @@ function DataRequestForm({
|
|
|
920
1108
|
value: details,
|
|
921
1109
|
onChange: (e) => setDetails(e.target.value),
|
|
922
1110
|
placeholder: t.detailsPlaceholder,
|
|
923
|
-
className:
|
|
1111
|
+
className: cn9(FIELD_CLASS, "border-border")
|
|
924
1112
|
}
|
|
925
1113
|
)
|
|
926
1114
|
] }),
|
|
927
|
-
/* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1116
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2", children: [
|
|
1117
|
+
/* @__PURE__ */ jsx9(
|
|
930
1118
|
"input",
|
|
931
1119
|
{
|
|
932
1120
|
id: `${id}-consent`,
|
|
@@ -938,12 +1126,12 @@ function DataRequestForm({
|
|
|
938
1126
|
className: "mt-1"
|
|
939
1127
|
}
|
|
940
1128
|
),
|
|
941
|
-
/* @__PURE__ */
|
|
1129
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: `${id}-consent`, className: "text-sm text-foreground/80", children: t.consent })
|
|
942
1130
|
] }),
|
|
943
1131
|
fieldError("consent")
|
|
944
1132
|
] }),
|
|
945
|
-
formError && /* @__PURE__ */
|
|
946
|
-
/* @__PURE__ */
|
|
1133
|
+
formError && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-sm text-destructive", children: formError }),
|
|
1134
|
+
/* @__PURE__ */ jsx9(
|
|
947
1135
|
"button",
|
|
948
1136
|
{
|
|
949
1137
|
type: "submit",
|
|
@@ -960,8 +1148,10 @@ export {
|
|
|
960
1148
|
AddToCartButton,
|
|
961
1149
|
CartIcon,
|
|
962
1150
|
Collection,
|
|
1151
|
+
CourseSyllabus,
|
|
963
1152
|
DATA_REQUEST_FIELD_LIMITS,
|
|
964
1153
|
DATA_REQUEST_TYPES,
|
|
1154
|
+
DEFAULT_COURSE_SYLLABUS_LABELS,
|
|
965
1155
|
DEFAULT_DATA_REQUEST_FORM_LABELS,
|
|
966
1156
|
DEFAULT_PRODUCT_CAROUSEL_LABELS,
|
|
967
1157
|
DataRequestForm,
|