diff --git a/src/admin/ui/ProgressBar.tsx b/src/admin/ui/ProgressBar.tsx new file mode 100644 index 0000000..6d3c4b8 --- /dev/null +++ b/src/admin/ui/ProgressBar.tsx @@ -0,0 +1,34 @@ +import LinearProgress from "@mui/material/LinearProgress"; +import Box from "@mui/material/Box"; + +export type ProgressColor = + | "primary" + | "success" + | "warning" + | "error" + | "info"; + +/** Determinate linear progress bar. `value` is 0–100 (clamped). */ +export default function ProgressBar({ + value, + color = "primary", + height = 8, +}: { + value: number; + color?: ProgressColor; + height?: number; +}) { + const clamped = Number.isFinite(value) + ? Math.max(0, Math.min(100, value)) + : 0; + return ( + + + + ); +} diff --git a/src/admin/ui/TimeField.tsx b/src/admin/ui/TimeField.tsx new file mode 100644 index 0000000..285ce88 --- /dev/null +++ b/src/admin/ui/TimeField.tsx @@ -0,0 +1,38 @@ +import { TimePicker } from "@mui/x-date-pickers/TimePicker"; +import { parse, format, isValid } from "date-fns"; + +// Fixed reference date — only the time part matters for parse/format round-trips. +const REF = new Date(2000, 0, 1); + +/** + * Time input over MUI X TimePicker. String in / string out ("HH:mm", or ""), + * 24-hour, configurable minute step (default 5) — matches the legacy + * AdminDatePicker mode="time". cs locale comes from MuiProvider's + * LocalizationProvider. + */ +export default function TimeField({ + value, + onChange, + label, + disabled, + minutesStep = 5, +}: { + value: string; + onChange: (value: string) => void; + label?: string; + disabled?: boolean; + minutesStep?: number; +}) { + const parsed = value ? parse(value, "HH:mm", REF) : null; + return ( + onChange(d && isValid(d) ? format(d, "HH:mm") : "")} + slotProps={{ textField: { size: "small", fullWidth: true } }} + /> + ); +} diff --git a/src/admin/ui/index.ts b/src/admin/ui/index.ts index 9299a89..25ca0de 100644 --- a/src/admin/ui/index.ts +++ b/src/admin/ui/index.ts @@ -17,6 +17,7 @@ export type { TabDef } from "./Tabs"; export { default as Pagination } from "./Pagination"; export { default as DateField } from "./DateField"; export { default as MonthField } from "./MonthField"; +export { default as TimeField } from "./TimeField"; export { default as PageHeader } from "./PageHeader"; export { default as EmptyState } from "./EmptyState"; export { default as LoadingState } from "./LoadingState"; @@ -24,3 +25,5 @@ export { default as FilterBar } from "./FilterBar"; export { default as StatCard } from "./StatCard"; export type { StatCardColor } from "./StatCard"; export { default as FileUpload } from "./FileUpload"; +export { default as ProgressBar } from "./ProgressBar"; +export type { ProgressColor } from "./ProgressBar";