"use client"; import { RiAddLine } from "@remixicon/react"; import type { KeyboardEvent, MouseEvent } from "react"; import type { CalendarDay, CalendarEvent } from "@/components/calendario/types"; import { currencyFormatter } from "@/lib/lancamentos/formatting-helpers"; import { cn } from "@/lib/utils/ui"; type DayCellProps = { day: CalendarDay; onSelect: (day: CalendarDay) => void; onCreate: (day: CalendarDay) => void; }; export const EVENT_TYPE_STYLES: Record< CalendarEvent["type"], { wrapper: string; dot: string; accent?: string } > = { lancamento: { wrapper: "bg-orange-100 text-orange-600 dark:bg-orange-900/10 dark:text-orange-50 border-l-4 border-orange-500", dot: "bg-orange-600", }, boleto: { wrapper: "bg-blue-100 text-blue-600 dark:bg-blue-900/10 dark:text-blue-50 border-l-4 border-blue-500", dot: "bg-blue-600", }, cartao: { wrapper: "bg-violet-100 text-violet-600 dark:bg-violet-900/10 dark:text-violet-50 border-l-4 border-violet-500", dot: "bg-violet-600", }, }; const eventStyles = EVENT_TYPE_STYLES; const formatCurrencyValue = (value: number | null | undefined) => currencyFormatter.format(Math.abs(value ?? 0)); const formatAmount = (event: Extract) => formatCurrencyValue(event.lancamento.amount); const buildEventLabel = (event: CalendarEvent) => { switch (event.type) { case "lancamento": { return event.lancamento.name; } case "boleto": { return event.lancamento.name; } case "cartao": { return event.card.name; } default: return ""; } }; const buildEventComplement = (event: CalendarEvent) => { switch (event.type) { case "lancamento": { return formatAmount(event); } case "boleto": { return formatCurrencyValue(event.lancamento.amount); } case "cartao": { if (event.card.totalDue !== null) { return formatCurrencyValue(event.card.totalDue); } return null; } default: return null; } }; const isPagamentoFatura = (event: CalendarEvent) => { return ( event.type === "lancamento" && event.lancamento.name.startsWith("Pagamento fatura -") ); }; const getEventStyle = (event: CalendarEvent) => { if (isPagamentoFatura(event)) { return { wrapper: "bg-green-100 text-green-600 dark:bg-green-900/10 dark:text-green-50 border-l-4 border-green-500", dot: "bg-green-600", }; } return eventStyles[event.type]; }; const DayEventPreview = ({ event }: { event: CalendarEvent }) => { const complement = buildEventComplement(event); const label = buildEventLabel(event); const style = getEventStyle(event); return (
{label}
{complement ? ( {complement} ) : null}
); }; export function DayCell({ day, onSelect, onCreate }: DayCellProps) { const previewEvents = day.events.slice(0, 3); const hasOverflow = day.events.length > 3; const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Enter" || event.key === " " || event.key === "Space") { event.preventDefault(); onSelect(day); } }; const handleCreateClick = (event: MouseEvent) => { event.stopPropagation(); onCreate(day); }; return (
onSelect(day)} onKeyDown={handleKeyDown} className={cn( "flex h-full cursor-pointer flex-col gap-1.5 rounded-lg border border-transparent bg-card/80 p-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:border-primary/40 hover:bg-primary/5 dark:hover:bg-primary/10", !day.isCurrentMonth && "opacity-60", day.isToday && "border-primary/70 bg-primary/5 hover:border-primary", )} >
{day.label}
{previewEvents.map((event) => ( ))} {hasOverflow ? ( + ver mais ) : null}
); }