Fix: Last UI Fixes + better create JSON

This commit is contained in:
zuma 2025-02-12 20:05:02 +01:00
parent 0ea1d4a3e4
commit 29411757cb
12 changed files with 54 additions and 53 deletions
app
app
account/profile/decks
api/account/decks/create
bset/[bset]
commander
faq
page.tsx
components/ui
tools

View file

@ -301,7 +301,7 @@ export default function Signin() {
</div> </div>
<div className="flex flex-col gap-4 w-full"> <div className="flex flex-col gap-4 w-full">
<Input className="text-3xl" value={deckName} onChange={(e) => setDeckName(e.target.value)} placeholder="Nom du deck" /> <Input className="text-3xl" value={deckName} onChange={(e) => setDeckName(e.target.value)} placeholder="Nom du deck" />
<Input placeholder="URL du Deck (Facultatif)" /> <Input value={deckUrl} onChange={(e) => setDeckUrl(e.target.value)} placeholder="URL du Deck (Facultatif)" />
<Popover open={openSelectBset} onOpenChange={setOpenSelectBset}> <Popover open={openSelectBset} onOpenChange={setOpenSelectBset}>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button

View file

@ -75,6 +75,7 @@ export async function POST(req: NextRequest) {
let allCardFound = true let allCardFound = true
if(cardsData.findIndex(cardData => cardData.sanitized_name == commander_name) == -1){ if(cardsData.findIndex(cardData => cardData.sanitized_name == commander_name) == -1){
if(cardsData.findIndex(cardData => cardData.sanitized_name.includes(commander_name)) == -1){ if(cardsData.findIndex(cardData => cardData.sanitized_name.includes(commander_name)) == -1){
console.log("Not Found : " + commander_name)
allCardFound = false allCardFound = false
} }
} }
@ -82,6 +83,7 @@ export async function POST(req: NextRequest) {
if(cardsData.findIndex(cardData => cardData.sanitized_name == card.sanitized_name) == -1){ if(cardsData.findIndex(cardData => cardData.sanitized_name == card.sanitized_name) == -1){
if(cardsData.findIndex(cardData => cardData.sanitized_name.includes(card.sanitized_name)) == -1 ){ if(cardsData.findIndex(cardData => cardData.sanitized_name.includes(card.sanitized_name)) == -1 ){
allCardFound = false allCardFound = false
console.log("Not Found : " + card.sanitized_name)
} }
} }
}) })

View file

