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>
DataTable: optional per-column width; when any column sets one, the table uses table-layout:fixed with a colgroup so columns keep a stable size instead of reflowing as rows are filtered (overflow clipped with ellipsis). Tables without widths keep auto layout. Projects: assign column widths; restore the original '(přiděleno automaticky)' suffix on the next-number hint.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After clicking the confirm button, it shows 'Zpracovávám…' (disabled) while the action is in flight — matching how the form modal shows 'Ukládám…'. The earlier freeze keeps it through the close fade (no flash back to the confirm label).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per request: the delete ConfirmDialog no longer shows the in-flight 'Pracuji…'/disabled state — button stays 'Smazat' and the dialog closes on success, consistent with the Vozidla delete. The kit ConfirmDialog still supports loading for callers that want it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds src/admin/pages/UiKit.tsx and registers a DEV-only <Route path="ui-kit">
sibling to <Route path="login">, outside the AdminLayout shell. The lazy import
uses the ternary `import.meta.env.DEV ? lazy(...) : null` pattern so Vite/Rolldown
evaluates the condition at build time and the UiKit chunk is entirely absent from
production bundles (confirmed: no UiKit-*.js in dist-client/assets after build:client).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The project create-modal start/end dates used raw <input type="date">;
converted to <AdminDatePicker> so every date field in the app now goes
through the shared component (react-datepicker on desktop, native on touch).
- AdminDatePicker now defaults its placeholder by mode (date 'dd.mm.rrrr',
month 'mm.rrrr', time 'hh:mm') so empty date fields always show a format
hint; explicit placeholders (e.g. 'Od'/'Do' range filters) still override.
- Dropped WarehouseReceiptForm's ad-hoc 'dd.mm.yyyy' so it inherits the
unified Czech default.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BulkAttendanceModal, ShiftFormModal, OrderConfirmationModal, DashQuickActions
trip modal, the Attendance leave modal, and DashProfile's 3 modals (edit
profile, 2FA setup, 2FA disable) now use the shared FormModal instead of
hand-rolled overlays, inheriting the canonical open/close animation, blurred
backdrop, ESC-to-close, click-outside, scroll-lock, staggered reveal, mobile
full-screen and reduced-motion. Footers stay pinned via the real FormModal
footer + submitDisabled; multi-step modals (2FA setup, order confirmation)
drive title/footer/close-guards per step. Behaviour preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror the create-modal fix on ProjectDetail: filter the 'Zodpovědná osoba'
select to active users (already scoped to projects.view), but keep the
project's currently-assigned user selectable even if inactive, labelled
'(neaktivní)', so the saved value still shows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The create-project modal's 'Zodpovědná osoba' select listed every user
(including inactive ones). Filter the query server-side by projects.view and
hide inactive users client-side.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds price/quantity fields (→ one line item) and a PDF attachment picker
to the manual-order create modal. Submit now uses apiFetch directly:
FormData (multipart) when a file is attached, JSON otherwise. Navigates
to the new order on success. Removes the old useApiMutation-based
createMutation; deleteMutation is untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirrors the Projects.tsx pattern: useQuery-driven customers + next-number
fetches (enabled only when modal is open), OrderCreatePayload type normalises
customer_id "" → null so the server's CreateOrderSchema never receives 0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mobile work-plan (Plán prací) responsive fixes — desktop unchanged:
- Toolbar stacks into clean full-width rows on ≤640px (nav group,
centered range label, full-width segmented view toggle, full-width
category button); drops the fixed 230px label min-width and the
margin-left:auto that made the toolbar ragged on phones.
- Grid scroll container: 100dvh-based max-height, momentum scroll, and
overscroll containment so a fling does not bounce the whole page.
- ≤480px tightens columns (date col 72px via the colgroup <col>, person
cols 132px) so ~2 people are comfortably visible at 360–390px.
- Touch (@media hover:none): faint persistent + on empty editable
cells, since the hover-reveal add hint never fires on a phone.
Dev: `npm run dev` (backend) now listens on 3050 instead of 3000 to
avoid colliding with other local apps; CLAUDE.md dev-port note updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11 form defaults across 6 files used new Date().toISOString().split('T')[0] (the UTC date), which lands on yesterday during the post-midnight Prague window (UTC+1/+2). Added todayLocalStr() (local YYYY-MM-DD) in formatters and replaced them. Future-date expressions (e.g. invoice due_date +14d) left untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- base.css: var(--danger-color) (undefined, no fallback -> inherited color) -> var(--danger)
- attendanceHelpers: re-export formatDate from formatters instead of a byte-identical copy
- dashboard.ts: remove dead duplicate require2FAOptions (canonical copy is in settings.ts)
- settings.ts: remove unused @deprecated systemSettingsOptions alias
- PlanWork: drop redundant per-page plan.css import (loaded globally in AdminApp)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Audit Log + dashboard feed used legacy keys (invoices_invoice, offers_quotation, trips, vehicles) that never matched the server's entity_type (invoice, quotation, trip, vehicle, ...) and omitted all warehouse_* entities, so many audit rows showed raw English. Single source of truth in lib/entityTypeLabels.ts, keyed to the actual EntityType values, with Czech labels for every type the server writes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- AttendanceAdmin: declare worked_hours_raw on UserTotalData (the hook sets it at runtime; the local interface omitted it)
- usePlanWork.rollbackMutation: type the mutation param as unknown + explicit cast so passing the TanStack mutation result (with the dynamically-stashed _rolled) no longer trips the weak-type check
tsc -p tsconfig.app.json --noEmit is now clean (0 errors, was 9).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace 14 hardcoded per-category CSS rules with a single --cat-color
custom property set inline on each filled cell button, driven by the DB
categories list threaded from PlanWork → PlanGrid → PlanRangeChips.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Work-plan fixes from this session:
- Czech audit descriptions for plan entries/overrides (was empty '-')
- server-embedded project label on grid cells (was '-' past the 100-project cap)
- dashboard activity + audit-log cache invalidation on plan mutations
- read-only cells: no '+' on empty, keep hover on cells with a record
- view modal: Czech category + formatted dates
- sticky date column made opaque (no bleed-through on horizontal scroll)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>