create-bluecopa-react-app 1.0.41 → 1.0.42
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 +7 -5
- package/package.json +1 -1
- package/templates/latest/.claude/settings.local.json +56 -0
- package/templates/latest/.env.example +8 -0
- package/templates/latest/Agent.md +598 -775
- package/templates/latest/CLAUDE.md +759 -0
- package/templates/latest/README.md +11 -2
- package/templates/latest/app/app.css +292 -85
- package/templates/latest/app/app.tsx +48 -39
- package/templates/latest/app/components/bluecopa-logo.tsx +20 -0
- package/templates/latest/app/components/charts/bar-chart.tsx +132 -0
- package/templates/latest/app/components/charts/base-chart.tsx +149 -0
- package/templates/latest/app/components/charts/chart-provider.tsx +71 -0
- package/templates/latest/app/components/charts/chart-theme.ts +262 -0
- package/templates/latest/app/components/charts/chart-utils.ts +142 -0
- package/templates/latest/app/components/charts/donut-chart.tsx +110 -0
- package/templates/latest/app/components/charts/index.ts +5 -0
- package/templates/latest/app/components/layouts/app-layout.tsx +22 -0
- package/templates/latest/app/components/layouts/app-sidebar.tsx +88 -0
- package/templates/latest/app/components/layouts/nav-main.tsx +50 -0
- package/templates/latest/app/components/layouts/nav-user.tsx +38 -0
- package/templates/latest/app/components/layouts/site-header.tsx +93 -0
- package/templates/latest/app/components/loading-screen.tsx +41 -0
- package/templates/latest/app/components/ui/ag-grid-table.tsx +79 -0
- package/templates/latest/app/components/ui/button.tsx +23 -23
- package/templates/latest/app/components/ui/card.tsx +20 -20
- package/templates/latest/app/components/ui/dropdown-menu.tsx +54 -49
- package/templates/latest/app/components/ui/input.tsx +8 -8
- package/templates/latest/app/components/ui/label.tsx +8 -8
- package/templates/latest/app/components/ui/separator.tsx +7 -7
- package/templates/latest/app/components/ui/sheet.tsx +43 -32
- package/templates/latest/app/components/ui/sidebar.tsx +240 -235
- package/templates/latest/app/components/ui/skeleton.tsx +4 -4
- package/templates/latest/app/components/ui/sonner.tsx +6 -9
- package/templates/latest/app/components/ui/tabs.tsx +15 -15
- package/templates/latest/app/components/ui/tooltip.tsx +18 -12
- package/templates/latest/app/constants/index.ts +31 -0
- package/templates/latest/app/contexts/app-context.tsx +201 -0
- package/templates/latest/app/hooks/use-mobile.ts +13 -12
- package/templates/latest/app/main.tsx +1 -1
- package/templates/latest/app/pages/dashboard.tsx +246 -0
- package/templates/latest/app/pages/payments.tsx +182 -0
- package/templates/latest/app/pages/settings.tsx +128 -0
- package/templates/latest/app/routes/index.tsx +19 -0
- package/templates/latest/app/single-spa.tsx +69 -186
- package/templates/latest/app/types/index.ts +37 -0
- package/templates/latest/app/utils/ag-grid-datasource.ts +63 -0
- package/templates/latest/app/utils/ag-grid-license.ts +12 -0
- package/templates/latest/app/utils/ag-grid-theme.ts +9 -0
- package/templates/latest/app/utils/component-style.ts +7 -0
- package/templates/latest/app/utils/style-drivers.ts +24 -0
- package/templates/latest/app/utils/utils.ts +10 -0
- package/templates/latest/components.json +3 -3
- package/templates/latest/index.html +30 -2
- package/templates/latest/package-lock.json +15 -401
- package/templates/latest/package.json +8 -18
- package/templates/latest/preview/index.html +125 -285
- package/templates/latest/public/favicon.svg +1 -0
- package/templates/latest/vite.config.ts +2 -8
- package/templates/latest/app/components/app-sidebar.tsx +0 -182
- package/templates/latest/app/components/chart-area-interactive.tsx +0 -290
- package/templates/latest/app/components/data-table.tsx +0 -807
- package/templates/latest/app/components/nav-documents.tsx +0 -92
- package/templates/latest/app/components/nav-main.tsx +0 -40
- package/templates/latest/app/components/nav-secondary.tsx +0 -42
- package/templates/latest/app/components/nav-user.tsx +0 -111
- package/templates/latest/app/components/section-cards.tsx +0 -102
- package/templates/latest/app/components/site-header.tsx +0 -28
- package/templates/latest/app/components/ui/avatar.tsx +0 -53
- package/templates/latest/app/components/ui/badge.tsx +0 -46
- package/templates/latest/app/components/ui/breadcrumb.tsx +0 -109
- package/templates/latest/app/components/ui/chart.tsx +0 -352
- package/templates/latest/app/components/ui/checkbox.tsx +0 -30
- package/templates/latest/app/components/ui/drawer.tsx +0 -139
- package/templates/latest/app/components/ui/select.tsx +0 -183
- package/templates/latest/app/components/ui/table.tsx +0 -117
- package/templates/latest/app/components/ui/toggle-group.tsx +0 -73
- package/templates/latest/app/components/ui/toggle.tsx +0 -47
- package/templates/latest/app/data/data.json +0 -614
- package/templates/latest/app/data/mock-payments.json +0 -122
- package/templates/latest/app/data/mock-transactions.json +0 -128
- package/templates/latest/app/hooks/use-bluecopa-user.ts +0 -37
- package/templates/latest/app/lib/utils.ts +0 -6
- package/templates/latest/app/routes/apitest.tsx +0 -2118
- package/templates/latest/app/routes/comments.tsx +0 -588
- package/templates/latest/app/routes/dashboard.tsx +0 -36
- package/templates/latest/app/routes/payments.tsx +0 -342
- package/templates/latest/app/routes/statements.tsx +0 -493
- package/templates/latest/app/routes/websocket.tsx +0 -450
- package/templates/latest/app/routes.tsx +0 -22
- package/templates/latest/dist/assets/__federation_expose_App-D-lv9y21.js +0 -161
- package/templates/latest/dist/assets/__federation_fn_import-CzfA7kmP.js +0 -438
- package/templates/latest/dist/assets/__federation_shared_react-Bp6HVBS4.js +0 -16
- package/templates/latest/dist/assets/__federation_shared_react-dom-BCcRGiYp.js +0 -17
- package/templates/latest/dist/assets/client-Dms8K6Dw.js +0 -78879
- package/templates/latest/dist/assets/index-BrhXrqF7.js +0 -60
- package/templates/latest/dist/assets/index-BzNimew1.js +0 -69
- package/templates/latest/dist/assets/index-DMFtQdNS.js +0 -412
- package/templates/latest/dist/assets/remoteEntry.css +0 -3996
- package/templates/latest/dist/assets/remoteEntry.js +0 -88
- package/templates/latest/dist/favicon.ico +0 -0
- package/templates/latest/dist/index.html +0 -19
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
A modern, production-ready template for building full-stack React applications using React Router v7 and shadcn/ui components.
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
## Features
|
|
7
6
|
|
|
8
7
|
- 🚀 **React Router v7** - Latest React Router with server-side rendering
|
|
@@ -59,11 +58,13 @@ Your application will be available at `http://localhost:8080`.
|
|
|
59
58
|
This template includes a comprehensive set of shadcn/ui components:
|
|
60
59
|
|
|
61
60
|
### Layout Components
|
|
61
|
+
|
|
62
62
|
- **Sidebar** - Collapsible navigation sidebar with mobile support
|
|
63
63
|
- **Sheet** - Slide-out panels for mobile navigation
|
|
64
64
|
- **Drawer** - Bottom drawer for mobile interactions
|
|
65
65
|
|
|
66
66
|
### Form Components
|
|
67
|
+
|
|
67
68
|
- **Button** - Multiple variants and sizes
|
|
68
69
|
- **Input** - Text input with validation states
|
|
69
70
|
- **Select** - Dropdown selection with search
|
|
@@ -71,6 +72,7 @@ This template includes a comprehensive set of shadcn/ui components:
|
|
|
71
72
|
- **Label** - Accessible form labels
|
|
72
73
|
|
|
73
74
|
### Data Display
|
|
75
|
+
|
|
74
76
|
- **Table** - Sortable, filterable data tables with TanStack Table
|
|
75
77
|
- **Card** - Content containers with header, content, and footer
|
|
76
78
|
- **Badge** - Status indicators and labels
|
|
@@ -78,16 +80,19 @@ This template includes a comprehensive set of shadcn/ui components:
|
|
|
78
80
|
- **Skeleton** - Loading placeholders
|
|
79
81
|
|
|
80
82
|
### Navigation
|
|
83
|
+
|
|
81
84
|
- **Tabs** - Tabbed content organization
|
|
82
85
|
- **Breadcrumb** - Navigation breadcrumbs
|
|
83
86
|
- **Dropdown Menu** - Context menus and actions
|
|
84
87
|
- **Tooltip** - Hover information
|
|
85
88
|
|
|
86
89
|
### Feedback
|
|
90
|
+
|
|
87
91
|
- **Sonner** - Toast notifications
|
|
88
92
|
- **Separator** - Visual content dividers
|
|
89
93
|
|
|
90
94
|
### Charts
|
|
95
|
+
|
|
91
96
|
- **Interactive Charts** - Recharts integration with hover states
|
|
92
97
|
- **Area Charts** - Time series data visualization
|
|
93
98
|
|
|
@@ -105,9 +110,11 @@ VITE_BLUECOPA_API_TOKEN=your_base64_encoded_token_here
|
|
|
105
110
|
```
|
|
106
111
|
|
|
107
112
|
**Note:** `VITE_BLUECOPA_API_TOKEN` should be a base64-encoded JSON string containing an `accessToken` field, for example:
|
|
113
|
+
|
|
108
114
|
```json
|
|
109
|
-
{"accessToken": "your_access_token_here"}
|
|
115
|
+
{ "accessToken": "your_access_token_here" }
|
|
110
116
|
```
|
|
117
|
+
|
|
111
118
|
encoded as base64.
|
|
112
119
|
|
|
113
120
|
If the API errors out or is not configured, the application will show "Set Environment" as the user name with email "setenv@email.com" as a fallback.
|
|
@@ -124,6 +131,7 @@ This template includes a comprehensive example of using Bluecopa statement hooks
|
|
|
124
131
|
- **useCreateStatementRun** - Creating new statement runs with mutations
|
|
125
132
|
|
|
126
133
|
The example includes two pre-configured statement IDs:
|
|
134
|
+
|
|
127
135
|
- Example 1: `MDYK9CU8NR1S41AFAOEX` (uses default view)
|
|
128
136
|
- Example 2: `MGIZ7GD08NQJ71SK8RA7` with View ID `MGJ1ZF0JN53B0V0YH10Z`
|
|
129
137
|
|
|
@@ -193,6 +201,7 @@ npx shadcn-ui@latest add toast
|
|
|
193
201
|
## Styling
|
|
194
202
|
|
|
195
203
|
This template comes with [Tailwind CSS v4](https://tailwindcss.com/) configured with:
|
|
204
|
+
|
|
196
205
|
- CSS variables for theming
|
|
197
206
|
- Dark mode support with next-themes
|
|
198
207
|
- shadcn/ui design system
|
|
@@ -1,26 +1,82 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*
|
|
2
|
+
* MFE CSS Strategy:
|
|
3
|
+
* - NO global preflight — we skip Tailwind's base reset to avoid leaking into the host app
|
|
4
|
+
* - Scoped reset under .mfe-root — only affects the MFE subtree
|
|
5
|
+
* - copa: prefix on all utilities — prevents class name collisions
|
|
6
|
+
* - Custom utilities scoped under .mfe-root — prevents naming collisions
|
|
7
|
+
*/
|
|
3
8
|
|
|
4
|
-
|
|
9
|
+
/* Import Tailwind WITHOUT preflight — preflight resets *, html, body globally which leaks into the host */
|
|
10
|
+
/* @import "tailwindcss/preflight" — INTENTIONALLY SKIPPED (global resets leak into host app) */
|
|
11
|
+
@import "tailwindcss/theme" prefix(copa);
|
|
12
|
+
@import "tailwindcss/utilities" prefix(copa);
|
|
13
|
+
@import "tw-animate-css";
|
|
5
14
|
|
|
15
|
+
/* ===== BUILD-TIME THEME (resolved at compile) ===== */
|
|
6
16
|
@theme {
|
|
7
|
-
|
|
8
|
-
|
|
17
|
+
/* Breakpoints (required — Tailwind v4 prefix does not auto-include defaults) */
|
|
18
|
+
--breakpoint-sm: 40rem;
|
|
19
|
+
--breakpoint-md: 48rem;
|
|
20
|
+
--breakpoint-lg: 64rem;
|
|
21
|
+
--breakpoint-xl: 80rem;
|
|
22
|
+
--breakpoint-2xl: 96rem;
|
|
9
23
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
/* Font family */
|
|
25
|
+
--font-sans: "Satoshi", sans-serif;
|
|
26
|
+
--font-mono: "Satoshi", sans-serif;
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
/* Fluid type scale (from Dream Light _typography.css — exact values) */
|
|
29
|
+
--text-xs: 0.702rem;
|
|
30
|
+
--text-xs--line-height: 1.053rem;
|
|
31
|
+
--text-sm: 0.835rem;
|
|
32
|
+
--text-sm--line-height: 1.258rem;
|
|
33
|
+
--text-md: 1.004rem;
|
|
34
|
+
--text-md--line-height: 1.513rem;
|
|
35
|
+
--text-lg: 1.21rem;
|
|
36
|
+
--text-lg--line-height: 1.815rem;
|
|
37
|
+
--text-xl: 1.452rem;
|
|
38
|
+
--text-xl--line-height: 2.190rem;
|
|
39
|
+
--text-2xl: 1.742rem;
|
|
40
|
+
--text-2xl--line-height: 2.626rem;
|
|
41
|
+
--text-3xl: 2.093rem;
|
|
42
|
+
--text-3xl--line-height: 3.146rem;
|
|
43
|
+
--text-4xl: 2.505rem;
|
|
44
|
+
--text-4xl--line-height: 3.763rem;
|
|
45
|
+
--text-5xl: 3.013rem;
|
|
46
|
+
--text-5xl--line-height: 4.513rem;
|
|
47
|
+
|
|
48
|
+
/* Heading scale */
|
|
49
|
+
--text-h1: 3rem;
|
|
50
|
+
--text-h1--line-height: 4.5rem;
|
|
51
|
+
--text-h2: 2.25rem;
|
|
52
|
+
--text-h2--line-height: 3.375rem;
|
|
53
|
+
--text-h3: 1.875rem;
|
|
54
|
+
--text-h3--line-height: 2.8125rem;
|
|
55
|
+
--text-h4: 1.5rem;
|
|
56
|
+
--text-h4--line-height: 2.25rem;
|
|
57
|
+
--text-h5: 1.25rem;
|
|
58
|
+
--text-h5--line-height: 1.875rem;
|
|
59
|
+
--text-h6: 1rem;
|
|
60
|
+
--text-h6--line-height: 1.5rem;
|
|
61
|
+
--text-body: 0.875rem;
|
|
62
|
+
--text-body--line-height: 1.2rem;
|
|
63
|
+
--text-caption: 0.75rem;
|
|
64
|
+
--text-caption--line-height: 0.95rem;
|
|
65
|
+
|
|
66
|
+
/* Radius (from Dream Light _spacing.css) */
|
|
67
|
+
--card-radius: 1.25rem;
|
|
68
|
+
--rounded-input: 12px;
|
|
17
69
|
}
|
|
18
70
|
|
|
71
|
+
/* ===== RUNTIME THEME (CSS vars bound at runtime) ===== */
|
|
19
72
|
@theme inline {
|
|
73
|
+
/* Radius (computed from --radius in .mfe-root) */
|
|
20
74
|
--radius-sm: calc(var(--radius) - 4px);
|
|
21
75
|
--radius-md: calc(var(--radius) - 2px);
|
|
22
76
|
--radius-lg: var(--radius);
|
|
23
77
|
--radius-xl: calc(var(--radius) + 4px);
|
|
78
|
+
|
|
79
|
+
/* Colors */
|
|
24
80
|
--color-background: var(--background);
|
|
25
81
|
--color-foreground: var(--foreground);
|
|
26
82
|
--color-card: var(--card);
|
|
@@ -39,11 +95,8 @@ body {
|
|
|
39
95
|
--color-border: var(--border);
|
|
40
96
|
--color-input: var(--input);
|
|
41
97
|
--color-ring: var(--ring);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
--color-chart-3: var(--chart-3);
|
|
45
|
-
--color-chart-4: var(--chart-4);
|
|
46
|
-
--color-chart-5: var(--chart-5);
|
|
98
|
+
|
|
99
|
+
/* Sidebar */
|
|
47
100
|
--color-sidebar: var(--sidebar);
|
|
48
101
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
49
102
|
--color-sidebar-primary: var(--sidebar-primary);
|
|
@@ -54,80 +107,234 @@ body {
|
|
|
54
107
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
55
108
|
}
|
|
56
109
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
--
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
--
|
|
64
|
-
--
|
|
65
|
-
--
|
|
66
|
-
--
|
|
67
|
-
--
|
|
68
|
-
--
|
|
69
|
-
--
|
|
70
|
-
--
|
|
71
|
-
--
|
|
72
|
-
--
|
|
110
|
+
/* ===== MFE-SCOPED VARIABLES (light theme-modern from Dream Light _colors.css) ===== */
|
|
111
|
+
.mfe-root {
|
|
112
|
+
/* Radius (Dream Light _spacing.css) */
|
|
113
|
+
--radius: 1rem;
|
|
114
|
+
|
|
115
|
+
/* Colors (exact values from Dream Light _colors.css) */
|
|
116
|
+
--background: oklch(0.975 0.005 280);
|
|
117
|
+
--foreground: oklch(0.145 0 0);
|
|
118
|
+
--card: oklch(0.995 0.003 280 / 0.85);
|
|
119
|
+
--card-foreground: oklch(0.145 0 0);
|
|
120
|
+
--popover: oklch(0.995 0.003 280);
|
|
121
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
122
|
+
--primary: #3548ff;
|
|
123
|
+
--primary-foreground: oklch(100% 0 0);
|
|
124
|
+
--primary-lighter: #ebf4ff;
|
|
125
|
+
--secondary: oklch(0.97 0.003 280);
|
|
126
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
127
|
+
--muted: oklch(0.97 0.003 280);
|
|
128
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
129
|
+
--accent: oklch(0.97 0.003 280);
|
|
130
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
73
131
|
--destructive: oklch(0.577 0.245 27.325);
|
|
74
|
-
--border: oklch(0.92 0.
|
|
75
|
-
--input: oklch(0.92 0.
|
|
76
|
-
--ring: oklch(0.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
--
|
|
80
|
-
--
|
|
81
|
-
--
|
|
82
|
-
--sidebar: oklch(0.985 0 0);
|
|
83
|
-
--sidebar-
|
|
84
|
-
--sidebar-
|
|
85
|
-
--sidebar-
|
|
86
|
-
--sidebar-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
--
|
|
90
|
-
|
|
132
|
+
--border: oklch(0.92 0.005 280);
|
|
133
|
+
--input: oklch(0.92 0.005 280);
|
|
134
|
+
--ring: oklch(0.25 0.08 9);
|
|
135
|
+
|
|
136
|
+
/* Sidebar (Dream Light — white panel, subtle border) */
|
|
137
|
+
--sidebar: oklch(1 0 0);
|
|
138
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
139
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
140
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
141
|
+
--sidebar-accent: oklch(0.96 0.003 280);
|
|
142
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
143
|
+
--sidebar-border: oklch(0.92 0.004 280);
|
|
144
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
145
|
+
|
|
146
|
+
/* Semantic status colors */
|
|
147
|
+
--status-success: oklch(0.72 0.19 142);
|
|
148
|
+
--status-success-bg: oklch(0.95 0.05 142);
|
|
149
|
+
--status-success-border: oklch(0.80 0.12 142);
|
|
150
|
+
--status-warning: oklch(0.80 0.18 85);
|
|
151
|
+
--status-warning-bg: oklch(0.96 0.06 85);
|
|
152
|
+
--status-warning-border: oklch(0.85 0.12 85);
|
|
153
|
+
--status-error: oklch(0.63 0.24 25);
|
|
154
|
+
--status-error-bg: oklch(0.95 0.04 25);
|
|
155
|
+
--status-error-border: oklch(0.75 0.15 25);
|
|
156
|
+
--status-info: oklch(0.62 0.19 250);
|
|
157
|
+
--status-info-bg: oklch(0.95 0.04 250);
|
|
158
|
+
--status-info-border: oklch(0.75 0.12 250);
|
|
91
159
|
|
|
92
|
-
|
|
93
|
-
--
|
|
94
|
-
--
|
|
95
|
-
--
|
|
96
|
-
--
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
--
|
|
100
|
-
--
|
|
101
|
-
--
|
|
102
|
-
--
|
|
103
|
-
--
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
--
|
|
107
|
-
--
|
|
108
|
-
--
|
|
109
|
-
--
|
|
110
|
-
--
|
|
111
|
-
--
|
|
112
|
-
--chart-2: oklch(0.696 0.17 162.48);
|
|
113
|
-
--chart-3: oklch(0.769 0.188 70.08);
|
|
114
|
-
--chart-4: oklch(0.627 0.265 303.9);
|
|
115
|
-
--chart-5: oklch(0.645 0.246 16.439);
|
|
116
|
-
--sidebar: oklch(0.21 0.006 285.885);
|
|
117
|
-
--sidebar-foreground: oklch(0.985 0 0);
|
|
118
|
-
--sidebar-primary: oklch(0.546 0.245 262.881);
|
|
119
|
-
--sidebar-primary-foreground: oklch(0.379 0.146 265.522);
|
|
120
|
-
--sidebar-accent: oklch(0.274 0.006 286.033);
|
|
121
|
-
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
122
|
-
--sidebar-border: oklch(1 0 0 / 10%);
|
|
123
|
-
--sidebar-ring: oklch(0.488 0.243 264.376);
|
|
160
|
+
/* Spacing (theme-modern preset) */
|
|
161
|
+
--spacing-sm: 0.5rem;
|
|
162
|
+
--spacing-md: 1rem;
|
|
163
|
+
--spacing-lg: 1.5rem;
|
|
164
|
+
--spacing-xl: 2rem;
|
|
165
|
+
|
|
166
|
+
/* Chart colors (Dream Light palette) */
|
|
167
|
+
--chart-1: oklch(0.55 0.15 255);
|
|
168
|
+
--chart-2: oklch(0.62 0.12 175);
|
|
169
|
+
--chart-3: oklch(0.70 0.13 80);
|
|
170
|
+
--chart-4: oklch(0.55 0.14 295);
|
|
171
|
+
--chart-5: oklch(0.62 0.12 15);
|
|
172
|
+
|
|
173
|
+
/* Motion tokens */
|
|
174
|
+
--duration-fast: 100ms;
|
|
175
|
+
--duration-normal: 200ms;
|
|
176
|
+
--duration-slow: 300ms;
|
|
177
|
+
--ease-default: cubic-bezier(0.4, 0, 0.2, 1);
|
|
178
|
+
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
179
|
+
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
124
180
|
}
|
|
125
181
|
|
|
182
|
+
/* ===== SCOPED BASE RESET ===== */
|
|
183
|
+
/* Tailwind preflight is scoped to .mfe-root so it only resets MFE elements, not the host app */
|
|
126
184
|
@layer base {
|
|
127
|
-
|
|
128
|
-
@apply
|
|
185
|
+
.mfe-root {
|
|
186
|
+
@apply copa:bg-background copa:text-foreground;
|
|
187
|
+
font-family: var(--font-sans, "Satoshi", sans-serif);
|
|
188
|
+
line-height: 1.5;
|
|
189
|
+
-webkit-font-smoothing: antialiased;
|
|
190
|
+
-moz-osx-font-smoothing: grayscale;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.mfe-root *,
|
|
194
|
+
.mfe-root *::before,
|
|
195
|
+
.mfe-root *::after {
|
|
196
|
+
box-sizing: border-box;
|
|
197
|
+
border-width: 0;
|
|
198
|
+
border-style: solid;
|
|
199
|
+
@apply copa:border-border copa:outline-ring/50;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.mfe-root button,
|
|
203
|
+
.mfe-root a,
|
|
204
|
+
.mfe-root [role="menuitem"],
|
|
205
|
+
.mfe-root [role="option"],
|
|
206
|
+
.mfe-root [data-slot="sidebar-menu-button"],
|
|
207
|
+
.mfe-root [data-slot="dropdown-menu-trigger"],
|
|
208
|
+
.mfe-root [data-slot="dropdown-menu-item"] {
|
|
209
|
+
cursor: pointer;
|
|
129
210
|
}
|
|
130
|
-
|
|
131
|
-
|
|
211
|
+
|
|
212
|
+
.mfe-root img,
|
|
213
|
+
.mfe-root svg,
|
|
214
|
+
.mfe-root video {
|
|
215
|
+
display: block;
|
|
216
|
+
max-width: 100%;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.mfe-root h1, .mfe-root h2, .mfe-root h3,
|
|
220
|
+
.mfe-root h4, .mfe-root h5, .mfe-root h6 {
|
|
221
|
+
font-size: inherit;
|
|
222
|
+
font-weight: inherit;
|
|
132
223
|
}
|
|
224
|
+
|
|
225
|
+
.mfe-root ol,
|
|
226
|
+
.mfe-root ul,
|
|
227
|
+
.mfe-root menu {
|
|
228
|
+
list-style: none;
|
|
229
|
+
margin: 0;
|
|
230
|
+
padding: 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.mfe-root p,
|
|
234
|
+
.mfe-root h1, .mfe-root h2, .mfe-root h3,
|
|
235
|
+
.mfe-root h4, .mfe-root h5, .mfe-root h6,
|
|
236
|
+
.mfe-root blockquote,
|
|
237
|
+
.mfe-root dl, .mfe-root dd,
|
|
238
|
+
.mfe-root figure,
|
|
239
|
+
.mfe-root fieldset,
|
|
240
|
+
.mfe-root legend,
|
|
241
|
+
.mfe-root pre {
|
|
242
|
+
margin: 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.mfe-root hr {
|
|
246
|
+
height: 0;
|
|
247
|
+
color: inherit;
|
|
248
|
+
border-top-width: 1px;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.mfe-root a {
|
|
252
|
+
color: inherit;
|
|
253
|
+
text-decoration: inherit;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.mfe-root button,
|
|
257
|
+
.mfe-root input,
|
|
258
|
+
.mfe-root optgroup,
|
|
259
|
+
.mfe-root select,
|
|
260
|
+
.mfe-root textarea {
|
|
261
|
+
font-family: inherit;
|
|
262
|
+
font-feature-settings: inherit;
|
|
263
|
+
font-variation-settings: inherit;
|
|
264
|
+
font-size: 100%;
|
|
265
|
+
font-weight: inherit;
|
|
266
|
+
line-height: inherit;
|
|
267
|
+
color: inherit;
|
|
268
|
+
margin: 0;
|
|
269
|
+
padding: 0;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.mfe-root table {
|
|
273
|
+
border-collapse: collapse;
|
|
274
|
+
border-spacing: 0;
|
|
275
|
+
text-indent: 0;
|
|
276
|
+
border-color: inherit;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* ===== SCOPED TYPOGRAPHY UTILITIES ===== */
|
|
281
|
+
.mfe-root .text-page-title {
|
|
282
|
+
font-size: 1.5rem;
|
|
283
|
+
line-height: 2rem;
|
|
284
|
+
font-weight: 600;
|
|
285
|
+
}
|
|
286
|
+
.mfe-root .text-section-title {
|
|
287
|
+
font-size: 0.9375rem;
|
|
288
|
+
line-height: 1.375rem;
|
|
289
|
+
font-weight: 600;
|
|
290
|
+
}
|
|
291
|
+
.mfe-root .text-label {
|
|
292
|
+
font-size: 0.75rem;
|
|
293
|
+
line-height: 1rem;
|
|
294
|
+
font-weight: 500;
|
|
295
|
+
text-transform: uppercase;
|
|
296
|
+
letter-spacing: 0.025em;
|
|
297
|
+
}
|
|
298
|
+
.mfe-root .text-value {
|
|
299
|
+
font-size: 1.75rem;
|
|
300
|
+
line-height: 2.25rem;
|
|
301
|
+
font-weight: 700;
|
|
302
|
+
}
|
|
303
|
+
.mfe-root .text-nav-section {
|
|
304
|
+
font-size: 0.6875rem;
|
|
305
|
+
line-height: 1rem;
|
|
306
|
+
font-weight: 600;
|
|
307
|
+
text-transform: uppercase;
|
|
308
|
+
letter-spacing: 0.05em;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* ===== SCOPED SHADOW UTILITIES ===== */
|
|
312
|
+
.mfe-root .shadow-soft-xs { box-shadow: 0 1px 8px rgba(0, 0, 0, 0.03); }
|
|
313
|
+
.mfe-root .shadow-soft-sm { box-shadow: 0 2px 15px rgba(0, 0, 0, 0.04); }
|
|
314
|
+
.mfe-root .shadow-soft { box-shadow: 0 4px 25px rgba(0, 0, 0, 0.05); }
|
|
315
|
+
.mfe-root .shadow-soft-md { box-shadow: 0 6px 30px rgba(0, 0, 0, 0.06); }
|
|
316
|
+
.mfe-root .shadow-soft-lg { box-shadow: 0 8px 40px rgba(0, 0, 0, 0.07); }
|
|
317
|
+
.mfe-root .shadow-card {
|
|
318
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 4px 8px rgba(0,0,0,0.02), 0 8px 16px rgba(0,0,0,0.01);
|
|
319
|
+
}
|
|
320
|
+
.mfe-root .shadow-card-hover {
|
|
321
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.06), 0 8px 16px rgba(0,0,0,0.04), 0 16px 32px rgba(0,0,0,0.02);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* ===== ANIMATION KEYFRAMES (keyframes are global but unique names prevent collisions) ===== */
|
|
325
|
+
@keyframes copa-fade-in-up {
|
|
326
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
327
|
+
to { opacity: 1; transform: translateY(0); }
|
|
328
|
+
}
|
|
329
|
+
@keyframes copa-fade-in-down {
|
|
330
|
+
from { opacity: 0; transform: translateY(-8px); }
|
|
331
|
+
to { opacity: 1; transform: translateY(0); }
|
|
332
|
+
}
|
|
333
|
+
@keyframes copa-scale-in {
|
|
334
|
+
from { opacity: 0; transform: scale(0.95); }
|
|
335
|
+
to { opacity: 1; transform: scale(1); }
|
|
336
|
+
}
|
|
337
|
+
@keyframes copa-shimmer {
|
|
338
|
+
0% { background-position: -200% 0; }
|
|
339
|
+
100% { background-position: 200% 0; }
|
|
133
340
|
}
|
|
@@ -1,51 +1,60 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "./app.css";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
2
3
|
import { reactQuery, ReactQueryDevtools, copaSetConfig } from "@bluecopa/react";
|
|
3
|
-
import { Toaster } from "sonner";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import
|
|
4
|
+
import { Toaster } from "~/components/ui/sonner";
|
|
5
|
+
import { AppProvider } from "~/contexts/app-context";
|
|
6
|
+
import { ChartProvider } from "~/components/charts";
|
|
7
|
+
import { LoadingScreen } from "~/components/loading-screen";
|
|
8
|
+
import RouteConfig from "./routes";
|
|
9
|
+
import type { MfeProps } from "~/types";
|
|
10
|
+
import { DEFAULT_API_BASE_URL, DEFAULT_WORKSPACE_ID, QUERY_DEFAULTS } from "~/constants";
|
|
11
|
+
import { initAgGridLicense } from "~/utils/ag-grid-license";
|
|
7
12
|
|
|
8
13
|
const { QueryClient, QueryClientProvider } = reactQuery;
|
|
9
14
|
|
|
10
|
-
export default function App(props:
|
|
11
|
-
const [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export default function App(props: MfeProps) {
|
|
16
|
+
const [isConfigured, setIsConfigured] = useState(false);
|
|
17
|
+
const [queryClient] = useState(
|
|
18
|
+
() =>
|
|
19
|
+
new QueryClient({
|
|
20
|
+
defaultOptions: {
|
|
21
|
+
queries: { staleTime: QUERY_DEFAULTS.STALE_TIME, retry: QUERY_DEFAULTS.RETRY },
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
19
25
|
|
|
20
26
|
useEffect(() => {
|
|
21
|
-
|
|
22
|
-
let copaUser = {} as any;
|
|
23
|
-
try {
|
|
24
|
-
const copaToken = import.meta.env.VITE_BLUECOPA_API_TOKEN
|
|
25
|
-
? atob(import.meta.env.VITE_BLUECOPA_API_TOKEN)
|
|
26
|
-
: '{}';
|
|
27
|
-
copaUser = JSON.parse(copaToken);
|
|
28
|
-
} catch (error) {
|
|
29
|
-
console.warn('Failed to parse VITE_BLUECOPA_API_TOKEN:', error);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
console.log("Copa User", import.meta.env.VITE_BLUECOPA_API_URL);
|
|
33
|
-
|
|
27
|
+
initAgGridLicense();
|
|
34
28
|
copaSetConfig({
|
|
35
|
-
apiBaseUrl:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
apiBaseUrl:
|
|
30
|
+
props.apiBaseUrl ||
|
|
31
|
+
import.meta.env.VITE_BLUECOPA_API_URL ||
|
|
32
|
+
DEFAULT_API_BASE_URL,
|
|
33
|
+
accessToken: props.accessToken || "",
|
|
34
|
+
workspaceId:
|
|
35
|
+
props.workspaceId ||
|
|
36
|
+
import.meta.env.VITE_BLUECOPA_WORKSPACE_ID ||
|
|
37
|
+
DEFAULT_WORKSPACE_ID,
|
|
38
|
+
userId: props.userId || "",
|
|
39
|
+
});
|
|
40
|
+
setIsConfigured(true);
|
|
41
|
+
}, [props.apiBaseUrl, props.accessToken, props.workspaceId, props.userId]);
|
|
42
|
+
|
|
43
|
+
if (!isConfigured) {
|
|
44
|
+
return <LoadingScreen message="Initializing..." />;
|
|
45
|
+
}
|
|
41
46
|
|
|
42
47
|
return (
|
|
43
48
|
<QueryClientProvider client={queryClient}>
|
|
44
|
-
<
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
<div className="mfe-root copa:min-h-svh copa:animate-in copa:fade-in copa:duration-300">
|
|
50
|
+
<ChartProvider>
|
|
51
|
+
<AppProvider>
|
|
52
|
+
<RouteConfig />
|
|
53
|
+
<Toaster />
|
|
54
|
+
</AppProvider>
|
|
55
|
+
</ChartProvider>
|
|
56
|
+
{import.meta.env.DEV && <ReactQueryDevtools initialIsOpen={false} />}
|
|
57
|
+
</div>
|
|
49
58
|
</QueryClientProvider>
|
|
50
|
-
)
|
|
59
|
+
);
|
|
51
60
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function BluecopaLogo(props: React.SVGProps<SVGSVGElement>) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
viewBox="0 0 1820 1774.9"
|
|
6
|
+
{...props}
|
|
7
|
+
>
|
|
8
|
+
<circle fill="#fff" cx="1054.53" cy="779.52" r="386.21" />
|
|
9
|
+
<path
|
|
10
|
+
fill="#8ac2ff"
|
|
11
|
+
d="M5.91,1004.47L0,1768.96l764.5,5.91c422.08,3.27,767.15-336.52,770.42-758.58,3.26-422.06-336.51-767.14-758.59-770.41C350.68,242.59,9.18,582.4,5.91,1004.47Z"
|
|
12
|
+
/>
|
|
13
|
+
<path
|
|
14
|
+
fill="#3548ff"
|
|
15
|
+
d="M1820,764.52V0h-764.52C633.38,0,290.95,342.44,290.95,764.52s342.43,764.52,764.52,764.52,764.52-342.44,764.52-764.52Z"
|
|
16
|
+
/>
|
|
17
|
+
<circle fill="#fff" cx="1055.48" cy="780.55" r="382.26" />
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|