@ -25,7 +25,7 @@ export default function PageContent({bset}: PageContentProps) {
fetch('/api/json/bset/'+bset+'.json').then((res) => { fetch('/api/json/bset/'+bset+'.json').then((res) => {
if(res.status == 200) { if(res.status == 200) {
res.json().then((data) => { res.json().then((data) => {
const limit = 20 const limit = 100
setCommanderList(data["commander"].slice(0,limit)) setCommanderList(data["commander"].slice(0,limit))
setCreatureList(data["creature"].slice(0,limit)) setCreatureList(data["creature"].slice(0,limit))
setPlaneswalkerList(data["planeswalker"].slice(0,limit)) setPlaneswalkerList(data["planeswalker"].slice(0,limit))
@ -70,7 +70,7 @@ export default function PageContent({bset}: PageContentProps) {
<div> <div>
<div className="flex flex-col items-center w-full"> <div className="flex flex-col items-center w-full">
<div ref={CardListRef} className="flex flex-col items-center mt-24 gap-4 max-w-6xl"> <div ref={CardListRef} className="flex flex-col items-center mt-24 gap-4 max-w-6xl">
<CardGroup className="scroll-mt-16" groupName={"Commandants"} id="commander" cards={commanderList} /> <CardGroup className="scroll-mt-16" groupName={"Commandants"} id="commander" showPercent={false} cards={commanderList} />
<CardGroup className="scroll-mt-16" groupName={"Planeswalker"} Icon={PlaneswalkerIcon} id="planeswalker" cards={planeswalkerList} /> <CardGroup className="scroll-mt-16" groupName={"Planeswalker"} Icon={PlaneswalkerIcon} id="planeswalker" cards={planeswalkerList} />
<CardGroup className="scroll-mt-16" groupName={"Créatures"} Icon={CreatureIcon} id="creature" cards={creatureList} /> <CardGroup className="scroll-mt-16" groupName={"Créatures"} Icon={CreatureIcon} id="creature" cards={creatureList} />
<CardGroup className="scroll-mt-16" groupName={"Rituels"} Icon={SorceryIcon} id="sorcery" cards={sorceryList} /> <CardGroup className="scroll-mt-16" groupName={"Rituels"} Icon={SorceryIcon} id="sorcery" cards={sorceryList} />

View file

@ -29,7 +29,7 @@ export default function PageContent({color}: PageContentProps) {
<div className="flex flex-col items-center w-full"> <div className="flex flex-col items-center w-full">
<div className="flex flex-col items-center mt-24 mb-24 max-w-6xl"> <div className="flex flex-col items-center mt-24 mb-24 max-w-6xl">
{ loading && ( <Spinner className='mt-36' /> )} { loading && ( <Spinner className='mt-36' /> )}
{ !loading && ( <CardGroup groupName={"Top commandants - " + color} cards={commanderCardList} /> )} { !loading && ( <CardGroup groupName={"Top commandants - " + color} showPercent={false} cards={commanderCardList} /> )}
</div> </div>
</div> </div>
); );

View file

@ -24,7 +24,7 @@ export default function Home() {
<div className="flex flex-col items-center w-full"> <div className="flex flex-col items-center w-full">
<div className="flex flex-col items-center mt-24 mb-24 max-w-6xl"> <div className="flex flex-col items-center mt-24 mb-24 max-w-6xl">
{ loading && ( <Spinner className='mt-36' /> )} { loading && ( <Spinner className='mt-36' /> )}
{ !loading && ( <CardGroup groupName="Top commandants" cards={commanderCardList} /> )} { !loading && ( <CardGroup groupName="Top commandants" showPercent={false} cards={commanderCardList} /> )}
</div> </div>
</div> </div>
); );

12
app/app/faq/page.tsx Normal file
View file

@ -0,0 +1,12 @@
export default function Home() {
return (
<>
<div className="flex flex-col items-center mt-32">
<div className="flex flex-col items-center w-full">
<h1 className="text-3xl">Foire Aux Questions</h1>
<h2>WIP</h2>
</div>
</div>
</>
);
}

View file

@ -2,9 +2,10 @@ export default function Home() {
return ( return (
<> <>
<div className="flex flex-col items-center mt-32"> <div className="flex flex-col items-center mt-32">
<p className="mb-12 text-3xl text-orange-500">CE SITE EST EN COURS DE DEVELOPPEMENT - NE SAUVEGARDEZ PAS VOS DONNÉES UNIQUEMENT SUR BRAWLSET</p>
<h1 className="text-8xl font-beleren">The BrawlSet</h1> <h1 className="text-8xl font-beleren">The BrawlSet</h1>
<p className="text-center text-stone-500 mt-12">Un système de règles MTG basé sur le mode de jeu commander et inventé à Rennes, pays de la galette saucisse.<br></br> <p className="text-center text-stone-500 mt-12">Un système de règles MTG basé sur le mode de jeu commander et inventé à Rennes, pays de la galette saucisse.<br></br>
Pour plus d&apos;informations allez voir les <a className="text-orange-500">règles</a> ou la <a className="text-orange-500">FAQ</a>.</p> Pour plus d&apos;informations allez voir les <a href="/rules" className="text-orange-500">règles</a> ou la <a href="/faq" className="text-orange-500">FAQ</a>.</p>
</div> </div>
</> </>
); );

View file

@ -22,11 +22,12 @@ interface CardGroupProps {
cards: carte_from_stats[], cards: carte_from_stats[],
showPrice?: boolean, showPrice?: boolean,
showStats?: boolean, showStats?: boolean,
showPercent?: boolean,
id?: string, id?: string,
Icon?: any Icon?: any
} }
const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true, id, Icon}: CardGroupProps) => { const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true,showPercent=true, id, Icon}: CardGroupProps) => {
return ( return (
<div id={id} className={cn('flex flex-col w-full items-start',className)}> <div id={id} className={cn('flex flex-col w-full items-start',className)}>
<div className="flex items-center flex-row gap-2 mb-2"> <div className="flex items-center flex-row gap-2 mb-2">
@ -40,7 +41,7 @@ const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true
> >
{cards.map((card: carte_from_stats) => ( {cards.map((card: carte_from_stats) => (
<MTGCard key={card.id} cardname={card.name} imageURI={card.normal_image} url={"/card/" + card.sanitized_name} nbrDecks={card.nbr_decks} totalDecks={card.total_decks} percentDecks={card.percent_decks} price={card.price} cardmarketURI={card.cardmarket_uri}/> <MTGCard key={card.id} cardname={card.name} imageURI={card.normal_image} url={"/card/" + card.sanitized_name} nbrDecks={card.nbr_decks} totalDecks={card.total_decks} percentDecks={showPercent ? card.percent_decks : undefined} price={card.price} cardmarketURI={card.cardmarket_uri}/>
))} ))}
</div> </div>
</div> </div>

View file

@ -19,8 +19,7 @@ const MTGCard = ({ className, imageURI, cardname, url, nbrDecks, totalDecks, per
const [loaded, setLoaded] = React.useState(false) const [loaded, setLoaded] = React.useState(false)
return ( return (
<a <div
href={url}
className={cn( className={cn(
"flex flex-col w-48", "flex flex-col w-48",
className className
@ -39,11 +38,12 @@ const MTGCard = ({ className, imageURI, cardname, url, nbrDecks, totalDecks, per
<span className="text-center text-xs">{cardname}</span> <span className="text-center text-xs">{cardname}</span>
{ nbrDecks != undefined && ( { nbrDecks != undefined && (
<> <>
<span className="text-md">{nbrDecks} Deck{nbrDecks > 1 ? "s" : ""} sur {totalDecks} ({percentDecks}%)</span> <span className="text-md">{nbrDecks} Deck{nbrDecks > 1 ? "s" : ""}
{ percentDecks != undefined && ( <span> sur {totalDecks} ({percentDecks}%)</span>)}</span>
</> </>
)} )}
</div> </div>
</a> </div>
)} )}
MTGCard.displayName = "MTGCard" MTGCard.displayName = "MTGCard"

View file

@ -435,7 +435,7 @@ export function NavigationBar ({ isLoggedIn, username}: NavigationProps) {
{ !isLoggedIn && { !isLoggedIn &&
<> <>
<a href="/account/signin" className="text-stone-500">Connexion</a> <a href="/account/signin" className="text-stone-500">Connexion</a>
<Button disabled={true} className="text-stone-500">Inscription</Button> <a href="#" className="text-stone-500 cursor-not-allowed">Inscription</a>
</> </>
} }
{ {
@ -443,7 +443,6 @@ export function NavigationBar ({ isLoggedIn, username}: NavigationProps) {
<> <>
<a href="/account/profile/decks" className="flex flex-row items-center gap-2 text-stone-500">Decks</a> <a href="/account/profile/decks" className="flex flex-row items-center gap-2 text-stone-500">Decks</a>
<a href="/account/profile" className="flex flex-row items-center gap-2"> <a href="/account/profile" className="flex flex-row items-center gap-2">
<IconUserFilled color="stone-500" />
<span className="text-stone-500">{username}</span> <span className="text-stone-500">{username}</span>
</a> </a>
</> </>

View file

@ -1,5 +1,6 @@
import { PrismaClient } from '@prisma/client' import { PrismaClient } from '@prisma/client'
import { writeFileSync } from 'fs' import { writeFileSync } from 'fs'
import { performance } from 'perf_hooks'
const db = new PrismaClient() const db = new PrismaClient()
@ -48,24 +49,11 @@ function getColorName(colorArray) {
return "" return ""
} }
// I need to create
//
// Commanders
// top all
// top by colors
//
// bsets
// Commanders
//
//
// Lands
// lands.json
// All jsons lands from colors
// Types
async function createJson() { async function createJson() {
console.log("Fetching data...") const start = performance.now()
console.log(process.env.NODE_ENV) console.log(process.env.NODE_ENV)
console.log("Fetching data...")
const bsets = await db.bset.findMany({ const bsets = await db.bset.findMany({
relationLoadStrategy: "join", relationLoadStrategy: "join",
include: { include: {
@ -92,6 +80,7 @@ async function createJson() {
}) })
console.log("Creating stats...")
let bsets_list_export = [] let bsets_list_export = []
let all_cards = [] let all_cards = []
const commanderData = {"top": []} const commanderData = {"top": []}
@ -151,36 +140,32 @@ async function createJson() {
bset_cards_data_export[bset.sanitized_name][card.type].push(card_object) bset_cards_data_export[bset.sanitized_name][card.type].push(card_object)
if(card.can_be_commander) { if(card.can_be_commander) {
card_object.total_decks = bset.decks.length let commander_card_object = structuredClone(card_object)
card_object.nbr_decks = card.decks_as_commander != undefined ? card.decks_as_commander.length : 0 commander_card_object.total_decks = bset.decks.length
card_object.percent_decks = (card_object.total_decks != 0) ? parseInt(10000 * (card_object.nbr_decks / card_object.total_decks)) / 100 : 0 commander_card_object.nbr_decks = card.decks_as_commander != undefined ? card.decks_as_commander.length : 0
bset_cards_data_export[bset.sanitized_name]["commander"].push(card_object) commander_card_object.percent_decks = (commander_card_object.total_decks != 0) ? parseInt(10000 * (commander_card_object.nbr_decks / commander_card_object.total_decks)) / 100 : 0
bset_cards_data_export[bset.sanitized_name]["commander"].push(commander_card_object)
const colorName = getColorName(card.color_identity) const colorName = getColorName(card.color_identity)
if(colorName != "") { if(colorName != "") {
commanderData[colorName].push(card_object) commanderData[colorName].push(commander_card_object)
commanderData["top"].push(card_object) commanderData["top"].push(commander_card_object)
} }
} }
} }
}) })
console.log("Exporting stats...")
if(process.env.NODE_ENV == "production") { if(process.env.NODE_ENV == "production") {
console.log('Production detected !')
writeFileSync("/app/data/misc/bsets.json",JSON.stringify(bsets_list_export), 'utf8') writeFileSync("/app/data/misc/bsets.json",JSON.stringify(bsets_list_export), 'utf8')
} else { } else {
writeFileSync(import.meta.dirname + "/json/misc/bsets.json",JSON.stringify(bsets_list_export), 'utf8') writeFileSync(import.meta.dirname + "/json/misc/bsets.json",JSON.stringify(bsets_list_export), 'utf8')
} }
//for (const card of all_cards) {
//}
for (const index of Object.keys(commanderData)) { for (const index of Object.keys(commanderData)) {
let JSONToWrite = commanderData[index].sort((a,b) => b.percent_decks - a.percent_decks) let JSONToWrite = commanderData[index].sort((a,b) => b.nbr_decks - a.nbr_decks)
if(process.env.NODE_ENV == "production") { if(process.env.NODE_ENV == "production") {
console.log('Production detected !')
writeFileSync("/app/data/commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8') writeFileSync("/app/data/commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
} else { } else {
writeFileSync(import.meta.dirname + "/json/commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8') writeFileSync(import.meta.dirname + "/json/commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
@ -190,15 +175,16 @@ async function createJson() {
for (const index of Object.keys(bset_cards_data_export)) { for (const index of Object.keys(bset_cards_data_export)) {
let JSONToWrite = bset_cards_data_export[index] let JSONToWrite = bset_cards_data_export[index]
for (const type of Object.keys(JSONToWrite)) { for (const type of Object.keys(JSONToWrite)) {
JSONToWrite[type] = JSONToWrite[type].sort((a,b) => b.percent_decks - a.percent_decks) JSONToWrite[type] = JSONToWrite[type].sort((a,b) => b.nbr_decks - a.nbr_decks)
} }
if(process.env.NODE_ENV == "production") { if(process.env.NODE_ENV == "production") {
console.log('Production detected !')
writeFileSync("/app/data/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8') writeFileSync("/app/data/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
} else { } else {
writeFileSync(import.meta.dirname + "/json/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8') writeFileSync(import.meta.dirname + "/json/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
} }
} }
const end = performance.now()
console.log(`Time taken to generate stats is ${end - start}ms.`);
} }
createJson() createJson()

View file

@ -9,7 +9,7 @@ const { Client } = pg
console.log("Fetching latest Scryfall Bulk Data URL...") console.log("Fetching latest Scryfall Bulk Data URL...")
const bulkDataApi = await fetch('https://api.scryfall.com/bulk-data') const bulkDataApi = await fetch('https://api.scryfall.com/bulk-data')
const bulkDataApiJson = await bulkDataApi.json() const bulkDataApiJson = await bulkDataApi.json()
const bulkDataDownloadUrl = bulkDataApiJson.data.filter((obj) => obj.type == "unique_artwork")[0].download_uri const bulkDataDownloadUrl = bulkDataApiJson.data.filter((obj) => obj.type == "default_cards")[0].download_uri
console.log("Downloading latest Scryfall Bulk Data...") console.log("Downloading latest Scryfall Bulk Data...")
const stream = fs.createWriteStream(import.meta.dirname + '/data/scryfall_data.json'); const stream = fs.createWriteStream(import.meta.dirname + '/data/scryfall_data.json');