From aaa0bee85301d9f6d76c261e7be31577fdb30e25 Mon Sep 17 00:00:00 2001 From: globuzma Date: Fri, 27 Dec 2024 16:41:39 +0100 Subject: [PATCH] Feat: Add creating decks --- app/app/account/profile/decks/page.tsx | 265 ++++++++++++++++++++ app/app/admin/bsets/page.tsx | 1 - app/app/api/account/decks/create/route.ts | 141 +++++++++++ app/app/api/account/decks/delete/route.ts | 55 +++++ app/app/api/account/decks/route.ts | 41 ++++ app/app/api/auth/signin/route.ts | 2 +- app/app/api/deck/[:id]/route.ts | 36 +++ app/app/deck/[:id]/page.tsx | 49 ++++ app/app/top/black/page.tsx | 40 ++-- app/app/top/blue/page.tsx | 40 ++-- app/app/top/colorless/page.tsx | 42 ++-- app/app/top/green/page.tsx | 40 ++-- app/app/top/multicolor/page.tsx | 42 ++-- app/app/top/red/page.tsx | 40 ++-- app/app/top/white/page.tsx | 40 ++-- app/components/ui/label.tsx | 26 ++ app/components/ui/mtg-card.tsx | 21 +- app/components/ui/navigation-bar.tsx | 13 +- app/components/ui/popover.tsx | 33 +++ app/components/ui/textarea.tsx | 22 ++ app/package-lock.json | 279 ++++++++++++++++++++++ app/package.json | 2 + app/prisma/schema.prisma | 92 ++++--- app/tools/createBsets.mjs | 6 +- app/tools/createJson.mjs | 56 ++++- app/tools/updateDatabase.mjs | 35 +-- 26 files changed, 1279 insertions(+), 180 deletions(-) create mode 100644 app/app/account/profile/decks/page.tsx create mode 100644 app/app/api/account/decks/create/route.ts create mode 100644 app/app/api/account/decks/delete/route.ts create mode 100644 app/app/api/account/decks/route.ts create mode 100644 app/app/api/deck/[:id]/route.ts create mode 100644 app/app/deck/[:id]/page.tsx create mode 100644 app/components/ui/label.tsx create mode 100644 app/components/ui/popover.tsx create mode 100644 app/components/ui/textarea.tsx diff --git a/app/app/account/profile/decks/page.tsx b/app/app/account/profile/decks/page.tsx new file mode 100644 index 0000000..3292861 --- /dev/null +++ b/app/app/account/profile/decks/page.tsx @@ -0,0 +1,265 @@ +'use client' + +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" + +import { useEffect, useState } from "react" +import { useRouter } from 'next/navigation' +import { getCookie } from "@/lib/utils" +import { Textarea } from "@/components/ui/textarea" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" + +import type { deck, bset } from "@prisma/client"; + +interface bsetJson extends bset { + set_codes: string[], + icons: string[] +} + +interface cardEntryAPIProps { + amount: number, + sanitized_name: string, + set: string +} + +interface deckAPIProps { + name: string, + selected_bset: string, + commander_name: string, + cards: cardEntryAPIProps[] +} + +export default function Signin() { + const [deckName, setDeckName] = useState("") + const [deckCommanderName, setDeckCommanderName] = useState("") + const [deckImporter, setDeckImporter] = useState("") + const [selectedBset, setSelectedBset] = useState("") + const [decks, setDecks] = useState([]) + const [bsets, setBsets] = useState([]) + const [openSelectBset, setOpenSelectBset] = useState(false) + const router = useRouter() + const token = getCookie('JWT') + + useEffect(() => { + if(getCookie('JWT') == "") { + router.refresh() + router.push('/') + } + + fetch('http://localhost:3000/api/account/decks/', { + method: "GET", + headers: {Authorization: 'Bearer ' + token}, + }).then((res) => { + if(res.status == 200) { + res.json().then((apiData) => { + setDecks(apiData.data) + }) + } + }) + + fetch('http://localhost:8072/misc/bsets.json').then((res) => { + if(res.status == 200) { + res.json().then((data) => { + setBsets(data) + }) + } + }) + + },[]) + + function getDataFromLine(line: string){ + if(line != "") { + const values = line.split(" ") + if (values.length >= 4) { + const amount: number = parseInt(values.at(0)!.toString()) + + let set_index = 0 + for(let i = 1; i < values.length; i++){ + if(values.at(-i)!.toString().match(/\([A-Z]{3}\)/gm)){ + set_index = -i + } + } + + const set = values.at(set_index)!.toString().replace(/[()]/gm,"").toLowerCase() + const card_name = values.slice(1,set_index).join(" ").replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase() + const card_data : cardEntryAPIProps = {amount, sanitized_name: card_name, set} + return card_data + } else { + return null + } + } else { + return null + } + + } + + function deleteDeck(id:string){ + fetch('http://localhost:3000/api/account/decks/delete', { + method: "DELETE", + headers: {Authorization: 'Bearer ' + token}, + body: JSON.stringify({ id }) + }).then((res) => { + if(res.status == 200) { + setDecks(old => old.filter((deck: deck) => deck.id != id)) + } + }) + } + + function updateDeckInput(txt:string){ + setDeckImporter(txt) + const lines = txt.split("\n") + setDeckCommanderName(lines[0]) + } + + function importDeck(){ + const deckText = deckImporter + const lines = deckText.split("\n") + const dataToSend : deckAPIProps = { name: deckName, selected_bset: selectedBset.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase() ,commander_name: getDataFromLine(deckCommanderName)!.sanitized_name, cards: [] } + lines.slice(1).forEach((line: string) => { + const data = getDataFromLine(line) + if(data != null) { + dataToSend.cards.push(data) + } + }); + console.log(dataToSend) + + + fetch('http://localhost:3000/api/account/decks/create', { + method: "POST", + headers: {Authorization: 'Bearer ' + token}, + body: JSON.stringify(dataToSend) + }).then((res) => { + if(res.status == 200) { + res.json().then((apiData) => { + const new_deck: deck = apiData.data + setDecks(oldDecks => [...oldDecks, new_deck]) + setDeckName("") + setDeckImporter("") + setSelectedBset("") + setDeckCommanderName("") + }) + } + }) + } + + return ( +
+ + + Importer un deck + Depuis moxfield + + +
+
+ + setDeckName(e.target.value)} placeholder="Nom du deck" /> +
+
+ + + + + + + + + + Pas de BSet trouvé. + + {bsets.map((bset) => ( + { + setSelectedBset(currentValue === selectedBset ? "" : currentValue) + setOpenSelectBset(false) + }} + > +
+ {bset.icons.map((icon) => ( + + ))} +
+ {bset.name} +
+ ))} +
+
+
+
+
+
+
+ + + +
+
+ +