feat(shift): current shift in the list + modal actions; full-width layout everywhere
Shift screen: - The standalone ShiftControl block is gone from /shift. The open/CURRENT shift now appears at the TOP of the shift list (CURRENT badge, live figures synthesized from the X-report), unified with history. Selecting it shows its live activity log. - Shift ACTIONS moved into the current shift's detail pane, each opening a MODAL: End shift (confirm → signed Z-report result), drawer voucher (Mandat in/out), takings-so-far (X-report). When no shift is open, a Start-shift button shows. - The current shift's log auto-refreshes (5s); a closed shift is bounded by its window. /setup/shifts stays read-only history (no manage props). Deleted the now- orphaned ShiftControl.tsx. Layout: - Every screen is now full-width like /booth — stripped the per-screen `mx-auto max-w-*` caps (Logs, Subscriptions, Plans, Tariff, Users, Roles, Setup layout, Shifts). The shell <main> already provides padding. Build+lint 12/12 (i18n parity). Verified a live open shift surfaces as the CURRENT list entry. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
+10
-13
@@ -24,7 +24,6 @@ import { TariffComposer } from "./TariffComposer.js";
|
||||
import { TariffLab } from "./TariffLab.js";
|
||||
import { SubscriptionManager } from "./SubscriptionManager.js";
|
||||
import { SubscriptionPlansManager } from "./SubscriptionPlansManager.js";
|
||||
import { ShiftControl } from "./ShiftControl.js";
|
||||
import { SiteSettings } from "./SiteSettings.js";
|
||||
import { UsersManager } from "./UsersManager.js";
|
||||
import { RolesManager } from "./RolesManager.js";
|
||||
@@ -78,7 +77,7 @@ function SetupLayout() {
|
||||
const { t } = useTranslation();
|
||||
const show = (perm: Permission) => can(user, perm);
|
||||
return (
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<div className="">
|
||||
<nav className="mb-4 flex flex-wrap items-center gap-1 border-b border-term-border">
|
||||
{show("site:update") && <SetupTab to="/setup" label={t("nav.devices")} exact />}
|
||||
{show("tariff:read") && <SetupTab to="/setup/tariff" label={t("nav.tariff")} />}
|
||||
@@ -344,18 +343,16 @@ const shiftRoute = createRoute({
|
||||
path: "/shift",
|
||||
component: function ShiftRoute() {
|
||||
const { user } = rootRoute.useRouteContext();
|
||||
// Top: the shift CONTROL (open/close, drawer vouchers, X-report). The drawer-voucher
|
||||
// form is operator-RAISED (shift:create); an admin authorizes with their password.
|
||||
// Below: the shift LIST + per-shift activity log (scoped server-side by permission).
|
||||
// The shift hub: list (current/open shift on top + history) + per-shift activity log.
|
||||
// The CURRENT shift's pane carries the actions (open/close, drawer voucher, takings),
|
||||
// each opening a modal. `canManage` = shift:create (start/end + raise vouchers); a
|
||||
// voucher additionally needs an admin's password sign-off server-side.
|
||||
return (
|
||||
<div className="mx-auto max-w-6xl px-4 py-4">
|
||||
<ShiftControl canVoucher={can(user, "shift:create")} />
|
||||
{can(user, "shift:read") && (
|
||||
<div className="mt-6">
|
||||
<ShiftsHistory user={user} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ShiftsHistory
|
||||
user={user}
|
||||
canManage={can(user, "shift:create")}
|
||||
canVoucher={can(user, "shift:create")}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user