Hello World!

This commit is contained in:
Sakura Knoll
2021-12-20 00:57:38 +09:00 Unverified
commit 61bf657f23
1744 changed files with 22024 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
/** @jsxImportSource theme-ui */
import { mdiChevronRight, mdiHome } from '@mdi/js'
import Icon from '@mdi/react'
import { NavLink, Text, Flex } from '@theme-ui/components'
import NextLink from 'next/link'
import React from 'react'
interface BreadcrumbItem {
href: string
label: string
}
interface BreadcrumbProps {
items: BreadcrumbItem[]
}
const Breadcrumb = ({ items }: BreadcrumbProps) => {
return (
<Flex
mb={3}
sx={{
backgroundColor: 'gray.2',
paddingY: 2,
paddingX: 4,
borderRadius: 8,
alignItems: 'center',
}}
>
<NextLink passHref href='/'>
<NavLink sx={{ display: 'flex' }}>
<Icon size={0.8} path={mdiHome} />
</NavLink>
</NextLink>
{items.map((item) => {
return (
<React.Fragment key={item.href}>
<Icon size={0.8} path={mdiChevronRight} />
<NextLink passHref href={item.href}>
<NavLink>{item.label}</NavLink>
</NextLink>
</React.Fragment>
)
})}
</Flex>
)
}
export default Breadcrumb
@@ -0,0 +1,45 @@
/** @jsxImportSource theme-ui */
import { NavLink, Heading, Flex } from '@theme-ui/components'
import NextLink from 'next/link'
const Honkai3rdNavigator = () => {
return (
<Flex mx={3} sx={{ alignItems: 'center' }}>
<Flex sx={{ alignItems: 'center', height: 50 }} mr={3}>
<Heading margin={0}>
<NextLink href='/' passHref>
<NavLink mr={2}>Abyss Lab</NavLink>
</NextLink>
:
<NextLink href='/honkai3rd' passHref>
<NavLink ml={2}>Honkai 3rd</NavLink>
</NextLink>
</Heading>
</Flex>
<Flex sx={{ height: 40, alignItems: 'center' }}>
<NextLink href='/honkai3rd/battlesuits' passHref>
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
Battlesuits
</NavLink>
</NextLink>
<NextLink href='/honkai3rd/weapons' passHref>
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
Weapons
</NavLink>
</NextLink>
<NextLink href='/honkai3rd/stigmata' passHref>
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
Stigmata
</NavLink>
</NextLink>
<NextLink href='/honkai3rd/elfs' passHref>
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
ELFs
</NavLink>
</NextLink>
</Flex>
</Flex>
)
}
export default Honkai3rdNavigator
@@ -0,0 +1,27 @@
/** @jsxImportSource theme-ui */
import { NavLink, Heading, Flex } from '@theme-ui/components'
import NextLink from 'next/link'
const RootNavigator = () => {
return (
<Flex mx={3} sx={{ alignItems: 'center' }}>
<Flex sx={{ alignItems: 'center', height: 50 }} mr={3}>
<Heading margin={0}>
<NextLink href='/' passHref>
<NavLink>Abyss Lab</NavLink>
</NextLink>
</Heading>
</Flex>
<Flex sx={{ height: 40, alignItems: 'center' }}>
<NextLink href='/genshin' passHref>
<NavLink mr={3}>Genshin</NavLink>
</NextLink>
<NextLink href='/honkai3rd' passHref>
<NavLink mr={3}>Honkai 3rd</NavLink>
</NextLink>
</Flex>
</Flex>
)
}
export default RootNavigator
+55
View File
@@ -0,0 +1,55 @@
import fs from 'fs'
import { readdirSync, readJsonFileSync, resolvePathname } from '../../lib/data'
export interface BattlesuitSkill {
name: string
description: string
requiredRank: string
}
export interface BattlesuitSkillGroup {
core: BattlesuitSkill
subskills: BattlesuitSkill[]
}
export interface BattlesuitData {
id: string
name: string
type: string
valkyrie: string
strengths: string[]
leader: BattlesuitSkillGroup
special: BattlesuitSkillGroup
evasion: BattlesuitSkillGroup
passive: BattlesuitSkillGroup
ultimate: BattlesuitSkillGroup
basic: BattlesuitSkillGroup
sp?: BattlesuitSkillGroup
}
const battlesuitsFileNameList = readdirSync('battlesuits')
const battlesuitDataList = battlesuitsFileNameList
.map((fileName) => {
const filePathname = 'battlesuits/' + fileName
const data = readJsonFileSync(filePathname) as BattlesuitData
return data
})
.sort((a, b) => {
let compareResult = a.name
.replace(/ \(.\)/, '')
.localeCompare(b.name.replace(/ \(.\)/, ''))
return compareResult
})
const battlesuitMap = battlesuitDataList.reduce((map, stigmata) => {
map.set(stigmata.id, stigmata)
return map
}, new Map<string, BattlesuitData>())
export function listBattlesuits() {
return battlesuitDataList
}
export function getBattlesuitById(id: string) {
return battlesuitMap.get(id)
}
+109
View File
@@ -0,0 +1,109 @@
import fs from 'fs'
import { readdirSync, readJsonFileSync, resolvePathname } from '../../lib/data'
export interface StigmataSkill {
name: string
description: string
}
export interface StigmataData {
id: string
name: string
skill: StigmataSkill
ttk: number
def: number
crt: number
set?: string
type: 'top' | 'mid' | 'bot'
hp: number
rarity: 3 | 4 | 5
version?: number
hidden?: boolean
}
export interface StigmataSet {
id: string
name: string
altName: string
twoSetSkill: StigmataSkill
threeSetSkill: StigmataSkill
version?: number
}
const stigmataDataFileNameList = readdirSync('stigmata')
const stigmataList = stigmataDataFileNameList
.map((fileName) => {
const filePathname = 'stigmata/' + fileName
const data = readJsonFileSync(filePathname) as StigmataData
return data
})
.filter((stigmataData) => !stigmataData.hidden)
.sort((a, b) => {
let compareResult = b.rarity - a.rarity
if (compareResult !== 0) {
return compareResult
}
compareResult = (b.version || 0) - (a.version || 0)
if (compareResult !== 0) {
return compareResult
}
compareResult = (a.set || 'ZZZZZ').localeCompare(b.set || 'ZZZZZ')
if (compareResult !== 0) {
return compareResult
}
compareResult = -a.type.localeCompare(b.type)
if (compareResult !== 0) {
return compareResult
}
compareResult = a.name
.replace(/ \(.\)/, '')
.localeCompare(b.name.replace(/ \(.\)/, ''))
return compareResult
})
const stigmataMap = stigmataList.reduce((map, stigmata) => {
map.set(stigmata.id, stigmata)
return map
}, new Map<string, StigmataData>())
const stigmataSetStigmataDataListMap = stigmataList.reduce((map, stigmata) => {
if (stigmata.set != null) {
let stigmataList = map.get(stigmata.set)
if (stigmataList == null) {
stigmataList = []
map.set(stigmata.set, stigmataList)
}
stigmataList.push(stigmata)
}
return map
}, new Map<string, StigmataData[]>())
const stigmataSetFileNameList = readdirSync('stigmata-sets')
const stigmataSetList = stigmataSetFileNameList.map((fileName) => {
const filePathname = 'stigmata-sets/' + fileName
const data = readJsonFileSync(filePathname) as StigmataSet
return data
})
const stigmataSetMap = stigmataSetList.reduce((map, stigmataSet) => {
map.set(stigmataSet.id, stigmataSet)
return map
}, new Map<string, StigmataSet>())
export function listStigmata() {
return stigmataList
}
export function getStigmataById(id: string) {
return stigmataMap.get(id)
}
export function getStigmataListBySetId(setId: string) {
return stigmataSetStigmataDataListMap.get(setId) || []
}
export function getStigmataSetBySetId(setId: string) {
return stigmataSetMap.get(setId)
}
+24
View File
@@ -0,0 +1,24 @@
import fs from 'fs'
import path from 'path'
const basePathname = path.join(process.cwd(), 'public/data')
export function resolvePathname(pathname: string) {
return path.join(basePathname, pathname)
}
export function readdirSync(pathname: string) {
const fileList = fs.readdirSync(resolvePathname(pathname))
return fileList
}
export function readFileSync(pathname: string) {
return fs.readFileSync(resolvePathname(pathname))
}
export function readJsonFileSync(pathname: string) {
const rawData = readFileSync(pathname).toString()
return JSON.parse(rawData)
}
+227
View File
@@ -0,0 +1,227 @@
import type { AppProps } from 'next/app'
import { Theme, ThemeProvider } from 'theme-ui'
export const theme: Theme = {
breakpoints: ['576px', '768px', '992px', '1200px'],
colors: {
white: '#fff',
black: '#000',
gray: [
'#fff',
'#f8f9fa',
'#e9ecef',
'#dee2e6',
'#ced4da',
'#adb5bd',
'#6c757d',
'#495057',
'#343a40',
'#212529',
],
blue: '#007bff',
indigo: '#6610f2',
purple: '#6f42c1',
pink: '#e83e8c',
red: '#dc3545',
orange: '#fd7e14',
yellow: '#ffc107',
green: '#28a745',
teal: '#20c997',
cyan: '#17a2b8',
grayDark: '#343a40',
text: '#212529',
background: '#fff',
primary: '#007bff',
secondary: '#6c757d',
muted: '#dee2e6',
success: '#28a745',
info: '#17a2b8',
warning: '#ffc107',
danger: '#dc3545',
light: '#f8f9fa',
dark: '#343a40',
textMuted: '#6c757d',
},
space: ['0rem', '0.25rem', '0.5rem', '1rem', '1.5rem', '3rem'],
fonts: {
body: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
heading:
'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
monospace:
'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
},
fontSizes: [
'0.75rem',
'0.875rem',
'1rem',
'1.25rem',
'1.5rem',
'1.75rem',
'2rem',
'2.5rem',
'3.5rem',
'4.5rem',
'5.5rem',
'6rem',
],
fontWeights: {
body: 400,
heading: 500,
bold: 700,
light: 300,
normal: 400,
display: 300,
},
lineHeights: {
body: 1.5,
heading: 1.2,
},
sizes: {
sm: 540,
md: 720,
lg: 960,
xl: 1140,
},
shadows: {
default: '0 .5rem 1rem rgba(0, 0, 0, .15)',
sm: '0 .125rem .25rem rgba(0, 0, 0, .075)',
lg: '0 1rem 3rem rgba(0, 0, 0, .175)',
},
radii: {
default: '0.25rem',
sm: '0.2rem',
lg: '0.3rem',
pill: '50rem',
},
text: {
heading: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
},
display: {
fontWeight: 'display',
lineHeight: 'heading',
},
},
styles: {
root: {
fontFamily: 'body',
lineHeight: 'body',
fontWeight: 'body',
},
a: {
color: 'primary',
textDecoration: 'none',
},
p: {
mb: 3,
lineHeight: 'body',
},
h1: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 7,
},
h2: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 6,
},
h3: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 5,
},
h4: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 4,
},
h5: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 3,
},
h6: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
mt: 0,
mb: 2,
fontSize: 2,
},
blockquote: {
fontSize: 3,
mb: 3,
},
table: {
width: '100%',
marginBottom: 3,
color: 'gray.9',
borderCollapse: 'collapse',
},
th: {
verticalAlign: 'bottom',
borderTopWidth: 2,
borderTopStyle: 'solid',
borderTopColor: 'gray.3',
borderBottomWidth: 2,
borderBottomStyle: 'solid',
borderBottomColor: 'gray.3',
padding: '.75rem',
textAlign: 'inherit',
},
td: {
borderBottomWidth: 2,
borderBottomStyle: 'solid',
borderBottomColor: 'gray.3',
verticalAlign: 'top',
padding: '.75rem',
},
inlineCode: {
color: 'pink',
},
img: {
maxWidth: '100%',
height: 'auto',
},
},
cards: {
stigmata: {
padding: 2,
borderRadius: 4,
borderColor: 'gray.3',
borderWidth: 1,
borderStyle: 'solid',
},
},
}
function MyApp({ Component, pageProps }: AppProps) {
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
+41
View File
@@ -0,0 +1,41 @@
import React, { useMemo } from 'react'
import { Badge } from 'react-bootstrap'
interface CharacterBadgeProps {
character: Character
}
const CharacterBadge = ({ character }: CharacterBadgeProps) => {
const name = useMemo(() => {
switch (character) {
case 'kiana':
return 'Kiana Kaslana'
case 'bronya':
return 'Bronya Zaychik'
case 'mei':
return 'Raiden Mei'
case 'himeko':
return 'Murata Himeko'
case 'hua':
return 'Fu Hua'
case 'kallen':
return 'Kallen Kaslana'
case 'theresa':
return 'Theresa Apocalypse'
case 'rita':
return 'Rita Rossweisse'
case 'olenyevas':
return 'Olenyevas'
case 'seele':
return 'Seele Vollerei'
case 'yae':
return 'Yae Sakura'
default:
return 'Undefined'
}
}, [])
return <Badge>{name}</Badge>
}
export default CharacterBadge
+52
View File
@@ -0,0 +1,52 @@
import React, { useMemo } from 'react'
import { Badge } from 'react-bootstrap'
import { BattlesuitType } from '../../data/honkai3rd/battlesuits'
interface TypeBadgeProps {
type: BattlesuitType
}
const TypeBadge = ({ type }: TypeBadgeProps) => {
const { name, backgroundColor } = useMemo(() => {
switch (type) {
case 'psychic':
return {
name: 'Psychic',
backgroundColor: 'pink',
}
case 'mecha':
return {
name: 'Mechanic',
backgroundColor: 'blue',
}
case 'biologic':
return {
name: 'Biologic',
backgroundColor: 'orange',
}
case 'quantum':
return {
name: 'Quantum',
backgroundColor: 'purple',
}
case 'imginary':
return {
name: 'Imaginery',
backgroundColor: 'yellow',
}
default:
return {
name: 'Unknown',
backgroundColor: 'gray',
}
}
}, [type])
return (
<Badge bg='' style={{ backgroundColor }}>
{name}
</Badge>
)
}
export default TypeBadge
@@ -0,0 +1,236 @@
import { Box, Heading, Paragraph } from '@theme-ui/components'
import { NextPageContext } from 'next'
import Link from 'next/link'
import React from 'react'
import Breadcrumb from '../../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator'
import {
BattlesuitData,
getBattlesuitById,
listBattlesuits,
} from '../../../data/honkai3rd/battlesuits'
import CharacterBadge from '../../atoms/CharacterBadge'
import TypeBadge from '../../atoms/TypeBadge'
interface BattlesuitShowPageProps {
battlesuit: BattlesuitData
}
const BattlesuitShowPage = ({ battlesuit }: BattlesuitShowPageProps) => {
return (
<Box>
<Honkai3rdNavigator />
<Box p={3}>
<Breadcrumb
items={[
{ href: '/honkai3rd', label: 'Honkai 3rd' },
{ href: '/honkai3rd/battlesuits', label: 'Battlesuits' },
{
href: `/honkai3rd/battlesuits/${battlesuit.id}`,
label: battlesuit.name,
},
]}
/>
<Heading as='h1'>{battlesuit.name}</Heading>
<Box className='mb-4'>
<Box>
<Box>
<CharacterBadge character={battlesuit.valkyrie} />
</Box>
<Box>
<TypeBadge type={battlesuit.type} />
</Box>
</Box>
<Box>
<img src={`/assets/honkai3rd/battlesuits/${battlesuit.id}.png`} />
</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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</Box>
</Box>
</Box>
<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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</Box>
</Box>
</Box>
<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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</Box>
</Box>
</Box>
{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 (
<>
<Heading as='h4'>
{subskill.name}
{subskill.requiredRank != null
? ` (${subskill.requiredRank})`
: ''}
</Heading>
<p>{subskill.description}</p>
</>
)
})}
</Box>
</Box>
</Box>
)}
</Box>
</Box>
)
}
export default BattlesuitShowPage
export function getStaticProps(
context: NextPageContext & { params: { battlesuitId: string } }
) {
const battlesuit = getBattlesuitById(context.params.battlesuitId)
return {
props: { battlesuit },
}
}
export async function getStaticPaths() {
return {
paths: listBattlesuits().map((battlesuit) => {
return {
params: { battlesuitId: battlesuit.id },
}
}),
fallback: true,
}
}
+114
View File
@@ -0,0 +1,114 @@
import { Box, Heading, Flex, Text, Link } from '@theme-ui/components'
import NextLink from 'next/link'
import React from 'react'
import Breadcrumb from '../../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator'
import {
BattlesuitData,
listBattlesuits,
} from '../../../data/honkai3rd/battlesuits'
interface BattlesuitListPageProps {
battlesuits: BattlesuitData[]
}
const BattlesuitListPage = ({ battlesuits }: BattlesuitListPageProps) => {
return (
<Box>
<Honkai3rdNavigator />
<Box p={3}>
<Breadcrumb
items={[
{ href: '/honkai3rd', label: 'Honkai 3rd' },
{ href: '/honkai3rd/battlesuits', label: 'Battlesuits' },
]}
/>
<Heading as='h1'>Battlesuits</Heading>
<Flex
sx={{
flexWrap: 'wrap',
justifyContent: 'space-around',
}}
>
{battlesuits.map((battlesuit) => {
return (
<Box
key={battlesuit.id}
sx={{
width: '160px',
padding: 2,
margin: 1,
borderColor: 'gray.3',
borderWidth: 1,
borderStyle: 'solid',
borderRadius: 8,
'&:hover': {
borderColor: 'gray.3',
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
transition: 'box-shadow 200ms ease-in-out',
},
}}
>
<NextLink
href={`/honkai3rd/battlesuits/${battlesuit.id}`}
key={battlesuit.id}
passHref={true}
>
<Link>
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
<div
className='rounded'
style={{
width: '140px',
height: '140px',
position: 'relative',
overflow: 'hidden',
borderRadius: 4,
}}
>
<img
style={{
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translateY(-50%) translateX(-50%)',
}}
height='140'
src={`/assets/honkai3rd/battlesuits/portrait-${battlesuit.id}.png`}
/>
</div>
</Box>
<Box
sx={{
overflow: 'hidden',
textOverflow: 'ellipsis',
width: '100%',
whiteSpace: 'nowrap',
textAlign: 'center',
}}
>
<Text>{battlesuit.name}</Text>
</Box>
</Link>
</NextLink>
</Box>
)
})}
</Flex>
</Box>
</Box>
)
}
export default BattlesuitListPage
export async function getStaticProps() {
return {
props: {
battlesuits: listBattlesuits(),
},
}
}
+33
View File
@@ -0,0 +1,33 @@
import { Box, Heading, Link, Image } from '@theme-ui/components'
import NextLink from 'next/link'
import React from 'react'
import Breadcrumb from '../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../components/organisms/Honkai3rdNavigator'
const Honkai3rdIndexPage = () => {
return (
<Box>
<Honkai3rdNavigator />
<Box p={3}>
<Breadcrumb items={[{ href: 'honkai3rd', label: 'Honkai 3rd' }]} />
<Heading as='h1'>Honkai 3rd</Heading>
<Box>
<Image src='/assets/honkai3rd/wallpaper.png' width='100%' />
</Box>
<Box>
<NextLink href={`/honkai3rd/battlesuits`} passHref>
<Link>Battlesuits</Link>
</NextLink>
</Box>
<Box>
<NextLink href={`/honkai3rd/stigmata`} passHref>
<Link>Stigmata</Link>
</NextLink>
</Box>
</Box>
</Box>
)
}
export default Honkai3rdIndexPage
@@ -0,0 +1,127 @@
import {
NavLink,
Box,
Card,
Heading,
Text,
Paragraph,
} from '@theme-ui/components'
import Link from 'next/link'
import React from 'react'
import {
StigmataData,
listStigmata,
getStigmataById,
getStigmataListBySetId,
getStigmataSetBySetId,
StigmataSet,
} from '../../../data/honkai3rd/stigmata'
interface StigmataShowPageProps {
stigmataData: StigmataData
stigmataSetList: StigmataData[]
stigmataSet?: StigmataSet
}
const StigmataListPage = ({
stigmataData,
stigmataSetList = [],
stigmataSet,
}: StigmataShowPageProps) => {
return (
<Box>
<Box>
<Link passHref href='/honkai3rd'>
<NavLink>Honkai 3rd</NavLink>
</Link>
<Link passHref href='/honkai3rd/stigmata'>
<NavLink>Stigmata</NavLink>
</Link>
</Box>
<Heading as='h1'>{stigmataData.name}</Heading>
<img src={`/assets/honkai3rd/stigmata/${stigmataData.id}.png`} />
<Box>
<Heading as='h2'>Skill - {stigmataData.skill.name}</Heading>
<Paragraph>{stigmataData.skill.description}</Paragraph>
</Box>
{stigmataSet != null && (
<Box>
<Heading as='h2'>Set</Heading>
<Box>
{stigmataSetList.map((stigmataSetItem) => {
return (
<Link
key={stigmataSetItem.id}
href={`/honkai3rd/stigmata/${stigmataSetItem.id}`}
>
<a>
<div
className='rounded'
style={{
width: '100px',
height: '100px',
position: 'relative',
overflow: 'hidden',
}}
>
<img
style={{
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translateY(-50%) translateX(-50%)',
}}
height='100'
src={`/assets/honkai3rd/stigmata/icon-${stigmataSetItem.id}.png`}
/>
</div>
<Text>{stigmataSetItem.name}</Text>
</a>
</Link>
)
})}
</Box>
<Box>
<Heading as='h3'>{stigmataSet.twoSetSkill.name}</Heading>
<Paragraph>{stigmataSet.twoSetSkill.description}</Paragraph>
</Box>
<Box>
<Heading as='h3'>{stigmataSet.threeSetSkill.name}</Heading>
<Paragraph>{stigmataSet.threeSetSkill.description}</Paragraph>
</Box>
</Box>
)}
</Box>
)
}
export default StigmataListPage
export async function getStaticProps(ctx) {
const stigmataData = getStigmataById(ctx.params.stigmataId)
return {
props: {
stigmataData: stigmataData,
stigmataSetList: getStigmataListBySetId(stigmataData.set).sort(
(a, b) => -a.type.localeCompare(b.type)
),
stigmataSet: getStigmataSetBySetId(stigmataData.set) || null,
},
}
}
export async function getStaticPaths() {
return {
paths: listStigmata().map((stigmata) => {
return {
params: { stigmataId: stigmata.id },
}
}),
fallback: true,
}
}
+114
View File
@@ -0,0 +1,114 @@
/** @jsxImportSource theme-ui */
import { Text, NavLink, Box, Heading, Flex, Link } from '@theme-ui/components'
import NextLink from 'next/link'
import Breadcrumb from '../../../components/organisms/Breadcrumb'
import Honkai3rdNavigator from '../../../components/organisms/Honkai3rdNavigator'
import { StigmataData, listStigmata } from '../../../data/honkai3rd/stigmata'
interface StigmataListPageProps {
stigmataDataList: StigmataData[]
}
const StigmataListPage = ({ stigmataDataList }: StigmataListPageProps) => {
return (
<Box>
<Honkai3rdNavigator />
<Box p={3}>
<Breadcrumb
items={[
{ href: '/honkai3rd', label: 'Honkai 3rd' },
{ href: '/honkai3rd/stigmata', label: 'Stigmata' },
]}
/>
<Heading as='h1'>Stigmata</Heading>
<Flex
sx={{
flexWrap: 'wrap',
justifyContent: 'space-around',
}}
>
{stigmataDataList.map((stigmata) => {
return (
<Box
key={stigmata.id}
sx={{
width: '120px',
padding: 2,
margin: 1,
borderColor: 'gray.3',
borderWidth: 1,
borderStyle: 'solid',
borderRadius: 8,
'&:hover': {
borderColor: 'gray.3',
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
transition: 'box-shadow 200ms ease-in-out',
},
}}
>
<NextLink
href={`/honkai3rd/stigmata/${stigmata.id}`}
key={stigmata.id}
passHref={true}
>
<Link>
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
<div
className='rounded'
style={{
width: '100px',
height: '100px',
position: 'relative',
overflow: 'hidden',
borderRadius: 4,
}}
>
<img
style={{
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translateY(-50%) translateX(-50%)',
}}
height='100'
src={`/assets/honkai3rd/stigmata/icon-${stigmata.id}.png`}
/>
</div>
</Box>
<Box
sx={{
overflow: 'hidden',
textOverflow: 'ellipsis',
width: '100%',
whiteSpace: 'nowrap',
textAlign: 'center',
}}
>
<Text>{stigmata.name}</Text>
</Box>
<Box sx={{ fontSize: 1, textAlign: 'center' }}>
{'⭐'.repeat(stigmata.rarity)}
</Box>
</Link>
</NextLink>
</Box>
)
})}
</Flex>
</Box>
</Box>
)
}
export default StigmataListPage
export async function getStaticProps() {
return {
props: {
stigmataDataList: listStigmata(),
},
}
}
+22
View File
@@ -0,0 +1,22 @@
import Link from 'next/link'
import React from 'react'
import { Container } from 'react-bootstrap'
import RootNavigator from '../components/organisms/RootNavigator'
const IndexPage = () => {
return (
<Container>
<RootNavigator />
<div>
<Link href='/honkai3rd'>
<a>
<h2>Honkai 3rd</h2>
</a>
</Link>
</div>
</Container>
)
}
export default IndexPage