@reblu/site-blocks 0.26.0 → 0.28.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 CHANGED
@@ -1,5 +1,34 @@
1
1
  # @reblu/site-blocks
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 275adaf: REB-1201: `ArbitrationBadge` drop-in renders the tenant's consumer-arbitration distinctive in the footer — logo at `h-16`, `alt` with the adhesion number («… N.º de adhesión CA00000»), the number as visible text, optional link in a new window. `TrustBadges` knows the new type (heading «Arbitraje de consumo») but leaves it out of its default groups, so a footer with both never shows it twice; opt in with `types`. Any badge with an adhesion number gets it in its `alt`.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [275adaf]
12
+ - @reblu/site-contracts@1.28.0
13
+
14
+ ## 0.27.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 3f76060: `CoursePurchaseTerms` shows the consent box that the course's modality calls for (REB-1240). It reads `AcademyCourseDetail.withdrawalConsent`:
19
+ - Digital content: the withdrawal waiver. It keeps `data-slot="course-purchase-terms-withdrawal-waiver"`, as in REB-1199.
20
+ - A training service: the express request to start, which does not say the withdrawal right is lost. It uses the new `data-slot="course-purchase-terms-service-start-request"`.
21
+ - A course in person or by webinar: no box.
22
+
23
+ Both items carry `data-kind`. Against an API that predates `withdrawalConsent`, the block still reads `withdrawalWaiverRequired`.
24
+
25
+ **Visible change:** each box is now followed by the tenant's exact text, «Texto de la casilla: «…»». Replace it, or hide it with an empty node, through the new `consentText` label. `serviceStartRequest` is also a new label.
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [143cef1]
30
+ - @reblu/site-contracts@1.27.0
31
+
3
32
  ## 0.26.0
4
33
 
5
34
  ### Minor Changes
package/README.md CHANGED
@@ -25,7 +25,7 @@ colour on the red background. See `docs/theming/theming.md`.
25
25
  | `sanitizeHtml` | `.` | Sanitises an HTML string before `dangerouslySetInnerHTML` — the **HTML boundary**. See "Security boundaries" below. |
26
26
  | `MarkdownRenderer` | `.` | Canonical Blog renderer: `marked` → **hast-util-sanitize** (XSS) → component map, with a YouTube-domain allowlist. RSC-safe. |
27
27
  | `CourseDescription` | `.` | Drop-in for the rich-text course `description` (`client.academy.bySlug()`). Server Component. See "Rich-text descriptions". |
28
- | `CoursePurchaseTerms`, `DEFAULT_COURSE_PURCHASE_TERMS_LABELS` | `.` | What the buyer sees before paying: withdrawal waiver, access duration, refund guarantee. Server Component. See "Course purchase terms". |
28
+ | `CoursePurchaseTerms`, `DEFAULT_COURSE_PURCHASE_TERMS_LABELS` | `.` | What the buyer sees before paying: consent box by course modality, access duration, refund guarantee. Server Component. See "Course purchase terms". |
29
29
  | `LessonPreview`, `DEFAULT_LESSON_PREVIEW_LABELS` | `.` | A public free-preview lesson: hosted video player + sanitised body (`getLessonPreview()`). Server Component. See "Free-preview lesson". |
30
30
  | `Treatment`, `ParentPage`, `ProfileCard`, `ProductCard` | `.` | Presentational organisms over the SITE API contracts. RSC-safe. `Specialty`: deprecated alias, see below. |
31
31
  | `ProfessionalFields` | `.` | The tenant's own professional fields (`professional.fields`) on a team card or profile. RSC-safe. See below. |
@@ -35,6 +35,7 @@ colour on the red background. See `docs/theming/theming.md`.
35
35
  | `PageBlocks`, `FaqAccordion` | `.` | Registry-block renderer (`PageDetail.blocks`) and native `<details>` FAQ. Server Components. See "Page blocks" below. |
36
36
  | `ProductTrustItems`, `DEFAULT_TRUST_ICONS` | `.` | Store-wide trust messages from `ShopConfig.productTrustItems`. Server Component. See "Product trust items" below. |
37
37
  | `TrustBadges`, `DEFAULT_TRUST_BADGE_HEADINGS` | `.` | The tenant's trust badges from `client.trustBadges.list()`, grouped by type. Server Component. See "Trust badges" below. |
38
+ | `ArbitrationBadge` | `.` | The consumer-arbitration distinctive with its adhesion number, for the footer. Server Component. See "Consumer arbitration badge" below. |
38
39
  | `buildFaqPageJsonLd`, `collectFaqItems` | `./seo` | schema.org `FAQPage` structured data. Directive-free (also on `.`). See "Page blocks" below. |
39
40
  | `useCollection` | `./client` | Headless filterable/sortable/paginated collection hook (facets, category, tag, search). Serves both page and blog indexes. |
40
41
  | `Collection` | `./client` | Token-driven presentational grid over `useCollection`. |
