Skip to content

Commit 01abc04

Browse files
committed
Add weapons pages
1 parent 4726085 commit 01abc04

File tree

13 files changed

+583
-68
lines changed

13 files changed

+583
-68
lines changed

components/Icon.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/* eslint-disable @next/next/no-img-element */
22
import Image from "next/image"
3-
import { SmallChar } from "../utils/types"
3+
import { SmallChar, SmallWeapon } from "../utils/types"
44
import { elements, getStarColor, image, urlify, weapons } from "../utils/utils"
55
import FormattedLink from "./FormattedLink"
6+
import styles from "../pages/style.module.css"
67

78
export default function Icon({ icon, className, loading = "lazy" }: { icon: { name: string, icon?: string }, className?: string, loading?: "eager" | "lazy" }) {
89
const src = (icon.icon?.startsWith("img/") ? ("/" + icon.icon) : icon.icon) ?? "img/unknown.png"
@@ -24,29 +25,33 @@ export function IconName({ name, type, urltype, loading = "lazy" }: { name: stri
2425
}
2526

2627

27-
export function CharIcon({ char, location }: { char: SmallChar, location: string }) {
28-
const color = getStarColor(char.stars ?? 0)
28+
export function SmallIcon({ thing, location }: { thing: SmallChar | SmallWeapon, location: string }) {
29+
const color = getStarColor(thing.stars ?? 0)
2930

30-
return <FormattedLink key={char.name} location={location} href={`/characters/${urlify(char.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+
return <FormattedLink key={thing.name} location={location} href={`/${isSmallChar(thing) ? "characters" : "weapons"}/${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" >
3132
<div className={`${color} rounded-t-xl h-24 sm:h-28 lg:h-32`}>
32-
<Icon icon={char} className="rounded-t-xl m-0 p-0" />
33+
<Icon icon={thing} className="rounded-t-xl m-0 p-0" />
3334
<span className="absolute block p-0.5 top-0 w-full">
3435
<div className="flex flex-col">
35-
{char.element && char.element.map(e => <div key={e} className="w-6 md:w-8">
36+
{isSmallChar(thing) && thing.element && thing.element.map(e => <div key={e} className="w-6 md:w-8">
3637
<Image src={elements[e]} alt={`${e} Element`} loading="eager" />
3738
</div>)}
3839
</div>
3940
</span>
4041
<span className="absolute block p-0.5 top-0 w-full">
4142
<div className="flex flex-col float-right">
42-
{char.weapon && <div className="w-6 md:w-8">
43-
<Image src={weapons[char.weapon]} alt={char.weapon} loading="eager" />
43+
{thing.weapon && <div className="w-6 md:w-8">
44+
<Image src={weapons[thing.weapon]} alt={thing.weapon} loading="eager" />
4445
</div>}
4546
</div>
4647
</span>
4748
</div>
48-
<span className="flex justify-center items-center h-10 md:h-12 m-0 p-0 duration-200 md:text-base">
49-
{char.name}
49+
<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}`}>
50+
{thing.name}
5051
</span>
5152
</FormattedLink>
5253
}
54+
55+
function isSmallChar(char: SmallChar | SmallWeapon): char is SmallChar {
56+
return (char as SmallChar).element != undefined
57+
}

components/NavBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from "react"
22
import FormattedLink from "./FormattedLink"
33

4-
const pages = ["Guides", "Characters", "Materials", "Reminders"]
4+
const pages = ["Guides", "Characters", "Weapons", "Materials", "Reminders"]
55

66
export default function NavBar({ location }: {location: string}) {
77
const [menuOpen, setMenuOpen] = useState(false)

components/Tables.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { useState } from "react"
2+
import { CostTemplates } from "../utils/data-cache"
3+
import { CostTemplate } from "../utils/types"
4+
import { getCostsFromTemplate } from "../utils/utils"
5+
import styles from "../pages/style.module.css"
6+
import { MaterialCost } from "./Material"
7+
8+
export function FullAscensionCosts({ template, costTemplates }: { template: CostTemplate, costTemplates: CostTemplates }) {
9+
const [expanded, setExpanded] = useState(false)
10+
const costs = getCostsFromTemplate(template, costTemplates)
11+
12+
return <>
13+
<h3 className="text-lg font-bold pt-1" id="ascensions">Ascensions:</h3>
14+
<table className={`table-auto w-full ${styles.table} mb-2 ${expanded ? "" : "cursor-pointer"} sm:text-sm md:text-base text-xs`} onClick={(e) => setExpanded(true)}>
15+
<thead className="font-semibold divide-x divide-gray-200 dark:divide-gray-500">
16+
<td>Asc.</td>
17+
<td>Mora</td>
18+
<td colSpan={costs[costs.length - 1].items.length}>Items</td>
19+
</thead>
20+
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
21+
{costs
22+
.slice(1)
23+
.map(({ mora, items }, ind) => {
24+
let newItems = items
25+
if (ind == 0 && template.mapping.BossMat)
26+
newItems = [items[0], { name: "", count: 0 }, ...items.slice(1)]
27+
return <tr className="pr-1 divide-x divide-gray-200 dark:divide-gray-500" key={ind}>
28+
<td>A{ind + 1}</td>
29+
<td className="text-right">{mora}</td>
30+
{newItems.map(({ count, name }) => <td key={name}>
31+
{count > 0 && <MaterialCost name={name} count={count}/> }
32+
</td>)}
33+
</tr>
34+
})
35+
.filter((_, i, arr) => expanded ? true : (i == arr.length - 1))}
36+
{!expanded && <tr className="pr-1 cursor-pointer text-blue-700 dark:text-blue-300 hover:text-blue-400 dark:hover:text-blue-400 no-underline transition-all duration-200 font-semibold">
37+
<td colSpan={costs[costs.length - 1].items.length + 2} style={({ textAlign: "center" })}>Click to expand...</td>
38+
</tr>}
39+
</tbody>
40+
</table>
41+
</>
42+
}

pages/characters/[char].tsx

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ 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 { FullAscensionCosts } from "../../components/Tables"
1213
import YouTube from "../../components/YouTube"
1314
import { CharacterCurves, CostTemplates, getCharacterCurves, getCharacters, getCostTemplates } from "../../utils/data-cache"
1415
import { Character, CharacterFull, Constellation, CostTemplate, CurveEnum, Meta, Passive, Skill, Skills, TalentTable, TalentValue } from "../../utils/types"
@@ -127,42 +128,6 @@ function AscensionCosts({ costs }: { costs: CostTemplate }) {
127128
</div>
128129
}
129130

130-
function FullAscensionCosts({ template, costTemplates }: { template: CostTemplate, costTemplates: CostTemplates }) {
131-
const [expanded, setExpanded] = useState(false)
132-
const costs = getCostsFromTemplate(template, costTemplates)
133-
134-
return <>
135-
<h3 className="text-lg font-bold pt-1" id="ascensions">Ascensions:</h3>
136-
<table className={`table-auto w-full ${styles.table} mb-2 ${expanded ? "" : "cursor-pointer"} sm:text-sm md:text-base text-xs`} onClick={(e) => setExpanded(true)}>
137-
<thead className="font-semibold divide-x divide-gray-200 dark:divide-gray-500">
138-
<td>Asc.</td>
139-
<td>Mora</td>
140-
<td colSpan={costs[costs.length - 1].items.length}>Items</td>
141-
</thead>
142-
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
143-
{costs
144-
.slice(1)
145-
.map(({ mora, items }, ind) => {
146-
let newItems = items
147-
if (ind == 0 && template.mapping.BossMat)
148-
newItems = [items[0], { name: "", count: 0 }, ...items.slice(1)]
149-
return <tr className="pr-1 divide-x divide-gray-200 dark:divide-gray-500" key={ind}>
150-
<td>A{ind + 1}</td>
151-
<td className="text-right">{mora}</td>
152-
{newItems.map(({ count, name }) => <td key={name}>
153-
{count > 0 && <MaterialCost name={name} count={count}/> }
154-
</td>)}
155-
</tr>
156-
})
157-
.filter((_, i, arr) => expanded ? true : (i == arr.length - 1))}
158-
{!expanded && <tr className="pr-1 cursor-pointer text-blue-700 dark:text-blue-300 hover:text-blue-400 dark:hover:text-blue-400 no-underline transition-all duration-200 font-semibold">
159-
<td colSpan={costs[costs.length - 1].items.length + 2} style={({ textAlign: "center" })}>Click to expand...</td>
160-
</tr>}
161-
</tbody>
162-
</table>
163-
</>
164-
}
165-
166131
function TalentCosts({ skills }: { skills: Skills[] }) {
167132
const talents = skills
168133
.flatMap(s => [...(s.talents ?? []), s.ult])

pages/characters/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Head from "next/head"
33
import Image from "next/image"
44
import { useState } from "react"
55
import { ExclusiveButton, ToggleAllButton, ToggleButton } from "../../components/Filters"
6-
import { CharIcon } from "../../components/Icon"
6+
import { SmallIcon } from "../../components/Icon"
77
import Main from "../../components/Main"
88
import { getCharacters } from "../../utils/data-cache"
99
import { SmallChar, WeaponType } from "../../utils/types"
@@ -109,7 +109,7 @@ export default function Characters(props: Props & { location: string }) {
109109
.filter(c => starFilter == 0 || starFilter == c.stars)
110110
.filter(c => elementFilter.some(e => c.element?.includes(e)) || c.element == undefined)
111111
.filter(c => weaponFilter.some(e => c.weapon?.includes(e)) || c.weapon == undefined)
112-
.map(char => <CharIcon key={char.name} char={char} location={props.location} />)}
112+
.map(char => <SmallIcon key={char.name} thing={char} location={props.location} />)}
113113
</div>
114114
</Main>
115115
)

pages/materials/[material].tsx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@ import Head from "next/head"
44
import ReactMarkdown from "react-markdown"
55
import FormattedLink from "../../components/FormattedLink"
66
import Guides from "../../components/Guides"
7-
import Icon, { CharIcon, IconName } from "../../components/Icon"
7+
import Icon, { SmallIcon } from "../../components/Icon"
88
import Main from "../../components/Main"
9-
import { CostTemplates, getCharacters, getCostTemplates, getMaterials } from "../../utils/data-cache"
10-
import { Cost, CostTemplate, Material, SmallChar } from "../../utils/types"
11-
import { createSmallChar, getCostsFromTemplate, getGuidesFor, getLinkToGuide, getStarColor, urlify } from "../../utils/utils"
9+
import { CostTemplates, getCharacters, getCostTemplates, getMaterials, getWeapons } from "../../utils/data-cache"
10+
import { Cost, CostTemplate, Material, SmallChar, SmallWeapon } from "../../utils/types"
11+
import { createSmallChar, createSmallWeapon, getCostsFromTemplate, getGuidesFor, getLinkToGuide, getStarColor, urlify } from "../../utils/utils"
1212

1313
interface Props {
1414
mat: Material,
1515
guides?: string[][],
1616
usedBy: {
1717
charTalents: SmallChar[]
1818
charAscension: SmallChar[]
19+
weaponAscension: SmallWeapon[]
1920
}
2021
}
2122

22-
export default function CharacterWebpage({ mat, location, guides, usedBy }: Props & { location: string }) {
23+
export default function MaterialWebpage({ mat, location, guides, usedBy }: Props & { location: string }) {
2324
const color = getStarColor(mat.stars ?? 1)
2425

2526
return (
@@ -81,14 +82,21 @@ export default function CharacterWebpage({ mat, location, guides, usedBy }: Prop
8182
{usedBy.charTalents.length > 0 && <>
8283
<h3 className="text-lg font-bold pt-1" id="chartalents">Used by character talents:</h3>
8384
<div className="flex flex-wrap justify-start text-center mt-2">
84-
{usedBy.charTalents.map(c => <CharIcon key={c.name} char={c} location={location} />)}
85+
{usedBy.charTalents.map(c => <SmallIcon key={c.name} thing={c} location={location} />)}
8586
</div>
8687
</>}
8788

8889
{usedBy.charAscension.length > 0 && <>
8990
<h3 className="text-lg font-bold pt-1" id="charascension">Used by character ascensions:</h3>
9091
<div className="flex flex-wrap justify-start text-center mt-2">
91-
{usedBy.charAscension.map(c => <CharIcon key={c.name} char={c} location={location} />)}
92+
{usedBy.charAscension.map(c => <SmallIcon key={c.name} thing={c} location={location} />)}
93+
</div>
94+
</>}
95+
96+
{usedBy.weaponAscension.length > 0 && <>
97+
<h3 className="text-lg font-bold pt-1" id="weaponascension">Used by weapon ascensions:</h3>
98+
<div className="flex flex-wrap justify-start text-center mt-2">
99+
{usedBy.weaponAscension.map(c => <SmallIcon key={c.name} thing={c} location={location} />)}
92100
</div>
93101
</>}
94102

@@ -147,13 +155,25 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
147155
}
148156
}
149157

158+
159+
const weapons = await getWeapons()
160+
const weaponAscension: SmallWeapon[] = []
161+
162+
if (weapons && costTemplates) {
163+
for (const w of Object.values(weapons)) {
164+
if (w.ascensionCosts && isInCosts(w.ascensionCosts, costTemplates, mat.name))
165+
weaponAscension.push(createSmallWeapon(w))
166+
}
167+
}
168+
150169
return {
151170
props: {
152171
mat,
153172
guides,
154173
usedBy: {
155174
charAscension,
156-
charTalents
175+
charTalents,
176+
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))
157177
}
158178
},
159179
revalidate: 60 * 60

pages/materials/index.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,13 @@ export async function getStaticProps(context: GetStaticPropsContext): Promise<Ge
172172
props: {
173173
materials: Object
174174
.values(data)
175-
.map(c => {
176-
const char: SmallMaterial = { name: c.name }
177-
if (c.stars) char.stars = c.stars
178-
if (c.icon) char.icon = c.icon
179-
if (c.category) char.category = c.category
180-
if (c.type) char.type = c.type
181-
return char
175+
.map(m => {
176+
const mat: SmallMaterial = { name: m.name }
177+
if (m.stars) mat.stars = m.stars
178+
if (m.icon) mat.icon = m.icon
179+
if (m.category) mat.category = m.category
180+
if (m.type) mat.type = m.type
181+
return mat
182182
})
183183
},
184184
revalidate: 60 * 60

pages/style.module.css

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,18 @@
3232
}
3333
.stattable tbody td {
3434
text-align: right;
35-
}
35+
}
36+
37+
.iconHeight {
38+
min-height: 4rem;
39+
}
40+
@media (min-width: 768px) {
41+
.iconHeight {
42+
min-height: 3rem;
43+
}
44+
}
45+
@media (min-width: 640px) {
46+
.iconHeight {
47+
min-height: 3rem;
48+
}
49+
}

0 commit comments

Comments
 (0)