summit-registration-lite 7.0.0 → 7.0.1

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.
@@ -0,0 +1,62 @@
1
+ # i18n / Translation Pattern
2
+
3
+ ## When to Apply
4
+
5
+ Adding user-facing text to components or modifying existing strings.
6
+
7
+ ## Pattern
8
+
9
+ **Library:** `i18n-react` — imported as `T`.
10
+
11
+ **Setup (in `registration-lite.js`):**
12
+
13
+ ```javascript
14
+ import T from 'i18n-react';
15
+
16
+ // Loaded once at component init, falls back to English
17
+ try {
18
+ T.setTexts(require(`../i18n/${language}.json`));
19
+ } catch {
20
+ T.setTexts(require(`../i18n/en.json`));
21
+ }
22
+ ```
23
+
24
+ **Usage in components:**
25
+
26
+ ```javascript
27
+ import T from 'i18n-react';
28
+
29
+ // Simple key
30
+ T.translate("bar_button.next") // → "Next"
31
+
32
+ // With interpolation
33
+ T.translate("purchase_complete_step.footer_assistance_text", { supportEmail: "help@example.com" })
34
+ // Template: "For further assistance, please email <a href=\"mailto:{supportEmail}\">{supportEmail}</a>"
35
+ ```
36
+
37
+ ## Translation File Structure
38
+
39
+ `src/i18n/en.json` — flat namespaced by UI section:
40
+
41
+ ```json
42
+ {
43
+ "purchase_complete_step": { "title": "...", "initial_order_complete_button": "..." },
44
+ "ticket_type": { "ticket_quantity_tooltip": "..." },
45
+ "promo_code": { "promo_code_tooltip": "..." },
46
+ "bar_button": { "back": "Back", "next": "Next", "get_ticket": "Get Ticket", "pay_now": "Pay Now", "loading": "Loading" }
47
+ }
48
+ ```
49
+
50
+ ## Key Points
51
+
52
+ - Namespace keys by component/step: `"section_name.key_name"`
53
+ - Interpolation uses `{variableName}` syntax (not `${}` or `%s`)
54
+ - HTML is allowed in translation values (rendered as-is)
55
+ - Only English (`en.json`) exists — add new languages as `{lang}.json` in `src/i18n/`
56
+ - Components using text must `import T from 'i18n-react'`
57
+
58
+ ## Common Mistakes
59
+
60
+ - Hardcoding user-facing strings instead of using `T.translate()`
61
+ - Adding keys without updating `en.json` (renders the key path as literal text)
62
+ - Using wrong namespace (check `en.json` for existing sections before creating new ones)
@@ -0,0 +1,77 @@
1
+ # Multi-Step Registration Flow
2
+
3
+ ## When to Apply
4
+
5
+ Adding step-specific logic, modifying step transitions, or rendering step-dependent UI.
6
+
7
+ ## Step Constants
8
+
9
+ Defined in `src/utils/constants.js`:
10
+
11
+ ```javascript
12
+ export const STEP_SELECT_TICKET_TYPE = 0; // Ticket selection + promo code
13
+ export const STEP_PERSONAL_INFO = 1; // Attendee details + ticket assignment
14
+ export const STEP_PAYMENT = 2; // Payment form (Stripe/LawPay)
15
+ export const STEP_COMPLETE = 3; // Order confirmation
16
+ ```
17
+
18
+ ## Step Transitions
19
+
20
+ **Forward flow (happy path):**
21
+
22
+ ```
23
+ STEP_SELECT_TICKET_TYPE → (Next/validate promo) → STEP_PERSONAL_INFO
24
+ STEP_PERSONAL_INFO → (submit form) → reserveTicket → STEP_PAYMENT
25
+ STEP_PAYMENT → (pay) → payTicketWithProvider → STEP_COMPLETE
26
+ ```
27
+
28
+ **Special cases:**
29
+
30
+ | Scenario | Transition |
31
+ |----------|------------|
32
+ | Free ticket (cost === 0) | `STEP_PERSONAL_INFO` → skip payment → `STEP_COMPLETE` |
33
+ | Pre-paid ticket | `STEP_PERSONAL_INFO` → skip payment → `STEP_COMPLETE` |
34
+ | Payment failure | `STEP_PAYMENT` → `removeReservedTicket()` → `STEP_PERSONAL_INFO` |
35
+ | No ticket selected + back | Any step → `STEP_SELECT_TICKET_TYPE` |
36
+
37
+ **Back navigation:**
38
+
39
+ - From `STEP_PERSONAL_INFO`: `changeStep(step - 1)`
40
+ - From `STEP_PAYMENT`: `removeReservedTicket()` (clears reservation, reducer resets to `STEP_PERSONAL_INFO`)
41
+
42
+ ## Redux Integration
43
+
44
+ ```javascript
45
+ // Action
46
+ export const changeStep = (step) => (dispatch, getState) => {
47
+ dispatch(createAction(CHANGE_STEP)(step));
48
+ };
49
+
50
+ // Reducer
51
+ case CHANGE_STEP: {
52
+ return { ...state, step: payload };
53
+ }
54
+ ```
55
+
56
+ Default state: `step: STEP_SELECT_TICKET_TYPE`
57
+
58
+ ## Rendering Pattern
59
+
60
+ In `registration-lite.js`, each step renders conditionally:
61
+
62
+ ```javascript
63
+ <StepComponent isActive={step === STEP_SELECT_TICKET_TYPE} ... />
64
+ <StepComponent isActive={step === STEP_PERSONAL_INFO} ... />
65
+ <StepComponent isActive={step === STEP_PAYMENT} ... />
66
+ {step === STEP_COMPLETE && <PurchaseCompleteComponent ... />}
67
+ ```
68
+
69
+ - Steps 0-2 share layout with `ButtonBarComponent`
70
+ - Step 3 (complete) has its own layout, no button bar
71
+ - Button bar renders step-specific buttons based on current `step` value
72
+
73
+ ## Common Mistakes
74
+
75
+ - Skipping `removeReservedTicket()` when going back from payment (leaves stale reservation)
76
+ - Not checking `reservation` existence before allowing forward navigation
77
+ - Adding steps without updating `ButtonBarComponent` (buttons won't render for new step)
@@ -0,0 +1,71 @@
1
+ # Utility Functions
2
+
3
+ ## When to Apply
4
+
5
+ Working with ticket pricing, order status checks, payment provider resolution, or UI color logic.
6
+
7
+ ## Key Functions (`src/utils/utils.js`)
8
+
9
+ ### Order/Ticket Status Checks
10
+
11
+ ```javascript
12
+ isFreeOrder(reservation) // reservation.amount === 0
13
+ isPrePaidOrder(reservation) // status === 'Paid' && payment_method === 'Offline'
14
+ isPrePaidTicketType(ticketType) // ticketType.sub_type === 'PrePaid'
15
+ hasDiscountApplied(ticketType) // has cost_with_applied_discount !== cost
16
+ ```
17
+
18
+ Used in payment providers to decide whether to skip the payment gateway.
19
+
20
+ ### Pricing Display
21
+
22
+ ```javascript
23
+ getTicketCost(ticket, quantity) // Returns JSX: strikethrough original + discounted price, or just price
24
+ getTicketTaxes(ticket, taxes) // Returns tax label string: " plus Tax A & Tax B"
25
+ formatCurrency(amount, { currency }) // From helpers/ — locale-aware currency formatting
26
+ ```
27
+
28
+ ### Payment Provider Resolution
29
+
30
+ ```javascript
31
+ getCurrentProvider(summit)
32
+ // Iterates summit.payment_profiles for application_type === 'Registration'
33
+ // Returns { publicKey, provider } — uses test vs live key based on test_mode_enabled
34
+ ```
35
+
36
+ ### UI Helpers
37
+
38
+ ```javascript
39
+ getContrastingTextColor(bgColor, lightColor, darkColor) // WCAG luminance contrast
40
+ parseColor(input, element) // Resolves CSS variables to RGB
41
+ removeWhiteSpaces(value) // Strip all whitespace
42
+ isEmptyString(val) // Trim-aware empty check
43
+ ```
44
+
45
+ ### Error Tracking
46
+
47
+ ```javascript
48
+ handleSentryException(err) // Sends to Sentry if window.SENTRY_DSN is set, else console.log
49
+ ```
50
+
51
+ ### Analytics
52
+
53
+ ```javascript
54
+ buildTrackEvent(data, ticketQuantity, promoCode)
55
+ // Builds GA4-style event data with currency, items_array, discount
56
+ ```
57
+
58
+ ## Helper Exports (`src/helpers/`)
59
+
60
+ Barrel export from `src/helpers/index.js`:
61
+
62
+ - `capitalizeFirstLetter` — text formatting
63
+ - `formatCurrency` — locale-aware currency display
64
+ - `formatErrorMessage` — error message normalization
65
+ - `getTicketMaxQuantity` — ticket quantity constraints
66
+
67
+ ## Common Mistakes
68
+
69
+ - Using `reservation.amount === 0` directly instead of `isFreeOrder()` (misses edge cases)
70
+ - Forgetting `isPrePaidOrder()` check alongside `isFreeOrder()` in payment flows
71
+ - Not handling `getCurrentProvider()` returning `{ publicKey: null, provider: '' }` when no payment profile exists
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "summit-registration-lite",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Summit Registration Lite",
5
5
  "main": "index.js",
6
6
  "scripts": {