115 lines
3.3 KiB
TypeScript
115 lines
3.3 KiB
TypeScript
import Box from "@mui/material/Box";
|
||
import Typography from "@mui/material/Typography";
|
||
import { Card } from "../../ui";
|
||
import { formatDate } from "../../utils/formatters";
|
||
|
||
/** One resolved plan record for today (see GET /api/admin/dashboard). */
|
||
export interface TodayPlan {
|
||
shift_date: string;
|
||
category: string;
|
||
category_label: string;
|
||
category_color: string | null;
|
||
project_id: number | null;
|
||
project_number: string | null;
|
||
project_name: string | null;
|
||
note: string;
|
||
source: "entry" | "override";
|
||
rangeFrom: string | null;
|
||
rangeTo: string | null;
|
||
}
|
||
|
||
function projectLabel(p: TodayPlan): string {
|
||
const parts = [p.project_number, p.project_name].filter(Boolean);
|
||
return parts.length > 0 ? parts.join(" — ") : "Bez projektu";
|
||
}
|
||
|
||
function PlanRow({ plan }: { plan: TodayPlan }) {
|
||
const color = plan.category_color || "var(--mui-palette-primary-main)";
|
||
return (
|
||
<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
|
||
<Box
|
||
sx={{ display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }}
|
||
>
|
||
<Box
|
||
sx={{
|
||
display: "inline-flex",
|
||
alignItems: "center",
|
||
gap: 0.75,
|
||
px: 1.25,
|
||
py: 0.5,
|
||
borderRadius: 999,
|
||
border: 1,
|
||
borderColor: "divider",
|
||
bgcolor: `color-mix(in srgb, ${color} 12%, transparent)`,
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
width: 10,
|
||
height: 10,
|
||
borderRadius: "50%",
|
||
bgcolor: color,
|
||
flexShrink: 0,
|
||
}}
|
||
/>
|
||
<Typography
|
||
component="span"
|
||
sx={{ fontWeight: 700, fontSize: "0.8rem" }}
|
||
>
|
||
{plan.category_label}
|
||
</Typography>
|
||
</Box>
|
||
{plan.rangeFrom && plan.rangeTo && plan.rangeFrom !== plan.rangeTo && (
|
||
<Typography variant="caption" color="text.secondary">
|
||
součást rozsahu {formatDate(plan.rangeFrom)} –{" "}
|
||
{formatDate(plan.rangeTo)}
|
||
</Typography>
|
||
)}
|
||
</Box>
|
||
<Typography variant="h6" sx={{ lineHeight: 1.25 }}>
|
||
{projectLabel(plan)}
|
||
</Typography>
|
||
{plan.note && (
|
||
<Typography variant="body2" color="text.secondary">
|
||
{plan.note}
|
||
</Typography>
|
||
)}
|
||
</Box>
|
||
);
|
||
}
|
||
|
||
/** "Vaše dnešní zařazení" — the logged-in user's resolved plan record(s) for
|
||
* today (up to 3). Empty array = nothing scheduled. */
|
||
export default function DashTodayPlan({ plans }: { plans: TodayPlan[] }) {
|
||
return (
|
||
<Card sx={{ mb: 3 }}>
|
||
<Typography
|
||
variant="subtitle2"
|
||
sx={{ mb: 1.5, fontWeight: 600, color: "text.secondary" }}
|
||
>
|
||
Vaše dnešní zařazení
|
||
</Typography>
|
||
{plans.length > 0 ? (
|
||
<Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
|
||
{plans.map((p, i) => (
|
||
<Box
|
||
key={i}
|
||
sx={{
|
||
pt: i === 0 ? 0 : 2,
|
||
borderTop: i === 0 ? 0 : 1,
|
||
borderColor: "divider",
|
||
}}
|
||
>
|
||
<PlanRow plan={p} />
|
||
</Box>
|
||
))}
|
||
</Box>
|
||
) : (
|
||
<Typography variant="body2" color="text.secondary">
|
||
Pro dnešek nemáte naplánováno.
|
||
</Typography>
|
||
)}
|
||
</Card>
|
||
);
|
||
}
|