@liiift-studio/sales-portal 1.3.4 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,23 +1,20 @@
1
1
  # @liiift-studio/sales-portal
2
2
 
3
- Centralized sales portal dashboard package for Liiift Studio foundary projects.
4
-
5
- ## Description
6
-
7
- This package provides a comprehensive sales dashboard for type foundries, featuring:
8
-
9
- - 📊 Period-over-period sales comparison
10
- - 📈 Interactive charts and data visualization
11
- - 🗂️ DataGrid tables with sorting, filtering, and CSV export
12
- - 📅 Date range selection for custom reports
13
- - 💰 Stripe reconciliation checks
14
- - 🎯 Top performers analysis (typefaces and designers)
15
- - 📋 Detailed typeface and license type breakdowns
16
- - 🔍 Summary cards with key metrics
17
-
18
- ## Liiift Add-on Features / Plugins
19
-
20
- The Liiift platform provides a modular plugin system. Each feature can be enabled or disabled per foundry via environment variables:
3
+ Centralized sales portal dashboard for Liiift Studio foundry projects.
4
+
5
+ ## Features
6
+
7
+ - Designer authentication via Sanity CMS
8
+ - Admin multi-designer view with sequential loading
9
+ - Monthly sales data from Stripe (invoices + payment intents)
10
+ - Interactive charts and data visualization (MUI X-Charts)
11
+ - DataGrid tables with sorting, filtering, and CSV export
12
+ - Date range selection for custom export reports
13
+ - Stripe balance reconciliation checks
14
+ - Top performers analysis (typefaces and designers)
15
+ - Typeface and license type breakdowns
16
+ - Summary cards with key metrics
17
+ - Login modal with two-column layout
21
18
 
22
19
  ## Installation
23
20
 
@@ -27,415 +24,146 @@ npm install @liiift-studio/sales-portal
27
24
 
28
25
  ## Prerequisites
29
26
 
30
- This package requires the following peer dependencies in your project:
27
+ Peer dependencies required in your project:
31
28
 
32
29
  ```json
33
30
  {
34
- "@mui/material": "^5.10.0",
35
- "@mui/x-data-grid": "^8.0.0",
36
- "@mui/x-date-pickers": "^7.0.0",
37
- "@mui/x-charts": "^7.0.0",
38
- "react": "^18.0.0",
39
- "react-dom": "^18.0.0",
40
- "next": "^14.0.0",
41
- "dayjs": "^1.11.0",
42
- "slugify": "^1.6.0"
31
+ "@mui/material": "^5.10.0",
32
+ "@mui/x-data-grid": "^8.0.0",
33
+ "@mui/x-date-pickers": "^7.0.0",
34
+ "@mui/x-charts": "^7.0.0",
35
+ "react": "^18.0.0",
36
+ "react-dom": "^18.0.0",
37
+ "next": "^14.0.0",
38
+ "dayjs": "^1.11.0",
39
+ "slugify": "^1.6.0"
43
40
  }
44
41
  ```
45
42
 
46
- ## Required Foundry Repository Structure
43
+ Note: Compatible with MUI v5 through v7 (uses Box/flexbox instead of Grid).
47
44
 
48
- Your foundry's Next.js application **must** have the following directory structure and wrapper files to use this package. The wrapper files are thin re-exports that allow Next.js API routes to work with the centralized package.
45
+ ## Quick Start
49
46
 
50
- ### Complete Directory Structure
47
+ ### 1. Create API route wrappers
51
48
 
