feat(portal): migrate V3 console to React 19 + Vite + TypeScript + Zustand + Tailwind v4
This commit is contained in:
1 parent
518f1e757e
commit
eae4596aa3
20 files changed
+4162
-3
No files matched your search
+21
-3
@@ -11,12 +11,14 @@ import subprocess
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
import mimetypes
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
PORT = int(os.environ.get("PORT", "3004"))
|
PORT = int(os.environ.get("PORT", "3004"))
|
||||||
BASE_DIR = Path(__file__).resolve().parent
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
|
DIST_DIR = BASE_DIR / "dist"
|
||||||
INDEX_FILE = BASE_DIR / "index.html"
|
INDEX_FILE = BASE_DIR / "index.html"
|
||||||
|
|
||||||
_cache = {"data": None, "ts": 0.0}
|
_cache = {"data": None, "ts": 0.0}
|
||||||
@@ -285,9 +287,25 @@ class PortalHandler(BaseHTTPRequestHandler):
|
|||||||
self._send_json(collect_telemetry())
|
self._send_json(collect_telemetry())
|
||||||
return
|
return
|
||||||
|
|
||||||
# Serve SPA index.html for root and any path
|
# Serve static assets from Vite build output (dist/) if available
|
||||||
if INDEX_FILE.exists():
|
clean_path = self.path.split("?", 1)[0].lstrip("/")
|
||||||
body = INDEX_FILE.read_bytes()
|
if clean_path and DIST_DIR.exists():
|
||||||
|
asset_file = (DIST_DIR / clean_path).resolve()
|
||||||
|
if str(asset_file).startswith(str(DIST_DIR.resolve())) and asset_file.is_file():
|
||||||
|
body = asset_file.read_bytes()
|
||||||
|
mime, _ = mimetypes.guess_type(str(asset_file))
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", mime or "application/octet-stream")
|
||||||
|
self.send_header("Cache-Control", "public, max-age=86400")
|
||||||
|
self.send_header("Content-Length", str(len(body)))
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(body)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Serve SPA index.html from dist/index.html (React+Vite build) or fallback index.html
|
||||||
|
spa_index = (DIST_DIR / "index.html") if (DIST_DIR / "index.html").exists() else INDEX_FILE
|
||||||
|
if spa_index.exists():
|
||||||
|
body = spa_index.read_bytes()
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-Type", "text/html; charset=utf-8")
|
self.send_header("Content-Type", "text/html; charset=utf-8")
|
||||||
self.send_header("Cache-Control", "no-cache")
|
self.send_header("Cache-Control", "no-cache")
|
||||||
|
|||||||
Reference in new issue
Block a user