import { useState } from "react"; import { Link as RouterLink } from "react-router-dom"; import { motion } from "framer-motion"; import Box from "@mui/material/Box"; import { useAuth } from "../../context/AuthContext"; import { useAlert } from "../../context/AlertContext"; import { formatKm, todayLocalStr } from "../../utils/formatters"; import { Button, Modal, Field, Select, DateField, TextField } from "../../ui"; import apiFetch from "../../utils/api"; const API_BASE = "/api/admin"; interface Vehicle { id: number | string; spz: string; name: string; } interface TripForm { vehicle_id: string; trip_date: string; start_km: string; end_km: string; route_from: string; route_to: string; is_business: number; notes: string; } interface TripErrors { vehicle_id?: string; trip_date?: string; start_km?: string; end_km?: string; route_from?: string; route_to?: string; } interface DashQuickActionsProps { dashData: { my_shift?: { has_ongoing: boolean; }; } | null; punching: boolean; onPunch: () => void; } // Maps the legacy quick-action color tokens to the MUI Button palette color. const ACTION_COLOR: Record = { success: "success", danger: "error", info: "info", warning: "warning", }; export default function DashQuickActions({ dashData, punching, onPunch, }: DashQuickActionsProps) { const { hasPermission } = useAuth(); const alert = useAlert(); const [showTripModal, setShowTripModal] = useState(false); const [tripSubmitting, setTripSubmitting] = useState(false); const [tripVehicles, setTripVehicles] = useState([]); const [tripForm, setTripForm] = useState({ vehicle_id: "", trip_date: "", start_km: "", end_km: "", route_from: "", route_to: "", is_business: 1, notes: "", }); const [tripErrors, setTripErrors] = useState({}); const openTripModal = async () => { setTripForm({ vehicle_id: "", trip_date: todayLocalStr(), start_km: "", end_km: "", route_from: "", route_to: "", is_business: 1, notes: "", }); setTripErrors({}); setShowTripModal(true); try { const response = await apiFetch(`${API_BASE}/vehicles`); const result = await response.json(); if (result.success) { setTripVehicles( Array.isArray(result.data) ? result.data : result.data?.vehicles || [], ); } } catch { // vozidla se nenacetla } }; const handleTripVehicleChange = async (vehicleId: string) => { setTripForm((prev) => ({ ...prev, vehicle_id: vehicleId })); if (!vehicleId) { return; } try { const response = await apiFetch(`${API_BASE}/trips/last-km/${vehicleId}`); const result = await response.json(); if (result.success) { setTripForm((prev) => ({ ...prev, start_km: result.data.last_km })); } } catch { // last_km se nenacetlo } }; const handleTripSubmit = async () => { const errs: TripErrors = {}; if (!tripForm.vehicle_id) { errs.vehicle_id = "Vyberte vozidlo"; } if (!tripForm.trip_date) { errs.trip_date = "Zadejte datum"; } if (!tripForm.start_km) { errs.start_km = "Zadejte počáteční km"; } if (!tripForm.end_km) { errs.end_km = "Zadejte konečný km"; } if ( tripForm.start_km && tripForm.end_km && parseInt(tripForm.end_km) <= parseInt(tripForm.start_km) ) { errs.end_km = "Musí být větší než počáteční"; } if (!tripForm.route_from) { errs.route_from = "Zadejte místo odjezdu"; } if (!tripForm.route_to) { errs.route_to = "Zadejte místo příjezdu"; } setTripErrors(errs); if (Object.keys(errs).length > 0) { return; } setTripSubmitting(true); try { const response = await apiFetch(`${API_BASE}/trips`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(tripForm), }); const result = await response.json(); if (result.success) { setShowTripModal(false); alert.success(result.message); } else { alert.error(result.error); } } catch { alert.error("Chyba připojení"); } finally { setTripSubmitting(false); } }; const tripDistance = (): number => { const s = parseInt(tripForm.start_km) || 0; const e = parseInt(tripForm.end_km) || 0; return e > s ? e - s : 0; }; const hasOngoingShift = dashData?.my_shift?.has_ongoing; const punchLabel = hasOngoingShift ? "Zaznamenat odchod" : "Zaznamenat příchod"; const quickActions: Array<{ label: string; color: string; icon: React.ReactNode; onClick?: () => void; path?: string; disabled?: boolean; }> = []; if (hasPermission("attendance.record")) { quickActions.push({ label: punching ? "Odesílám..." : punchLabel, color: hasOngoingShift ? "danger" : "success", icon: hasOngoingShift ? ( ) : ( ), onClick: onPunch, disabled: punching, }); } if (hasPermission("offers.create")) { quickActions.push({ label: "Nová nabídka", path: "/offers/new", color: "info", icon: ( ), }); } if (hasPermission("trips.record")) { quickActions.push({ label: "Přidat jízdu", color: "warning", icon: ( ), onClick: openTripModal, }); } if (hasPermission("invoices.create")) { quickActions.push({ label: "Vystavit fakturu", path: "/invoices/new", color: "danger", icon: ( ), }); } return ( <> {quickActions.map((action) => { const color = ACTION_COLOR[action.color] ?? "primary"; const common = { variant: "contained" as const, color, startIcon: action.icon, sx: { py: 1.5, justifyContent: "flex-start" }, }; return action.onClick ? ( ) : ( ); })} setShowTripModal(false)} title="Přidat jízdu" maxWidth="md" onSubmit={handleTripSubmit} submitText="Uložit" loading={tripSubmitting} > setTripForm((prev) => ({ ...prev, is_business: parseInt(val) })) } options={[ { value: "1", label: "Služební" }, { value: "0", label: "Soukromá" }, ]} /> setTripForm((prev) => ({ ...prev, notes: e.target.value })) } placeholder="Volitelné poznámky..." /> ); }