176 lines
4.4 KiB
TypeScript
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>
|
|
);
|
|
}
|