igloo-d2c-components 1.0.13 → 1.0.14
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/README.md +1151 -321
- package/dist/assets/icons/alert.svg +5 -0
- package/dist/assets/icons/arrow-down.svg +3 -0
- package/dist/assets/icons/arrow.svg +9 -0
- package/dist/assets/icons/close.svg +4 -0
- package/dist/assets/icons/facebook.svg +3 -0
- package/dist/assets/icons/index.ts +26 -0
- package/dist/assets/icons/instagram.svg +11 -0
- package/dist/assets/icons/youtube.svg +11 -0
- package/dist/assets/index.ts +13 -0
- package/dist/assets/tenants/ammetlife/logo.svg +10 -0
- package/dist/assets/tenants/cimb/logo-white.png +0 -0
- package/dist/assets/tenants/cimb/logo.svg +62 -0
- package/dist/assets/tenants/igloo/logo.svg +22 -0
- package/dist/cjs/index.js +2804 -41
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +2752 -41
- package/dist/esm/index.js.map +1 -1
- package/dist/types/assets/icons/index.d.ts +21 -0
- package/dist/types/assets/index.d.ts +9 -0
- package/dist/types/components/BenefitsSummary/BenefitsSummary.d.ts +22 -0
- package/dist/types/components/BenefitsSummary/index.d.ts +2 -0
- package/dist/types/components/BenefitsSummary/styled.d.ts +29 -0
- package/dist/types/components/BenefitsSummary/types.d.ts +58 -0
- package/dist/types/components/BillingToggle/BillingToggle.d.ts +34 -0
- package/dist/types/components/BillingToggle/index.d.ts +3 -0
- package/dist/types/components/BillingToggle/styled.d.ts +12 -0
- package/dist/types/components/CheckoutFormButton/CheckoutFormButton.d.ts +39 -0
- package/dist/types/components/CheckoutFormButton/index.d.ts +2 -0
- package/dist/types/components/CheckoutFormButton/styled.d.ts +9 -0
- package/dist/types/components/CheckoutHeader/CheckoutHeader.d.ts +41 -0
- package/dist/types/components/CheckoutHeader/index.d.ts +2 -0
- package/dist/types/components/CheckoutHeader/styled.d.ts +15 -0
- package/dist/types/components/CheckoutProgress/CheckoutProgress.d.ts +35 -0
- package/dist/types/components/CheckoutProgress/index.d.ts +2 -0
- package/dist/types/components/CheckoutProgress/styled.d.ts +16 -0
- package/dist/types/components/ChildInformationForm/ChildInformationForm.d.ts +52 -0
- package/dist/types/components/ChildInformationForm/index.d.ts +2 -0
- package/dist/types/components/ChildInformationForm/styled.d.ts +4 -0
- package/dist/types/components/ContactDetailsForm/ContactDetailsForm.d.ts +63 -0
- package/dist/types/components/ContactDetailsForm/index.d.ts +2 -0
- package/dist/types/components/ContactDetailsForm/styled.d.ts +10 -0
- package/dist/types/components/CoverageAmountSlider/CoverageAmountSlider.d.ts +57 -0
- package/dist/types/components/CoverageAmountSlider/index.d.ts +3 -0
- package/dist/types/components/CoverageAmountSlider/styled.d.ts +50 -0
- package/dist/types/components/FAQAccordion/FAQAccordion.d.ts +22 -0
- package/dist/types/components/FAQAccordion/index.d.ts +2 -0
- package/dist/types/components/FAQAccordion/styled.d.ts +37 -0
- package/dist/types/components/FAQAccordion/types.d.ts +57 -0
- package/dist/types/components/Footer/Footer.d.ts +94 -0
- package/dist/types/components/Footer/index.d.ts +3 -0
- package/dist/types/components/Footer/styled.d.ts +38 -0
- package/dist/types/components/Header/Header.d.ts +159 -0
- package/dist/types/components/Header/index.d.ts +3 -0
- package/dist/types/components/Header/styled.d.ts +80 -0
- package/dist/types/components/HealthInformationForm/HealthInformationForm.d.ts +81 -0
- package/dist/types/components/HealthInformationForm/index.d.ts +2 -0
- package/dist/types/components/HealthInformationForm/styled.d.ts +4 -0
- package/dist/types/components/HealthQuestionGroup/HealthQuestionGroup.d.ts +40 -0
- package/dist/types/components/HealthQuestionGroup/index.d.ts +2 -0
- package/dist/types/components/HealthQuestionGroup/styled.d.ts +20 -0
- package/dist/types/components/InfoCallout/InfoCallout.d.ts +34 -0
- package/dist/types/components/InfoCallout/index.d.ts +3 -0
- package/dist/types/components/InfoCallout/styled.d.ts +16 -0
- package/dist/types/components/NewHeader/NewHeader.d.ts +60 -0
- package/dist/types/components/NewHeader/index.d.ts +3 -0
- package/dist/types/components/NewHeader/styled.d.ts +26 -0
- package/dist/types/components/OptionButton/OptionButton.d.ts +59 -0
- package/dist/types/components/OptionButton/index.d.ts +3 -0
- package/dist/types/components/OptionButton/styled.d.ts +18 -0
- package/dist/types/components/PersonalInformationForm/PersonalInformationForm.d.ts +75 -0
- package/dist/types/components/PersonalInformationForm/index.d.ts +2 -0
- package/dist/types/components/PersonalInformationForm/styled.d.ts +10 -0
- package/dist/types/components/ProductCard/ProductCard.d.ts +43 -0
- package/dist/types/components/ProductCard/index.d.ts +2 -0
- package/dist/types/components/ProductCard/styled.d.ts +27 -0
- package/dist/types/components/ProductSelectionDrawer/ProductSelectionDrawer.d.ts +54 -0
- package/dist/types/components/ProductSelectionDrawer/index.d.ts +3 -0
- package/dist/types/components/ProductSelectionDrawer/styled.d.ts +44 -0
- package/dist/types/components/QuestionSection/QuestionSection.d.ts +71 -0
- package/dist/types/components/QuestionSection/index.d.ts +3 -0
- package/dist/types/components/QuestionSection/styled.d.ts +16 -0
- package/dist/types/components/RecommendationsDrawer/RecommendationsDrawer.d.ts +92 -0
- package/dist/types/components/RecommendationsDrawer/index.d.ts +3 -0
- package/dist/types/components/RecommendationsDrawer/styled.d.ts +35 -0
- package/dist/types/components/ToggleGroup/ToggleGroup.d.ts +45 -0
- package/dist/types/components/ToggleGroup/index.d.ts +3 -0
- package/dist/types/components/ToggleGroup/styled.d.ts +17 -0
- package/dist/types/context/TenantThemeContext.d.ts +3 -2
- package/dist/types/index.d.ts +52 -4
- package/dist/types/{components/Banner → storybook-components}/Banner.stories.d.ts +1 -1
- package/dist/types/storybook-components/BenefitsSummary.stories.d.ts +37 -0
- package/dist/types/storybook-components/BillingToggle.stories.d.ts +10 -0
- package/dist/types/{components/Button → storybook-components}/Button.stories.d.ts +1 -1
- package/dist/types/{components/Card → storybook-components}/Card.stories.d.ts +1 -1
- package/dist/types/storybook-components/CheckoutProgress.stories.d.ts +9 -0
- package/dist/types/storybook-components/CoverageAmountSlider.stories.d.ts +14 -0
- package/dist/types/storybook-components/FAQAccordion.stories.d.ts +37 -0
- package/dist/types/storybook-components/Footer.stories.d.ts +10 -0
- package/dist/types/storybook-components/Header.stories.d.ts +9 -0
- package/dist/types/storybook-components/HealthQuestionGroup.stories.d.ts +9 -0
- package/dist/types/storybook-components/InfoCallout.stories.d.ts +11 -0
- package/dist/types/storybook-components/NewHeader.stories.d.ts +82 -0
- package/dist/types/storybook-components/OptionButton.stories.d.ts +12 -0
- package/dist/types/storybook-components/ProductCard.stories.d.ts +9 -0
- package/dist/types/storybook-components/ProductSelectionDrawer.stories.d.ts +24 -0
- package/dist/types/storybook-components/QuestionSection.stories.d.ts +11 -0
- package/dist/types/storybook-components/RecommendationsDrawer.stories.d.ts +36 -0
- package/dist/types/storybook-components/ToggleGroup.stories.d.ts +10 -0
- package/dist/types/themes/index.d.ts +1 -1
- package/dist/types/themes/typography.d.ts +69 -0
- package/dist/types/types/tenant.d.ts +23 -2
- package/dist/types/utils/assets.d.ts +54 -0
- package/dist/types/utils/theme.d.ts +3 -2
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -5,17 +5,31 @@ Reusable React component library with **centralized tenant themes** and tenant-a
|
|
|
5
5
|
## 📋 Table of Contents
|
|
6
6
|
|
|
7
7
|
- [Overview](#-overview)
|
|
8
|
+
- [Project Architecture](#-project-architecture)
|
|
8
9
|
- [Features](#-features)
|
|
9
10
|
- [Installation](#-installation)
|
|
10
11
|
- [Quick Start](#-quick-start)
|
|
11
12
|
- [Centralized Themes](#-centralized-themes)
|
|
12
13
|
- [Components](#-components)
|
|
14
|
+
- [General Components](#general-components)
|
|
15
|
+
- [Interactive Components](#interactive-components)
|
|
16
|
+
- [Checkout Components](#checkout-components)
|
|
17
|
+
- [Form Components](#form-components)
|
|
13
18
|
- [Hooks & Utilities](#-hooks--utilities)
|
|
19
|
+
- [Asset Management](#-asset-management)
|
|
20
|
+
- [Integration Guide](#-integration-guide)
|
|
21
|
+
- [Multi-Tenant Architecture](#multi-tenant-architecture)
|
|
22
|
+
- [Checkout Flow Integration](#checkout-flow-integration)
|
|
23
|
+
- [Recommendations Feature](#recommendations-feature)
|
|
24
|
+
- [Header Integration](#header-integration)
|
|
25
|
+
- [Routing Guide](#routing-guide)
|
|
14
26
|
- [Development](#-development)
|
|
15
|
-
- [Publishing](#-publishing)
|
|
16
27
|
- [Storybook](#-storybook)
|
|
28
|
+
- [Build Pipeline](#-build-pipeline)
|
|
29
|
+
- [Publishing](#-publishing)
|
|
17
30
|
- [Technical Details](#-technical-details)
|
|
18
31
|
- [Troubleshooting](#-troubleshooting)
|
|
32
|
+
- [Changelog](#-changelog)
|
|
19
33
|
- [Contributing](#-contributing)
|
|
20
34
|
|
|
21
35
|
---
|
|
@@ -24,6 +38,15 @@ Reusable React component library with **centralized tenant themes** and tenant-a
|
|
|
24
38
|
|
|
25
39
|
The D2C Component Library provides reusable, tenant-aware UI components with **centralized theme management**. All tenant themes are defined in one place, ensuring consistency across all applications.
|
|
26
40
|
|
|
41
|
+
### What Are These Projects?
|
|
42
|
+
|
|
43
|
+
We've built a **multi-tenant B2C insurance platform** that enables rapid deployment of white-label insurance applications for different partners.
|
|
44
|
+
|
|
45
|
+
| Project | Purpose |
|
|
46
|
+
| ------------------------- | --------------------------------------------------------------------------- |
|
|
47
|
+
| **d2c-component-library** | Shared component library with centralized themes and reusable UI components |
|
|
48
|
+
| **b2c-web-demo** | Multi-tenant web application consuming the component library |
|
|
49
|
+
|
|
27
50
|
### Key Highlights
|
|
28
51
|
|
|
29
52
|
- 🎨 **Centralized Themes** - All tenant themes (Igloo, CIMB, AmmetLife) in one library
|
|
@@ -33,6 +56,70 @@ The D2C Component Library provides reusable, tenant-aware UI components with **c
|
|
|
33
56
|
- 📖 **Full TypeScript Support** - Complete type definitions
|
|
34
57
|
- ⚡ **Tree-Shakeable** - Import only what you need
|
|
35
58
|
|
|
59
|
+
### Supported Tenants
|
|
60
|
+
|
|
61
|
+
| Tenant | Port | Description |
|
|
62
|
+
| ------------- | ---- | ----------------------- |
|
|
63
|
+
| **Igloo** | 8000 | Default insurance brand |
|
|
64
|
+
| **AmmetLife** | 8001 | Life insurance partner |
|
|
65
|
+
| **CIMB** | 8002 | Banking partner |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 🏗️ Project Architecture
|
|
70
|
+
|
|
71
|
+
### The Solution Architecture
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
75
|
+
│ d2c-component-library │
|
|
76
|
+
│ ┌─────────────────────────────────────────────────────────────┐│
|
|
77
|
+
│ │ Centralized Themes ││
|
|
78
|
+
│ │ ┌───────────────────────┐ ┌───────────────────────┐ ││
|
|
79
|
+
│ │ │ iglooTheme │ │ ammetlifeTheme │ ││
|
|
80
|
+
│ │ └───────────────────────┘ └───────────────────────┘ ││
|
|
81
|
+
│ └─────────────────────────────────────────────────────────────┘│
|
|
82
|
+
│ ┌─────────────────────────────────────────────────────────────┐│
|
|
83
|
+
│ │ Shared Components ││
|
|
84
|
+
│ │ Button │ Card │ Banner │ Header │ CheckoutProgress │ ... ││
|
|
85
|
+
│ └─────────────────────────────────────────────────────────────┘│
|
|
86
|
+
│ ┌─────────────────────────────────────────────────────────────┐│
|
|
87
|
+
│ │ Theme Utilities ││
|
|
88
|
+
│ │ TenantThemeProvider │ useTenantTheme │ getTenantTheme ││
|
|
89
|
+
│ └─────────────────────────────────────────────────────────────┘│
|
|
90
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
91
|
+
│
|
|
92
|
+
▼
|
|
93
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
94
|
+
│ b2c-web-demo │
|
|
95
|
+
│ ┌─────────────────────────────────────────────────────────────┐│
|
|
96
|
+
│ │ Tenant Configurations ││
|
|
97
|
+
│ │ ┌───────────────────────┐ ┌───────────────────────┐ ││
|
|
98
|
+
│ │ │ igloo.ts │ │ ammetlife.ts │ ││
|
|
99
|
+
│ │ │ (uses iglooTheme) │ │ (uses ammetlifeTheme) │ ││
|
|
100
|
+
│ │ └───────────────────────┘ └───────────────────────┘ ││
|
|
101
|
+
│ └─────────────────────────────────────────────────────────────┘│
|
|
102
|
+
│ ┌─────────────────────────────────────────────────────────────┐│
|
|
103
|
+
│ │ Single Codebase, Multiple Tenants ││
|
|
104
|
+
│ │ yarn start-igloo → http://localhost:8000 ││
|
|
105
|
+
│ │ yarn start-ammetlife → http://localhost:8001 ││
|
|
106
|
+
│ └─────────────────────────────────────────────────────────────┘│
|
|
107
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Technical Stack
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
Frontend Framework: React 17 + TypeScript
|
|
114
|
+
Build System: UmiJS (React framework) for b2c-web-demo
|
|
115
|
+
UI Components: MUI v5 + Custom Components
|
|
116
|
+
Styling: Emotion (CSS-in-JS) + Tailwind CSS
|
|
117
|
+
State Management: Recoil + React Context
|
|
118
|
+
Component Library: Rollup (ES2015 output)
|
|
119
|
+
Documentation: Storybook
|
|
120
|
+
Package Manager: Yarn
|
|
121
|
+
```
|
|
122
|
+
|
|
36
123
|
---
|
|
37
124
|
|
|
38
125
|
## ✨ Features
|
|
@@ -47,23 +134,28 @@ The D2C Component Library provides reusable, tenant-aware UI components with **c
|
|
|
47
134
|
|
|
48
135
|
### Available Themes
|
|
49
136
|
|
|
50
|
-
| Tenant
|
|
51
|
-
|
|
52
|
-
| **Igloo**
|
|
53
|
-
| **CIMB**
|
|
54
|
-
| **AmmetLife** | `ammetlifeTheme` | Life insurance partner
|
|
137
|
+
| Tenant | Theme Export | Description |
|
|
138
|
+
| ------------- | ---------------- | ----------------------- |
|
|
139
|
+
| **Igloo** | `iglooTheme` | Default insurance brand |
|
|
140
|
+
| **CIMB** | `cimbTheme` | Banking partner theme |
|
|
141
|
+
| **AmmetLife** | `ammetlifeTheme` | Life insurance partner |
|
|
55
142
|
|
|
56
|
-
###
|
|
143
|
+
### Component Categories
|
|
57
144
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
145
|
+
| Category | Components |
|
|
146
|
+
| --------------- | ----------------------------------------------------------------------------------------- |
|
|
147
|
+
| **General** | Button, Card, Banner, Header, NewHeader, Footer |
|
|
148
|
+
| **Interactive** | RecommendationsDrawer, ProductSelectionDrawer, QuestionSection, OptionButton, ToggleGroup |
|
|
149
|
+
| **Checkout** | CheckoutProgress, ProductCard, CheckoutHeader, CheckoutFormButton, HealthQuestionGroup |
|
|
150
|
+
| **Forms** | PersonalInformationForm, ContactDetailsForm, HealthInformationForm |
|
|
61
151
|
|
|
62
152
|
### Hooks
|
|
63
153
|
|
|
64
154
|
- `useTenantTheme()` - Access tenant theme and ID
|
|
65
155
|
- `useTenantId()` - Get current tenant ID
|
|
66
156
|
- `useIsTenant()` - Check tenant match
|
|
157
|
+
- `useTenantLogo()` - Get tenant logo
|
|
158
|
+
- `useTenantAsset()` - Get tenant-specific asset
|
|
67
159
|
|
|
68
160
|
### Utilities
|
|
69
161
|
|
|
@@ -72,6 +164,27 @@ The D2C Component Library provides reusable, tenant-aware UI components with **c
|
|
|
72
164
|
- `getThemeColor()` - Extract colors from theme
|
|
73
165
|
- `createThemeCSSVariables()` - Generate CSS variables
|
|
74
166
|
|
|
167
|
+
### Key Benefits
|
|
168
|
+
|
|
169
|
+
#### For Development Teams
|
|
170
|
+
|
|
171
|
+
| Benefit | Impact |
|
|
172
|
+
| -------------------------- | -------------------------------------------------------- |
|
|
173
|
+
| **Single Source of Truth** | Update themes once, reflected everywhere |
|
|
174
|
+
| **~585 Lines Removed** | From consuming apps (no more duplicated themes) |
|
|
175
|
+
| **Type Safety** | Full TypeScript support with interfaces |
|
|
176
|
+
| **Faster Development** | Reuse tested components instead of building from scratch |
|
|
177
|
+
| **Better DX** | Hot reload, Storybook for component development |
|
|
178
|
+
|
|
179
|
+
#### For Business
|
|
180
|
+
|
|
181
|
+
| Benefit | Impact |
|
|
182
|
+
| ----------------------------- | -------------------------------------------- |
|
|
183
|
+
| **Faster Partner Onboarding** | Days instead of weeks to launch a new tenant |
|
|
184
|
+
| **Consistent UX** | Same quality experience across all brands |
|
|
185
|
+
| **Reduced Costs** | One team maintains one codebase |
|
|
186
|
+
| **Scalability** | Easy to add new tenants and features |
|
|
187
|
+
|
|
75
188
|
---
|
|
76
189
|
|
|
77
190
|
## 📦 Installation
|
|
@@ -101,6 +214,7 @@ yarn install
|
|
|
101
214
|
```
|
|
102
215
|
|
|
103
216
|
**Workflow:**
|
|
217
|
+
|
|
104
218
|
```bash
|
|
105
219
|
# Make changes to library
|
|
106
220
|
cd d2c-component-library
|
|
@@ -117,6 +231,7 @@ yarn install # Copies updated build
|
|
|
117
231
|
For production deployments and CI/CD.
|
|
118
232
|
|
|
119
233
|
**Install:**
|
|
234
|
+
|
|
120
235
|
```bash
|
|
121
236
|
yarn add igloo-d2c-components
|
|
122
237
|
# or
|
|
@@ -124,6 +239,7 @@ npm install igloo-d2c-components
|
|
|
124
239
|
```
|
|
125
240
|
|
|
126
241
|
**Configure authentication (if using private registry):**
|
|
242
|
+
|
|
127
243
|
```bash
|
|
128
244
|
# For npm
|
|
129
245
|
export NPM_AUTH_TOKEN="your-npm-token"
|
|
@@ -132,6 +248,28 @@ export NPM_AUTH_TOKEN="your-npm-token"
|
|
|
132
248
|
export GITLAB_NPM_TOKEN="glpat-your-token"
|
|
133
249
|
```
|
|
134
250
|
|
|
251
|
+
### Component Library Management Scripts (in b2c-web-demo)
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Check installed version
|
|
255
|
+
yarn lib:check
|
|
256
|
+
|
|
257
|
+
# Get package information
|
|
258
|
+
yarn lib:info
|
|
259
|
+
|
|
260
|
+
# Upgrade to latest version (from registry)
|
|
261
|
+
yarn lib:upgrade
|
|
262
|
+
|
|
263
|
+
# Install local development version
|
|
264
|
+
yarn lib:install-local
|
|
265
|
+
|
|
266
|
+
# Install registry version
|
|
267
|
+
yarn lib:install-registry
|
|
268
|
+
|
|
269
|
+
# Verify registry configuration
|
|
270
|
+
yarn lib:verify-registry
|
|
271
|
+
```
|
|
272
|
+
|
|
135
273
|
---
|
|
136
274
|
|
|
137
275
|
## 🚀 Quick Start
|
|
@@ -209,6 +347,7 @@ function MyPage() {
|
|
|
209
347
|
### Why Centralized Themes?
|
|
210
348
|
|
|
211
349
|
**Before** (❌ Old Way):
|
|
350
|
+
|
|
212
351
|
```typescript
|
|
213
352
|
// In each consuming app - duplicated code
|
|
214
353
|
const iglooTheme = {
|
|
@@ -220,6 +359,7 @@ const iglooTheme = {
|
|
|
220
359
|
```
|
|
221
360
|
|
|
222
361
|
**After** (✅ New Way):
|
|
362
|
+
|
|
223
363
|
```typescript
|
|
224
364
|
// Import from library - single source of truth
|
|
225
365
|
import { iglooTheme } from 'igloo-d2c-components'
|
|
@@ -272,13 +412,18 @@ interface TenantThemeConfig {
|
|
|
272
412
|
fontFamily: string
|
|
273
413
|
}
|
|
274
414
|
logo: string
|
|
415
|
+
logoDark?: string
|
|
416
|
+
logoAlt?: string
|
|
417
|
+
logoWhite?: string
|
|
275
418
|
favicon: string
|
|
419
|
+
assetBaseUrl?: string
|
|
276
420
|
}
|
|
277
421
|
```
|
|
278
422
|
|
|
279
423
|
### Using Themes
|
|
280
424
|
|
|
281
425
|
**In Tenant Configuration:**
|
|
426
|
+
|
|
282
427
|
```typescript
|
|
283
428
|
// config/tenants/igloo.ts
|
|
284
429
|
import { iglooTheme } from 'igloo-d2c-components'
|
|
@@ -290,19 +435,8 @@ const iglooConfig: TenantConfig = {
|
|
|
290
435
|
}
|
|
291
436
|
```
|
|
292
437
|
|
|
293
|
-
**Dynamic Loading:**
|
|
294
|
-
```typescript
|
|
295
|
-
import { getTenantTheme, isValidTenantId } from 'igloo-d2c-components'
|
|
296
|
-
|
|
297
|
-
function loadTheme(tenantId: string) {
|
|
298
|
-
if (isValidTenantId(tenantId)) {
|
|
299
|
-
return getTenantTheme(tenantId)
|
|
300
|
-
}
|
|
301
|
-
throw new Error(`Invalid tenant: ${tenantId}`)
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
438
|
**In Components:**
|
|
439
|
+
|
|
306
440
|
```typescript
|
|
307
441
|
import { useTenantTheme } from 'igloo-d2c-components'
|
|
308
442
|
|
|
@@ -320,19 +454,13 @@ function MyComponent() {
|
|
|
320
454
|
}
|
|
321
455
|
```
|
|
322
456
|
|
|
323
|
-
### Theme Benefits
|
|
324
|
-
|
|
325
|
-
- ✅ **Single source of truth** - Update in one place
|
|
326
|
-
- ✅ **Type-safe** - Full TypeScript support
|
|
327
|
-
- ✅ **Consistent** - Same themes across all apps
|
|
328
|
-
- ✅ **Maintainable** - Easy to update and extend
|
|
329
|
-
- ✅ **Scalable** - Add new tenants easily
|
|
330
|
-
|
|
331
457
|
---
|
|
332
458
|
|
|
333
459
|
## 📚 Components
|
|
334
460
|
|
|
335
|
-
###
|
|
461
|
+
### General Components
|
|
462
|
+
|
|
463
|
+
#### Button
|
|
336
464
|
|
|
337
465
|
Tenant-aware button component based on MUI Button.
|
|
338
466
|
|
|
@@ -351,11 +479,12 @@ import { Button } from 'igloo-d2c-components'
|
|
|
351
479
|
```
|
|
352
480
|
|
|
353
481
|
**Props:**
|
|
482
|
+
|
|
354
483
|
- `tenantColored?: boolean` - Use tenant primary color
|
|
355
484
|
- `variant?: 'text' | 'outlined' | 'contained'` - Button variant
|
|
356
485
|
- All MUI ButtonProps
|
|
357
486
|
|
|
358
|
-
|
|
487
|
+
#### Card
|
|
359
488
|
|
|
360
489
|
Tenant-aware card component based on MUI Card.
|
|
361
490
|
|
|
@@ -371,14 +500,14 @@ import { Card } from 'igloo-d2c-components'
|
|
|
371
500
|
```
|
|
372
501
|
|
|
373
502
|
**Props:**
|
|
503
|
+
|
|
374
504
|
- `title?: React.ReactNode` - Card title
|
|
375
505
|
- `content?: React.ReactNode` - Card content
|
|
376
506
|
- `actions?: React.ReactNode` - Card actions
|
|
377
507
|
- `tenantAccent?: boolean` - Add tenant-colored top border
|
|
378
|
-
- `headerAction?: React.ReactNode` - Action in header
|
|
379
508
|
- All MUI CardProps
|
|
380
509
|
|
|
381
|
-
|
|
510
|
+
#### Banner
|
|
382
511
|
|
|
383
512
|
Promotional banner with tenant theming.
|
|
384
513
|
|
|
@@ -393,12 +522,402 @@ import { Banner } from 'igloo-d2c-components'
|
|
|
393
522
|
/>
|
|
394
523
|
```
|
|
395
524
|
|
|
525
|
+
#### NewHeader
|
|
526
|
+
|
|
527
|
+
Simplified header component with mobile drawer navigation.
|
|
528
|
+
|
|
529
|
+
```tsx
|
|
530
|
+
import { NewHeader } from 'igloo-d2c-components'
|
|
531
|
+
|
|
532
|
+
<NewHeader
|
|
533
|
+
logo="/path/to/logo.svg"
|
|
534
|
+
navigationLinks={[
|
|
535
|
+
{
|
|
536
|
+
key: 'car',
|
|
537
|
+
label: 'Car Insurance',
|
|
538
|
+
onClick: () => navigate('/car')
|
|
539
|
+
}
|
|
540
|
+
]}
|
|
541
|
+
additionalMenuSections={[
|
|
542
|
+
{
|
|
543
|
+
title: 'Account',
|
|
544
|
+
items: [
|
|
545
|
+
{ key: 'login', label: 'Log in', onClick: handleLogin }
|
|
546
|
+
]
|
|
547
|
+
}
|
|
548
|
+
]}
|
|
549
|
+
onLogoClick={() => navigate('/')}
|
|
550
|
+
/>
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Props:**
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
interface NewHeaderProps {
|
|
557
|
+
logo: string // Logo image source
|
|
558
|
+
navigationLinks?: NewHeaderNavigationLink[]
|
|
559
|
+
additionalMenuSections?: {
|
|
560
|
+
title?: string
|
|
561
|
+
items: NewHeaderNavigationLink[]
|
|
562
|
+
}[]
|
|
563
|
+
isMobile?: boolean
|
|
564
|
+
onLogoClick?: () => void
|
|
565
|
+
onMenuOpen?: () => void
|
|
566
|
+
onMenuClose?: () => void
|
|
567
|
+
customDrawerContent?: React.ReactNode
|
|
568
|
+
formatMessage?: (descriptor: { id: string }) => string
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Interactive Components
|
|
573
|
+
|
|
574
|
+
#### RecommendationsDrawer
|
|
575
|
+
|
|
576
|
+
Mobile drawer for collecting user preferences and showing personalized recommendations.
|
|
577
|
+
|
|
578
|
+
```tsx
|
|
579
|
+
import {
|
|
580
|
+
RecommendationsDrawer,
|
|
581
|
+
QuestionSection,
|
|
582
|
+
OptionButton,
|
|
583
|
+
ToggleGroup
|
|
584
|
+
} from 'igloo-d2c-components'
|
|
585
|
+
|
|
586
|
+
function MyComponent() {
|
|
587
|
+
const [open, setOpen] = React.useState(false)
|
|
588
|
+
const [selectedOption, setSelectedOption] = React.useState('')
|
|
589
|
+
|
|
590
|
+
const options = [
|
|
591
|
+
{ value: 'option1', label: 'Option 1', icon: '🎯' },
|
|
592
|
+
{ value: 'option2', label: 'Option 2', icon: '✨' },
|
|
593
|
+
]
|
|
594
|
+
|
|
595
|
+
return (
|
|
596
|
+
<>
|
|
597
|
+
<Button onClick={() => setOpen(true)}>
|
|
598
|
+
See my recommendations
|
|
599
|
+
</Button>
|
|
600
|
+
|
|
601
|
+
<RecommendationsDrawer
|
|
602
|
+
open={open}
|
|
603
|
+
onClose={() => setOpen(false)}
|
|
604
|
+
title="Personalize Your Plan"
|
|
605
|
+
subtitle="Answer a few questions"
|
|
606
|
+
primaryButtonText="Next"
|
|
607
|
+
onPrimaryAction={handleSubmit}
|
|
608
|
+
>
|
|
609
|
+
<QuestionSection
|
|
610
|
+
question="What's your preference?"
|
|
611
|
+
options={options}
|
|
612
|
+
selectedValue={selectedOption}
|
|
613
|
+
onSelect={setSelectedOption}
|
|
614
|
+
renderOption={(option, isSelected) => (
|
|
615
|
+
<OptionButton
|
|
616
|
+
key={option.value}
|
|
617
|
+
value={option.value}
|
|
618
|
+
label={option.label}
|
|
619
|
+
icon={option.icon}
|
|
620
|
+
selected={isSelected}
|
|
621
|
+
onClick={setSelectedOption}
|
|
622
|
+
/>
|
|
623
|
+
)}
|
|
624
|
+
/>
|
|
625
|
+
</RecommendationsDrawer>
|
|
626
|
+
</>
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
**RecommendationsDrawer Props:**
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
interface RecommendationsDrawerProps {
|
|
635
|
+
open: boolean
|
|
636
|
+
onClose: () => void
|
|
637
|
+
children: React.ReactNode
|
|
638
|
+
headerIcon?: string
|
|
639
|
+
title?: string
|
|
640
|
+
subtitle?: string
|
|
641
|
+
showBackButton?: boolean
|
|
642
|
+
onBack?: () => void
|
|
643
|
+
primaryButtonText?: string
|
|
644
|
+
onPrimaryAction?: () => void
|
|
645
|
+
primaryButtonDisabled?: boolean
|
|
646
|
+
secondaryButtonText?: string
|
|
647
|
+
onSecondaryAction?: () => void
|
|
648
|
+
showFooter?: boolean
|
|
649
|
+
customFooter?: React.ReactNode
|
|
650
|
+
formatMessage?: (descriptor: { id: string }) => string
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### ProductSelectionDrawer
|
|
655
|
+
|
|
656
|
+
Mobile-first bottom drawer for displaying insurance products in a grid.
|
|
657
|
+
|
|
658
|
+
```tsx
|
|
659
|
+
import { ProductSelectionDrawer, Product } from 'igloo-d2c-components'
|
|
660
|
+
|
|
661
|
+
const products: Product[] = [
|
|
662
|
+
{
|
|
663
|
+
id: 'life-byond',
|
|
664
|
+
name: 'LIFE BYOND',
|
|
665
|
+
type: 'Term Plan',
|
|
666
|
+
logo: '/path/to/logo.png',
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
id: 'health-cvr',
|
|
670
|
+
name: 'HEALTH CVR',
|
|
671
|
+
type: 'CI Plan',
|
|
672
|
+
logo: '/path/to/logo.png',
|
|
673
|
+
},
|
|
674
|
+
]
|
|
675
|
+
|
|
676
|
+
<ProductSelectionDrawer
|
|
677
|
+
open={open}
|
|
678
|
+
onClose={() => setOpen(false)}
|
|
679
|
+
products={products}
|
|
680
|
+
onProductSelect={(productId) => {
|
|
681
|
+
console.log('Selected:', productId)
|
|
682
|
+
setOpen(false)
|
|
683
|
+
}}
|
|
684
|
+
title="Select your product"
|
|
685
|
+
subtitle="Pick the product that suits your protection goals"
|
|
686
|
+
viewPlansButtonText="View plans"
|
|
687
|
+
/>
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
#### ToggleGroup
|
|
691
|
+
|
|
692
|
+
Segmented control for binary/multiple choice toggles.
|
|
693
|
+
|
|
694
|
+
```tsx
|
|
695
|
+
import { ToggleGroup } from 'igloo-d2c-components'
|
|
696
|
+
|
|
697
|
+
<ToggleGroup
|
|
698
|
+
options={[
|
|
699
|
+
{ value: 'domestic', label: 'Domestic', icon: '/icon1.svg' },
|
|
700
|
+
{ value: 'international', label: 'International', icon: '/icon2.svg' }
|
|
701
|
+
]}
|
|
702
|
+
value={travelType}
|
|
703
|
+
onChange={setTravelType}
|
|
704
|
+
/>
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Checkout Components
|
|
708
|
+
|
|
709
|
+
#### CheckoutProgress
|
|
710
|
+
|
|
711
|
+
Progress bar with step indicator for multi-step checkout flows.
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
import { CheckoutProgress } from 'igloo-d2c-components'
|
|
715
|
+
|
|
716
|
+
<CheckoutProgress
|
|
717
|
+
currentStep={0}
|
|
718
|
+
totalSteps={3}
|
|
719
|
+
onBack={() => handleBack()}
|
|
720
|
+
showBackButton={true}
|
|
721
|
+
/>
|
|
722
|
+
```
|
|
723
|
+
|
|
396
724
|
**Props:**
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
725
|
+
|
|
726
|
+
| Prop | Type | Default | Description |
|
|
727
|
+
| ---------------- | ------------ | -------- | ------------------------------------ |
|
|
728
|
+
| `currentStep` | `number` | Required | Current step (0-indexed) |
|
|
729
|
+
| `totalSteps` | `number` | Required | Total number of steps |
|
|
730
|
+
| `onBack` | `() => void` | - | Callback when back button is clicked |
|
|
731
|
+
| `showBackButton` | `boolean` | `true` | Whether to show the back button |
|
|
732
|
+
|
|
733
|
+
#### ProductCard
|
|
734
|
+
|
|
735
|
+
Product information card for checkout flows.
|
|
736
|
+
|
|
737
|
+
```tsx
|
|
738
|
+
import { ProductCard } from 'igloo-d2c-components'
|
|
739
|
+
|
|
740
|
+
<ProductCard
|
|
741
|
+
productName="LIFE BYOND"
|
|
742
|
+
planName="Plan A"
|
|
743
|
+
price="25"
|
|
744
|
+
currency="RM"
|
|
745
|
+
period="/month"
|
|
746
|
+
logoUrl="path/to/logo.png"
|
|
747
|
+
showIndicator={true}
|
|
748
|
+
/>
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
#### CheckoutHeader
|
|
752
|
+
|
|
753
|
+
Complete header component combining progress, product card, and section information.
|
|
754
|
+
|
|
755
|
+
```tsx
|
|
756
|
+
import { CheckoutHeader } from 'igloo-d2c-components'
|
|
757
|
+
|
|
758
|
+
<CheckoutHeader
|
|
759
|
+
progress={{
|
|
760
|
+
currentStep: 0,
|
|
761
|
+
totalSteps: 3,
|
|
762
|
+
onBack: () => handleBack(),
|
|
763
|
+
}}
|
|
764
|
+
product={{
|
|
765
|
+
productName: 'LIFE BYOND',
|
|
766
|
+
planName: 'Plan A',
|
|
767
|
+
price: '25',
|
|
768
|
+
currency: 'RM',
|
|
769
|
+
period: '/month',
|
|
770
|
+
}}
|
|
771
|
+
sectionTitle="Personal information"
|
|
772
|
+
sectionDescription="Let's get to know you better..."
|
|
773
|
+
sticky={true}
|
|
774
|
+
/>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
#### CheckoutFormButton
|
|
778
|
+
|
|
779
|
+
Fixed or floating button for form submission.
|
|
780
|
+
|
|
781
|
+
```tsx
|
|
782
|
+
import { CheckoutFormButton } from 'igloo-d2c-components'
|
|
783
|
+
|
|
784
|
+
<CheckoutFormButton
|
|
785
|
+
text="Next"
|
|
786
|
+
disabled={!isValid}
|
|
787
|
+
onClick={handleSubmit}
|
|
788
|
+
fixed={true}
|
|
789
|
+
type="button"
|
|
790
|
+
loading={isSubmitting}
|
|
791
|
+
/>
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
**Tenant Theme Support:** The button automatically uses tenant-specific colors:
|
|
795
|
+
|
|
796
|
+
- **AmmetLife**: Blue (#317ABC)
|
|
797
|
+
- **CIMB**: Red (#D71920)
|
|
798
|
+
- **Igloo**: Black (#13131B)
|
|
799
|
+
|
|
800
|
+
#### HealthQuestionGroup
|
|
801
|
+
|
|
802
|
+
Health questions with Yes/No button options.
|
|
803
|
+
|
|
804
|
+
```tsx
|
|
805
|
+
import { HealthQuestionGroup } from 'igloo-d2c-components'
|
|
806
|
+
|
|
807
|
+
<HealthQuestionGroup
|
|
808
|
+
question="Have you ever had any ongoing or past health conditions?"
|
|
809
|
+
questionNumber={1}
|
|
810
|
+
value={healthConditions}
|
|
811
|
+
onChange={(value) => setHealthConditions(value)}
|
|
812
|
+
error={errors.healthConditions}
|
|
813
|
+
labels={{ yes: 'Yes', no: 'No' }}
|
|
814
|
+
/>
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Form Components
|
|
818
|
+
|
|
819
|
+
The library includes three reusable checkout form components designed to be **form library agnostic**.
|
|
820
|
+
|
|
821
|
+
#### PersonalInformationForm
|
|
822
|
+
|
|
823
|
+
Collects personal details, occupation, and banking information.
|
|
824
|
+
|
|
825
|
+
```tsx
|
|
826
|
+
import { PersonalInformationForm } from 'igloo-d2c-components'
|
|
827
|
+
|
|
828
|
+
<PersonalInformationForm
|
|
829
|
+
renderField={renderField}
|
|
830
|
+
fields={{
|
|
831
|
+
full_name: {
|
|
832
|
+
name: 'full_name',
|
|
833
|
+
label: 'Full name',
|
|
834
|
+
value: formik.values.full_name,
|
|
835
|
+
error: formik.errors.full_name,
|
|
836
|
+
touched: formik.touched.full_name,
|
|
837
|
+
helperText: 'Full name as per your ID card',
|
|
838
|
+
onChange: formik.handleChange,
|
|
839
|
+
onBlur: formik.handleBlur,
|
|
840
|
+
},
|
|
841
|
+
nric: { /* ... */ },
|
|
842
|
+
date_of_birth: { /* ... */ },
|
|
843
|
+
gender: { /* ... */ },
|
|
844
|
+
// ... other fields
|
|
845
|
+
}}
|
|
846
|
+
consents={{
|
|
847
|
+
bank_account_confirmation: {
|
|
848
|
+
checked: formik.values.bank_account_confirmation,
|
|
849
|
+
onChange: (checked) =>
|
|
850
|
+
formik.setFieldValue('bank_account_confirmation', checked),
|
|
851
|
+
error: formik.errors.bank_account_confirmation,
|
|
852
|
+
},
|
|
853
|
+
marketing_consent: {
|
|
854
|
+
checked: formik.values.marketing_consent,
|
|
855
|
+
onChange: (checked) =>
|
|
856
|
+
formik.setFieldValue('marketing_consent', checked),
|
|
857
|
+
},
|
|
858
|
+
}}
|
|
859
|
+
onSubmit={formik.handleSubmit}
|
|
860
|
+
/>
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
#### ContactDetailsForm
|
|
864
|
+
|
|
865
|
+
Collects contact and address information.
|
|
866
|
+
|
|
867
|
+
```tsx
|
|
868
|
+
import { ContactDetailsForm } from 'igloo-d2c-components'
|
|
869
|
+
|
|
870
|
+
<ContactDetailsForm
|
|
871
|
+
renderField={renderField}
|
|
872
|
+
fields={{
|
|
873
|
+
phone_number: { /* ... */ },
|
|
874
|
+
email_address: { /* ... */ },
|
|
875
|
+
residential_address: { /* ... */ },
|
|
876
|
+
postal_code: { /* ... */ },
|
|
877
|
+
city: { /* ... */ },
|
|
878
|
+
state: { /* ... */ },
|
|
879
|
+
}}
|
|
880
|
+
mailingAddressSame={{
|
|
881
|
+
checked: formik.values.mailing_same_as_residential,
|
|
882
|
+
onChange: (checked) =>
|
|
883
|
+
formik.setFieldValue('mailing_same_as_residential', checked),
|
|
884
|
+
}}
|
|
885
|
+
onSubmit={formik.handleSubmit}
|
|
886
|
+
/>
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
#### HealthInformationForm
|
|
890
|
+
|
|
891
|
+
Collects health measurements and questions with gender-specific support.
|
|
892
|
+
|
|
893
|
+
```tsx
|
|
894
|
+
import { HealthInformationForm } from 'igloo-d2c-components'
|
|
895
|
+
|
|
896
|
+
<HealthInformationForm
|
|
897
|
+
renderField={renderField}
|
|
898
|
+
measurementFields={{
|
|
899
|
+
weight: {
|
|
900
|
+
name: 'weight',
|
|
901
|
+
label: 'Weight (kg)',
|
|
902
|
+
type: 'number',
|
|
903
|
+
value: formik.values.weight,
|
|
904
|
+
inputProps: { min: 20, max: 300 },
|
|
905
|
+
onChange: formik.handleChange,
|
|
906
|
+
},
|
|
907
|
+
height: { /* ... */ },
|
|
908
|
+
}}
|
|
909
|
+
healthQuestions={[
|
|
910
|
+
{
|
|
911
|
+
question: 'Have you ever had any ongoing or past health conditions?',
|
|
912
|
+
questionNumber: 1,
|
|
913
|
+
name: 'health_conditions',
|
|
914
|
+
value: formik.values.health_conditions,
|
|
915
|
+
onChange: (value) => formik.setFieldValue('health_conditions', value),
|
|
916
|
+
},
|
|
917
|
+
]}
|
|
918
|
+
onSubmit={formik.handleSubmit}
|
|
919
|
+
/>
|
|
920
|
+
```
|
|
402
921
|
|
|
403
922
|
---
|
|
404
923
|
|
|
@@ -452,6 +971,20 @@ function MyComponent() {
|
|
|
452
971
|
}
|
|
453
972
|
```
|
|
454
973
|
|
|
974
|
+
#### useTenantLogo()
|
|
975
|
+
|
|
976
|
+
Get tenant logo URL.
|
|
977
|
+
|
|
978
|
+
```tsx
|
|
979
|
+
import { useTenantLogo } from 'igloo-d2c-components'
|
|
980
|
+
|
|
981
|
+
function MyComponent() {
|
|
982
|
+
const logo = useTenantLogo() // Default logo
|
|
983
|
+
const darkLogo = useTenantLogo('dark') // Dark variant
|
|
984
|
+
return <img src={logo} alt="Logo" />
|
|
985
|
+
}
|
|
986
|
+
```
|
|
987
|
+
|
|
455
988
|
### Utility Functions
|
|
456
989
|
|
|
457
990
|
#### getTenantTheme()
|
|
@@ -465,8 +998,6 @@ const theme = getTenantTheme('igloo')
|
|
|
465
998
|
console.log(theme.palette.primary.main) // '#5656F6'
|
|
466
999
|
```
|
|
467
1000
|
|
|
468
|
-
**Throws:** Error if tenant ID is invalid
|
|
469
|
-
|
|
470
1001
|
#### isValidTenantId()
|
|
471
1002
|
|
|
472
1003
|
Type guard to check if a string is a valid tenant ID.
|
|
@@ -501,15 +1032,348 @@ const color = getThemeColor(theme, 'primary.main', '#000')
|
|
|
501
1032
|
// Returns theme.palette.primary.main or '#000' if not found
|
|
502
1033
|
```
|
|
503
1034
|
|
|
504
|
-
|
|
1035
|
+
---
|
|
505
1036
|
|
|
506
|
-
|
|
1037
|
+
## 📦 Asset Management
|
|
1038
|
+
|
|
1039
|
+
### Asset Organization
|
|
1040
|
+
|
|
1041
|
+
```
|
|
1042
|
+
d2c-component-library/src/assets/
|
|
1043
|
+
├── icons/ # Common UI icons
|
|
1044
|
+
│ ├── alert.svg
|
|
1045
|
+
│ ├── arrow-down.svg
|
|
1046
|
+
│ ├── close.svg
|
|
1047
|
+
│ ├── facebook.svg
|
|
1048
|
+
│ ├── instagram.svg
|
|
1049
|
+
│ ├── youtube.svg
|
|
1050
|
+
│ └── index.ts # Icon path utilities
|
|
1051
|
+
├── tenants/ # Tenant-specific assets
|
|
1052
|
+
│ ├── igloo/logo.svg
|
|
1053
|
+
│ ├── cimb/logo.svg
|
|
1054
|
+
│ └── ammetlife/logo.svg
|
|
1055
|
+
└── index.ts # Main asset exports
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
### Asset Flow Architecture
|
|
1059
|
+
|
|
1060
|
+
```
|
|
1061
|
+
┌─────────────────────────────────────────────────────┐
|
|
1062
|
+
│ ASSET MANAGEMENT ARCHITECTURE │
|
|
1063
|
+
├─────────────────────────────────────────────────────┤
|
|
1064
|
+
│ │
|
|
1065
|
+
│ d2c-component-library/ │
|
|
1066
|
+
│ └── src/assets/ │
|
|
1067
|
+
│ ├── icons/ → Common UI icons │
|
|
1068
|
+
│ └── tenants/ → Tenant logos │
|
|
1069
|
+
│ ├── igloo/logo.svg │
|
|
1070
|
+
│ ├── cimb/logo.svg │
|
|
1071
|
+
│ └── ammetlife/logo.svg │
|
|
1072
|
+
│ │
|
|
1073
|
+
│ BUILD ⬇️ │
|
|
1074
|
+
│ dist/assets/ → Published with library │
|
|
1075
|
+
│ │
|
|
1076
|
+
│ INSTALL ⬇️ │
|
|
1077
|
+
│ node_modules/igloo-d2c-components/dist/assets/ │
|
|
1078
|
+
│ │
|
|
1079
|
+
│ COPY (yarn copy-assets) ⬇️ │
|
|
1080
|
+
│ public/assets/ → Served by UMI │
|
|
1081
|
+
│ │
|
|
1082
|
+
└─────────────────────────────────────────────────────┘
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
### Using Assets
|
|
507
1086
|
|
|
508
|
-
```
|
|
509
|
-
|
|
1087
|
+
```typescript
|
|
1088
|
+
// Get Tenant Logo
|
|
1089
|
+
import { useTenantLogo } from 'igloo-d2c-components'
|
|
1090
|
+
|
|
1091
|
+
function MyComponent() {
|
|
1092
|
+
const logo = useTenantLogo() // Default logo
|
|
1093
|
+
const darkLogo = useTenantLogo('dark') // Dark variant
|
|
1094
|
+
return <img src={logo} alt="Logo" />
|
|
1095
|
+
}
|
|
510
1096
|
|
|
511
|
-
|
|
512
|
-
|
|
1097
|
+
// Get Icon Paths
|
|
1098
|
+
import { ICON_PATHS, getIconPath } from 'igloo-d2c-components'
|
|
1099
|
+
<img src={ICON_PATHS.facebook} alt="Facebook" />
|
|
1100
|
+
<img src={getIconPath('instagram')} alt="Instagram" />
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
### Asset Distribution Strategy
|
|
1104
|
+
|
|
1105
|
+
| Asset Type | Location | Reason |
|
|
1106
|
+
| --------------------- | ------------------- | --------------------------- |
|
|
1107
|
+
| **Generic UI Icons** | Library | Reusable across projects |
|
|
1108
|
+
| **Tenant Logos** | Library (via theme) | Centralized management |
|
|
1109
|
+
| **Insurer Logos** | CDN | Shared, updated by partners |
|
|
1110
|
+
| **Marketing Banners** | Application | Frequent changes |
|
|
1111
|
+
| **Documents (PDFs)** | CDN | Large, rarely change |
|
|
1112
|
+
|
|
1113
|
+
### Logo Rendering in Applications
|
|
1114
|
+
|
|
1115
|
+
**Important**: Assets need to be copied to the `public/` folder for UMI to serve them:
|
|
1116
|
+
|
|
1117
|
+
```bash
|
|
1118
|
+
# In consuming application
|
|
1119
|
+
yarn copy-assets # Copies library assets to public/assets/
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
The theme paths reference `/assets/tenants/{tenant}/logo.svg` which maps to:
|
|
1123
|
+
|
|
1124
|
+
- Theme config: `logo: '/assets/tenants/igloo/logo.svg'`
|
|
1125
|
+
- File location: `public/assets/tenants/igloo/logo.svg`
|
|
1126
|
+
- Browser URL: `http://localhost:8001/assets/tenants/igloo/logo.svg`
|
|
1127
|
+
|
|
1128
|
+
---
|
|
1129
|
+
|
|
1130
|
+
## 🔌 Integration Guide
|
|
1131
|
+
|
|
1132
|
+
### Multi-Tenant Architecture
|
|
1133
|
+
|
|
1134
|
+
#### Tenant Configuration Structure
|
|
1135
|
+
|
|
1136
|
+
```
|
|
1137
|
+
config/tenants/
|
|
1138
|
+
├── index.ts # Tenant registry and utility functions
|
|
1139
|
+
├── types.ts # TypeScript interfaces
|
|
1140
|
+
├── igloo.ts # Igloo tenant configuration
|
|
1141
|
+
├── ammetlife.ts # AmmetLife tenant configuration
|
|
1142
|
+
└── cimb.ts # CIMB tenant configuration
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
#### Tenant Configuration Example
|
|
1146
|
+
|
|
1147
|
+
```typescript
|
|
1148
|
+
// config/tenants/igloo.ts
|
|
1149
|
+
import { iglooTheme } from 'igloo-d2c-components'
|
|
1150
|
+
import { TenantConfig } from './types'
|
|
1151
|
+
|
|
1152
|
+
const iglooConfig: TenantConfig = {
|
|
1153
|
+
id: 'igloo',
|
|
1154
|
+
name: 'igloo',
|
|
1155
|
+
displayName: 'Igloo',
|
|
1156
|
+
domain: 'igloo.co.id',
|
|
1157
|
+
|
|
1158
|
+
theme: iglooTheme, // ← Centralized theme from component library
|
|
1159
|
+
|
|
1160
|
+
features: {
|
|
1161
|
+
showPAMenu: true,
|
|
1162
|
+
enableAIChatbot: true,
|
|
1163
|
+
showWorkshopEntryPoint: false,
|
|
1164
|
+
enableFreeAddons: false,
|
|
1165
|
+
},
|
|
1166
|
+
|
|
1167
|
+
routes: {
|
|
1168
|
+
enabled: ['car', 'motorbike', 'health', 'life', 'travel', 'pet'],
|
|
1169
|
+
disabled: [],
|
|
1170
|
+
},
|
|
1171
|
+
|
|
1172
|
+
branding: {
|
|
1173
|
+
companyName: 'Igloo',
|
|
1174
|
+
supportEmail: 'hello@iglooinsure.com',
|
|
1175
|
+
supportPhone: '+62 21 5022 0888',
|
|
1176
|
+
},
|
|
1177
|
+
|
|
1178
|
+
integrations: {
|
|
1179
|
+
gtmCode: 'GTM-5RHHNVQ',
|
|
1180
|
+
gaCode: 'G-QQV6F41YPJ',
|
|
1181
|
+
},
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
export default iglooConfig
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
#### AmmetLife Custom Homepage
|
|
1188
|
+
|
|
1189
|
+
AmMetLife uses a custom homepage that displays the life insurance landing page:
|
|
1190
|
+
|
|
1191
|
+
```typescript
|
|
1192
|
+
// config/tenants/ammetlife.ts
|
|
1193
|
+
customRoutes: [
|
|
1194
|
+
{
|
|
1195
|
+
path: '/',
|
|
1196
|
+
exact: true,
|
|
1197
|
+
component: '@/pages/life-landing-page/index.tsx',
|
|
1198
|
+
},
|
|
1199
|
+
]
|
|
1200
|
+
```
|
|
1201
|
+
|
|
1202
|
+
### Checkout Flow Integration
|
|
1203
|
+
|
|
1204
|
+
#### Complete 3-Step Checkout
|
|
1205
|
+
|
|
1206
|
+
The library provides components for a complete checkout flow:
|
|
1207
|
+
|
|
1208
|
+
1. **Personal Information** - 11 fields + 2 consent checkboxes
|
|
1209
|
+
2. **Contact Details** - 6 address fields + mailing checkbox
|
|
1210
|
+
3. **Health Information** - 2 measurements + health questions (gender-specific)
|
|
1211
|
+
|
|
1212
|
+
#### Session Storage Requirements
|
|
1213
|
+
|
|
1214
|
+
```typescript
|
|
1215
|
+
// Required before navigating to checkout
|
|
1216
|
+
session.setItem('plan', {
|
|
1217
|
+
name: 'Plan A',
|
|
1218
|
+
premiumInfo: { currency: 'RM', monthlyAmount: '25' }
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
session.setItem('product', {
|
|
1222
|
+
name: 'LIFE BYOND',
|
|
1223
|
+
logoUrl: 'url-to-logo'
|
|
1224
|
+
});
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
#### Navigation Flow
|
|
1228
|
+
|
|
1229
|
+
```
|
|
1230
|
+
PDP (/en/ammetlife-pdp)
|
|
1231
|
+
↓ Click "Buy now"
|
|
1232
|
+
Checkout Step 1/3 (Personal Info) ← Back → PDP
|
|
1233
|
+
↓ Click "Next"
|
|
1234
|
+
Checkout Step 2/3 (Contact Details) ← Back → Step 1
|
|
1235
|
+
↓ Click "Next"
|
|
1236
|
+
Checkout Step 3/3 (Health Information) ← Back → Step 2
|
|
1237
|
+
↓ Click "Submit"
|
|
1238
|
+
Payment (/en/payment-options)
|
|
1239
|
+
```
|
|
1240
|
+
|
|
1241
|
+
#### Back Button Logic
|
|
1242
|
+
|
|
1243
|
+
```typescript
|
|
1244
|
+
const handleBack = () => {
|
|
1245
|
+
if (currentStep === 0) {
|
|
1246
|
+
// On first step, redirect to PDP
|
|
1247
|
+
window.location.href = `/${currentLocale}/ammetlife-pdp`;
|
|
1248
|
+
} else {
|
|
1249
|
+
// On other steps, go to previous step
|
|
1250
|
+
setCurrentStep(currentStep - 1);
|
|
1251
|
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
#### Validation Rules
|
|
1257
|
+
|
|
1258
|
+
**Personal Information:**
|
|
1259
|
+
|
|
1260
|
+
- Full name: minimum 2 characters
|
|
1261
|
+
- NRIC: numbers and dashes only
|
|
1262
|
+
- DOB: 30 days to 80 years old
|
|
1263
|
+
- Bank account: numbers only
|
|
1264
|
+
- Bank confirmation: must be checked
|
|
1265
|
+
|
|
1266
|
+
**Contact Details:**
|
|
1267
|
+
|
|
1268
|
+
- Phone: 9-14 digits
|
|
1269
|
+
- Email: valid format
|
|
1270
|
+
- Address: minimum 10 characters
|
|
1271
|
+
- Postal code: exactly 5 digits
|
|
1272
|
+
|
|
1273
|
+
**Health Information:**
|
|
1274
|
+
|
|
1275
|
+
- Weight: 20-300 kg
|
|
1276
|
+
- Height: 50-250 cm
|
|
1277
|
+
- All questions: must select Yes or No
|
|
1278
|
+
|
|
1279
|
+
### Recommendations Feature
|
|
1280
|
+
|
|
1281
|
+
#### User Flow
|
|
1282
|
+
|
|
1283
|
+
```
|
|
1284
|
+
1. User sees "See my recommendations" button
|
|
1285
|
+
↓ User clicks
|
|
1286
|
+
2. Mobile drawer slides up from bottom (95vh height)
|
|
1287
|
+
↓
|
|
1288
|
+
3. Drawer shows:
|
|
1289
|
+
- Toggle: Domestic/International
|
|
1290
|
+
- 5 Questions with selectable options
|
|
1291
|
+
- Next button
|
|
1292
|
+
↓ User answers questions
|
|
1293
|
+
4. User clicks "Next" button
|
|
1294
|
+
↓
|
|
1295
|
+
5. Data collected, drawer closes, recommendations shown
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
#### Implementation
|
|
1299
|
+
|
|
1300
|
+
```typescript
|
|
1301
|
+
import { TravelRecommendations } from '@/components/recommendations';
|
|
1302
|
+
import { RecommendationsButton } from '@/components/recommendations/recommendations-button';
|
|
1303
|
+
|
|
1304
|
+
export default function MyPage() {
|
|
1305
|
+
const [showRecommendations, setShowRecommendations] = React.useState(false);
|
|
1306
|
+
|
|
1307
|
+
return (
|
|
1308
|
+
<div>
|
|
1309
|
+
<RecommendationsButton
|
|
1310
|
+
onClick={() => setShowRecommendations(true)}
|
|
1311
|
+
/>
|
|
1312
|
+
|
|
1313
|
+
<TravelRecommendations
|
|
1314
|
+
open={showRecommendations}
|
|
1315
|
+
onClose={() => setShowRecommendations(false)}
|
|
1316
|
+
onSubmit={(data) => {
|
|
1317
|
+
console.log('User selected:', data);
|
|
1318
|
+
}}
|
|
1319
|
+
/>
|
|
1320
|
+
</div>
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
#### Data Structure
|
|
1326
|
+
|
|
1327
|
+
```typescript
|
|
1328
|
+
interface TravelRecommendationsData {
|
|
1329
|
+
travelType: 'domestic' | 'international';
|
|
1330
|
+
selectedPlan: string;
|
|
1331
|
+
monthlyIncome: string;
|
|
1332
|
+
monthlyExpenses: string;
|
|
1333
|
+
currentCoverage: string;
|
|
1334
|
+
employerCoverage: string;
|
|
1335
|
+
}
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
### Header Integration
|
|
1339
|
+
|
|
1340
|
+
#### NewHeader Implementation
|
|
1341
|
+
|
|
1342
|
+
The NewHeader component provides a simplified header with mobile drawer navigation.
|
|
1343
|
+
|
|
1344
|
+
**Features:**
|
|
1345
|
+
|
|
1346
|
+
1. **Product Navigation** - Dynamically loaded from navLinks
|
|
1347
|
+
2. **User Authentication** - Login/Logout flow
|
|
1348
|
+
3. **Additional Links** - Partnership, About Us, Blog
|
|
1349
|
+
4. **Language Selector** - EN/ID with cookie persistence
|
|
1350
|
+
5. **Analytics** - Google Analytics integration
|
|
1351
|
+
|
|
1352
|
+
**Performance Improvement:**
|
|
1353
|
+
|
|
1354
|
+
| Metric | Before | After |
|
|
1355
|
+
| -------------- | --------- | --------- |
|
|
1356
|
+
| Component size | 860 lines | 200 lines |
|
|
1357
|
+
| Bundle size | ~45KB | ~15KB |
|
|
1358
|
+
| Props count | 30+ | 9 |
|
|
1359
|
+
|
|
1360
|
+
### Routing Guide
|
|
1361
|
+
|
|
1362
|
+
#### Route Pattern
|
|
1363
|
+
|
|
1364
|
+
```
|
|
1365
|
+
/:locale/life-checkout
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
#### Navigation with Locale
|
|
1369
|
+
|
|
1370
|
+
```typescript
|
|
1371
|
+
// ✅ CORRECT - With locale
|
|
1372
|
+
const { currentLocale } = local.getItem('globalState');
|
|
1373
|
+
window.location.href = `/${currentLocale}/life-checkout`;
|
|
1374
|
+
|
|
1375
|
+
// ❌ WRONG - Without locale
|
|
1376
|
+
window.location.href = '/life-checkout';
|
|
513
1377
|
```
|
|
514
1378
|
|
|
515
1379
|
---
|
|
@@ -522,6 +1386,7 @@ const vars = createThemeCSSVariables(theme, '--my-app')
|
|
|
522
1386
|
- **Yarn**: `^1.22.0` (recommended) or npm
|
|
523
1387
|
|
|
524
1388
|
Check your version:
|
|
1389
|
+
|
|
525
1390
|
```bash
|
|
526
1391
|
node --version # Should be 16.20.0 - 18.x
|
|
527
1392
|
yarn --version # Should be 1.22.x
|
|
@@ -576,22 +1441,11 @@ dist/
|
|
|
576
1441
|
├── esm/
|
|
577
1442
|
│ ├── index.js # ES Module bundle (unminified, ES2015)
|
|
578
1443
|
│ └── index.js.map # Source map
|
|
579
|
-
|
|
580
|
-
|
|
1444
|
+
├── types/
|
|
1445
|
+
│ └── index.d.ts # TypeScript definitions
|
|
1446
|
+
└── assets/ # Copied assets
|
|
581
1447
|
```
|
|
582
1448
|
|
|
583
|
-
**Why unminified?**
|
|
584
|
-
- ✅ Consuming apps handle minification
|
|
585
|
-
- ✅ Better debugging experience
|
|
586
|
-
- ✅ Better tree-shaking
|
|
587
|
-
- ✅ No impact on final bundle size
|
|
588
|
-
|
|
589
|
-
**Why ES2015?**
|
|
590
|
-
- ✅ Maximum compatibility with older webpack configs
|
|
591
|
-
- ✅ No babel-loader required in consuming apps
|
|
592
|
-
- ✅ Optional chaining (`?.`) transpiled to verbose checks
|
|
593
|
-
- ✅ Works with webpack 4+
|
|
594
|
-
|
|
595
1449
|
### Project Structure
|
|
596
1450
|
|
|
597
1451
|
```
|
|
@@ -600,7 +1454,13 @@ d2c-component-library/
|
|
|
600
1454
|
│ ├── components/ # Component implementations
|
|
601
1455
|
│ │ ├── Button/
|
|
602
1456
|
│ │ ├── Card/
|
|
603
|
-
│ │
|
|
1457
|
+
│ │ ├── Banner/
|
|
1458
|
+
│ │ ├── NewHeader/
|
|
1459
|
+
│ │ ├── RecommendationsDrawer/
|
|
1460
|
+
│ │ ├── ProductSelectionDrawer/
|
|
1461
|
+
│ │ ├── CheckoutHeader/
|
|
1462
|
+
│ │ ├── PersonalInformationForm/
|
|
1463
|
+
│ │ └── ...
|
|
604
1464
|
│ ├── context/
|
|
605
1465
|
│ │ └── TenantThemeContext.tsx
|
|
606
1466
|
│ ├── themes/
|
|
@@ -608,7 +1468,9 @@ d2c-component-library/
|
|
|
608
1468
|
│ ├── types/
|
|
609
1469
|
│ │ └── tenant.ts # TypeScript types
|
|
610
1470
|
│ ├── utils/
|
|
611
|
-
│ │
|
|
1471
|
+
│ │ ├── theme.ts # Theme utilities
|
|
1472
|
+
│ │ └── assets.ts # Asset utilities
|
|
1473
|
+
│ ├── assets/ # UI icons and tenant logos
|
|
612
1474
|
│ └── index.ts # Main exports
|
|
613
1475
|
├── dist/ # Build output (generated)
|
|
614
1476
|
├── examples/
|
|
@@ -617,8 +1479,129 @@ d2c-component-library/
|
|
|
617
1479
|
├── rollup.config.cjs # Rollup build config
|
|
618
1480
|
├── tsconfig.json # TypeScript config
|
|
619
1481
|
├── package.json
|
|
620
|
-
|
|
621
|
-
|
|
1482
|
+
└── README.md # This file
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
---
|
|
1486
|
+
|
|
1487
|
+
## 📖 Storybook
|
|
1488
|
+
|
|
1489
|
+
The library includes Storybook for component documentation and testing.
|
|
1490
|
+
|
|
1491
|
+
### Running Storybook
|
|
1492
|
+
|
|
1493
|
+
```bash
|
|
1494
|
+
# Start Storybook dev server
|
|
1495
|
+
yarn storybook
|
|
1496
|
+
# Opens at http://localhost:6006
|
|
1497
|
+
|
|
1498
|
+
# Build static Storybook
|
|
1499
|
+
yarn build-storybook
|
|
1500
|
+
# Output in storybook-static/
|
|
1501
|
+
```
|
|
1502
|
+
|
|
1503
|
+
### Available Stories
|
|
1504
|
+
|
|
1505
|
+
**NewHeader Stories (12 scenarios):**
|
|
1506
|
+
|
|
1507
|
+
1. Default - Basic header with Igloo branding
|
|
1508
|
+
2. Authenticated User - Header with logged-in user menu
|
|
1509
|
+
3. Mobile View - Responsive mobile layout
|
|
1510
|
+
4. CIMB Tenant - CIMB branding
|
|
1511
|
+
5. AmMetLife Tenant - AmMetLife branding
|
|
1512
|
+
6. Minimal Header - Bare-bones implementation
|
|
1513
|
+
7. Custom Drawer Content - Advanced customization
|
|
1514
|
+
8. Many Menu Items - Stress test with scrolling
|
|
1515
|
+
9. Without Logo - Edge case testing
|
|
1516
|
+
10. With Internationalization - i18n integration
|
|
1517
|
+
11. All Tenants Comparison - Side-by-side view
|
|
1518
|
+
12. Responsive Demo - Interactive responsive testing
|
|
1519
|
+
|
|
1520
|
+
**Other Component Stories:**
|
|
1521
|
+
|
|
1522
|
+
- RecommendationsDrawer - Complete questionnaire flow
|
|
1523
|
+
- ProductSelectionDrawer - Product grid selection
|
|
1524
|
+
- CheckoutHeader - Progress and product display
|
|
1525
|
+
- All checkout components
|
|
1526
|
+
|
|
1527
|
+
### Keyboard Shortcuts
|
|
1528
|
+
|
|
1529
|
+
| Key | Action |
|
|
1530
|
+
| --- | ------------------- |
|
|
1531
|
+
| `F` | Toggle fullscreen |
|
|
1532
|
+
| `S` | Toggle sidebar |
|
|
1533
|
+
| `A` | Toggle addons panel |
|
|
1534
|
+
| `T` | Toggle toolbar |
|
|
1535
|
+
| `D` | Toggle dark mode |
|
|
1536
|
+
| `/` | Search stories |
|
|
1537
|
+
|
|
1538
|
+
---
|
|
1539
|
+
|
|
1540
|
+
## 🔧 Build Pipeline
|
|
1541
|
+
|
|
1542
|
+
### Problems Solved
|
|
1543
|
+
|
|
1544
|
+
1. **Module parse error**: Webpack couldn't parse igloo-d2c-components ESM format
|
|
1545
|
+
2. **Source map error**: Terser plugin couldn't process source maps
|
|
1546
|
+
|
|
1547
|
+
### Solutions Applied
|
|
1548
|
+
|
|
1549
|
+
#### 1. Library: Disabled Source Maps
|
|
1550
|
+
|
|
1551
|
+
```javascript
|
|
1552
|
+
// rollup.config.cjs
|
|
1553
|
+
output: [
|
|
1554
|
+
{
|
|
1555
|
+
file: packageJson.main,
|
|
1556
|
+
format: 'cjs',
|
|
1557
|
+
sourcemap: false, // ✅ Disabled
|
|
1558
|
+
exports: 'named',
|
|
1559
|
+
banner: '"use client"',
|
|
1560
|
+
},
|
|
1561
|
+
]
|
|
1562
|
+
```
|
|
1563
|
+
|
|
1564
|
+
#### 2. Consumer App: Webpack Configuration
|
|
1565
|
+
|
|
1566
|
+
```typescript
|
|
1567
|
+
// .umirc.ts
|
|
1568
|
+
chainWebpack: (memo, { type, webpack }) => {
|
|
1569
|
+
// Prefer CommonJS over ESM
|
|
1570
|
+
memo.resolve.mainFields.clear().add('main').add('module').add('browser');
|
|
1571
|
+
|
|
1572
|
+
// Include igloo-d2c-components in babel transpilation
|
|
1573
|
+
memo.module
|
|
1574
|
+
.rule('js')
|
|
1575
|
+
.include.add(/node_modules[\\/]igloo-d2c-components/)
|
|
1576
|
+
.end();
|
|
1577
|
+
}
|
|
1578
|
+
```
|
|
1579
|
+
|
|
1580
|
+
### CI/CD Pipeline Options
|
|
1581
|
+
|
|
1582
|
+
**Option A: Publish to npm (Recommended)**
|
|
1583
|
+
|
|
1584
|
+
```bash
|
|
1585
|
+
cd d2c-component-library
|
|
1586
|
+
npm publish --access public
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
**Option B: Use Git URL**
|
|
1590
|
+
|
|
1591
|
+
```json
|
|
1592
|
+
{
|
|
1593
|
+
"igloo-d2c-components": "git+https://gitlab.com/axinan/fe/d2c-component-library.git#main"
|
|
1594
|
+
}
|
|
1595
|
+
```
|
|
1596
|
+
|
|
1597
|
+
**Option C: Multi-Repo CI/CD**
|
|
1598
|
+
|
|
1599
|
+
```yaml
|
|
1600
|
+
before_script:
|
|
1601
|
+
- cd ..
|
|
1602
|
+
- git clone https://gitlab.com/axinan/fe/d2c-component-library.git
|
|
1603
|
+
- cd d2c-component-library && yarn install && yarn build
|
|
1604
|
+
- cd ../b2c-web-demo && yarn install
|
|
622
1605
|
```
|
|
623
1606
|
|
|
624
1607
|
---
|
|
@@ -628,21 +1611,21 @@ d2c-component-library/
|
|
|
628
1611
|
### Prerequisites
|
|
629
1612
|
|
|
630
1613
|
1. **Ensure clean working directory:**
|
|
1614
|
+
|
|
631
1615
|
```bash
|
|
632
1616
|
git status # Should be clean
|
|
633
1617
|
```
|
|
634
1618
|
|
|
635
1619
|
2. **Update version in package.json:**
|
|
1620
|
+
|
|
636
1621
|
```json
|
|
637
1622
|
{
|
|
638
1623
|
"version": "1.0.7"
|
|
639
1624
|
}
|
|
640
1625
|
```
|
|
641
1626
|
|
|
642
|
-
3. **
|
|
643
|
-
Document changes in the new version section
|
|
1627
|
+
3. **Build the library:**
|
|
644
1628
|
|
|
645
|
-
4. **Build the library:**
|
|
646
1629
|
```bash
|
|
647
1630
|
yarn build
|
|
648
1631
|
```
|
|
@@ -650,15 +1633,13 @@ d2c-component-library/
|
|
|
650
1633
|
### Publishing to NPM
|
|
651
1634
|
|
|
652
1635
|
**Set up NPM token:**
|
|
1636
|
+
|
|
653
1637
|
```bash
|
|
654
|
-
# Get token from https://www.npmjs.com/settings/YOUR_USERNAME/tokens
|
|
655
1638
|
export NPM_AUTH_TOKEN="npm_your_actual_token"
|
|
656
|
-
|
|
657
|
-
# Or add to ~/.npmrc globally
|
|
658
|
-
//registry.npmjs.org/:_authToken=npm_your_token
|
|
659
1639
|
```
|
|
660
1640
|
|
|
661
1641
|
**Publish:**
|
|
1642
|
+
|
|
662
1643
|
```bash
|
|
663
1644
|
# Automated script with safety checks
|
|
664
1645
|
./publish-to-npm.sh
|
|
@@ -668,137 +1649,22 @@ yarn build
|
|
|
668
1649
|
npm publish --access public
|
|
669
1650
|
```
|
|
670
1651
|
|
|
671
|
-
### Publishing to GitLab Package Registry
|
|
672
|
-
|
|
673
|
-
**Set up GitLab token:**
|
|
674
|
-
```bash
|
|
675
|
-
# Get token from https://gitlab.com/-/profile/personal_access_tokens
|
|
676
|
-
# Scopes: api, read_registry, write_registry
|
|
677
|
-
export GITLAB_NPM_TOKEN="glpat-your-token"
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
**Configure `.npmrc` for GitLab:**
|
|
681
|
-
```ini
|
|
682
|
-
@igloo:registry=https://gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/npm/
|
|
683
|
-
//gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/npm/:_authToken=${GITLAB_NPM_TOKEN}
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
**Publish:**
|
|
687
|
-
```bash
|
|
688
|
-
yarn build
|
|
689
|
-
npm publish
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
### CI/CD Publishing
|
|
693
|
-
|
|
694
|
-
The library includes a GitLab CI/CD configuration (`.gitlab-ci.yml`) that automatically:
|
|
695
|
-
|
|
696
|
-
1. **Runs on main branch** or tags
|
|
697
|
-
2. **Lints and type-checks** code
|
|
698
|
-
3. **Builds** the library
|
|
699
|
-
4. **Publishes** to registry (if tag)
|
|
700
|
-
|
|
701
|
-
**Trigger CI/CD publish:**
|
|
702
|
-
```bash
|
|
703
|
-
# Create and push a tag
|
|
704
|
-
git tag v1.0.7
|
|
705
|
-
git push origin v1.0.7
|
|
706
|
-
```
|
|
707
|
-
|
|
708
1652
|
### Version Management
|
|
709
1653
|
|
|
710
1654
|
**Semantic Versioning:**
|
|
1655
|
+
|
|
711
1656
|
- **Major** (1.0.0 → 2.0.0): Breaking changes
|
|
712
1657
|
- **Minor** (1.0.0 → 1.1.0): New features, backwards compatible
|
|
713
1658
|
- **Patch** (1.0.0 → 1.0.1): Bug fixes
|
|
714
1659
|
|
|
715
1660
|
**Update version:**
|
|
716
|
-
```bash
|
|
717
|
-
# Manually in package.json
|
|
718
|
-
"version": "1.0.7"
|
|
719
1661
|
|
|
720
|
-
|
|
1662
|
+
```bash
|
|
721
1663
|
npm version patch # 1.0.6 → 1.0.7
|
|
722
1664
|
npm version minor # 1.0.6 → 1.1.0
|
|
723
1665
|
npm version major # 1.0.6 → 2.0.0
|
|
724
1666
|
```
|
|
725
1667
|
|
|
726
|
-
### Post-Publishing
|
|
727
|
-
|
|
728
|
-
After publishing:
|
|
729
|
-
|
|
730
|
-
1. **Tag the release:**
|
|
731
|
-
```bash
|
|
732
|
-
git tag v1.0.7
|
|
733
|
-
git push origin v1.0.7
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
2. **Update consuming apps:**
|
|
737
|
-
```bash
|
|
738
|
-
cd ../b2c-web-demo
|
|
739
|
-
yarn upgrade igloo-d2c-components@latest
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
3. **Announce the release** to the team
|
|
743
|
-
|
|
744
|
-
---
|
|
745
|
-
|
|
746
|
-
## 📖 Storybook
|
|
747
|
-
|
|
748
|
-
The library includes Storybook for component documentation and testing.
|
|
749
|
-
|
|
750
|
-
### Running Storybook
|
|
751
|
-
|
|
752
|
-
```bash
|
|
753
|
-
# Start Storybook dev server
|
|
754
|
-
yarn storybook
|
|
755
|
-
# Opens at http://localhost:6006
|
|
756
|
-
|
|
757
|
-
# Build static Storybook
|
|
758
|
-
yarn build-storybook
|
|
759
|
-
# Output in storybook-static/
|
|
760
|
-
```
|
|
761
|
-
|
|
762
|
-
### Storybook Features
|
|
763
|
-
|
|
764
|
-
- **Component Playground** - Interactive component testing
|
|
765
|
-
- **Props Documentation** - Auto-generated from TypeScript
|
|
766
|
-
- **Theme Switching** - Test with different tenant themes
|
|
767
|
-
- **Responsive Design** - Test different viewports
|
|
768
|
-
- **Accessibility** - Built-in a11y addon
|
|
769
|
-
|
|
770
|
-
### Adding Stories
|
|
771
|
-
|
|
772
|
-
Create a `.stories.tsx` file next to your component:
|
|
773
|
-
|
|
774
|
-
```tsx
|
|
775
|
-
// src/components/MyComponent/MyComponent.stories.tsx
|
|
776
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
777
|
-
import { TenantThemeProvider, iglooTheme } from '../../index'
|
|
778
|
-
import { MyComponent } from './MyComponent'
|
|
779
|
-
|
|
780
|
-
const meta: Meta<typeof MyComponent> = {
|
|
781
|
-
title: 'Components/MyComponent',
|
|
782
|
-
component: MyComponent,
|
|
783
|
-
decorators: [
|
|
784
|
-
(Story) => (
|
|
785
|
-
<TenantThemeProvider tenantId="igloo" theme={iglooTheme}>
|
|
786
|
-
<Story />
|
|
787
|
-
</TenantThemeProvider>
|
|
788
|
-
),
|
|
789
|
-
],
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
export default meta
|
|
793
|
-
type Story = StoryObj<typeof MyComponent>
|
|
794
|
-
|
|
795
|
-
export const Default: Story = {
|
|
796
|
-
args: {
|
|
797
|
-
prop1: 'value1',
|
|
798
|
-
},
|
|
799
|
-
}
|
|
800
|
-
```
|
|
801
|
-
|
|
802
1668
|
---
|
|
803
1669
|
|
|
804
1670
|
## 🔬 Technical Details
|
|
@@ -806,6 +1672,7 @@ export const Default: Story = {
|
|
|
806
1672
|
### Build Configuration
|
|
807
1673
|
|
|
808
1674
|
**Rollup Configuration** (`rollup.config.cjs`):
|
|
1675
|
+
|
|
809
1676
|
```javascript
|
|
810
1677
|
{
|
|
811
1678
|
input: 'src/index.ts',
|
|
@@ -825,19 +1692,6 @@ export const Default: Story = {
|
|
|
825
1692
|
banner: '"use client"',
|
|
826
1693
|
},
|
|
827
1694
|
],
|
|
828
|
-
plugins: [
|
|
829
|
-
peerDepsExternal(),
|
|
830
|
-
resolve(),
|
|
831
|
-
commonjs(),
|
|
832
|
-
typescript({
|
|
833
|
-
tsconfig: './tsconfig.json',
|
|
834
|
-
compilerOptions: {
|
|
835
|
-
declaration: false,
|
|
836
|
-
target: 'ES2015', // For compatibility
|
|
837
|
-
},
|
|
838
|
-
}),
|
|
839
|
-
// NO terser() - libraries should not be minified
|
|
840
|
-
],
|
|
841
1695
|
}
|
|
842
1696
|
```
|
|
843
1697
|
|
|
@@ -863,17 +1717,6 @@ export const Default: Story = {
|
|
|
863
1717
|
}
|
|
864
1718
|
```
|
|
865
1719
|
|
|
866
|
-
### Package Exports
|
|
867
|
-
|
|
868
|
-
```json
|
|
869
|
-
{
|
|
870
|
-
"main": "dist/cjs/index.js",
|
|
871
|
-
"module": "dist/esm/index.js",
|
|
872
|
-
"types": "dist/types/index.d.ts",
|
|
873
|
-
"files": ["dist", "README.md"]
|
|
874
|
-
}
|
|
875
|
-
```
|
|
876
|
-
|
|
877
1720
|
---
|
|
878
1721
|
|
|
879
1722
|
## 🐛 Troubleshooting
|
|
@@ -881,129 +1724,107 @@ export const Default: Story = {
|
|
|
881
1724
|
### Webpack Module Parse Error
|
|
882
1725
|
|
|
883
1726
|
**Error:**
|
|
1727
|
+
|
|
884
1728
|
```
|
|
885
1729
|
Module parse failed: Unexpected token
|
|
886
1730
|
```
|
|
887
1731
|
|
|
888
|
-
**Cause:** Webpack can't parse the library output.
|
|
889
|
-
|
|
890
1732
|
**Solution:**
|
|
891
1733
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
```bash
|
|
900
|
-
cd ../b2c-web-demo
|
|
901
|
-
rm -rf node_modules/igloo-d2c-components
|
|
902
|
-
yarn install
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
**Prevention:** The library is configured to output ES2015 JavaScript which is compatible with webpack 4+. Modern syntax like optional chaining (`?.`) is transpiled to verbose null checks.
|
|
1734
|
+
```bash
|
|
1735
|
+
cd d2c-component-library
|
|
1736
|
+
yarn clean && yarn build
|
|
1737
|
+
cd ../b2c-web-demo
|
|
1738
|
+
rm -rf node_modules/igloo-d2c-components
|
|
1739
|
+
yarn install
|
|
1740
|
+
```
|
|
906
1741
|
|
|
907
1742
|
### Theme Not Found Error
|
|
908
1743
|
|
|
909
1744
|
**Error:**
|
|
1745
|
+
|
|
910
1746
|
```
|
|
911
1747
|
Theme not found for tenant: xxx
|
|
912
1748
|
```
|
|
913
1749
|
|
|
914
1750
|
**Solution:** Use valid tenant IDs: `'igloo'`, `'cimb'`, or `'ammetlife'`.
|
|
915
1751
|
|
|
916
|
-
```typescript
|
|
917
|
-
import { isValidTenantId, getTenantTheme } from 'igloo-d2c-components'
|
|
918
|
-
|
|
919
|
-
if (isValidTenantId(tenantId)) {
|
|
920
|
-
const theme = getTenantTheme(tenantId)
|
|
921
|
-
} else {
|
|
922
|
-
console.error('Invalid tenant ID:', tenantId)
|
|
923
|
-
}
|
|
924
|
-
```
|
|
925
|
-
|
|
926
1752
|
### TypeScript Errors with Imports
|
|
927
1753
|
|
|
928
1754
|
**Error:**
|
|
1755
|
+
|
|
929
1756
|
```
|
|
930
1757
|
Module '"igloo-d2c-components"' has no exported member 'iglooTheme'
|
|
931
1758
|
```
|
|
932
1759
|
|
|
933
1760
|
**Solution:**
|
|
934
1761
|
|
|
935
|
-
1.
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
yarn build
|
|
939
|
-
```
|
|
940
|
-
|
|
941
|
-
2. **Reinstall in consuming app:**
|
|
942
|
-
```bash
|
|
943
|
-
cd ../b2c-web-demo
|
|
944
|
-
yarn remove igloo-d2c-components
|
|
945
|
-
yarn add igloo-d2c-components@file:../d2c-component-library
|
|
946
|
-
```
|
|
947
|
-
|
|
948
|
-
3. **Restart TypeScript server** in your IDE:
|
|
949
|
-
- VS Code: Cmd+Shift+P → "TypeScript: Restart TS Server"
|
|
1762
|
+
1. Rebuild the library: `yarn build`
|
|
1763
|
+
2. Reinstall in consuming app: `yarn install`
|
|
1764
|
+
3. Restart TypeScript server in your IDE
|
|
950
1765
|
|
|
951
1766
|
### Build Failures
|
|
952
1767
|
|
|
953
1768
|
**Error:** Build fails with memory issues
|
|
954
1769
|
|
|
955
1770
|
**Solution:**
|
|
1771
|
+
|
|
956
1772
|
```bash
|
|
957
1773
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
958
1774
|
yarn build
|
|
959
1775
|
```
|
|
960
1776
|
|
|
961
|
-
|
|
1777
|
+
### Asset Issues
|
|
962
1778
|
|
|
963
|
-
**
|
|
964
|
-
```bash
|
|
965
|
-
# Check types first
|
|
966
|
-
yarn type-check
|
|
1779
|
+
**Logos not displaying:**
|
|
967
1780
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1781
|
+
1. Run `yarn copy-assets` in consuming app
|
|
1782
|
+
2. Verify assets in `public/assets/tenants/`
|
|
1783
|
+
3. Check theme path: `/assets/tenants/igloo/logo.svg`
|
|
971
1784
|
|
|
972
|
-
###
|
|
1785
|
+
### Routing Issues
|
|
973
1786
|
|
|
974
|
-
**
|
|
975
|
-
|
|
976
|
-
**Solution:** Install peer dependencies in consuming app:
|
|
977
|
-
```bash
|
|
978
|
-
yarn add react@17 react-dom@17 @mui/material@5 @emotion/react @emotion/styled
|
|
979
|
-
```
|
|
1787
|
+
**Issue: 404 on /life-checkout**
|
|
1788
|
+
Use locale prefix: `/en/life-checkout`, not `/life-checkout`
|
|
980
1789
|
|
|
981
1790
|
---
|
|
982
1791
|
|
|
983
|
-
##
|
|
1792
|
+
## 📝 Changelog
|
|
1793
|
+
|
|
1794
|
+
### [Unreleased]
|
|
1795
|
+
|
|
1796
|
+
#### Added
|
|
984
1797
|
|
|
985
|
-
|
|
1798
|
+
- **CheckoutProgress** - Progress bar component with step indicator
|
|
1799
|
+
- **ProductCard** - Product information card for checkout flows
|
|
1800
|
+
- **CheckoutHeader** - Complete checkout header combining progress and product card
|
|
1801
|
+
- **CheckoutFormButton** - Fixed/floating button for form submission
|
|
1802
|
+
- **HealthQuestionGroup** - Health question component with Yes/No options
|
|
1803
|
+
- **ProductSelectionDrawer** - Mobile-first bottom drawer for product selection
|
|
1804
|
+
- **PersonalInformationForm** - Personal details form component
|
|
1805
|
+
- **ContactDetailsForm** - Contact and address form component
|
|
1806
|
+
- **HealthInformationForm** - Health measurements and questions form
|
|
1807
|
+
- Comprehensive Storybook documentation
|
|
1808
|
+
- Integration guides for multi-tenant architecture
|
|
986
1809
|
|
|
987
|
-
1.
|
|
988
|
-
2. **Use ES2015 features** - Avoid ES2020+ syntax
|
|
989
|
-
3. **Test in consuming apps** - Test changes in b2c-web-demo
|
|
990
|
-
4. **Update CHANGELOG** - Document all changes
|
|
991
|
-
5. **Version appropriately** - Follow semantic versioning
|
|
1810
|
+
### [1.0.1] - 2025-11-11
|
|
992
1811
|
|
|
993
|
-
|
|
1812
|
+
#### Changed
|
|
994
1813
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
3. **Use tenantColored prop** - For tenant-specific styling
|
|
998
|
-
4. **Maintain type safety** - Use provided TypeScript types
|
|
999
|
-
5. **Extend via composition** - Don't modify library components
|
|
1814
|
+
- Package name configured for public NPM registry
|
|
1815
|
+
- Updated all documentation
|
|
1000
1816
|
|
|
1001
|
-
###
|
|
1817
|
+
### [1.0.0] - 2025-10-31
|
|
1002
1818
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1819
|
+
#### Added
|
|
1820
|
+
|
|
1821
|
+
- Initial release of D2C Component Library
|
|
1822
|
+
- `TenantThemeProvider` - Context provider for tenant theming
|
|
1823
|
+
- Hooks: `useTenantTheme()`, `useTenantId()`, `useIsTenant()`
|
|
1824
|
+
- Components: `Button`, `Card`, `Banner`
|
|
1825
|
+
- Utility functions for theme management
|
|
1826
|
+
- Full TypeScript support
|
|
1827
|
+
- ESM and CommonJS builds
|
|
1007
1828
|
|
|
1008
1829
|
---
|
|
1009
1830
|
|
|
@@ -1013,31 +1834,35 @@ yarn add react@17 react-dom@17 @mui/material@5 @emotion/react @emotion/styled
|
|
|
1013
1834
|
|
|
1014
1835
|
1. **Fork the repository**
|
|
1015
1836
|
2. **Create a feature branch:**
|
|
1837
|
+
|
|
1016
1838
|
```bash
|
|
1017
1839
|
git checkout -b feature/my-new-feature
|
|
1018
1840
|
```
|
|
1841
|
+
|
|
1019
1842
|
3. **Make your changes**
|
|
1020
1843
|
4. **Test thoroughly:**
|
|
1844
|
+
|
|
1021
1845
|
```bash
|
|
1022
1846
|
yarn lint
|
|
1023
1847
|
yarn type-check
|
|
1024
1848
|
yarn build
|
|
1025
1849
|
```
|
|
1850
|
+
|
|
1026
1851
|
5. **Test in consuming app:**
|
|
1852
|
+
|
|
1027
1853
|
```bash
|
|
1028
1854
|
cd ../b2c-web-demo
|
|
1029
1855
|
yarn install
|
|
1030
1856
|
yarn start-igloo-dev
|
|
1031
1857
|
```
|
|
1858
|
+
|
|
1032
1859
|
6. **Commit your changes:**
|
|
1860
|
+
|
|
1033
1861
|
```bash
|
|
1034
1862
|
git commit -m "feat: add new feature"
|
|
1035
1863
|
```
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
git push origin feature/my-new-feature
|
|
1039
|
-
```
|
|
1040
|
-
8. **Create a Pull Request**
|
|
1864
|
+
|
|
1865
|
+
7. **Push and create a Pull Request**
|
|
1041
1866
|
|
|
1042
1867
|
### Commit Message Format
|
|
1043
1868
|
|
|
@@ -1045,13 +1870,10 @@ Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
|
1045
1870
|
|
|
1046
1871
|
```
|
|
1047
1872
|
<type>(<scope>): <description>
|
|
1048
|
-
|
|
1049
|
-
[optional body]
|
|
1050
|
-
|
|
1051
|
-
[optional footer]
|
|
1052
1873
|
```
|
|
1053
1874
|
|
|
1054
1875
|
**Types:**
|
|
1876
|
+
|
|
1055
1877
|
- `feat`: New feature
|
|
1056
1878
|
- `fix`: Bug fix
|
|
1057
1879
|
- `docs`: Documentation changes
|
|
@@ -1060,22 +1882,15 @@ Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
|
1060
1882
|
- `test`: Test additions/changes
|
|
1061
1883
|
- `chore`: Maintenance tasks
|
|
1062
1884
|
|
|
1063
|
-
**Examples:**
|
|
1064
|
-
```
|
|
1065
|
-
feat(themes): add new tenant theme
|
|
1066
|
-
fix(Button): correct hover state color
|
|
1067
|
-
docs: update installation guide
|
|
1068
|
-
chore: bump version to 1.0.7
|
|
1069
|
-
```
|
|
1070
|
-
|
|
1071
1885
|
### Adding a New Tenant
|
|
1072
1886
|
|
|
1073
1887
|
1. **Add theme to `src/themes/index.ts`:**
|
|
1888
|
+
|
|
1074
1889
|
```typescript
|
|
1075
1890
|
export const newTenantTheme: TenantThemeConfig = {
|
|
1076
1891
|
palette: { /* ... */ },
|
|
1077
1892
|
typography: { /* ... */ },
|
|
1078
|
-
logo: '/assets/
|
|
1893
|
+
logo: '/assets/tenants/newtenant/logo.svg',
|
|
1079
1894
|
favicon: 'https://...',
|
|
1080
1895
|
}
|
|
1081
1896
|
|
|
@@ -1088,18 +1903,26 @@ chore: bump version to 1.0.7
|
|
|
1088
1903
|
```
|
|
1089
1904
|
|
|
1090
1905
|
2. **Update TenantId type in `src/types/tenant.ts`:**
|
|
1906
|
+
|
|
1091
1907
|
```typescript
|
|
1092
1908
|
export type TenantId = 'igloo' | 'cimb' | 'ammetlife' | 'newtenant'
|
|
1093
1909
|
```
|
|
1094
1910
|
|
|
1095
|
-
3. **
|
|
1911
|
+
3. **Add logo asset to `src/assets/tenants/newtenant/`**
|
|
1912
|
+
|
|
1913
|
+
4. **Build and test:**
|
|
1914
|
+
|
|
1096
1915
|
```bash
|
|
1097
1916
|
yarn build
|
|
1098
|
-
cd ../b2c-web-demo
|
|
1099
|
-
yarn install
|
|
1100
1917
|
```
|
|
1101
1918
|
|
|
1102
|
-
|
|
1919
|
+
### Adding New Components
|
|
1920
|
+
|
|
1921
|
+
1. Create component folder in `src/components/`
|
|
1922
|
+
2. Include: `ComponentName.tsx`, `styled.tsx`, `index.ts`
|
|
1923
|
+
3. Add Storybook stories
|
|
1924
|
+
4. Export from `src/index.ts`
|
|
1925
|
+
5. Update documentation
|
|
1103
1926
|
|
|
1104
1927
|
---
|
|
1105
1928
|
|
|
@@ -1117,16 +1940,16 @@ Frontend Engineering Team - Axinan/Igloo
|
|
|
1117
1940
|
|
|
1118
1941
|
## 🔗 Links
|
|
1119
1942
|
|
|
1120
|
-
- **Repository:** https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library
|
|
1121
|
-
- **NPM Package:** https://www.npmjs.com/package/igloo-d2c-components
|
|
1122
|
-
- **Consuming App:** https://gitlab.iglooinsure.com/axinan/fe/b2c-web-demo
|
|
1123
|
-
- **Issue Tracker:** https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library/-/issues
|
|
1943
|
+
- **Repository:** <https://gitlab.iglooinsure.com/axinan/fe/d2c-component-library>
|
|
1944
|
+
- **NPM Package:** <https://www.npmjs.com/package/igloo-d2c-components>
|
|
1945
|
+
- **Consuming App:** <https://gitlab.iglooinsure.com/axinan/fe/b2c-web-demo>
|
|
1124
1946
|
|
|
1125
1947
|
---
|
|
1126
1948
|
|
|
1127
1949
|
## 📝 Quick Reference
|
|
1128
1950
|
|
|
1129
1951
|
### Installation
|
|
1952
|
+
|
|
1130
1953
|
```bash
|
|
1131
1954
|
# Local development
|
|
1132
1955
|
yarn add igloo-d2c-components@file:../d2c-component-library
|
|
@@ -1136,38 +1959,45 @@ yarn add igloo-d2c-components@latest
|
|
|
1136
1959
|
```
|
|
1137
1960
|
|
|
1138
1961
|
### Import Themes
|
|
1962
|
+
|
|
1139
1963
|
```typescript
|
|
1140
1964
|
import { iglooTheme, cimbTheme, ammetlifeTheme, getTenantTheme } from 'igloo-d2c-components'
|
|
1141
1965
|
```
|
|
1142
1966
|
|
|
1143
1967
|
### Import Components
|
|
1968
|
+
|
|
1144
1969
|
```typescript
|
|
1145
|
-
import { Button, Card, Banner, TenantThemeProvider } from 'igloo-d2c-components'
|
|
1970
|
+
import { Button, Card, Banner, TenantThemeProvider, NewHeader, CheckoutHeader } from 'igloo-d2c-components'
|
|
1146
1971
|
```
|
|
1147
1972
|
|
|
1148
1973
|
### Import Hooks
|
|
1974
|
+
|
|
1149
1975
|
```typescript
|
|
1150
|
-
import { useTenantTheme, useTenantId, useIsTenant } from 'igloo-d2c-components'
|
|
1976
|
+
import { useTenantTheme, useTenantId, useIsTenant, useTenantLogo } from 'igloo-d2c-components'
|
|
1151
1977
|
```
|
|
1152
1978
|
|
|
1153
1979
|
### Build & Publish
|
|
1980
|
+
|
|
1154
1981
|
```bash
|
|
1155
1982
|
# Build
|
|
1156
1983
|
yarn build
|
|
1157
1984
|
|
|
1158
1985
|
# Publish to NPM
|
|
1159
1986
|
./publish-to-npm.sh
|
|
1987
|
+
```
|
|
1160
1988
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1989
|
+
### Test All Tenants (in b2c-web-demo)
|
|
1990
|
+
|
|
1991
|
+
```bash
|
|
1992
|
+
yarn start-igloo # Port 8000
|
|
1993
|
+
yarn start-ammetlife # Port 8001
|
|
1994
|
+
yarn start-cimb # Port 8002
|
|
1163
1995
|
```
|
|
1164
1996
|
|
|
1165
1997
|
---
|
|
1166
1998
|
|
|
1167
|
-
**Version:** 1.0.
|
|
1168
|
-
**Last Updated:**
|
|
1999
|
+
**Version:** 1.0.11+
|
|
2000
|
+
**Last Updated:** December 2025
|
|
1169
2001
|
**Node.js:** >=16.20.0 <=18.x
|
|
1170
2002
|
**Target:** ES2015
|
|
1171
2003
|
**Output:** Unminified
|
|
1172
|
-
|
|
1173
|
-
For version history, see [CHANGELOG.md](./CHANGELOG.md)
|