Replace version page with supply event page
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import { Box, Flex, Text } from '@theme-ui/components'
|
||||
import {
|
||||
differenceInCalendarDays,
|
||||
differenceInCalendarWeeks,
|
||||
format,
|
||||
} from 'date-fns'
|
||||
import { times } from 'ramda'
|
||||
import { useMemo, MouseEventHandler } from 'react'
|
||||
|
||||
export interface GanttChartItem {
|
||||
id: string
|
||||
row: number
|
||||
duration: [string, string]
|
||||
label: React.ReactNode
|
||||
onClick?: MouseEventHandler<HTMLDivElement>
|
||||
}
|
||||
|
||||
interface GanttChartProps {
|
||||
startDate: string
|
||||
endDate: string
|
||||
today: string
|
||||
items: GanttChartItem[]
|
||||
}
|
||||
|
||||
const GanttChart = ({
|
||||
startDate: startDateString,
|
||||
endDate: endDateString,
|
||||
today: todayDateString,
|
||||
items,
|
||||
}: GanttChartProps) => {
|
||||
const startDate = new Date(startDateString)
|
||||
const endDate = new Date(endDateString)
|
||||
const todayDate = new Date(todayDateString)
|
||||
|
||||
const totalDays = differenceInCalendarDays(endDate, startDate)
|
||||
const totalWeeks = differenceInCalendarWeeks(endDate, startDate)
|
||||
|
||||
const totalRow = useMemo(() => {
|
||||
return items.reduce((max, item) => {
|
||||
return item.row > max ? item.row : max
|
||||
}, 1)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Box mb={3} sx={{ width: totalWeeks * 280 }}>
|
||||
<Flex
|
||||
sx={{
|
||||
marginLeft: -20,
|
||||
}}
|
||||
>
|
||||
{times((index) => {
|
||||
const weekNumber = index + 1
|
||||
return (
|
||||
<Box
|
||||
key={`week-${weekNumber}`}
|
||||
sx={{
|
||||
width: 280,
|
||||
textAlign: 'center',
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
Week {weekNumber}
|
||||
</Box>
|
||||
)
|
||||
}, totalWeeks)}
|
||||
</Flex>
|
||||
<Box
|
||||
sx={{
|
||||
position: 'relative',
|
||||
height: totalRow * 50 + 40,
|
||||
borderBottomStyle: 'solid',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: 'gray.5',
|
||||
borderTopStyle: 'solid',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: 'gray.5',
|
||||
}}
|
||||
>
|
||||
{times((index) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
height: totalRow * 50 + 40,
|
||||
borderRightStyle: 'solid',
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: index % 7 === 6 ? 'gray.5' : 'gray.3',
|
||||
left: (index + 1) * 40 - 1 - 20,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}, totalDays)}
|
||||
<Box
|
||||
sx={{
|
||||
boxSizing: 'border-box',
|
||||
position: 'absolute',
|
||||
width: 40,
|
||||
height: totalRow * 50 + 40,
|
||||
backgroundColor: 'blue.5',
|
||||
borderStyle: 'solid',
|
||||
borderColor: 'blue.7',
|
||||
opacity: 0.2,
|
||||
zIndex: 20,
|
||||
borderRadius: 4,
|
||||
left: differenceInCalendarDays(todayDate, startDate) * 40 - 20,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
color: 'blue.7',
|
||||
transform: 'rotate(90deg)',
|
||||
zIndex: 21,
|
||||
top: 150,
|
||||
left:
|
||||
differenceInCalendarDays(new Date(todayDate), startDate) * 40 -
|
||||
150,
|
||||
width: 300,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
Today ({format(todayDate, 'P')})
|
||||
</Text>
|
||||
|
||||
{items.map((item) => {
|
||||
const offset =
|
||||
differenceInCalendarDays(new Date(item.duration[0]), startDate) * 40
|
||||
const length =
|
||||
differenceInCalendarDays(
|
||||
new Date(item.duration[1]),
|
||||
new Date(item.duration[0])
|
||||
) * 40
|
||||
|
||||
return (
|
||||
<Flex
|
||||
key={item.id}
|
||||
py={2}
|
||||
px={3}
|
||||
sx={{
|
||||
boxSizing: 'border-box',
|
||||
position: 'absolute',
|
||||
borderColor: 'gray.5',
|
||||
borderWidth: 1,
|
||||
borderStyle: 'solid',
|
||||
backgroundColor: 'white',
|
||||
width: length,
|
||||
left: offset,
|
||||
top: (item.row - 1) * 50 + 20,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
height: 40,
|
||||
borderRadius: 40,
|
||||
fontWeight: 700,
|
||||
zIndex: 10,
|
||||
'&:hover': {
|
||||
minWidth: length,
|
||||
width: 'inherit',
|
||||
zIndex: 25,
|
||||
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
|
||||
transition: 'box-shadow 200ms ease-in-out',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default GanttChart
|
||||
@@ -16,6 +16,11 @@ const Honkai3rdNavigator = () => {
|
||||
</NextLink>
|
||||
</Heading>
|
||||
</Flex>
|
||||
<NextLink href='/honkai3rd/versions' passHref>
|
||||
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
|
||||
Versions
|
||||
</NavLink>
|
||||
</NextLink>
|
||||
<Flex sx={{ height: 40, alignItems: 'center' }}>
|
||||
<NextLink href='/honkai3rd/battlesuits' passHref>
|
||||
<NavLink mr={3} sx={{ fontFamily: 'monospace' }}>
|
||||
|
||||
Reference in New Issue
Block a user