feat(frontend)!: drop SetupWizardPage, backend URL via build-time VITE_*

Frontend no longer has any wizard flow. Backend URL is baked into the bundle
at build time via VITE_HF_BACKEND_BASE_URL (forwarded as a Dockerfile ARG
from compose).

- src/App.tsx: drop SetupWizardPage import + appState='setup' fallback +
  HF_WIZARD_PORT-via-localStorage probe. getApiBase() now reads
  import.meta.env.VITE_HF_BACKEND_BASE_URL with localStorage as an escape
  hatch for dev. When /config/status reports no admin yet, show a card
  prompting the operator to run `docker exec hf_backend hf-cli admin
  create-user ...`.
- src/pages/SetupWizardPage.tsx: deleted (~250 lines)
- src/index.css: drop .setup-wizard + .setup-* styles (~36 lines)
- src/vite-env.d.ts: add VITE_HF_BACKEND_BASE_URL to ImportMetaEnv
- Dockerfile: ARG VITE_HF_BACKEND_BASE_URL → ENV → npm run build

Build the prod image with:
  docker build --build-arg VITE_HF_BACKEND_BASE_URL=https://hf-api.hangman-lab.top \
    -t git.hangman-lab.top/zhi/harborforge-frontend:latest .

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
h z
2026-05-24 19:01:51 +01:00
parent 8e52e2bf74
commit 10771a8ffc
5 changed files with 71 additions and 372 deletions

View File

@@ -180,7 +180,7 @@ input, textarea, select, button { font-family: inherit; }
.sidebar-footer button:hover { border-color: var(--accent); color: var(--accent); }
/* ---- Login -------------------------------------------------------------- */
.login-page, .setup-wizard {
.login-page {
display: flex; align-items: center; justify-content: center;
min-height: 100vh; padding: 24px;
}
@@ -469,43 +469,6 @@ dd { font-size: .92rem; font-family: 'JetBrains Mono', monospace; }
.empty::after { content: ' —'; color: var(--accent); }
.text-dim { color: var(--text-dim); font-size: .82rem; }
/* ---- Setup Wizard ------------------------------------------------------- */
.setup-container {
position: relative; background: var(--bg-card); border: var(--hair);
border-radius: 6px; padding: 44px; max-width: 620px; width: 100%;
box-shadow: 0 40px 80px -30px rgba(0,0,0,.8);
animation: deck-in .55s cubic-bezier(.16,1,.3,1) both;
}
.setup-container::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px; background: var(--ember); border-radius: 6px 6px 0 0; }
.setup-header { text-align: center; margin-bottom: 34px; }
.setup-header h1 { font-size: 1.6rem; margin-bottom: 22px; letter-spacing: .1em; }
.setup-steps { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }
.setup-step {
font-size: .68rem; color: var(--text-dim); padding: 5px 12px; border-radius: 2px;
border: var(--hair); text-transform: uppercase; letter-spacing: .1em;
font-family: 'JetBrains Mono', monospace;
}
.setup-step.active { color: var(--accent); border-color: var(--accent); background: var(--ember-soft); }
.setup-step.done { color: var(--success); border-color: var(--success); }
.setup-step-content { animation: fadeIn .25s ease; }
.setup-step-content h2 { margin-bottom: 10px; font-size: 1.3rem; }
.setup-form { margin: 22px 0; }
.setup-nav { display: flex; justify-content: space-between; margin-top: 28px; }
.setup-nav button:disabled { opacity: .5; cursor: default; }
.setup-error {
background: rgba(226,85,60,.12); border: 1px solid var(--danger); color: var(--danger);
padding: 13px 16px; border-radius: var(--radius); margin-bottom: 18px;
font-size: .85rem; white-space: pre-line; font-family: 'JetBrains Mono', monospace;
}
.setup-info { background: rgba(86,198,214,.07); border: 1px solid rgba(86,198,214,.25); padding: 18px; border-radius: var(--radius); margin: 18px 0; }
.setup-info code {
display: block; background: var(--bg-sink); padding: 10px 13px; border-radius: 2px;
margin-top: 10px; font-size: .82rem; color: var(--steel); word-break: break-all;
}
.setup-hint { color: var(--warning); font-size: .82rem; margin-top: 8px; }
.setup-done { text-align: center; }
.setup-done h2 { color: var(--success); margin-bottom: 14px; }
/* ---- Monitor ------------------------------------------------------------ */
.monitor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 18px; margin-top: 14px; }
.monitor-card {