52
49
  ```
53
- your-foundry-app/
54
- ├── .env.local # Environment variables
55
- ├── .npmrc # GitHub Packages authentication
56
- ├── package.json # Add @liiift/sales-portal dependency
57
- ├── pages/
58
- │ ├── _app.js # Wrap with MUI providers
59
- │ ├── sales-portal.js # Your sales dashboard page
60
- │ └── api/
61
- │ └── sales-portal/ # API wrapper directory
62
- │ ├── getDesignerInfo.js # ⚠️ REQUIRED
63
- │ ├── getDesigners.js # ⚠️ REQUIRED
64
- │ ├── getSales.js # ⚠️ REQUIRED
65
- │ ├── getSalesRange.js # ⚠️ REQUIRED
66
- │ ├── getPreviousSales.js # ⚠️ REQUIRED
67
- │ ├── getBalanceTransactions.js # ⚠️ REQUIRED
68
- │ ├── getAnalytics.js # ⚠️ REQUIRED
69
- │ └── utils/ # Utility wrappers
70
- │ ├── authMiddleware.js
71
- │ ├── dateUtils.js
72
- │ ├── feeCalculator.js
73
- │ ├── salesDataProcessing.js
74
- │ ├── salesDataProcessor.js
75
- │ ├── stripeFetcher.js
76
- │ └── processors/
77
- │ ├── invoiceProcessor.js
78
- │ └── paymentProcessor.js
79
- └── next.config.js # MUI transpile configuration
80
- ```
81
-
82
- ### Required Wrapper Files
83
-
84
- Create each of these files **exactly** as shown:
85
-
86
- #### API Route Wrappers (with default exports)
87
-
88
- **`pages/api/sales-portal/getDesignerInfo.js`**
89
- ```javascript
90
- export { default, config } from '@liiift-studio/sales-portal/api/getDesignerInfo';
50
+ pages/api/sales-portal/
51
+ getDesignerInfo.js
52
+ getDesigners.js
53
+ getSales.js
54
+ getBalanceTransactions.js
91
55
  ```
92
56
 
93
- **`pages/api/sales-portal/getDesigners.js`**
94
- ```javascript
95
- export { default, config } from '@liiift-studio/sales-portal/api/getDesigners';
96
- ```
57
+ Each file is a one-line re-export:
97
58
 
98
- **`pages/api/sales-portal/getSales.js`**
99
- ```javascript
59
+ ```js
60
+ // pages/api/sales-portal/getSales.js
100
61
  export { default, config } from '@liiift-studio/sales-portal/api/getSales';
101
62
  ```
102
63
 
103
- **`pages/api/sales-portal/getSalesRange.js`**
104
- ```javascript
105
- export { default, config } from '@liiift-studio/sales-portal/api/getSalesRange';
106
- ```
107
-
108
- **`pages/api/sales-portal/getPreviousSales.js`**
109
- ```javascript
110
- export { default, config } from '@liiift-studio/sales-portal/api/getPreviousSales';
111
- ```
112
-
113
- **`pages/api/sales-portal/getBalanceTransactions.js`**
114
- ```javascript
115
- export { default, config } from '@liiift-studio/sales-portal/api/getBalanceTransactions';
116
- ```
117
-
118
- **`pages/api/sales-portal/getAnalytics.js`**
119
- ```javascript
120
- export { default, config } from '@liiift-studio/sales-portal/api/getAnalytics';
121
- ```
122
-
123
- #### Utility Wrappers (with named exports)
64
+ ### 2. Create the page
124
65
 
125
- **`pages/api/sales-portal/utils/authMiddleware.js`**
126
- ```javascript
127
- export * from '@liiift-studio/sales-portal/api/utils/authMiddleware';
128
- ```
129
-
130
- **`pages/api/sales-portal/utils/dateUtils.js`**
131
- ```javascript
132
- export * from '@liiift-studio/sales-portal/api/utils/dateUtils';
133
- ```
134
-
135
- **`pages/api/sales-portal/utils/feeCalculator.js`**
136
- ```javascript
137
- export * from '@liiift-studio/sales-portal/api/utils/feeCalculator';
138
- ```
139
-
140
- **`pages/api/sales-portal/utils/salesDataProcessing.js`**
141
- ```javascript
142
- export * from '@liiift-studio/sales-portal/api/utils/salesDataProcessing';
143
- ```
144
-
145
- **`pages/api/sales-portal/utils/salesDataProcessor.js`**
146
- ```javascript
147
- export * from '@liiift-studio/sales-portal/api/utils/salesDataProcessor';
148
- ```
149
-
150
- **`pages/api/sales-portal/utils/stripeFetcher.js`**
151
- ```javascript
152
- export * from '@liiift-studio/sales-portal/api/utils/stripeFetcher';
153
- ```
154
-
155
- **`pages/api/sales-portal/utils/processors/invoiceProcessor.js`**
156
- ```javascript
157
- export * from '@liiift-studio/sales-portal/api/utils/processors/invoiceProcessor';
158
- ```
159
-
160
- **`pages/api/sales-portal/utils/processors/paymentProcessor.js`**
161
- ```javascript
162
- export * from '@liiift-studio/sales-portal/api/utils/processors/paymentProcessor';
66
+ ```jsx
67
+ // pages/sales-portal.js
68
+ import { SalesPortalPage } from '@liiift-studio/sales-portal';
69
+
70
+ export default function SalesPortal() {
71
+ return (
72
+ <SalesPortalPage
73
+ texts={{
74
+ title: 'Sales Portal',
75
+ dashboardTitle: 'Monthly Sales',
76
+ dashboardSubtitle: 'by designer'
77
+ }}
78
+ />
79
+ );
80
+ }
163
81
  ```
