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
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

@@ -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: { fontWeights: {
body: 400, body: 400,
heading: 500, heading: 600,
bold: 700, bold: 700,
light: 300, light: 300,
normal: 400, normal: 400,
display: 300, display: 300,
}, },
borders: {
default: `1px solid ${colors.gray[5]}`,
},
lineHeights: { lineHeights: {
body: 1.5, body: 1.6,
heading: 1.2, heading: 1.2,
}, },
sizes: { 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 { NextPageContext } from 'next'
import Image from 'next/image' import Image from 'next/image'
import React from 'react' import React from 'react'
import BattlesuitRankIcon from '../../../components/atoms/BattlesuitRankIcon'
import ValkyrieLabel from '../../../components/atoms/ValkyrieLabel'
import Breadcrumb from '../../../components/organisms/Breadcrumb' import Breadcrumb from '../../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator' import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator'
import { import {
BattlesuitData, BattlesuitData,
BattlesuitSkillGroup,
getBattlesuitById, getBattlesuitById,
listBattlesuits, listBattlesuits,
} from '../../../data/honkai3rd/battlesuits' } from '../../../data/honkai3rd/battlesuits'
import { battlesuitStrengths } from '../../../lib/safeData'
interface BattlesuitShowPageProps { interface BattlesuitShowPageProps {
battlesuit: BattlesuitData battlesuit: BattlesuitData
@@ -33,184 +37,89 @@ const BattlesuitShowPage = ({ battlesuit }: BattlesuitShowPageProps) => {
<Heading as='h1'>{battlesuit.name}</Heading> <Heading as='h1'>{battlesuit.name}</Heading>
<Box className='mb-4'> <Box
<Box sx={{
sx={{ borderRadius: 4,
position: 'relative', border: 'default',
overflow: 'hidden', overflow: 'hidden',
width: '100%', }}
maxWidth: '600px', mb={3}
borderRadius: 4, >
}} <Box sx={{ borderBottom: 'default' }}>
> <Box
<Image sx={{
alt={battlesuit.name} margin: '0 auto',
src={`/assets/honkai3rd/battlesuits/${battlesuit.id}.png`} position: 'relative',
width={600} overflow: 'hidden',
height={600} width: '100%',
layout='responsive' 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> </Box>
<Box className='mb-2'> <BattlesuitSkillGroupCard
<Heading as='h2'>Leader</Heading> heading='Leader'
<Box variant='flush'> skillGroup={battlesuit.leader}
<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>
<Box className='mb-2'> <BattlesuitSkillGroupCard
<Heading as='h2'>Ultimate</Heading> heading='Passive'
<Box variant='flush'> skillGroup={battlesuit.passive}
<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>
<Box className='mb-2'> <BattlesuitSkillGroupCard
<Heading as='h2'>Basic Attack</Heading> heading='Evasion'
<Box variant='flush'> skillGroup={battlesuit.evasion}
<Box> />
<Heading as='h3'>{battlesuit.basic.core.name}</Heading>
<Paragraph>{battlesuit.basic.core.description}</Paragraph> <BattlesuitSkillGroupCard
{battlesuit.basic.subskills.map((subskill, index) => { heading='Special Attack'
return ( skillGroup={battlesuit.special}
<React.Fragment key={subskill.name}> />
<Heading as='h4'>
{subskill.name} <BattlesuitSkillGroupCard
{subskill.requiredRank != null heading='Ultimate'
? ` (${subskill.requiredRank})` skillGroup={battlesuit.ultimate}
: ''} />
</Heading>
<p>{subskill.description}</p> <BattlesuitSkillGroupCard
</React.Fragment> heading='Basic Attack'
) skillGroup={battlesuit.basic}
})} />
</Box>
</Box>
</Box>
{battlesuit.sp != null && ( {battlesuit.sp != null && (
<Box className='mb-2'> <BattlesuitSkillGroupCard
<Heading as='h2'>SP Skill</Heading> heading='SP Skill'
<Box variant='flush'> skillGroup={battlesuit.sp}
<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>
)} )}
</Box> </Box>
</Box> </Box>
@@ -238,3 +147,78 @@ export async function getStaticPaths() {
fallback: false, 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, BattlesuitData,
listBattlesuits, listBattlesuits,
} from '../../../data/honkai3rd/battlesuits' } from '../../../data/honkai3rd/battlesuits'
import { battlesuitStrengths } from '../../../lib/safeData'
type BattlesuitListItemData = Pick< type BattlesuitListItemData = Pick<
BattlesuitData, BattlesuitData,
@@ -22,24 +23,7 @@ interface BattlesuitListPageProps {
const featureFilterOptions = [ const featureFilterOptions = [
{ value: 'all', label: 'All' }, { value: 'all', label: 'All' },
{ value: 'physical', label: 'Physical' }, ...battlesuitStrengths,
{ 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' },
] ]
const valkyrieFilterOptions = [ const valkyrieFilterOptions = [