@@ -755,7 +756,11 @@ export async function Footer() {
755
756
  - `types` picks which groups render and in what order, e.g. only the funding
756
757
  logos: `<TrustBadges badges={badges} types={['SUBVENTION']} />`. To fetch
757
758
  only one type, `client.trustBadges.list({ type: 'SUBVENTION' })`.
758
- - A logo is an `<img>` with `alt` = badge name, rendered only when its URL is
759
+ - `CONSUMER_ARBITRATION` is not in the default groups — render it with
760
+ `ArbitrationBadge` (below). Opt in with `types` to group it here; its heading
761
+ is «Arbitraje de consumo».
762
+ - A logo is an `<img>` with `alt` = badge name (plus «N.º de adhesión …» when
763
+ the badge has an adhesion number), rendered only when its URL is
759
764
  http(s) or root-relative (`/logos/x.svg`); any other scheme (`javascript:`,
760
765
  `data:`, `//host`) is dropped and the badge shows its name as text, like a
761
766
  badge without a logo. A badge `url` (http/https only) opens in a new window
@@ -781,6 +786,46 @@ export async function Footer() {
781
786
  `listClassName` and `logoClassName` are layout/sizing slots and still merge
782
787
  with `cn`.
783
788
 
789
+ ## Consumer arbitration badge — `ArbitrationBadge` (REB-1201)
790
+
791
+ A tenant adhered to the consumer arbitration system shows the official
792
+ distinctive in the footer, visible and accessible, with its adhesion number. In
793
+ nexus › Trust badges create a badge of type «Arbitraje de consumo» with the
794
+ official logo, the «Número de adhesión» (required for that type) and an
795
+ optional link. The API serves it like any other badge, with `adhesionNumber`.
796
+
797
+ ```tsx
798
+ import { ArbitrationBadge, TrustBadges } from '@reblu/site-blocks'
799
+
800
+ export async function Footer() {
801
+ const { data: badges } = await client.trustBadges.list().catch(() => ({ data: [] }))
802
+ return (
803
+ <footer>
804
+ {/* … */}
805
+ <TrustBadges badges={badges} headingLevel={2} />
806
+ <ArbitrationBadge badges={badges} />
807
+ </footer>
808
+ )
809
+ }
810
+ ```
811
+
812
+ - Feed it the whole list: only `CONSUMER_ARBITRATION` badges render, and
813
+ `TrustBadges` leaves that type out by default, so it never shows twice. To
814
+ fetch only it, `client.trustBadges.list({ type: 'CONSUMER_ARBITRATION' })`.
815
+ - The logo is an `<img>` at `h-16` (not a tiny icon) with `alt` = «{name}.
816
+ N.º de adhesión {number}». The number is also shown as visible text under the
817
+ logo, `aria-hidden` there because the `alt` already says it. Without a usable
818
+ logo (same http(s)/root-relative rule as `TrustBadges`) the name and number
819
+ are plain text.
820
+ - `numberLabel` changes «N.º de adhesión» (alt and caption); `showNumber={false}`
821
+ drops the visible caption, the `alt` keeps the number.
822
+ - A http(s) `url` opens in a new window with `rel="noopener noreferrer"` and a
823
+ visually hidden `newWindowLabel`.
824
+ - Nothing renders without a named consumer-arbitration badge.
825
+ - Styling hooks: `className` (the `<ul>`), `logoClassName` (merged with
826
+ `h-16 w-auto object-contain`, e.g. `brightness-0 invert` on a dark footer),
827
+ `numberClassName`.
828
+
784
829
  ## `ParentPage` (formerly `Specialty`)
785
830
 
786
831
  `ParentPage` renders a page that groups other pages: the hero and content
@@ -1128,11 +1173,16 @@ export default async function Page({ params }) {
1128
1173
  `lesson-preview-badge`, `lesson-preview-duration`, `lesson-preview-player`,
1129
1174
  `lesson-preview-content`.
1130
1175
 
1131
- ## Course purchase terms — `CoursePurchaseTerms` (REB-1199)
1176
+ ## Course purchase terms — `CoursePurchaseTerms` (REB-1199, REB-1240)
1132
1177
 
1133
1178
  What a buyer must see before paying for a course, from `client.academy.bySlug()`:
1134
1179
 
1135
- - **Withdrawal waiver** (`withdrawalWaiverRequired`): checkout asks for a separate box in which the buyer requests immediate access and waives the 14-day withdrawal right.
1180
+ - **Consent box** (`withdrawalConsent`, REB-1240): which box checkout asks for, as set by the course's modality (`deliveryModality`), followed by the tenant's exact text:
1181
+ - `DIGITAL_CONTENT_WAIVER`, for digital content: the buyer requests immediate access and waives the 14-day withdrawal right (`labels.withdrawalWaiver`);
1182
+ - `SERVICE_START_REQUEST`, for a training service: the buyer expressly asks for the training to start within the 14 days. It does not say the right is lost (`labels.serviceStartRequest`);
1183
+ - `null`, for example in person or webinar: nothing is shown.
1184
+
1185
+ Against an API that predates `withdrawalConsent`, the block falls back to `withdrawalWaiverRequired` (waiver line only).
1136
1186
  - **Access duration** (`accessDurationMonths`): months of access after enrolment. `null` means no end date, and nothing is shown.
1137
1187
  - **Refund guarantee** (`refundGuarantee`): the course's terms. `null` means none, and nothing is shown.
1138
1188
 
@@ -1150,11 +1200,15 @@ const course = await client.academy.bySlug(slug)
1150
1200
  course={course}
1151
1201
  labels={{
1152
1202
  withdrawalWaiver: 'Immediate access: you waive the 14-day withdrawal right.',
1203
+ serviceStartRequest: 'You ask the training to start within the 14-day withdrawal period.',
1204
+ consentText: (text) => ` Box text: “${text}”`,
1153
1205
  accessDuration: (months) => `Access for ${months} months.`,
1154
1206
  }}
1155
1207
  />
1156
1208
  ```
1157
1209
 
1210
+ The waiver item keeps `data-slot='course-purchase-terms-withdrawal-waiver'` (as in REB-1199); the express request to start uses `data-slot='course-purchase-terms-service-start-request'`. Both carry `data-kind` with the kind.
1211
+
1158
1212
  ## Page blocks
1159
1213
 
1160
1214
  `PageBlocks` renders a page's registry blocks (`PageDetail.blocks` from