tweaks
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { clientSession, hasModuleAccess } from '$lib/session';
|
||||
import type { MixCalculatorSession } from '$lib/types';
|
||||
import { featureFlags } from '$lib/features';
|
||||
import MixCalculatorEditor from '$lib/components/mix-calculator/MixCalculatorEditor.svelte';
|
||||
import type { MixCalculatorOptions, MixCalculatorSession } from '$lib/types';
|
||||
|
||||
let { data }: { data: { sessions: MixCalculatorSession[] } } = $props();
|
||||
let { data }: { data: { sessions?: MixCalculatorSession[]; options?: MixCalculatorOptions } } =
|
||||
$props();
|
||||
|
||||
const sessions = $derived(data.sessions ?? []);
|
||||
const canEdit = $derived(hasModuleAccess($clientSession, 'mix_calculator', 'edit'));
|
||||
|
||||
function formatDate(value: string) {
|
||||
@@ -18,6 +22,9 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if !featureFlags.mixCalculatorSessionHistory}
|
||||
<MixCalculatorEditor options={data.options} />
|
||||
{:else}
|
||||
{#if canEdit}
|
||||
<section class="page-actions">
|
||||
<a class="primary-button" href="/mix-calculator/new">New mix session</a>
|
||||
@@ -27,17 +34,17 @@
|
||||
<section class="metric-row">
|
||||
<article class="metric-card">
|
||||
<span>Saved Sessions</span>
|
||||
<strong>{data.sessions.length}</strong>
|
||||
<strong>{sessions.length}</strong>
|
||||
<p>Visible under your access scope</p>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<span>Total Planned Kg</span>
|
||||
<strong>{formatNumber(data.sessions.reduce((sum, session) => sum + session.total_kg, 0), 2)}</strong>
|
||||
<strong>{formatNumber(sessions.reduce((sum, session) => sum + session.total_kg, 0), 2)}</strong>
|
||||
<p>Across the visible history</p>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<span>Sessions With Warnings</span>
|
||||
<strong>{data.sessions.filter((session) => session.warnings.length).length}</strong>
|
||||
<strong>{sessions.filter((session) => session.warnings.length).length}</strong>
|
||||
<p>Fractional bag outputs need review</p>
|
||||
</article>
|
||||
</section>
|
||||
@@ -50,7 +57,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if data.sessions.length}
|
||||
{#if sessions.length}
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -65,7 +72,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.sessions as session}
|
||||
{#each sessions as session}
|
||||
<tr>
|
||||
<td data-label="Session">
|
||||
<strong>{session.session_number}</strong>
|
||||
@@ -102,6 +109,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
h2,
|
||||
@@ -140,10 +148,24 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.78rem 0.96rem;
|
||||
border-radius: 0.9rem;
|
||||
border-radius: 0.6rem;
|
||||
background: var(--color-brand);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
transition: background-color 160ms ease;
|
||||
}
|
||||
|
||||
.primary-button:hover {
|
||||
background: #126a33;
|
||||
}
|
||||
|
||||
.primary-button:active {
|
||||
background: #0f5a2b;
|
||||
}
|
||||
|
||||
.primary-button:focus-visible {
|
||||
outline: 3px solid color-mix(in srgb, var(--color-brand) 45%, transparent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.metric-row {
|
||||
@@ -155,7 +177,7 @@
|
||||
.metric-card,
|
||||
.table-card {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 1.3rem;
|
||||
border-radius: 0.8rem;
|
||||
background: var(--panel);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
@@ -222,12 +244,12 @@
|
||||
|
||||
tbody td:first-child {
|
||||
border-left: 1px solid var(--line);
|
||||
border-radius: 1rem 0 0 1rem;
|
||||
border-radius: 0.65rem 0 0 0.65rem;
|
||||
}
|
||||
|
||||
tbody td:last-child {
|
||||
border-right: 1px solid var(--line);
|
||||
border-radius: 0 1rem 1rem 0;
|
||||
border-radius: 0 0.65rem 0.65rem 0;
|
||||
}
|
||||
|
||||
.row-actions {
|
||||
@@ -245,8 +267,8 @@
|
||||
margin-left: 0.55rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
background: #fff6e6;
|
||||
color: #8b5b1e;
|
||||
background: #fdf6e9;
|
||||
color: #8a5a00;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
@@ -257,7 +279,7 @@
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
border-radius: 0.65rem;
|
||||
background: var(--panel-soft);
|
||||
}
|
||||
|
||||
@@ -299,7 +321,7 @@
|
||||
tbody tr {
|
||||
padding: 0.3rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 1rem;
|
||||
border-radius: 0.65rem;
|
||||
background: var(--panel-soft);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,35 @@ import { redirect } from '@sveltejs/kit';
|
||||
import { api } from '$lib/api';
|
||||
import { featureFlags } from '$lib/features';
|
||||
import { getStoredClientSession, hasModuleAccess, hasStoredClientSession } from '$lib/session';
|
||||
import { canOpenMixCalculator, getWorkspaceHomeHref } from '$lib/workspace-access';
|
||||
import { canCreateMixSession, canOpenMixCalculator, getWorkspaceHomeHref } from '$lib/workspace-access';
|
||||
|
||||
export async function load({ fetch }) {
|
||||
// Single-page mode (session history disabled): this route IS the calculator.
|
||||
if (!featureFlags.mixCalculatorSessionHistory) {
|
||||
throw redirect(307, '/mix-calculator/new');
|
||||
if (!hasStoredClientSession()) {
|
||||
return { options: { clients: [], products: [] } };
|
||||
}
|
||||
|
||||
const session = getStoredClientSession();
|
||||
if (!canCreateMixSession(session)) {
|
||||
throw redirect(307, getWorkspaceHomeHref(session));
|
||||
}
|
||||
|
||||
try {
|
||||
return {
|
||||
options:
|
||||
hasModuleAccess(session, 'mix_calculator', 'edit') || session?.role === 'internal'
|
||||
? await api.mixCalculatorOptions(fetch)
|
||||
: { clients: [], products: [] }
|
||||
};
|
||||
} catch {
|
||||
return { options: { clients: [], products: [] } };
|
||||
}
|
||||
}
|
||||
|
||||
// History mode: list saved sessions.
|
||||
if (!hasStoredClientSession()) {
|
||||
return {
|
||||
sessions: []
|
||||
};
|
||||
return { sessions: [] };
|
||||
}
|
||||
|
||||
const session = getStoredClientSession();
|
||||
@@ -22,11 +40,12 @@ export async function load({ fetch }) {
|
||||
|
||||
try {
|
||||
return {
|
||||
sessions: hasModuleAccess(session, 'mix_calculator') || session?.role === 'internal' ? await api.mixCalculatorSessions(fetch) : []
|
||||
sessions:
|
||||
hasModuleAccess(session, 'mix_calculator') || session?.role === 'internal'
|
||||
? await api.mixCalculatorSessions(fetch)
|
||||
: []
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
sessions: []
|
||||
};
|
||||
return { sessions: [] };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{#if featureFlags.mixCalculatorSessionHistory}
|
||||
<a class="secondary-button" href="/mix-calculator">Back to session history</a>
|
||||
{:else}
|
||||
<a class="secondary-button" href="/mix-calculator/new">New mix session</a>
|
||||
<a class="secondary-button" href="/mix-calculator">New mix session</a>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
@@ -38,7 +38,7 @@
|
||||
max-width: 42rem;
|
||||
padding: 1.25rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 1.25rem;
|
||||
border-radius: 0.8rem;
|
||||
background: var(--panel);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
@@ -58,7 +58,7 @@
|
||||
margin-top: 1rem;
|
||||
padding: 0.78rem 0.92rem;
|
||||
border: 1px solid var(--line-strong);
|
||||
border-radius: 0.88rem;
|
||||
border-radius: 0.6rem;
|
||||
background: #fff;
|
||||
color: #304038;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{#if featureFlags.mixCalculatorSessionHistory}
|
||||
<a class="secondary-button" href="/mix-calculator">Back to session history</a>
|
||||
{:else}
|
||||
<a class="secondary-button" href="/mix-calculator/new">New mix session</a>
|
||||
<a class="secondary-button" href="/mix-calculator">New mix session</a>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user