@reblu/site-blocks 0.22.0 → 0.24.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/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ShopErrorCode, AcademyLessonPreview, PageDetail, PageListItem, ProfessionalField, ShopProductListItem, ShopProductTrustIcon, ShopProductTrustItem, TrustBadgeType, TrustBadge, BlockType, PageBlock, ResolvedEmbed, ShopFacets, AcademyInstructorPublic, ShopStaffAutoDiscount, ShopOrder, ShopBillingInput, ShopCheckoutInput, Config, ShopOrderInvoice } from '@reblu/site-contracts';
1
+ import { ShopErrorCode, AcademyLessonPreview, PageDetail, PageListItem, ProfessionalField, ShopProductListItem, ShopProductTrustIcon, ShopProductTrustItem, TrustBadgeType, TrustBadge, BlockType, PageBlock, ResolvedEmbed, ShopFacets, AcademyInstructorPublic, AcademyCategoryPublic, AcademyCatalogFiltersPublic, ShopStaffAutoDiscount, ShopOrder, ShopBillingInput, ShopCheckoutInput, Config, ShopOrderInvoice } from '@reblu/site-contracts';
2
2
  export { DATA_REQUEST_TYPES } from '@reblu/site-contracts';
3
3
  import { FaqItem } from './seo.cjs';
4
4
  export { FaqPageJsonLd, MarkdownToPlainTextOptions, buildFaqPageJsonLd, collectFaqItems, markdownToPlainText } from './seo.cjs';
