From 84fa0947e1918f9bbdebae22a9c0fc794e416ed2 Mon Sep 17 00:00:00 2001 From: ppc Date: Wed, 7 Aug 2024 22:58:18 +0100 Subject: [PATCH] add card-in page --- aimenet-web/app/cards/page.tsx | 7 +- aimenet-web/app/layout.tsx | 1 + aimenet-web/app/servers/[serverId]/page.tsx | 174 ++++++++++++++++++ aimenet-web/components/aime-card.tsx | 17 +- .../components/no-cards-notification.tsx | 9 + 5 files changed, 199 insertions(+), 9 deletions(-) create mode 100644 aimenet-web/app/servers/[serverId]/page.tsx create mode 100644 aimenet-web/components/no-cards-notification.tsx diff --git a/aimenet-web/app/cards/page.tsx b/aimenet-web/app/cards/page.tsx index 8350aca..715ce93 100644 --- a/aimenet-web/app/cards/page.tsx +++ b/aimenet-web/app/cards/page.tsx @@ -18,6 +18,7 @@ import { } from "@/components/ui/context-menu"; import {AimeCardEntry} from "@/components/aime-card"; import {IncognitoStorageWarning} from "@/components/incognito-warning"; +import {NoCardsNotification} from "@/components/no-cards-notification"; function CardAddButton() { return (<> @@ -34,11 +35,7 @@ function CardList(props: { cards: AimeCard[] | undefined }) { if (!props.cards?.length) { return (<> - -
- - No cards found -
+ ); } diff --git a/aimenet-web/app/layout.tsx b/aimenet-web/app/layout.tsx index 4371073..84845f5 100644 --- a/aimenet-web/app/layout.tsx +++ b/aimenet-web/app/layout.tsx @@ -3,6 +3,7 @@ import {Inter as FontSans} from "next/font/google"; import {cn} from "@/lib/utils"; import "./globals.css"; import {ThemeProvider} from "@/components/theme-provider"; +import {Toaster} from "@/components/ui/toaster"; const fontSans = FontSans({ subsets: ["latin"], diff --git a/aimenet-web/app/servers/[serverId]/page.tsx b/aimenet-web/app/servers/[serverId]/page.tsx new file mode 100644 index 0000000..b028fd1 --- /dev/null +++ b/aimenet-web/app/servers/[serverId]/page.tsx @@ -0,0 +1,174 @@ +"use client"; + +import {useLiveQuery} from "dexie-react-hooks"; +import React, {useEffect, useState} from "react"; +import {useParams, useRouter} from "next/navigation"; +import {ChevronRight, Circle, CircleCheckBig, Home, Plus, ServerOff} from "lucide-react"; +import {AimeCard, AimeServer, db} from "@/lib/database"; +import {getServerInfo, serverCardIn} from "@/lib/aime-net"; +import {Button} from "@/components/ui/button"; +import {Footer} from "@/components/footer"; +import {Toaster} from "@/components/ui/toaster"; +import {useToast} from "@/components/ui/use-toast"; +import {Separator} from "@/components/ui/separator"; +import {AimeCardEntry} from "@/components/aime-card"; +import {LoadingIndicator} from "@/components/loading-indicator"; +import {CardCreationDialog} from "@/components/card-creation-form"; +import {NoCardsNotification} from "@/components/no-cards-notification"; +import {Alert, AlertDescription, AlertTitle} from "@/components/ui/alert"; +import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip"; + +function CardList(props: { cards: ReadonlyArray | null, cardSelected: (card: AimeCard) => void }) { + return (<> +

{props.cards?.length ? "Cards" : "Additional Cards"}

+ + + + + {props.cards?.length ? props.cards.map(x => + + + + + + +

Select Card

+
+
+
+
) : } + ); +} + +async function performCardInAction(card: AimeCard, server: AimeServer, setCardInStatus: (status: boolean) => void, toaster: any) { + setCardInStatus(true); + + try { + await serverCardIn(server.address, card.id); + await db.cards.update(card.id, {lastUsed: Date.now()}); + + setTimeout(() => setCardInStatus(false), 1000); + toaster({ + title: "Card In Success", + description: "Card in request has been sent successfully.", + duration: 5000 + }); + } catch { + toaster({ + variant: "destructive", + title: "Card in failed", + description: "Failed to perform card in action. Please try again.", + duration: 5000 + }); + + setTimeout(() => setCardInStatus(false), 1000); + } +} + +export default function ServerPage() { + const {serverId} = useParams<{ serverId: string }>(); + + const {toast} = useToast(); + const router = useRouter(); + const cards = useLiveQuery(() => db.cards.toArray()); + + const [server, setServer] = useState(null); + const [connectionError, setConnectionError] = useState(false); + const [cardInStatus, setCardInStatus] = useState(false); + const [selectedCard, setSelectedCard] = useState(null); + + // select newest card + useEffect(() => setSelectedCard(cards?.sort(x => x.lastUsed)[0]), [cards]); + useEffect(() => { + const loadServer = async () => { + const sid = parseInt(serverId); + if (isNaN(sid)) { + router.push('/'); + return; + } + + const server = await db.servers.get(sid); + if (!server) { + router.push('/'); + return; + } + + try { + const info = await getServerInfo(server.address); + + server.name = info.name; + server.lastConnected = Date.now(); + + setConnectionError(false); + await db.servers.put(server); + } catch { + setConnectionError(true); + } + + setServer(server); + }; + + loadServer().catch(console.error); + }, [serverId]); + + return ( + <> +
+
+

{server?.name ?? "Server"}

+ +
+ + + {!server && ()} + {(server && connectionError) && ( + + Connection Issue + + There was an issue connecting to the machine at {server.address}. Please check the + server is running and try again. + + )} + +
+ {selectedCard && (<> +

Selected Card

+ + + + + + + )} + + x !== selectedCard).sort(x => x.lastUsed) ?? null} + cardSelected={card => { + toast({ + duration: 2500, + title: "Card Selected", + description: `${card.name} has been selected.` + }); + + setSelectedCard(card); + }}/> +
+
+
+ + + + ); +} \ No newline at end of file diff --git a/aimenet-web/components/aime-card.tsx b/aimenet-web/components/aime-card.tsx index 6969fff..a1387bf 100644 --- a/aimenet-web/components/aime-card.tsx +++ b/aimenet-web/components/aime-card.tsx @@ -1,7 +1,8 @@ -import {CreditCard} from "lucide-react"; +import {CreditCard, History} from "lucide-react"; import {Card} from "@/components/ui/card"; import React from "react"; import {AimeCard} from "@/lib/database"; +import TimeAgo from "react-timeago"; export function AimeCardEntry(props: { card: AimeCard, children?: Readonly }) { return ( @@ -9,9 +10,17 @@ export function AimeCardEntry(props: { card: AimeCard, children?: Readonly

{props.card.name}

-
- - {props.card.id.match(/.{1,4}/g)?.join(" ")} +
+ {props.card.lastUsed > 0 && ( +
+ + +
+ )} +
+ + {props.card.id.match(/.{1,4}/g)?.join(" ")} +
{props.children} diff --git a/aimenet-web/components/no-cards-notification.tsx b/aimenet-web/components/no-cards-notification.tsx new file mode 100644 index 0000000..8dae16a --- /dev/null +++ b/aimenet-web/components/no-cards-notification.tsx @@ -0,0 +1,9 @@ +import {CreditCard} from "lucide-react"; +import React from "react"; + +export function NoCardsNotification() { + return (
+ + No cards found +
); +} \ No newline at end of file