mirror of
https://gitea.tendokyu.moe/ppc/amnet.git
synced 2026-10-06 05:37:58 +03:00
add card management page and generic component
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import {Separator} from "@/components/ui/separator";
|
||||
import {Footer} from "@/components/footer";
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {CreditCard, Plus, ServerCog, Trash} from "lucide-react";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {useLiveQuery} from "dexie-react-hooks";
|
||||
import {AimeCard, db} from "@/lib/database";
|
||||
import {LoadingIndicator} from "@/components/loading-indicator";
|
||||
import {CardCreationDialog} from "@/components/card-creation-form";
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuTrigger
|
||||
} from "@/components/ui/context-menu";
|
||||
import {AimeCardEntry} from "@/components/aime-card";
|
||||
|
||||
function CardAddButton() {
|
||||
return (
|
||||
<CardCreationDialog>
|
||||
<Button className="bg-blue-500">
|
||||
<Plus className="mr-2 h-4 w-4"/> Add Card
|
||||
</Button>
|
||||
</CardCreationDialog>
|
||||
);
|
||||
}
|
||||
|
||||
function CardList(props: { cards: AimeCard[] | undefined }) {
|
||||
if (!props.cards) {
|
||||
return (<LoadingIndicator/>);
|
||||
}
|
||||
|
||||
if (!props.cards.length) {
|
||||
return (<>
|
||||
<CardAddButton/>
|
||||
<div className="flex flex-col gap-2 items-center text-gray-500 pt-6 pb-5">
|
||||
<CreditCard className="h-8 w-8"/>
|
||||
<span className="text-center">No cards found</span>
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<CardAddButton/>
|
||||
|
||||
{props.cards.map(s =>
|
||||
<ContextMenu key={s.id}>
|
||||
<ContextMenuTrigger>
|
||||
<AimeCardEntry card={s}/>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem className="text-red-500" onClick={() => db.cards.delete(s.id)}>
|
||||
<Trash className="mr-2 h-4 w-4"/> Remove
|
||||
</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>)}
|
||||
</>);
|
||||
}
|
||||
|
||||
export default function CardManagerPage() {
|
||||
const router = useRouter();
|
||||
const cards = useLiveQuery(() => db.cards.toArray());
|
||||
|
||||
return (
|
||||
<main className="flex flex-col gap-5 container min-h-screen py-10">
|
||||
<div className="flex items-center gap-1">
|
||||
<h2 className="text-4xl font-bold select-none flex-grow">Cards</h2>
|
||||
<Button variant="ghost" size={"default"} onClick={() => router.push('/')}>
|
||||
<ServerCog className="h-4 w-4 sm:mr-2"/>
|
||||
<span className="hidden sm:block">Manage Servers</span>
|
||||
</Button>
|
||||
</div>
|
||||
<Separator/>
|
||||
|
||||
<div className="flex flex-col gap-4 w-full flex-grow">
|
||||
<CardList cards={cards}/>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import {CreditCard} from "lucide-react";
|
||||
import {Card} from "@/components/ui/card";
|
||||
import React from "react";
|
||||
import {AimeCard} from "@/lib/database";
|
||||
|
||||
export function AimeCardEntry(props: { card: AimeCard, children?: Readonly<React.ReactNode> }) {
|
||||
return (
|
||||
<Card>
|
||||
<div className="flex p-4 items-center gap-3">
|
||||
<div className="flex-grow flex flex-col gap-4">
|
||||
<h4 className="text-2xl font-semibold">{props.card.name}</h4>
|
||||
<div className="flex items-center gap-2 text-gray-500">
|
||||
<CreditCard className="h-5 w-5"/>
|
||||
<code>{props.card.id.match(/.{1,4}/g)?.join(" ")}</code>
|
||||
</div>
|
||||
</div>
|
||||
{props.children}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user