@@ -830,6 +830,13 @@ declare function ShopFilters({ facets, hrefs, active, onChange, priceBands, labe
830
830
  * picking a band turns «Gratis» off; a consumer building `hrefs` should do the
831
831
  * same (drop `free` in `hrefs.price`, drop the range in `hrefs.free(true)`).
832
832
  *
833
+ * Which filters show is tenant config (REB-1234): pass
834
+ * `(await client.academy.config()).catalogFilters` as `enabled`. A filter left
835
+ * out of `enabled` shows, so omitting the prop keeps every filter. The category
836
+ * filter also needs `categories` (from `client.academy.categories()`) and
837
+ * `hrefs.category`. With every filter off, nothing renders; the search box is
838
+ * the SITE's own and stays.
839
+ *
833
840
  * Tokens only, Spanish defaults, every label overridable.
834
841
  */
835
842
  /** One price band. `min`/`max` are integer cents; either may be omitted for an open end. */
@@ -843,6 +850,8 @@ interface CourseCatalogPriceBand {
843
850
  declare const DEFAULT_COURSE_PRICE_BANDS: CourseCatalogPriceBand[];
844
851
  /** The selection currently reflected in the URL (or component state). */
845
852
  interface CourseCatalogFiltersActive {
853
+ /** A category slug (`AcademyCategoryPublic.slug`). */
854
+ category?: string;
846
855
  /** An instructor id (`AcademyInstructorPublic.id`). */
847
856
  instructor?: string;
848
857
  priceMin?: number;
@@ -851,6 +860,8 @@ interface CourseCatalogFiltersActive {
851
860
  }
852
861
  /** Href generators — the RSC-safe navigation seam. Keep the other current params. */
853
862
  interface CourseCatalogFiltersHrefs {
863
+ /** `slug` undefined clears the category filter. Required to show the category filter. */
864
+ category?: (slug: string | undefined) => string;
854
865
  /** `id` undefined clears the instructor filter. */
855
866
  instructor: (id: string | undefined) => string;
856
867
  /** Both undefined clears the price range. Should also drop `free`. */
@@ -860,6 +871,8 @@ interface CourseCatalogFiltersHrefs {
860
871
  clearAll: () => string;
861
872
  }
862
873
  interface CourseCatalogFiltersLabels {
874
+ category: string;
875
+ allCategories: string;
863
876
  instructor: string;
864
877
  allInstructors: string;
865
878
  price: string;
@@ -873,6 +886,13 @@ declare const DEFAULT_COURSE_CATALOG_FILTERS_LABELS: CourseCatalogFiltersLabels;
873
886
  interface CourseCatalogFiltersProps {
874
887
  /** From `client.academy.instructors()`. Unnamed instructors are not offered. */
875
888
  instructors: AcademyInstructorPublic[];
889
+ /** From `client.academy.categories()`. Shown in `sortOrder` order. */
890
+ categories?: AcademyCategoryPublic[];
891
+ /**
892
+ * Which filters the tenant switched on — `client.academy.config()`'s
893
+ * `catalogFilters`. A missing key counts as on.
894
+ */
895
+ enabled?: Partial<AcademyCatalogFiltersPublic>;
876
896
  hrefs: CourseCatalogFiltersHrefs;
877
897
  active?: CourseCatalogFiltersActive;
878
898
  /** Client-only: intercepts navigation with a callback instead. */
@@ -884,7 +904,7 @@ interface CourseCatalogFiltersProps {
884
904
  locale?: string;
885
905
  className?: string;
886
906
  }
887
- declare function CourseCatalogFilters({ instructors, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: CourseCatalogFiltersProps): react_jsx_runtime.JSX.Element;
907
+ declare function CourseCatalogFilters({ instructors, categories, enabled, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: CourseCatalogFiltersProps): react_jsx_runtime.JSX.Element | null;
888
908
 
889
909
  /**
890
910
  * `CartLineList` — presentational cart lines (REB-829), container/
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ShopErrorCode, AcademyLessonPreview, PageDetail, PageListItem, ProfessionalField, ShopProductListItem, ShopProductTrustIcon, ShopProductTrustItem, TrustBadgeType, TrustBadge, BlockType, PageBlock, ResolvedEmbed, ShopFacets, AcademyInstructorPublic, ShopStaffAutoDiscount, ShopOrder, ShopBillingInput, ShopCheckoutInput, Config, ShopOrderInvoice } from '@reblu/site-contracts';
1
+ import { ShopErrorCode, AcademyLessonPreview, PageDetail, PageListItem, ProfessionalField, ShopProductListItem, ShopProductTrustIcon, ShopProductTrustItem, TrustBadgeType, TrustBadge, BlockType, PageBlock, ResolvedEmbed, ShopFacets, AcademyInstructorPublic, AcademyCategoryPublic, AcademyCatalogFiltersPublic, ShopStaffAutoDiscount, ShopOrder, ShopBillingInput, ShopCheckoutInput, Config, ShopOrderInvoice } from '@reblu/site-contracts';
2
2
  export { DATA_REQUEST_TYPES } from '@reblu/site-contracts';
3
3
  import { FaqItem } from './seo.js';
4
4
  export { FaqPageJsonLd, MarkdownToPlainTextOptions, buildFaqPageJsonLd, collectFaqItems, markdownToPlainText } from './seo.js';
@@ -830,6 +830,13 @@ declare function ShopFilters({ facets, hrefs, active, onChange, priceBands, labe
830
830
  * picking a band turns «Gratis» off; a consumer building `hrefs` should do the
831
831
  * same (drop `free` in `hrefs.price`, drop the range in `hrefs.free(true)`).
832
832
  *
833
+ * Which filters show is tenant config (REB-1234): pass
834
+ * `(await client.academy.config()).catalogFilters` as `enabled`. A filter left
835
+ * out of `enabled` shows, so omitting the prop keeps every filter. The category
836
+ * filter also needs `categories` (from `client.academy.categories()`) and
837
+ * `hrefs.category`. With every filter off, nothing renders; the search box is
838
+ * the SITE's own and stays.
839
+ *
833
840
  * Tokens only, Spanish defaults, every label overridable.
834
841
  */
835
842
  /** One price band. `min`/`max` are integer cents; either may be omitted for an open end. */
@@ -843,6 +850,8 @@ interface CourseCatalogPriceBand {
843
850
  declare const DEFAULT_COURSE_PRICE_BANDS: CourseCatalogPriceBand[];
844
851
  /** The selection currently reflected in the URL (or component state). */
845
852
  interface CourseCatalogFiltersActive {
853
+ /** A category slug (`AcademyCategoryPublic.slug`). */
854
+ category?: string;
846
855
  /** An instructor id (`AcademyInstructorPublic.id`). */
847
856
  instructor?: string;
848
857
  priceMin?: number;
@@ -851,6 +860,8 @@ interface CourseCatalogFiltersActive {
851
860
  }
852
861
  /** Href generators — the RSC-safe navigation seam. Keep the other current params. */
853
862
  interface CourseCatalogFiltersHrefs {
863
+ /** `slug` undefined clears the category filter. Required to show the category filter. */
864
+ category?: (slug: string | undefined) => string;
854
865
  /** `id` undefined clears the instructor filter. */
855
866
  instructor: (id: string | undefined) => string;
856
867
  /** Both undefined clears the price range. Should also drop `free`. */
@@ -860,6 +871,8 @@ interface CourseCatalogFiltersHrefs {
860
871
  clearAll: () => string;
861
872
  }
862
873
  interface CourseCatalogFiltersLabels {
874
+ category: string;
875
+ allCategories: string;
863
876
  instructor: string;
864
877
  allInstructors: string;
865
878
  price: string;
@@ -873,6 +886,13 @@ declare const DEFAULT_COURSE_CATALOG_FILTERS_LABELS: CourseCatalogFiltersLabels;
873
886
  interface CourseCatalogFiltersProps {
874
887
  /** From `client.academy.instructors()`. Unnamed instructors are not offered. */
875
888
  instructors: AcademyInstructorPublic[];
889
+ /** From `client.academy.categories()`. Shown in `sortOrder` order. */
890
+ categories?: AcademyCategoryPublic[];
891
+ /**
892
+ * Which filters the tenant switched on — `client.academy.config()`'s
893
+ * `catalogFilters`. A missing key counts as on.
894
+ */
895
+ enabled?: Partial<AcademyCatalogFiltersPublic>;
876
896
  hrefs: CourseCatalogFiltersHrefs;
877
897
  active?: CourseCatalogFiltersActive;
878
898
  /** Client-only: intercepts navigation with a callback instead. */
@@ -884,7 +904,7 @@ interface CourseCatalogFiltersProps {
884
904
  locale?: string;
885
905
  className?: string;
886
906
  }
887
- declare function CourseCatalogFilters({ instructors, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: CourseCatalogFiltersProps): react_jsx_runtime.JSX.Element;
907
+ declare function CourseCatalogFilters({ instructors, categories, enabled, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: CourseCatalogFiltersProps): react_jsx_runtime.JSX.Element | null;
888
908
 
889
909
  /**
890
910
  * `CartLineList` — presentational cart lines (REB-829), container/
package/dist/index.js CHANGED
@@ -52,7 +52,17 @@ var DEFAULT_SHOP_ERROR_MESSAGES = {
52
52
  INVOICING_NOT_READY: "No se puede completar la compra en este momento. Int\xE9ntalo m\xE1s tarde.",
53
53
  FULL_INVOICE_UNAVAILABLE: "Esta tienda no emite facturas completas: contin\xFAa sin solicitarla.",
54
54
  // REB-912 — the code used up its total uses; refused before any payment.
55
- DISCOUNT_LIMIT_REACHED: "Este c\xF3digo ya ha alcanzado su l\xEDmite de usos"
55
+ DISCOUNT_LIMIT_REACHED: "Este c\xF3digo ya ha alcanzado su l\xEDmite de usos",
56
+ // REB-1197 — delivery refusals before any payment.
57
+ PICKUP_UNAVAILABLE: "La recogida no est\xE1 disponible en esta tienda. Elige el env\xEDo a domicilio.",
58
+ PICKUP_LOCATION_INVALID: "El punto de recogida elegido ya no est\xE1 disponible. Elige otro.",
59
+ SHIPPING_ADDRESS_REQUIRED: "Indica la direcci\xF3n de env\xEDo para recibir tu pedido.",
60
+ ORDER_TOO_HEAVY: "Tu pedido supera el peso m\xE1ximo. Reduce alguna cantidad o divide la compra.",
61
+ // REB-1198 — terms acceptance, before any payment.
62
+ TERMS_NOT_ACCEPTED: "Para continuar, acepta las condiciones generales de contrataci\xF3n.",
63
+ TERMS_VERSION_CHANGED: "Las condiciones de contrataci\xF3n se han actualizado. Rev\xEDsalas y vuelve a aceptarlas.",
64
+ // Owner, 2-Nov — no home delivery nor pickup for a cart that ships.
65
+ DELIVERY_UNAVAILABLE: "Ahora mismo no podemos entregar productos f\xEDsicos. Int\xE9ntalo m\xE1s tarde o contacta con la tienda."
56
66
  };
57
67
  var DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE = "No se ha podido completar la operaci\xF3n. Int\xE9ntalo de nuevo.";
58
68
  function getShopErrorMessage(code, overrides, fallback = DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE) {
@@ -14745,6 +14755,8 @@ var DEFAULT_COURSE_PRICE_BANDS = [
14745
14755
  { min: 3e4 }
14746
14756
  ];
14747
14757
  var DEFAULT_COURSE_CATALOG_FILTERS_LABELS = {
14758
+ category: "Categor\xEDa",
14759
+ allCategories: "Todas",
14748
14760
  instructor: "Docente",
14749
14761
  allInstructors: "Todos",
14750
14762
  price: "Precio",
@@ -14768,6 +14780,8 @@ function bandLabel(band, t, currencyCode, locale) {
14768
14780
  }
14769
14781
  function CourseCatalogFilters({
14770
14782
  instructors,
14783
+ categories = [],
14784
+ enabled = {},
14771
14785
  hrefs,
14772
14786
  active = {},
14773
14787
  onChange,
@@ -14779,9 +14793,39 @@ function CourseCatalogFilters({
14779
14793
  }) {
14780
14794
  const t = { ...DEFAULT_COURSE_CATALOG_FILTERS_LABELS, ...labels };
14781
14795
  const named = instructors.filter((i) => instructorName(i) !== "");
14782
- const showInstructors = named.length > 0 || active.instructor !== void 0;
14796
+ const sortedCategories = [...categories].sort((a, b2) => a.sortOrder - b2.sortOrder);
14797
+ const categoryHref = hrefs.category;
14798
+ const showCategories = enabled.category !== false && categoryHref !== void 0 && (sortedCategories.length > 0 || active.category !== void 0);
14799
+ const showInstructors = enabled.instructor !== false && (named.length > 0 || active.instructor !== void 0);
14800
+ const showPrice = enabled.price !== false;
14783
14801
  const isFree = Boolean(active.free);
14802
+ if (!showCategories && !showInstructors && !showPrice) return null;
14784
14803
  return /* @__PURE__ */ jsxs16("div", { className: cn13("space-y-6", className), "data-slot": "course-catalog-filters", children: [
14804
+ showCategories && /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.category, children: [
14805
+ /* @__PURE__ */ jsx17(
14806
+ OptionLink,
14807
+ {
14808
+ href: categoryHref(void 0),
14809
+ active: active.category === void 0,
14810
+ label: t.allCategories,
14811
+ onActivate: onChange ? () => onChange({ category: void 0 }) : void 0
14812
+ }
14813
+ ),
14814
+ sortedCategories.map((category) => {
14815
+ const isActive = active.category === category.slug;
14816
+ const next2 = isActive ? void 0 : category.slug;
14817
+ return /* @__PURE__ */ jsx17(
14818
+ OptionLink,
14819
+ {
14820
+ href: categoryHref(next2),
14821
+ active: isActive,
14822
+ label: category.name,
14823
+ onActivate: onChange ? () => onChange({ category: next2 }) : void 0
14824
+ },
14825
+ category.id
14826
+ );
14827
+ })
14828
+ ] }),
14785
14829
  showInstructors && /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.instructor, children: [
14786
14830
  /* @__PURE__ */ jsx17(
14787
14831
  OptionLink,
@@ -14807,7 +14851,7 @@ function CourseCatalogFilters({
14807
14851
  );
14808
14852
  })
14809
14853
  ] }),
14810
- /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.price, children: [
14854
+ showPrice && /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.price, children: [
14811
14855
  /* @__PURE__ */ jsx17(
14812
14856
  OptionLink,
14813
14857
  {
@@ -14842,6 +14886,7 @@ function CourseCatalogFilters({
14842
14886
  onClick: onChange ? (event) => {
14843
14887
  event.preventDefault();
14844
14888
  onChange({
14889
+ category: void 0,
14845
14890
  instructor: void 0,
14846
14891
  priceMin: void 0,
14847
14892
  priceMax: void 0,