ui selector

This commit is contained in:
2026-03-13 14:59:32 -03:00
parent ccc478fbaa
commit d5a3372d6b
7 changed files with 173 additions and 11 deletions

View File

@@ -95,10 +95,12 @@ services:
- "80:80" - "80:80"
volumes: volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./landing.html:/etc/nginx/landing.html:ro
depends_on: depends_on:
- django - django
- fastapi - fastapi
- timeline - timeline
- chunker
- minio - minio
# ============================================================================= # =============================================================================
@@ -162,6 +164,17 @@ services:
volumes: volumes:
- ../ui/timeline/src:/app/src - ../ui/timeline/src:/app/src
chunker:
build:
context: ../ui/chunker
dockerfile: Dockerfile
ports:
- "5174:5174"
environment:
VITE_ALLOWED_HOSTS: ${VITE_ALLOWED_HOSTS:-}
volumes:
- ../ui/chunker/src:/app/src
volumes: volumes:
postgres-data: postgres-data:
redis-data: redis-data:

107
ctrl/landing.html Normal file
View File

@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MPR</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
background: #0f0f0f;
color: #e0e0e0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
text-align: center;
max-width: 600px;
padding: 2rem;
}
h1 {
font-size: 2rem;
font-weight: 700;
letter-spacing: -0.02em;
margin-bottom: 0.5rem;
}
.subtitle {
color: #666;
font-size: 0.9rem;
margin-bottom: 2.5rem;
}
.cards {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
a.card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
padding: 2rem 1.5rem;
background: #141414;
border: 1px solid #2a2a2a;
border-radius: 12px;
text-decoration: none;
color: #e0e0e0;
transition: all 0.2s;
}
a.card:hover {
border-color: #3b82f6;
background: #1a1a2e;
transform: translateY(-2px);
}
.card-icon {
font-size: 2.5rem;
line-height: 1;
}
.card-title {
font-size: 1.1rem;
font-weight: 600;
}
.card-desc {
font-size: 0.75rem;
color: #666;
line-height: 1.4;
}
.links {
margin-top: 2rem;
display: flex;
gap: 1.5rem;
justify-content: center;
}
.links a {
color: #555;
font-size: 0.75rem;
text-decoration: none;
transition: color 0.2s;
}
.links a:hover { color: #94a3b8; }
</style>
</head>
<body>
<div class="container">
<h1>MPR</h1>
<p class="subtitle">Media Processing & Review</p>
<div class="cards">
<a class="card" href="/timeline/">
<div class="card-icon">&#9654;</div>
<div class="card-title">Timeline</div>
<div class="card-desc">Browse assets, trim, transcode</div>
</a>
<a class="card" href="/chunker/">
<div class="card-icon">&#9638;</div>
<div class="card-title">Chunker</div>
<div class="card-desc">Split media into segments, pipeline visualization</div>
</a>
</div>
<div class="links">
<a href="/admin/">Admin</a>
<a href="/api/graphql">GraphQL</a>
</div>
</div>
</body>
</html>

View File

@@ -21,6 +21,10 @@ http {
server timeline:5173; server timeline:5173;
} }
upstream chunker {
server chunker:5174;
}
upstream minio { upstream minio {
server minio:9000; server minio:9000;
} }
@@ -29,6 +33,12 @@ http {
listen 80; listen 80;
server_name mpr.local.ar; server_name mpr.local.ar;
# Landing page
location = / {
root /etc/nginx;
try_files /landing.html =404;
}
# Django Admin # Django Admin
location /admin { location /admin {
proxy_pass http://django; proxy_pass http://django;
@@ -54,7 +64,7 @@ http {
} }
# Timeline UI # Timeline UI
location /ui { location /timeline/ {
proxy_pass http://timeline; proxy_pass http://timeline;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@@ -62,8 +72,17 @@ http {
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
} }
# Vite HMR websocket # Chunker UI
location /@vite { location /chunker/ {
proxy_pass http://chunker;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Vite HMR websocket (timeline)
location /timeline/@vite {
proxy_pass http://timeline; proxy_pass http://timeline;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
@@ -71,6 +90,15 @@ http {
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# Vite HMR websocket (chunker)
location /chunker/@vite {
proxy_pass http://chunker;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# Media files - proxied from MinIO (local) or S3 (AWS) # Media files - proxied from MinIO (local) or S3 (AWS)
location /media/in/ { location /media/in/ {
proxy_pass http://minio/mpr-media-in/; proxy_pass http://minio/mpr-media-in/;
@@ -81,13 +109,5 @@ http {
proxy_pass http://minio/mpr-media-out/; proxy_pass http://minio/mpr-media-out/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
} }
# Default to Timeline UI
location / {
proxy_pass http://timeline;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
} }
} }

2
ui/chunker/.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
dist/

12
ui/chunker/Dockerfile Normal file
View File

@@ -0,0 +1,12 @@
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 5174
CMD ["npm", "run", "dev"]

View File

@@ -2,11 +2,15 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react"; import react from "@vitejs/plugin-react";
export default defineConfig({ export default defineConfig({
base: "/chunker/",
plugins: [react()], plugins: [react()],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
port: 5174, port: 5174,
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [], allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
hmr: {
path: "/chunker/@vite/client",
},
proxy: { proxy: {
"/api": { "/api": {
target: "http://fastapi:8702", target: "http://fastapi:8702",

View File

@@ -2,11 +2,15 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react"; import react from "@vitejs/plugin-react";
export default defineConfig({ export default defineConfig({
base: "/timeline/",
plugins: [react()], plugins: [react()],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
port: 5173, port: 5173,
allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [], allowedHosts: process.env.VITE_ALLOWED_HOSTS?.split(",") || [],
hmr: {
path: "/timeline/@vite/client",
},
proxy: { proxy: {
"/api": { "/api": {
target: "http://fastapi:8702", target: "http://fastapi:8702",