@nuskin/react-mysite-elements 1.4.3 → 1.5.0-comx-2229.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -0
- package/dist/common/carousel/ProductTabCarousel.d.ts +1 -1
- package/dist/common/icon/icons/SocialMediaIcons.styled.d.ts +5 -0
- package/dist/common/index.d.ts +1 -0
- package/dist/common/shopping-dashboard/MysiteDashboardWithNavigation.d.ts +50 -0
- package/dist/common/shopping-dashboard/PoDashboardWithNavigation.d.ts +4 -0
- package/dist/common/shopping-dashboard/ProductOfferDashboard.d.ts +4 -0
- package/dist/common/shopping-dashboard/ProductOfferDashboard.styled.d.ts +20 -0
- package/dist/common/shopping-dashboard/ShoppingDashboard.d.ts +32 -0
- package/dist/common/shopping-dashboard/ShoppingDashboard.styled.d.ts +20 -0
- package/dist/common/shopping-dashboard/TranslationContext.d.ts +10 -0
- package/dist/common/shopping-dashboard/TranslationKeys/ProductOfferDashboardTranslationKeys.d.ts +230 -0
- package/dist/common/shopping-dashboard/TranslationKeys/ShoppingDashboardTranslationKeys.d.ts +612 -0
- package/dist/common/shopping-dashboard/TranslationKeys/translationResolver.d.ts +8 -0
- package/dist/common/shopping-dashboard/fixtures/index.d.ts +1 -0
- package/dist/common/shopping-dashboard/fixtures/mockDashboardData.d.ts +10 -0
- package/dist/common/shopping-dashboard/fixtures/mockProductOfferData.d.ts +8 -0
- package/dist/common/shopping-dashboard/index.d.ts +42 -0
- package/dist/common/shopping-dashboard/shared/ConversionRate/ConversionRateChart.d.ts +13 -0
- package/dist/common/shopping-dashboard/shared/ConversionRate/ConversionRateChart.styled.d.ts +62 -0
- package/dist/common/shopping-dashboard/shared/ConversionRate/ConversionRateFullView.d.ts +18 -0
- package/dist/common/shopping-dashboard/shared/ConversionRate/ConversionRateFullView.styled.d.ts +37 -0
- package/dist/common/shopping-dashboard/shared/DashboardHeader.d.ts +14 -0
- package/dist/common/shopping-dashboard/shared/DashboardHeader.styled.d.ts +48 -0
- package/dist/common/shopping-dashboard/shared/DataTable.d.ts +18 -0
- package/dist/common/shopping-dashboard/shared/DataTable.styled.d.ts +42 -0
- package/dist/common/shopping-dashboard/shared/FilterBar.d.ts +7 -0
- package/dist/common/shopping-dashboard/shared/FilterBar.styled.d.ts +12 -0
- package/dist/common/shopping-dashboard/shared/FullViewComponents.styled.d.ts +52 -0
- package/dist/common/shopping-dashboard/shared/LoadingSkeletons.d.ts +8 -0
- package/dist/common/shopping-dashboard/shared/LoadingSkeletons.styled.d.ts +121 -0
- package/dist/common/shopping-dashboard/shared/PageHeader.d.ts +32 -0
- package/dist/common/shopping-dashboard/shared/PageHeader.styled.d.ts +56 -0
- package/dist/common/shopping-dashboard/shared/Pagination.d.ts +9 -0
- package/dist/common/shopping-dashboard/shared/Pagination.styled.d.ts +18 -0
- package/dist/common/shopping-dashboard/shared/Signups/SignupsChart.d.ts +11 -0
- package/dist/common/shopping-dashboard/shared/Signups/SignupsChart.styled.d.ts +56 -0
- package/dist/common/shopping-dashboard/shared/Signups/SignupsFullView.d.ts +16 -0
- package/dist/common/shopping-dashboard/shared/Signups/SignupsFullView.styled.d.ts +15 -0
- package/dist/common/shopping-dashboard/shared/StatsCard.d.ts +13 -0
- package/dist/common/shopping-dashboard/shared/StatsCard.styled.d.ts +62 -0
- package/dist/common/shopping-dashboard/shared/TopCategories/CategoriesFullView.d.ts +15 -0
- package/dist/common/shopping-dashboard/shared/TopCategories/CategoriesFullView.styled.d.ts +72 -0
- package/dist/common/shopping-dashboard/shared/TopCategories/TopCategoriesPieChart.d.ts +11 -0
- package/dist/common/shopping-dashboard/shared/TopCategories/TopCategoriesPieChart.styled.d.ts +90 -0
- package/dist/common/shopping-dashboard/shared/TopPerformingOffers/TopPerformingOffersFullView.d.ts +15 -0
- package/dist/common/shopping-dashboard/shared/TopPerformingOffers/TopPerformingOffersFullView.styled.d.ts +86 -0
- package/dist/common/shopping-dashboard/shared/TopPerformingOffers/TopPerformingOffersPieChart.d.ts +11 -0
- package/dist/common/shopping-dashboard/shared/TopProducts/ProductsFullView.d.ts +15 -0
- package/dist/common/shopping-dashboard/shared/TopProducts/ProductsFullView.styled.d.ts +53 -0
- package/dist/common/shopping-dashboard/shared/TopProducts/TopSellingProductsList.d.ts +11 -0
- package/dist/common/shopping-dashboard/shared/TopProducts/TopSellingProductsList.styled.d.ts +74 -0
- package/dist/common/shopping-dashboard/shared/WidgetMenu.d.ts +6 -0
- package/dist/common/shopping-dashboard/shared/WidgetMenu.styled.d.ts +5 -0
- package/dist/common/shopping-dashboard/shared/types.d.ts +13 -0
- package/dist/common/shopping-dashboard/shared/useViewport.d.ts +2 -0
- package/dist/common/shopping-dashboard/specs/CategoriesFullView.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/ConversionRateChart.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/ConversionRateFullView.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/DashboardHeader.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/DataTable.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/FilterBar.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/MysiteDashboardWithNavigation.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/Pagination.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/PoDashboardWithNavigation.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/ProductOfferDashboard.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/ProductsFullView.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/ShoppingDashboard.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/SignupsFullView.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/TopCategoriesPieChart.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/TopPerformingOffersFullView.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/TopPerformingOffersPieChart.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/TopSellingProductsList.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/WidgetMenu.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/dataUtils.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/dateFormat.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/marketOptions.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/productOfferTranslation.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/translationResolver.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/specs/trendUtils.spec.d.ts +1 -0
- package/dist/common/shopping-dashboard/stories/CategoriesFullView.stories.d.ts +10 -0
- package/dist/common/shopping-dashboard/stories/ConversionRateChart.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/ConversionRateFullView.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/DashboardHeader.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/DataTable.stories.d.ts +8 -0
- package/dist/common/shopping-dashboard/stories/PageHeader.stories.d.ts +8 -0
- package/dist/common/shopping-dashboard/stories/Pagination.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/ProductOfferDashboard.stories.d.ts +13 -0
- package/dist/common/shopping-dashboard/stories/ProductsFullView.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/ShoppingDashboard.stories.d.ts +13 -0
- package/dist/common/shopping-dashboard/stories/SignupsChart.stories.d.ts +10 -0
- package/dist/common/shopping-dashboard/stories/SignupsFullView.stories.d.ts +9 -0
- package/dist/common/shopping-dashboard/stories/StatsCard.stories.d.ts +11 -0
- package/dist/common/shopping-dashboard/stories/TopCategoriesPieChart.stories.d.ts +10 -0
- package/dist/common/shopping-dashboard/stories/TopPerformingOffersFullView.stories.d.ts +10 -0
- package/dist/common/shopping-dashboard/stories/TopPerformingOffersPieChart.stories.d.ts +11 -0
- package/dist/common/shopping-dashboard/stories/TopSellingProductsList.stories.d.ts +11 -0
- package/dist/common/shopping-dashboard/utils/dataUtils.d.ts +9 -0
- package/dist/common/shopping-dashboard/utils/dateConstants.d.ts +5 -0
- package/dist/common/shopping-dashboard/utils/dateFormat.d.ts +7 -0
- package/dist/common/shopping-dashboard/utils/marketOptions.d.ts +4 -0
- package/dist/common/shopping-dashboard/utils/trendUtils.d.ts +11 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -123,6 +123,202 @@ The main hero component for Mysite pages with advanced scroll behavior and respo
|
|
|
123
123
|
[];
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
### Shopping Dashboard Suite
|
|
127
|
+
|
|
128
|
+
The Shopping Dashboard provides a complete analytics experience with overview widgets,
|
|
129
|
+
full-detail views, and stateful in-page navigation.
|
|
130
|
+
|
|
131
|
+
#### Highlights
|
|
132
|
+
|
|
133
|
+
- Dashboard overview with stats cards and 4 widgets (Top Products, Sign-ups, Conversion Rate, Top Categories)
|
|
134
|
+
- Full views for each widget with filtering, sorting, and pagination
|
|
135
|
+
- History-state navigation between dashboard and full views (back/forward/refresh aware)
|
|
136
|
+
- Loading skeletons and explicit empty/error states
|
|
137
|
+
- Translation-ready text (`getTranslation` + key catalog)
|
|
138
|
+
- Accessibility and test automation support with stable `data-testid` selectors
|
|
139
|
+
- Responsive mobile/desktop rendering with performance-focused optimizations
|
|
140
|
+
|
|
141
|
+
#### Main Exports
|
|
142
|
+
|
|
143
|
+
- `ShoppingDashboard`
|
|
144
|
+
- `MysiteDashboardWithNavigation`
|
|
145
|
+
- `ProductOfferDashboard`
|
|
146
|
+
- `PoDashboardWithNavigation`
|
|
147
|
+
- `ProductsFullView`
|
|
148
|
+
- `SignupsFullView`
|
|
149
|
+
- `ConversionRateFullView`
|
|
150
|
+
- `CategoriesFullView`
|
|
151
|
+
- `TopPerformingOffersFullView`
|
|
152
|
+
- `StatsCard`, `DashboardHeader`, `WidgetMenu`
|
|
153
|
+
- `TopSellingProductsList`, `SignupsChart`, `ConversionRateChart`, `TopCategoriesPieChart`, `TopPerformingOffersPieChart`
|
|
154
|
+
|
|
155
|
+
#### Quick Usage
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import React, { useState } from 'react';
|
|
159
|
+
import {
|
|
160
|
+
MysiteDashboardWithNavigation,
|
|
161
|
+
mockStats,
|
|
162
|
+
mockTopProducts,
|
|
163
|
+
mockConversionData,
|
|
164
|
+
mockSignupData,
|
|
165
|
+
mockCategories,
|
|
166
|
+
mockOrders,
|
|
167
|
+
mockSignupDetails,
|
|
168
|
+
} from '@nuskin/react-mysite-elements';
|
|
169
|
+
|
|
170
|
+
export default function DashboardExample() {
|
|
171
|
+
const [dateRange, setDateRange] = useState('last30days');
|
|
172
|
+
const [market, setMarket] = useState('all');
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<MysiteDashboardWithNavigation
|
|
176
|
+
stats={mockStats}
|
|
177
|
+
topProducts={mockTopProducts}
|
|
178
|
+
conversionData={mockConversionData}
|
|
179
|
+
signupData={mockSignupData}
|
|
180
|
+
categories={mockCategories}
|
|
181
|
+
orders={mockOrders}
|
|
182
|
+
signups={mockSignupDetails}
|
|
183
|
+
dateRange={dateRange}
|
|
184
|
+
market={market}
|
|
185
|
+
onDateRangeChange={setDateRange}
|
|
186
|
+
onMarketChange={setMarket}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Translations (i18n)
|
|
193
|
+
|
|
194
|
+
The dashboard ships built-in **English** fallback strings for every label (see the
|
|
195
|
+
`ShoppingDashboardTranslationKeys` catalog). To localize, pass an optional
|
|
196
|
+
`translate` resolver — `(key, fallback) => string` — into the top-level component.
|
|
197
|
+
Every internal `getTranslation` call routes through it; any key the resolver can't
|
|
198
|
+
localize (or an empty/throwing result) safely falls back to the built-in English text,
|
|
199
|
+
so partial catalogs are fine. Omit the prop to keep the current English-only behavior.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { MysiteDashboardWithNavigation } from '@nuskin/react-mysite-elements';
|
|
203
|
+
// e.g. a ContentStack-backed resolver in the host app
|
|
204
|
+
import { translate } from '@/utils/translation';
|
|
205
|
+
|
|
206
|
+
<MysiteDashboardWithNavigation
|
|
207
|
+
translate={translate} // (key: string, fallback: string) => string
|
|
208
|
+
stats={stats}
|
|
209
|
+
/* …other props… */
|
|
210
|
+
/>;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
A declarative `TranslationProvider` and a `useTranslation()` hook are also exported for
|
|
214
|
+
advanced/standalone usage:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
import { TranslationProvider } from '@nuskin/react-mysite-elements';
|
|
218
|
+
|
|
219
|
+
<TranslationProvider translate={translate}>{/* any dashboard components */}</TranslationProvider>;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Translation keys follow the `shoppingDashboard.*` namespace; the host maps these to its
|
|
223
|
+
locale resources.
|
|
224
|
+
|
|
225
|
+
#### Storybook
|
|
226
|
+
|
|
227
|
+
Shopping Dashboard stories are available under the `ShoppingDashboard` group, including
|
|
228
|
+
loading, error, navigation, and full-view scenarios.
|
|
229
|
+
|
|
230
|
+
#### Product Offer Dashboard
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import {
|
|
234
|
+
PoDashboardWithNavigation,
|
|
235
|
+
mockProductOfferStats,
|
|
236
|
+
mockTopProducts,
|
|
237
|
+
mockConversionData,
|
|
238
|
+
mockTopOffers,
|
|
239
|
+
} from '@nuskin/react-mysite-elements';
|
|
240
|
+
|
|
241
|
+
export default function ProductOfferDashboardExample() {
|
|
242
|
+
return (
|
|
243
|
+
<PoDashboardWithNavigation
|
|
244
|
+
stats={mockProductOfferStats}
|
|
245
|
+
topProducts={mockTopProducts}
|
|
246
|
+
conversionData={mockConversionData}
|
|
247
|
+
topOffers={mockTopOffers}
|
|
248
|
+
/>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### Dashboard Architecture
|
|
254
|
+
|
|
255
|
+
The dashboard is a **presentational (dumb) component library**. It renders whatever
|
|
256
|
+
data the host application passes in and owns none of the data fetching. Hosts
|
|
257
|
+
(`Mysite-Admin`, `Personal-offer-mfe`) are responsible for calling the analytics APIs,
|
|
258
|
+
adapting the raw responses into the view models below, and passing them in as props.
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
┌──────────────────────── Host application (Mysite-Admin / PO-MFE) ───────────────────────┐
|
|
262
|
+
│ API call ──▶ adapters (adaptDashboardResponse / drilldownAdapters) ──▶ view models │
|
|
263
|
+
└───────────────────────────────────────────┬─────────────────────────────────────────────┘
|
|
264
|
+
│ props (stats, topProducts, categories, …)
|
|
265
|
+
▼
|
|
266
|
+
┌──────────────── *DashboardWithNavigation (stateful wrapper) ────────────────┐
|
|
267
|
+
│ Owns view state + history-state navigation (overview ⇄ full views) │
|
|
268
|
+
│ │
|
|
269
|
+
│ ┌── Overview ──────────────┐ ┌── Full views ───────────────────┐ │
|
|
270
|
+
│ │ StatsCard × n │ │ ProductsFullView │ │
|
|
271
|
+
│ │ TopSellingProductsList │ ⇄ │ CategoriesFullView │ │
|
|
272
|
+
│ │ ConversionRateChart │ │ ConversionRateFullView │ │
|
|
273
|
+
│ │ TopCategoriesPieChart │ │ TopPerformingOffersFullView … │ │
|
|
274
|
+
│ └──────────────────────────┘ └──────────────────────────────────┘ │
|
|
275
|
+
│ │
|
|
276
|
+
│ shared/ primitives: DataTable · Pagination · FilterBar · PageHeader · │
|
|
277
|
+
│ WidgetMenu · LoadingSkeletons │
|
|
278
|
+
│ utils/: dataUtils (formatMoney, usePaginatedItems) · trendUtils · │
|
|
279
|
+
│ marketOptions · dateFormat │
|
|
280
|
+
└──────────────────────────────────────────────────────────────────────────────┘
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
##### Layers
|
|
284
|
+
|
|
285
|
+
| Layer | Location | Responsibility |
|
|
286
|
+
| ----------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
287
|
+
| Stateful wrapper | `MysiteDashboardWithNavigation`, `PoDashboardWithNavigation` | View selection, history-state (back/forward/refresh) navigation, prop routing |
|
|
288
|
+
| Overview screens | `ShoppingDashboard`, `ProductOfferDashboard` | Compose stats cards + widgets for the landing view |
|
|
289
|
+
| Widgets | `shared/TopProducts`, `shared/TopCategories`, `shared/ConversionRate`, `shared/Signups`, `shared/TopPerformingOffers` | Summarized charts/lists shown on the overview |
|
|
290
|
+
| Full views | `*FullView.tsx` in each `shared/*` folder | Detailed tables/charts with filtering, sorting, and pagination |
|
|
291
|
+
| Shared primitives | `shared/` (`DataTable`, `Pagination`, `FilterBar`, `PageHeader`, `WidgetMenu`, `LoadingSkeletons`) | Reusable building blocks across every screen |
|
|
292
|
+
| Utilities | `utils/` | `formatMoney`, `usePaginatedItems`, trend parsing, market/date helpers |
|
|
293
|
+
| Types | `types.d.ts`, `types/` | Shared view-model contracts (`TopProduct`, `CategoryRevenue`, `OrderHistory`, …) |
|
|
294
|
+
| Translations | `TranslationContext.tsx`, `TranslationKeys/` | `getTranslation` catalog + optional host `translate` resolver |
|
|
295
|
+
|
|
296
|
+
##### Navigation model
|
|
297
|
+
|
|
298
|
+
`*DashboardWithNavigation` keeps the active view in local state and mirrors it into
|
|
299
|
+
`window.history` state, so browser **back / forward / refresh** move between the overview
|
|
300
|
+
and a full view without a hard reload. Filter, sort, and page selections live in the
|
|
301
|
+
component that owns the view and reset appropriately when the underlying data changes.
|
|
302
|
+
|
|
303
|
+
##### Currency formatting
|
|
304
|
+
|
|
305
|
+
Monetary values are formatted **inside the library** so charts, totals, and sorting keep
|
|
306
|
+
working with numeric revenue while still displaying the correct symbol. Each data item
|
|
307
|
+
carries an optional `currencyCode` (ISO code, e.g. `USD`, `EUR`) that the host adapters
|
|
308
|
+
stamp from the API `currency_code` field. Rendering goes through the `formatMoney` helper:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
formatMoney(value, currencyCode?, locale = 'en-US', fractionDigits?)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
- When `currencyCode` is present it uses `Intl.NumberFormat` (code → symbol) with natural
|
|
315
|
+
decimals (`0`–`2`); pass `fractionDigits` to force fixed decimals (order totals use `2`).
|
|
316
|
+
- When `currencyCode` is missing or invalid it falls back to a `$` prefix, so existing
|
|
317
|
+
behavior is preserved.
|
|
318
|
+
|
|
319
|
+
Hosts should populate `currencyCode` on every money-bearing item (products, categories,
|
|
320
|
+
offers, order rows). See `HOST_APP_API_RESPONSE.md` for the expected API payload shape.
|
|
321
|
+
|
|
126
322
|
## ✨ Advanced Features
|
|
127
323
|
|
|
128
324
|
### Intelligent Scroll Behavior
|
|
@@ -250,6 +446,36 @@ The component automatically detects and integrates with Nu Skin's external heade
|
|
|
250
446
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
251
447
|
5. Open a Pull Request
|
|
252
448
|
|
|
449
|
+
### Constitution Compliance (Required)
|
|
450
|
+
|
|
451
|
+
All UI contributions must follow the repository constitution in
|
|
452
|
+
`.specify/memory/constitution.md`.
|
|
453
|
+
|
|
454
|
+
Core non-negotiable rules:
|
|
455
|
+
|
|
456
|
+
- No inline CSS in production components (`style={{}}`, inline `sx`, runtime `.style` mutation)
|
|
457
|
+
- Styled component definitions must live in dedicated `*.styled.tsx` files, not inside component files
|
|
458
|
+
- No hardcoded user-visible strings in component code (use translation keys)
|
|
459
|
+
- Accessibility-first implementation (ADA/WCAG aligned)
|
|
460
|
+
- Mobile and desktop viewport validation for changed flows
|
|
461
|
+
- Stable `data-testid` selectors for critical interactions
|
|
462
|
+
|
|
463
|
+
PR validation checklist:
|
|
464
|
+
|
|
465
|
+
- [ ] UI styles are in stylesheet/styled-component files only
|
|
466
|
+
- [ ] Styled components are defined in `*.styled.tsx` files, not inline in component files
|
|
467
|
+
- [ ] All user-facing text is sourced from translation files
|
|
468
|
+
- [ ] Keyboard and semantic accessibility checks were completed
|
|
469
|
+
- [ ] Mobile and desktop behavior was validated
|
|
470
|
+
- [ ] Critical interactive elements include `data-testid`
|
|
471
|
+
|
|
472
|
+
Recommended verification commands:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
npx jest --testPathPattern="shopping-dashboard" --no-coverage
|
|
476
|
+
npx tsc --noEmit --project tsconfig.json
|
|
477
|
+
```
|
|
478
|
+
|
|
253
479
|
### Commit Convention
|
|
254
480
|
|
|
255
481
|
We use [Conventional Commits](https://www.conventionalcommits.org/) for semantic versioning:
|
|
@@ -34,7 +34,7 @@ interface ProductTabCarouselProps {
|
|
|
34
34
|
readonly emptyProductMessage?: string;
|
|
35
35
|
readonly showCustomCategory?: boolean;
|
|
36
36
|
readonly productsCountLabel?: string;
|
|
37
|
-
readonly getCategoryId
|
|
37
|
+
readonly getCategoryId?: (categoryId: string) => Promise<Category[]>;
|
|
38
38
|
readonly history?: {
|
|
39
39
|
push: (path: string) => void;
|
|
40
40
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const StyledButton: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
2
|
+
ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
3
|
+
}, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
|
|
4
|
+
brandColor: string;
|
|
5
|
+
}, {}, {}>;
|
package/dist/common/index.d.ts
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TranslateFn } from './TranslationKeys/translationResolver';
|
|
3
|
+
import type { DashboardStats, TopProduct, ConversionDataPoint, SignupDataPoint, CategoryRevenue, OrderHistory, SignupDetail, DateRangeOption, MarketOption, MarketFilterOption, ProductSortOption, SignupViewOption, ConversionFilterOption, CategorySortOption, FullViewWidgetType } from './types.d';
|
|
4
|
+
export type MysiteDashboardView = 'dashboard' | FullViewWidgetType;
|
|
5
|
+
export interface MysiteDashboardHistoryLocation {
|
|
6
|
+
readonly pathname?: string;
|
|
7
|
+
readonly search?: string;
|
|
8
|
+
readonly hash?: string;
|
|
9
|
+
readonly state?: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface MysiteDashboardHistoryAdapter {
|
|
12
|
+
readonly location?: MysiteDashboardHistoryLocation;
|
|
13
|
+
push(location: MysiteDashboardHistoryLocation): void;
|
|
14
|
+
replace(location: MysiteDashboardHistoryLocation): void;
|
|
15
|
+
goBack(): void;
|
|
16
|
+
listen(listener: (location: MysiteDashboardHistoryLocation, action: string) => void): () => void;
|
|
17
|
+
}
|
|
18
|
+
export interface MysiteDashboardWithNavigationProps {
|
|
19
|
+
readonly stats?: DashboardStats | null;
|
|
20
|
+
readonly topProducts?: TopProduct[];
|
|
21
|
+
readonly conversionData?: ConversionDataPoint[];
|
|
22
|
+
readonly signupData?: SignupDataPoint[];
|
|
23
|
+
readonly categories?: CategoryRevenue[];
|
|
24
|
+
readonly orders?: OrderHistory[];
|
|
25
|
+
readonly signups?: SignupDetail[];
|
|
26
|
+
readonly isLoading?: boolean;
|
|
27
|
+
readonly error?: string | null;
|
|
28
|
+
readonly shopTitle?: string;
|
|
29
|
+
readonly className?: string;
|
|
30
|
+
readonly translate?: TranslateFn;
|
|
31
|
+
readonly initialDateRange?: DateRangeOption;
|
|
32
|
+
readonly initialMarket?: MarketOption;
|
|
33
|
+
readonly initialProductSort?: ProductSortOption;
|
|
34
|
+
readonly initialSignupView?: SignupViewOption;
|
|
35
|
+
readonly initialConversionFilter?: ConversionFilterOption;
|
|
36
|
+
readonly initialCategorySort?: CategorySortOption;
|
|
37
|
+
readonly markets?: ReadonlyArray<MarketFilterOption>;
|
|
38
|
+
readonly historyAdapter?: MysiteDashboardHistoryAdapter;
|
|
39
|
+
readonly historyStateKey?: string;
|
|
40
|
+
readonly resetToDashboardOnMount?: boolean;
|
|
41
|
+
readonly onDateRangeChange?: (range: DateRangeOption) => void;
|
|
42
|
+
readonly onMarketChange?: (market: MarketOption) => void;
|
|
43
|
+
readonly onProductSortChange?: (sort: ProductSortOption) => void;
|
|
44
|
+
readonly onSignupViewChange?: (view: SignupViewOption) => void;
|
|
45
|
+
readonly onConversionFilterChange?: (filter: ConversionFilterOption) => void;
|
|
46
|
+
readonly onCategorySortChange?: (sort: CategorySortOption) => void;
|
|
47
|
+
readonly onViewChange?: (view: MysiteDashboardView) => void;
|
|
48
|
+
}
|
|
49
|
+
export declare const MysiteDashboardWithNavigation: React.FC<MysiteDashboardWithNavigationProps>;
|
|
50
|
+
export default MysiteDashboardWithNavigation;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const PoDashboardContainer: import("@emotion/styled").StyledComponent<{
|
|
2
|
+
theme?: import("@emotion/react").Theme;
|
|
3
|
+
as?: React.ElementType;
|
|
4
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
5
|
+
export declare const TopChartsRow: import("@emotion/styled").StyledComponent<{
|
|
6
|
+
theme?: import("@emotion/react").Theme;
|
|
7
|
+
as?: React.ElementType;
|
|
8
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
9
|
+
export declare const StatsCardStack: import("@emotion/styled").StyledComponent<{
|
|
10
|
+
theme?: import("@emotion/react").Theme;
|
|
11
|
+
as?: React.ElementType;
|
|
12
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
13
|
+
export declare const BottomChartsRow: import("@emotion/styled").StyledComponent<{
|
|
14
|
+
theme?: import("@emotion/react").Theme;
|
|
15
|
+
as?: React.ElementType;
|
|
16
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
17
|
+
export declare const ErrorContainer: import("@emotion/styled").StyledComponent<{
|
|
18
|
+
theme?: import("@emotion/react").Theme;
|
|
19
|
+
as?: React.ElementType;
|
|
20
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DashboardStats, TopProduct, ConversionDataPoint, SignupDataPoint, CategoryRevenue, DateRangeOption, MarketOption, MarketFilterOption, ProductSortOption, SignupViewOption, ConversionFilterOption, CategorySortOption } from './types.d';
|
|
3
|
+
export interface ShoppingDashboardProps {
|
|
4
|
+
readonly stats?: DashboardStats | null;
|
|
5
|
+
readonly topProducts?: TopProduct[];
|
|
6
|
+
readonly conversionData?: ConversionDataPoint[];
|
|
7
|
+
readonly signupData?: SignupDataPoint[];
|
|
8
|
+
readonly categories?: CategoryRevenue[];
|
|
9
|
+
readonly isLoading?: boolean;
|
|
10
|
+
readonly error?: string | null;
|
|
11
|
+
readonly shopTitle?: string;
|
|
12
|
+
readonly className?: string;
|
|
13
|
+
readonly dateRange?: DateRangeOption;
|
|
14
|
+
readonly market?: MarketOption;
|
|
15
|
+
readonly productSort?: ProductSortOption;
|
|
16
|
+
readonly signupView?: SignupViewOption;
|
|
17
|
+
readonly conversionFilter?: ConversionFilterOption;
|
|
18
|
+
readonly categorySort?: CategorySortOption;
|
|
19
|
+
readonly markets?: ReadonlyArray<MarketFilterOption>;
|
|
20
|
+
readonly onDateRangeChange?: (range: DateRangeOption) => void;
|
|
21
|
+
readonly onMarketChange?: (market: MarketOption) => void;
|
|
22
|
+
readonly onProductSortChange?: (sort: ProductSortOption) => void;
|
|
23
|
+
readonly onSignupViewChange?: (view: SignupViewOption) => void;
|
|
24
|
+
readonly onConversionFilterChange?: (filter: ConversionFilterOption) => void;
|
|
25
|
+
readonly onCategorySortChange?: (sort: CategorySortOption) => void;
|
|
26
|
+
readonly onProductsTitleClick?: () => void;
|
|
27
|
+
readonly onConversionTitleClick?: () => void;
|
|
28
|
+
readonly onSignupsTitleClick?: () => void;
|
|
29
|
+
readonly onCategoriesToTitleClick?: () => void;
|
|
30
|
+
}
|
|
31
|
+
export declare const ShoppingDashboard: React.FC<ShoppingDashboardProps>;
|
|
32
|
+
export default ShoppingDashboard;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const DashboardContainer: import("@emotion/styled").StyledComponent<{
|
|
2
|
+
theme?: import("@emotion/react").Theme;
|
|
3
|
+
as?: React.ElementType;
|
|
4
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
5
|
+
export declare const StatsRow: import("@emotion/styled").StyledComponent<{
|
|
6
|
+
theme?: import("@emotion/react").Theme;
|
|
7
|
+
as?: React.ElementType;
|
|
8
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
9
|
+
export declare const WidgetContainer: import("@emotion/styled").StyledComponent<{
|
|
10
|
+
theme?: import("@emotion/react").Theme;
|
|
11
|
+
as?: React.ElementType;
|
|
12
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
13
|
+
export declare const TwoColumnGrid: import("@emotion/styled").StyledComponent<{
|
|
14
|
+
theme?: import("@emotion/react").Theme;
|
|
15
|
+
as?: React.ElementType;
|
|
16
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
17
|
+
export declare const ErrorContainer: import("@emotion/styled").StyledComponent<{
|
|
18
|
+
theme?: import("@emotion/react").Theme;
|
|
19
|
+
as?: React.ElementType;
|
|
20
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type TranslateFn, type TranslationEntry } from './TranslationKeys/translationResolver';
|
|
3
|
+
export declare function useTranslationResolver(translate?: TranslateFn): void;
|
|
4
|
+
export interface TranslationProviderProps {
|
|
5
|
+
readonly translate?: TranslateFn;
|
|
6
|
+
readonly children?: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare const TranslationProvider: React.FC<TranslationProviderProps>;
|
|
9
|
+
export declare function useTranslation(): (entry: TranslationEntry) => string;
|
|
10
|
+
export type { TranslateFn, TranslationEntry };
|
package/dist/common/shopping-dashboard/TranslationKeys/ProductOfferDashboardTranslationKeys.d.ts
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
type TranslationEntry = {
|
|
2
|
+
readonly key: string;
|
|
3
|
+
readonly fallback: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const ProductOfferDashboardTranslationKeys: {
|
|
6
|
+
readonly title: {
|
|
7
|
+
readonly key: "productOfferDashboard.title";
|
|
8
|
+
readonly fallback: "Performance Overview";
|
|
9
|
+
};
|
|
10
|
+
readonly error: {
|
|
11
|
+
readonly key: "productOfferDashboard.error";
|
|
12
|
+
readonly fallback: "Failed to load dashboard data. Please try again.";
|
|
13
|
+
};
|
|
14
|
+
readonly stats: {
|
|
15
|
+
readonly revenue: {
|
|
16
|
+
readonly key: "productOfferDashboard.stats.revenue";
|
|
17
|
+
readonly fallback: "Total Revenue";
|
|
18
|
+
};
|
|
19
|
+
readonly offersPurchased: {
|
|
20
|
+
readonly key: "productOfferDashboard.stats.offersPurchased";
|
|
21
|
+
readonly fallback: "Offers Purchased";
|
|
22
|
+
};
|
|
23
|
+
readonly conversionRate: {
|
|
24
|
+
readonly key: "productOfferDashboard.stats.conversionRate";
|
|
25
|
+
readonly fallback: "Conversion Rate";
|
|
26
|
+
};
|
|
27
|
+
readonly trendUp: {
|
|
28
|
+
readonly key: "productOfferDashboard.stats.trendUp";
|
|
29
|
+
readonly fallback: "Trending up";
|
|
30
|
+
};
|
|
31
|
+
readonly trendDown: {
|
|
32
|
+
readonly key: "productOfferDashboard.stats.trendDown";
|
|
33
|
+
readonly fallback: "Trending down";
|
|
34
|
+
};
|
|
35
|
+
readonly trendNeutral: {
|
|
36
|
+
readonly key: "productOfferDashboard.stats.trendNeutral";
|
|
37
|
+
readonly fallback: "No change";
|
|
38
|
+
};
|
|
39
|
+
readonly comparedTo: {
|
|
40
|
+
readonly key: "productOfferDashboard.stats.comparedTo";
|
|
41
|
+
readonly fallback: "compared to this time last month";
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly filter: {
|
|
45
|
+
readonly dateRange: {
|
|
46
|
+
readonly label: {
|
|
47
|
+
readonly key: "productOfferDashboard.filter.dateRange.label";
|
|
48
|
+
readonly fallback: "Date Range";
|
|
49
|
+
};
|
|
50
|
+
readonly last7days: {
|
|
51
|
+
readonly key: "productOfferDashboard.filter.dateRange.last7days";
|
|
52
|
+
readonly fallback: "Last 7 Days";
|
|
53
|
+
};
|
|
54
|
+
readonly last30days: {
|
|
55
|
+
readonly key: "productOfferDashboard.filter.dateRange.last30days";
|
|
56
|
+
readonly fallback: "Last 30 Days";
|
|
57
|
+
};
|
|
58
|
+
readonly last90days: {
|
|
59
|
+
readonly key: "productOfferDashboard.filter.dateRange.last90days";
|
|
60
|
+
readonly fallback: "Last 90 Days";
|
|
61
|
+
};
|
|
62
|
+
readonly thisMonth: {
|
|
63
|
+
readonly key: "productOfferDashboard.filter.dateRange.thisMonth";
|
|
64
|
+
readonly fallback: "This Month";
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
readonly market: {
|
|
68
|
+
readonly label: {
|
|
69
|
+
readonly key: "productOfferDashboard.filter.market.label";
|
|
70
|
+
readonly fallback: "Market";
|
|
71
|
+
};
|
|
72
|
+
readonly all: {
|
|
73
|
+
readonly key: "productOfferDashboard.filter.market.all";
|
|
74
|
+
readonly fallback: "All Markets";
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
readonly offerSort: {
|
|
78
|
+
readonly byRevenue: {
|
|
79
|
+
readonly key: "productOfferDashboard.filter.offerSort.byRevenue";
|
|
80
|
+
readonly fallback: "Revenue";
|
|
81
|
+
};
|
|
82
|
+
readonly byUnits: {
|
|
83
|
+
readonly key: "productOfferDashboard.filter.offerSort.byUnits";
|
|
84
|
+
readonly fallback: "Units";
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
readonly productSort: {
|
|
88
|
+
readonly byUnits: {
|
|
89
|
+
readonly key: "productOfferDashboard.filter.productSort.byUnits";
|
|
90
|
+
readonly fallback: "Units";
|
|
91
|
+
};
|
|
92
|
+
readonly byRevenue: {
|
|
93
|
+
readonly key: "productOfferDashboard.filter.productSort.byRevenue";
|
|
94
|
+
readonly fallback: "Revenue";
|
|
95
|
+
};
|
|
96
|
+
readonly byVolume: {
|
|
97
|
+
readonly key: "productOfferDashboard.filter.productSort.byVolume";
|
|
98
|
+
readonly fallback: "Volume";
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
readonly conversionFilter: {
|
|
102
|
+
readonly overall: {
|
|
103
|
+
readonly key: "productOfferDashboard.filter.conversionFilter.overall";
|
|
104
|
+
readonly fallback: "Overall";
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
readonly widget: {
|
|
109
|
+
readonly topProducts: {
|
|
110
|
+
readonly title: {
|
|
111
|
+
readonly key: "productOfferDashboard.widget.topProducts.title";
|
|
112
|
+
readonly fallback: "Top Selling Products";
|
|
113
|
+
};
|
|
114
|
+
readonly emptyState: {
|
|
115
|
+
readonly key: "productOfferDashboard.widget.topProducts.emptyState";
|
|
116
|
+
readonly fallback: "No products data available";
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
readonly conversionRate: {
|
|
120
|
+
readonly title: {
|
|
121
|
+
readonly key: "productOfferDashboard.widget.conversionRate.title";
|
|
122
|
+
readonly fallback: "Conversion Rate";
|
|
123
|
+
};
|
|
124
|
+
readonly subtitle: {
|
|
125
|
+
readonly key: "productOfferDashboard.widget.conversionRate.subtitle";
|
|
126
|
+
readonly fallback: "Orders ÷ Site visits";
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
readonly topPerformingOffers: {
|
|
130
|
+
readonly title: {
|
|
131
|
+
readonly key: "productOfferDashboard.widget.topPerformingOffers.title";
|
|
132
|
+
readonly fallback: "Top Performing Offers";
|
|
133
|
+
};
|
|
134
|
+
readonly totalRevenue: {
|
|
135
|
+
readonly key: "productOfferDashboard.widget.topPerformingOffers.totalRevenue";
|
|
136
|
+
readonly fallback: "Total revenue";
|
|
137
|
+
};
|
|
138
|
+
readonly emptyState: {
|
|
139
|
+
readonly key: "productOfferDashboard.widget.topPerformingOffers.emptyState";
|
|
140
|
+
readonly fallback: "No offers data available";
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
readonly menu: {
|
|
144
|
+
readonly fullView: {
|
|
145
|
+
readonly key: "productOfferDashboard.widget.menu.fullView";
|
|
146
|
+
readonly fallback: "Full View";
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
readonly navigation: {
|
|
151
|
+
readonly back: {
|
|
152
|
+
readonly key: "productOfferDashboard.navigation.back";
|
|
153
|
+
readonly fallback: "Back to Dashboard";
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
readonly ariaLabel: {
|
|
157
|
+
readonly dashboard: {
|
|
158
|
+
readonly key: "productOfferDashboard.ariaLabel.dashboard";
|
|
159
|
+
readonly fallback: "Product Offer Performance Dashboard";
|
|
160
|
+
};
|
|
161
|
+
readonly statsCard: {
|
|
162
|
+
readonly key: "productOfferDashboard.ariaLabel.statsCard";
|
|
163
|
+
readonly fallback: "Performance metric";
|
|
164
|
+
};
|
|
165
|
+
readonly conversionChart: {
|
|
166
|
+
readonly key: "productOfferDashboard.ariaLabel.conversionChart";
|
|
167
|
+
readonly fallback: "Conversion rate chart";
|
|
168
|
+
};
|
|
169
|
+
readonly topProducts: {
|
|
170
|
+
readonly key: "productOfferDashboard.ariaLabel.topProducts";
|
|
171
|
+
readonly fallback: "Top selling products";
|
|
172
|
+
};
|
|
173
|
+
readonly topOffers: {
|
|
174
|
+
readonly key: "productOfferDashboard.ariaLabel.topOffers";
|
|
175
|
+
readonly fallback: "Top performing offers chart";
|
|
176
|
+
};
|
|
177
|
+
readonly widgetMenu: {
|
|
178
|
+
readonly key: "productOfferDashboard.ariaLabel.widgetMenu";
|
|
179
|
+
readonly fallback: "Widget options menu";
|
|
180
|
+
};
|
|
181
|
+
readonly filterDateRange: {
|
|
182
|
+
readonly key: "productOfferDashboard.ariaLabel.filterDateRange";
|
|
183
|
+
readonly fallback: "Filter by date range";
|
|
184
|
+
};
|
|
185
|
+
readonly filterMarket: {
|
|
186
|
+
readonly key: "productOfferDashboard.ariaLabel.filterMarket";
|
|
187
|
+
readonly fallback: "Filter by market";
|
|
188
|
+
};
|
|
189
|
+
readonly backButton: {
|
|
190
|
+
readonly key: "productOfferDashboard.ariaLabel.backButton";
|
|
191
|
+
readonly fallback: "Back to dashboard overview";
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
readonly fullView: {
|
|
195
|
+
readonly topOffers: {
|
|
196
|
+
readonly title: {
|
|
197
|
+
readonly key: "productOfferDashboard.fullView.topOffers.title";
|
|
198
|
+
readonly fallback: "Top Performing Offers";
|
|
199
|
+
};
|
|
200
|
+
readonly columnName: {
|
|
201
|
+
readonly key: "productOfferDashboard.fullView.topOffers.columnName";
|
|
202
|
+
readonly fallback: "Offer Name";
|
|
203
|
+
};
|
|
204
|
+
readonly columnRevenue: {
|
|
205
|
+
readonly key: "productOfferDashboard.fullView.topOffers.columnRevenue";
|
|
206
|
+
readonly fallback: "Revenue";
|
|
207
|
+
};
|
|
208
|
+
readonly columnPercentage: {
|
|
209
|
+
readonly key: "productOfferDashboard.fullView.topOffers.columnPercentage";
|
|
210
|
+
readonly fallback: "Share";
|
|
211
|
+
};
|
|
212
|
+
readonly columnTrend: {
|
|
213
|
+
readonly key: "productOfferDashboard.fullView.topOffers.columnTrend";
|
|
214
|
+
readonly fallback: "Trend";
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
readonly defaults: {
|
|
219
|
+
readonly trendZero: {
|
|
220
|
+
readonly key: "productOfferDashboard.defaults.trendZero";
|
|
221
|
+
readonly fallback: "+0%";
|
|
222
|
+
};
|
|
223
|
+
readonly noData: {
|
|
224
|
+
readonly key: "productOfferDashboard.defaults.noData";
|
|
225
|
+
readonly fallback: "--";
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
export declare function getTranslation(entry: TranslationEntry): string;
|
|
230
|
+
export {};
|