Style battlesuit show page

This commit is contained in:
Sakura Knoll
2021-12-31 00:58:25 +09:00 Unverified
parent a0292505dc
commit 371e9ad7ed
17 changed files with 279 additions and 192 deletions
@@ -0,0 +1,42 @@
import SquareImageBox from './SquareImageBox'
interface BattlesuitRankIconProps {
size: number
rank: string
m?: number | string
mx?: number | string
my?: number | string
ml?: number | string
mr?: number | string
mt?: number | string
mb?: number | string
}
const BattlesuitRankIcon = ({
size,
rank,
m,
mx,
my,
ml,
mr,
mt,
mb,
}: BattlesuitRankIconProps) => {
return (
<SquareImageBox
size={size}
src={`/assets/honkai3rd/rank-icons/${rank}-rank.png`}
alt={`${rank} rank`}
m={m}
mx={mx}
my={my}
ml={ml}
mr={mr}
mt={mt}
mb={mb}
/>
)
}
export default BattlesuitRankIcon
+54
View File
@@ -0,0 +1,54 @@
import { Text } from '@theme-ui/components'
interface ValkyrieLabelProps {
valkyrie: string
}
const ValkyrieLabel = ({ valkyrie }: ValkyrieLabelProps) => {
const { label } = getLabelData(valkyrie)
return <Text>{label}</Text>
}
export default ValkyrieLabel
function getLabelData(valkyrie: string): { label: string; icon?: string } {
switch (valkyrie) {
case 'kiana':
return { icon: 'kiana', label: 'Kiana Kaslana' }
case 'mei':
return { icon: 'mei', label: 'Raiden Mei' }
case 'bronya':
return { icon: 'bronya', label: 'Bronya Zaychik' }
case 'himeko':
return { icon: 'himeko', label: 'Murata Himeko' }
case 'theresa':
return { icon: 'theresa', label: 'Theresa Apocalypse' }
case 'fuhua':
return { icon: 'fuhua', label: 'Fu Hua' }
case 'rita':
return { icon: 'rita', label: 'Rita Rossweisse' }
case 'sakura':
return { icon: 'sakura', label: 'Yae Sakura' }
case 'kallen':
return { icon: 'kallen', label: 'Kallen Kaslana' }
case 'olenyevas':
return { icon: 'olenyevas', label: 'Olenyevas Sisters' }
case 'seele':
return { icon: 'seele', label: 'Seele Vollerei' }
case 'durandal':
return { icon: 'durandal', label: 'Durandal' }
case 'fischl':
return { icon: 'fischl', label: 'Fischl' }
case 'elysia':
return { icon: 'elysia', label: 'Elysia' }
case 'mobius':
return { icon: 'mobius', label: 'Mobius' }
case 'raven':
return { icon: 'raven', label: 'Raven' }
case 'carole':
return { icon: 'carole', label: 'Carole Pepper' }
}
return {
label: valkyrie,
}
}
+20
View File
@@ -0,0 +1,20 @@
export const battlesuitStrengths = [
{ value: 'physical', label: 'Physical' },
{ value: 'fire dmg', label: 'Fire DMG' },
{ value: 'ice dmg', label: 'Ice DMG' },
{ value: 'lightning dmg', label: 'Lightning DMG' },
{ value: 'freeze', label: 'Freeze' },
{ value: 'paralyze', label: 'Paralyze' },
{ value: 'stun', label: 'Stun' },
{ value: 'ignite', label: 'Ignite' },
{ value: 'bleed', label: 'Bleed' },
{ value: 'heavy atk', label: 'Heavy ATK' },
{ value: 'weaken', label: 'Weaken' },
{ value: 'impair', label: 'Impair' },
{ value: 'time mastery', label: 'Time Mastery' },
{ value: 'gather', label: 'Gather' },
{ value: 'heal', label: 'Heal' },
{ value: 'fast atk', label: 'Fast ATK' },
{ value: 'burst', label: 'Burst' },
{ value: 'aerial', label: 'Aerial' },
]
+5 -2
View File
@@ -46,14 +46,17 @@ export const theme: Theme = {
],
fontWeights: {
body: 400,
heading: 500,
heading: 600,
bold: 700,
light: 300,
normal: 400,
display: 300,
},
borders: {
default: `1px solid ${colors.gray[5]}`,
},
lineHeights: {
body: 1.5,
body: 1.6,
heading: 1.2,
},
sizes: {
+156 -172
View File
@@ -1,14 +1,18 @@
import { Box, Heading, Paragraph } from '@theme-ui/components'
import { Box, Flex, Heading, Paragraph, Text } from '@theme-ui/components'
import { NextPageContext } from 'next'
import Image from 'next/image'
import React from 'react'
import BattlesuitRankIcon from '../../../components/atoms/BattlesuitRankIcon'
import ValkyrieLabel from '../../../components/atoms/ValkyrieLabel'
import Breadcrumb from '../../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator'
import {
BattlesuitData,
BattlesuitSkillGroup,
getBattlesuitById,
listBattlesuits,
} from '../../../data/honkai3rd/battlesuits'
import { battlesuitStrengths } from '../../../lib/safeData'
interface BattlesuitShowPageProps {
battlesuit: BattlesuitData
@@ -33,184 +37,89 @@ const BattlesuitShowPage = ({ battlesuit }: BattlesuitShowPageProps) => {
<Heading as='h1'>{battlesuit.name}</Heading>
<Box className='mb-4'>
<Box
sx={{
position: 'relative',
overflow: 'hidden',
width: '100%',
maxWidth: '600px',
borderRadius: 4,
}}
>
<Image
alt={battlesuit.name}
src={`/assets/honkai3rd/battlesuits/${battlesuit.id}.png`}
width={600}
height={600}
layout='responsive'
/>
<Box
sx={{
borderRadius: 4,
border: 'default',
overflow: 'hidden',
}}
mb={3}
>
<Box sx={{ borderBottom: 'default' }}>
<Box
sx={{
margin: '0 auto',
position: 'relative',
overflow: 'hidden',
width: '100%',
maxWidth: '600px',
}}
>
<Image
alt={battlesuit.name}
src={`/assets/honkai3rd/battlesuits/${battlesuit.id}.png`}
width={600}
height={600}
layout='responsive'
/>
</Box>
</Box>
<Box p={2} sx={{ borderBottom: 'default' }}>
<ValkyrieLabel valkyrie={battlesuit.valkyrie} />
</Box>
<Box p={2}>
<Text mr={1}>
{battlesuit.type.replace(/^\w/, (c) => c.toUpperCase())}
</Text>
{battlesuit.strengths.map((strength) => {
const strengthData = battlesuitStrengths.find(
(aStrength) => aStrength.value === strength
)
return (
<Text mx={1} key={strength}>
{strengthData != null ? strengthData.label : strength}
</Text>
)
})}
</Box>
</Box>
<Box className='mb-2'>
<Heading as='h2'>Leader</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.leader.core.name}</Heading>
<Paragraph>{battlesuit.leader.core.description}</Paragraph>
{battlesuit.leader.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<Box className='mb-2'>
<Heading as='h2'>Passive</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.passive.core.name}</Heading>
<Paragraph>{battlesuit.passive.core.description}</Paragraph>
{battlesuit.passive.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<Box className='mb-2'>
<Heading as='h2'>Evasion</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.evasion.core.name}</Heading>
<Paragraph>{battlesuit.evasion.core.description}</Paragraph>
{battlesuit.evasion.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<Box className='mb-2'>
<Heading as='h2'>Special Attack</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.special.core.name}</Heading>
<Paragraph>{battlesuit.special.core.description}</Paragraph>
{battlesuit.special.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<BattlesuitSkillGroupCard
heading='Leader'
skillGroup={battlesuit.leader}
/>
<Box className='mb-2'>
<Heading as='h2'>Ultimate</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.ultimate.core.name}</Heading>
<Paragraph>{battlesuit.ultimate.core.description}</Paragraph>
{battlesuit.ultimate.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<BattlesuitSkillGroupCard
heading='Passive'
skillGroup={battlesuit.passive}
/>
<Box className='mb-2'>
<Heading as='h2'>Basic Attack</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.basic.core.name}</Heading>
<Paragraph>{battlesuit.basic.core.description}</Paragraph>
{battlesuit.basic.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<BattlesuitSkillGroupCard
heading='Evasion'
skillGroup={battlesuit.evasion}
/>
<BattlesuitSkillGroupCard
heading='Special Attack'
skillGroup={battlesuit.special}
/>
<BattlesuitSkillGroupCard
heading='Ultimate'
skillGroup={battlesuit.ultimate}
/>
<BattlesuitSkillGroupCard
heading='Basic Attack'
skillGroup={battlesuit.basic}
/>
{battlesuit.sp != null && (
<Box className='mb-2'>
<Heading as='h2'>SP Skill</Heading>
<Box variant='flush'>
<Box>
<Heading as='h3'>{battlesuit.sp.core.name}</Heading>
<Paragraph>{battlesuit.sp.core.description}</Paragraph>
{battlesuit.sp.subskills.map((subskill, index) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</React.Fragment>
)
})}
</Box>
</Box>
</Box>
<BattlesuitSkillGroupCard
heading='SP Skill'
skillGroup={battlesuit.sp}
/>
)}
</Box>
</Box>
@@ -238,3 +147,78 @@ export async function getStaticPaths() {
fallback: false,
}
}
interface BattlesuitSkillGroupCardProps {
heading: string
skillGroup: BattlesuitSkillGroup
}
const BattlesuitSkillGroupCard = ({
heading,
skillGroup,
}: BattlesuitSkillGroupCardProps) => {
return (
<Box
mb={3}
sx={{
borderRadius: 4,
border: 'default',
}}
>
<Heading
as='h2'
p={2}
m={0}
sx={{ borderBottom: 'default', fontSize: 4 }}
>
{skillGroup.core.name}
<br />
<Text as='small' sx={{ fontSize: 2, color: 'gray.6' }}>
{heading}
</Text>
</Heading>
<Paragraph p={2} sx={{ whiteSpace: 'pre-wrap', borderBottom: 'default' }}>
{skillGroup.core.description}
</Paragraph>
{skillGroup.subskills.map((subskill) => {
return (
<React.Fragment key={subskill.name}>
<Heading as='h3' p={2} m={0} sx={{ borderBottom: 'default' }}>
<Flex sx={{ alignItems: 'center' }}>
<Text>{subskill.name}</Text>
{subskill.requiredRank != null ? (
/^[0-9]/.test(subskill.requiredRank) ? (
<Box
ml={2}
sx={{ height: 30, lineHeight: '30px', fontSize: 2 }}
>
{subskill.requiredRank.slice(0, 1)}
</Box>
) : (
<BattlesuitRankIcon
rank={subskill.requiredRank}
size={30}
ml={2}
/>
)
) : (
<Box sx={{ height: 30 }} />
)}
</Flex>
</Heading>
<Paragraph
p={2}
sx={{
whiteSpace: 'pre-wrap',
borderBottom: 'default',
'&:last-child': { borderBottom: 'none' },
}}
>
{subskill.description}
</Paragraph>
</React.Fragment>
)
})}
</Box>
)
}
+2 -18
View File
@@ -10,6 +10,7 @@ import {
BattlesuitData,
listBattlesuits,
} from '../../../data/honkai3rd/battlesuits'
import { battlesuitStrengths } from '../../../lib/safeData'
type BattlesuitListItemData = Pick<
BattlesuitData,
@@ -22,24 +23,7 @@ interface BattlesuitListPageProps {
const featureFilterOptions = [
{ value: 'all', label: 'All' },
{ value: 'physical', label: 'Physical' },
{ value: 'fire dmg', label: 'Fire DMG' },
{ value: 'ice dmg', label: 'Ice DMG' },
{ value: 'lightning dmg', label: 'Lightning DMG' },
{ value: 'freeze', label: 'Freeze' },
{ value: 'paralyze', label: 'Paralyze' },
{ value: 'stun', label: 'Stun' },
{ value: 'ignite', label: 'Ignite' },
{ value: 'bleed', label: 'Bleed' },
{ value: 'heavy atk', label: 'Heavy ATK' },
{ value: 'weaken', label: 'Weaken' },
{ value: 'impair', label: 'Impair' },
{ value: 'time mastery', label: 'Time Mastery' },
{ value: 'gather', label: 'Gather' },
{ value: 'heal', label: 'Heal' },
{ value: 'fast atk', label: 'Fast ATK' },
{ value: 'burst', label: 'Burst' },
{ value: 'aerial', label: 'Aerial' },
...battlesuitStrengths,
]
const valkyrieFilterOptions = [