ultisuite-client/components/agenda/agenda-mini-month.tsx
R3D347HR4Y ad1370ea7e
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: enhance configuration and add new demo layouts
- Introduced turbopack alias for canvas in next.config.mjs.
- Updated package.json scripts for development and branding tasks.
- Added new dependencies for Tiptap extensions.
- Implemented new demo layouts for agenda, contacts, drive, and mail applications.
- Enhanced globals.css for improved theming and splash screen animations.
- Added OAuth callback handling for drive mounts.
- Updated layout components to integrate new demo shells and improve structure.
2026-06-12 19:10:24 +02:00

106 lines
3.3 KiB
TypeScript

"use client"
import { useEffect, useState } from "react"
import {
addDays,
addMonths,
format,
isSameDay,
isSameMonth,
startOfMonth,
startOfWeek,
} from "date-fns"
import { fr } from "date-fns/locale"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { getWeekOptionsFor, weekdayLabelsFor } from "@/lib/agenda/agenda-date"
import type { AgendaWeekStart } from "@/lib/agenda/agenda-settings-types"
import { useResolvedWeekStartsOn } from "@/lib/agenda/use-resolved-week-start"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
export function AgendaMiniMonth({
selected,
onSelect,
weekStart = "auto",
}: {
selected: Date
onSelect: (date: Date) => void
weekStart?: AgendaWeekStart
}) {
const weekStartsOn = useResolvedWeekStartsOn(weekStart)
const [cursor, setCursor] = useState(() => startOfMonth(selected))
const weekLabels = weekdayLabelsFor(weekStartsOn)
useEffect(() => {
setCursor(startOfMonth(selected))
}, [selected])
const gridStart = startOfWeek(cursor, getWeekOptionsFor(weekStartsOn))
const today = new Date()
const cells: Date[] = []
for (let i = 0; i < 42; i++) cells.push(addDays(gridStart, i))
return (
<div className="select-none px-1">
<div className="flex items-center justify-between pb-1 pl-2">
<span className="text-sm font-medium text-foreground/90">
{format(cursor, "MMMM yyyy", { locale: fr }).replace(/^./, (c) =>
c.toUpperCase(),
)}
</span>
<div className="flex">
<Button
variant="ghost"
size="icon"
className="size-7 rounded-full text-muted-foreground"
aria-label="Mois précédent"
onClick={() => setCursor((c) => addMonths(c, -1))}
>
<ChevronLeft className="size-4" />
</Button>
<Button
variant="ghost"
size="icon"
className="size-7 rounded-full text-muted-foreground"
aria-label="Mois suivant"
onClick={() => setCursor((c) => addMonths(c, 1))}
>
<ChevronRight className="size-4" />
</Button>
</div>
</div>
<div className="grid grid-cols-7 text-center">
{weekLabels.map((d, i) => (
<span
key={`${d}-${i}`}
className="py-1 text-[0.65rem] font-medium text-muted-foreground"
>
{d}
</span>
))}
{cells.map((day) => {
const isToday = isSameDay(day, today)
const isSelected = isSameDay(day, selected)
const inMonth = isSameMonth(day, cursor)
return (
<button
key={day.getTime()}
type="button"
onClick={() => onSelect(day)}
className={cn(
"mx-auto flex size-6 items-center justify-center rounded-full text-[0.7rem] transition-colors",
inMonth ? "text-foreground/85" : "text-muted-foreground/50",
isToday && "bg-primary font-semibold text-primary-foreground",
isSelected && !isToday && "bg-primary/15 font-semibold text-primary",
!isToday && !isSelected && "hover:bg-mail-nav-hover",
)}
>
{format(day, "d")}
</button>
)
})}
</div>
</div>
)
}