Files
Projektarbeit-MYP/frontend/src/components/printer-card/index.tsx

88 lines
3.3 KiB
TypeScript

"use client";
import { PrinterReserveForm } from "@/app/printer/[printerId]/reserve/form";
import { Countdown } from "@/components/printer-card/countdown";
import { AlertDialogHeader } from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { UserRole, hasRole } from "@/server/auth/permissions";
import type { InferResultType } from "@/utils/drizzle";
import { PrinterStatus, derivePrinterStatus, translatePrinterStatus } from "@/utils/printers";
import { cn } from "@/utils/styles";
import type { RegisteredDatabaseUserAttributes } from "lucia";
import { CalendarPlusIcon, ChevronRightIcon } from "lucide-react";
import Link from "next/link";
import { Else, If, Then } from "react-if";
interface PrinterCardProps {
printer: InferResultType<"printers", { printJobs: true }>;
user?: RegisteredDatabaseUserAttributes | null;
}
export function PrinterCard(props: PrinterCardProps) {
const { printer, user } = props;
const status = derivePrinterStatus(printer);
const userIsLoggedIn = Boolean(user);
return (
<Card
className={cn("w-auto h-36", {
"opacity-50 select-none cursor-not-allowed": status === PrinterStatus.OUT_OF_ORDER,
})}
>
<CardHeader>
<div className="flex flex-row items-start justify-between">
<div>
<CardTitle>{printer.name}</CardTitle>
<CardDescription>{printer.description}</CardDescription>
</div>
<Badge
className={cn({
"bg-green-500 hover:bg-green-400": status === PrinterStatus.IDLE,
"bg-red-500 hover:bg-red-500": status === PrinterStatus.OUT_OF_ORDER,
"bg-yellow-500 hover:bg-yellow-400": status === PrinterStatus.RESERVED,
})}
>
{status === PrinterStatus.RESERVED && <Countdown jobId={printer.printJobs[0].id} />}
<If condition={status === PrinterStatus.RESERVED}>
<Else>{translatePrinterStatus(status)}</Else>
</If>
</Badge>
</div>
</CardHeader>
<CardContent className="flex justify-end">
<If condition={status === PrinterStatus.IDLE && userIsLoggedIn && !hasRole(user, UserRole.GUEST)}>
<Then>
<Dialog>
<DialogTrigger asChild>
<Button variant={"default"} className="flex items-center gap-2 w-full">
<CalendarPlusIcon className="w-4 h-4" />
<span>Reservieren</span>
</Button>
</DialogTrigger>
<DialogContent>
<AlertDialogHeader>
<DialogTitle>{printer.name} reservieren</DialogTitle>
<DialogDescription>Gebe die geschätzte Druckdauer an.</DialogDescription>
</AlertDialogHeader>
<PrinterReserveForm isDialog={true} printerId={printer.id} userId={user?.id ?? ""} />
</DialogContent>
</Dialog>
</Then>
</If>
{status === PrinterStatus.RESERVED && (
<Button asChild variant={"secondary"}>
<Link href={`/job/${printer.printJobs[0].id}`} className="flex items-center gap-2 w-full">
<ChevronRightIcon className="w-4 h-4" />
<span>Details anzeigen</span>
</Link>
</Button>
)}
</CardContent>
</Card>
);
}