62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { StickyNote } from "lucide-react";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
import { MouseFollowTooltip } from "@/components/board/mouse-follow-tooltip";
|
|
import type { ScheduledOccurrenceDTO } from "@/types/scheduled-todo";
|
|
|
|
/** One occurrence row -- "emphasis" is how loud this date's section reads
|
|
* (Overdue/Today get their own text treatment; every other day relies on
|
|
* ScheduledPanel fading its whole section via opacity instead). */
|
|
export function ScheduledTodoItem({
|
|
occurrence,
|
|
emphasis = "normal",
|
|
onToggle,
|
|
onEdit,
|
|
}: {
|
|
occurrence: ScheduledOccurrenceDTO;
|
|
emphasis?: "overdue" | "today" | "normal";
|
|
onToggle: (completed: boolean) => void;
|
|
onEdit: () => void;
|
|
}) {
|
|
const titleButton = (
|
|
<button
|
|
type="button"
|
|
onClick={onEdit}
|
|
className={cn(
|
|
"min-w-0 flex-1 truncate text-left text-sm hover:underline",
|
|
occurrence.completed
|
|
? "text-muted-foreground line-through"
|
|
: emphasis === "overdue"
|
|
? "font-semibold text-destructive"
|
|
: emphasis === "today"
|
|
? "font-medium text-foreground"
|
|
: "text-foreground"
|
|
)}
|
|
>
|
|
{occurrence.title}
|
|
</button>
|
|
);
|
|
|
|
return (
|
|
<li className="flex items-start gap-2 py-1">
|
|
<Checkbox
|
|
checked={occurrence.completed}
|
|
onCheckedChange={(checked) => onToggle(!!checked)}
|
|
className="mt-0.5"
|
|
aria-label={`Mark "${occurrence.title}" ${occurrence.completed ? "incomplete" : "complete"}`}
|
|
/>
|
|
{occurrence.details ? (
|
|
<MouseFollowTooltip content={occurrence.details}>{titleButton}</MouseFollowTooltip>
|
|
) : (
|
|
titleButton
|
|
)}
|
|
{occurrence.details && (
|
|
<StickyNote className="mt-0.5 size-3 shrink-0 text-muted-foreground/70" />
|
|
)}
|
|
</li>
|
|
);
|
|
}
|