145 lines
4.2 KiB
TypeScript
145 lines
4.2 KiB
TypeScript
"use client";
|
|
import { ReactNode, useState } from "react";
|
|
import { cn } from "../helper/cn";
|
|
|
|
export const PenaltyDropdown = ({
|
|
onClick,
|
|
btnClassName,
|
|
showDatePicker,
|
|
btnTip,
|
|
btnName,
|
|
Icon,
|
|
showBtnName = false,
|
|
}: {
|
|
onClick: (data: { reason: string; until: Date | null }) => void;
|
|
showDatePicker?: boolean;
|
|
btnClassName?: string;
|
|
btnName: string;
|
|
btnTip?: string;
|
|
showBtnName?: boolean;
|
|
Icon: ReactNode;
|
|
}) => {
|
|
const [open, setOpen] = useState(false);
|
|
const [reason, setReason] = useState("");
|
|
const [until, setUntil] = useState<string>("default");
|
|
return (
|
|
<div className="dropdown dropdown-open">
|
|
<div tabIndex={0} role="button"></div>
|
|
<div className="indicator">
|
|
<button
|
|
className={cn(
|
|
"btn btn-xs btn-soft cursor-pointer",
|
|
!showBtnName && "btn-square",
|
|
btnClassName,
|
|
)}
|
|
onClick={() => setOpen(!open)}
|
|
>
|
|
{Icon} {showBtnName && <span className="hidden md:inline-block">{btnName}</span>}
|
|
</button>
|
|
</div>
|
|
{open && (
|
|
<div
|
|
className="dropdown-content bg-base-100 rounded-box z-1 space-y-4 p-4 shadow-md shadow-sm"
|
|
style={{ minWidth: "500px", right: "40px" }}
|
|
>
|
|
<button
|
|
className="btn btn-xs btn-circle btn-ghost absolute right-2 top-2"
|
|
onClick={() => setOpen(false)}
|
|
type="button"
|
|
>
|
|
<span className="text-xl leading-none">×</span>
|
|
</button>
|
|
<h2 className="text-center text-xl font-bold">{btnName}</h2>
|
|
<textarea
|
|
value={reason}
|
|
onChange={(e) => setReason(e.target.value)}
|
|
className="input w-full"
|
|
placeholder="Begründung"
|
|
style={{ minHeight: "100px" }}
|
|
/>
|
|
{showDatePicker && (
|
|
<select
|
|
className="select select-bordered w-full"
|
|
value={until}
|
|
onChange={(e) => setUntil(e.target.value)}
|
|
>
|
|
<option value="default" disabled>
|
|
Keine
|
|
</option>
|
|
<option value="1h">1 Stunde</option>
|
|
<option value="6h">6 Stunden</option>
|
|
<option value="12h">12 Stunden</option>
|
|
<option value="24h">24 Stunden</option>
|
|
<option value="72h">72 Stunden</option>
|
|
<option value="1w">1 Woche</option>
|
|
<option value="2w">2 Wochen</option>
|
|
<option value="1m">1 Monat</option>
|
|
<option value="3m">3 Monate</option>
|
|
<option value="6m">6 Monate</option>
|
|
<option value="1y">1 Jahr</option>
|
|
</select>
|
|
)}
|
|
<button
|
|
className={cn("btn btn-square btn-soft tooltip tooltip-bottom w-full", btnClassName)}
|
|
data-tip={btnTip}
|
|
onClick={() => {
|
|
let untilDate: Date | null = null;
|
|
if (until !== "default") {
|
|
const now = new Date();
|
|
switch (until) {
|
|
case "1h":
|
|
untilDate = new Date(now.getTime() + 1 * 60 * 60 * 1000);
|
|
break;
|
|
case "6h":
|
|
untilDate = new Date(now.getTime() + 6 * 60 * 60 * 1000);
|
|
break;
|
|
case "12h":
|
|
untilDate = new Date(now.getTime() + 12 * 60 * 60 * 1000);
|
|
break;
|
|
case "24h":
|
|
untilDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
break;
|
|
case "72h":
|
|
untilDate = new Date(now.getTime() + 72 * 60 * 60 * 1000);
|
|
break;
|
|
case "1w":
|
|
untilDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
|
|
break;
|
|
case "2w":
|
|
untilDate = new Date(now.getTime() + 14 * 24 * 60 * 60 * 1000);
|
|
break;
|
|
case "1m":
|
|
untilDate = new Date(now.setMonth(now.getMonth() + 1));
|
|
break;
|
|
case "3m":
|
|
untilDate = new Date(now.setMonth(now.getMonth() + 3));
|
|
break;
|
|
case "6m":
|
|
untilDate = new Date(now.setMonth(now.getMonth() + 6));
|
|
break;
|
|
case "1y":
|
|
untilDate = new Date(now.setFullYear(now.getFullYear() + 1));
|
|
break;
|
|
default:
|
|
untilDate = null;
|
|
}
|
|
}
|
|
onClick({ reason, until: untilDate });
|
|
}}
|
|
>
|
|
{Icon} {btnName}
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
return (
|
|
<details className={"dropdown dropdown-left dropdown-center dropdown-open"}>
|
|
<summary
|
|
className={cn("btn btn-xs btn-square btn-soft", btnClassName)}
|
|
onClick={() => setOpen(true)}
|
|
></summary>
|
|
</details>
|
|
);
|
|
};
|