feat: update operator details

This commit is contained in:
jinhojang6 2024-09-28 01:26:45 +09:00
parent 6b4a2bbc82
commit 6042d918af
No known key found for this signature in database
GPG Key ID: 1762F21FE8B543F8
6 changed files with 109 additions and 47 deletions

View File

@ -59,7 +59,7 @@ const OperatorGrid: React.FC<OperatorGridProps> = ({ data, isLoading }) => {
if (index === itemsCount - 1) {
return (
<Link
href={`/operators/${index + 1}`}
href={`/operators/${operator.id}`}
key={'explore-operator-' + index}
>
<GridItem ref={lastElementRef}>
@ -77,7 +77,7 @@ const OperatorGrid: React.FC<OperatorGridProps> = ({ data, isLoading }) => {
} else {
return (
<Link
href={`/operators/${index + 1}`}
href={`/operators/${operator.id}`}
key={'explore-operator-' + index}
>
<GridItem>

View File

@ -1,7 +1,9 @@
import { breakpoints } from '@/configs/ui.configs'
import styled from '@emotion/styled'
import 'lazysizes'
import React from 'react'
import operators from '../../../../data/operators.json'
import { findOperatorById, processOperators } from '../../../../utils/operators'
interface OperatorDetailsProps {
id: number
@ -29,6 +31,11 @@ const operatorInfo = [
const OperatorDetails: React.FC<OperatorDetailsProps> = ({
id,
}: OperatorDetailsProps) => {
const processedOperators = processOperators(operators as any, [])
const isIncripted = false
const operator = findOperatorById(processedOperators, id)
const handleDownload = () => {
window.open(`/dashboard/mock/operators/${id % 7}.gif`, '_blank')
}
@ -53,9 +60,11 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
<Container>
<OperatorImage>
<img
src={`/dashboard/mock/operators/${id % 7}.gif`}
src={operator?.image}
data-src={operator?.gif}
alt={`Operator ${id}`}
className="operator-img"
loading="lazy"
className="lazyload"
/>
<ActionButtons>
<Button onClick={handleShare}>Share</Button>
@ -63,46 +72,48 @@ const OperatorDetails: React.FC<OperatorDetailsProps> = ({
</ActionButtons>
</OperatorImage>
<OperatorInfo>
<OperatorTitle>Memetic</OperatorTitle>
<OperatorSubtitle>
<OperatorTitle>{operator?.name}</OperatorTitle>
<ArchetypeSection>
<span>Archetype</span>
<span>{operator?.archetype}</span>
</ArchetypeSection>
{/* <OperatorSubtitle>
<span>Operator</span>
<span className="id">#{id}</span>
</OperatorSubtitle>
</OperatorSubtitle> */}
<AttributesFirstGrid>
<AttributeItem>
<AttributeLabel>Count</AttributeLabel>
<AttributeValue>3</AttributeValue>
<AttributeLabel>Comp</AttributeLabel>
<AttributeValue>{operator?.comp}</AttributeValue>
</AttributeItem>
<AttributeItem>
<AttributeLabel>Body</AttributeLabel>
<AttributeValue>Purple</AttributeValue>
<AttributeLabel>Background</AttributeLabel>
<AttributeValue>{operator?.background}</AttributeValue>
</AttributeItem>
</AttributesFirstGrid>
<AttributesSecondGrid>
<AttributeItem>
<AttributeLabel>Head</AttributeLabel>
<AttributeValue>Woodsman</AttributeValue>
<AttributeLabel>Helmet</AttributeLabel>
<AttributeValue>{operator?.helmet}</AttributeValue>
</AttributeItem>
<AttributeItem>
<AttributeLabel>Eyes</AttributeLabel>
<AttributeValue>Patch</AttributeValue>
<AttributeLabel>Jacket</AttributeLabel>
<AttributeValue>{operator?.jacket}</AttributeValue>
</AttributeItem>
<AttributeItem>
<AttributeLabel>Earing</AttributeLabel>
<AttributeLabel>Skin</AttributeLabel>
<AttributeValue>None</AttributeValue>
</AttributeItem>
</AttributesSecondGrid>
<ArchetypeSection>
<span>Archetype</span>
<span>Memetic</span>
</ArchetypeSection>
<DetailsList>
{operatorInfo.map((info, index) => (
<DetailItem key={index}>
<DetailLabel>{info.trait}</DetailLabel>
<DetailValue>{info.value}</DetailValue>
</DetailItem>
))}
{isIncripted &&
operatorInfo.map((info, index) => (
<DetailItem key={index}>
<DetailLabel>{info.trait}</DetailLabel>
<DetailValue>{info.value}</DetailValue>
</DetailItem>
))}
</DetailsList>
</OperatorInfo>
</Container>
@ -127,6 +138,7 @@ const OperatorImage = styled.div`
img {
width: 100%;
height: auto;
min-height: 400px;
}
grid-column: 1 / 13;
@ -171,16 +183,16 @@ const OperatorTitle = styled.h1`
margin: 0;
`
const OperatorSubtitle = styled.div`
display: flex;
gap: 16px;
font-size: 18px;
margin-top: 16px;
// const OperatorSubtitle = styled.div`
// display: flex;
// gap: 16px;
// font-size: 18px;
// margin-top: 16px;
.id {
opacity: 0.5;
}
`
// .id {
// opacity: 0.5;
// }
// `
const AttributesFirstGrid = styled.div`
display: grid;
@ -195,19 +207,19 @@ const AttributesSecondGrid = styled(AttributesFirstGrid)`
`
const AttributeItem = styled.div`
background-color: var(--dark-orange);
background-color: #320430;
padding: 16px 8px;
`
const AttributeLabel = styled.div`
font-size: 14px;
color: var(--orange);
color: #f29ae9;
`
const AttributeValue = styled.div`
margin-top: 8px;
font-size: 14px;
color: var(--orange);
color: #f29ae9;
`
const ArchetypeSection = styled.div`

View File

@ -15,8 +15,14 @@ export type DashboardPageProps = React.DetailedHTMLProps<
export interface Operator {
id: number
name: string
archetype: string
image_400_url: string
image_400_jpeg_url: string
comp: string
background: string
skin: string
helmet: string
jacket: string
}
export interface Group {
@ -29,7 +35,13 @@ export interface ProcessedOperator {
id: string
image: string
name: string
archetype: string
gif: string
comp: string
background: string
skin: string
helmet: string
jacket: string
pointsPerHour: number
isStaked: boolean
isPinned: boolean

View File

@ -12,7 +12,12 @@ const ExploreOperator: React.FC<ExploreOperatorProps> = ({ id }) => {
const router = useRouter()
const handleGoBack = () => {
router.back()
// if router has history, go back, else go to home
if (router?.back) {
router.back()
} else {
router.push('/')
}
}
return (
<Container>

View File

@ -1,6 +1,8 @@
import { SEO } from '@/components/SEO'
import { OperatorContainer } from '@/containers/Operator'
import { OperatorInfoLayout } from '@/layouts/OperatorInfoLayout'
import operators from '../../../data/operators.json'
import { getAllIds } from '../../../utils/operators'
const Page = ({ id }: any) => {
return (
@ -18,13 +20,14 @@ Page.getLayout = function getLayout(page: React.ReactNode) {
export async function getStaticPaths() {
const paths: any = []
// operator id from 1 to 1000
const operators = Array.from({ length: 1000 }, (_, i) => i + 1)
// get operators id from data
const operatorIds = getAllIds(operators)
operators.forEach((operator) => {
// create paths with operator id
operatorIds.forEach((id: any) => {
paths.push({
params: {
id: operator.toString(),
id: id.toString(),
},
})
})
@ -47,8 +50,7 @@ export async function getStaticProps({ params }: any) {
} catch (error) {
return {
props: {
jobs: [],
issues: {},
id: [],
},
}
}

View File

@ -22,8 +22,14 @@ export function processOperators(
id: operator.id.toString(),
image: operator.image_400_jpeg_url,
gif: operator.image_400_url,
name: `OP ${operator.id}`,
name: operator.name,
pointsPerHour: Math.floor(Math.random() * 500),
comp: operator.comp,
background: operator.background,
skin: operator.skin,
helmet: operator.helmet,
jacket: operator.jacket,
archetype: groupArchetype,
isStaked: false,
isPinned: false,
}))
@ -37,3 +43,28 @@ export function getRandomSubset<T>(array: T[], count: number): T[] {
const shuffled = array?.sort(() => 0.5 - Math.random())
return shuffled?.slice(0, count)
}
export function getAllIds(groups: Group[]): number[] {
const ids: number[] = []
// Extract group IDs
groups.forEach((group) => {
ids.push(group.id)
// Extract operator IDs within each group
group.operators.forEach((operator) => {
ids.push(operator.id)
})
})
return ids
}
export function findOperatorById(
operators: ProcessedOperator[],
operatorId: number | string,
): ProcessedOperator | undefined {
return operators.find(
(operator) => String(operator.id) === String(operatorId),
)
}