v1.4 - Login fixes, etc
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { api } from '$lib/api';
|
||||
import { clientSession } from '$lib/session';
|
||||
import { clientSession, sessionHydrated } from '$lib/session';
|
||||
import type { Mix, ProductCostBreakdown, RawMaterial } from '$lib/types';
|
||||
|
||||
type Segment = {
|
||||
@@ -42,7 +41,6 @@
|
||||
try {
|
||||
const session = await api.clientLogin(email, password);
|
||||
clientSession.set(session);
|
||||
await invalidateAll();
|
||||
} catch (error) {
|
||||
loginError = error instanceof Error ? error.message : 'Unable to sign in';
|
||||
} finally {
|
||||
@@ -253,7 +251,23 @@
|
||||
const focusCards = $derived(buildFocusCards());
|
||||
</script>
|
||||
|
||||
{#if !$clientSession}
|
||||
{#if !$sessionHydrated}
|
||||
<section class="dashboard-intro">
|
||||
<div>
|
||||
<p class="eyebrow">Client Workspace</p>
|
||||
<h2>Restoring your workspace.</h2>
|
||||
<p>Checking the saved client session before deciding whether sign-in is required.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="workspace-banner login-banner loading-banner">
|
||||
<div>
|
||||
<p class="eyebrow">Checking Session</p>
|
||||
<h3>Hold while the app restores your client access state.</h3>
|
||||
<p>The sign-in form only appears if no valid local session is available.</p>
|
||||
</div>
|
||||
</section>
|
||||
{:else if !$clientSession}
|
||||
<section class="dashboard-intro">
|
||||
<div>
|
||||
<p class="eyebrow">Client Workspace</p>
|
||||
@@ -515,7 +529,7 @@
|
||||
<tbody>
|
||||
{#each focusCards as card}
|
||||
<tr>
|
||||
<td class="task-cell">
|
||||
<td class="task-cell" data-label="Focus">
|
||||
<div class="table-item">
|
||||
<span class={`task-icon ${card.tone}`}>{card.code}</span>
|
||||
<div>
|
||||
@@ -524,19 +538,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td data-label="Owner">
|
||||
<div class="owner-chip">
|
||||
<span>HP</span>
|
||||
<strong>Hunter Premium Produce</strong>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td data-label="Reference Date">
|
||||
<div class="due-block">
|
||||
<strong>{card.detail}</strong>
|
||||
<span>Current checkpoint</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class={`status-chip ${card.tone}`}>{card.tone === 'warning' ? 'Watch' : 'On track'}</span></td>
|
||||
<td data-label="Status">
|
||||
<span class={`status-chip ${card.tone}`}>{card.tone === 'warning' ? 'Watch' : 'On track'}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
@@ -681,6 +697,10 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading-banner {
|
||||
min-height: 11rem;
|
||||
}
|
||||
|
||||
.signin-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
@@ -759,8 +779,10 @@
|
||||
|
||||
.dashboard-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.15fr) 0.72fr;
|
||||
grid-template-columns: minmax(0, 1.12fr) minmax(0, 1.02fr) minmax(16rem, 0.76fr);
|
||||
grid-template-areas: 'market gauge metrics';
|
||||
gap: 1rem;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.analysis-grid {
|
||||
@@ -775,6 +797,14 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.market-card {
|
||||
grid-area: market;
|
||||
}
|
||||
|
||||
.gauge-card {
|
||||
grid-area: gauge;
|
||||
}
|
||||
|
||||
.card-toolbar {
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
@@ -948,6 +978,7 @@
|
||||
}
|
||||
|
||||
.metric-stack {
|
||||
grid-area: metrics;
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
@@ -1130,6 +1161,7 @@
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
min-width: 46rem;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 0.7rem;
|
||||
}
|
||||
@@ -1293,11 +1325,29 @@
|
||||
}
|
||||
|
||||
@media (max-width: 1320px) {
|
||||
.workspace-banner,
|
||||
.dashboard-grid,
|
||||
.analysis-grid,
|
||||
.detail-grid,
|
||||
.workspace-banner {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.focus-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.dashboard-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-template-areas:
|
||||
'market gauge'
|
||||
'metrics metrics';
|
||||
}
|
||||
|
||||
.metric-stack {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1120px) {
|
||||
.analysis-grid,
|
||||
.detail-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -1306,6 +1356,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.dashboard-grid {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
'market'
|
||||
'gauge'
|
||||
'metrics';
|
||||
}
|
||||
|
||||
.metric-stack {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.focus-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.dashboard-intro,
|
||||
.intro-actions,
|
||||
@@ -1320,7 +1388,6 @@
|
||||
}
|
||||
|
||||
.preview-facts,
|
||||
.metric-stack,
|
||||
.signin-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@@ -1339,4 +1406,80 @@
|
||||
row-gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.workspace-banner,
|
||||
.panel-card,
|
||||
.preview-body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
table,
|
||||
thead,
|
||||
tbody,
|
||||
tr,
|
||||
td {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 0;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
tbody {
|
||||
display: grid;
|
||||
gap: 0.9rem;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
padding: 0.3rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 1rem;
|
||||
background: var(--panel-soft);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 0.78rem 0.8rem;
|
||||
white-space: normal;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
tbody td:first-child,
|
||||
tbody td:last-child {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
tbody td + td {
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
|
||||
tbody td::before {
|
||||
content: attr(data-label);
|
||||
display: block;
|
||||
margin-bottom: 0.35rem;
|
||||
color: var(--muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.task-cell {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.table-item,
|
||||
.owner-chip {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user