summit-registration-lite 6.0.9 → 7.0.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.
Files changed (30) hide show
  1. package/.claude/rules/summit-registration-lite-component-props.md +95 -0
  2. package/.claude/rules/summit-registration-lite-payment-providers.md +69 -0
  3. package/.claude/rules/summit-registration-lite-project.md +80 -0
  4. package/.claude/rules/summit-registration-lite-redux-actions.md +65 -0
  5. package/.claude/rules/summit-registration-lite-testing.md +97 -0
  6. package/.claude/skills/summit-registration-lite-add-provider/SKILL.md +155 -0
  7. package/.claude/skills/summit-registration-lite-dev-setup/SKILL.md +67 -0
  8. package/.claude/skills/summit-registration-lite-publish/SKILL.md +64 -0
  9. package/.claude/skills/summit-registration-lite-scaffold-component/SKILL.md +152 -0
  10. package/dist/components/index.css +34 -0
  11. package/dist/components/index.css.map +1 -0
  12. package/dist/components/index.js +4907 -0
  13. package/dist/components/index.js.map +1 -0
  14. package/dist/components/registration-form.css +32 -0
  15. package/dist/components/registration-form.css.map +1 -0
  16. package/dist/components/registration-form.js +4726 -0
  17. package/dist/components/registration-form.js.map +1 -0
  18. package/dist/components/registration-modal.css +34 -0
  19. package/dist/components/registration-modal.css.map +1 -0
  20. package/dist/components/registration-modal.js +4870 -0
  21. package/dist/components/registration-modal.js.map +1 -0
  22. package/dist/index.css +2 -2
  23. package/dist/index.css.map +1 -1
  24. package/dist/index.js +4127 -3892
  25. package/dist/index.js.map +1 -1
  26. package/index.js +2 -0
  27. package/package.json +1 -1
  28. package/.cert/cert.pem +0 -26
  29. package/.cert/key.pem +0 -28
  30. package/ca.cer +0 -0
