shared library hinzugefügt
This commit is contained in:
28
packages/shared-components/components/Badge.tsx
Normal file
28
packages/shared-components/components/Badge.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { BADGES } from "@repo/db";
|
||||
import { cn } from "../../../apps/hub/helper/cn";
|
||||
import * as React from "react";
|
||||
|
||||
const badgeImageMapping = {
|
||||
[BADGES.P1]: "p-1.png",
|
||||
[BADGES.P2]: "p-2.png",
|
||||
[BADGES.P3]: "p-3.png",
|
||||
[BADGES.D1]: "d-1.png",
|
||||
[BADGES.D2]: "d-2.png",
|
||||
[BADGES.D3]: "d-3.png",
|
||||
[BADGES.DAY1]: "day-1-member.png",
|
||||
[BADGES.V1Veteran]: "v1-veteran.png",
|
||||
};
|
||||
|
||||
export const Badge = ({ badge, className }: { badge: BADGES; className?: string }) => {
|
||||
return (
|
||||
<span className={cn("h-fit p-1 flex justify-center items-center", className)}>
|
||||
<img
|
||||
src={`${process.env.NEXT_PUBLIC_HUB_URL}/badges/${badgeImageMapping[badge]}`}
|
||||
alt="Badge"
|
||||
width="80"
|
||||
height="auto"
|
||||
className="block h-auto max-h-[80px] w-auto"
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
106
packages/shared-components/components/PenaltyDropdown.tsx
Normal file
106
packages/shared-components/components/PenaltyDropdown.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
"use client";
|
||||
import { ReactNode, useState } from "react";
|
||||
import { cn } from "../helper/cn";
|
||||
|
||||
export const PenaltyDropdown = ({
|
||||
onClick,
|
||||
btnClassName,
|
||||
showDatePicker,
|
||||
btnTip,
|
||||
Icon,
|
||||
}: {
|
||||
onClick: (data: { reason: string; until: Date | null }) => void;
|
||||
showDatePicker?: boolean;
|
||||
btnClassName?: string;
|
||||
btnTip?: string;
|
||||
Icon: ReactNode;
|
||||
}) => {
|
||||
const [reason, setReason] = useState("");
|
||||
const [until, setUntil] = useState<string>("default");
|
||||
return (
|
||||
<details className="dropdown dropdown-left dropdown-center">
|
||||
<summary className={cn("btn btn-xs btn-square btn-soft", btnClassName)}>{Icon}</summary>
|
||||
<div className="dropdown-content flex gap-3 items-center bg-base-100 rounded-box z-1 p-2 mr-3 shadow-sm">
|
||||
<input
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
type="text"
|
||||
className="input min-w-[250px]"
|
||||
placeholder="Begründung"
|
||||
/>
|
||||
{showDatePicker && (
|
||||
<select
|
||||
className="select min-w-[150px] select-bordered"
|
||||
value={until}
|
||||
onChange={(e) => setUntil(e.target.value)}
|
||||
>
|
||||
<option value="default" disabled>
|
||||
Unbegrenzt
|
||||
</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", 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}
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
);
|
||||
};
|
||||
2
packages/shared-components/components/index.ts
Normal file
2
packages/shared-components/components/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./Badge";
|
||||
export * from "./PenaltyDropdown";
|
||||
6
packages/shared-components/helper/cn.ts
Normal file
6
packages/shared-components/helper/cn.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import clsx, { ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export const cn = (...inputs: ClassValue[]) => {
|
||||
return twMerge(clsx(inputs));
|
||||
};
|
||||
1
packages/shared-components/helper/index.ts
Normal file
1
packages/shared-components/helper/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./cn";
|
||||
2
packages/shared-components/index.ts
Normal file
2
packages/shared-components/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./components";
|
||||
export * from "./helper";
|
||||
22
packages/shared-components/package.json
Normal file
22
packages/shared-components/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@repo/shared-components",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.ts"
|
||||
},
|
||||
"main": "index.ts",
|
||||
"dependencies": {
|
||||
"@repo/db": "workspace:*",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@types/node": "^22.15.29",
|
||||
"clsx": "^2.1.1",
|
||||
"tailwind-merge": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.6",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
}
|
||||
}
|
||||
10
packages/shared-components/tsconfig.json
Normal file
10
packages/shared-components/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@repo/typescript-config/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"jsx": "react-jsx",
|
||||
"types": ["node", "react"]
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user