AuditLog uses a raw useQuery with the filters in the queryKey and a page-level early return (if isPending && no rows → <LoadingState/>), which sits ABOVE <PageEnter>. On any filter change the new queryKey had no cached data, so isPending flipped true with empty rows, the early return unmounted the whole PageEnter subtree, and it remounted (replaying the staggered entrance) when data arrived. Add placeholderData: keepPreviousData so rows persist through the refetch (isPending stays false, subtree never unmounts), and dim the table via isFetching instead of isPending. Verified by DOM node-identity: the PageEnter root survives a filter (no remount). The paginated list pages were already immune (usePaginatedQuery bakes in keepPreviousData).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The kit CheckboxField (used on most pages) renders MUI's default medium checkbox, but four raw <Checkbox> usages forced size="small": OfferDetail's 'V ceně' table cell and 'Účtovat DPH' form checkbox, and the Settings permission-matrix module + per-permission checkboxes. They looked undersized next to the rest of the page. Removing size="small" makes every checkbox the same standard size app-wide.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The project-number column was plain text and the Objednávka link was colored text.secondary (grey/black). Make the number a RouterLink to /projects/:id and recolor the order link to primary.main, so both match the red table-link convention used on Offers/Orders/Invoices.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every list-page FilterBar now follows one spec: bare controls (no Field label rows — which broke flex-end alignment), standardized widths (search 1 1 320px grows; small selects 0 0 160px; entity selects 0 0 220px; MonthField 0 0 180px; dates 0 0 150px), consistent 'Všechny/Všichni/Všechna <entity>' defaults, and a placeholder on every search. TripsAdmin's separate month-Select + year-Select collapse into one MonthField (yyyy-MM, split at the query boundary) — matching Attendance/TripsHistory. The 4 labeled attendance/trips pages move off the Field wrapper; Projects & ReceivedInvoices move their inline search into a FilterBar. Chrome-verified all ~18 filter pages in light + the existing theme.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The customer Select was wrapped in <Field label> while the search was bare, so in the flex-end FilterBar the Field's label + mb:2 pushed the select ~16px above the search input. Drop the Field wrapper (matching the bare list-page filter pattern used on AuditLog/Warehouse/Orders) and make the default option self-describing ("Všichni zákazníci"). Both controls now sit on the same line.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The PageEnter sweep had replaced the left grid column's wrapper with a React Fragment, so its two cards (clock + completed shifts) leaked out as separate grid items and the layout broke (shifts table jumped to the right cell, stat box wrapped to row 2). Wrap the left column back in a <Box> so the 2-col grid has exactly two column children again.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adopt the PageEnter wrapper as every page's outermost render element and remove the ad-hoc per-page entrance motion.div wrappers. Every page now enters the same way — all top-level sections rise+fade in, staggered — so nothing appears instantly and the motion is identical app-wide. Presentation-only: no data/logic/hooks/invalidate/permissions touched. Embedded sub-tabs (CompanySettings, ReceivedInvoices), Login (auth shell) and the dev UiKit are intentionally excluded. Gates: tsc -b --noEmit=0, build=0, vitest 152/152.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each top-level child rises+fades in, staggered (0.4s, ease-out), so every page enters the same way and nothing appears instantly; honors prefers-reduced-motion. Replaces ad-hoc per-page motion.div entrance wrappers. One component → the look is tunable in one place.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace legacy admin-empty-state/admin-empty-icon/admin-btn markup and motion
wrapper with a centered MUI Box + Typography (h1 variant for 404 heading,
body1 for message) and a kit Button component={RouterLink}. All text and link
target ('/') preserved verbatim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace legacy admin-* markup (motion.div header, admin-card, admin-table,
WarehouseMovementTable, LocationSelect, admin-form-input) with Box/Typography/
IconButton from @mui/material and Button/Card/TextField/Select/Field from the
kit. Item rows are inlined (grid) matching the receipt/issue form siblings.
All data logic (useQuery, useApiMutation, validate, handleSubmit, navigate,
hasPermission guard, Czech alerts) preserved verbatim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces admin-* CSS, ConfirmModal, and legacy markup with PageHeader,
Card, DataTable, ConfirmDialog, StatusChip, EmptyState, LoadingState.
Dual StatusChip badges per row: leave-type (info/error/default) and
status (warning/success/error/default). Note cell preserved with Box
title-tooltip and ellipsis truncation. cancelMutation and invalidate:
["leave-requests", "leave", "attendance"] preserved verbatim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace legacy admin-* CSS, FormModal, ConfirmModal, FormField, and
framer-motion wrappers with PageHeader, Card, DataTable, Modal,
ConfirmDialog, Field, TextField, EmptyState, LoadingState, and MUI
IconButton. All data logic preserved verbatim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>