mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-24 15:08:44 -05:00
builds page starting to look cleaner
This commit is contained in:
parent
2071a3beeb
commit
df31c2c6b5
|
|
@ -12,7 +12,16 @@ import {
|
|||
} from "../../types"
|
||||
import useBreakPoints from "../../hooks/useBreakPoints"
|
||||
import { abilitiesGameOrder } from "../../utils/lists"
|
||||
import { Box, Flex, Heading, FormLabel, Switch, Button } from "@chakra-ui/core"
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Heading,
|
||||
FormLabel,
|
||||
Switch,
|
||||
Button,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
} from "@chakra-ui/core"
|
||||
import AbilityIcon from "./AbilityIcon"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
|
|
@ -23,6 +32,8 @@ import Loading from "../common/Loading"
|
|||
import Error from "../common/Error"
|
||||
import BuildCard from "./BuildCard"
|
||||
import InfiniteScroll from "react-infinite-scroller"
|
||||
import FieldsetWithLegend from "../common/FieldsetWithLegend"
|
||||
import PageHeader from "../common/PageHeader"
|
||||
|
||||
const BuildsPage: React.FC<RouteComponentProps> = () => {
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
|
|
@ -60,6 +71,7 @@ const BuildsPage: React.FC<RouteComponentProps> = () => {
|
|||
<Helmet>
|
||||
<title>{weapon ? `${weapon} ` : ""}Builds | sendou.ink</title>
|
||||
</Helmet>
|
||||
<PageHeader title="Builds" />
|
||||
<Box mb="1em">
|
||||
<FormLabel htmlFor="apview">Default to Ability Point view</FormLabel>
|
||||
<Switch
|
||||
|
|
@ -75,49 +87,64 @@ const BuildsPage: React.FC<RouteComponentProps> = () => {
|
|||
dropdownMode={isSmall}
|
||||
/>
|
||||
{weapon && (
|
||||
<Flex flexWrap="wrap" justifyContent="center" mt="1em">
|
||||
{abilitiesGameOrder.map(ability => (
|
||||
<Box
|
||||
key={ability}
|
||||
p="5px"
|
||||
cursor={abilities.indexOf(ability) === -1 ? "pointer" : undefined}
|
||||
onClick={() => {
|
||||
if (abilities.indexOf(ability) !== -1) return
|
||||
setAbilities(abilities.concat(ability))
|
||||
}}
|
||||
>
|
||||
<AbilityIcon
|
||||
ability={abilities.indexOf(ability) === -1 ? ability : "EMPTY"}
|
||||
size="SUB"
|
||||
/>{" "}
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
)}
|
||||
{abilities.length > 0 && (
|
||||
<>
|
||||
<Heading size="sm" mx="auto" width="50%" textAlign="center" pt="1em">
|
||||
Only showing builds featuring the following abilities
|
||||
</Heading>
|
||||
<Flex flexWrap="wrap" justifyContent="center" pt="1em">
|
||||
{abilities.map(ability => (
|
||||
<FieldsetWithLegend
|
||||
title="Click an ability to filter by it"
|
||||
titleFontSize="md"
|
||||
centerTitle
|
||||
dividerMode
|
||||
>
|
||||
<Flex flexWrap="wrap" justifyContent="center">
|
||||
{abilitiesGameOrder.map(ability => (
|
||||
<Box
|
||||
key={ability}
|
||||
cursor="pointer"
|
||||
p="5px"
|
||||
onClick={() =>
|
||||
setAbilities(
|
||||
abilities.filter(
|
||||
abilityInArray => ability !== abilityInArray
|
||||
)
|
||||
)
|
||||
cursor={
|
||||
abilities.indexOf(ability) === -1 ? "pointer" : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
if (abilities.indexOf(ability) !== -1) return
|
||||
setAbilities(abilities.concat(ability))
|
||||
}}
|
||||
>
|
||||
<AbilityIcon ability={ability} size="SUB" />{" "}
|
||||
<AbilityIcon
|
||||
ability={
|
||||
abilities.indexOf(ability) === -1 ? ability : "EMPTY"
|
||||
}
|
||||
size="SUB"
|
||||
/>{" "}
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
</>
|
||||
</FieldsetWithLegend>
|
||||
)}
|
||||
{abilities.length > 0 && (
|
||||
<Box textAlign="center" width="100%">
|
||||
<FieldsetWithLegend
|
||||
title="Only showing builds featuring the following abilities"
|
||||
titleFontSize="md"
|
||||
centerTitle
|
||||
fullWidth
|
||||
>
|
||||
<Flex flexWrap="wrap" justifyContent="center">
|
||||
{abilities.map(ability => (
|
||||
<Box
|
||||
key={ability}
|
||||
cursor="pointer"
|
||||
p="5px"
|
||||
onClick={() =>
|
||||
setAbilities(
|
||||
abilities.filter(
|
||||
abilityInArray => ability !== abilityInArray
|
||||
)
|
||||
)
|
||||
}
|
||||
>
|
||||
<AbilityIcon ability={ability} size="SUB" />{" "}
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
</FieldsetWithLegend>
|
||||
</Box>
|
||||
)}
|
||||
{loading && <Loading />}
|
||||
{buildsFilterByAbilities.length > 0 && data && (
|
||||
|
|
@ -143,7 +170,7 @@ const BuildsPage: React.FC<RouteComponentProps> = () => {
|
|||
))}
|
||||
</Flex>
|
||||
</InfiniteScroll>
|
||||
<Box w="50%" textAlign="center" mx="auto">
|
||||
<Box w="50%" textAlign="center" mx="auto" mt="1em">
|
||||
<Heading size="sm">No more builds to show</Heading>
|
||||
<Button
|
||||
variantColor={themeColor}
|
||||
|
|
@ -156,6 +183,12 @@ const BuildsPage: React.FC<RouteComponentProps> = () => {
|
|||
</Box>
|
||||
</>
|
||||
)}
|
||||
{weapon && buildsFilterByAbilities.length === 0 && (
|
||||
<Alert status="info" borderRadius="5px" mt="1em">
|
||||
<AlertIcon />
|
||||
No builds found with the current selection. Please adjust it above.
|
||||
</Alert>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,45 @@
|
|||
import React from "react"
|
||||
import { Box, BoxProps } from "@chakra-ui/core"
|
||||
import { Box } from "@chakra-ui/core"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
|
||||
interface FieldsetWithLegendProps {
|
||||
children: React.ReactNode
|
||||
title: string
|
||||
title: React.ReactNode
|
||||
titleFontSize: string
|
||||
dividerMode?: boolean
|
||||
centerTitle?: boolean
|
||||
fullWidth?: boolean
|
||||
}
|
||||
|
||||
const FieldsetWithLegend: React.FC<FieldsetWithLegendProps> = ({
|
||||
children,
|
||||
title,
|
||||
titleFontSize,
|
||||
dividerMode = false,
|
||||
centerTitle = false,
|
||||
fullWidth = false,
|
||||
}) => {
|
||||
const { borderStyle, grayWithShade } = useContext(MyThemeContext)
|
||||
const { borderStyle, textColor } = useContext(MyThemeContext)
|
||||
return (
|
||||
<Box
|
||||
as="fieldset"
|
||||
maxW="sm"
|
||||
border={borderStyle}
|
||||
rounded="lg"
|
||||
borderX={dividerMode ? "none" : undefined}
|
||||
borderBottom={dividerMode ? "none" : undefined}
|
||||
rounded={dividerMode ? undefined : "lg"}
|
||||
display="inline-block"
|
||||
p="1em"
|
||||
w={fullWidth ? "100%" : undefined}
|
||||
>
|
||||
<Box
|
||||
as="legend"
|
||||
color={grayWithShade}
|
||||
color={textColor}
|
||||
fontWeight="semibold"
|
||||
letterSpacing="wide"
|
||||
fontSize={titleFontSize}
|
||||
textAlign={centerTitle ? "center" : undefined}
|
||||
px="3px"
|
||||
>
|
||||
{title}
|
||||
</Box>
|
||||
|
|
|
|||
26
frontend-react/src/components/common/PageHeader.tsx
Normal file
26
frontend-react/src/components/common/PageHeader.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react"
|
||||
import { Heading } from "@chakra-ui/core"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
|
||||
interface PageHeaderProps {
|
||||
title: string
|
||||
}
|
||||
|
||||
const PageHeader: React.FC<PageHeaderProps> = ({ title }) => {
|
||||
const { themeColorWithShade } = useContext(MyThemeContext)
|
||||
return (
|
||||
<>
|
||||
<Heading
|
||||
borderLeftColor={themeColorWithShade}
|
||||
borderLeftWidth="5px"
|
||||
pl="5px"
|
||||
mb="0.5em"
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default PageHeader
|
||||
|
|
@ -6,6 +6,7 @@ import { weapons } from "../../utils/lists"
|
|||
import WeaponImage from "./WeaponImage"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import FieldsetWithLegend from "./FieldsetWithLegend"
|
||||
|
||||
interface WeaponSelectorProps {
|
||||
weapon: Weapon | null
|
||||
|
|
@ -18,9 +19,7 @@ const WeaponSelector: React.FC<WeaponSelectorProps> = ({
|
|||
setWeapon,
|
||||
dropdownMode = false,
|
||||
}) => {
|
||||
const { darkerBgColor, borderStyle, grayWithShade } = useContext(
|
||||
MyThemeContext
|
||||
)
|
||||
const { darkerBgColor } = useContext(MyThemeContext)
|
||||
const [input, setInput] = useState("")
|
||||
|
||||
const filterWeaponArray = (weapon: Weapon) =>
|
||||
|
|
@ -69,31 +68,18 @@ const WeaponSelector: React.FC<WeaponSelectorProps> = ({
|
|||
autoFocus
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
as="fieldset"
|
||||
border={borderStyle}
|
||||
borderWidth="1px"
|
||||
overflow="hidden"
|
||||
borderX="none"
|
||||
borderBottom="none"
|
||||
<FieldsetWithLegend
|
||||
title="Click a weapon to select it"
|
||||
titleFontSize="md"
|
||||
dividerMode
|
||||
centerTitle
|
||||
fullWidth
|
||||
>
|
||||
<Box
|
||||
as="legend"
|
||||
color={grayWithShade}
|
||||
fontWeight="semibold"
|
||||
letterSpacing="wide"
|
||||
fontSize="md"
|
||||
textAlign="center"
|
||||
px="5px"
|
||||
>
|
||||
Click a weapon to select it
|
||||
</Box>
|
||||
<Flex flexWrap="wrap" justifyContent="center" p="0.5em">
|
||||
<Flex flexWrap="wrap" justifyContent="center">
|
||||
{weapons.filter(filterWeaponArray).map(weapon => (
|
||||
<PseudoBox
|
||||
key={weapon}
|
||||
px="3px"
|
||||
py="2px"
|
||||
px="2px"
|
||||
cursor="pointer"
|
||||
onClick={() => setWeapon(weapon)}
|
||||
userSelect="none"
|
||||
|
|
@ -107,7 +93,7 @@ const WeaponSelector: React.FC<WeaponSelectorProps> = ({
|
|||
</PseudoBox>
|
||||
))}
|
||||
</Flex>
|
||||
</Box>
|
||||
</FieldsetWithLegend>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,6 @@ interface WeaponPoolProps {
|
|||
weapons: Weapon[]
|
||||
}
|
||||
|
||||
const styles = {
|
||||
light: "1px solid rgba(0, 0, 0, .2)",
|
||||
dark: "1px solid rgba(255, 255, 255, .2)",
|
||||
} as const
|
||||
|
||||
const WeaponPool: React.FC<WeaponPoolProps> = ({ weapons }) => {
|
||||
return (
|
||||
<FieldsetWithLegend title="WEAPON POOL" titleFontSize="xs">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user