164
82
 
165
- ### Quick Setup Script
83
+ ### 3. Configure Next.js
166
84
 
167
- To quickly create all wrapper files, you can run this bash script from your foundry app root:
168
-
169
- ```bash
170
- #!/bin/bash
171
- # create-sales-portal-wrappers.sh
172
-
173
- # Create directory structure
174
- mkdir -p pages/api/sales-portal/utils/processors
175
-
176
- # API route wrappers
177
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getDesignerInfo';" > pages/api/sales-portal/getDesignerInfo.js
178
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getDesigners';" > pages/api/sales-portal/getDesigners.js
179
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getSales';" > pages/api/sales-portal/getSales.js
180
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getSalesRange';" > pages/api/sales-portal/getSalesRange.js
181
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getPreviousSales';" > pages/api/sales-portal/getPreviousSales.js
182
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getBalanceTransactions';" > pages/api/sales-portal/getBalanceTransactions.js
183
- echo "export { default, config } from '@liiift-studio/sales-portal/api/getAnalytics';" > pages/api/sales-portal/getAnalytics.js
184
-
185
- # Utility wrappers
186
- echo "export * from '@liiift-studio/sales-portal/api/utils/authMiddleware';" > pages/api/sales-portal/utils/authMiddleware.js
187
- echo "export * from '@liiift-studio/sales-portal/api/utils/dateUtils';" > pages/api/sales-portal/utils/dateUtils.js
188
- echo "export * from '@liiift-studio/sales-portal/api/utils/feeCalculator';" > pages/api/sales-portal/utils/feeCalculator.js
189
- echo "export * from '@liiift-studio/sales-portal/api/utils/salesDataProcessing';" > pages/api/sales-portal/utils/salesDataProcessing.js
190
- echo "export * from '@liiift-studio/sales-portal/api/utils/salesDataProcessor';" > pages/api/sales-portal/utils/salesDataProcessor.js
191
- echo "export * from '@liiift-studio/sales-portal/api/utils/stripeFetcher';" > pages/api/sales-portal/utils/stripeFetcher.js
192
- echo "export * from '@liiift-studio/sales-portal/api/utils/processors/invoiceProcessor';" > pages/api/sales-portal/utils/processors/invoiceProcessor.js
193
- echo "export * from '@liiift-studio/sales-portal/api/utils/processors/paymentProcessor';" > pages/api/sales-portal/utils/processors/paymentProcessor.js
194
-
195
- echo "✅ All sales-portal wrapper files created!"
196
- ```
197
-
198
- Make the script executable and run it:
199
- ```bash
200
- chmod +x create-sales-portal-wrappers.sh
201
- ./create-sales-portal-wrappers.sh
85
+ ```js
86
+ // next.config.js
87
+ const nextConfig = {
88
+ transpilePackages: ['@mui/x-charts', '@liiift-studio/sales-portal'],
89
+ };
202
90
  ```
203
91
 
204
- ### Environment Variables
205
-
206
- Create `.env.local` in your foundry app root with these required variables:
92
+ ### 4. Set environment variables
207
93
 
208
94
  ```bash
