import { motion, AnimatePresence } from "framer-motion";
import AdminDatePicker from "./AdminDatePicker";
import useModalLock from "../hooks/useModalLock";
import {
calcFormWorkMinutes,
calcProjectMinutesTotal,
formatDate,
} from "../utils/attendanceHelpers";
let _logKeyCounter = 0;
// ---------- Shared types ----------
export interface ShiftFormData {
user_id: string;
shift_date: string;
leave_type: string;
leave_hours: number;
arrival_date: string;
arrival_time: string;
break_start_date: string;
break_start_time: string;
break_end_date: string;
break_end_time: string;
departure_date: string;
departure_time: string;
notes: string;
}
export interface ProjectLog {
_key?: string;
id?: number;
project_id: string | number;
hours: string | number;
minutes: string | number;
}
export interface Project {
id: number | string;
project_number: string;
name: string;
}
export interface User {
id: number | string;
name: string;
}
export interface EditingRecord {
user_name: string;
shift_date: string;
}
// ---------- Sub-component props ----------
interface ProjectTimeStatusProps {
form: ShiftFormData;
projectLogs: ProjectLog[];
}
interface ProjectLogRowProps {
log: ProjectLog;
index: number;
projectList: Project[];
onUpdate: (index: number, field: string, value: string) => void;
onRemove: (index: number) => void;
}
export interface ShiftFormModalProps {
mode: "create" | "edit";
isOpen: boolean;
onClose: () => void;
onSubmit: () => void;
form: ShiftFormData;
setForm: (form: ShiftFormData) => void;
projectLogs: ProjectLog[];
setProjectLogs: (logs: ProjectLog[]) => void;
projectList: Project[];
users: User[];
onShiftDateChange: (value: string) => void;
editingRecord: EditingRecord | null;
}
// ---------- ProjectTimeStatus ----------
function ProjectTimeStatus({ form, projectLogs }: ProjectTimeStatusProps) {
const totalWork = calcFormWorkMinutes(form);
const totalProject = calcProjectMinutesTotal(
projectLogs.map((l) => ({
...l,
project_id:
l.project_id !== "" && l.project_id != null
? Number(l.project_id)
: undefined,
})),
);
const remaining = totalWork - totalProject;
const hasLogs = projectLogs.some((l) => l.project_id);
if (!hasLogs || totalWork <= 0) return null;
const isMatch = remaining === 0;
return (
Odpracováno: {Math.floor(totalWork / 60)}h {totalWork % 60}m | Přiřazeno:{" "}
{Math.floor(totalProject / 60)}h {totalProject % 60}m | Zbývá:{" "}
{Math.floor(Math.abs(remaining) / 60)}h {Math.abs(remaining) % 60}m{" "}
{remaining < 0 ? "(překročeno)" : ""}
);
}
// ---------- ProjectLogRow ----------
function ProjectLogRow({
log,
index,
projectList,
onUpdate,
onRemove,
}: ProjectLogRowProps) {
return (
onUpdate(index, "hours", e.target.value)}
className="admin-form-input"
style={{ width: "60px", marginBottom: 0, textAlign: "center" }}
placeholder="h"
/>
h
onUpdate(index, "minutes", e.target.value)}
className="admin-form-input"
style={{ width: "60px", marginBottom: 0, textAlign: "center" }}
placeholder="m"
/>
m
);
}
// ---------- ShiftFormModal ----------
export default function ShiftFormModal({
mode,
isOpen,
onClose,
onSubmit,
form,
setForm,
projectLogs,
setProjectLogs,
projectList,
users,
onShiftDateChange,
editingRecord,
}: ShiftFormModalProps) {
useModalLock(isOpen);
const isCreate = mode === "create";
const isWorkType = form.leave_type === "work";
const updateField = (field: keyof ShiftFormData, value: string | number) => {
setForm({ ...form, [field]: value });
};
const updateProjectLog = (index: number, field: string, value: string) => {
const updated = [...projectLogs];
updated[index] = { ...updated[index], [field]: value };
setProjectLogs(updated);
};
const removeProjectLog = (index: number) => {
setProjectLogs(projectLogs.filter((_, j) => j !== index));
};
const addProjectLog = () => {
setProjectLogs([
...projectLogs,
{
_key: `log-${++_logKeyCounter}`,
project_id: "",
hours: "",
minutes: "",
},
]);
};
return (
{isOpen && (
{!isCreate && editingRecord && (
{editingRecord.user_name} —{" "}
{formatDate(editingRecord.shift_date)}
)}
{isCreate ? (
onShiftDateChange(val)}
/>
) : (
updateField("shift_date", val)}
/>
)}
{!isWorkType && (
updateField("leave_hours", parseFloat(e.target.value))
}
min="0.5"
max="24"
step="0.5"
className="admin-form-input"
/>
{isCreate && (
8 hodin = celý den
)}
)}
{isWorkType && (
<>
updateField("arrival_date", val)}
/>
updateField("arrival_time", val)}
/>
updateField("break_start_date", val)
}
/>
updateField("break_start_time", val)
}
/>
updateField("break_end_date", val)}
/>
updateField("break_end_time", val)}
/>
updateField("departure_date", val)}
/>
updateField("departure_time", val)}
/>
>
)}
{isWorkType && projectList.length > 0 && (
{projectLogs.map((log, i) => (
))}
)}
)}
);
}