Migrate from Create React App to Vite
All checks were successful
Deploy HiHala Dashboard / deploy (push) Successful in 7s

CRA (react-scripts 5.0.1) is abandoned and incompatible with TypeScript 5.x.
Vite provides faster builds, active maintenance, and native TS5 support.

- Replace react-scripts with vite + @vitejs/plugin-react
- Move index.html to root with script module entry point
- Replace setupProxy.js with vite.config.ts proxy config
- Rename env vars from REACT_APP_ to VITE_ prefix
- Update tsconfig for bundler module resolution
- Add nginx setup script for deployment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fahed
2026-03-09 17:24:11 +03:00
parent 42cb524cd8
commit b7ad978e29
12 changed files with 1023 additions and 16242 deletions

View File

@@ -1,7 +1,7 @@
# NocoDB (primary data source)
REACT_APP_NOCODB_URL=http://localhost:8090
REACT_APP_NOCODB_TOKEN=your_token_here
VITE_NOCODB_URL=http://localhost:8090
VITE_NOCODB_TOKEN=your_token_here
# Google Sheets (fallback if NocoDB fails)
REACT_APP_SHEETS_ID=your_spreadsheet_id_here
REACT_APP_SHEETS_NAME=Consolidated Data
VITE_SHEETS_ID=your_spreadsheet_id_here
VITE_SHEETS_NAME=Consolidated Data

24
index.html Normal file
View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap" rel="stylesheet">
<title>HiHala Data Museums</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>

17071
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
"name": "hihala-dashboard",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8090",
"dependencies": {
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
@@ -16,38 +15,20 @@
"react-chartjs-2": "^5.3.1",
"react-dom": "^19.2.4",
"react-router-dom": "^7.13.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
"start": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@types/node": "^25.2.0",
"@types/react": "^19.2.10",
"@types/react-dom": "^19.2.3",
"@types/react-router-dom": "^5.3.3",
"typescript": "^5.9.3"
"@vitejs/plugin-react": "^5.1.4",
"typescript": "^5.9.3",
"vite": "^7.3.1"
}
}

View File

@@ -1,46 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap" rel="stylesheet">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>HiHala Data Museums</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

37
setup-nginx.sh Normal file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# Create nginx config for dashboard.tools.hihala.com
sudo tee /etc/nginx/sites-available/dashboard.tools.hihala.com > /dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name dashboard.tools.hihala.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/dashboard.tools.hihala.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Test ACME challenge path
sudo mkdir -p /var/www/html/.well-known/acme-challenge/
echo "test" | sudo tee /var/www/html/.well-known/acme-challenge/test
curl -s http://dashboard.tools.hihala.com/.well-known/acme-challenge/test && echo " - OK"
rm -f /var/www/html/.well-known/acme-challenge/test
# Run certbot
sudo certbot --nginx -d dashboard.tools.hihala.com

View File

@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom/client';
import { LanguageProvider } from './contexts/LanguageContext';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<LanguageProvider>

View File

@@ -17,8 +17,8 @@ import type {
NocoDBDailyStat
} from '../types';
const NOCODB_URL = process.env.REACT_APP_NOCODB_URL || '';
const NOCODB_TOKEN = process.env.REACT_APP_NOCODB_TOKEN || '';
const NOCODB_URL = import.meta.env.VITE_NOCODB_URL || '';
const NOCODB_TOKEN = import.meta.env.VITE_NOCODB_TOKEN || '';
// Table IDs (Cloudron NocoDB)
const NOCODB_TABLES = {
@@ -230,7 +230,7 @@ export async function fetchData(): Promise<FetchResult> {
console.warn('NocoDB not configured, using cached data');
return { data: cached.data, fromCache: true, cacheTimestamp: cached.timestamp };
}
throw new Error('NocoDB not configured and no cached data available. Set REACT_APP_NOCODB_URL and REACT_APP_NOCODB_TOKEN in .env.local');
throw new Error('NocoDB not configured and no cached data available. Set VITE_NOCODB_URL and VITE_NOCODB_TOKEN in .env.local');
}
try {

View File

@@ -1,7 +1,7 @@
// Salla Integration Service
// Connects to the local Salla backend server
const SALLA_SERVER_URL = process.env.REACT_APP_SALLA_SERVER_URL || 'http://localhost:3001';
const SALLA_SERVER_URL = import.meta.env.VITE_SALLA_SERVER_URL || 'http://localhost:3001';
export interface SallaAuthStatus {
connected: boolean;

View File

@@ -1,11 +0,0 @@
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8090',
changeOrigin: true,
})
);
};

View File

@@ -11,12 +11,13 @@
"strictNullChecks": false,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"module": "ESNext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"types": ["vite/client"]
},
"include": ["src"]
}

18
vite.config.ts Normal file
View File

@@ -0,0 +1,18 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8090',
changeOrigin: true,
},
},
},
build: {
outDir: 'build',
},
});