@@ -0,0 +1,95 @@
1
+ # Component Prop Conventions
2
+
3
+ ## When to Apply
4
+
5
+ Defining props for new components or understanding prop flow from widget to child components.
6
+
7
+ ## Pattern
8
+
9
+ **Widget Root (RegistrationLiteWidget):**
10
+
11
+ Parent app passes all props to widget, which wraps `<RegistrationLite>` in Redux Provider.
12
+
13
+ **Main Component (RegistrationLite):**
14
+
15
+ ```javascript
16
+ const RegistrationLite = ({
17
+ // Lifecycle callbacks (parent app control)
18
+ authUser, // (provider) => void - handle SSO login
19
+ goToExtraQuestions, // (attendeeId) => void - redirect to extra questions
20
+ goToEvent, // () => void - redirect to event page
21
+ goToMyOrders, // () => void - redirect to my orders
22
+ onPurchaseComplete, // (order) => void - handle successful purchase
23
+ closeWidget, // () => void - close/minimize widget
24
+
25
+ // Auth callbacks
26
+ getPasswordlessCode, // (email) => void - request OTP code
27
+ loginWithCode, // (email, code) => void - verify OTP
28
+ authErrorCallback, // (error) => void - handle auth errors
29
+
30
+ // Error handling
31
+ onError, // ({type, msg, exception}) => void
32
+ handleCompanyError, // (error) => void - company dropdown errors
33
+
34
+ // Data
35
+ summitData, // { id, name, time_zone, registration_disclaimer, ... }
36
+ profileData, // { email, first_name, last_name, company, ... }
37
+
38
+ // Config
39
+ apiBaseUrl, // Base URL for API calls
40
+ supportEmail, // Support email for help text
41
+ allowPromoCodes, // boolean - show/hide promo code field (default: true)
42
+ showCompanyInput, // boolean - show/hide company field (default: true)
43
+ allowsNativeAuth, // boolean - show email/password login
44
+ allowsOtpAuth, // boolean - show passwordless OTP login
45
+ loginOptions, // [{ button_color, provider_label, provider_param }]
46
+
47
+ // UI customization
48
+ loading, // boolean - external loading state
49
+ showMultipleTicketTexts, // boolean - show multi-ticket messaging
50
+ hidePostalCode, // boolean - hide postal code in payment (default: false)
51
+ idpLogoDark, // string - custom logo src (dark theme)
52
+ idpLogoLight, // string - custom logo src (light theme)
53
+
54
+ // Messages (optional overrides)
55
+ noAllowedTicketsMessage,
56
+ ticketTaxesErrorMessage,
57
+
58
+ // Provider options
59
+ providerOptions, // { stripe: {...}, lawpay: {...} }
60
+ successfulPaymentReturnUrl, // Stripe return URL after payment
61
+
62
+ // Redux state (from connect)
63
+ step, reservation, ticketTypes, taxTypes, ...
64
+
65
+ // Redux actions (from connect)
66
+ loadSession, changeStep, reserveTicket, payTicketWithProvider, ...
67
+ }) => { /* ... */ }
68
+ ```
69
+
70
+ ## Key Points
71
+
72
+ - **Callback pattern:** Parent app controls navigation (`goToExtraQuestions`, `goToEvent`, etc.) - widget doesn't redirect directly
73
+ - **Error handling delegation:** Widget calls `onError` / `authErrorCallback` / `handleCompanyError`, parent decides what to do
74
+ - **Data vs. Config:** `summitData` is event info, `profileData` is user info, others are config/behavior flags
75
+ - **Optional overrides:** Most text/messages have defaults but can be overridden via props
76
+ - **Redux separation:** Connected props (`step`, `reservation`) vs. passed props (callbacks, config)
77
+
78
+ ## Prop Flow Example
79
+
80
+ ```
81
+ Parent App
82
+ └─> RegistrationLiteWidget (wraps Provider)
83
+ └─> RegistrationLite (receives props + Redux state)
84
+ ├─> LoginComponent (loginOptions, allowsNativeAuth, allowsOtpAuth)
85
+ ├─> TicketTypeComponent (ticketTypes, summitData)
86
+ ├─> PersonalInfoComponent (profileData, showCompanyInput)
87
+ └─> PaymentComponent (reservation, providerOptions)
88
+ ```
89
+
90
+ ## Common Mistakes
91
+
92
+ - Hardcoding navigation instead of calling prop callbacks (breaks widget embedding)
93
+ - Not providing `apiBaseUrl` (causes API calls to fail)
94
+ - Forgetting `onError` handler (errors go to console only, user sees nothing)
95
+ - Passing incomplete `summitData` (missing `time_zone` breaks clock, missing `id` breaks API calls)
@@ -0,0 +1,69 @@
1
+ # Payment Provider Integration
2
+
3
+ ## When to Apply
4
+
5
+ Adding or modifying payment providers (Stripe, LawPay, or new providers).
6
+
7
+ ## Pattern
8
+
9
+ **Factory Pattern:** `PaymentProviderFactory.build(provider, params)` returns provider instance.
10
+
11
+ **Provider Structure:**
12
+
13
+ ```javascript
14
+ export class NewProvider {
15
+ constructor({ reservation, summitId, userProfile, access_token, apiBaseUrl, dispatch }) {
16
+ // Store params as instance properties
17
+ this.reservation = reservation;
18
+ this.summitId = summitId;
19
+ // ... etc
20
+ }
21
+
22
+ payTicket = ({ /* provider-specific params */, onError = () => {} }) => async (dispatch) => {
23
+ // 1. Custom error handler for HTTP status codes
24
+ const errorHandler = (err, res) => (dispatch, state) => {
25
+ switch (err.status) {
26
+ case 404: onError({type: ERROR_TYPE_VALIDATION, msg: res.body.message, exception: null}); break;
27
+ case 500: onError({type: ERROR_TYPE_ERROR, msg: res.body.message, exception: null}); break;
28
+ default: authErrorHandler(err, res)(dispatch, state); break;
29
+ }
30
+ };
31
+
32
+ // 2. Free/prepaid orders skip payment gateway
33
+ if (isFreeOrder(this.reservation) || isPrePaidOrder(this.reservation)) {
34
+ return putRequest(/* ... checkout endpoint ... */)(params)(this.dispatch);
35
+ }
36
+
37
+ // 3. Payment gateway flow (provider-specific)
38
+ // Call gateway API, handle result, then checkout
39
+ }
40
+ }
41
+ ```
42
+
43
+ **Factory Registration:**
44
+
45
+ ```javascript
46
+ // src/utils/payment-providers/payment-provider-factory.js
47
+ import { NEW_PROVIDER } from '../constants';
48
+ import { NewProvider } from './new-provider';
49
+
50
+ case NEW_PROVIDER: {
51
+ currentProvider = new NewProvider({...params});
52
+ break;
53
+ }
54
+ ```
55
+
56
+ ## Key Points
57
+
58
+ - Free/prepaid orders always skip gateway, go straight to `/checkout` endpoint
59
+ - Error types: `ERROR_TYPE_VALIDATION` (404), `ERROR_TYPE_ERROR` (500), `ERROR_TYPE_PAYMENT` (gateway errors)
60
+ - Always dispatch `startWidgetLoading()` before async ops, `stopWidgetLoading()` after
61
+ - Success flow: checkout API → `CLEAR_RESERVATION` → `changeStep(STEP_COMPLETE)`
62
+ - Failure flow: `removeReservedTicket()` → `changeStep(STEP_PERSONAL_INFO)`
63
+ - Checkout endpoint requires billing address fields from `userProfile`
64
+
65
+ ## Common Mistakes
66
+
67
+ - Forgetting to handle free/prepaid orders (they don't have `payment_gateway_client_token`)
68
+ - Not calling `removeReservedTicket()` on payment failure (leaves stale reservation)
69
+ - Missing `stopWidgetLoading()` in catch blocks (spinner never stops)
@@ -0,0 +1,80 @@
1
+ # Project: Summit Registration Lite
2
+
3
+ **Last Updated:** 2026-03-05
4
+
5
+ ## Overview
6
+
7
+ React widget for summit registration supporting authentication, ticket selection, payment processing, and order completion. Published as NPM package, designed to be embedded in parent applications.
8
+
9
+ ## Technology Stack
10
+
11
+ - **Language:** JavaScript (ES6+)
12
+ - **Framework:** React 16+ with Redux for state management
13
+ - **Build Tool:** Webpack 5 (dev/prod configs)
14
+ - **Testing:** Jest with @testing-library/react
15
+ - **Package Manager:** Yarn
16
+ - **Key Libraries:**
17
+ - openstack-uicore-foundation (HTTP utils, actions)
18
+ - redux-persist (state persistence)
19
+ - Stripe.js and custom payment providers
20
+ - Material-UI (@mui/material)
21
+
22
+ ## Directory Structure
23
+
24
+ ```
25
+ summit-registration-lite/
26
+ ├── src/
27
+ │ ├── components/ # React components (login, payment, tickets, etc.)
28
+ │ ├── utils/
29
+ │ │ ├── payment-providers/ # Stripe, LawPay provider implementations
30
+ │ │ ├── hooks/ # Custom React hooks
31
+ │ │ └── constants.js # Step constants, error types
32
+ │ ├── helpers/ # Formatting utilities
33
+ │ ├── actions.js # Redux action creators (API calls)
34
+ │ ├── reducer.js # Redux reducer
35
+ │ ├── store.js # Redux store configuration
36
+ │ └── summit-registration-lite.js # Main widget export
37
+ ├── webpack.common.js
38
+ ├── webpack.dev.js
39
+ ├── webpack.prod.js
40
+ └── babel.config.js
41
+ ```
42
+
43
+ ## Key Files
44
+
45
+ - **Entry:** `src/summit-registration-lite.js` - Provider wrapper, exports widget and standalone login components
46
+ - **Main Component:** `src/components/registration-lite.js` - Multi-step registration flow
47
+ - **Actions:** `src/actions.js` - API integration (ticket types, reservations, payments)
48
+ - **Payment:** `src/utils/payment-providers/` - Factory pattern for payment provider abstraction
49
+ - **Config:** `webpack.common.js` - Shared webpack configuration
50
+
51
+ ## Development Commands
52
+
53
+ | Task | Command |
54
+ |------|---------|
55
+ | Install | `yarn` |
56
+ | Dev Server | `yarn serve` |
57
+ | Build Dev | `yarn build-dev` |
58
+ | Build Prod | `yarn build` |
59
+ | Test (watch) | `yarn test` |
60
+ | Clean | `yarn clean` |
61
+ | Publish | `yarn publish-package` |
62
+
63
+ ## Architecture Notes
64
+
65
+ - **State:** Redux with redux-persist for cross-session state
66
+ - **API Base:** Configurable via props (`apiBaseUrl`), uses openstack-uicore-foundation HTTP utils
67
+ - **Payment Providers:** Factory pattern (`PaymentProviderFactory`) supports Stripe and LawPay
68
+ - **Steps:** Multi-step flow defined in `utils/constants.js` (login, personal info, payment, complete)
69
+ - **Auth:** Supports native auth, OTP (passwordless), and configurable SSO providers via `loginOptions` prop
70
+ - **Integration:** Widget receives callbacks (`authUser`, `goToExtraQuestions`, `onPurchaseComplete`, etc.) for parent app control
71
+
72
+ ## Testing
73
+
74
+ - Jest configuration in `package.json`
75
+ - Component tests in `__tests__` directories alongside components
76
+ - Mock files for static assets (`src/__mocks__/fileMock.js`)
77
+
78
+ ## Debug Mode
79
+
80
+ URL hash override for testing time-based logic: `#now=2020-06-03,10:59:50` (summit timezone)
@@ -0,0 +1,65 @@
1
+ # Redux API Action Patterns
2
+
3
+ ## When to Apply
4
+
5
+ Creating new API actions or modifying existing ones in `src/actions.js`.
6
+
7
+ ## Pattern
8
+
9
+ **Action Structure (openstack-uicore-foundation):**
10
+
11
+ ```javascript
12
+ export const GET_DATA = 'GET_DATA';
13
+
14
+ export const getData = (summitId) => async (dispatch, getState) => {
15
+ const { apiBaseUrl } = getState().registration;
16
+
17
+ const params = {
18
+ access_token: await accessTokenSelector()(dispatch, getState),
19
+ expand: 'relations,nested.relations'
20
+ };
21
+
22
+ return getRequest(
23
+ null,
24
+ createAction(GET_DATA),
25
+ `${apiBaseUrl}/api/v1/summits/${summitId}/resource`,
26
+ customErrorHandler // optional
27
+ )(params)(dispatch);
28
+ };
29
+ ```
30
+
31
+ **Error Handling:**
32
+
33
+ ```javascript
34
+ const customErrorHandler = (err, res) => (dispatch, state) => {
35
+ if (err.timeout) return err;
36
+ if (res?.statusCode === 404) return err; // Handle specific codes
37
+ if (res?.statusCode === 500) return err;
38
+ return authErrorHandler(err, res)(dispatch, state); // Default auth handling
39
+ };
40
+ ```
41
+
42
+ **Reducer Convention:**
43
+
44
+ ```javascript
45
+ case GET_DATA: {
46
+ return {...state, data: payload.response};
47
+ }
48
+ ```
49
+
50
+ ## Key Points
51
+
52
+ - Actions exported as constants (`export const ACTION_NAME`) AND action creators (`export const actionName`)
53
+ - Use `createAction()` from openstack-uicore-foundation for action creators
54
+ - HTTP methods: `getRequest`, `postRequest`, `putRequest`, `deleteRequest`
55
+ - Always pass `params` object with `access_token` (use `accessTokenSelector()` or widget prop)
56
+ - Use `expand` param for nested relations (dot notation: `tickets.owner.extra_questions`)
57
+ - Custom error handlers must return `authErrorHandler` as default case
58
+ - Thunk signature: `(dispatch, getState) => { ... }`
59
+
60
+ ## Common Mistakes
61
+
62
+ - Forgetting to await `accessTokenSelector()` (results in Promise instead of token)
63
+ - Not handling 404/500 in custom error handlers (triggers unwanted auth errors)
64
+ - Hardcoding API base URL (always use `state.registration.apiBaseUrl` or prop)
65
+ - Missing `expand` params (causes N+1 queries or missing data in components)
@@ -0,0 +1,97 @@
1
+ # Testing Patterns
2
+
3
+ ## When to Apply
4
+
5
+ Writing new component tests or maintaining existing tests.
6
+
7
+ ## Pattern
8
+
9
+ **Test Structure:**
10
+
11
+ ```javascript
12
+ import React from 'react';
13
+ import { render, fireEvent, waitFor, screen } from '@testing-library/react';
14
+ import '@testing-library/jest-dom';
15
+ import ComponentName from '..';
16
+
17
+ const mockCallback = jest.fn();
18
+
19
+ afterEach(() => {
20
+ jest.clearAllMocks(); // Reset mocks between tests
21
+ });
22
+
23
+ it('describes expected behavior', () => {
24
+ const { getByTestId, getAllByTestId, queryByText } = render(
25
+ <ComponentName prop1={value1} callback={mockCallback} />
26
+ );
27
+
28
+ // Arrange: find elements
29
+ const button = getByTestId('button-id');
30
+
31
+ // Act: interact
32
+ fireEvent.click(button);
33
+
34
+ // Assert: verify outcome
35
+ expect(mockCallback).toHaveBeenCalledWith(expectedArg);
36
+ });
37
+ ```
38
+
39
+ **Common Queries:**
40
+
41
+ ```javascript
42
+ // Single element (throws if not found)
43
+ getByTestId('id') // data-testid attribute
44
+ getByText('text') // visible text content
45
+ getByRole('button') // ARIA role
46
+
47
+ // Multiple elements
48
+ getAllByTestId('id') // returns array
49
+
50
+ // Nullable queries (returns null if not found)
51
+ queryByText('text') // useful for "expect().toBeFalsy()"
52
+
53
+ // From screen utility
54
+ screen.queryByText('text')
55
+ ```
56
+
57
+ **Async Testing:**
58
+
59
+ ```javascript
60
+ it('handles async behavior', async () => {
61
+ const { getByTestId } = render(<Component />);
62
+
63
+ fireEvent.click(getByTestId('async-button'));
64
+
65
+ await waitFor(() => {
66
+ expect(getByTestId('result')).toBeInTheDocument();
67
+ });
68
+ });
69
+ ```
70
+
71
+ ## Key Points
72
+
73
+ - Tests live in `__tests__/` directories alongside components
74
+ - Use `data-testid` attributes for reliable element selection
75
+ - Mock callbacks with `jest.fn()`, verify with `.toHaveBeenCalled()` or `.toHaveBeenCalledWith()`
76
+ - Use `queryBy*` for negative assertions (`expect().toBeFalsy()`)
77
+ - Use `getBy*` for positive assertions (throws if element missing)
78
+ - `@testing-library/react` auto-cleanup enabled (no manual unmount needed)
79
+ - CSS/SCSS mocked via `identity-obj-proxy` (className checks work)
80
+ - Static assets (images) mocked via `src/__mocks__/fileMock.js`
81
+
82
+ ## Test Organization
83
+
84
+ ```
85
+ src/components/my-component/
86
+ ├── index.js
87
+ ├── my-component.module.scss
88
+ └── __tests__/
89
+ └── my-component.test.js
90
+ ```
91
+
92
+ ## Common Mistakes
93
+
94
+ - Using brittle selectors (text content that changes) instead of `data-testid`
95
+ - Forgetting `@testing-library/jest-dom` import (causes `.toBeInTheDocument()` to fail)
96
+ - Not awaiting async operations (tests pass locally, fail in CI due to timing)
97
+ - Testing implementation details instead of user behavior (prefer user interactions over internal state checks)
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: summit-registration-lite-add-provider
3
+ version: 1.0.0
4
+ description: Scaffold new payment provider with factory registration
5
+ triggers:
6
+ - add payment provider
7
+ - new payment gateway
8
+ - integrate payment
9
+ ---
10
+
11
+ # Add Payment Provider Workflow
12
+
13
+ Scaffolds a new payment provider class with factory registration, error handling, and test template.
14
+
15
+ ## Steps
16
+
17
+ 1. **Ask for provider details**
18
+ - Provider name (e.g., "PayPal", "Square")
19
+ - Provider constant (e.g., "PAYMENT_PROVIDER_PAYPAL")
20
+ - Gateway-specific fields needed (API keys, client IDs, etc.)
21
+
22
+ 2. **Add constant to utils/constants.js**
23
+ ```javascript
24
+ export const PAYMENT_PROVIDER_NEWNAME = 'new_provider_name';
25
+ ```
26
+
27
+ 3. **Create provider class**
28
+ File: `src/utils/payment-providers/{name}-provider.js`
29
+
30
+ Use StripeProvider as template:
31
+ - Constructor receives: `{ reservation, summitId, userProfile, access_token, apiBaseUrl, dispatch }`
32
+ - Implement `payTicket` method with signature:
33
+ ```javascript
34
+ payTicket = ({ /* gateway-specific params */, onError = () => {} }) => async (dispatch) => {
35
+ // Implementation
36
+ }
37
+ ```
38
+ - Handle free/prepaid orders (skip gateway, call `/checkout` directly)
39
+ - Custom error handler for HTTP status codes (404 → VALIDATION, 500 → ERROR)
40
+ - Success flow: checkout → CLEAR_RESERVATION → changeStep(STEP_COMPLETE)
41
+ - Failure flow: removeReservedTicket → changeStep(STEP_PERSONAL_INFO)
42
+
43
+ 4. **Register in factory**
44
+ File: `src/utils/payment-providers/payment-provider-factory.js`
45
+
46
+ Add import and case:
47
+ ```javascript
48
+ import { NewProvider } from './new-provider';
49
+
50
+ case PAYMENT_PROVIDER_NEWNAME: {
51
+ currentProvider = new NewProvider({...params});
52
+ break;
53
+ }
54
+ ```
55
+
56
+ 5. **Add provider component** (if custom UI needed)
57
+ File: `src/components/{name}-component/index.js`
58
+
59
+ Handles gateway-specific UI (payment form, buttons, etc.).
60
+
61
+ 6. **Create test file**
62
+ File: `src/utils/payment-providers/__tests__/{name}-provider.test.js`
63
+
64
+ Mock patterns:
65
+ - Mock API calls (putRequest)
66
+ - Mock gateway SDK (if any)
67
+ - Test free/prepaid flow
68
+ - Test error handling
69
+
70
+ 7. **Update PaymentComponent**
71
+ File: `src/components/payment/index.js`
72
+
73
+ Add conditional rendering for new provider UI.
74
+
75
+ ## Provider Template
76
+
77
+ ```javascript
78
+ import { createAction, putRequest, authErrorHandler } from 'openstack-uicore-foundation/lib/utils/actions';
79
+ import { CLEAR_RESERVATION, PAY_RESERVATION } from '../../actions';
80
+ import { changeStep, removeReservedTicket, startWidgetLoading, stopWidgetLoading } from '../../actions';
81
+ import { isFreeOrder, isPrePaidOrder } from '../utils';
82
+ import { ERROR_TYPE_ERROR, ERROR_TYPE_VALIDATION, STEP_COMPLETE, STEP_PERSONAL_INFO } from '../constants';
83
+
84
+ export class NewProvider {
85
+ constructor({ reservation, summitId, userProfile, access_token, apiBaseUrl, dispatch }) {
86
+ this.reservation = reservation;
87
+ this.summitId = summitId;
88
+ this.userProfile = userProfile;
89
+ this.access_token = access_token;
90
+ this.apiBaseUrl = apiBaseUrl;
91
+ this.dispatch = dispatch;
92
+ }
93
+
94
+ payTicket = ({ /* custom params */, onError = () => {} }) => async (dispatch) => {
95
+ const errorHandler = (err, res) => (dispatch, state) => {
96
+ let code = err.status;
97
+ switch (code) {
98
+ case 404: onError({type: ERROR_TYPE_VALIDATION, msg: res.body.message, exception: null}); break;
99
+ case 500: onError({type: ERROR_TYPE_ERROR, msg: res.body.message, exception: null}); break;
100
+ default: authErrorHandler(err, res)(dispatch, state); break;
101
+ }
102
+ };
103
+
104
+ const normalizedEntity = {
105
+ billing_address_1: this.userProfile?.address1 || '',
106
+ billing_address_2: this.userProfile?.address2 || '',
107
+ billing_address_city: this.userProfile?.locality || '',
108
+ billing_address_state: this.userProfile?.region || '',
109
+ billing_address_country: this.userProfile?.country || ''
110
+ };
111
+
112
+ dispatch(startWidgetLoading());
113
+
114
+ // Free/prepaid orders
115
+ if (isFreeOrder(this.reservation) || isPrePaidOrder(this.reservation)) {
116
+ return this.checkout(normalizedEntity, errorHandler, onError);
117
+ }
118
+
119
+ // Gateway-specific payment flow here
120
+ // Then call this.checkout() on success
121
+ };
122
+
123
+ checkout = (normalizedEntity, errorHandler, onError) => {
124
+ const params = { access_token: this.access_token, expand: 'tickets,tickets.owner,...' };
125
+
126
+ return putRequest(
127
+ null,
128
+ createAction(PAY_RESERVATION),
129
+ `${this.apiBaseUrl}/api/v1/summits/${this.summitId}/orders/${this.reservation.hash}/checkout`,
130
+ normalizedEntity,
131
+ errorHandler
132
+ )(params)(this.dispatch)
133
+ .then((payload) => {
134
+ this.dispatch(stopWidgetLoading());
135
+ this.dispatch(createAction(CLEAR_RESERVATION)({}));
136
+ this.dispatch(changeStep(STEP_COMPLETE));
137
+ return payload;
138
+ })
139
+ .catch(e => {
140
+ this.dispatch(stopWidgetLoading());
141
+ this.dispatch(removeReservedTicket());
142
+ this.dispatch(changeStep(STEP_PERSONAL_INFO));
143
+ onError({type: ERROR_TYPE_ERROR, msg: e?.message, exception: e});
144
+ return e;
145
+ });
146
+ };
147
+ }
148
+ ```
149
+
150
+ ## Testing
151
+
152
+ Run provider tests:
153
+ ```bash
154
+ yarn test payment-providers
155
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: summit-registration-lite-dev-setup
3
+ version: 1.0.0
4
+ description: Clean install and start development server
5
+ triggers:
6
+ - setup dev environment
7
+ - start dev server
8
+ - clean install
9
+ ---
10
+
11
+ # Development Setup Workflow
12
+
13
+ Cleans existing installation and starts fresh development environment.
14
+
15
+ ## Steps
16
+
17
+ ### Option 1: Clean Setup (Recommended for Issues)
18
+
19
+ 1. **Clean all build artifacts and dependencies**
20
+ ```bash
21
+ yarn clean
22
+ ```
23
+ Removes `dist/` and `node_modules/`, then reinstalls with `yarn`.
24
+
25
+ 2. **Start dev server**
26
+ ```bash
27
+ yarn serve
28
+ ```
29
+ Starts webpack-dev-server on default port (usually 8080). Opens browser automatically.
30
+
31
+ ### Option 2: Quick Start (No Clean)
32
+
33
+ 1. **Install dependencies** (if `node_modules/` missing)
34
+ ```bash
35
+ yarn
36
+ ```
37
+
38
+ 2. **Start dev server**
39
+ ```bash
40
+ yarn serve
41
+ ```
42
+
43
+ ## Development Configuration
44
+
45
+ - **Webpack config:** `webpack.dev.js` (extends `webpack.common.js`)
46
+ - **Environment variables:**
47
+ - `API_BASE_URL` - API endpoint for development
48
+ - `ACCESS_TOKEN` - Auth token for standalone testing (stored in localStorage)
49
+
50
+ Set these in shell or `.env` file:
51
+ ```bash
52
+ export API_BASE_URL=https://api.dev.example.com
53
+ export ACCESS_TOKEN=your_dev_token
54
+ ```
55
+
56
+ ## Standalone Testing
57
+
58
+ The widget supports standalone mode in development. Set environment variables before running `yarn serve` to test without parent app.
59
+
60
+ ## Troubleshooting
61
+
62
+ | Issue | Solution |
63
+ |-------|----------|
64
+ | Port already in use | Kill process: `lsof -ti:8080 | xargs kill` or change port in webpack.dev.js |
65
+ | Stale cache | Run `yarn clean` |
66
+ | Module not found | Delete `node_modules/` and `yarn.lock`, then `yarn` |
67
+ | Hot reload not working | Check webpack-dev-server config, ensure `watchFiles` configured |
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: summit-registration-lite-publish
3
+ version: 1.0.0
4
+ description: Build and publish package to NPM registry
5
+ triggers:
6
+ - publish to npm
7
+ - release package
8
+ - deploy widget
9
+ ---
10
+
11
+ # Package Publishing Workflow
12
+
13
+ Builds the production bundle and publishes to NPM registry.
14
+
15
+ ## Steps
16
+
17
+ 1. **Verify clean state**
18
+ ```bash
19
+ git status
20
+ ```
21
+ Ensure no uncommitted changes. If changes exist, ask user to commit or stash first.
22
+
23
+ 2. **Verify version**
24
+ ```bash
25
+ cat package.json | grep '"version"'
26
+ ```
27
+ Confirm version with user before publishing. Ask if version should be bumped (patch/minor/major).
28
+
29
+ 3. **Build production bundle**
30
+ ```bash
31
+ yarn build
32
+ ```
33
+ Compiles with webpack.prod.js. Output goes to `dist/`.
34
+
35
+ 4. **Verify build output**
36
+ ```bash
37
+ ls -lh dist/
38
+ ```
39
+ Check that `index.js` and `index.css` exist.
40
+
41
+ 5. **Publish to NPM**
42
+ ```bash
43
+ yarn publish
44
+ ```
45
+ Prompts for new version (if not already updated). Requires NPM authentication.
46
+
47
+ ## Alternative: Combined Command
48
+
49
+ The `yarn publish-package` script combines build and publish:
50
+ ```bash
51
+ yarn publish-package
52
+ ```
53
+
54
+ ## Prerequisites
55
+
56
+ - NPM authentication configured (`npm login`)
57
+ - Write access to `summit-registration-lite` package on NPM
58
+ - Clean git working directory (or committed changes)
59
+
60
+ ## Post-Publish
61
+
62
+ - Tag the release in git: `git tag v{version}`
63
+ - Push tag: `git push origin v{version}`
64
+ - Update CHANGELOG.md with release notes