"use client"; import { motion, useReducedMotion } from "motion/react"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { LuPencil, LuTrash2 } from "react-icons/lu"; import { describeCadence, minutesToClock, StatusDot, scheduleBlockedReason, scheduleTone, } from "@/components/cookie-bot-shared"; import { Button } from "@/components/ui/button"; import { FadingScrollArea } from "@/components/ui/fading-scroll-area"; import { Skeleton } from "@/components/ui/skeleton"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import { useInputModality } from "@/hooks/use-input-modality"; import type { CookieBotSchedule } from "@/lib/cookie-bot"; import { MOTION_EASE_OUT } from "@/lib/motion"; import { scheduleLanes } from "@/lib/schedule-layout"; import { cn } from "@/lib/utils"; interface CookieBotScheduleTabProps { schedules: CookieBotSchedule[]; isLoading: boolean; currentUserId: string | null; canEditOthers: boolean; onEdit: (schedule: CookieBotSchedule) => void; onRemove: (schedule: CookieBotSchedule) => void; } export function CookieBotScheduleTab({ schedules, isLoading, currentUserId, canEditOthers, onEdit, onRemove, }: CookieBotScheduleTabProps) { const { t } = useTranslation(); const reduced = useReducedMotion(); const modality = useInputModality(); const groups = useMemo(() => scheduleLanes(schedules), [schedules]); if (isLoading && !schedules.length) return ; if (!schedules.length) return (

{t("cookieBot.schedule.empty")}

); return (

{t("appFeedback.requestedSchedule")}

{[...groups].map(([timezone, lanes]) => { const start = Math.max( 0, Math.floor( (Math.min(...lanes.map((lane) => lane.minute)) - 30) / 60, ) * 60, ); const end = Math.max( start + 120, Math.ceil( (Math.max(...lanes.map((lane) => lane.minute + lane.duration)) + 30) / 60, ) * 60, ); const span = end - start; return (

{timezone || t("common.labels.default")}

{lanes.map((lane) => { const { schedule } = lane; const editable = !schedule.owner_user_id || schedule.owner_user_id === currentUserId || canEditOthers; const blocked = scheduleBlockedReason(t, schedule); return (
{schedule.owner_email && schedule.owner_user_id !== currentUserId && (

{schedule.owner_email}

)}

{describeCadence(t, lane.days)}

{minutesToClock(lane.minute)} ยท{" "} {t("cookieBot.chart.minutes", { minutes: lane.duration, })}

{blocked && (

{blocked}

)} {lane.overlaps > 0 && (

{t("appFeedback.overlappingBookings", { count: lane.overlaps, })}

)}
onEdit(schedule)} > onRemove(schedule)} >
); })}
); })}
); } function SlotAction({ label, forbidden, destructive, onClick, children, }: { label: string; forbidden: boolean; destructive?: boolean; onClick: () => void; children: React.ReactNode; }) { const { t } = useTranslation(); return ( {forbidden ? t("cookieBot.conflict.replaceForbidden") : label} ); }