Files
app/src/admin/components/BulkAttendanceModal.tsx
2026-06-07 00:57:26 +02:00

176 lines
4.4 KiB
TypeScript

import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { Modal, MonthField, TimeField, Field, CheckboxField } from "../ui";
interface BulkAttendanceForm {
month: string;
user_ids: string[];
arrival_time: string;
departure_time: string;
break_start_time: string;
break_end_time: string;
}
interface BulkAttendanceUser {
id: number | string;
name: string;
}
interface BulkAttendanceModalProps {
isOpen: boolean;
onClose: () => void;
form: BulkAttendanceForm;
setForm: (form: BulkAttendanceForm) => void;
users: BulkAttendanceUser[];
onSubmit: () => void;
submitting: boolean;
toggleUser: (userId: number | string) => void;
toggleAllUsers: () => void;
}
export default function BulkAttendanceModal({
isOpen,
onClose,
form,
setForm,
users,
onSubmit,
submitting,
toggleUser,
toggleAllUsers,
}: BulkAttendanceModalProps) {
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title="Vyplnit docházku za měsíc"
maxWidth="lg"
loading={submitting}
onSubmit={onSubmit}
submitText="Vyplnit měsíc"
submitDisabled={form.user_ids.length === 0}
>
<Typography
variant="body2"
color="text.secondary"
sx={{ mt: 0.25, mb: 2 }}
>
Vytvoří záznamy pro všechny pracovní dny. Svátky se automaticky označí.
Existující záznamy se přeskočí.
</Typography>
<Field label="Měsíc">
<MonthField
value={form.month}
onChange={(val) => setForm({ ...form, month: val })}
/>
</Field>
<Box sx={{ mb: 2 }}>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1.5,
mb: 0.5,
}}
>
<Typography
component="span"
variant="body2"
sx={{ fontWeight: 600, color: "text.secondary" }}
>
Zaměstnanci
</Typography>
<Typography
component="button"
type="button"
onClick={toggleAllUsers}
variant="caption"
sx={{
background: "none",
border: "none",
p: 0,
cursor: "pointer",
fontWeight: 500,
color: "primary.main",
}}
>
{form.user_ids.length === users.length
? "Odznačit vše"
: "Vybrat vše"}
</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: 0.25,
maxHeight: 200,
overflowY: "auto",
p: 1.5,
bgcolor: "action.hover",
borderRadius: 2,
border: 1,
borderColor: "divider",
}}
>
{users.map((user) => (
<CheckboxField
key={user.id}
label={user.name}
checked={form.user_ids.includes(String(user.id))}
onChange={() => toggleUser(user.id)}
/>
))}
</Box>
<Typography variant="caption" color="text.secondary">
Vybráno: {form.user_ids.length} z {users.length}
</Typography>
</Box>
<Box
sx={{
display: "grid",
gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
gap: 2,
}}
>
<Field label="Příchod">
<TimeField
value={form.arrival_time}
onChange={(val) => setForm({ ...form, arrival_time: val })}
/>
</Field>
<Field label="Odchod">
<TimeField
value={form.departure_time}
onChange={(val) => setForm({ ...form, departure_time: val })}
/>
</Field>
</Box>
<Box
sx={{
display: "grid",
gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
gap: 2,
}}
>
<Field label="Začátek pauzy">
<TimeField
value={form.break_start_time}
onChange={(val) => setForm({ ...form, break_start_time: val })}
/>
</Field>
<Field label="Konec pauzy">
<TimeField
value={form.break_end_time}
onChange={(val) => setForm({ ...form, break_end_time: val })}
/>
</Field>
</Box>
</Modal>
);
}