create-bluecopa-react-app 1.0.0 → 1.0.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 +69 -28
- package/bin/create-bluecopa-react-app.js +1 -1
- package/package.json +1 -1
- package/templates/latest/.env.example +14 -0
- package/templates/latest/.eslintrc.cjs +42 -0
- package/templates/latest/README.md +264 -0
- package/templates/latest/clean.sh +39 -0
- package/templates/latest/index.html +14 -0
- package/templates/{basic → latest}/package-lock.json +1099 -1084
- package/templates/latest/package.json +61 -0
- package/templates/{basic/postcss.config.js → latest/postcss.config.cjs} +1 -1
- package/templates/latest/public/bluecopa-logo.svg +30 -0
- package/templates/latest/public/favicon-32x32.png +0 -0
- package/templates/latest/public/favicon-96x96.png +0 -0
- package/templates/latest/public/favicon.ico +0 -0
- package/templates/latest/setup.sh +55 -0
- package/templates/latest/src/App.tsx +15 -0
- package/templates/latest/src/components/layout/dashboard-header.tsx +139 -0
- package/templates/latest/src/components/layout/dashboard-layout.tsx +29 -0
- package/templates/latest/src/components/layout/sidebar.tsx +54 -0
- package/templates/latest/src/components/page/dashboard.tsx +1506 -0
- package/templates/latest/src/components/page/navbar.tsx +104 -0
- package/templates/latest/src/components/tables/data-grid.tsx +439 -0
- package/templates/latest/src/components/ui/alert.tsx +59 -0
- package/templates/latest/src/components/ui/avatar.tsx +50 -0
- package/templates/latest/src/components/ui/badge.tsx +36 -0
- package/templates/latest/src/components/ui/bluecopa-logo.tsx +54 -0
- package/templates/{basic → latest}/src/components/ui/button.tsx +5 -11
- package/templates/latest/src/components/ui/dropdown-menu.tsx +200 -0
- package/templates/latest/src/components/ui/input.tsx +24 -0
- package/templates/latest/src/components/ui/label.tsx +23 -0
- package/templates/latest/src/components/ui/select.tsx +29 -0
- package/templates/latest/src/hooks/use-api.ts +55 -0
- package/templates/{basic → latest}/src/index.css +1 -1
- package/templates/{basic → latest}/src/main.tsx +6 -2
- package/templates/latest/src/pages/Dashboard.tsx +13 -0
- package/templates/latest/src/pages/Home.tsx +622 -0
- package/templates/latest/src/providers/query-provider.tsx +48 -0
- package/templates/latest/src/single-spa.tsx +105 -0
- package/templates/{basic/src/types/index.ts → latest/src/types/api.ts} +19 -35
- package/templates/latest/src/vite-env.d.ts +11 -0
- package/templates/{basic → latest}/tailwind.config.js +15 -4
- package/templates/{basic/tsconfig.json → latest/tsconfig.app.json} +5 -10
- package/templates/latest/tsconfig.json +19 -0
- package/templates/latest/vite.config.ts +64 -0
- package/templates/basic/.editorconfig +0 -12
- package/templates/basic/.env.example +0 -10
- package/templates/basic/README.md +0 -213
- package/templates/basic/index.html +0 -13
- package/templates/basic/package.json +0 -68
- package/templates/basic/setup.sh +0 -46
- package/templates/basic/src/App.tsx +0 -95
- package/templates/basic/src/components/dashboard/AdvancedAnalytics.tsx +0 -351
- package/templates/basic/src/components/dashboard/MetricsOverview.tsx +0 -150
- package/templates/basic/src/components/dashboard/TransactionCharts.tsx +0 -215
- package/templates/basic/src/components/dashboard/TransactionTable.tsx +0 -172
- package/templates/basic/src/components/ui/tabs.tsx +0 -53
- package/templates/basic/src/pages/Dashboard.tsx +0 -135
- package/templates/basic/vite.config.ts +0 -13
- /package/templates/{basic → latest}/src/components/ui/card.tsx +0 -0
- /package/templates/{basic → latest}/src/lib/utils.ts +0 -0
- /package/templates/{basic → latest}/tsconfig.node.json +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot, Root } from 'react-dom/client';
|
|
3
|
+
import singleSpaReact from 'single-spa-react';
|
|
4
|
+
import { MemoryRouter, BrowserRouter } from 'react-router-dom';
|
|
5
|
+
import App from './App';
|
|
6
|
+
|
|
7
|
+
// Single-spa lifecycle props interface
|
|
8
|
+
interface LifecycleProps {
|
|
9
|
+
domElement: HTMLElement;
|
|
10
|
+
basename?: string;
|
|
11
|
+
singleSpa?: {
|
|
12
|
+
name: string;
|
|
13
|
+
mountParcel: Function;
|
|
14
|
+
getProps: () => any;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let root: Root | null = null;
|
|
19
|
+
|
|
20
|
+
// Root component wrapper that handles routing
|
|
21
|
+
const PnLExplorerRoot: React.FC<{ basename?: string; isMicroFrontend?: boolean }> = ({
|
|
22
|
+
basename = '/',
|
|
23
|
+
isMicroFrontend = false
|
|
24
|
+
}) => {
|
|
25
|
+
// Use MemoryRouter for micro-frontend to avoid conflicts with host routing
|
|
26
|
+
// Use BrowserRouter for standalone mode
|
|
27
|
+
const Router = isMicroFrontend ? MemoryRouter : BrowserRouter;
|
|
28
|
+
const routerProps = isMicroFrontend ? {} : { basename };
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Router {...routerProps}>
|
|
32
|
+
<App />
|
|
33
|
+
</Router>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Single-spa React configuration
|
|
38
|
+
const lifecycles = singleSpaReact({
|
|
39
|
+
React,
|
|
40
|
+
ReactDOMClient: { createRoot },
|
|
41
|
+
rootComponent: (props) => <PnLExplorerRoot isMicroFrontend={true} basename={props.basename} />,
|
|
42
|
+
errorBoundary: (err, info, props) => {
|
|
43
|
+
console.error('PnL Explorer Single-spa Error:', err, info);
|
|
44
|
+
return <div>Something went wrong loading PnL Explorer</div>;
|
|
45
|
+
},
|
|
46
|
+
renderType: 'createRoot',
|
|
47
|
+
domElementGetter: () => document.getElementById('single-spa-application:pnl-explorer') || document.body
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Export the single-spa lifecycle functions
|
|
51
|
+
export const { mount, unmount, bootstrap } = lifecycles;
|
|
52
|
+
|
|
53
|
+
// Export a manual mount function for direct usage
|
|
54
|
+
export const manualMount = async (props: LifecycleProps) => {
|
|
55
|
+
if (!props.domElement) {
|
|
56
|
+
throw new Error('domElement is required for mounting PnL Explorer');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
// Clean up any existing root
|
|
61
|
+
if (root) {
|
|
62
|
+
root.unmount();
|
|
63
|
+
root = null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Create new root
|
|
67
|
+
root = createRoot(props.domElement);
|
|
68
|
+
|
|
69
|
+
// Mount the application with the provided basename as micro-frontend
|
|
70
|
+
root.render(
|
|
71
|
+
<PnLExplorerRoot
|
|
72
|
+
isMicroFrontend={true}
|
|
73
|
+
basename={props.basename || '/app/external/pnl-explorer'}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
console.log('PnL Explorer mounted successfully');
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error('Failed to mount PnL Explorer:', error);
|
|
81
|
+
return Promise.reject(error);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Export a manual unmount function
|
|
86
|
+
export const manualUnmount = async () => {
|
|
87
|
+
try {
|
|
88
|
+
if (root) {
|
|
89
|
+
root.unmount();
|
|
90
|
+
root = null;
|
|
91
|
+
}
|
|
92
|
+
console.log('PnL Explorer unmounted successfully');
|
|
93
|
+
return Promise.resolve();
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error('Failed to unmount PnL Explorer:', error);
|
|
96
|
+
return Promise.reject(error);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Default export for module federation
|
|
101
|
+
export default {
|
|
102
|
+
mount: manualMount,
|
|
103
|
+
unmount: manualUnmount,
|
|
104
|
+
bootstrap: () => Promise.resolve()
|
|
105
|
+
};
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
//
|
|
2
|
-
export interface
|
|
1
|
+
// API Types
|
|
2
|
+
export interface MetricData {
|
|
3
|
+
TotalAmount: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface ApiMetricResponse {
|
|
7
|
+
data: MetricData[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface DatasetSchema {
|
|
11
|
+
name: string;
|
|
12
|
+
data_type: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface TransactionData {
|
|
3
16
|
transaction_id: string;
|
|
4
17
|
transaction_day: string;
|
|
5
18
|
payment_end: string;
|
|
@@ -23,22 +36,13 @@ export interface TransactionRecord {
|
|
|
23
36
|
copa_source_name: string;
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
export interface
|
|
39
|
+
export interface ApiDatasetResponse {
|
|
27
40
|
data: {
|
|
28
|
-
schema:
|
|
29
|
-
|
|
30
|
-
data_type: string;
|
|
31
|
-
}>;
|
|
32
|
-
data: TransactionRecord[];
|
|
41
|
+
schema: DatasetSchema[];
|
|
42
|
+
data: TransactionData[];
|
|
33
43
|
};
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
export interface MetricResponse {
|
|
37
|
-
data: Array<{
|
|
38
|
-
TotalAmount: number;
|
|
39
|
-
}>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
46
|
export interface User {
|
|
43
47
|
email: string;
|
|
44
48
|
firstName: string;
|
|
@@ -68,27 +72,7 @@ export interface Organization {
|
|
|
68
72
|
entityVersion: number;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
export interface
|
|
75
|
+
export interface ApiUserResponse {
|
|
72
76
|
user: User;
|
|
73
77
|
organization: Organization;
|
|
74
78
|
}
|
|
75
|
-
|
|
76
|
-
// Chart data types
|
|
77
|
-
export interface CategorySalesData {
|
|
78
|
-
category: string;
|
|
79
|
-
totalSales: number;
|
|
80
|
-
quantity: number;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface PaymentMethodData {
|
|
84
|
-
paymentMethod: string;
|
|
85
|
-
count: number;
|
|
86
|
-
totalAmount: number;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface StateAnalytics {
|
|
90
|
-
state: string;
|
|
91
|
-
totalTransactions: number;
|
|
92
|
-
totalAmount: number;
|
|
93
|
-
averageOrderValue: number;
|
|
94
|
-
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
interface ImportMetaEnv {
|
|
4
|
+
readonly VITE_BLUECOPA_API_TOKEN: string
|
|
5
|
+
readonly VITE_BLUECOPA_API_URL: string
|
|
6
|
+
readonly VITE_BLUECOPA_WORKSPACE_ID: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface ImportMeta {
|
|
10
|
+
readonly env: ImportMetaEnv
|
|
11
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
|
-
|
|
2
|
+
module.exports = {
|
|
3
3
|
darkMode: ["class"],
|
|
4
4
|
content: [
|
|
5
|
-
'./pages/**/*.{ts,tsx}',
|
|
6
|
-
'./components/**/*.{ts,tsx}',
|
|
7
|
-
'./app/**/*.{ts,tsx}',
|
|
8
5
|
'./src/**/*.{ts,tsx}',
|
|
6
|
+
'./node_modules/@tremor/**/*.{js,ts,jsx,tsx}',
|
|
9
7
|
],
|
|
10
8
|
prefix: "",
|
|
11
9
|
theme: {
|
|
@@ -51,6 +49,19 @@ export default {
|
|
|
51
49
|
DEFAULT: "hsl(var(--card))",
|
|
52
50
|
foreground: "hsl(var(--card-foreground))",
|
|
53
51
|
},
|
|
52
|
+
// Bluecopa brand colors
|
|
53
|
+
bluecopa: {
|
|
54
|
+
50: '#eff6ff',
|
|
55
|
+
100: '#dbeafe',
|
|
56
|
+
200: '#bfdbfe',
|
|
57
|
+
300: '#93c5fd',
|
|
58
|
+
400: '#60a5fa',
|
|
59
|
+
500: '#3b82f6',
|
|
60
|
+
600: '#2563eb',
|
|
61
|
+
700: '#1d4ed8',
|
|
62
|
+
800: '#1e40af',
|
|
63
|
+
900: '#1e3a8a',
|
|
64
|
+
},
|
|
54
65
|
},
|
|
55
66
|
borderRadius: {
|
|
56
67
|
lg: "var(--radius)",
|
|
@@ -9,23 +9,18 @@
|
|
|
9
9
|
/* Bundler mode */
|
|
10
10
|
"moduleResolution": "bundler",
|
|
11
11
|
"allowImportingTsExtensions": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
12
|
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
14
|
"noEmit": true,
|
|
15
15
|
"jsx": "react-jsx",
|
|
16
16
|
|
|
17
17
|
/* Linting */
|
|
18
|
-
"strict":
|
|
18
|
+
"strict": true,
|
|
19
19
|
"noUnusedLocals": true,
|
|
20
20
|
"noUnusedParameters": true,
|
|
21
21
|
"noFallthroughCasesInSwitch": true,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"baseUrl": ".",
|
|
25
|
-
"paths": {
|
|
26
|
-
"@/*": ["./src/*"]
|
|
27
|
-
}
|
|
22
|
+
"noImplicitAny": false,
|
|
23
|
+
"strictNullChecks": false
|
|
28
24
|
},
|
|
29
|
-
"include": ["src"]
|
|
30
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
+
"include": ["src"]
|
|
31
26
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [],
|
|
3
|
+
"references": [
|
|
4
|
+
{ "path": "./tsconfig.app.json" },
|
|
5
|
+
{ "path": "./tsconfig.node.json" }
|
|
6
|
+
],
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"baseUrl": ".",
|
|
9
|
+
"paths": {
|
|
10
|
+
"@/*": ["./src/*"]
|
|
11
|
+
},
|
|
12
|
+
"noImplicitAny": false,
|
|
13
|
+
"noUnusedParameters": false,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"allowJs": true,
|
|
16
|
+
"noUnusedLocals": false,
|
|
17
|
+
"strictNullChecks": false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react-swc";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import federation from "@originjs/vite-plugin-federation";
|
|
5
|
+
|
|
6
|
+
// https://vitejs.dev/config/
|
|
7
|
+
export default defineConfig(({ mode }) => {
|
|
8
|
+
const isStandaloneBuild = process.env.VITE_BUILD_TARGET === 'standalone';
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
server: {
|
|
12
|
+
host: "::",
|
|
13
|
+
port: 8080,
|
|
14
|
+
cors: true,
|
|
15
|
+
headers: {
|
|
16
|
+
"Access-Control-Allow-Origin": "*",
|
|
17
|
+
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
|
|
18
|
+
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
plugins: [
|
|
22
|
+
react(),
|
|
23
|
+
!isStandaloneBuild && federation({
|
|
24
|
+
name: '__copa_ext_app__react_route',
|
|
25
|
+
filename: 'remoteEntry.js',
|
|
26
|
+
exposes: {
|
|
27
|
+
'./App': './src/single-spa.tsx',
|
|
28
|
+
},
|
|
29
|
+
shared: {
|
|
30
|
+
react: {
|
|
31
|
+
singleton: true,
|
|
32
|
+
},
|
|
33
|
+
'react-dom': {
|
|
34
|
+
singleton: true,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
|
+
].filter(Boolean),
|
|
39
|
+
resolve: {
|
|
40
|
+
alias: {
|
|
41
|
+
"@": path.resolve(__dirname, "./src"),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
build: isStandaloneBuild ? {
|
|
45
|
+
target: 'esnext',
|
|
46
|
+
minify: false,
|
|
47
|
+
cssCodeSplit: false,
|
|
48
|
+
rollupOptions: {
|
|
49
|
+
input: path.resolve(__dirname, 'standalone.html')
|
|
50
|
+
}
|
|
51
|
+
} : {
|
|
52
|
+
target: 'esnext',
|
|
53
|
+
minify: false,
|
|
54
|
+
cssCodeSplit: false,
|
|
55
|
+
rollupOptions: {
|
|
56
|
+
external: ['react', 'react-dom'],
|
|
57
|
+
output: {
|
|
58
|
+
format: 'system'
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
base: '/'
|
|
63
|
+
};
|
|
64
|
+
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# BlueCopa API Configuration
|
|
2
|
-
REACT_APP_API_BASE_URL=https://api.bluecopa.com
|
|
3
|
-
REACT_APP_API_KEY=your_api_key_here
|
|
4
|
-
|
|
5
|
-
# Environment
|
|
6
|
-
NODE_ENV=development
|
|
7
|
-
|
|
8
|
-
# Optional: Analytics and Monitoring
|
|
9
|
-
REACT_APP_SENTRY_DSN=your_sentry_dsn
|
|
10
|
-
REACT_APP_ANALYTICS_ID=your_analytics_id
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
# BlueCopa Dashboard Template
|
|
2
|
-
|
|
3
|
-
A modern React dashboard template for BlueCopa applications built with TanStack Query, shadcn/ui, and Recharts.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🚀 **Modern Tech Stack**: React 18, TypeScript, Vite
|
|
8
|
-
- 📊 **Data Fetching**: TanStack Query for server state management
|
|
9
|
-
- 🎨 **UI Components**: shadcn/ui with Radix UI primitives
|
|
10
|
-
- 📈 **Charts**: Recharts for beautiful data visualizations
|
|
11
|
-
- 🎯 **Type Safety**: Full TypeScript support
|
|
12
|
-
- 🔄 **Real-time Updates**: Automatic data refetching and caching
|
|
13
|
-
- 📱 **Responsive Design**: Mobile-first responsive layout
|
|
14
|
-
- 🌙 **Dark Mode**: Built-in dark mode support
|
|
15
|
-
|
|
16
|
-
## Quick Start
|
|
17
|
-
|
|
18
|
-
1. **Install dependencies**:
|
|
19
|
-
```bash
|
|
20
|
-
npm install
|
|
21
|
-
# or
|
|
22
|
-
yarn install
|
|
23
|
-
# or
|
|
24
|
-
pnpm install
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
2. **Start the development server**:
|
|
28
|
-
```bash
|
|
29
|
-
npm run dev
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
3. **Open your browser** and navigate to `http://localhost:5173`
|
|
33
|
-
|
|
34
|
-
## Project Structure
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
src/
|
|
38
|
-
├── components/ # Reusable UI components
|
|
39
|
-
│ ├── ui/ # shadcn/ui components
|
|
40
|
-
│ └── dashboard/ # Dashboard-specific components
|
|
41
|
-
├── lib/ # Utilities and helpers
|
|
42
|
-
├── pages/ # Page components
|
|
43
|
-
├── services/ # API services and data fetching
|
|
44
|
-
├── types/ # TypeScript type definitions
|
|
45
|
-
├── App.tsx # Main application component
|
|
46
|
-
└── main.tsx # Application entry point
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Components Overview
|
|
50
|
-
|
|
51
|
-
### Dashboard Components
|
|
52
|
-
|
|
53
|
-
- **MetricsOverview**: Key performance indicators and metrics cards
|
|
54
|
-
- **TransactionCharts**: Interactive charts showing sales data, payment methods, and analytics
|
|
55
|
-
- **TransactionTable**: Data table with transaction details and filters
|
|
56
|
-
|
|
57
|
-
### Features Demonstrated
|
|
58
|
-
|
|
59
|
-
1. **TanStack Query Integration**:
|
|
60
|
-
- Automatic caching and background updates
|
|
61
|
-
- Loading states and error handling
|
|
62
|
-
- Query invalidation and refetching
|
|
63
|
-
|
|
64
|
-
2. **Data Visualization**:
|
|
65
|
-
- Bar charts for category sales and state analytics
|
|
66
|
-
- Pie charts for payment method distribution
|
|
67
|
-
- Line charts for trend analysis
|
|
68
|
-
|
|
69
|
-
3. **Real Transaction Data**:
|
|
70
|
-
- Based on actual BlueCopa transaction dataset
|
|
71
|
-
- Proper data typing with TypeScript
|
|
72
|
-
- Mock API responses for development
|
|
73
|
-
|
|
74
|
-
## API Integration
|
|
75
|
-
|
|
76
|
-
The template includes a mock API service (`src/services/api.ts`) that demonstrates:
|
|
77
|
-
|
|
78
|
-
- Dataset queries for transaction data
|
|
79
|
-
- Metric queries for aggregated data
|
|
80
|
-
- User authentication and organization data
|
|
81
|
-
- Proper error handling and loading states
|
|
82
|
-
|
|
83
|
-
### Replacing Mock Data
|
|
84
|
-
|
|
85
|
-
To use real APIs, update the `BlueCOPAApi` service:
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
// In src/services/api.ts
|
|
89
|
-
export const BlueCOPAApi = {
|
|
90
|
-
getDataset: async (datasetId: string) => {
|
|
91
|
-
const response = await apiClient.get(`/datasets/${datasetId}`);
|
|
92
|
-
return response.data;
|
|
93
|
-
},
|
|
94
|
-
// ... other methods
|
|
95
|
-
};
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Customization
|
|
99
|
-
|
|
100
|
-
### Adding New Charts
|
|
101
|
-
|
|
102
|
-
1. Create a new component in `src/components/dashboard/`
|
|
103
|
-
2. Use Recharts components for visualization
|
|
104
|
-
3. Add TanStack Query for data fetching
|
|
105
|
-
4. Include proper TypeScript types
|
|
106
|
-
|
|
107
|
-
### Extending the API
|
|
108
|
-
|
|
109
|
-
1. Add new types to `src/types/index.ts`
|
|
110
|
-
2. Extend the API service in `src/services/api.ts`
|
|
111
|
-
3. Create corresponding UI components
|
|
112
|
-
4. Add new routes if needed
|
|
113
|
-
|
|
114
|
-
### Styling
|
|
115
|
-
|
|
116
|
-
The template uses Tailwind CSS with shadcn/ui design system:
|
|
117
|
-
|
|
118
|
-
- Modify `tailwind.config.js` for custom themes
|
|
119
|
-
- Update CSS variables in `src/index.css` for color schemes
|
|
120
|
-
- Use the `cn()` utility for conditional styling
|
|
121
|
-
|
|
122
|
-
## Data Types
|
|
123
|
-
|
|
124
|
-
The template includes comprehensive TypeScript types for BlueCopa data:
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
interface TransactionRecord {
|
|
128
|
-
transaction_id: string;
|
|
129
|
-
transaction_day: string;
|
|
130
|
-
city: string;
|
|
131
|
-
category: string;
|
|
132
|
-
total_amount: number;
|
|
133
|
-
payment_method: string;
|
|
134
|
-
// ... other fields
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Development
|
|
139
|
-
|
|
140
|
-
### Available Scripts
|
|
141
|
-
|
|
142
|
-
- `npm run dev` - Start development server
|
|
143
|
-
- `npm run build` - Build for production
|
|
144
|
-
- `npm run preview` - Preview production build
|
|
145
|
-
- `npm run lint` - Run ESLint
|
|
146
|
-
- `npm run type-check` - Run TypeScript compiler
|
|
147
|
-
|
|
148
|
-
### Environment Variables
|
|
149
|
-
|
|
150
|
-
Create a `.env` file for configuration:
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
REACT_APP_API_BASE_URL=https://api.bluecopa.com
|
|
154
|
-
REACT_APP_API_KEY=your_api_key
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Deployment
|
|
158
|
-
|
|
159
|
-
### Build for Production
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
npm run build
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
The built files will be in the `dist/` directory.
|
|
166
|
-
|
|
167
|
-
### Deploy to Vercel
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
vercel --prod
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Deploy to Netlify
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
netlify deploy --prod --dir=dist
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## Technologies Used
|
|
180
|
-
|
|
181
|
-
- **React 18** - UI framework
|
|
182
|
-
- **TypeScript** - Type safety
|
|
183
|
-
- **Vite** - Build tool and dev server
|
|
184
|
-
- **TanStack Query** - Server state management
|
|
185
|
-
- **shadcn/ui** - UI component library
|
|
186
|
-
- **Radix UI** - Headless UI primitives
|
|
187
|
-
- **Recharts** - Chart library
|
|
188
|
-
- **Tailwind CSS** - Utility-first CSS framework
|
|
189
|
-
- **React Router** - Client-side routing
|
|
190
|
-
- **Axios** - HTTP client
|
|
191
|
-
|
|
192
|
-
## Contributing
|
|
193
|
-
|
|
194
|
-
1. Fork the repository
|
|
195
|
-
2. Create a feature branch
|
|
196
|
-
3. Make your changes
|
|
197
|
-
4. Add tests if applicable
|
|
198
|
-
5. Submit a pull request
|
|
199
|
-
|
|
200
|
-
## License
|
|
201
|
-
|
|
202
|
-
This template is part of the BlueCopa platform and follows the project's licensing terms.
|
|
203
|
-
|
|
204
|
-
## Support
|
|
205
|
-
|
|
206
|
-
For questions and support:
|
|
207
|
-
- Check the [BlueCopa documentation](https://docs.bluecopa.com)
|
|
208
|
-
- Open an issue in the repository
|
|
209
|
-
- Contact the BlueCopa team
|
|
210
|
-
|
|
211
|
-
---
|
|
212
|
-
|
|
213
|
-
Built with ❤️ by the BlueCopa team
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>BlueCopa Dashboard</title>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="root"></div>
|
|
11
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "bluecopa-dashboard",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "BlueCopa Dashboard Template with TanStack Query and shadcn/ui",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "tsc && vite build",
|
|
9
|
-
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
10
|
-
"preview": "vite preview",
|
|
11
|
-
"type-check": "tsc --noEmit"
|
|
12
|
-
},
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"@bluecopa/react": "^0.1.3",
|
|
15
|
-
"@radix-ui/react-accordion": "^1.1.2",
|
|
16
|
-
"@radix-ui/react-alert-dialog": "^1.0.5",
|
|
17
|
-
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
|
18
|
-
"@radix-ui/react-avatar": "^1.0.4",
|
|
19
|
-
"@radix-ui/react-checkbox": "^1.0.4",
|
|
20
|
-
"@radix-ui/react-collapsible": "^1.0.3",
|
|
21
|
-
"@radix-ui/react-dialog": "^1.0.5",
|
|
22
|
-
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
23
|
-
"@radix-ui/react-hover-card": "^1.0.7",
|
|
24
|
-
"@radix-ui/react-label": "^2.0.2",
|
|
25
|
-
"@radix-ui/react-menubar": "^1.0.4",
|
|
26
|
-
"@radix-ui/react-navigation-menu": "^1.1.4",
|
|
27
|
-
"@radix-ui/react-popover": "^1.0.7",
|
|
28
|
-
"@radix-ui/react-progress": "^1.0.3",
|
|
29
|
-
"@radix-ui/react-radio-group": "^1.1.3",
|
|
30
|
-
"@radix-ui/react-scroll-area": "^1.0.5",
|
|
31
|
-
"@radix-ui/react-select": "^2.0.0",
|
|
32
|
-
"@radix-ui/react-separator": "^1.0.3",
|
|
33
|
-
"@radix-ui/react-slider": "^1.1.2",
|
|
34
|
-
"@radix-ui/react-slot": "^1.0.2",
|
|
35
|
-
"@radix-ui/react-switch": "^1.0.3",
|
|
36
|
-
"@radix-ui/react-tabs": "^1.0.4",
|
|
37
|
-
"@radix-ui/react-toast": "^1.1.5",
|
|
38
|
-
"@radix-ui/react-toggle": "^1.0.3",
|
|
39
|
-
"@radix-ui/react-toggle-group": "^1.0.4",
|
|
40
|
-
"@radix-ui/react-tooltip": "^1.0.7",
|
|
41
|
-
"axios": "^1.6.0",
|
|
42
|
-
"class-variance-authority": "^0.7.0",
|
|
43
|
-
"clsx": "^2.0.0",
|
|
44
|
-
"date-fns": "^2.30.0",
|
|
45
|
-
"lucide-react": "^0.292.0",
|
|
46
|
-
"react": "^18.2.0",
|
|
47
|
-
"react-dom": "^18.2.0",
|
|
48
|
-
"react-router-dom": "^6.20.0",
|
|
49
|
-
"recharts": "^2.8.0",
|
|
50
|
-
"tailwind-merge": "^2.0.0",
|
|
51
|
-
"tailwindcss-animate": "^1.0.7"
|
|
52
|
-
},
|
|
53
|
-
"devDependencies": {
|
|
54
|
-
"@types/react": "^18.2.37",
|
|
55
|
-
"@types/react-dom": "^18.2.15",
|
|
56
|
-
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
|
57
|
-
"@typescript-eslint/parser": "^6.10.0",
|
|
58
|
-
"@vitejs/plugin-react": "^4.1.1",
|
|
59
|
-
"autoprefixer": "^10.4.16",
|
|
60
|
-
"eslint": "^8.53.0",
|
|
61
|
-
"eslint-plugin-react-hooks": "^4.6.0",
|
|
62
|
-
"eslint-plugin-react-refresh": "^0.4.4",
|
|
63
|
-
"postcss": "^8.4.31",
|
|
64
|
-
"tailwindcss": "^3.3.5",
|
|
65
|
-
"typescript": "^5.2.2",
|
|
66
|
-
"vite": "^4.5.0"
|
|
67
|
-
}
|
|
68
|
-
}
|