mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-06-03 06:35:42 -05:00
free agent page milestone
This commit is contained in:
parent
1626a824ac
commit
77af38de54
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState, useEffect, useRef } from "react"
|
||||
import jstz from "jstz"
|
||||
import {
|
||||
Button,
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
|
|
@ -17,6 +16,7 @@ import { useContext } from "react"
|
|||
import MyThemeContext from "../themeContext"
|
||||
import PageHeader from "../components/common/PageHeader"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import Button from "../components/elements/Button"
|
||||
|
||||
const CalendarPage: React.FC<RouteComponentProps> = () => {
|
||||
const {
|
||||
|
|
@ -46,14 +46,11 @@ const CalendarPage: React.FC<RouteComponentProps> = () => {
|
|||
<PageHeader title="Competitive Calendar" />
|
||||
<Popover placement="top-start">
|
||||
<PopoverTrigger>
|
||||
<Button
|
||||
variantColor={themeColor}
|
||||
variant="outline"
|
||||
onClick={() => setShowCode(!showCode)}
|
||||
mt="1em"
|
||||
>
|
||||
Show emoji code
|
||||
</Button>
|
||||
<Box mt="1em">
|
||||
<Button outlined onClick={() => setShowCode(!showCode)}>
|
||||
Show emoji code
|
||||
</Button>
|
||||
</Box>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent zIndex={4} background={darkerBgColor} width="280px">
|
||||
<PopoverArrow />
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import React, { useState } from "react"
|
||||
import FieldsetWithLegend from "../common/FieldsetWithLegend"
|
||||
import { Flex, Box, Button } from "@chakra-ui/core"
|
||||
import { Flex, Box } from "@chakra-ui/core"
|
||||
import { abilitiesGameOrder } from "../../utils/lists"
|
||||
import AbilityIcon from "./AbilityIcon"
|
||||
import { Ability } from "../../types"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import Button from "../elements/Button"
|
||||
|
||||
interface AbilitySelectorProps {
|
||||
abilities: Ability[]
|
||||
|
|
@ -21,7 +22,6 @@ const AbilitySelector: React.FC<AbilitySelectorProps> = ({
|
|||
return show ? (
|
||||
<>
|
||||
<Button
|
||||
variantColor={themeColor}
|
||||
onClick={() => {
|
||||
setShow(!show)
|
||||
setAbilities([])
|
||||
|
|
@ -86,9 +86,7 @@ const AbilitySelector: React.FC<AbilitySelectorProps> = ({
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
<Button variantColor={themeColor} onClick={() => setShow(!show)}>
|
||||
Filter by ability
|
||||
</Button>
|
||||
<Button onClick={() => setShow(!show)}>Filter by ability</Button>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,7 @@ import {
|
|||
Build,
|
||||
} from "../../types"
|
||||
import useBreakPoints from "../../hooks/useBreakPoints"
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Heading,
|
||||
FormLabel,
|
||||
Switch,
|
||||
Button,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
} from "@chakra-ui/core"
|
||||
import { Box, Flex, Heading, FormLabel, Switch, Button } from "@chakra-ui/core"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import useLocalStorage from "@rehooks/local-storage"
|
||||
|
|
@ -32,6 +23,7 @@ import BuildCard from "./BuildCard"
|
|||
import InfiniteScroll from "react-infinite-scroller"
|
||||
import PageHeader from "../common/PageHeader"
|
||||
import AbilitySelector from "./AbilitySelector"
|
||||
import Alert from "../elements/Alert"
|
||||
|
||||
const BuildsPage: React.FC<RouteComponentProps> = () => {
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
|
|
@ -126,10 +118,7 @@ const BuildsPage: React.FC<RouteComponentProps> = () => {
|
|||
</>
|
||||
)}
|
||||
{weapon && buildsFilterByAbilities.length === 0 && (
|
||||
<Alert status="info" borderRadius="5px" mt="2em">
|
||||
<AlertIcon />
|
||||
No builds found with the current selection. Please adjust it above.
|
||||
</Alert>
|
||||
<Alert status="info">No builds found with the current filter</Alert>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
import React from "react"
|
||||
import { Alert, AlertIcon } from "@chakra-ui/core"
|
||||
import Alert from "../elements/Alert"
|
||||
|
||||
interface ErrorProps {
|
||||
errorMessage: string
|
||||
}
|
||||
|
||||
const Error: React.FC<ErrorProps> = ({ errorMessage }) => {
|
||||
return (
|
||||
<Alert status="error">
|
||||
<AlertIcon color="red.500" />
|
||||
{errorMessage}
|
||||
</Alert>
|
||||
)
|
||||
return <Alert status="error">{errorMessage}</Alert>
|
||||
}
|
||||
|
||||
export default Error
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import Select from "../elements/Select"
|
|||
|
||||
interface WeaponSelectorProps {
|
||||
setValue: (value: string) => void
|
||||
label?: string
|
||||
autoFocus?: boolean
|
||||
clearable?: boolean
|
||||
}
|
||||
|
||||
const singleOption = (props: any) => (
|
||||
|
|
@ -23,19 +25,29 @@ const singleOption = (props: any) => (
|
|||
|
||||
const WeaponSelector: React.FC<WeaponSelectorProps> = ({
|
||||
setValue,
|
||||
autoFocus = false,
|
||||
label,
|
||||
clearable,
|
||||
autoFocus,
|
||||
}) => {
|
||||
return (
|
||||
<Select
|
||||
options={weaponSelectOptions}
|
||||
setValue={setValue}
|
||||
placeholder="Select a weapon"
|
||||
components={{
|
||||
IndicatorSeparator: () => null,
|
||||
Option: singleOption,
|
||||
}}
|
||||
autoFocus={autoFocus}
|
||||
/>
|
||||
<>
|
||||
{label && (
|
||||
<Box mb="0.2em">
|
||||
<b>{label}</b>
|
||||
</Box>
|
||||
)}
|
||||
<Select
|
||||
options={weaponSelectOptions}
|
||||
setValue={setValue}
|
||||
placeholder="Select weapon"
|
||||
clearable={clearable}
|
||||
components={{
|
||||
IndicatorSeparator: () => null,
|
||||
Option: singleOption,
|
||||
}}
|
||||
autoFocus={autoFocus}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
18
frontend-react/src/components/elements/Alert.tsx
Normal file
18
frontend-react/src/components/elements/Alert.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react"
|
||||
import { Alert as ChakraAlert, AlertIcon } from "@chakra-ui/core"
|
||||
|
||||
interface AlertProps {
|
||||
children: string | string[]
|
||||
status: "error" | "success" | "warning" | "info"
|
||||
}
|
||||
|
||||
const Alert: React.FC<AlertProps> = ({ children, status }) => {
|
||||
return (
|
||||
<ChakraAlert status={status} borderRadius="5px" mt="2em">
|
||||
<AlertIcon />
|
||||
{children}
|
||||
</ChakraAlert>
|
||||
)
|
||||
}
|
||||
|
||||
export default Alert
|
||||
12
frontend-react/src/components/elements/Box.tsx
Normal file
12
frontend-react/src/components/elements/Box.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import React from "react"
|
||||
import { Box as ChakraBox, BoxProps } from "@chakra-ui/core"
|
||||
|
||||
interface MyBoxProps {
|
||||
children: JSX.Element | JSX.Element[]
|
||||
}
|
||||
|
||||
const Box: React.FC<BoxProps & MyBoxProps> = ({ children, ...props }) => {
|
||||
return <ChakraBox {...props}>{children}</ChakraBox>
|
||||
}
|
||||
|
||||
export default Box
|
||||
39
frontend-react/src/components/elements/Button.tsx
Normal file
39
frontend-react/src/components/elements/Button.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import React from "react"
|
||||
import { Button as ChakraButton } from "@chakra-ui/core"
|
||||
import { useContext } from "react"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import { IconType } from "react-icons/lib/cjs"
|
||||
|
||||
interface ButtonProps {
|
||||
children: string | string[]
|
||||
onClick: () => void
|
||||
size?: "xs" | "sm" | "lg" | "md"
|
||||
icon?: IconType
|
||||
outlined?: boolean
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const Button: React.FC<ButtonProps> = ({
|
||||
children,
|
||||
onClick,
|
||||
icon,
|
||||
size,
|
||||
disabled,
|
||||
outlined = false,
|
||||
}) => {
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
return (
|
||||
<ChakraButton
|
||||
variant={outlined ? "outline" : "solid"}
|
||||
variantColor={themeColor}
|
||||
leftIcon={icon}
|
||||
onClick={onClick}
|
||||
size={size}
|
||||
isDisabled={disabled}
|
||||
>
|
||||
{children}
|
||||
</ChakraButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default Button
|
||||
48
frontend-react/src/components/elements/RadioGroup.tsx
Normal file
48
frontend-react/src/components/elements/RadioGroup.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import React, { useContext } from "react"
|
||||
import { RadioGroup as ChakraRadioGroup, Radio } from "@chakra-ui/core"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import Box from "./Box"
|
||||
|
||||
interface RadioGroupProps {
|
||||
options: string[]
|
||||
value: string
|
||||
label?: string
|
||||
setValue: (value: any) => void
|
||||
}
|
||||
|
||||
const RadioGroup: React.FC<RadioGroupProps> = ({
|
||||
value,
|
||||
setValue,
|
||||
options,
|
||||
label,
|
||||
}) => {
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
return (
|
||||
<>
|
||||
{label && (
|
||||
<Box mb="0.2em">
|
||||
<b>{label}</b>
|
||||
</Box>
|
||||
)}
|
||||
<ChakraRadioGroup
|
||||
spacing={5}
|
||||
isInline
|
||||
onChange={e => setValue(e.target.value)}
|
||||
value={value}
|
||||
>
|
||||
{options.map(option => (
|
||||
<Radio
|
||||
key={option}
|
||||
variantColor={themeColor}
|
||||
value={option}
|
||||
isChecked={value === option}
|
||||
>
|
||||
{option}
|
||||
</Radio>
|
||||
))}
|
||||
</ChakraRadioGroup>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RadioGroup
|
||||
|
|
@ -29,6 +29,7 @@ interface SelectProps {
|
|||
value: string
|
||||
}>
|
||||
>
|
||||
clearable?: boolean
|
||||
}
|
||||
|
||||
const Select: React.FC<SelectProps> = ({
|
||||
|
|
@ -36,7 +37,8 @@ const Select: React.FC<SelectProps> = ({
|
|||
components,
|
||||
placeholder,
|
||||
setValue,
|
||||
autoFocus = false,
|
||||
clearable,
|
||||
autoFocus,
|
||||
}) => {
|
||||
const {
|
||||
colorMode,
|
||||
|
|
@ -46,7 +48,7 @@ const Select: React.FC<SelectProps> = ({
|
|||
} = useContext(MyThemeContext)
|
||||
|
||||
const handleChange = (selectedOption: any) => {
|
||||
setValue(selectedOption.value)
|
||||
setValue(selectedOption?.value)
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -56,6 +58,7 @@ const Select: React.FC<SelectProps> = ({
|
|||
onChange={handleChange}
|
||||
placeholder={placeholder}
|
||||
isSearchable
|
||||
isClearable={clearable}
|
||||
options={options}
|
||||
components={{
|
||||
IndicatorSeparator: () => null,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import React, { useState } from "react"
|
||||
import { useQuery } from "@apollo/react-hooks"
|
||||
import { USER } from "../../graphql/queries/user"
|
||||
import { UserData, FreeAgentPostsData, Weapon } from "../../types"
|
||||
import {
|
||||
UserData,
|
||||
FreeAgentPostsData,
|
||||
Weapon,
|
||||
FreeAgentPost,
|
||||
} from "../../types"
|
||||
import { FREE_AGENT_POSTS } from "../../graphql/queries/freeAgentPosts"
|
||||
import Loading from "../common/Loading"
|
||||
import Error from "../common/Error"
|
||||
|
|
@ -10,9 +15,27 @@ import PostsAccordion from "./PostsAccordion"
|
|||
import PageHeader from "../common/PageHeader"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import WeaponSelector from "../common/WeaponSelector"
|
||||
import RadioGroup from "../elements/RadioGroup"
|
||||
import Box from "../elements/Box"
|
||||
import { continents } from "../../utils/lists"
|
||||
|
||||
/*can_vc: "YES" | "USUALLY" | "SOMETIMES" | "NO"
|
||||
playstyles: ("FRONTLINE" | "MIDLINE" | "BACKLINE")[]*/
|
||||
|
||||
const playstyleToEnum = {
|
||||
"Frontline/Slayer": "FRONTLINE",
|
||||
"Midline/Support": "MIDLINE",
|
||||
"Backline/Anchor": "BACKLINE",
|
||||
} as const
|
||||
|
||||
const FreeAgentsPage: React.FC<RouteComponentProps> = () => {
|
||||
const [weapon, setWeapon] = useState<Weapon | null>(null)
|
||||
const [playstyle, setPlaystyle] = useState<
|
||||
"Any" | "Frontline/Slayer" | "Midline/Support" | "Backline/Anchor"
|
||||
>("Any")
|
||||
const [region, setRegion] = useState<
|
||||
"Any" | "Europe" | "The Americas" | "Oceania" | "Other"
|
||||
>("Any")
|
||||
const { data, error, loading } = useQuery<FreeAgentPostsData>(
|
||||
FREE_AGENT_POSTS
|
||||
)
|
||||
|
|
@ -28,17 +51,83 @@ const FreeAgentsPage: React.FC<RouteComponentProps> = () => {
|
|||
|
||||
const faPosts = data.freeAgentPosts
|
||||
|
||||
const postsFilter = (post: FreeAgentPost) => {
|
||||
if (post.hidden) return false
|
||||
|
||||
if (weapon && post.discord_user.weapons.indexOf(weapon) === -1) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (playstyle !== "Any") {
|
||||
if (post.playstyles.indexOf(playstyleToEnum[playstyle]) === -1)
|
||||
return false
|
||||
}
|
||||
|
||||
if (region !== "Any") {
|
||||
if (!post.discord_user.country) {
|
||||
if (region === "Other") return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const continentCode = continents[post.discord_user.country]
|
||||
|
||||
if (region === "Europe" && continentCode !== "EU") return false
|
||||
else if (
|
||||
region === "The Americas" &&
|
||||
continentCode !== "NA" &&
|
||||
continentCode !== "SA"
|
||||
)
|
||||
return false
|
||||
else if (region === "Oceania" && continentCode !== "OC") return false
|
||||
else if (
|
||||
region === "Other" &&
|
||||
continentCode !== "AF" &&
|
||||
continentCode !== "AN" &&
|
||||
continentCode !== "AS" &&
|
||||
continentCode !== "OC"
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Free Agents | sendou.ink</title>
|
||||
</Helmet>
|
||||
<PageHeader title="Free Agents" />
|
||||
<WeaponSelector
|
||||
setValue={(weapon: string) => setWeapon(weapon as Weapon)}
|
||||
autoFocus
|
||||
/>
|
||||
<PostsAccordion posts={faPosts} />
|
||||
<Box maxW="600px" my="1em">
|
||||
<RadioGroup
|
||||
value={playstyle}
|
||||
setValue={setPlaystyle}
|
||||
label="Filter by playstyle"
|
||||
options={[
|
||||
"Any",
|
||||
"Frontline/Slayer",
|
||||
"Midline/Support",
|
||||
"Backline/Anchor",
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
<Box maxW="600px" my="1em">
|
||||
<RadioGroup
|
||||
value={region}
|
||||
setValue={setRegion}
|
||||
label="Filter by region"
|
||||
options={["Any", "Europe", "The Americas", "Oceania", "Other"]}
|
||||
/>
|
||||
</Box>
|
||||
<Box maxW="600px" my="1em">
|
||||
<WeaponSelector
|
||||
label="Filter by weapon"
|
||||
setValue={(weapon: string) => setWeapon(weapon as Weapon)}
|
||||
clearable
|
||||
/>
|
||||
</Box>
|
||||
<PostsAccordion posts={faPosts.filter(postsFilter)} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { FaTwitter } from "react-icons/fa"
|
|||
import WeaponImage from "../common/WeaponImage"
|
||||
import RoleIcons from "./RoleIcons"
|
||||
import VCIcon from "./VCIcon"
|
||||
import Alert from "../elements/Alert"
|
||||
|
||||
interface PostsAccordionProps {
|
||||
posts: FreeAgentPost[]
|
||||
|
|
@ -37,125 +38,126 @@ const hasExtraInfo = (post: FreeAgentPost) => {
|
|||
|
||||
const PostsAccordion: React.FC<PostsAccordionProps> = ({ posts }) => {
|
||||
const { darkerBgColor } = useContext(MyThemeContext)
|
||||
|
||||
if (posts.length === 0) {
|
||||
return (
|
||||
<Alert status="info">No free agents found with the current filter</Alert>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Accordion allowMultiple>
|
||||
{posts
|
||||
.filter(post => !post.hidden)
|
||||
.map(post => {
|
||||
const { discord_user } = post
|
||||
const canBeExpanded = hasExtraInfo(post)
|
||||
return (
|
||||
<AccordionItem key={post.id}>
|
||||
<AccordionHeader cursor={canBeExpanded ? undefined : "default"}>
|
||||
{canBeExpanded ? (
|
||||
<AccordionIcon size="2em" mr="1em" />
|
||||
) : (
|
||||
<Box w="2em" h="2em" mr="1em" />
|
||||
)}
|
||||
<Grid
|
||||
gridTemplateColumns="repeat(auto-fill, 200px)"
|
||||
width="100%"
|
||||
rowGap="0.7em"
|
||||
justifyItems="center"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Link to={`/u/${discord_user.discord_id}`}>
|
||||
<Flex alignItems="center">
|
||||
<UserAvatar
|
||||
twitterName={discord_user.twitter_name}
|
||||
name={discord_user.username}
|
||||
mr="5px"
|
||||
/>
|
||||
<span>
|
||||
{discord_user.username}#{discord_user.discriminator}
|
||||
</span>
|
||||
</Flex>
|
||||
</Link>
|
||||
<Box>
|
||||
{discord_user.country && (
|
||||
<>
|
||||
<Flag code={discord_user.country} />
|
||||
{
|
||||
countries.find(
|
||||
obj => obj.code === discord_user.country
|
||||
)?.name
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Flex alignItems="center">
|
||||
{discord_user.twitter_name && (
|
||||
<>
|
||||
<Box as={FaTwitter} />
|
||||
<Box as="span" ml="5px">
|
||||
{discord_user.twitter_name}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
<Box color="#999999">
|
||||
{new Date(parseInt(post.createdAt)).toLocaleDateString()}
|
||||
</Box>
|
||||
<Flex alignItems="center">
|
||||
{discord_user?.weapons &&
|
||||
discord_user.weapons.map(wpn => (
|
||||
<Box mx="0.3em" key={wpn}>
|
||||
<WeaponImage englishName={wpn} size="SMALL" />
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
<RoleIcons playstyles={post.playstyles} />
|
||||
<VCIcon canVC={post.can_vc} />
|
||||
</Grid>
|
||||
</AccordionHeader>
|
||||
{canBeExpanded && (
|
||||
<AccordionPanel
|
||||
mt="3px"
|
||||
py={4}
|
||||
background={darkerBgColor}
|
||||
whiteSpace="pre-wrap"
|
||||
textAlign="center"
|
||||
>
|
||||
{post.activity && (
|
||||
<Box>
|
||||
<Heading size="md">Activity</Heading>
|
||||
{post.activity}
|
||||
</Box>
|
||||
)}
|
||||
{post.looking_for && (
|
||||
<Box mt={post.activity ? "1em" : undefined}>
|
||||
<Heading size="md">Looking for</Heading>
|
||||
{post.looking_for}
|
||||
</Box>
|
||||
)}
|
||||
{post.past_experience && (
|
||||
<Box
|
||||
mt={post.activity || post.looking_for ? "1em" : undefined}
|
||||
>
|
||||
<Heading size="md">Past experience</Heading>
|
||||
{post.past_experience}
|
||||
</Box>
|
||||
)}
|
||||
{post.description && (
|
||||
<Box
|
||||
mt={
|
||||
post.activity ||
|
||||
post.looking_for ||
|
||||
post.past_experience
|
||||
? "1em"
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Heading size="md">Description</Heading>
|
||||
{post.description}
|
||||
</Box>
|
||||
)}
|
||||
</AccordionPanel>
|
||||
{posts.map(post => {
|
||||
const { discord_user } = post
|
||||
const canBeExpanded = hasExtraInfo(post)
|
||||
return (
|
||||
<AccordionItem key={post.id}>
|
||||
<AccordionHeader cursor={canBeExpanded ? undefined : "default"}>
|
||||
{canBeExpanded ? (
|
||||
<AccordionIcon size="2em" mr="1em" />
|
||||
) : (
|
||||
<Box w="2em" h="2em" mr="1em" />
|
||||
)}
|
||||
</AccordionItem>
|
||||
)
|
||||
})}
|
||||
<Grid
|
||||
gridTemplateColumns="repeat(auto-fill, 200px)"
|
||||
width="100%"
|
||||
rowGap="0.7em"
|
||||
justifyItems="center"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Link to={`/u/${discord_user.discord_id}`}>
|
||||
<Flex alignItems="center">
|
||||
<UserAvatar
|
||||
twitterName={discord_user.twitter_name}
|
||||
name={discord_user.username}
|
||||
mr="5px"
|
||||
/>
|
||||
<span>
|
||||
{discord_user.username}#{discord_user.discriminator}
|
||||
</span>
|
||||
</Flex>
|
||||
</Link>
|
||||
<Box>
|
||||
{discord_user.country && (
|
||||
<>
|
||||
<Flag code={discord_user.country} />
|
||||
{
|
||||
countries.find(obj => obj.code === discord_user.country)
|
||||
?.name
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Flex alignItems="center">
|
||||
{discord_user.twitter_name && (
|
||||
<>
|
||||
<Box as={FaTwitter} />
|
||||
<Box as="span" ml="5px">
|
||||
{discord_user.twitter_name}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
<Box color="#999999">
|
||||
{new Date(parseInt(post.createdAt)).toLocaleDateString()}
|
||||
</Box>
|
||||
<Flex alignItems="center">
|
||||
{discord_user?.weapons &&
|
||||
discord_user.weapons.map(wpn => (
|
||||
<Box mx="0.3em" key={wpn}>
|
||||
<WeaponImage englishName={wpn} size="SMALL" />
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
<RoleIcons playstyles={post.playstyles} />
|
||||
<VCIcon canVC={post.can_vc} />
|
||||
</Grid>
|
||||
</AccordionHeader>
|
||||
{canBeExpanded && (
|
||||
<AccordionPanel
|
||||
mt="3px"
|
||||
py={4}
|
||||
background={darkerBgColor}
|
||||
whiteSpace="pre-wrap"
|
||||
textAlign="center"
|
||||
>
|
||||
{post.activity && (
|
||||
<Box>
|
||||
<Heading size="md">Activity</Heading>
|
||||
{post.activity}
|
||||
</Box>
|
||||
)}
|
||||
{post.looking_for && (
|
||||
<Box mt={post.activity ? "1em" : undefined}>
|
||||
<Heading size="md">Looking for</Heading>
|
||||
{post.looking_for}
|
||||
</Box>
|
||||
)}
|
||||
{post.past_experience && (
|
||||
<Box
|
||||
mt={post.activity || post.looking_for ? "1em" : undefined}
|
||||
>
|
||||
<Heading size="md">Past experience</Heading>
|
||||
{post.past_experience}
|
||||
</Box>
|
||||
)}
|
||||
{post.description && (
|
||||
<Box
|
||||
mt={
|
||||
post.activity || post.looking_for || post.past_experience
|
||||
? "1em"
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Heading size="md">Description</Heading>
|
||||
{post.description}
|
||||
</Box>
|
||||
)}
|
||||
</AccordionPanel>
|
||||
)}
|
||||
</AccordionItem>
|
||||
)
|
||||
})}
|
||||
</Accordion>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { useContext } from "react"
|
|||
import MyThemeContext from "../../themeContext"
|
||||
import "./HomePage.css"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import Alert from "../elements/Alert"
|
||||
|
||||
const HomePage: React.FC<RouteComponentProps> = () => {
|
||||
const { colorMode, grayWithShade } = useContext(MyThemeContext)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect, useRef, useContext } from "react"
|
||||
import React, { useState, useEffect, useRef } from "react"
|
||||
import { SketchField, Tools } from "@sendou/react-sketch"
|
||||
import { CirclePicker } from "react-color"
|
||||
import weaponDict from "../../utils/english_internal.json"
|
||||
|
|
@ -9,20 +9,19 @@ import { Helmet } from "react-helmet-async"
|
|||
import { Weapon } from "../../types"
|
||||
import Error from "../common/Error"
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
Box,
|
||||
InputGroup,
|
||||
Input,
|
||||
InputRightElement,
|
||||
} from "@chakra-ui/core"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import { FaFileDownload, FaFileUpload, FaFileImage } from "react-icons/fa"
|
||||
import reef from "../../assets/plannerMaps/reef-sz.png"
|
||||
import MapSelect from "./MapSelect"
|
||||
import { RouteComponentProps } from "@reach/router"
|
||||
import PageHeader from "../common/PageHeader"
|
||||
import DraggableWeaponSelector from "./DraggableWeaponSelector"
|
||||
import Button from "../elements/Button"
|
||||
|
||||
const MapPlannerPage: React.FC<RouteComponentProps> = () => {
|
||||
let sketch: any = null
|
||||
|
|
@ -53,7 +52,6 @@ const MapPlannerPage: React.FC<RouteComponentProps> = () => {
|
|||
enableCopyPaste: false,
|
||||
}
|
||||
const fileInput = useRef<HTMLInputElement | null>(null)
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
const [tool, setTool] = useState(Tools.Pencil)
|
||||
const [color, setColor] = useState("#f44336")
|
||||
const [canUndo, setCanUndo] = useState(false)
|
||||
|
|
@ -202,9 +200,8 @@ const MapPlannerPage: React.FC<RouteComponentProps> = () => {
|
|||
<Flex justifyContent="space-between" mt="1em" flexWrap="wrap">
|
||||
<Button
|
||||
onClick={() => download(sketch.toDataURL(), "png")}
|
||||
leftIcon={FaFileImage}
|
||||
variantColor={themeColor}
|
||||
variant="outline"
|
||||
icon={FaFileImage}
|
||||
outlined
|
||||
>
|
||||
Download as .png
|
||||
</Button>
|
||||
|
|
@ -216,18 +213,12 @@ const MapPlannerPage: React.FC<RouteComponentProps> = () => {
|
|||
"json"
|
||||
)
|
||||
}
|
||||
leftIcon={FaFileDownload}
|
||||
variantColor={themeColor}
|
||||
variant="outline"
|
||||
icon={FaFileDownload}
|
||||
outlined
|
||||
>
|
||||
Download as .json
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleUpload()}
|
||||
leftIcon={FaFileUpload}
|
||||
variantColor={themeColor}
|
||||
variant="outline"
|
||||
>
|
||||
<Button onClick={() => handleUpload()} icon={FaFileUpload} outlined>
|
||||
Load from .json
|
||||
</Button>
|
||||
<input type="file" accept=".json" ref={fileInput} />
|
||||
|
|
@ -244,10 +235,9 @@ const MapPlannerPage: React.FC<RouteComponentProps> = () => {
|
|||
/>
|
||||
<InputRightElement width="7rem">
|
||||
<Button
|
||||
h="1.75rem"
|
||||
size="sm"
|
||||
onClick={() => addTextToSketch()}
|
||||
isDisabled={text === ""}
|
||||
disabled={text === ""}
|
||||
>
|
||||
Add to picture
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export interface User {
|
|||
twitch_name?: string
|
||||
twitter_name?: string
|
||||
country?: CountryCode
|
||||
weapons?: Weapon[]
|
||||
weapons: Weapon[]
|
||||
top500: boolean
|
||||
custom_url?: string
|
||||
sens?: {
|
||||
|
|
@ -143,7 +143,7 @@ export interface FreeAgentPost {
|
|||
discord_id: string
|
||||
twitter_name?: string
|
||||
country?: CountryCode
|
||||
weapons?: Weapon[]
|
||||
weapons: Weapon[]
|
||||
top500: boolean
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const typeDef = gql`
|
|||
twitter_name: String
|
||||
country: String
|
||||
sens: Sens
|
||||
weapons: [String]!
|
||||
weapons: [String!]!
|
||||
custom_url: String
|
||||
top500: Boolean!
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user