@reblu/site-blocks 0.23.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
@@ -14755,6 +14755,8 @@ var DEFAULT_COURSE_PRICE_BANDS = [
14755
14755
  { min: 3e4 }
14756
14756
  ];
14757
14757
  var DEFAULT_COURSE_CATALOG_FILTERS_LABELS = {
14758
+ category: "Categor\xEDa",
14759
+ allCategories: "Todas",
14758
14760
  instructor: "Docente",
14759
14761
  allInstructors: "Todos",
14760
14762
  price: "Precio",
@@ -14778,6 +14780,8 @@ function bandLabel(band, t, currencyCode, locale) {
14778
14780
  }
14779
14781
  function CourseCatalogFilters({
14780
14782
  instructors,
14783
+ categories = [],
14784
+ enabled = {},
14781
14785
  hrefs,
14782
14786
  active = {},
14783
14787
  onChange,
@@ -14789,9 +14793,39 @@ function CourseCatalogFilters({
14789
14793
  }) {
14790
14794
  const t = { ...DEFAULT_COURSE_CATALOG_FILTERS_LABELS, ...labels };
14791
14795
  const named = instructors.filter((i) => instructorName(i) !== "");
14792
- 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;
14793
14801
  const isFree = Boolean(active.free);
14802
+ if (!showCategories && !showInstructors && !showPrice) return null;
14794
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
+ ] }),
14795
14829
  showInstructors && /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.instructor, children: [
14796
14830
  /* @__PURE__ */ jsx17(
14797
14831
  OptionLink,
@@ -14817,7 +14851,7 @@ function CourseCatalogFilters({
14817
14851
  );
14818
14852
  })
14819
14853
  ] }),
14820
- /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.price, children: [
14854
+ showPrice && /* @__PURE__ */ jsxs16(FilterFieldset, { legend: t.price, children: [
14821
14855
  /* @__PURE__ */ jsx17(
14822
14856
  OptionLink,
14823
14857
  {
@@ -14852,6 +14886,7 @@ function CourseCatalogFilters({
14852
14886
  onClick: onChange ? (event) => {
14853
14887
  event.preventDefault();
14854
14888
  onChange({
14889
+ category: void 0,
14855
14890
  instructor: void 0,
14856
14891
  priceMin: void 0,
14857
14892
  priceMax: void 0,