From 24ac3ac0584ae6e3db5c8e0f0a351b89d626c3d8 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 May 2026 04:00:33 +0000 Subject: [PATCH] =?UTF-8?q?ui:=20echte=20Mobile-First-Variante=20=E2=80=94?= =?UTF-8?q?=20Recording-Hero,=20Job-Cards,=20Admin-Klappe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile-Layout ab <700px komplett umgebaut, nicht mehr nur Desktop-Verkleinerung: - Header: nur Logo + User + Profil-Mini-Dropdown + Logout - Upload-Card: großer roter Aufnahme-Button als Hero-Element - Profil und Titel darunter, kompakt - Datei-Upload in
-Klappe (auf Desktop offen, Mobile zu) - Jobs: Card-Liste statt Tabelle (Tabelle nur Desktop, Cards nur Mobile) - Admin: H2 als Toggle, Body kollabiert (auf Desktop immer offen) - Inputs auf Mobile mit font-size:16px → kein iOS-Zoom-on-Focus - Recording-Pane: Timer 64px, Buttons full-width - safe-area-inset für iPhone-Notch + Bottom-Bar Ohne JS-Mode-Switch — alles via CSS Media Query + .desktop-only / .mobile-only Helfer-Klassen. JS rendert beide Job-Repräsentationen, CSS schaltet die richtige sichtbar. --- lxc-frontend/app/static/app.js | 55 +++++++- lxc-frontend/app/static/index.html | 78 +++++++----- lxc-frontend/app/static/style.css | 198 +++++++++++++++++++++++------ 3 files changed, 260 insertions(+), 71 deletions(-) diff --git a/lxc-frontend/app/static/app.js b/lxc-frontend/app/static/app.js index 719bd9d..d4e9d55 100644 --- a/lxc-frontend/app/static/app.js +++ b/lxc-frontend/app/static/app.js @@ -37,6 +37,10 @@ const defaultProfileName = document.getElementById("default-profile-name"); const headerProfileWrap = document.getElementById("header-profile-wrap"); const headerProfile = document.getElementById("header-profile"); +const jobsCards = document.getElementById("jobs-cards"); +const adminToggle = document.getElementById("admin-toggle"); +const adminCollapsible = document.getElementById("admin-card"); + const recordToggle = document.getElementById("record-toggle"); const recordToggleLabel = document.getElementById("record-toggle-label"); const recordPane = document.getElementById("record-pane"); @@ -302,6 +306,43 @@ function row(job) { return tr; } +function card(job) { + const div = document.createElement("div"); + div.className = "jc"; + const title = job.title || job.original_name; + const showProfileTag = availableProfiles.length > 1 || (job.profile && job.profile !== "meeting"); + const profileTag = showProfileTag + ? `${escapeHtml(profileLabelOf(job.profile || "meeting"))}` + : ""; + const ownerLine = currentUser?.is_admin && job.owner_username + ? `
von ${escapeHtml(job.owner_username)}
` : ""; + + const dlButtons = DOWNLOADS.map(({ kind, label, title: tip }) => { + const dis = !job.has[kind]; + const href = dis ? "" : `href="/api/jobs/${job.id}/download/${kind}"`; + return `${label}`; + }).join(""); + + div.innerHTML = ` +
+
+
${escapeHtml(title)} ${profileTag}
+
${escapeHtml(job.original_name)} · #${job.id}
+ ${ownerLine} +
+ ${escapeHtml(job.status)} +
+
+
+ ${job.progress}% +
+ ${job.error ? `
${escapeHtml(job.error)}
` : ""} +
aktualisiert: ${escapeHtml(fmtDate(job.updated_at))}
+
${dlButtons}
+ `; + return div; +} + async function loadJobs() { if (!currentUser) return; try { @@ -309,11 +350,16 @@ async function loadJobs() { if (r.status === 401) { showAuth("login"); return; } const jobs = await r.json(); jobsBody.innerHTML = ""; + jobsCards.innerHTML = ""; if (!jobs.length) { jobsBody.innerHTML = 'Noch keine Jobs.'; + jobsCards.innerHTML = '
Noch keine Jobs.
'; return; } - jobs.forEach((j) => jobsBody.appendChild(row(j))); + jobs.forEach((j) => { + jobsBody.appendChild(row(j)); + jobsCards.appendChild(card(j)); + }); } catch (e) { console.error(e); } @@ -613,6 +659,13 @@ recPauseBtn.addEventListener("click", pauseRecording); recStopBtn.addEventListener("click", stopRecording); recordDiscardBtn.addEventListener("click", discardRecording); +// Admin-Toggle (klappbar auf Mobile, immer offen auf Desktop) +adminToggle.addEventListener("click", () => { + if (window.matchMedia("(max-width: 700px)").matches) { + adminCollapsible.classList.toggle("open"); + } +}); + // ─── Init ────────────────────────────────────────────────────────────────── bootstrap(); checkMac(); diff --git a/lxc-frontend/app/static/index.html b/lxc-frontend/app/static/index.html index 58eeb39..0bf8f40 100644 --- a/lxc-frontend/app/static/index.html +++ b/lxc-frontend/app/static/index.html @@ -19,17 +19,17 @@

Voice-Agent

-

Sitzungsaufnahmen automatisch transkribieren und protokollieren

+

Sitzungsaufnahmen automatisch transkribieren und protokollieren

-
Mac-Backend: prüfe …
+
Mac-Backend: prüfe …
-
-

Neue Aufnahme hochladen

+
+

Neue Aufnahme hochladen

- - -
- -
— oder —
- -
+ + +
+ + +
+ + +
+ + +
+ Lieber eine vorhandene Audio-Datei hochladen? + +
+