209
- # Sanity CMS Configuration
95
+ # .env.local
210
96
  SANITY_STUDIO_PROJECT_ID=your_project_id
211
97
  SANITY_STUDIO_DATASET=production
212
- SANITY_STUDIO_API_VERSION=2022-04-01
213
- SANITY_STUDIO_TOKEN=your_sanity_token_here
214
-
215
- # Stripe Configuration
216
- STRIPE_SECRET_KEY=your_stripe_secret_key_here
217
-
218
- # ============================================
219
- # LIIIFT ADD-ON FEATURES / PLUGINS
220
- # ============================================
221
- # Each feature can be enabled/disabled independently per foundry
222
-
223
- # Sales Portal - Designer sales dashboard with analytics
98
+ SANITY_STUDIO_TOKEN=your_sanity_token
99
+ STRIPE_SECRET_KEY=your_stripe_secret_key
224
100
  SALES_PORTAL_ENABLED=true
225
-
226
- # Custom Documents - Branded invoices, receipts, license PDFs
227
- CUSTOM_DOCUMENTS_ENABLED=true
228
-
229
- # Meta Fingerprinting - On-sale font metadata injection
230
- META_FINGERPRINTING_ENABLED=true
231
-
232
- # Multi-Script License Selection - Language/script-based licensing
233
- MULTI_SCRIPT_LICENSE_ENABLED=true
234
-
235
- # Beta/Pre-release Section - Early access font releases
236
- BETA_PRERELEASE_ENABLED=true
237
-
238
- # Bulk Font Uploader - Batch font file uploads to CMS
239
- BULK_FONT_UPLOADER_ENABLED=true
240
-
241
- # Smart Media Pipeline - Automated image/video optimization
242
- MEDIA_PIPELINE_ENABLED=true
243
-
244
- # Optional: NextAuth (if using)
245
- NEXTAUTH_URL=https://your-domain.com
246
- NEXTAUTH_SECRET=your_nextauth_secret
247
- ```
248
-
249
- #### Feature Toggle
250
-
251
- The `SALES_PORTAL_ENABLED` environment variable controls whether the sales portal is accessible:
252
-
253
- - **`true`** (default) - Sales portal functions normally
254
- - **`false`** - All API endpoints return a 503 response with `{ success: false, message: 'Sales portal is currently disabled', disabled: true }`
255
-
256
- This is useful for:
257
- - Temporarily disabling the sales portal during maintenance
258
- - Enabling/disabling the feature per foundry site
259
- - Quick rollback without code changes
260
-
261
- ### NPM Authentication
262
-
263
- This package is published to npmjs.org under the `@liiift-studio` organization. No additional registry configuration is required - npm will automatically fetch from the public registry.
264
-
265
- For private installations requiring authentication, configure your npm credentials:
266
- ```bash
267
- npm login
268
101
  ```
269
102
 
270
- ### Integration Checklist
271
-
272
- Use this checklist to verify your setup:
103
+ ## API Endpoints
273
104
 
274
- - [ ] Package installed: `@liiift-studio/sales-portal` in package.json
275
- - [ ] ✅ All 7 API route wrappers created in `pages/api/sales-portal/`
276
- - [ ] All 8 utility wrappers created in `pages/api/sales-portal/utils/`
277
- - [ ] `.env.local` file created with all required environment variables
278
- - [ ] `next.config.js` includes MUI transpilePackages
279
- - [ ] `pages/_app.js` wrapped with MUI ThemeProvider and LocalizationProvider
280
- - [ ] ✅ `pages/sales-portal.js` created with Sales component
281
- - [ ] ✅ Development server starts without errors
282
- - [ ] ✅ Navigate to `/sales-portal` and see login form
283
- - [ ] ✅ Login with designer credentials succeeds
284
- - [ ] ✅ Sales data displays correctly
285
- - [ ] ✅ CSV export works
286
- - [ ] ✅ PDF print works
105
+ | Endpoint | Method | Purpose |
106
+ |----------|--------|---------|
107
+ | `getDesignerInfo` | POST | Authenticate designer, return account data |
108
+ | `getDesigners` | GET | List all designers (admin) |
109
+ | `getSales` | POST | Fetch sales data for a month or date range |
110
+ | `getBalanceTransactions` | POST | Fetch Stripe balance transactions for reconciliation |
287
111
 
288
- ## Setup
289
-
290
- ### 1. Configure Next.js
291
-
292
- Add MUI X packages to transpilation in `next.config.js`:
112
+ ## Component Exports
293
113
 
294
114
  ```js
