/** * Shared content for day detail: title and sections (duty, unavailable, vacation, events). * Ported from webapp/js/dayDetail.js buildDayDetailContent. */ "use client"; import { useMemo } from "react"; import { useTranslation } from "@/i18n/use-translation"; import { localDateString, dateKeyToDDMM } from "@/lib/date-utils"; import { getDutyMarkerRows } from "@/lib/duty-marker-rows"; import { ContactLinks } from "@/components/contact"; import type { DutyWithUser } from "@/types"; import { cn } from "@/lib/utils"; const NBSP = "\u00a0"; export interface DayDetailContentProps { /** YYYY-MM-DD key for the day. */ dateKey: string; /** Duties overlapping this day. */ duties: DutyWithUser[]; /** Calendar event summary strings for this day. */ eventSummaries: string[]; className?: string; } export function DayDetailContent({ dateKey, duties, eventSummaries, className, }: DayDetailContentProps) { const { t } = useTranslation(); const todayKey = localDateString(new Date()); const ddmm = dateKeyToDDMM(dateKey); const title = dateKey === todayKey ? t("duty.today") + ", " + ddmm : ddmm; const fromLabel = t("hint.from"); const toLabel = t("hint.to"); const dutyList = useMemo( () => duties .filter((d) => d.event_type === "duty") .sort( (a, b) => new Date(a.start_at || 0).getTime() - new Date(b.start_at || 0).getTime() ), [duties] ); const unavailableList = useMemo( () => duties.filter((d) => d.event_type === "unavailable"), [duties] ); const vacationList = useMemo( () => duties.filter((d) => d.event_type === "vacation"), [duties] ); const dutyRows = useMemo(() => { const hasTimes = dutyList.some((it) => it.start_at || it.end_at); return hasTimes ? getDutyMarkerRows(dutyList, dateKey, NBSP, fromLabel, toLabel) : dutyList.map((d) => ({ id: d.id, timePrefix: "", fullName: d.full_name ?? "", phone: d.phone, username: d.username, })); }, [dutyList, dateKey, fromLabel, toLabel]); const uniqueUnavailable = useMemo( () => [ ...new Set( unavailableList.map((d) => d.full_name ?? "").filter(Boolean) ), ], [unavailableList] ); const uniqueVacation = useMemo( () => [ ...new Set(vacationList.map((d) => d.full_name ?? "").filter(Boolean)), ], [vacationList] ); const summaries = eventSummaries ?? []; return (

{title}

{dutyList.length > 0 && (

{t("event_type.duty")}

    {dutyRows.map((r) => (
  • {r.timePrefix && ( {r.timePrefix} — )} {r.fullName}
  • ))}
)} {uniqueUnavailable.length > 0 && (

{t("event_type.unavailable")}

    {uniqueUnavailable.map((name) => (
  • {name}
  • ))}
)} {uniqueVacation.length > 0 && (

{t("event_type.vacation")}

    {uniqueVacation.map((name) => (
  • {name}
  • ))}
)} {summaries.length > 0 && (

{t("hint.events")}

    {summaries.map((s) => (
  • {String(s)}
  • ))}
)}
); }