mirror of
https://github.com/System-End/site.git
synced 2026-04-19 18:35:12 +00:00
Team page redesign updated (#1786)
This commit is contained in:
parent
7a31866e23
commit
596ef1dbc4
31 changed files with 2562 additions and 1994 deletions
|
|
@ -62,21 +62,21 @@ const Prizes = ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
transform: `rotate(${pRotate}deg)`,
|
transform: `rotate(${pRotate}deg)`,
|
||||||
transitionDuration: '0.5s',
|
transitionDuration: '0.5s',
|
||||||
opacity: stock == 0 ? '0.5' : 1,
|
opacity: stock === 0 ? '0.5' : 1,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
transform: stock == 0 ? null : 'scale(1.1)',
|
transform: stock === 0 ? null : 'scale(1.1)',
|
||||||
cursor: stock == 0 ? 'default' : 'pointer'
|
cursor: stock === 0 ? 'default' : 'pointer'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
const div = e.currentTarget
|
const div = e.currentTarget
|
||||||
const quantity = div.querySelector('[id*="dropdown-"]')
|
const quantity = div.querySelector('[id*="dropdown-"]')
|
||||||
const buy = div.querySelector('#buy')
|
const buy = div.querySelector('#buy')
|
||||||
if (quantity === e.target || buy == e.target) {
|
if (quantity === e.target || buy === e.target) {
|
||||||
console.log('TRUE')
|
console.log('TRUE')
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
stock != 0
|
stock !== 0
|
||||||
? document.getElementById(`${parsedFullName}-info`).showModal()
|
? document.getElementById(`${parsedFullName}-info`).showModal()
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ const Prizes = ({
|
||||||
alt={text}
|
alt={text}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
{stock <= 100 && stock != null && (
|
{stock <= 100 && stock !== null && (
|
||||||
<Text
|
<Text
|
||||||
sx={{
|
sx={{
|
||||||
background: '#CC6CE7',
|
background: '#CC6CE7',
|
||||||
|
|
@ -113,7 +113,7 @@ const Prizes = ({
|
||||||
variant="headline"
|
variant="headline"
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{stock == 0 ? <>Sold out</> : <>Only {stock} left! </>}
|
{stock === 0 ? <>Sold out</> : <>Only {stock} left! </>}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<Text
|
<Text
|
||||||
|
|
@ -161,7 +161,7 @@ const Prizes = ({
|
||||||
(
|
(
|
||||||
hoursBalance
|
hoursBalance
|
||||||
? hoursBalance / cost >= 2
|
? hoursBalance / cost >= 2
|
||||||
? stock != 0
|
? stock !== 0
|
||||||
: null
|
: null
|
||||||
: null
|
: null
|
||||||
) ? (
|
) ? (
|
||||||
|
|
@ -182,7 +182,7 @@ const Prizes = ({
|
||||||
(
|
(
|
||||||
hoursBalance
|
hoursBalance
|
||||||
? hoursBalance / cost >= 1
|
? hoursBalance / cost >= 1
|
||||||
? stock != 0
|
? stock !== 0
|
||||||
: null
|
: null
|
||||||
: null
|
: null
|
||||||
) ? (
|
) ? (
|
||||||
|
|
@ -289,7 +289,7 @@ const Prizes = ({
|
||||||
variant="headline"
|
variant="headline"
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{cost} {cost == 1 ? 'ticket' : 'tickets'}
|
{cost} {cost === 1 ? 'ticket' : 'tickets'}
|
||||||
</Text>
|
</Text>
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
|
|
@ -378,7 +378,7 @@ const Prizes = ({
|
||||||
(
|
(
|
||||||
hoursBalance
|
hoursBalance
|
||||||
? hoursBalance / cost >= 2
|
? hoursBalance / cost >= 2
|
||||||
? stock != 0
|
? stock !== 0
|
||||||
: null
|
: null
|
||||||
: null
|
: null
|
||||||
) ? (
|
) ? (
|
||||||
|
|
@ -398,7 +398,7 @@ const Prizes = ({
|
||||||
(
|
(
|
||||||
hoursBalance
|
hoursBalance
|
||||||
? hoursBalance / cost >= 1
|
? hoursBalance / cost >= 1
|
||||||
? stock != 0
|
? stock !== 0
|
||||||
: null
|
: null
|
||||||
: null
|
: null
|
||||||
) ? (
|
) ? (
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ export default function ShopComponent({
|
||||||
>
|
>
|
||||||
{availableItems
|
{availableItems
|
||||||
.sort((a, b) => a['Cost Hours'] - b['Cost Hours'])
|
.sort((a, b) => a['Cost Hours'] - b['Cost Hours'])
|
||||||
.filter(item => (item['Stock'] > 0 || item['Stock'] == null))
|
.filter(item => (item['Stock'] > 0 || item['Stock'] === null))
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<Prizes
|
<Prizes
|
||||||
img={item['Image URL']}
|
img={item['Image URL']}
|
||||||
|
|
@ -101,7 +101,7 @@ export default function ShopComponent({
|
||||||
))}
|
))}
|
||||||
{availableItems
|
{availableItems
|
||||||
.sort((a, b) => a['Cost Hours'] - b['Cost Hours'])
|
.sort((a, b) => a['Cost Hours'] - b['Cost Hours'])
|
||||||
.filter(item => (item['Stock'] == 0))
|
.filter(item => (item['Stock'] === 0))
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<Prizes
|
<Prizes
|
||||||
img={item['Image URL']}
|
img={item['Image URL']}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const CreateCard = ({ createCardLink }) => {
|
||||||
<>
|
<>
|
||||||
<a href={createCardLink} className={styles.linkWrapper} rel="noopener noreferrer">
|
<a href={createCardLink} className={styles.linkWrapper} rel="noopener noreferrer">
|
||||||
<div className={styles.card}>
|
<div className={styles.card}>
|
||||||
<img src={img}/>
|
<img src={img} alt="Create a card" />
|
||||||
Create a card
|
Create a card
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const NewProjectForm = ({ authToken }) => {
|
||||||
success: 'Pulling repo data'
|
success: 'Pulling repo data'
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
background: status == 'error' ? '#DE4E2B' : '#09AFB4',
|
background: status === 'error' ? '#DE4E2B' : '#09AFB4',
|
||||||
borderRadius: '10px'
|
borderRadius: '10px'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ const ProjectView = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDarkColor(darkenColor(color, 0.8))
|
setDarkColor(darkenColor(color, 0.8))
|
||||||
setInvertedColor(invertColor(textColor))
|
setInvertedColor(invertColor(textColor))
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [color])
|
}, [color])
|
||||||
|
|
||||||
// function convertToRawUrl(githubUrl) {
|
// function convertToRawUrl(githubUrl) {
|
||||||
|
|
@ -133,8 +134,8 @@ const ProjectView = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1 className="slackey">{title}</h1>
|
<h1 className="slackey">{title}</h1>
|
||||||
<h2>{description != 'Description Not Found' ? description : <></>}</h2>
|
<h2>{description !== 'Description Not Found' ? description : <></>}</h2>
|
||||||
<h3>{user != 'User Not Found' ? <>By {user}</> : <></>}</h3>
|
<h3>{user !== 'User Not Found' ? <>By {user}</> : <></>}</h3>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={styles.buttonGroup}
|
className={styles.buttonGroup}
|
||||||
|
|
@ -218,13 +219,13 @@ const ProjectView = ({
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
gridTemplateColumns:
|
gridTemplateColumns:
|
||||||
screenshot != '' && video != ''
|
screenshot !== '' && video !== ''
|
||||||
? ['1fr', '1fr 1fr', '1fr 1fr']
|
? ['1fr', '1fr 1fr', '1fr 1fr']
|
||||||
: '1fr',
|
: '1fr',
|
||||||
gap: '10px'
|
gap: '10px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{image != '' && (
|
{image !== '' && (
|
||||||
<div
|
<div
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
@ -254,7 +255,7 @@ const ProjectView = ({
|
||||||
|
|
||||||
<p
|
<p
|
||||||
className={styles.description}
|
className={styles.description}
|
||||||
sx={{ textAlign: screenshot.length != 1 ? 'center' : 'left' }}
|
sx={{ textAlign: screenshot.length !== 1 ? 'center' : 'left' }}
|
||||||
>
|
>
|
||||||
<ReadmeRenderer markdown={markdown} />
|
<ReadmeRenderer markdown={markdown} />
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import Icon from '@hackclub/icons'
|
import Icon from '@hackclub/icons'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Avatar, Box, Card, Flex, Text } from 'theme-ui'
|
import { Box, Card, Flex, Text } from 'theme-ui'
|
||||||
|
|
||||||
export default function Bio({ popup = true, spanTwo = false, ...props }) {
|
export default function Bio({ popup = true, spanTwo = false, ...props }) {
|
||||||
const { img, name, teamRole, pronouns, text, subrole, email, href, video } =
|
const { name, teamRole, pronouns, text, subrole, email, href, video, img } =
|
||||||
props
|
props
|
||||||
const [expand, setExpand] = useState(false)
|
const [expand, setExpand] = useState(false)
|
||||||
return (
|
return (
|
||||||
|
|
@ -36,23 +36,21 @@ export default function Bio({ popup = true, spanTwo = false, ...props }) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar
|
{img && (
|
||||||
size={64}
|
<Box
|
||||||
width={64}
|
as="img"
|
||||||
height={64}
|
src={img}
|
||||||
mr={3}
|
alt={name}
|
||||||
src={img}
|
sx={{
|
||||||
alt={name}
|
width: 96,
|
||||||
sx={{
|
height: 96,
|
||||||
overflow: 'hidden',
|
minWidth: 96,
|
||||||
objectFit: 'cover',
|
borderRadius: '50%',
|
||||||
transition: 'transform 0.125s ease-in-out',
|
objectFit: 'cover',
|
||||||
'&:hover': { transform: 'rotate(-8deg) scale(1.25)' },
|
mr: 3
|
||||||
flexShrink: 0,
|
}}
|
||||||
width: '64px',
|
/>
|
||||||
height: '64px'
|
)}
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box>
|
<Box>
|
||||||
<Text sx={{ fontSize: [3, 3, 3] }} variant="headline" color="black">
|
<Text sx={{ fontSize: [3, 3, 3] }} variant="headline" color="black">
|
||||||
{name}
|
{name}
|
||||||
|
|
|
||||||
239
components/boardbio.js
Normal file
239
components/boardbio.js
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
import Icon from '@hackclub/icons'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { Avatar, Box, Card, Flex, Text } from 'theme-ui'
|
||||||
|
|
||||||
|
export default function BoardBox({ popup = true, ...props }) {
|
||||||
|
const { img, name, teamRole, pronouns, text, subrole, email, href, video } = props
|
||||||
|
const [expand, setExpand] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card
|
||||||
|
bg="#d9f7ed"
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: popup ? 'column' : 'row',
|
||||||
|
alignItems: popup ? 'center' : 'flex-start',
|
||||||
|
justifyContent: popup ? 'center' : 'flex-start',
|
||||||
|
transition: 'transform 0.125s ease-in-out',
|
||||||
|
'&:hover': { transform: 'scale(1.025)' },
|
||||||
|
cursor: (text && popup) || href ? 'pointer' : null,
|
||||||
|
textDecoration: 'none',
|
||||||
|
maxWidth: popup ? 'auto' : '600px',
|
||||||
|
zIndex: !popup ? 1003 : 5,
|
||||||
|
maxHeight: popup ? 'auto' : '90vh',
|
||||||
|
overflowY: 'hidden',
|
||||||
|
position: 'relative'
|
||||||
|
}}
|
||||||
|
as={href && !text ? 'a' : 'div'}
|
||||||
|
href={href}
|
||||||
|
target="_blank"
|
||||||
|
onClick={() => {
|
||||||
|
if (text && popup) {
|
||||||
|
setExpand(true)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{popup ? (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
sx={{ fontSize: subrole ? 3 : 4, textAlign: 'center', mb: subrole ? 0 : 1, mt: subrole ? -3: -2 }}
|
||||||
|
color="black"
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
color="#24B5A5"
|
||||||
|
variant="subheadline"
|
||||||
|
sx={{ fontSize: subrole ? 1 : 3, textAlign: 'center', mb: subrole ? 0 : 2 }}
|
||||||
|
>
|
||||||
|
{teamRole}
|
||||||
|
</Text>
|
||||||
|
{subrole && (
|
||||||
|
<Text
|
||||||
|
color="#24B5A5"
|
||||||
|
sx={{
|
||||||
|
fontSize: 1,
|
||||||
|
textAlign: 'center',
|
||||||
|
mb: 2,
|
||||||
|
fontWeight: 400
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{subrole}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
as="img"
|
||||||
|
src={img}
|
||||||
|
alt={name}
|
||||||
|
sx={{
|
||||||
|
width: '120px',
|
||||||
|
height: '120px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
objectFit: 'cover',
|
||||||
|
mb: subrole ? -3: -2
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Avatar
|
||||||
|
size={64}
|
||||||
|
width={64}
|
||||||
|
height={64}
|
||||||
|
mr={3}
|
||||||
|
src={img}
|
||||||
|
alt={name}
|
||||||
|
sx={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
objectFit: 'cover',
|
||||||
|
transition: 'transform 0.125s ease-in-out',
|
||||||
|
'&:hover': { transform: 'rotate(-8deg) scale(1.25)' },
|
||||||
|
flexShrink: 0,
|
||||||
|
width: '64px',
|
||||||
|
height: '64px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box>
|
||||||
|
<Text sx={{ fontSize: [3, 3, 3] }} variant="headline" color="black">
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
<Flex>
|
||||||
|
<Text>
|
||||||
|
<Text
|
||||||
|
color="#24B5A5"
|
||||||
|
variant="subheadline"
|
||||||
|
fontSize={2}
|
||||||
|
sx={{
|
||||||
|
mb: ['0px', '0px', '0px'],
|
||||||
|
fontSize: '1.1em',
|
||||||
|
width: 'fit-content'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{teamRole}
|
||||||
|
</Text>
|
||||||
|
{subrole && (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<Text
|
||||||
|
color="#24B5A5"
|
||||||
|
sx={{
|
||||||
|
mb: ['0px', '0px', '0px'],
|
||||||
|
fontSize: 1,
|
||||||
|
fontWeight: 400,
|
||||||
|
width: 'fit-content'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{subrole}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{pronouns && (
|
||||||
|
<Text fontSize={1} ml={1} color="muted" align="center">
|
||||||
|
({pronouns})
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
{email &&
|
||||||
|
(email.includes('@') ? (
|
||||||
|
<Text color="muted" as={'a'} href={`mailto:${email}`}>
|
||||||
|
{email}
|
||||||
|
<br />
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text
|
||||||
|
color="muted"
|
||||||
|
as={'a'}
|
||||||
|
href={`mailto:${email}@hackclub.com`}
|
||||||
|
>
|
||||||
|
{email}@hackclub.com
|
||||||
|
<br />
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
<Text mt={2} mb={0} color="black">
|
||||||
|
{text}
|
||||||
|
</Text>
|
||||||
|
{video && (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
marginTop: 4,
|
||||||
|
marginX: 5,
|
||||||
|
justifyContent: 'center',
|
||||||
|
aspectRatio: 4 / 3
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
width="100%"
|
||||||
|
src={video}
|
||||||
|
title="YouTube video player"
|
||||||
|
frameBorder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
allowFullScreen
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
{href && (
|
||||||
|
<Flex sx={{ alignItems: 'center' }}>
|
||||||
|
<Text
|
||||||
|
sx={{
|
||||||
|
transform: 'translateX(-4px) translateY(2px)',
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon glyph="external-fill" size={24} />
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
mt={1}
|
||||||
|
mb={0}
|
||||||
|
color="black"
|
||||||
|
as={'a'}
|
||||||
|
target="_blank"
|
||||||
|
href={href}
|
||||||
|
sx={{ transform: 'translateX(-2px)' }}
|
||||||
|
>
|
||||||
|
{href}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
{popup && expand && (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 1004,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
height: '100vh',
|
||||||
|
width: '100vw',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
background: 'rgba(0,0,0,0.6)',
|
||||||
|
pb: 4
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BoardBox {...props} popup={false} />
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 1002,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
height: '100vh',
|
||||||
|
width: '100vw',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
pb: 4
|
||||||
|
}}
|
||||||
|
onClick={() => setExpand(false)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ const ForceTheme = ({ theme }) => {
|
||||||
const [colorMode, setColorMode] = useColorMode()
|
const [colorMode, setColorMode] = useColorMode()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setColorMode(theme)
|
setColorMode(theme)
|
||||||
}, [])
|
}, [setColorMode, theme])
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function Blueprint({ stars, blueprintData }) {
|
||||||
setProjects('100+ projects built')
|
setProjects('100+ projects built')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [])
|
}, [blueprintData])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ const ReplitForm = ({ cssDark }) => {
|
||||||
draggedSticker.current = null
|
draggedSticker.current = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleInputChange = e => {
|
const handleInputChange = e => {
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ export default function Join() {
|
||||||
</Box>
|
</Box>
|
||||||
<Image
|
<Image
|
||||||
src="https://cloud-j0p07nviw-hack-club-bot.vercel.app/0image.png"
|
src="https://cloud-j0p07nviw-hack-club-bot.vercel.app/0image.png"
|
||||||
|
alt="Hack Club Slack community"
|
||||||
sx={{
|
sx={{
|
||||||
width: ['100%', '100%', '50%'],
|
width: ['100%', '100%', '50%'],
|
||||||
height: ['100%', '100%', '30rem'],
|
height: ['100%', '100%', '30rem'],
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ export default function Project({ title, description, color, img, itemId }) {
|
||||||
</Box>
|
</Box>
|
||||||
<Image
|
<Image
|
||||||
src={`/slack/${img}.png`}
|
src={`/slack/${img}.png`}
|
||||||
|
alt={title}
|
||||||
sx={{
|
sx={{
|
||||||
visibility: ['visible'],
|
visibility: ['visible'],
|
||||||
height: ['100%'],
|
height: ['100%'],
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export default function Quote({ text, person, age, location, img }) {
|
||||||
"{text}"
|
"{text}"
|
||||||
</Text>
|
</Text>
|
||||||
<Flex sx={{ gap: '8px' }}>
|
<Flex sx={{ gap: '8px' }}>
|
||||||
<Image src={img} sx={{ height: 24, width: 24, borderRadius: 100 }} />
|
<Image src={img} alt={`${person}'s profile picture`} sx={{ height: 24, width: 24, borderRadius: 100 }} />
|
||||||
<Text as="h3" sx={{ fontWeight: 400 }}>
|
<Text as="h3" sx={{ fontWeight: 400 }}>
|
||||||
{person}, {age} from {location}
|
{person}, {age} from {location}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
110
pages/acknowledged.tsx
Normal file
110
pages/acknowledged.tsx
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { Box, Container, Flex, Grid, Text } from 'theme-ui'
|
||||||
|
import Meta from '@hackclub/meta'
|
||||||
|
import Head from 'next/head'
|
||||||
|
import Nav from '../components/nav'
|
||||||
|
import Footer from '../components/footer'
|
||||||
|
import Bio from '../components/bio'
|
||||||
|
import BoardBox from '../components/boardbio'
|
||||||
|
import ForceTheme from '../components/force-theme'
|
||||||
|
import { fetchTeam } from './api/team'
|
||||||
|
|
||||||
|
|
||||||
|
export default function Acknowleged({ team }) {
|
||||||
|
// Spacing between major team section boxes
|
||||||
|
const BOX_SPACING = 5
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box as="main" key="main" pb={5}>
|
||||||
|
<ForceTheme theme="light" />
|
||||||
|
{/* @ts-expect-error -- TODO: fix this */}
|
||||||
|
<Nav />
|
||||||
|
<Meta
|
||||||
|
as={Head}
|
||||||
|
title="Team"
|
||||||
|
description="Meet the team that runs Hack Club, a global nonprofit network of high school computer science clubs."
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
pt={6}
|
||||||
|
pb={5}
|
||||||
|
px={[2, 4]}
|
||||||
|
sx={{
|
||||||
|
backgroundImage:
|
||||||
|
'radial-gradient(ellipse farthest-corner at top left,rgb(36 181 165 / 70%),rgb(30 151 137 / 70%)), url(https://hc-cdn.hel1.your-objectstorage.com/s/v3/cf3488823b5ae7c41ed968224485ea06423a6862_IMG_9920.jpg)',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: '25% 15%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Container>
|
||||||
|
<Text variant="ultratitle" color="snow">
|
||||||
|
By the students,
|
||||||
|
<br /> for the students.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
as="div"
|
||||||
|
variant="lead"
|
||||||
|
color="smoke"
|
||||||
|
sx={{ maxWidth: '650px' }}
|
||||||
|
>
|
||||||
|
We believe in a world where every young person is empowered to be
|
||||||
|
the change they want to see around them. At Hack Club, we’re
|
||||||
|
working hard to make it reality.
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
<Container>
|
||||||
|
<Box sx={{ textAlign: 'center', mt: 100, mb: [3, 4] }}>
|
||||||
|
<Text
|
||||||
|
variant="title"
|
||||||
|
color="orange"
|
||||||
|
sx={{ lineHeight: '1em', fontSize: [4, 5, 6] }}
|
||||||
|
as="h2"
|
||||||
|
>
|
||||||
|
Acknowledgements
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
variant="title"
|
||||||
|
color="text"
|
||||||
|
sx={{
|
||||||
|
lineHeight: '1.2',
|
||||||
|
fontSize: [1, 3, 4],
|
||||||
|
my: [3, 0, 0],
|
||||||
|
fontWeight: 400,
|
||||||
|
maxWidth: '600px',
|
||||||
|
width: '100%',
|
||||||
|
margin: 'auto'
|
||||||
|
}}
|
||||||
|
as="h2"
|
||||||
|
>
|
||||||
|
Thank you to everyone who helped shape Hack Club into what it is
|
||||||
|
today...
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.acknowledged?.map(member => (
|
||||||
|
<Bio
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
key={member.name}
|
||||||
|
href={member.website}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
<Footer light key="footer" />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getServerSideProps = async () => {
|
||||||
|
try {
|
||||||
|
const team = await fetchTeam()
|
||||||
|
return { props: { team } }
|
||||||
|
} catch (e) {
|
||||||
|
return { props: { team: {} } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ export default async function handler(req, res) {
|
||||||
formURL: record.fields['Order Form URL'],
|
formURL: record.fields['Order Form URL'],
|
||||||
description: record.fields['Description'],
|
description: record.fields['Description'],
|
||||||
flavorText: record?.fields['Flavor text']?.map(recordID => {
|
flavorText: record?.fields['Flavor text']?.map(recordID => {
|
||||||
const flavorRecord = data.flavor.find(f => f.id == recordID)
|
const flavorRecord = data.flavor.find(f => f.id === recordID)
|
||||||
const result = {
|
const result = {
|
||||||
message: flavorRecord.fields["Message"],
|
message: flavorRecord.fields["Message"],
|
||||||
character: flavorRecord.fields["Character"],
|
character: flavorRecord.fields["Character"],
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export const shopParts = async () => {
|
||||||
if (stock && fields["Count of Orders Fulfilled"]) {
|
if (stock && fields["Count of Orders Fulfilled"]) {
|
||||||
stock -= fields["Count of Orders Fulfilled"]
|
stock -= fields["Count of Orders Fulfilled"]
|
||||||
}
|
}
|
||||||
return { id: record.id, ...record.fields, "Stock": (stock == null)? null : (stock >= 0 ? stock : 0) }
|
return { id: record.id, ...record.fields, "Stock": (stock === null)? null : (stock >= 0 ? stock : 0) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default async function handler(req, res) {
|
||||||
await rsvpsTable.create(fields)
|
await rsvpsTable.create(fields)
|
||||||
|
|
||||||
res.status(200).json({ success: true })
|
res.status(200).json({ success: true })
|
||||||
} else if (req.method == 'GET') {
|
} else if (req.method === 'GET') {
|
||||||
const result = await rsvpsTable.read()
|
const result = await rsvpsTable.read()
|
||||||
|
|
||||||
res.status(200).json(result.length)
|
res.status(200).json(result.length)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ interface TeamMember {
|
||||||
website: string
|
website: string
|
||||||
pronouns: string
|
pronouns: string
|
||||||
avatar: string
|
avatar: string
|
||||||
|
staff?: boolean
|
||||||
|
gapyear?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTeam() {
|
export async function fetchTeam() {
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,13 @@ export default function Shop({
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cat == 'all') {
|
if (cat === 'all') {
|
||||||
setItems(availableItems)
|
setItems(availableItems)
|
||||||
} else {
|
} else {
|
||||||
let i = availableItems.filter(items => items['Category'].includes(cat))
|
let i = availableItems.filter(items => items['Category'].includes(cat))
|
||||||
setItems(i)
|
setItems(i)
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [cat])
|
}, [cat])
|
||||||
|
|
||||||
const spotlightRef = useRef()
|
const spotlightRef = useRef()
|
||||||
|
|
@ -232,7 +233,7 @@ export default function Shop({
|
||||||
🦢 Swag
|
🦢 Swag
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
{cat == 'all' ? (
|
{cat === 'all' ? (
|
||||||
<>
|
<>
|
||||||
<Text
|
<Text
|
||||||
sx={{
|
sx={{
|
||||||
|
|
@ -314,6 +315,7 @@ export default function Shop({
|
||||||
</Box>
|
</Box>
|
||||||
<img
|
<img
|
||||||
src="/arcade/o6.png"
|
src="/arcade/o6.png"
|
||||||
|
alt="Decorative illustration"
|
||||||
sx={{
|
sx={{
|
||||||
width: ['30%', '30%', '30%', '40%'],
|
width: ['30%', '30%', '30%', '40%'],
|
||||||
maxWidth: '210px',
|
maxWidth: '210px',
|
||||||
|
|
|
||||||
|
|
@ -257,10 +257,10 @@ const Powerups = ({
|
||||||
variant="headline"
|
variant="headline"
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{cost} {cost == 1 ? 'ticket' : 'tickets'}
|
{cost} {cost === 1 ? 'ticket' : 'tickets'}
|
||||||
</Text>
|
</Text>
|
||||||
{extraTags?.map((tag, i) => {
|
{extraTags?.map((tag, i) => {
|
||||||
if (tag == 'Limited Supply') {
|
if (tag === 'Limited Supply') {
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
key={tag}
|
key={tag}
|
||||||
|
|
@ -383,7 +383,7 @@ const Powerups = ({
|
||||||
variant="headline"
|
variant="headline"
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{cost} {cost == 1 ? 'ticket' : 'tickets'}
|
{cost} {cost === 1 ? 'ticket' : 'tickets'}
|
||||||
</Text>
|
</Text>
|
||||||
</dialog>
|
</dialog>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
@ -407,7 +407,7 @@ const Intro = ({ title, num, text, img, third, ...props }) => {
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
sx={{
|
sx={{
|
||||||
display: 'block',
|
display: 'block',
|
||||||
width: third == 'true' ? ['100%', '100%', '100%', '70%'] : '100%'
|
width: third === 'true' ? ['100%', '100%', '100%', '70%'] : '100%'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
|
|
@ -953,7 +953,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
paddingBottom: '20vh'
|
paddingBottom: '20vh'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{slack == 'slack' ? (
|
{slack === 'slack' ? (
|
||||||
<Announcement
|
<Announcement
|
||||||
copy="You were redirected as we're running a special summer event!"
|
copy="You were redirected as we're running a special summer event!"
|
||||||
caption="To join our Slack, join ARCADE."
|
caption="To join our Slack, join ARCADE."
|
||||||
|
|
@ -1105,6 +1105,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="/arcade/prizes.png"
|
src="/arcade/prizes.png"
|
||||||
|
alt="Arcade prizes"
|
||||||
sx={{
|
sx={{
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
width: ['80%', '70%', '65%', '80%'],
|
width: ['80%', '70%', '65%', '80%'],
|
||||||
|
|
@ -1188,6 +1189,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="/arcade/a1.png"
|
src="/arcade/a1.png"
|
||||||
|
alt=""
|
||||||
sx={{
|
sx={{
|
||||||
width: '100px',
|
width: '100px',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
@ -1571,6 +1573,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="/arcade/r5.png"
|
src="/arcade/r5.png"
|
||||||
|
alt=""
|
||||||
sx={{
|
sx={{
|
||||||
width: ['35%', '35%', '35%', '50%'],
|
width: ['35%', '35%', '35%', '50%'],
|
||||||
maxWidth: '210px',
|
maxWidth: '210px',
|
||||||
|
|
@ -1605,6 +1608,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="/arcade/o5.png"
|
src="/arcade/o5.png"
|
||||||
|
alt=""
|
||||||
sx={{
|
sx={{
|
||||||
width: ['45%', '45%', '45%', '60%'],
|
width: ['45%', '45%', '45%', '60%'],
|
||||||
maxWidth: '310px',
|
maxWidth: '310px',
|
||||||
|
|
@ -1617,6 +1621,7 @@ const Arcade = ({ stickers = [], carousel = [], highlightedItems = [] }) => {
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="/arcade/o6.png"
|
src="/arcade/o6.png"
|
||||||
|
alt=""
|
||||||
sx={{
|
sx={{
|
||||||
width: ['30%', '30%', '30%', '40%'],
|
width: ['30%', '30%', '30%', '40%'],
|
||||||
maxWidth: '210px',
|
maxWidth: '210px',
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,13 @@ export default function Shop({
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cat == 'all') {
|
if (cat === 'all') {
|
||||||
setItems(availableItems)
|
setItems(availableItems)
|
||||||
} else {
|
} else {
|
||||||
let i = availableItems.filter(items => items['Category'].includes(cat))
|
let i = availableItems.filter(items => items['Category'].includes(cat))
|
||||||
setItems(i)
|
setItems(i)
|
||||||
}
|
}
|
||||||
}, [cat])
|
}, [cat, availableItems])
|
||||||
|
|
||||||
// Spotlight effect
|
// Spotlight effect
|
||||||
const spotlightRef = useRef()
|
const spotlightRef = useRef()
|
||||||
|
|
@ -132,6 +132,7 @@ export default function Shop({
|
||||||
<Flag sx={{ display: 'block', zIndex: 4, ml: 5 }} />
|
<Flag sx={{ display: 'block', zIndex: 4, ml: 5 }} />
|
||||||
<img
|
<img
|
||||||
src="/arcade/o6.png"
|
src="/arcade/o6.png"
|
||||||
|
alt="Decorative dino"
|
||||||
sx={{
|
sx={{
|
||||||
width: ['30%', '30%', '30%', '40%'],
|
width: ['30%', '30%', '30%', '40%'],
|
||||||
maxWidth: '210px',
|
maxWidth: '210px',
|
||||||
|
|
@ -270,7 +271,7 @@ export default function Shop({
|
||||||
🦢 Swag
|
🦢 Swag
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
{cat == 'all' ? (
|
{cat === 'all' ? (
|
||||||
<>
|
<>
|
||||||
<Text
|
<Text
|
||||||
sx={{
|
sx={{
|
||||||
|
|
|
||||||
|
|
@ -27,26 +27,28 @@ const flavorText = [
|
||||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||||
const LoginPage = ({token}) => {
|
const LoginPage = ({token}) => {
|
||||||
const [ status, setStatus ] = useState('Loading...')
|
const [ status, setStatus ] = useState('Loading...')
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
const minWaitTime = sleep(3 * 1000)
|
const run = async () => {
|
||||||
let data = {}
|
const minWaitTime = sleep(3 * 1000)
|
||||||
const getTokenPromise = new Promise(async resolve => {
|
let data = {}
|
||||||
const response = await fetch(`/api/arcade/showcase/login/${token}`, {method: 'POST'})
|
const getTokenPromise = new Promise(async resolve => {
|
||||||
data = await response.json()
|
const response = await fetch(`/api/arcade/showcase/login/${token}`, {method: 'POST'})
|
||||||
resolve()
|
data = await response.json()
|
||||||
})
|
resolve()
|
||||||
const [ _wait, _data ] = await Promise.all([minWaitTime, getTokenPromise])
|
})
|
||||||
|
const [ _wait, _data ] = await Promise.all([minWaitTime, getTokenPromise])
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
setStatus(data.error)
|
setStatus(data.error)
|
||||||
} else {
|
} else {
|
||||||
setStatus("Redirecting!")
|
setStatus("Redirecting!")
|
||||||
window.localStorage.setItem('arcade.authToken', data.authToken)
|
window.localStorage.setItem('arcade.authToken', data.authToken)
|
||||||
await sleep(250)
|
await sleep(250)
|
||||||
window.location.href = '/arcade/showcase/my'
|
window.location.href = '/arcade/showcase/my'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
run()
|
||||||
}, [])
|
}, [token])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,7 @@ const My = () => {
|
||||||
if (now > deadline) {
|
if (now > deadline) {
|
||||||
setSubmissionClose(true)
|
setSubmissionClose(true)
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [])
|
||||||
// const launchDate = new Date(2025, 7, 25, 8, 0, 0, 0)
|
// const launchDate = new Date(2025, 7, 25, 8, 0, 0, 0)
|
||||||
|
|
||||||
|
|
@ -252,9 +253,12 @@ const My = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
loadProjects()
|
const fetchData = async () => {
|
||||||
loadCohort()
|
loadProjects()
|
||||||
|
loadCohort()
|
||||||
|
}
|
||||||
|
fetchData()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -289,6 +293,7 @@ const My = () => {
|
||||||
<div sx={{ zIndex: 5, position: 'relative' }}>
|
<div sx={{ zIndex: 5, position: 'relative' }}>
|
||||||
<img
|
<img
|
||||||
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
||||||
|
alt="Arcade"
|
||||||
sx={{
|
sx={{
|
||||||
width: '30%',
|
width: '30%',
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
|
|
@ -309,7 +314,7 @@ const My = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text className="gaegu" sx={{ color: '#FF5C00' }}>
|
<Text className="gaegu" sx={{ color: '#FF5C00' }}>
|
||||||
{status == 'success' ? `Welcome, ${name}` : ''}
|
{status === 'success' ? `Welcome, ${name}` : ''}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -342,11 +347,11 @@ const My = () => {
|
||||||
</Heading>
|
</Heading>
|
||||||
</SlideDown>
|
</SlideDown>
|
||||||
|
|
||||||
{status == 'loading' && <Loading />}
|
{status === 'loading' && <Loading />}
|
||||||
|
|
||||||
{status == 'error' && <ErrorMessage />}
|
{status === 'error' && <ErrorMessage />}
|
||||||
|
|
||||||
{status == 'success' && (
|
{status === 'success' && (
|
||||||
<ProjectGallery
|
<ProjectGallery
|
||||||
projects={projects}
|
projects={projects}
|
||||||
loadProjects={loadProjects}
|
loadProjects={loadProjects}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ const Showcase = ({ projectID }) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
setStatus('error')
|
setStatus('error')
|
||||||
})
|
})
|
||||||
}, [])
|
}, [projectID])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -121,6 +121,7 @@ const Showcase = ({ projectID }) => {
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
||||||
|
alt="Arcade logo"
|
||||||
sx={{
|
sx={{
|
||||||
width: '30%',
|
width: '30%',
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
|
|
|
||||||
|
|
@ -39,33 +39,37 @@ const ProjectShowPage = ({ projectID }) => {
|
||||||
const [status, setStatus] = useState('loading')
|
const [status, setStatus] = useState('loading')
|
||||||
const [errorMsg, setError] = useState(null)
|
const [errorMsg, setError] = useState(null)
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
const token = window.localStorage.getItem('arcade.authToken')
|
const fetchProject = async () => {
|
||||||
const response = await fetch(`/api/arcade/showcase/projects/${projectID}`, {
|
const token = window.localStorage.getItem('arcade.authToken')
|
||||||
method: 'GET',
|
const response = await fetch(`/api/arcade/showcase/projects/${projectID}`, {
|
||||||
headers: {
|
method: 'GET',
|
||||||
Authorization: `Bearer ${token}`
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
setStatus('error')
|
||||||
|
setError(e)
|
||||||
|
})
|
||||||
|
const data = await response.json()
|
||||||
|
if (data.error) {
|
||||||
|
setStatus('error')
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
setProject(data.project)
|
||||||
|
setStatus('success')
|
||||||
}
|
}
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
setStatus('error')
|
|
||||||
setError(e)
|
|
||||||
})
|
|
||||||
const data = await response.json()
|
|
||||||
if (data.error) {
|
|
||||||
setStatus('error')
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
setProject(data.project)
|
|
||||||
setStatus('success')
|
|
||||||
}
|
}
|
||||||
}, [])
|
fetchProject()
|
||||||
|
}, [projectID])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div sx={{ zIndex: 5, position: 'relative' }}>
|
<div sx={{ zIndex: 5, position: 'relative' }}>
|
||||||
<img
|
<img
|
||||||
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
||||||
|
alt="Arcade logo"
|
||||||
sx={{
|
sx={{
|
||||||
width: '30%',
|
width: '30%',
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
|
|
@ -76,11 +80,11 @@ const ProjectShowPage = ({ projectID }) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className={styles.min}>
|
<div className={styles.min}>
|
||||||
{status == 'loading' && <Loading />}
|
{status === 'loading' && <Loading />}
|
||||||
|
|
||||||
{status == 'error' && <ErrorMessage />}
|
{status === 'error' && <ErrorMessage />}
|
||||||
|
|
||||||
{status == 'success' && (
|
{status === 'success' && (
|
||||||
<ProjectView
|
<ProjectView
|
||||||
key={project.id}
|
key={project.id}
|
||||||
id={project.id}
|
id={project.id}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState, useRef } from 'react'
|
import { useEffect, useState, useRef, useCallback } from 'react'
|
||||||
import { Button, Text, Box, Close, Flex } from 'theme-ui'
|
import { Button, Text, Box, Close, Flex } from 'theme-ui'
|
||||||
import ProjectView from '../../../components/arcade/showcase/project-view'
|
import ProjectView from '../../../components/arcade/showcase/project-view'
|
||||||
import SmallView from '../../../components/arcade/showcase/small-view-card'
|
import SmallView from '../../../components/arcade/showcase/small-view-card'
|
||||||
|
|
@ -283,12 +283,12 @@ const Vote = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
loadProjects()
|
loadProjects()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
/* get individual project details */
|
/* get individual project details */
|
||||||
const getProjectDetails = async () => {
|
const getProjectDetails = useCallback(async () => {
|
||||||
const token = window.localStorage.getItem('arcade.authToken')
|
const token = window.localStorage.getItem('arcade.authToken')
|
||||||
setStatus('loading')
|
setStatus('loading')
|
||||||
|
|
||||||
|
|
@ -318,11 +318,11 @@ const Vote = () => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
setStatus('error')
|
setStatus('error')
|
||||||
}
|
}
|
||||||
}
|
}, [openProjectId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getProjectDetails()
|
getProjectDetails()
|
||||||
}, [openProjectId])
|
}, [getProjectDetails])
|
||||||
|
|
||||||
const dialogRef = useRef(null)
|
const dialogRef = useRef(null)
|
||||||
|
|
||||||
|
|
@ -438,7 +438,7 @@ const Vote = () => {
|
||||||
isCursorInsideBoundingBox(mousePosition, box)
|
isCursorInsideBoundingBox(mousePosition, box)
|
||||||
) {
|
) {
|
||||||
insideVotingBox = true
|
insideVotingBox = true
|
||||||
if (activeDroppableId != box.id) {
|
if (activeDroppableId !== box.id) {
|
||||||
setActiveDroppable(true)
|
setActiveDroppable(true)
|
||||||
setActiveDroppableId(box.id)
|
setActiveDroppableId(box.id)
|
||||||
}
|
}
|
||||||
|
|
@ -461,7 +461,7 @@ const Vote = () => {
|
||||||
|
|
||||||
console.log(destination)
|
console.log(destination)
|
||||||
|
|
||||||
if (destination.droppableId == 'projects') {
|
if (destination.droppableId === 'projects') {
|
||||||
console.log('projects')
|
console.log('projects')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -607,7 +607,7 @@ const Vote = () => {
|
||||||
|
|
||||||
/* VOTE SUBMISSION BELOW */
|
/* VOTE SUBMISSION BELOW */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(votes).length == 5) {
|
if (Object.keys(votes).length === 5) {
|
||||||
setIsButtonActive(true)
|
setIsButtonActive(true)
|
||||||
} else {
|
} else {
|
||||||
setIsButtonActive(false)
|
setIsButtonActive(false)
|
||||||
|
|
@ -724,7 +724,7 @@ const Vote = () => {
|
||||||
//skips first render
|
//skips first render
|
||||||
submitVote(overall, technical, creative)
|
submitVote(overall, technical, creative)
|
||||||
}
|
}
|
||||||
}, [endPage])
|
}, [endPage, creative, overall, technical])
|
||||||
|
|
||||||
//MOBILE w/ ChatGPT help
|
//MOBILE w/ ChatGPT help
|
||||||
const [selectedProjects, setSelectedProjects] = useState(Array(5).fill(''))
|
const [selectedProjects, setSelectedProjects] = useState(Array(5).fill(''))
|
||||||
|
|
@ -763,8 +763,8 @@ const Vote = () => {
|
||||||
setSelectedProjects(Array(5).fill(''))
|
setSelectedProjects(Array(5).fill(''))
|
||||||
}
|
}
|
||||||
|
|
||||||
return startVote == true ? (
|
return startVote === true ? (
|
||||||
endPage == true ? (
|
endPage === true ? (
|
||||||
<div
|
<div
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
@ -781,6 +781,7 @@ const Vote = () => {
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
||||||
|
alt="Arcade logo"
|
||||||
sx={{
|
sx={{
|
||||||
width: '30%',
|
width: '30%',
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
|
|
@ -794,9 +795,9 @@ const Vote = () => {
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
sx={{ textAlign: 'center', maxWidth: '800px' }}
|
sx={{ textAlign: 'center', maxWidth: '800px' }}
|
||||||
>
|
>
|
||||||
{submitStatus == 'loading'
|
{submitStatus === 'loading'
|
||||||
? 'Loading...'
|
? 'Loading...'
|
||||||
: submitStatus == 'success'
|
: submitStatus === 'success'
|
||||||
? 'Thanks for voting!'
|
? 'Thanks for voting!'
|
||||||
: 'Ran into an error sending your votes'}
|
: 'Ran into an error sending your votes'}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
@ -806,7 +807,7 @@ const Vote = () => {
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
sx={{ textAlign: 'center', maxWidth: '800px', mt: 0 }}
|
sx={{ textAlign: 'center', maxWidth: '800px', mt: 0 }}
|
||||||
>
|
>
|
||||||
{submitStatus == 'loading' ? 'It takes a while' : ''}
|
{submitStatus === 'loading' ? 'It takes a while' : ''}
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
as="a"
|
as="a"
|
||||||
|
|
@ -1018,7 +1019,7 @@ const Vote = () => {
|
||||||
transition: 'transform 0.2s ease',
|
transition: 'transform 0.2s ease',
|
||||||
transform:
|
transform:
|
||||||
activeDroppableId === voteId
|
activeDroppableId === voteId
|
||||||
? activeDroppable == true
|
? activeDroppable === true
|
||||||
? 'scale(1.05)'
|
? 'scale(1.05)'
|
||||||
: 'scale(1)'
|
: 'scale(1)'
|
||||||
: 'scale(1)'
|
: 'scale(1)'
|
||||||
|
|
@ -1153,11 +1154,11 @@ const Vote = () => {
|
||||||
}}
|
}}
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{status == 'loading' && <Loading />}
|
{status === 'loading' && <Loading />}
|
||||||
|
|
||||||
{status == 'error' && <ErrorMessage />}
|
{status === 'error' && <ErrorMessage />}
|
||||||
|
|
||||||
{status == 'success' && (
|
{status === 'success' && (
|
||||||
<ProjectView
|
<ProjectView
|
||||||
preview="preview"
|
preview="preview"
|
||||||
key={openProject.id}
|
key={openProject.id}
|
||||||
|
|
@ -1198,7 +1199,7 @@ const Vote = () => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) : startViewProject == true ? (
|
) : startViewProject === true ? (
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
|
|
@ -1300,6 +1301,7 @@ const Vote = () => {
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
|
||||||
|
alt="Arcade logo"
|
||||||
sx={{
|
sx={{
|
||||||
width: '30%',
|
width: '30%',
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
|
|
@ -1312,8 +1314,8 @@ const Vote = () => {
|
||||||
sx={{ width: '90vw', margin: 'auto', maxWidth: '800px' }}
|
sx={{ width: '90vw', margin: 'auto', maxWidth: '800px' }}
|
||||||
className="gaegu"
|
className="gaegu"
|
||||||
>
|
>
|
||||||
{loadStatus == 'success' ? (
|
{loadStatus === 'success' ? (
|
||||||
voted == true ? (
|
voted === true ? (
|
||||||
<div
|
<div
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
@ -1397,7 +1399,7 @@ const Vote = () => {
|
||||||
{loadStatus}
|
{loadStatus}
|
||||||
</Text>
|
</Text>
|
||||||
<Text variant="caption" as="h4">
|
<Text variant="caption" as="h4">
|
||||||
{loadStatus == 'loading'
|
{loadStatus === 'loading'
|
||||||
? "Please give it some time. If it's taken too long, ask for help in #arcade-help"
|
? "Please give it some time. If it's taken too long, ask for help in #arcade-help"
|
||||||
: 'Try logging in again with /showcase in Slack. If it persists, please ask for help in #arcade-help.'}
|
: 'Try logging in again with /showcase in Slack. If it persists, please ask for help in #arcade-help.'}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,15 @@ function Gallery({ posts = [], tags = [] }) {
|
||||||
const [filterPosts, setFilterPosts] = useState([]);
|
const [filterPosts, setFilterPosts] = useState([]);
|
||||||
const [filterParts, setFilterParts] = useState([]);
|
const [filterParts, setFilterParts] = useState([]);
|
||||||
|
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAllPosts(posts);
|
setAllPosts(posts);
|
||||||
setFilterParts([]);
|
setFilterParts([]);
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
/* eslint-enable react-hooks/exhaustive-deps */
|
||||||
|
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFilterPosts(
|
setFilterPosts(
|
||||||
allPosts.filter(post =>
|
allPosts.filter(post =>
|
||||||
|
|
@ -50,6 +53,7 @@ function Gallery({ posts = [], tags = [] }) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}, [filterParts]);
|
}, [filterParts]);
|
||||||
|
/* eslint-enable react-hooks/exhaustive-deps */
|
||||||
|
|
||||||
|
|
||||||
const addFilter = (partID) => {
|
const addFilter = (partID) => {
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,14 @@ import { TypeAnimation } from 'react-type-animation'
|
||||||
const RsvpCount = () => {
|
const RsvpCount = () => {
|
||||||
const targetRSVPs = 500
|
const targetRSVPs = 500
|
||||||
const [rsvpCount, setRsvpCount] = useState(0)
|
const [rsvpCount, setRsvpCount] = useState(0)
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
// const url = 'https://api2.hackclub.com/v0.1/The Bin/rsvp' <- switch to this once we have api2 back up and running
|
const fetchRsvpCount = async () => {
|
||||||
const url = '/api/bin/rsvp'
|
// const url = 'https://api2.hackclub.com/v0.1/The Bin/rsvp' <- switch to this once we have api2 back up and running
|
||||||
const results = await fetch(url).then(r => r.json())
|
const url = '/api/bin/rsvp'
|
||||||
setRsvpCount(results)
|
const results = await fetch(url).then(r => r.json())
|
||||||
|
setRsvpCount(results)
|
||||||
|
}
|
||||||
|
fetchRsvpCount()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
if (rsvpCount < targetRSVPs) {
|
if (rsvpCount < targetRSVPs) {
|
||||||
|
|
@ -91,10 +94,13 @@ const PartPicker = () => {
|
||||||
const OnboardCount = () => {
|
const OnboardCount = () => {
|
||||||
const [onboardCount, setOnboardCount] = useState(200)
|
const [onboardCount, setOnboardCount] = useState(200)
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(() => {
|
||||||
const url = '/api/onboard/p/count'
|
const fetchOnboardCount = async () => {
|
||||||
const results = await fetch(url).then(r => r.json())
|
const url = '/api/onboard/p/count'
|
||||||
setOnboardCount(results.count)
|
const results = await fetch(url).then(r => r.json())
|
||||||
|
setOnboardCount(results.count)
|
||||||
|
}
|
||||||
|
fetchOnboardCount()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return <Text>{onboardCount}</Text>
|
return <Text>{onboardCount}</Text>
|
||||||
|
|
@ -106,7 +112,7 @@ const Electronic = ({ imageUrl, name, description }) => {
|
||||||
<Flex
|
<Flex
|
||||||
sx={{ mx: 'auto', flexDirection: 'column', display: 'inline-flex' }}
|
sx={{ mx: 'auto', flexDirection: 'column', display: 'inline-flex' }}
|
||||||
>
|
>
|
||||||
<Image src={imageUrl} width="100" />
|
<Image src={imageUrl} width="100" alt={name} />
|
||||||
<Heading as="span" variant="headline">
|
<Heading as="span" variant="headline">
|
||||||
{name}
|
{name}
|
||||||
</Heading>
|
</Heading>
|
||||||
|
|
@ -207,6 +213,7 @@ export default function Bin() {
|
||||||
}}>
|
}}>
|
||||||
<Image
|
<Image
|
||||||
src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/0rummaging.png"
|
src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/0rummaging.png"
|
||||||
|
alt="Rummaging through The Bin"
|
||||||
onClick={(e) => { fireConfetti(); crunch(); spinIt(e.target) }}
|
onClick={(e) => { fireConfetti(); crunch(); spinIt(e.target) }}
|
||||||
sx={{
|
sx={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
|
@ -223,7 +230,7 @@ export default function Bin() {
|
||||||
<RsvpCount />
|
<RsvpCount />
|
||||||
<Box id="rsvp">
|
<Box id="rsvp">
|
||||||
<Sparkles size="100px">
|
<Sparkles size="100px">
|
||||||
<Image src="https://cloud-rdlz8he4l-hack-club-bot.vercel.app/0thebin.svg" sx={{ maxWidth: '250px' }} />
|
<Image src="https://cloud-rdlz8he4l-hack-club-bot.vercel.app/0thebin.svg" alt="The Bin logo" sx={{ maxWidth: '250px' }} />
|
||||||
</Sparkles>
|
</Sparkles>
|
||||||
</Box>
|
</Box>
|
||||||
<Text sx={{ fontWeight: 'bold' }}>
|
<Text sx={{ fontWeight: 'bold' }}>
|
||||||
|
|
@ -309,7 +316,7 @@ export default function Bin() {
|
||||||
<Box sx={{ textAlign: 'left' }}>
|
<Box sx={{ textAlign: 'left' }}>
|
||||||
<Flex sx={{ my: 4 }}>
|
<Flex sx={{ my: 4 }}>
|
||||||
<Box>
|
<Box>
|
||||||
<Image src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/0rummaging.png" />
|
<Image src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/0rummaging.png" alt="Rummage" />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Heading as="p" variant="headline">
|
<Heading as="p" variant="headline">
|
||||||
|
|
@ -321,10 +328,10 @@ export default function Bin() {
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Image src="https://cloud-2wkwrydc4-hack-club-bot.vercel.app/0parts.svg" sx={{ width: '100%' }} />
|
<Image src="https://cloud-2wkwrydc4-hack-club-bot.vercel.app/0parts.svg" alt="Example parts" sx={{ width: '100%' }} />
|
||||||
<Flex sx={{ my: 4 }}>
|
<Flex sx={{ my: 4 }}>
|
||||||
<Box>
|
<Box>
|
||||||
<Image src="https://cloud-h7vwjlwe3-hack-club-bot.vercel.app/0frame_1__50_.png" />
|
<Image src="https://cloud-h7vwjlwe3-hack-club-bot.vercel.app/0frame_1__50_.png" alt="Think" />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text as="p" variant="headline">
|
<Text as="p" variant="headline">
|
||||||
|
|
@ -347,7 +354,7 @@ export default function Bin() {
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Image src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/1prototype.png" />
|
<Image src="https://cloud-mt5wqf6f5-hack-club-bot.vercel.app/1prototype.png" alt="Prototype" />
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
|
|
@ -388,6 +395,7 @@ export default function Bin() {
|
||||||
</Flex>
|
</Flex>
|
||||||
<Image
|
<Image
|
||||||
src="https://cloud-ge8yutn2q-hack-club-bot.vercel.app/0image.png"
|
src="https://cloud-ge8yutn2q-hack-club-bot.vercel.app/0image.png"
|
||||||
|
alt="Build it"
|
||||||
width="100%"
|
width="100%"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ export const categories = [
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
description:
|
description:
|
||||||
'Everywhere from San Jose to Boston to New York, HCB powers teams of all sizes.',
|
'Everywhere from San Jose to Boston to New York, HCB powers teams of all sizes.',
|
||||||
match: org => org.category == 'robotics_team',
|
match: org => org.category === 'robotics_team',
|
||||||
icon: 'sam'
|
icon: 'sam'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -107,7 +107,7 @@ export const categories = [
|
||||||
id: 'hackathons',
|
id: 'hackathons',
|
||||||
color: 'purple',
|
color: 'purple',
|
||||||
description: `Hackers are using HCB to run hackathons that'll blow your mind away.`,
|
description: `Hackers are using HCB to run hackathons that'll blow your mind away.`,
|
||||||
match: org => org.category == 'hackathon',
|
match: org => org.category === 'hackathon',
|
||||||
icon: 'event-code'
|
icon: 'event-code'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -204,10 +204,10 @@ const FilterPanel = ({ filter, mobile, clearOffset }) => {
|
||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
fontSize: 3,
|
fontSize: 3,
|
||||||
color:
|
color:
|
||||||
category == availableCategory.id ||
|
category === availableCategory.id ||
|
||||||
(availableCategory.index &&
|
(availableCategory.index &&
|
||||||
category == null &&
|
category === null &&
|
||||||
region == null)
|
region === null)
|
||||||
? 'primary'
|
? 'primary'
|
||||||
: 'null',
|
: 'null',
|
||||||
':hover': {
|
':hover': {
|
||||||
|
|
@ -311,7 +311,7 @@ const FilterPanel = ({ filter, mobile, clearOffset }) => {
|
||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
fontSize: 3,
|
fontSize: 3,
|
||||||
color:
|
color:
|
||||||
region == kebabCase(availableRegion.label)
|
region === kebabCase(availableRegion.label)
|
||||||
? 'primary'
|
? 'primary'
|
||||||
: 'null',
|
: 'null',
|
||||||
':hover': {
|
':hover': {
|
||||||
|
|
@ -599,7 +599,7 @@ export default function Directory({ rawOrganizations, pageRegion, category }) {
|
||||||
sx={{
|
sx={{
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
mb: 4,
|
mb: 4,
|
||||||
display: searchValue == '' ? 'flex' : 'none',
|
display: searchValue === '' ? 'flex' : 'none',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
gap: '16px'
|
gap: '16px'
|
||||||
|
|
@ -809,7 +809,7 @@ export async function fetchRawOrganizations() {
|
||||||
page++
|
page++
|
||||||
total = [...total, ...json]
|
total = [...total, ...json]
|
||||||
}
|
}
|
||||||
return [...total.filter((a) => a.logo != null), ...total.filter((a) => a.logo == null)]
|
return [...total.filter((a) => a.logo !== null), ...total.filter((a) => a.logo === null)]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getStaticProps = async () => {
|
export const getStaticProps = async () => {
|
||||||
|
|
|
||||||
440
pages/team.tsx
440
pages/team.tsx
|
|
@ -4,8 +4,10 @@ import Head from 'next/head'
|
||||||
import Nav from '../components/nav'
|
import Nav from '../components/nav'
|
||||||
import Footer from '../components/footer'
|
import Footer from '../components/footer'
|
||||||
import Bio from '../components/bio'
|
import Bio from '../components/bio'
|
||||||
|
import BoardBox from '../components/boardbio'
|
||||||
import ForceTheme from '../components/force-theme'
|
import ForceTheme from '../components/force-theme'
|
||||||
import { fetchTeam } from './api/team'
|
import { fetchTeam } from './api/team'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
const CommunityTeamBox = ({ title, children }) => {
|
const CommunityTeamBox = ({ title, children }) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -22,7 +24,7 @@ const CommunityTeamBox = ({ title, children }) => {
|
||||||
<Text
|
<Text
|
||||||
variant="headline"
|
variant="headline"
|
||||||
as="h4"
|
as="h4"
|
||||||
sx={{ textAlign: 'center', fontSize: 3 }}
|
sx={{ textAlign: 'center', fontSize: 4 }}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
@ -40,6 +42,9 @@ const CommunityTeamBox = ({ title, children }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Team({ team }) {
|
export default function Team({ team }) {
|
||||||
|
// Spacing between major team section boxes
|
||||||
|
const BOX_SPACING = 5
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box as="main" key="main">
|
<Box as="main" key="main">
|
||||||
|
|
@ -82,156 +87,64 @@ export default function Team({ team }) {
|
||||||
</Box>
|
</Box>
|
||||||
<Box bg="#f9f9fa" py={4}>
|
<Box bg="#f9f9fa" py={4}>
|
||||||
<Container>
|
<Container>
|
||||||
<Flex
|
<Box sx={{
|
||||||
sx={{
|
mb: BOX_SPACING
|
||||||
bg: 'rgb(51 142 218 / 40%)',
|
}}>
|
||||||
p: 3,
|
<Text
|
||||||
borderRadius: '20px',
|
|
||||||
mb: 3,
|
|
||||||
gap: 3,
|
|
||||||
flexWrap: ['wrap', null, null, 'nowrap']
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
variant="headline"
|
variant="headline"
|
||||||
|
mt={2}
|
||||||
|
mb={3}
|
||||||
as="h3"
|
as="h3"
|
||||||
sx={{
|
sx={{ textAlign: 'center', fontSize: 5 }}
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 3,
|
|
||||||
writingMode: [null, null, null, 'vertical-rl'],
|
|
||||||
mr: [0, 0, 0, 1],
|
|
||||||
transform: [null, null, null, 'rotate(180deg)'],
|
|
||||||
width: ['100%', null, null, 'fit-content'],
|
|
||||||
my: ['0px!important', '0px!important', '0px!important', 3]
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Board & Advisors
|
Board & Advisors
|
||||||
</Text>
|
</Text>
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
<Grid columns={[1, null, 2]} gap={5} mb={4}>
|
||||||
<Grid columns={[1, null, 2]} gap={2} mb={2}>
|
<BoardBox
|
||||||
<Bio
|
img="/team/zach.jpg"
|
||||||
img="/team/zach.jpg"
|
name="Zach Latta"
|
||||||
name="Zach Latta"
|
teamRole="Founder"
|
||||||
teamRole="Founder"
|
text="Zach dropped out of high school after his freshman year to work in the technology industry and had over 5 million people using his software by the time he turned 17. He founded Hack Club to build the program he wish he had in high school and has been awarded the Thiel Fellowship and Forbes 30 Under 30 for his work."
|
||||||
text="Zach dropped out of high school after his freshman year to work in the technology industry and had over 5 million people using his software by the time he turned 17. He founded Hack Club to build the program he wish he had in high school and has been awarded the Thiel Fellowship and Forbes 30 Under 30 for his work."
|
email="zach"
|
||||||
pronouns="he/him"
|
/>
|
||||||
email="zach"
|
<BoardBox
|
||||||
/>
|
img="/team/christina.jpg"
|
||||||
<Bio
|
name="Christina Asquith"
|
||||||
img="/team/christina.jpg"
|
teamRole="Co-Founder and COO"
|
||||||
name="Christina Asquith"
|
text="With more than a decade of experience in starting and leading organizations, Christina has built global teams and raised millions of dollars. She has 20 years experience as a journalist, including reporting for The New York Times from Iraq. She has an MA in education, and taught as a public school teacher in 2000, which inspired her book “The Emergency Teacher.”"
|
||||||
teamRole="Co-founder and COO"
|
email="christina"
|
||||||
text="With more than a decade of experience in starting and leading organizations, Christina has built global teams and raised millions of dollars. She has 20 years experience as a journalist, including reporting for The New York Times from Iraq. She has an MA in education, and taught as a public school teacher in 2000, which inspired her book “The Emergency Teacher.”"
|
/>
|
||||||
pronouns="she/her"
|
|
||||||
email="christina"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid columns={[1, null, 3]} gap={2}>
|
|
||||||
<Bio
|
|
||||||
img="https://cloud-80nhjzldl-hack-club-bot.vercel.app/0.jpeg"
|
|
||||||
name="Tom Preston-Werner"
|
|
||||||
teamRole={<>Board Member</>}
|
|
||||||
subrole="Co-Founder, GitHub"
|
|
||||||
pronouns="he/him"
|
|
||||||
href="https://github.com/mojombo"
|
|
||||||
/>
|
|
||||||
<Bio
|
|
||||||
img="https://philanthropy.hackclub.com/_next/image?url=/quinn.png&w=1200&q=75"
|
|
||||||
name="Quinn Slack"
|
|
||||||
teamRole={<>Board Member</>}
|
|
||||||
subrole="CEO, Sourcegraph"
|
|
||||||
pronouns="he/him"
|
|
||||||
href="https://github.com/sqs"
|
|
||||||
/>
|
|
||||||
<Bio
|
|
||||||
img="https://media.licdn.com/dms/image/C5603AQFum8zxW-IEEA/profile-displayphoto-shrink_800_800/0/1517058384850?e=2147483647&v=beta&t=-oM8no3Zc7xUzCDBsHxajD_joBkQi8Ge5iPaeF5p0gM"
|
|
||||||
name="John Abele"
|
|
||||||
teamRole={<>Board Advisor</>}
|
|
||||||
href="https://en.wikipedia.org/wiki/John_Abele"
|
|
||||||
subrole="Founder, Boston Scientific"
|
|
||||||
pronouns="he/him"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
|
||||||
<Grid columns={[1, null, 2]} gap={3}>
|
|
||||||
<Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
bg: 'rgb(51 214 166 / 40%)',
|
|
||||||
p: 3,
|
|
||||||
borderRadius: '20px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
variant="headline"
|
|
||||||
mt={2}
|
|
||||||
mb={3}
|
|
||||||
as="h3"
|
|
||||||
sx={{ textAlign: 'center', fontSize: 4 }}
|
|
||||||
>
|
|
||||||
Hacker Resources Team
|
|
||||||
</Text>
|
|
||||||
<Grid columns={[1, null, 2]} gap={2}>
|
|
||||||
{team.current
|
|
||||||
?.filter(member => member.department === 'HQ')
|
|
||||||
.map(member => (
|
|
||||||
<Bio
|
|
||||||
img={member.avatar}
|
|
||||||
name={member.name}
|
|
||||||
teamRole={member.role}
|
|
||||||
text={member.bio}
|
|
||||||
pronouns={member.pronouns}
|
|
||||||
email={member.email}
|
|
||||||
href={member.website}
|
|
||||||
key={member.name}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
bg: 'rgb(236 55 80 / 40%)',
|
|
||||||
p: 3,
|
|
||||||
borderRadius: '20px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
variant="headline"
|
|
||||||
mt={2}
|
|
||||||
mb={3}
|
|
||||||
as="h3"
|
|
||||||
sx={{ textAlign: 'center', fontSize: 4 }}
|
|
||||||
>
|
|
||||||
HCB Team
|
|
||||||
</Text>
|
|
||||||
<Grid columns={[1, null, 2]} gap={2}>
|
|
||||||
{team.current
|
|
||||||
?.filter(member => member.department === 'HCB')
|
|
||||||
.map(member => (
|
|
||||||
<Bio
|
|
||||||
img={member.avatar}
|
|
||||||
name={member.name}
|
|
||||||
teamRole={member.role}
|
|
||||||
text={member.bio}
|
|
||||||
pronouns={member.pronouns}
|
|
||||||
email={member.email}
|
|
||||||
href={member.website}
|
|
||||||
key={member.name}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid columns={[1, null, 3]} gap={4} mb={4}>
|
||||||
|
<BoardBox
|
||||||
|
img="https://i.ibb.co/gMVMqJzt/2026-01-27-0io-Kleki.jpg"
|
||||||
|
name="Tom Preston-Werner"
|
||||||
|
teamRole={<>Board Member</>}
|
||||||
|
subrole="Co-Founder, GitHub"
|
||||||
|
href="https://github.com/mojombo"
|
||||||
|
/>
|
||||||
|
<BoardBox
|
||||||
|
img="https://i.ibb.co/qMCYrJn8/sqs.jpg"
|
||||||
|
name="Quinn Slack"
|
||||||
|
teamRole={<>Board Member</>}
|
||||||
|
subrole="Co-Founder and CEO, AMP"
|
||||||
|
href="https://github.com/sqs"
|
||||||
|
/>
|
||||||
|
<BoardBox
|
||||||
|
img="https://i.ibb.co/0pGTSmks/2026-01-27-0il-Kleki.png"
|
||||||
|
name="John Abele"
|
||||||
|
teamRole={<>Board Advisor</>}
|
||||||
|
href="https://en.wikipedia.org/wiki/John_Abele"
|
||||||
|
subrole="Founder, Boston Scientific"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
bg: 'rgb(166 51 214 / 40%)',
|
bg: '#afcfee',
|
||||||
p: 3,
|
p: 3,
|
||||||
borderRadius: '20px',
|
borderRadius: '20px',
|
||||||
mt: 3
|
mb: BOX_SPACING
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
|
|
@ -239,13 +152,193 @@ export default function Team({ team }) {
|
||||||
mt={2}
|
mt={2}
|
||||||
mb={3}
|
mb={3}
|
||||||
as="h3"
|
as="h3"
|
||||||
sx={{ textAlign: 'center', fontSize: 4 }}
|
sx={{ textAlign: 'center', fontSize: 5 }}
|
||||||
|
>
|
||||||
|
Hacker Resources Team
|
||||||
|
</Text>
|
||||||
|
{team.current?.filter(member => member.department === 'HQ' && member.staff).length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={2}
|
||||||
|
mb={2}
|
||||||
|
as="h4"
|
||||||
|
sx={{ fontSize: 3 }}
|
||||||
|
>
|
||||||
|
Staff:
|
||||||
|
</Text>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.current
|
||||||
|
?.filter(member => member.department === 'HQ' && member.staff)
|
||||||
|
.map(member => (
|
||||||
|
<Bio
|
||||||
|
img={member.avatar}
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
email={member.email}
|
||||||
|
href={member.website}
|
||||||
|
key={member.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{team.current?.filter(member => member.department === 'HQ' && member.gapyear).length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={3}
|
||||||
|
mb={2}
|
||||||
|
as="h4"
|
||||||
|
sx={{ fontSize: 3 }}
|
||||||
|
>
|
||||||
|
2025-2026 Gap Years:
|
||||||
|
</Text>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.current
|
||||||
|
?.filter(member => member.department === 'HQ' && member.gapyear)
|
||||||
|
.map(member => (
|
||||||
|
<Bio
|
||||||
|
img={member.avatar}
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
email={member.email}
|
||||||
|
href={member.website}
|
||||||
|
key={member.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{team.current?.filter(member => member.department === 'HQ' && !member.gapyear && !member.staff).length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={3}
|
||||||
|
mb={2}
|
||||||
|
as="h4"
|
||||||
|
sx={{ fontSize: 3 }}
|
||||||
|
>
|
||||||
|
Teen Contractors:
|
||||||
|
</Text>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.current
|
||||||
|
?.filter(member => member.department === 'HQ' && !member.gapyear && !member.staff)
|
||||||
|
.map(member => (
|
||||||
|
<Bio
|
||||||
|
img={member.avatar}
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
email={member.email}
|
||||||
|
href={member.website}
|
||||||
|
key={member.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
bg: 'rgb(236 55 80 / 40%)',
|
||||||
|
p: 3,
|
||||||
|
borderRadius: '20px',
|
||||||
|
mb: BOX_SPACING
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={2}
|
||||||
|
mb={3}
|
||||||
|
as="h3"
|
||||||
|
sx={{ textAlign: 'center', fontSize: 5 }}
|
||||||
|
>
|
||||||
|
HCB Team
|
||||||
|
</Text>
|
||||||
|
{team.current?.filter(member => member.department === 'HCB' && member.staff).length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={2}
|
||||||
|
mb={2}
|
||||||
|
as="h4"
|
||||||
|
sx={{ fontSize: 3 }}
|
||||||
|
>
|
||||||
|
Staff:
|
||||||
|
</Text>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.current
|
||||||
|
?.filter(member => member.department === 'HCB' && member.staff)
|
||||||
|
.map(member => (
|
||||||
|
<Bio
|
||||||
|
img={member.avatar}
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
email={member.email}
|
||||||
|
href={member.website}
|
||||||
|
key={member.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{team.current?.filter(member => member.department === 'HCB' && !member.staff).length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={3}
|
||||||
|
mb={2}
|
||||||
|
as="h4"
|
||||||
|
sx={{ fontSize: 3 }}
|
||||||
|
>
|
||||||
|
Contributors:
|
||||||
|
</Text>
|
||||||
|
<Grid columns={[1, null, 2, 3]} gap={3}>
|
||||||
|
{team.current
|
||||||
|
?.filter(member => member.department === 'HCB' && !member.staff)
|
||||||
|
.map(member => (
|
||||||
|
<Bio
|
||||||
|
img={member.avatar}
|
||||||
|
name={member.name}
|
||||||
|
teamRole={member.role}
|
||||||
|
text={member.bio}
|
||||||
|
pronouns={member.pronouns}
|
||||||
|
email={member.email}
|
||||||
|
href={member.website}
|
||||||
|
key={member.name}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
bg: 'rgb(166 51 214 / 40%)',
|
||||||
|
p: 3,
|
||||||
|
borderRadius: '20px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
variant="headline"
|
||||||
|
mt={2}
|
||||||
|
mb={3}
|
||||||
|
as="h3"
|
||||||
|
sx={{ textAlign: 'center', fontSize: 5 }}
|
||||||
>
|
>
|
||||||
Community Team
|
Community Team
|
||||||
</Text>
|
</Text>
|
||||||
<Grid columns={[1, null, 2]} gap={3}>
|
<Grid columns={[1, null, 2]} gap={3}>
|
||||||
<CommunityTeamBox title="Moderation">
|
<CommunityTeamBox title="Moderation">
|
||||||
<Grid columns={[1, null, 2]} gap={2} m={10}>
|
<Grid columns={[1, null, 2]} gap={3} m={10}>
|
||||||
{team.current
|
{team.current
|
||||||
?.filter(member => member.department === 'Moderation')
|
?.filter(member => member.department === 'Moderation')
|
||||||
.map(member => (
|
.map(member => (
|
||||||
|
|
@ -263,7 +356,7 @@ export default function Team({ team }) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</CommunityTeamBox>
|
</CommunityTeamBox>
|
||||||
<CommunityTeamBox title="Welcomers">
|
<CommunityTeamBox title="Welcomers">
|
||||||
<Grid columns={[1, null, 2]} gap={2} m={10}>
|
<Grid columns={[1, null, 2]} gap={3} m={10}>
|
||||||
{team.current
|
{team.current
|
||||||
?.filter(member => member.department === 'Welcoming')
|
?.filter(member => member.department === 'Welcoming')
|
||||||
.map(member => (
|
.map(member => (
|
||||||
|
|
@ -281,7 +374,7 @@ export default function Team({ team }) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</CommunityTeamBox>
|
</CommunityTeamBox>
|
||||||
<CommunityTeamBox title="Virtual Events">
|
<CommunityTeamBox title="Virtual Events">
|
||||||
<Grid columns={[1, null, 2]} gap={2} m={10}>
|
<Grid columns={[1, null, 2]} gap={3} m={10}>
|
||||||
{team.current
|
{team.current
|
||||||
?.filter(member => member.department === 'Events')
|
?.filter(member => member.department === 'Events')
|
||||||
.map(member => (
|
.map(member => (
|
||||||
|
|
@ -299,7 +392,7 @@ export default function Team({ team }) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</CommunityTeamBox>
|
</CommunityTeamBox>
|
||||||
<CommunityTeamBox title="Newspaper">
|
<CommunityTeamBox title="Newspaper">
|
||||||
<Grid columns={[1, null, 2]} gap={2} m={10}>
|
<Grid columns={[1, null, 2]} gap={3} m={10}>
|
||||||
{team.current
|
{team.current
|
||||||
?.filter(member => member.department === 'Newspaper')
|
?.filter(member => member.department === 'Newspaper')
|
||||||
.map(member => (
|
.map(member => (
|
||||||
|
|
@ -319,46 +412,23 @@ export default function Team({ team }) {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
<br />
|
<br />
|
||||||
<Box sx={{ textAlign: 'center', mt: 100, mb: [3, 4] }}>
|
<Box sx={{ fontWeight: 'bold', textAlign: 'center' }}>
|
||||||
<Text
|
<Link href="/acknowledged/">
|
||||||
variant="title"
|
<Box sx={{ cursor: 'pointer' }}>
|
||||||
color="orange"
|
<Text
|
||||||
sx={{ lineHeight: '1em', fontSize: [4, 5, 6] }}
|
variant="title"
|
||||||
as="h2"
|
color="orange"
|
||||||
>
|
sx={{ lineHeight: '1em', fontSize: [4, 5, 6], textAlign: 'center', textDecoration: 'underline' }}
|
||||||
Acknowledgements
|
as="h2"
|
||||||
</Text>
|
>
|
||||||
<Text
|
Acknowledgements
|
||||||
variant="title"
|
</Text>
|
||||||
color="text"
|
<Text sx={{ color: 'muted', fontSize: 2, mt: 2 }}>
|
||||||
sx={{
|
Thank you to everyone who helped shape Hack Club into what it is today...
|
||||||
lineHeight: '1.2',
|
</Text>
|
||||||
fontSize: [1, 3, 4],
|
</Box>
|
||||||
my: [3, 0, 0],
|
</Link>
|
||||||
fontWeight: 400,
|
|
||||||
maxWidth: '600px',
|
|
||||||
width: '100%',
|
|
||||||
margin: 'auto'
|
|
||||||
}}
|
|
||||||
as="h2"
|
|
||||||
>
|
|
||||||
Thank you to everyone who helped shape Hack Club into what it is
|
|
||||||
today...
|
|
||||||
</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
<Grid columns={[1, null, 2, 4]} gap={2}>
|
|
||||||
{team.acknowledged?.map(member => (
|
|
||||||
<Bio
|
|
||||||
img={member.avatar}
|
|
||||||
name={member.name}
|
|
||||||
teamRole={member.role}
|
|
||||||
text={member.bio}
|
|
||||||
pronouns={member.pronouns}
|
|
||||||
key={member.name}
|
|
||||||
href={member.website}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Container>
|
</Container>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
3431
public/team.json
3431
public/team.json
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue