import type { Metadata } from "next"; import { notFound, redirect } from "next/navigation"; import { auth } from "@/auth"; import { TopNav } from "@/components/navigation/top-nav"; import { prisma } from "@/lib/db/prisma"; import { hasPermission } from "@/lib/auth/permissions"; import { Permission } from "@/generated/prisma/enums"; import { getActingBusinessContext } from "@/lib/business/get-acting-business-context"; import { listTimeOff } from "@/services/staff/staff.service"; import { TimeOffList } from "@/features/staff/components/time-off-list"; import { createOwnerTimeOffActionSet } from "@/features/owner/actions/time-off-action-set"; export const metadata: Metadata = { title: "Staff Time Off" }; export const dynamic = "force-dynamic"; function toCalendarDate(date: Date): string { return date.toISOString().slice(0, 10); } export default async function OwnerStaffTimeOffPage({ params }: { params: Promise<{ id: string }> }) { const session = await auth(); if (!session?.user) redirect("/sign-in"); const canManage = await hasPermission(session.user.id, Permission.MANAGE_STAFF); if (!canManage) redirect("/staff"); const context = await getActingBusinessContext(); if (!context) redirect("/staff"); const { id } = await params; const target = await prisma.staffProfile.findFirst({ where: { id, businessId: context.businessId }, include: { user: { select: { name: true } } }, }); if (!target) notFound(); const { upcoming, past } = await listTimeOff(prisma, id); // Whole-day rows only — partial-day "Block Time" entries are managed from the owner calendar (see owner-block-time-button.tsx). const wholeDay = (rows: typeof upcoming) => rows.filter((r) => r.startMinutes === null && r.endMinutes === null); const toEditable = (rows: typeof upcoming) => wholeDay(rows).map((t) => ({ id: t.id, startDate: toCalendarDate(t.startDate), endDate: toCalendarDate(t.endDate), reason: t.reason, })); return (
); }