295
- const nextConfig = {
296
- transpilePackages: ['@mui/x-data-grid', '@mui/x-date-pickers', '@mui/x-charts'],
297
- // ... rest of your config
298
- };
299
- ```
300
-
301
- ### 2. Add MUI Providers
302
-
303
- Wrap your app with required providers in `pages/_app.js`:
304
-
305
- ```jsx
306
- import { ThemeProvider } from '@mui/material/styles';
307
- import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
308
- import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
309
- import { salesTheme } from '@liiift-studio/sales-portal';
310
-
311
- function MyApp({ Component, pageProps }) {
312
- return (
313
- <ThemeProvider theme={salesTheme}>
314
- <LocalizationProvider dateAdapter={AdapterDayjs}>
315
- <Component {...pageProps} />
316
- </LocalizationProvider>
317
- </ThemeProvider>
318
- );
319
- }
320
- ```
321
-
322
- ### 3. Set up API Routes
323
-
324
- Copy the API handlers from the package to your `pages/api/sales-portal/` directory:
325
-
326
- ```bash
327
- cp -R node_modules/@liiift-studio/sales-portal/api/* pages/api/sales-portal/
328
- ```
329
-
330
- Or create wrapper handlers:
331
-
332
- ```js
333
- // pages/api/sales-portal/getSales.js
334
- import handler from '@liiift-studio/sales-portal/api/getSales';
335
- export default handler;
115
+ import {
116
+ SalesPortalPage, // Full page with login modal + dashboard
117
+ LoginForm, // Login modal component
118
+ Sales, // Individual designer sales dashboard
119
+ SalesTable, // Sales data table with CSV export
120
+ DateRangeSalesTable, // Custom date range export table
121
+ SalesChart, // Revenue trend charts
122
+ SummaryCards, // Key metrics cards
123
+ TopPerformers, // Top typefaces/designers
124
+ TypefaceList, // Typeface breakdown
125
+ LicenseTypeList, // License type analysis
126
+ PeriodComparison, // Period comparison charts
127
+ salesTheme, // MUI theme
128
+ } from '@liiift-studio/sales-portal';
336
129
  ```
337
130
 
338
- ## Usage
339
-
340
- ### Basic Sales Dashboard
341
-
342
- ```jsx
343
- import { Sales } from '@liiift-studio/sales-portal';
131
+ ## Architecture
344
132
 
345
- export default function SalesPortalPage() {
346
- return <Sales designer={designerData} admin={isAdmin} />;
347
- }
348
133
  ```
349
-
350
- ### Date Range Sales Table
351
-
352
- ```jsx
353
- import { DateRangeSalesTable } from '@liiift-studio/sales-portal';
354
-
355
- export default function ExportsPage() {
356
- return (
357
- <DateRangeSalesTable
358
- designer={designerData}
359
- admin={isAdmin}
360
- loading={false}
361
- updateLoadingState={(key, state) => console.log(key, state)}
362
- />
363
- );
364
- }
134
+ @liiift-studio/sales-portal
135
+ api/
136
+ utils/
137
+ clients.js # Shared Sanity + Stripe clients
138
+ apiResponse.js # Standardized error/success responses
139
+ authMiddleware.js # Request authentication
140
+ dateUtils.js # UTC date range utilities
141
+ salesDataProcessor.js # Core sales data pipeline
142
+ stripeFetcher.js # Stripe API pagination
143
+ feeCalculator.js # Fee distribution + rounding
144
+ processors/
145
+ invoiceProcessor.js # Stripe invoice processing
146
+ paymentProcessor.js # Stripe payment intent processing
147
+ components/ # React components (Box/flexbox, no MUI Grid)
148
+ styles/ # SCSS + MUI theme
149
+ hooks/ # Custom React hooks
150
+ utils/ # Client-side utilities
365
151
  ```
366
152
 
367
- ### Individual Components
153
+ ## Currently deployed on
368
154
 
369
- ```jsx
370
- import {
371
- SalesTable,
372
- SalesChart,
373
- SummaryCards,
374
- TopPerformers
375
- } from '@liiift-studio/sales-portal';
376
-
377
- // Use components individually as needed
378
- ```
379
-
380
- ## Exports
381
-
382
- ### Components
383
- - `Sales` - Main dashboard component
384
- - `SalesTable` - Table with sales data
385
- - `DateRangeSalesTable` - Table for custom date ranges
386
- - `SalesChart` - Charts for visualizing sales trends
387
- - `SummaryCards` - Key metrics summary cards
388
- - `TopPerformers` - Top performing typefaces/designers
389
- - `TypefaceList` - Detailed typeface breakdown
390
- - `LicenseTypeList` - License type analysis
391
- - `PeriodComparison` - Period-over-period comparison
392
- - `DebugValues` - Debug information display
393
- - `TableRowCells`, `getCellValue` - Table cell rendering utilities
394
- - `COLUMNS` - Table column definitions
395
-
396
- ### Hooks
397
- - `useSalesDateQuery` - Date query management hook
398
-
399
- ### Utilities
400
- - Currency formatting utilities
401
- - Sales data processing functions
402
-
403
- ### Styles
404
- - `salesTheme` - MUI theme configuration
405
-
406
- ### API Handlers (import separately)
407
- ```js
408
- import getDesignerInfo from '@liiift-studio/sales-portal/api/getDesignerInfo';
409
- import getDesigners from '@liiift-studio/sales-portal/api/getDesigners';
410
- import getSales from '@liiift-studio/sales-portal/api/getSales';
411
- import getPreviousSales from '@liiift-studio/sales-portal/api/getPreviousSales';
412
- import getSalesRange from '@liiift-studio/sales-portal/api/getSalesRange';
413
- import getBalanceTransactions from '@liiift-studio/sales-portal/api/getBalanceTransactions';
414
- import getAnalytics from '@liiift-studio/sales-portal/api/getAnalytics';
415
- ```
155
+ - [The Designers Foundry](https://thedesignersfoundry.com) (staging)
156
+ - [Darden Studio](https://dardenstudio.com)
157
+ - [Positype](https://positype.com)
416
158
 
417
159
  ## Development
418
160
 
419
- To make changes to this package:
420
-
421
- 1. Clone the repository
422
- 2. Make your changes
423
- 3. Update the version: `npm version patch|minor|major`
424
- 4. Commit and push
425
- 5. GitHub Actions will automatically publish to npmjs.org
426
-
427
- ## Updating in Projects
428
-
429
- To get the latest version in your project:
430
-
431
- ```bash
432
- npm update @liiift-studio/sales-portal
433
- ```
161
+ 1. Make changes in the sales-portal repo
162
+ 2. Bump version in package.json
163
+ 3. Commit and push to master
164
+ 4. Publish: `npm publish --access public`
165
+ 5. Foundry sites pick up new version on next deploy (uses `^` semver)
434
166
 
435
167
  ## License
436
168
 
437
169
  UNLICENSED
438
-
439
- ## Support
440
-
441
- For issues or questions, contact the development team or open an issue in the repository.