Polish results, FPP, and auth UI
This commit is contained in:
59
server.js
59
server.js
@@ -687,7 +687,7 @@ function renderResultsTable(results, selectedResultId) {
|
||||
(result) => `
|
||||
<tr>
|
||||
<td><strong>${escapeHtml(result.patient)}</strong><br /><span class="muted">${escapeHtml(result.summary)}</span></td>
|
||||
<td><a href="/results/${result.id}">${escapeHtml(result.id)}</a></td>
|
||||
<td><a href="/results/${result.id}" hx-get="/fragments/results/detail/${result.id}" hx-target="#result-detail-fragment" hx-swap="innerHTML">${escapeHtml(result.id)}</a></td>
|
||||
<td>${escapeHtml(result.test)}</td>
|
||||
<td>${statusBadge(result.status)}</td>
|
||||
<td>${escapeHtml(result.date)}</td>
|
||||
@@ -710,6 +710,8 @@ function renderResultsTable(results, selectedResultId) {
|
||||
</div>
|
||||
${statusBadge(result.status)}
|
||||
</div>
|
||||
<div style="height:12px"></div>
|
||||
<a class="btn btn-secondary" href="/results/${result.id}" hx-get="/fragments/results/detail/${result.id}" hx-target="#result-detail-fragment" hx-swap="innerHTML">Open detail</a>
|
||||
<p class="muted" style="margin-top:10px">${escapeHtml(result.summary)}</p>
|
||||
</article>
|
||||
`,
|
||||
@@ -717,7 +719,7 @@ function renderResultsTable(results, selectedResultId) {
|
||||
.join("")}
|
||||
</div>
|
||||
</section>
|
||||
<aside class="panel">
|
||||
<aside class="panel" id="result-detail-fragment">
|
||||
${panelHeader("Selected result", "Use the right pane for quick context without losing list position.", `<a class="btn btn-secondary" href="/results/${selected.id}">Open detail</a>`)}
|
||||
<div class="stack">
|
||||
<div class="card">
|
||||
@@ -766,7 +768,20 @@ function renderFpp(groups) {
|
||||
${panelHeader("FPP catalog", "Filter blocks and list cards on mobile, richer panel on desktop.")}
|
||||
<div class="pill-row">
|
||||
${["All", ...mockFppGroups.map((item) => item.group)]
|
||||
.map((item) => `<a class="pill ${groups.filter === item ? "active" : ""}" href="/fragments/fpp/list?group=${encodeURIComponent(item)}">${escapeHtml(item)}</a>`)
|
||||
.map(
|
||||
(item) => `
|
||||
<button
|
||||
class="pill ${groups.filter === item ? "active" : ""}"
|
||||
type="button"
|
||||
hx-get="/fragments/fpp/list?group=${encodeURIComponent(item)}"
|
||||
hx-target="#fpp-fragment"
|
||||
hx-swap="innerHTML"
|
||||
hx-push-url="true"
|
||||
>
|
||||
${escapeHtml(item)}
|
||||
</button>
|
||||
`,
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
</section>
|
||||
@@ -916,12 +931,21 @@ function loginPage({ error = "" } = {}) {
|
||||
<section class="auth-card">
|
||||
<div class="auth-visual">
|
||||
<div class="badge">DocLink rebuild · responsive shell</div>
|
||||
<h1>Clinical workflow that works on desktop and mobile.</h1>
|
||||
<p>The old app behavior is preserved in a cleaner layout with dashboard, orders, results, FPP, and settings routes.</p>
|
||||
<h1>Clinical workflow that stays fast on desktop and mobile.</h1>
|
||||
<p>The rebuilt shell keeps the old app's workflows intact, but removes the cramped mobile-only feel.</p>
|
||||
<div class="auth-highlight">
|
||||
<strong>Built for doctors who move between screens</strong>
|
||||
<span>Orders, results, FPP, and account actions stay one click away.</span>
|
||||
</div>
|
||||
<div class="auth-points">
|
||||
<div class="auth-point"><strong>Route structure</strong><div>Login, dashboard, order flow, result flow, and account pages.</div></div>
|
||||
<div class="auth-point"><strong>Responsive shell</strong><div>Persistent sidebar on desktop, bottom nav on mobile.</div></div>
|
||||
<div class="auth-point"><strong>Clean interaction model</strong><div>HTMX fragments plus server-rendered templates.</div></div>
|
||||
<div class="auth-point"><strong>HTMX fragments</strong><div>Detail panels update without leaving the page.</div></div>
|
||||
<div class="auth-point"><strong>API adapter</strong><div>Login, orders, results, and save flows proxy upstream.</div></div>
|
||||
</div>
|
||||
<div class="auth-mini-grid">
|
||||
<div class="auth-mini-card"><strong>5 routes</strong><span>Public + shell</span></div>
|
||||
<div class="auth-mini-card"><strong>3 flows</strong><span>Most used actions</span></div>
|
||||
<div class="auth-mini-card"><strong>1 session</strong><span>Cookie-backed auth</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-form">
|
||||
@@ -940,6 +964,7 @@ function loginPage({ error = "" } = {}) {
|
||||
<div class="pill-row">
|
||||
<a class="pill" href="/splash">Open splash</a>
|
||||
<a class="pill" href="/problem-login">Problem login</a>
|
||||
<span class="pill">Demo fallback ready</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -958,12 +983,20 @@ function splashPage() {
|
||||
<div class="auth-visual">
|
||||
<div class="badge">Starting DocLink</div>
|
||||
<h1>Loading workspace...</h1>
|
||||
<p>Checking session and routing into the right entry point.</p>
|
||||
<p>Checking session state, then routing into the right clinical entry point.</p>
|
||||
<div class="auth-highlight">
|
||||
<strong>Fast redirect</strong>
|
||||
<span>Users land on dashboard, login, or the error screen without extra clicks.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-form">
|
||||
<div class="empty-state">
|
||||
<strong>Redirecting</strong>
|
||||
<p>We will move you to the correct route in a moment.</p>
|
||||
<div class="pill-row" style="justify-content:center; margin-top:14px">
|
||||
<span class="pill">Session check</span>
|
||||
<span class="pill">Route resolve</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -982,7 +1015,11 @@ function problemLoginPage() {
|
||||
<div class="auth-visual">
|
||||
<div class="badge">Login problem</div>
|
||||
<h1>Access needs attention.</h1>
|
||||
<p>Use this page when auth state is broken or a session expires.</p>
|
||||
<p>Use this page when auth state is broken, expired, or the upstream login rejects credentials.</p>
|
||||
<div class="auth-highlight">
|
||||
<strong>What to do</strong>
|
||||
<span>Re-enter credentials or wait for the upstream service to recover.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-form">
|
||||
<div class="empty-state">
|
||||
@@ -990,6 +1027,10 @@ function problemLoginPage() {
|
||||
<p>The session was cleared. Go back to login and sign in again.</p>
|
||||
<div style="height:16px"></div>
|
||||
<a class="btn btn-primary" href="/login">Back to login</a>
|
||||
<div class="pill-row" style="justify-content:center; margin-top:14px">
|
||||
<span class="pill">Auth reset</span>
|
||||
<span class="pill">Retry login</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
54
styles.css
54
styles.css
@@ -734,6 +734,52 @@ tr:last-child td {
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.auth-highlight {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
margin-top: 18px;
|
||||
padding: 16px 18px;
|
||||
border-radius: 18px;
|
||||
color: #effaf8;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
|
||||
.auth-highlight strong {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.auth-highlight span {
|
||||
line-height: 1.55;
|
||||
opacity: 0.94;
|
||||
}
|
||||
|
||||
.auth-mini-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.auth-mini-card {
|
||||
padding: 14px 15px;
|
||||
border-radius: 18px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.auth-mini-card strong {
|
||||
display: block;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.auth-mini-card span {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
opacity: 0.86;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.auth-form h2 {
|
||||
margin: 0;
|
||||
font-size: 1.9rem;
|
||||
@@ -823,6 +869,10 @@ tr:last-child td {
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.modal-card .panel-header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.desktop-only {
|
||||
display: block;
|
||||
}
|
||||
@@ -908,6 +958,10 @@ tr:last-child td {
|
||||
max-height: 100vh;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.auth-mini-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 620px) {
|
||||
|
||||
Reference in New Issue
Block a user