Feat: Add Synergy and Details to commander cards
This commit is contained in:
parent
d402c7f2d6
commit
dcbab5c99f
12 changed files with 253 additions and 29 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -22,6 +22,7 @@ app/next-env.d.ts
|
|||
app/tools/data/*
|
||||
app/data/misc/*
|
||||
app/data/commander/*
|
||||
app/data/card-commander/*
|
||||
app/data/bset/*
|
||||
app/tools/json/*
|
||||
app/.pg
|
||||
|
|
|
@ -23,5 +23,6 @@ tools/data/*
|
|||
tools/json
|
||||
data/misc/*
|
||||
data/commander/*
|
||||
data/card-commander/*
|
||||
data/bset/*
|
||||
.pg/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { useEffect, useState, useRef } from 'react'
|
||||
import { CardGroup } from '@/components/ui/card-group'
|
||||
import {PlaneswalkerIcon, SorceryIcon, InstantIcon, CreatureIcon, EnchantmentIcon, LandIcon, ArtifactIcon} from '@/components/ui/symbols-icons'
|
||||
import {CommanderIcon, PlaneswalkerIcon, SorceryIcon, InstantIcon, CreatureIcon, EnchantmentIcon, LandIcon, ArtifactIcon} from '@/components/ui/symbols-icons'
|
||||
|
||||
interface PageContentProps {
|
||||
bset: string
|
||||
|
@ -69,7 +69,7 @@ export default function PageContent({bset}: PageContentProps) {
|
|||
<div>
|
||||
<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">
|
||||
<CardGroup className="scroll-mt-16" groupName={"Commandants"} id="commander" showPercent={false} cards={commanderList} />
|
||||
<CardGroup className="scroll-mt-16" groupName={"Commandants"} Icon={CommanderIcon} id="commander" commanderUrl={true} showPercent={false} cards={commanderList} />
|
||||
<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={"Rituels"} Icon={SorceryIcon} id="sorcery" cards={sorceryList} />
|
||||
|
@ -80,7 +80,7 @@ export default function PageContent({bset}: PageContentProps) {
|
|||
</div>
|
||||
</div>
|
||||
<div className="fixed top-80 ml-8 flex flex-col gap-2 text-stone-500">
|
||||
<a href="#commander" className={ scrollState == "commander" ? "text-black text-2xl" : ""}>Commandants</a>
|
||||
<a href="#commander" className={`${scrollState == "commander" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><CommanderIcon className={scrollState == "commander" ? "h-5" : "h-4"} />Commandants</a>
|
||||
<a href="#planeswalker" className={`${scrollState == "planeswalker" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><PlaneswalkerIcon className={scrollState == "planeswalker" ? "h-5" : "h-4"} />Planeswalker</a>
|
||||
<a href="#creature" className={`${scrollState == "creature" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><CreatureIcon className={scrollState == "creature" ? "h-5" : "h-4"} />Créatures</a>
|
||||
<a href="#sorcery" className={`${scrollState == "sorcery" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><SorceryIcon className={scrollState == "sorcery" ? "h-5" : "h-4"} />Rituels</a>
|
||||
|
|
|
@ -17,7 +17,7 @@ export default function PageContent({color}: PageContentProps) {
|
|||
fetch('/api/json/commander/'+color+'.json').then((res) => {
|
||||
if(res.status == 200) {
|
||||
res.json().then((data) => {
|
||||
const limit = 20
|
||||
const limit = 100
|
||||
setCommanderCardList(data.slice(0,limit))
|
||||
setLoading(false)
|
||||
console.log(data)
|
||||
|
@ -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 mt-24 mb-24 max-w-6xl">
|
||||
{ loading && ( <Spinner className='mt-36' /> )}
|
||||
{ !loading && ( <CardGroup groupName={"Top commandants - " + color} showPercent={false} cards={commanderCardList} /> )}
|
||||
{ !loading && ( <CardGroup groupName={"Top commandants - " + color} showPercent={false} commanderUrl={true} cards={commanderCardList} /> )}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
10
app/app/commander/card/[card_name]/page.tsx
Normal file
10
app/app/commander/card/[card_name]/page.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
'use server'
|
||||
|
||||
import PageContent from './page_content'
|
||||
|
||||
export default async function Home({ params }: { params: { card_name: string } } ) {
|
||||
const card_name = (await params).card_name
|
||||
return (
|
||||
<PageContent card_name={card_name}/>
|
||||
);
|
||||
}
|
118
app/app/commander/card/[card_name]/page_content.tsx
Normal file
118
app/app/commander/card/[card_name]/page_content.tsx
Normal file
|
@ -0,0 +1,118 @@
|
|||
'use client'
|
||||
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { CardGroup } from '@/components/ui/card-group'
|
||||
|
||||
import { Spinner } from '@/components/ui/spinner'
|
||||
import {PlaneswalkerIcon, SorceryIcon, InstantIcon, CreatureIcon, EnchantmentIcon, LandIcon, ArtifactIcon} from '@/components/ui/symbols-icons'
|
||||
import { MTGCard } from '@/components/ui/mtg-card'
|
||||
|
||||
interface PageContentProps {
|
||||
card_name: string
|
||||
}
|
||||
|
||||
interface commanderCardData {
|
||||
name: string,
|
||||
normal_image: string,
|
||||
nbr_decks: number,
|
||||
total_decks: number,
|
||||
price: string,
|
||||
cardmarket_uri: string,
|
||||
}
|
||||
|
||||
export default function PageContent({card_name}: PageContentProps) {
|
||||
const [highSynergyList, setHighSynergyList] = useState([])
|
||||
const [creatureList, setCreatureList] = useState([])
|
||||
const [planeswalkerList, setPlaneswalkerList] = useState([])
|
||||
const [instantList, setInstantList] = useState([])
|
||||
const [sorceryList, setSorceryList] = useState([])
|
||||
const [artifactList, setArtifactList] = useState([])
|
||||
const [enchantmentList, setEnchantmentList] = useState([])
|
||||
const [landList, setLandList] = useState([])
|
||||
const [commanderCard, setCommanderCard] = useState<commanderCardData | null>(null)
|
||||
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const [scrollState, setScrollState] = useState("commander")
|
||||
const CardListRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/api/json/card-commander/'+card_name+'.json').then((res) => {
|
||||
if(res.status == 200) {
|
||||
res.json().then((data) => {
|
||||
setCommanderCard(data["card_data"])
|
||||
setHighSynergyList(data["high_synergy"])
|
||||
setCreatureList(data["creature"])
|
||||
setPlaneswalkerList(data["planeswalker"])
|
||||
setSorceryList(data["sorcery"])
|
||||
setInstantList(data["instant"])
|
||||
setEnchantmentList(data["enchantment"])
|
||||
setLandList(data["land"])
|
||||
setArtifactList(data["artifact"])
|
||||
setLoading(false)
|
||||
console.log(data)
|
||||
})
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const windowHeight = window.innerHeight
|
||||
const TOP_MARGIN = 0.1
|
||||
const BOTTOM_MARGIN = 0.2
|
||||
const card_children = CardListRef.current?.children
|
||||
if (card_children) {
|
||||
for (const child of card_children){
|
||||
const targetBounds = child.getBoundingClientRect()
|
||||
if( targetBounds.bottom > windowHeight * TOP_MARGIN && targetBounds.top < windowHeight * ( 1 - BOTTOM_MARGIN ) ) {
|
||||
setScrollState(child.id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add event listener to the window
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
|
||||
// Remove event listener when the component is unmounted
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<div>
|
||||
<div className="flex flex-col items-center w-full">
|
||||
<div className="flex flex-col items-center mt-24 mb-24 max-w-6xl">
|
||||
{ loading && ( <Spinner className='mt-36' /> )}
|
||||
{ !loading && (
|
||||
<div ref={CardListRef} className="flex flex-col items-center mt-24 gap-4 max-w-6xl">
|
||||
<div className="w-full flex flex-col items-center">
|
||||
<MTGCard className="w-64 h-auto" cardname={commanderCard!.name} imageURI={commanderCard!.normal_image} url={undefined} nbrDecks={commanderCard?.nbr_decks} totalDecks={commanderCard?.total_decks} price={commanderCard?.price} cardmarketURI={commanderCard?.cardmarket_uri}/>
|
||||
</div>
|
||||
<CardGroup className="scroll-mt-16" groupName={"Haute synergie"} Icon={undefined} id="highsynergy" cards={highSynergyList} />
|
||||
<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={"Rituels"} Icon={SorceryIcon} id="sorcery" cards={sorceryList} />
|
||||
<CardGroup className="scroll-mt-16" groupName={"Artefacts"} Icon={ArtifactIcon} id="artifact" cards={artifactList} />
|
||||
<CardGroup className="scroll-mt-16" groupName={"Éphémères"} Icon={InstantIcon} id="instant" cards={instantList} />
|
||||
<CardGroup className="scroll-mt-16" groupName={"Enchantements"} Icon={EnchantmentIcon} id="enchantment" cards={enchantmentList} />
|
||||
<CardGroup className="scroll-mt-16" groupName={"Terrains"} Icon={LandIcon} id="land" cards={landList} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="fixed top-80 ml-8 flex flex-col gap-2 text-stone-500">
|
||||
<a href="#highsynergy" className={`${scrollState == "highsynergy" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><PlaneswalkerIcon className={scrollState == "highsynergy" ? "h-5" : "h-4"} />Haute synergie</a>
|
||||
<a href="#planeswalker" className={`${scrollState == "planeswalker" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><PlaneswalkerIcon className={scrollState == "planeswalker" ? "h-5" : "h-4"} />Planeswalker</a>
|
||||
<a href="#creature" className={`${scrollState == "creature" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><CreatureIcon className={scrollState == "creature" ? "h-5" : "h-4"} />Créatures</a>
|
||||
<a href="#sorcery" className={`${scrollState == "sorcery" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><SorceryIcon className={scrollState == "sorcery" ? "h-5" : "h-4"} />Rituels</a>
|
||||
<a href="#artifact" className={`${scrollState == "artifact" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><ArtifactIcon className={scrollState == "artifact" ? "h-5" : "h-4"} />Artefacts</a>
|
||||
<a href="#instant" className={`${scrollState == "instant" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><InstantIcon className={scrollState == "instant" ? "h-5" : "h-4"} />Éphémères</a>
|
||||
<a href="#enchantment" className={`${scrollState == "enchantment" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><EnchantmentIcon className={scrollState == "enchantment" ? "h-5" : "h-4"} />Enchantements</a>
|
||||
<a href="#land" className={`${scrollState == "land" ? "text-black text-2xl" : "neutral-svg-filter"} flex flex-row items-center gap-1`}><LandIcon className={scrollState == "land" ? "h-5" : "h-4"} />Terrains</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -12,7 +12,7 @@ export default function Home() {
|
|||
fetch('/api/json/commander/top.json').then((res) => {
|
||||
if(res.status == 200) {
|
||||
res.json().then((data) => {
|
||||
const limit = 20
|
||||
const limit = 100
|
||||
setCommanderCardList(data.slice(0,limit))
|
||||
setLoading(false)
|
||||
console.log(data)
|
||||
|
@ -24,7 +24,7 @@ export default function Home() {
|
|||
<div className="flex flex-col items-center w-full">
|
||||
<div className="flex flex-col items-center mt-24 mb-24 max-w-6xl">
|
||||
{ loading && ( <Spinner className='mt-36' /> )}
|
||||
{ !loading && ( <CardGroup groupName="Top commandants" showPercent={false} cards={commanderCardList} /> )}
|
||||
{ !loading && ( <CardGroup groupName="Top commandants" commanderUrl={true} showPercent={false} cards={commanderCardList} /> )}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { MTGCardProps } from "@/components/ui/mtg-card"
|
||||
import { MTGCard } from '@/components/ui/mtg-card'
|
||||
|
||||
interface carte_from_stats {
|
||||
id: string,
|
||||
name: string,
|
||||
normal_image: string,
|
||||
url: string,
|
||||
sanitized_name: string,
|
||||
nbr_decks: number,
|
||||
total_decks: number,
|
||||
percent_decks: number,
|
||||
price: string,
|
||||
synergy?: number
|
||||
cardmarket_uri: string
|
||||
}
|
||||
|
||||
|
@ -23,11 +24,12 @@ interface CardGroupProps {
|
|||
showPrice?: boolean,
|
||||
showStats?: boolean,
|
||||
showPercent?: boolean,
|
||||
commanderUrl?: boolean,
|
||||
id?: string,
|
||||
Icon?: any
|
||||
}
|
||||
|
||||
const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true,showPercent=true, id, Icon}: CardGroupProps) => {
|
||||
const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true,showPercent=true, commanderUrl=false, id, Icon}: CardGroupProps) => {
|
||||
return (
|
||||
<div id={id} className={cn('flex flex-col w-full items-start',className)}>
|
||||
<div className="flex items-center flex-row gap-2 mb-2">
|
||||
|
@ -39,9 +41,11 @@ const CardGroup = ({ className, groupName, cards, showPrice=true, showStats=true
|
|||
<div
|
||||
className="flex flex-row flex-wrap gap-4"
|
||||
>
|
||||
|
||||
{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={showPercent ? card.percent_decks : undefined} price={card.price} cardmarketURI={card.cardmarket_uri}/>
|
||||
{cards.length == 0 && (
|
||||
<span>Pas de cartes...</span>
|
||||
)}
|
||||
{cards.length > 0 && cards.map((card: carte_from_stats) => (
|
||||
<MTGCard key={card.id} cardname={card.name} imageURI={card.normal_image} url={commanderUrl ? "/commander/card/" + card.url : undefined} nbrDecks={card.nbr_decks} totalDecks={card.total_decks} percentDecks={showPercent ? card.percent_decks : undefined} price={card.price} synergy={card.synergy} cardmarketURI={card.cardmarket_uri}/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,33 +4,35 @@ import { cn } from "@/lib/utils"
|
|||
import { Spinner } from "./spinner"
|
||||
|
||||
interface MTGCardProps {
|
||||
className?: string,
|
||||
imageURI: string,
|
||||
cardname: string,
|
||||
url: string,
|
||||
nbrDecks?: number,
|
||||
totalDecks?: number,
|
||||
percentDecks?: number,
|
||||
price?: string,
|
||||
className?: string,
|
||||
imageURI: string,
|
||||
cardname: string,
|
||||
url?: string,
|
||||
nbrDecks?: number,
|
||||
totalDecks?: number,
|
||||
percentDecks?: number,
|
||||
synergy?: number,
|
||||
price?: string,
|
||||
cardmarketURI?: string
|
||||
}
|
||||
|
||||
const MTGCard = ({ className, imageURI, cardname, url, nbrDecks, totalDecks, percentDecks, price, cardmarketURI }: MTGCardProps) => {
|
||||
const MTGCard = ({ className, imageURI, cardname, url, nbrDecks, totalDecks, percentDecks, price, synergy, cardmarketURI }: MTGCardProps) => {
|
||||
const [loaded, setLoaded] = React.useState(false)
|
||||
|
||||
return (
|
||||
<div
|
||||
<a
|
||||
className={cn(
|
||||
"flex flex-col w-48",
|
||||
className
|
||||
)}
|
||||
href={url != undefined ? url : "#"}
|
||||
>
|
||||
{!loaded &&
|
||||
<div className="flex flex-col items-center justify-center h-64 bg-stone-500 rounded-md">
|
||||
<Spinner />
|
||||
</div>
|
||||
}
|
||||
<img src={imageURI} className={ loaded ? "rounded h-64" : "absolute opacity-0" } onLoad={() => {setLoaded(true)}} loading="lazy" />
|
||||
<img src={imageURI} className={ cn(loaded ? "rounded h-64" : "absolute opacity-0", className) } onLoad={() => {setLoaded(true)}} loading="lazy" />
|
||||
<div className="flex flex-col items-center gap-0">
|
||||
{ price != undefined && (
|
||||
<a className="text-xs" href={cardmarketURI != undefined ? cardmarketURI : "#"} target={cardmarketURI != undefined ? "_blank" : "_self"}>{price}€</a>
|
||||
|
@ -42,8 +44,9 @@ const MTGCard = ({ className, imageURI, cardname, url, nbrDecks, totalDecks, per
|
|||
{ percentDecks != undefined && ( <span> sur {totalDecks} ({percentDecks}%)</span>)}</span>
|
||||
</>
|
||||
)}
|
||||
{ synergy != undefined && ( <span className="text-md">{synergy}% Synergie</span> )}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
)}
|
||||
MTGCard.displayName = "MTGCard"
|
||||
|
||||
|
|
|
@ -4,6 +4,12 @@ interface SymbolsIconProps {
|
|||
className: string
|
||||
}
|
||||
|
||||
const CommanderIcon = ({ className }: SymbolsIconProps) => {
|
||||
return (
|
||||
<img className={cn("h-4",className)} src="/assets/commander.svg"></img>
|
||||
)}
|
||||
CommanderIcon.displayName = "CommanderIcon"
|
||||
|
||||
const PlaneswalkerIcon = ({ className }: SymbolsIconProps) => {
|
||||
return (
|
||||
<img className={cn("h-4",className)} src="/assets/planeswalker.svg"></img>
|
||||
|
@ -46,4 +52,4 @@ const LandIcon = ({ className }: SymbolsIconProps) => {
|
|||
)}
|
||||
LandIcon.displayName = "LandIcon"
|
||||
|
||||
export { PlaneswalkerIcon, SorceryIcon, InstantIcon, CreatureIcon, ArtifactIcon, EnchantmentIcon, LandIcon }
|
||||
export { CommanderIcon, PlaneswalkerIcon, SorceryIcon, InstantIcon, CreatureIcon, ArtifactIcon, EnchantmentIcon, LandIcon }
|
||||
|
|
21
app/public/assets/commander.svg
Normal file
21
app/public/assets/commander.svg
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width="196.8"
|
||||
height="313.92001"
|
||||
viewBox="0 0 196.8 313.92001"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g1">
|
||||
<path
|
||||
style="display:inline;fill:#000000"
|
||||
d="M 96.320001,313.40138 C 95.076773,312.62187 81.49991,295.60736 80.997053,294.19868 l -0.442949,-1.24086 17.681525,-48.57366 c 9.724841,-26.71552 17.628161,-48.62183 17.562951,-48.68071 -0.35562,-0.32102 -44.593783,-24.28395 -45.05205,-24.40379 -0.398576,-0.10423 -2.71562,2.38823 -8.526912,9.17245 -4.388789,5.12356 -8.019833,9.49241 -8.068986,9.70854 -0.04915,0.21614 2.218848,9.13697 5.040001,19.82407 2.821152,10.6871 5.129368,19.61729 5.129368,19.84486 0,0.67091 -7.611897,21.35883 -8.174903,22.21809 -0.516408,0.78813 -2.229594,1.69234 -3.206458,1.69234 -0.287054,0 -1.017772,-0.2353 -1.623817,-0.52289 -0.897986,-0.42612 -1.652705,-1.44763 -4.078312,-5.52 C 25.682028,211.52918 11.152081,171.83985 4.3462228,130.56001 1.6197832,114.02322 0,95.660031 0,81.28766 0,75.078203 0.04263351,74.592113 0.65559264,73.812862 1.6837009,72.505834 96.232205,0.60704129 97.390241,0.25162984 98.163133,0.01442256 98.703079,0.05252569 99.531845,0.40275926 101.46605,1.220148 195.61007,73.16182 196.26493,74.32291 c 0.53622,0.950725 0.56848,1.636703 0.38742,8.237094 -0.49091,17.895296 -1.92443,33.081656 -4.6518,49.280006 -1.50352,8.92965 -2.43272,13.11567 -3.11571,14.03627 -0.92574,1.2478 -2.81622,1.79919 -4.24473,1.23805 -1.65348,-0.6495 -42.83099,-35.30468 -43.40168,-36.52705 -0.25352,-0.543 -3.68019,-12.839587 -7.61482,-27.325745 -3.93463,-14.486158 -7.20557,-26.376247 -7.26874,-26.422419 -0.25098,-0.183427 -34.012768,-12.007881 -34.083517,-11.937132 -0.195052,0.195051 -37.639624,61.515706 -37.768065,61.850426 -0.08113,0.21142 25.483777,21.8881 57.317352,48.59981 31.60509,26.51999 57.62644,48.52205 57.82522,48.89347 0.74334,1.38895 0.37554,2.9055 -1.99701,8.23432 -9.99817,22.45617 -22.91518,44.41087 -38.02711,64.63366 -5.70912,7.63994 -28.06775,35.27685 -29.19434,36.08634 -1.1768,0.84557 -2.941955,0.93211 -4.107399,0.20137 z"
|
||||
id="path1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -61,7 +61,19 @@ async function createJson() {
|
|||
include: {
|
||||
cards: {
|
||||
include: {
|
||||
decks: true,
|
||||
decks: {
|
||||
include: {
|
||||
deck: {
|
||||
include: {
|
||||
commander: {
|
||||
include: {
|
||||
decks_as_commander: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
decks_as_commander: true,
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +100,7 @@ async function createJson() {
|
|||
commanderData[colorName] = []
|
||||
}
|
||||
let bset_cards_data_export = {}
|
||||
let commander_details_export = {}
|
||||
|
||||
bsets.forEach((bset) => {
|
||||
let icons = []
|
||||
|
@ -124,6 +137,7 @@ async function createJson() {
|
|||
let card_object = {
|
||||
"name": card.name,
|
||||
"sanitized_name": card.sanitized_name,
|
||||
"url": card.set_code + "-" + card.sanitized_name,
|
||||
"normal_image": card.normal_image,
|
||||
"small_image": card.small_image,
|
||||
"type": card.type,
|
||||
|
@ -135,19 +149,46 @@ async function createJson() {
|
|||
"color_identity": card.color_identity,
|
||||
}
|
||||
|
||||
card_object.percent_decks = (card_object.total_decks != 0) ? parseInt(10000 * (card_object.nbr_decks / card_object.total_decks)) / 100 : 0
|
||||
card_object.percent_decks = (card_object.total_decks != 0) ? parseInt(100 * (card_object.nbr_decks / card_object.total_decks)) : 0
|
||||
|
||||
bset_cards_data_export[bset.sanitized_name][card.type].push(card_object)
|
||||
|
||||
card.decks.forEach((deck) => {
|
||||
const card_url_name = deck.deck.commander.set_code + "-" + deck.deck.commander.sanitized_name
|
||||
if(!Object.keys(commander_details_export).includes(card_url_name)) {
|
||||
commander_details_export[card_url_name] = {
|
||||
"card_data": deck.deck.commander,
|
||||
"creature": {},
|
||||
"land": {},
|
||||
"enchantment": {},
|
||||
"sorcery": {},
|
||||
"instant": {},
|
||||
"planeswalker": {},
|
||||
"artifact": {},
|
||||
}
|
||||
commander_details_export[card_url_name].card_data.nbr_decks = deck.deck.commander.decks_as_commander.length
|
||||
}
|
||||
|
||||
if(!Object.keys(commander_details_export[card_url_name][card.type]).includes(card.sanitized_name)) {
|
||||
let card_synergy_object = structuredClone(card_object)
|
||||
card_synergy_object.commander_total = 0
|
||||
commander_details_export[card_url_name][card.type][card.sanitized_name] = card_synergy_object
|
||||
}
|
||||
|
||||
commander_details_export[card_url_name][card.type][card.sanitized_name].commander_total += 1
|
||||
})
|
||||
|
||||
|
||||
if(card.can_be_commander) {
|
||||
let commander_card_object = structuredClone(card_object)
|
||||
commander_card_object.total_decks = bset.decks.length
|
||||
commander_card_object.nbr_decks = card.decks_as_commander != undefined ? card.decks_as_commander.length : 0
|
||||
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
|
||||
commander_card_object.percent_decks = (commander_card_object.total_decks != 0) ? parseInt(100 * (commander_card_object.nbr_decks / commander_card_object.total_decks)) : 0
|
||||
bset_cards_data_export[bset.sanitized_name]["commander"].push(commander_card_object)
|
||||
|
||||
const colorName = getColorName(card.color_identity)
|
||||
|
||||
|
||||
if(colorName != "") {
|
||||
commanderData[colorName].push(commander_card_object)
|
||||
commanderData["top"].push(commander_card_object)
|
||||
|
@ -164,12 +205,31 @@ async function createJson() {
|
|||
writeFileSync(import.meta.dirname + "/../data/commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
|
||||
}
|
||||
|
||||
for (const index of Object.keys(commander_details_export)) {
|
||||
let JSONToWrite = structuredClone(commander_details_export[index])
|
||||
JSONToWrite["high_synergy"] = []
|
||||
for (const type of ["creature","land","enchantment","sorcery","instant","planeswalker","artifact"]) {
|
||||
JSONToWrite[type] = []
|
||||
for (const card_key of Object.keys(commander_details_export[index][type])) {
|
||||
let card_object_synergy = commander_details_export[index][type][card_key]
|
||||
card_object_synergy.synergy = parseInt(100 * (card_object_synergy.commander_total / commander_details_export[index].card_data.nbr_decks) - card_object_synergy.percent_decks)
|
||||
JSONToWrite[type].push(card_object_synergy)
|
||||
}
|
||||
JSONToWrite[type].sort((a,b) => b.synergy - a.synergy || b.percent_decks - a.percent_decks || b.nbr_decks - a.nbr_decks)
|
||||
JSONToWrite["high_synergy"] = [...JSONToWrite["high_synergy"], ...JSONToWrite[type]]
|
||||
}
|
||||
|
||||
JSONToWrite["high_synergy"].sort((a,b) => b.synergy - a.synergy || b.percent_decks - a.percent_decks || b.nbr_decks - a.nbr_decks)
|
||||
JSONToWrite["high_synergy"] = JSONToWrite["high_synergy"].slice(0,15)
|
||||
writeFileSync(import.meta.dirname + "/../data/card-commander/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
|
||||
}
|
||||
|
||||
for (const index of Object.keys(bset_cards_data_export)) {
|
||||
let JSONToWrite = bset_cards_data_export[index]
|
||||
for (const type of Object.keys(JSONToWrite)) {
|
||||
JSONToWrite[type] = JSONToWrite[type].sort((a,b) => b.percent_decks - a.percent_decks || b.nbr_decks - a.nbr_decks)
|
||||
}
|
||||
writeFileSync(import.meta.dirname + "/../data/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
|
||||
writeFileSync(import.meta.dirname + "/../data/bset/" + index + ".json",JSON.stringify(JSONToWrite), 'utf8')
|
||||
}
|
||||
const end = performance.now()
|
||||
console.log(`Time taken to generate stats is ${(end - start)/1000}s.`);
|
||||
|
|
Loading…
Reference in a new issue