Skip to content

Commit 2af8686

Browse files
committed
Add recipies and specialty links
1 parent 42748f3 commit 2af8686

File tree

6 files changed

+161
-34
lines changed

6 files changed

+161
-34
lines changed

components/Icon.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,37 @@ export function IconName({ name, type, urltype, loading = "lazy" }: { name: stri
2424
</FormattedLink>
2525
}
2626

27-
export function SmallIcon({ thing, location }: { thing: SmallThing, location: string }) {
27+
export function SmallIcon({ thing, location, sizeSet = "m", children }: { thing: SmallThing, location: string, sizeSet?: "m" | "s", children?: any }) {
2828
const color = getStarColor((hasStars(thing) ? thing.stars : 0) ?? 0)
29+
const sizes = {
30+
m: "w-24 sm:w-28 lg:w-32",
31+
s: "w-10 sm:w-12 lg:w-14"
32+
}
2933

30-
return <FormattedLink key={thing.name} location={location} href={`/${thing.urlpath}/${urlify(thing.name, false)}`} className="bg-slate-300 dark:bg-slate-800 w-24 sm:w-28 lg:w-32 m-1 relative rounded-xl transition-all duration-100 hover:outline outline-slate-800 dark:outline-slate-300 font-bold text-sm" >
31-
<div className={`${color} rounded-t-xl h-24 sm:h-28 lg:h-32`}>
32-
<Icon icon={thing} className="rounded-t-xl m-0 p-0" />
33-
<span className="absolute block p-0.5 top-0 w-full">
34+
return <><FormattedLink key={thing.name} location={location} href={`/${thing.urlpath}/${urlify(thing.name, false)}`} className={`bg-slate-300 dark:bg-slate-800 ${sizes[sizeSet]} m-1 relative rounded-xl transition-all duration-100 hover:outline outline-slate-800 dark:outline-slate-300 font-bold text-sm`} >
35+
<div className={`${color} rounded-xl ${sizes[sizeSet]}`}>
36+
<Icon icon={thing} className={`${sizeSet == "s" ? "rounded-xl" : "rounded-t-xl"} m-0 p-0`} />
37+
{hasElement(thing) && thing.element && sizeSet != "s" && <span className="absolute block p-0.5 top-0 w-full">
3438
<div className="flex flex-col">
35-
{hasElement(thing) && thing.element && thing.element.map(e => <div key={e} className="w-6 md:w-8">
39+
{thing.element.map(e => <div key={e} className="w-6 md:w-8">
3640
<Image src={elements[e]} alt={`${e} Element`} loading="eager" />
3741
</div>)}
3842
</div>
39-
</span>
40-
<span className="absolute block p-0.5 top-0 w-full">
43+
</span>}
44+
{hasWeapon(thing) && thing.weapon && sizeSet != "s" && <span className="absolute block p-0.5 top-0 w-full">
4145
<div className="flex flex-col float-right">
42-
{hasWeapon(thing) && thing.weapon && <div className="w-6 md:w-8">
46+
<div className="w-6 md:w-8">
4347
<Image src={weapons[thing.weapon]} alt={thing.weapon} loading="eager" />
44-
</div>}
48+
</div>
4549
</div>
46-
</span>
50+
</span>}
4751
</div>
48-
<span className={`flex justify-center items-center m-0 p-0 px-1 ${thing.name.length > 27 ? "text-xs md:text-xs" : thing.name.length > 20 ? "text-sm md:text-sm" : ""} duration-200 md:text-base ${styles.iconHeight}`}>
52+
{sizeSet != "s" && <span className={`flex justify-center items-center m-0 p-0 px-1 ${thing.name.length > 27 ? "text-xs md:text-xs" : thing.name.length > 20 ? "text-sm md:text-sm" : ""} duration-200 md:text-base ${styles.iconHeight}`}>
4953
{thing.name}
50-
</span>
54+
</span>}
5155
</FormattedLink>
56+
{children && <FormattedLink location={location} href={`/${thing.urlpath}/${urlify(thing.name, false)}`}>{children}</FormattedLink>}
57+
</>
5258
}
5359

5460
function hasElement(char: SmallThing): char is SmallChar {

components/Specialty.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { SmallChar, SmallMaterial } from "../utils/types"
2+
import { SmallIcon } from "./Icon"
3+
4+
export interface SpecialtyItem {
5+
special: SmallMaterial,
6+
char: SmallChar,
7+
recipe: SmallMaterial
8+
}
9+
10+
export function Specialty({ specialty, location }: { specialty: SpecialtyItem, location: string }) {
11+
return <div className="flex flex-wrap justify-start text-center items-center mt-2 gap-1">
12+
<SmallIcon thing={specialty.special} location={location} sizeSet="s">{specialty.special.name}</SmallIcon>
13+
<div>be obtained by using </div>
14+
<SmallIcon thing={specialty.char} location={location} sizeSet="s">{specialty.char.name}</SmallIcon>
15+
<div> while cooking </div>
16+
<SmallIcon thing={specialty.recipe} location={location} sizeSet="s">{specialty.recipe.name}</SmallIcon>
17+
</div>
18+
}

pages/characters/[char].tsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@ import Guides from "../../components/Guides"
99
import Icon from "../../components/Icon"
1010
import Main from "../../components/Main"
1111
import { MaterialCost, MaterialImage } from "../../components/Material"
12+
import { Specialty, SpecialtyItem } from "../../components/Specialty"
1213
import { FullAscensionCosts } from "../../components/Tables"
1314
import YouTube from "../../components/YouTube"
14-
import { CharacterCurves, CostTemplates, getCharacterCurves, getCharacters, getCostTemplates } from "../../utils/data-cache"
15+
import { CharacterCurves, CostTemplates, getCharacterCurves, getCharacters, getCostTemplates, getMaterials } from "../../utils/data-cache"
1516
import { Character, CharacterFull, Constellation, CostTemplate, CurveEnum, Meta, Passive, Skill, Skills, TalentTable, TalentValue } from "../../utils/types"
16-
import { elements, ElementType, getCharStatsAt, getCostsFromTemplate, getGuidesFor, getIconPath, getLinkToGuide, getStarColor, isFullCharacter, isValueTable, joinMulti, stat, urlify, weapons } from "../../utils/utils"
17+
import { createSmallChar, createSmallMaterial, elements, ElementType, getCharStatsAt, getCostsFromTemplate, getGuidesFor, getIconPath, getLinkToGuide, getStarColor, isFullCharacter, isValueTable, joinMulti, stat, urlify, weapons } from "../../utils/utils"
1718
import styles from "../style.module.css"
1819

1920
interface Props {
2021
char: Character,
2122
characterCurves: CharacterCurves | null
2223
costTemplates: CostTemplates | null
24+
specialty: SpecialtyItem | null
2325
guides?: string[][]
2426
}
2527

26-
export default function CharacterWebpage({ char, location, characterCurves, costTemplates, guides }: Props & { location: string }) {
28+
export default function CharacterWebpage({ char, location, characterCurves, costTemplates, guides, specialty }: Props & { location: string }) {
2729
const charElems = char.skills?.map(skill => skill.ult?.type).filter(x => x) as ElementType[] ?? [char.meta.element]
2830
const multiskill = (char.skills?.length ?? 0) > 1
2931
const color = getStarColor(char.star ?? 0)
@@ -103,6 +105,10 @@ export default function CharacterWebpage({ char, location, characterCurves, cost
103105
{isFullCharacter(char) && characterCurves && <Stats char={char} curves={characterCurves} />}
104106
{char.ascensionCosts && costTemplates && <FullAscensionCosts template={char.ascensionCosts} costTemplates={costTemplates} />}
105107
{char.meta && <MetaSection meta={char.meta} />}
108+
{specialty && <>
109+
<h3 className="text-lg font-bold pt-1" id="specialty">Specialty:</h3>
110+
<Specialty specialty={specialty} location={location} />
111+
</>}
106112
{char.media.videos && <Videos videos={char.media.videos} />}
107113
{char.skills && costTemplates && <CharacterSkills skills={char.skills} costTemplates={costTemplates} />}
108114
</div>
@@ -472,9 +478,26 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
472478

473479
const guides = (await getGuidesFor("character", char.name))?.map(({ guide, page }) => [page.name, getLinkToGuide(guide, page)])
474480

481+
let specialty: SpecialtyItem | null = null
482+
483+
const mats = await getMaterials()
484+
const special = Object.values(mats ?? {}).find(m => m.specialty?.char == char.name)
485+
if (special) {
486+
const recipe = Object.values(mats ?? {}).find(m => m.name == special.specialty?.recipe)
487+
488+
if (recipe)
489+
specialty = {
490+
special: createSmallMaterial(special),
491+
char: createSmallChar(char),
492+
recipe: createSmallMaterial(recipe)
493+
}
494+
}
495+
496+
475497
return {
476498
props: {
477499
char,
500+
specialty,
478501
characterCurves,
479502
costTemplates,
480503
guides

pages/materials/[material].tsx

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@ import FormattedLink from "../../components/FormattedLink"
66
import Guides from "../../components/Guides"
77
import Icon, { SmallIcon } from "../../components/Icon"
88
import Main from "../../components/Main"
9-
import { CostTemplates, getCharacters, getCostTemplates, getMaterials, getWeapons } from "../../utils/data-cache"
10-
import { Cost, CostTemplate, Material, SmallChar, SmallWeapon } from "../../utils/types"
11-
import { clean, createSmallChar, createSmallWeapon, getCostsFromTemplate, getGuidesFor, getIconPath, getLinkToGuide, getStarColor, isInCosts, joinMulti, urlify } from "../../utils/utils"
9+
import { MaterialCost } from "../../components/Material"
10+
import { Specialty, SpecialtyItem } from "../../components/Specialty"
11+
import { getCharacters, getCostTemplates, getMaterials, getWeapons } from "../../utils/data-cache"
12+
import { Material, SmallChar, SmallMaterial, SmallWeapon } from "../../utils/types"
13+
import { clean, createSmallChar, createSmallMaterial, createSmallWeapon, getGuidesFor, getIconPath, getLinkToGuide, getStarColor, isInCosts, joinMulti, urlify } from "../../utils/utils"
14+
import styles from "../style.module.css"
15+
1216

1317
interface Props {
1418
mat: Material,
1519
guides?: string[][],
20+
specialty: SpecialtyItem | null,
1621
usedBy: {
1722
charTalents: SmallChar[]
1823
charAscension: SmallChar[]
1924
weaponAscension: SmallWeapon[]
25+
food: SmallMaterial[]
2026
}
2127
}
2228

23-
export default function MaterialWebpage({ mat, location, guides, usedBy }: Props & { location: string }) {
29+
export default function MaterialWebpage({ mat, location, guides, specialty, usedBy }: Props & { location: string }) {
2430
const color = getStarColor(mat.stars ?? 1)
2531
const usedByDesc = []
2632

27-
const { charTalents, charAscension, weaponAscension } = usedBy
33+
const { charTalents, charAscension, weaponAscension, food } = usedBy
2834

2935
const overlap = charTalents.filter(x => charAscension.some(y => x.name == y.name))
3036
const uniqueTalents = charTalents.filter(x => !charAscension.some(y => x.name == y.name))
@@ -101,6 +107,27 @@ export default function MaterialWebpage({ mat, location, guides, usedBy }: Props
101107
{mat.sources.map(s => <div key={s}>{s}</div>)}
102108
</>}
103109

110+
{mat.recipe && <>
111+
<h3 className="text-lg font-bold pt-1" id="recipe">Recipe:</h3>
112+
<table className={`table-auto ${styles.table} mb-2 sm:text-sm md:text-base text-xs`}>
113+
<thead>
114+
<tr className="divide-x divide-gray-200 dark:divide-gray-500">
115+
<th>Items</th>
116+
</tr>
117+
</thead>
118+
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
119+
{mat.recipe.map(({ name, count }) => <tr className="pr-1 divide-x divide-gray-200 dark:divide-gray-500" key={name} >
120+
<td><MaterialCost name={name} count={count} /></td>
121+
</tr>)}
122+
</tbody>
123+
</table>
124+
</>}
125+
126+
{specialty && <>
127+
<h3 className="text-lg font-bold pt-1" id="specialty">Specialty:</h3>
128+
<Specialty specialty={specialty} location={location} />
129+
</>}
130+
104131
{overlap.length > 0 && <>
105132
<h3 className="text-lg font-bold pt-1" id="chartalents">Used by character ascensions and talents:</h3>
106133
<div className="flex flex-wrap justify-start text-center mt-2">
@@ -129,6 +156,13 @@ export default function MaterialWebpage({ mat, location, guides, usedBy }: Props
129156
</div>
130157
</>}
131158

159+
{food.length > 0 && <>
160+
<h3 className="text-lg font-bold pt-1" id="food">Used by food:</h3>
161+
<div className="flex flex-wrap justify-start text-center mt-2">
162+
{food.map(c => <SmallIcon key={c.name} thing={c} location={location} />)}
163+
</div>
164+
</>}
165+
132166
{mat.longDesc && <>
133167
<h3 className="text-lg font-bold pt-1" id="longdesc">Description:</h3>
134168
<blockquote className="pl-5 mb-2 border-l-2">
@@ -140,6 +174,7 @@ export default function MaterialWebpage({ mat, location, guides, usedBy }: Props
140174
)
141175
}
142176

177+
143178
export async function getStaticProps(context: GetStaticPropsContext): Promise<GetStaticPropsResult<Props>> {
144179
const matName = context.params?.material
145180
const data = await getMaterials()
@@ -154,13 +189,13 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
154189

155190
const guides = (await getGuidesFor("material", mat.name))?.map(({ guide, page }) => [page.name, getLinkToGuide(guide, page)])
156191

157-
const char = await getCharacters()
192+
const chars = await getCharacters()
158193
const costTemplates = await getCostTemplates()
159194
const charAscension: SmallChar[] = []
160195
const charTalents: SmallChar[] = []
161196

162-
if (char && costTemplates) {
163-
for (const c of Object.values(char)) {
197+
if (chars && costTemplates) {
198+
for (const c of Object.values(chars)) {
164199
if (c.ascensionCosts && isInCosts(c.ascensionCosts, costTemplates, mat.name))
165200
charAscension.push(createSmallChar(c))
166201

@@ -184,14 +219,46 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
184219
}
185220
}
186221

222+
const food: SmallMaterial[] = []
223+
for (const material of Object.values(data ?? {})) {
224+
if (material.recipe && material.recipe.some(x => x.name == mat.name))
225+
food.push(createSmallMaterial(material))
226+
}
227+
228+
let specialty: SpecialtyItem | null = null
229+
if (mat.specialty && chars && data) {
230+
const char = Object.values(chars).find(c => c.name == mat.specialty?.char)
231+
const recipe = Object.values(data).find(m => m.name == mat.specialty?.recipe)
232+
if (char && recipe)
233+
specialty = {
234+
special: createSmallMaterial(mat),
235+
char: createSmallChar(char),
236+
recipe: createSmallMaterial(recipe)
237+
}
238+
} else if (chars && data) {
239+
const special = Object.values(data).find(m => mat.name == m.specialty?.recipe)
240+
if (special) {
241+
const char = Object.values(chars).find(c => c.name == special.specialty?.char)
242+
243+
if (char)
244+
specialty = {
245+
special: createSmallMaterial(special),
246+
char: createSmallChar(char),
247+
recipe: createSmallMaterial(mat)
248+
}
249+
}
250+
}
251+
187252
return {
188253
props: {
189254
mat,
190255
guides,
256+
specialty,
191257
usedBy: {
192258
charAscension,
193259
charTalents,
194-
weaponAscension: weaponAscension.sort((a, b) => (a.stars && b.stars && b.stars - a.stars) || (a.weapon && b.weapon && a.weapon.localeCompare(b.weapon)) || a.name.localeCompare(b.name))
260+
weaponAscension: weaponAscension.sort((a, b) => (a.stars && b.stars && b.stars - a.stars) || (a.weapon && b.weapon && a.weapon.localeCompare(b.weapon)) || a.name.localeCompare(b.name)),
261+
food
195262
}
196263
},
197264
revalidate: 60 * 60 * 2

utils/types.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,16 @@ export interface Enemy {
310310
}
311311

312312
export interface Material {
313-
name: string
314-
desc: string
315-
longDesc?: string
316-
stars?: number
317-
type: string
318-
category: string
319-
icon: string
320-
sources?: string[]
313+
name: string
314+
desc: string
315+
longDesc?: string
316+
stars?: number
317+
type: string
318+
category: string
319+
icon: string
320+
sources?: string[]
321+
specialty?: { char: string, recipe: string }
322+
recipe?: Item[]
321323
}
322324

323325

@@ -368,3 +370,7 @@ export interface SmallEnemy extends SmallThing {
368370
kind?: string
369371
urlpath: "enemies"
370372
}
373+
374+
export interface SmallMaterial extends SmallThing {
375+
urlpath: "materials"
376+
}

utils/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Claymore from "../public/img/weapon_types/Claymore.png"
1111
import Polearm from "../public/img/weapon_types/Polearm.png"
1212
import Sword from "../public/img/weapon_types/Sword.png"
1313
import { CostTemplates, getGuides } from "./data-cache"
14-
import { Artifact, Character, CharacterFull, Cost, CostTemplate, CurveEnum, Enemy, Guide, GuidePage, SmallArtifact, SmallChar, SmallEnemy, SmallWeapon, TalentTable, TalentValue, Weapon, WeaponCurveName, WeaponType } from "./types"
14+
import { Artifact, Character, CharacterFull, Cost, CostTemplate, CurveEnum, Enemy, Guide, GuidePage, Material, SmallArtifact, SmallChar, SmallEnemy, SmallMaterial, SmallWeapon, TalentTable, TalentValue, Weapon, WeaponCurveName, WeaponType } from "./types"
1515

1616
export const elements = {
1717
Pyro, Electro, Cryo, Hydro, Anemo, Geo, Dendro
@@ -209,6 +209,13 @@ export function createSmallEnemy(enemy: Enemy): SmallEnemy {
209209
return e
210210
}
211211

212+
export function createSmallMaterial(material: Material): SmallMaterial {
213+
const m: SmallMaterial = { name: material.name, urlpath: "materials" }
214+
if (material.stars) m.stars = material.stars
215+
if (material.icon) m.icon = material.icon
216+
return m
217+
}
218+
212219
export function joinMulti(input: string[]): string {
213220
if (input.length <= 1) return input[0]
214221

0 commit comments

Comments
 (0)