mirror of
https://github.com/System-End/site.git
synced 2026-04-19 22:05:11 +00:00
Add hackathon grant page! (#502)
* Add hackathon grant page! * oops * Update pages/hackathon-grant.js Co-authored-by: Ella <git@ella.cx> * Update pages/hackathon-grant.js Co-authored-by: Ella <git@ella.cx> * copy updates * Fix opacity thing * Add no-spam disclaimer * ® * Use an Assemble photo! * touch-up * apply * other touches * Update pages/hackathon-grant.js Co-authored-by: Caleb Denio <cjdenio44@gmail.com> * Update pages/hackathon-grant.js Co-authored-by: Caleb Denio <cjdenio44@gmail.com> * Update pages/hackathon-grant.js Co-authored-by: Caleb Denio <cjdenio44@gmail.com> * Add new grant apply heading * Mobile fixes for hackathon grant site * line-bug * Trigger preview deploy sorry folks! * money * bank mail * sparkle + add var * `Slack` * 18 * fillrule stuff * dollar * small bugs * meta * meta-2 * meta-3 * weekdays * change channel * grant * some new stuff * rename * responsive * pill * darkmode * Delete package-lock.json * oops * wahoo * Update pages/hackathons/grant.js Co-authored-by: Gary Tou <gary@garytou.com> * Update pages/hackathons/grant.js Co-authored-by: Gary Tou <gary@garytou.com> Co-authored-by: Ella <git@ella.cx> Co-authored-by: Belle <bellesee1212@gmail.com> Co-authored-by: Belle <65808924+bellesea@users.noreply.github.com> Co-authored-by: Max Wofford <max@maxwofford.com> Co-authored-by: Sam Poder <39828164+sampoder@users.noreply.github.com> Co-authored-by: Gary Tou <gary@garytou.com>
This commit is contained in:
parent
b10cbc1cc4
commit
3e73843821
14 changed files with 1511 additions and 300 deletions
|
|
@ -40,7 +40,8 @@ export default function Start() {
|
|||
</Heading>
|
||||
<Container variant="narrow" sx={{ color: 'muted' }}>
|
||||
<Text variant="lead">
|
||||
Open to all registered Hack Clubs, hackathons, and charitable organizations in the US and Canada.
|
||||
Open to all registered Hack Clubs, hackathons, and charitable
|
||||
organizations in the US and Canada.
|
||||
</Text>
|
||||
</Container>
|
||||
</Container>
|
||||
|
|
|
|||
227
components/hackathon-grant/apply.js
Normal file
227
components/hackathon-grant/apply.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
import { Box, Badge, Container, Flex, Grid, Heading } from 'theme-ui'
|
||||
import { Link, Text, Button, Card } from 'theme-ui'
|
||||
import Icon from '@hackclub/icons'
|
||||
import { Slide } from 'react-reveal'
|
||||
import MSparkles from './money'
|
||||
import Image from 'next/image'
|
||||
|
||||
function Timeline({ children }) {
|
||||
return (
|
||||
<Flex
|
||||
sx={{ flexDirection: ['column', null, 'row'], justifyContent: 'center' }}
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
function TimelineStep({ children }) {
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
marginX: [2, null, null],
|
||||
// paddingX: [null, null, 3, 4],
|
||||
paddingY: [4, null, 0],
|
||||
flexDirection: ['row', null, 'column'],
|
||||
alignItems: 'center',
|
||||
justifyContent: ['center', 'center', 'unset', 'unset'],
|
||||
// width: 'fit-content',
|
||||
'&:before': {
|
||||
content: '""',
|
||||
background: '#3c4858',
|
||||
height: [0, null, '4px'],
|
||||
width: [0, null, '60%'],
|
||||
maxWidth: '840px',
|
||||
marginLeft: [null, null, 0],
|
||||
marginTop: [null, null, '34px'],
|
||||
position: 'absolute',
|
||||
zIndex: -1
|
||||
},
|
||||
'&:first-of-type:before': {
|
||||
top: [0, null, 'auto'],
|
||||
width: [0, null, 0],
|
||||
left: [0, null, 0]
|
||||
},
|
||||
'&:last-of-type:before': {
|
||||
bottom: [0, null, 'auto'],
|
||||
left: [0, null, 0],
|
||||
width: [0, null, 0]
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
function Circle({ children }) {
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
padding: 12,
|
||||
backgroundColor: '#ec3750',
|
||||
color: 'white',
|
||||
borderRadius: '100%',
|
||||
display: 'inline-block',
|
||||
lineHeight: 0,
|
||||
position: 'relative',
|
||||
zIndex: 999
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
function Step({ icon, name, duration, href }) {
|
||||
return (
|
||||
<TimelineStep pb={4}>
|
||||
<Slide left>
|
||||
<Circle>
|
||||
{href ? (
|
||||
<Link href={href} sx={{ cursor: 'pointer' }}>
|
||||
<Icon glyph={icon} size={48} color="white" />
|
||||
</Link>
|
||||
) : (
|
||||
<Icon glyph={icon} size={48} />
|
||||
)}
|
||||
</Circle>
|
||||
<Container
|
||||
sx={{
|
||||
marginTop: 3,
|
||||
display: 'flex',
|
||||
justifyContent: ['left', 'left', null, 'center'],
|
||||
flexDirection: 'column',
|
||||
textAlign: ['left', null, 'center'],
|
||||
pr: [0, 16, 16]
|
||||
}}
|
||||
>
|
||||
<Badge
|
||||
variant="pill"
|
||||
sx={{
|
||||
bg: 'muted',
|
||||
color: 'darker',
|
||||
fontWeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
width: [52, null, 64],
|
||||
fontSize: [14, null, 18],
|
||||
px: 2,
|
||||
mx: [null, null, 'auto']
|
||||
}}
|
||||
>
|
||||
{duration}
|
||||
</Badge>
|
||||
<Text
|
||||
sx={{
|
||||
color: 'white',
|
||||
fontSize: [2, 3, 3],
|
||||
maxWidth: [300, null, 550]
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
</Container>
|
||||
</Slide>
|
||||
</TimelineStep>
|
||||
)
|
||||
}
|
||||
|
||||
const Apply = ({ channel }) => {
|
||||
return (
|
||||
<>
|
||||
<Box id="apply" sx={{pt: 6}}>
|
||||
<Heading sx={{ textAlign: 'center', mb: 3, fontSize: [5, null, 6, 7] }}>
|
||||
The <MSparkles>bucks</MSparkles> start here.
|
||||
</Heading>
|
||||
<Heading
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
mb: [3, null, 5],
|
||||
fontSize: [28, 30, 40],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
Get your hackathon funded.
|
||||
</Heading>
|
||||
<Timeline px={3}>
|
||||
<Step
|
||||
icon="slack"
|
||||
name={
|
||||
<>
|
||||
On{' '}
|
||||
<Link
|
||||
href="https://hackclub.com/slack"
|
||||
target="_blank"
|
||||
sx={{
|
||||
color: 'white'
|
||||
}}
|
||||
>
|
||||
Slack
|
||||
</Link>
|
||||
, send your website to{' '}
|
||||
<Link
|
||||
href="https://hackclub.slack.com/archives/C03TS9KSBGC"
|
||||
target="_blank"
|
||||
>
|
||||
#hackathon-grant
|
||||
</Link>{' '}
|
||||
</>
|
||||
}
|
||||
duration="Step 1"
|
||||
href="https://hackclub.com/slack"
|
||||
/>
|
||||
<Step
|
||||
icon="post"
|
||||
name="Fill in your application, we'll respond in 24 hours (on weekdays)"
|
||||
duration="Step 2"
|
||||
/>
|
||||
<Step
|
||||
icon="payment-transfer"
|
||||
name="Ka-ching! If approved, start spending your $500"
|
||||
duration="Step 3"
|
||||
/>
|
||||
</Timeline>
|
||||
<br />
|
||||
<br />
|
||||
<Slide left>
|
||||
<Link
|
||||
href="/slack/?reason=Application%20for%20the%20high%20school%20hackathon%20grant"
|
||||
target="_blank"
|
||||
sx={{ textDecoration: 'none' }}
|
||||
>
|
||||
<Button
|
||||
as="a"
|
||||
variant="primary"
|
||||
sx={{
|
||||
fontSize: [2, null, 3],
|
||||
display: 'block',
|
||||
mx: 'auto',
|
||||
width: 'fit-content'
|
||||
}}
|
||||
>
|
||||
Join Slack
|
||||
</Button>
|
||||
</Link>
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
textAlign: 'center',
|
||||
color: 'muted',
|
||||
my: 3,
|
||||
width: '60%',
|
||||
mx: 'auto'
|
||||
}}
|
||||
>
|
||||
Already have an account? Join the{' '}
|
||||
<Link href={channel} target="_blank">
|
||||
#hackathon-grant
|
||||
</Link>{' '}
|
||||
channel!
|
||||
</Box>
|
||||
</Slide>
|
||||
</Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Apply
|
||||
314
components/hackathon-grant/apply2.js
Normal file
314
components/hackathon-grant/apply2.js
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
import { Box, Badge, Container, Flex, Grid, Heading } from 'theme-ui'
|
||||
import { Link, Text, Button, Card } from 'theme-ui'
|
||||
import Icon from '@hackclub/icons'
|
||||
import { Slide } from 'react-reveal'
|
||||
import Zoom from 'react-reveal/Zoom'
|
||||
import MSparkles from './money'
|
||||
// import Stage from '../stage'
|
||||
import Image from 'next/image'
|
||||
/** @jsxImportSource theme-ui */
|
||||
|
||||
function TimelineStep({ children }) {
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
marginX: [2, null, null],
|
||||
// paddingX: [null, null, 3, 4],
|
||||
paddingY: [4, null, 0],
|
||||
flexDirection: ['row', null, 'column'],
|
||||
alignItems: 'center',
|
||||
justifyContent: ['center', 'center', 'unset', 'unset'],
|
||||
// width: 'fit-content',
|
||||
'&:before': {
|
||||
content: '""',
|
||||
background: '#3c4858',
|
||||
height: [0, null, '4px'],
|
||||
width: [0, null, '60%'],
|
||||
maxWidth: '840px',
|
||||
marginLeft: [null, null, 0],
|
||||
marginTop: [null, null, '34px'],
|
||||
position: 'absolute',
|
||||
zIndex: -1
|
||||
},
|
||||
'&:first-of-type:before': {
|
||||
top: [0, null, 'auto'],
|
||||
width: [0, null, 0],
|
||||
left: [0, null, 0]
|
||||
},
|
||||
'&:last-of-type:before': {
|
||||
bottom: [0, null, 'auto'],
|
||||
left: [0, null, 0],
|
||||
width: [0, null, 0]
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
const Photo = ({
|
||||
icon,
|
||||
color,
|
||||
name,
|
||||
desc,
|
||||
duration,
|
||||
children,
|
||||
src,
|
||||
width,
|
||||
height,
|
||||
alt,
|
||||
showAlt,
|
||||
dark,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<Card
|
||||
{...props}
|
||||
as="figure"
|
||||
variant="interactive"
|
||||
sx={{
|
||||
p: [0, 0, 0],
|
||||
boxShadow: 'elevated',
|
||||
borderRadius: 'extra',
|
||||
position: 'relative',
|
||||
maxWidth: '100%',
|
||||
lineHeight: 0,
|
||||
height: 'fit-content',
|
||||
...props.sx,
|
||||
img: { objectFit: 'cover', objectPosition: 'center' }
|
||||
}}
|
||||
> <Box sx={{ position: 'relative' }}>
|
||||
<Image
|
||||
src={src}
|
||||
alt={alt}
|
||||
width="100%"
|
||||
height="60%"
|
||||
layout="responsive"
|
||||
/>
|
||||
<Box
|
||||
as="span"
|
||||
sx={{
|
||||
width: 'fit-content',
|
||||
bg: color,
|
||||
borderRadius: 20,
|
||||
lineHeight: 0,
|
||||
p: '14px',
|
||||
px: 0,
|
||||
mb: 1,
|
||||
display: 'inline-block',
|
||||
transform: ['scale(0.75)', 'none'],
|
||||
transformOrigin: 'bottom left',
|
||||
boxShadow:
|
||||
'inset 2px 2px 6px rgba(255,255,255,0.2), inset -2px -2px 6px rgba(0,0,0,0.1), 0 1px 4px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.1)',
|
||||
position: 'absolute',
|
||||
bottom: '20px',
|
||||
left: '20px',
|
||||
fontSize: '20px'
|
||||
}}
|
||||
>
|
||||
<Badge variant="pill">{duration}</Badge>
|
||||
{/* <Icon glyph={icon} size={36} /> */}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{ mt: '20px' }}>
|
||||
{/* <Text
|
||||
sx={{
|
||||
color: 'muted',
|
||||
fontWeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
fontSize: [18, null, 22],
|
||||
p: 3,
|
||||
mx: [null, null, 'auto'],
|
||||
boxShadow: 'none !important'
|
||||
}}
|
||||
>
|
||||
{duration}
|
||||
</Text> */}
|
||||
<Heading variant="subtitle" mb={2} p={3} pt={0}>
|
||||
{name}
|
||||
</Heading>
|
||||
</Box>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
const Stage = ({ icon, color, name, desc, ...props }) => (
|
||||
<Box>
|
||||
<Box
|
||||
as="span"
|
||||
sx={{
|
||||
width: 'fit-content',
|
||||
bg: color,
|
||||
borderRadius: 18,
|
||||
lineHeight: 0,
|
||||
p: 2,
|
||||
mb: 1,
|
||||
display: 'inline-block',
|
||||
transform: ['scale(0.75)', 'none'],
|
||||
transformOrigin: 'bottom left',
|
||||
boxShadow:
|
||||
'inset 2px 2px 6px rgba(255,255,255,0.2), inset -2px -2px 6px rgba(0,0,0,0.1), 0 1px 4px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.1)'
|
||||
}}
|
||||
>
|
||||
<Icon glyph={icon} size={48} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Image src="/hackathon-grant/first.png" width="200" height="200" />
|
||||
<Heading as="h3" variant="headline" mb={2}>
|
||||
{name}
|
||||
</Heading>
|
||||
<Text
|
||||
as="p"
|
||||
variant="subtitle"
|
||||
sx={{ mt: 0, pb: 2, a: { variant: 'styles.a', color: 'blue' } }}
|
||||
>
|
||||
{desc}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
|
||||
const Apply = ({ channel }) => {
|
||||
return (
|
||||
<>
|
||||
<Box id="apply" sx={{ pt: 6 }}>
|
||||
<Zoom>
|
||||
<Heading sx={{ textAlign: 'center', mb: 3, fontSize: [5, null, 6, 7] }}>
|
||||
The <MSparkles>bucks</MSparkles> start here.
|
||||
</Heading>
|
||||
</Zoom>
|
||||
<Zoom>
|
||||
<Heading
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
mb: [2, null, 4],
|
||||
fontSize: [28, 30, 40],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
Get your hackathon funded.
|
||||
</Heading>
|
||||
</Zoom>
|
||||
</Box>
|
||||
<Grid
|
||||
pt={[3, 4]}
|
||||
pb={[4, 5]}
|
||||
gap={[4, 3, 4]}
|
||||
columns={[1, 1, 3]}
|
||||
sx={{
|
||||
textAlign: 'left',
|
||||
'> a, > div': {
|
||||
borderRadius: 'extra',
|
||||
boxShadow: 'elevated',
|
||||
},
|
||||
span: {
|
||||
boxShadow:
|
||||
'-2px -2px 6px rgba(255,255,255,0.125), inset 2px 2px 6px rgba(0,0,0,0.1), 2px 2px 8px rgba(0,0,0,0.0625)'
|
||||
},
|
||||
svg: { fill: 'currentColor' }
|
||||
}}
|
||||
>
|
||||
<Slide left delay={20}>
|
||||
<Photo
|
||||
src="/hackathon-grant/step1.gif"
|
||||
alt="Summer Creek Hack Club meeting, February 2020"
|
||||
width={3000}
|
||||
height={2550}
|
||||
showAlt
|
||||
color="#ec3750"
|
||||
icon="slack"
|
||||
duration="Step 1"
|
||||
name={
|
||||
<>
|
||||
On{' '}
|
||||
<Link
|
||||
href="https://hackclub.com/slack"
|
||||
target="_blank"
|
||||
sx={{
|
||||
color: 'white'
|
||||
}}
|
||||
>
|
||||
Slack
|
||||
</Link>
|
||||
, send your website to{' '}
|
||||
<Link href={channel} target="_blank">
|
||||
#hackathon-grants
|
||||
</Link>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Slide>
|
||||
<Slide left delay={10}>
|
||||
<Photo
|
||||
src="/hackathon-grant/step2.png"
|
||||
alt="Summer Creek Hack Club meeting, February 2020"
|
||||
width={3000}
|
||||
height={2550}
|
||||
showAlt
|
||||
color="#ec3750"
|
||||
icon="post"
|
||||
duration="Step 2"
|
||||
name={
|
||||
<>
|
||||
Fill in your application, we'll respond in 24 hours
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Slide>
|
||||
<Slide left>
|
||||
<Photo
|
||||
src="/hackathon-grant/step3.png"
|
||||
alt="Summer Creek Hack Club meeting, February 2020"
|
||||
width={3000}
|
||||
height={2550}
|
||||
showAlt
|
||||
color="#ec3750"
|
||||
duration="Step 3"
|
||||
icon="payment-transfer"
|
||||
name="Ka-ching! If approved, start spending your $500"
|
||||
/>
|
||||
</Slide>
|
||||
</Grid>
|
||||
|
||||
<Slide left>
|
||||
<Link
|
||||
href="/slack/?reason=Application%20for%20the%20high%20school%20hackathon%20grant"
|
||||
target="_blank"
|
||||
sx={{ textDecoration: 'none' }}
|
||||
>
|
||||
<Button
|
||||
as="a"
|
||||
variant="primary"
|
||||
sx={{
|
||||
fontSize: [2, null, 3],
|
||||
display: 'block',
|
||||
mx: 'auto',
|
||||
width: 'fit-content'
|
||||
}}
|
||||
>
|
||||
Join Slack
|
||||
</Button>
|
||||
</Link>
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
textAlign: 'center',
|
||||
color: 'muted',
|
||||
my: 3,
|
||||
width: '60%',
|
||||
mx: 'auto'
|
||||
}}
|
||||
>
|
||||
Already have an account? Join the{' '}
|
||||
<Link href={channel} target="_blank">
|
||||
#hackathon-grants
|
||||
</Link>{' '}
|
||||
channel!
|
||||
</Box>
|
||||
</Slide>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Apply
|
||||
78
components/hackathon-grant/form.js
Normal file
78
components/hackathon-grant/form.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import Icon from '@hackclub/icons'
|
||||
import { useRef, useState } from 'react'
|
||||
import { Box, Label, Input, Button, Text } from 'theme-ui'
|
||||
|
||||
const Form = () => {
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
const formRef = useRef(null)
|
||||
|
||||
const handleSubmit = async e => {
|
||||
e.preventDefault()
|
||||
|
||||
await fetch(
|
||||
'https://airtable-forms-proxy.hackclub.dev/api/appEzv7w2IBMoxxHe/Hackathon%20Grant%20Waitlist',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
Email: e.target.email.value
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
formRef.current.reset()
|
||||
|
||||
setSubmitted(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{ textAlign: 'center', maxWidth: '24rem', mx: 'auto' }}
|
||||
as="form"
|
||||
ref={formRef}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Label htmlFor="email" sx={{ color: 'smoke', fontSize: 18 }}>
|
||||
Your email
|
||||
<Input
|
||||
id="email"
|
||||
placeholder="orpheus@hackclub.com"
|
||||
name="email"
|
||||
type="email"
|
||||
sx={{
|
||||
bg: 'darkless',
|
||||
my: 0,
|
||||
mt: 1,
|
||||
mb: 2
|
||||
}}
|
||||
required
|
||||
/>
|
||||
</Label>
|
||||
|
||||
{submitted ? (
|
||||
<Text color="smoke" sx={{ display: 'block', mt: 3 }}>
|
||||
<Box color="green">
|
||||
<Icon glyph="checkmark" />
|
||||
</Box>
|
||||
Thanks! We'll send you an email in the coming weeks when applications
|
||||
have opened.
|
||||
</Text>
|
||||
) : (
|
||||
<>
|
||||
<Button variant="outline">Get notified</Button>
|
||||
<Text
|
||||
variant="caption"
|
||||
sx={{ color: 'muted', fontSize: 16, display: 'block', mt: 3 }}
|
||||
>
|
||||
We'll send you an email when grant applications are open— no spam or
|
||||
unexpected marketing emails.
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default Form
|
||||
128
components/hackathon-grant/money.js
Normal file
128
components/hackathon-grant/money.js
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Full credit to https://joshwcomeau.com/react/animated-sparkles-in-react/
|
||||
import { useState } from 'react'
|
||||
import styled from '@emotion/styled'
|
||||
import { keyframes } from '@emotion/react'
|
||||
import { range, sample, random } from 'lodash'
|
||||
import { Text } from 'theme-ui'
|
||||
import theme from '@hackclub/theme'
|
||||
|
||||
import useRandomInterval from '../../lib/use-random-interval'
|
||||
import usePrefersReducedMotion from '../../lib/use-prefers-reduced-motion'
|
||||
|
||||
const generateSparkle = color => {
|
||||
const sparkle = {
|
||||
id: String(random(10000, 99999)),
|
||||
createdAt: Date.now(),
|
||||
color,
|
||||
size: random(10, 25),
|
||||
style: {
|
||||
top: random(-10, 100) + '%',
|
||||
left: random(-10, 100) + '%'
|
||||
}
|
||||
}
|
||||
return sparkle
|
||||
}
|
||||
|
||||
const MSparkles = ({
|
||||
colors = ['orange', 'yellow', 'green'],
|
||||
children,
|
||||
sx,
|
||||
props,
|
||||
...delegated
|
||||
}) => {
|
||||
const allColors = colors.map(n => theme.colors[n])
|
||||
const getColor = () => sample(allColors)
|
||||
const [sparkles, setSparkles] = useState(() => {
|
||||
return range(3).map(() => generateSparkle(getColor()))
|
||||
})
|
||||
const prefersReducedMotion = usePrefersReducedMotion()
|
||||
useRandomInterval(
|
||||
() => {
|
||||
const sparkle = generateSparkle(getColor())
|
||||
const now = Date.now()
|
||||
const nextSparkles = sparkles.filter(sp => {
|
||||
const delta = now - sp.createdAt
|
||||
return delta < 750
|
||||
})
|
||||
nextSparkles.push(sparkle)
|
||||
setSparkles(nextSparkles)
|
||||
},
|
||||
prefersReducedMotion ? null : 250,
|
||||
prefersReducedMotion ? null : 150
|
||||
)
|
||||
|
||||
return (
|
||||
<Wrapper {...delegated}>
|
||||
{sparkles.map(sparkle => (
|
||||
<Sparkle
|
||||
key={sparkle.id}
|
||||
color={sparkle.color}
|
||||
size={sparkle.size}
|
||||
style={sparkle.style}
|
||||
/>
|
||||
))}
|
||||
<ChildWrapper as="strong" sx={sx} {...props}>
|
||||
{children}
|
||||
</ChildWrapper>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const Sparkle = ({ size, color, style }) => {
|
||||
const path =
|
||||
'M27 0H18V7.44119C8.56638 8.96454 2.608 15.2023 2.608 24.168C2.608 34.4553 10.2396 38.3636 18 41.2862V60.3901C14.2364 58.7919 11.8724 55.3359 11.536 50.088H0.591999C0.999374 61.0056 7.97574 68.051 18 69.933V80H27V70.2565C37.6237 69.0685 44.656 62.1891 44.656 51.912C44.656 40.3121 35.4657 36.7574 27 33.8641V16.9739C30.363 18.3007 32.5185 21.3983 32.656 26.76H43.312C43.228 15.2519 36.6759 8.81537 27 7.38614V0ZM18 16.871C14.8637 17.9425 13.072 20.2358 13.072 23.304C13.072 26.6134 15.0429 28.7127 18 30.3352V16.871ZM27 44.7132V61.0707C31.4416 60.1212 34.192 57.2657 34.192 53.16C34.192 48.9744 31.1721 46.6064 27 44.7132Z'
|
||||
return (
|
||||
<SparkleWrapper style={style}>
|
||||
<SparkleSvg width={size} height={size} viewBox="0 0 82 82" fill="none">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d={path} fill={color} />
|
||||
</SparkleSvg>
|
||||
</SparkleWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const comeInOut = keyframes`
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
`
|
||||
const spin = keyframes`
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(20deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg)
|
||||
}
|
||||
`
|
||||
const Wrapper = styled.span`
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
`
|
||||
const SparkleWrapper = styled.span`
|
||||
position: absolute;
|
||||
display: block;
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
animation: ${comeInOut} 1000ms forwards;
|
||||
}
|
||||
`
|
||||
const SparkleSvg = styled.svg`
|
||||
display: block;
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
animation: ${spin} 2250ms linear;
|
||||
}
|
||||
`
|
||||
const ChildWrapper = styled(Text)`
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
font-weight: bold;
|
||||
`
|
||||
|
||||
export default MSparkles
|
||||
|
|
@ -9,9 +9,10 @@ const JoinForm = ({ sx = {} }) => {
|
|||
clearOnSubmit: 5000,
|
||||
method: 'POST',
|
||||
initData: router.query.continent
|
||||
? { continent: router.query.continent }
|
||||
: {}
|
||||
? { continent: router.query.continent, reason: router.query.reason }
|
||||
: { reason: router.query.reason }
|
||||
})
|
||||
|
||||
return (
|
||||
<Card sx={{ maxWidth: 'narrow', mx: 'auto', label: { mb: 3 }, ...sx }}>
|
||||
<form {...formProps}>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const nextConfig = {
|
|||
'cloud-dtijd5g0u-hack-club-bot.vercel.app',
|
||||
'cloud-3aeson6ue-hack-club-bot.vercel.app',
|
||||
'cloud-k3mgtdz5i-hack-club-bot.vercel.app',
|
||||
'assets.hackclub.com',
|
||||
''
|
||||
]
|
||||
},
|
||||
|
|
@ -25,6 +26,7 @@ const nextConfig = {
|
|||
},
|
||||
async redirects() {
|
||||
return [
|
||||
{ source: '/grant/', destination: '/hackathon-grant', permanent: false },
|
||||
{ source: '/start/', destination: '/', permanent: false },
|
||||
{ source: '/clubs/', destination: '/', permanent: false },
|
||||
{ source: '/repl/', destination: '/', permanent: true },
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"animejs": "^3.2.1",
|
||||
"country-list-js": "^3.1.7",
|
||||
"globby": "^11.0.4",
|
||||
"jquery": "^3.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "^12.2.5",
|
||||
"next-compose-plugins": "^2.2.1",
|
||||
|
|
@ -48,7 +49,7 @@
|
|||
"vanilla-tilt": "^1.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-next": "12.2.5",
|
||||
"eslint": "8.22.0"
|
||||
"eslint": "8.21.0",
|
||||
"eslint-config-next": "12.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
448
pages/hackathons/grant.js
Normal file
448
pages/hackathons/grant.js
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { Box, Badge, Container, Flex, Grid, Heading } from 'theme-ui'
|
||||
import Meta from '@hackclub/meta'
|
||||
import Head from 'next/head'
|
||||
import ForceTheme from '../../components/force-theme'
|
||||
import Nav from '../../components/nav'
|
||||
import Footer from '../../components/footer'
|
||||
import MSparkles from '../../components/hackathon-grant/money'
|
||||
import NextLink from 'next/link'
|
||||
import { Link, Text, Button, Card } from 'theme-ui'
|
||||
import Icon from '@hackclub/icons'
|
||||
import Form from '../../components/hackathon-grant/form'
|
||||
import Apply from '../../components/hackathon-grant/apply'
|
||||
import Apply2 from '../../components/hackathon-grant/apply2'
|
||||
|
||||
import Zoom from 'react-reveal/Zoom'
|
||||
/** @jsxImportSource theme-ui */
|
||||
if (typeof window !== 'undefined') {
|
||||
window.$ = window.jQuery = require('jquery')
|
||||
|
||||
$(document).ready(function () {
|
||||
// Add smooth scrolling to all links (source: w3schools)
|
||||
$('a').on('click', function (event) {
|
||||
if (this.hash !== '') {
|
||||
event.preventDefault()
|
||||
var hash = this.hash
|
||||
|
||||
$('html, body').animate(
|
||||
{
|
||||
scrollTop: $(hash).offset().top
|
||||
},
|
||||
800,
|
||||
function () {
|
||||
window.location.hash = hash
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const Requirement = ({ title, children, checkmark, background, size }) => {
|
||||
return (
|
||||
<Zoom>
|
||||
<Card
|
||||
variant="interactive"
|
||||
sx={{
|
||||
backgroundColor: 'elevated',
|
||||
backgroundImage: `url('${background}')`,
|
||||
backgroundSize: '40px 40px',
|
||||
backgroundRepeat: 'repeat',
|
||||
backgroundPosition: '10% 10%',
|
||||
color: 'snow',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'start',
|
||||
height: '100%'
|
||||
}}
|
||||
>
|
||||
<Flex sx={{ alignItems: 'center' }}>
|
||||
<Box mr={3} sx={{ lineHeight: 0, flexShrink: 0 }}>
|
||||
<Icon glyph={checkmark} color="#ec3750" size={size} />
|
||||
</Box>
|
||||
<Text variant="heading" sx={{ fontSize: [2, 3, 3], lineHeight: 1.5 }}>
|
||||
{title}
|
||||
</Text>
|
||||
</Flex>
|
||||
|
||||
<Text pl={48} mt={2} sx={{ fontSize: [1, 2, 2] }}>
|
||||
{children}
|
||||
</Text>
|
||||
</Card>
|
||||
</Zoom>
|
||||
)
|
||||
}
|
||||
|
||||
const HackathonGrant = () => {
|
||||
let open = true // change this when we open the form :)
|
||||
let channel = 'https://hackclub.slack.com/archives/C03TS0VKFPZ' //change link to the right channel (right now it goes to #hackathon-grants-dev)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Meta
|
||||
as={Head}
|
||||
title="Hackathon Grant"
|
||||
description="Hack Club is partnering with FIRST to provide $500 grants to in-person high school hackathons happening this semester."
|
||||
image="https://cloud-7yw9f6xnv-hack-club-bot.vercel.app/0grant.png"
|
||||
/>
|
||||
<Box as="main" key="main">
|
||||
<Nav dark />
|
||||
<ForceTheme theme="dark" />
|
||||
<Meta as={Head} title="Hackathon Grant" />
|
||||
<Box
|
||||
sx={{
|
||||
pt: [5, null, null, null, 6],
|
||||
pb: [3, 4, 5, null, 6],
|
||||
minHeight: ['70vh', 'none'],
|
||||
textAlign: 'center',
|
||||
backgroundImage:
|
||||
"linear-gradient(to bottom, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.4)), url('https://cloud-gxxp8xcyl-hack-club-bot.vercel.app/0fzfm1e-ueaef1qw.jpeg')",
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center center',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
maxWidth: 'calc(56rem + 32px)',
|
||||
mx: 'auto',
|
||||
px: '16px',
|
||||
backdropFilter: 'blur(1.5px)'
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
mt: [2, 4],
|
||||
textShadow: '0 0 16px rgba(0, 0, 0, 1)',
|
||||
fontSize: [5, null, 6, 7]
|
||||
}}
|
||||
as="h1"
|
||||
variant="title"
|
||||
>
|
||||
<Flex
|
||||
sx={{ justifyContent: 'center', alignItems: 'center', mb: 2 }}
|
||||
>
|
||||
<NextLink href="https://hackclub.com" passHref>
|
||||
<Box
|
||||
as="a"
|
||||
width={64}
|
||||
height={64}
|
||||
sx={{
|
||||
width: 72,
|
||||
height: 72,
|
||||
backgroundImage:
|
||||
"url('https://assets.hackclub.com/icon-square.svg')",
|
||||
backgroundSize: 'contain',
|
||||
backgroundPosition: 'center center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
mr: 3,
|
||||
borderRadius: 8
|
||||
}}
|
||||
target="_blank"
|
||||
></Box>
|
||||
</NextLink>
|
||||
<Box mr={3} sx={{ fontWeight: 'normal' }}>
|
||||
+
|
||||
</Box>
|
||||
<NextLink href="https://www.firstinspires.org" passHref>
|
||||
<Box
|
||||
as="a"
|
||||
sx={{
|
||||
width: 72,
|
||||
height: 72,
|
||||
backgroundImage: "url('/hackathon-grant/first.png')",
|
||||
backgroundColor: '#231F20',
|
||||
backgroundSize: '60px, cover',
|
||||
backgroundPosition: 'center center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
borderRadius: 8
|
||||
}}
|
||||
target="_blank"
|
||||
></Box>
|
||||
</NextLink>
|
||||
</Flex>
|
||||
A <MSparkles>$500</MSparkles> grant for your{' '}
|
||||
<a sx={{ whiteSpace: 'nowrap' }}>in-person</a> hackathon.
|
||||
</Heading>
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: [2, 3, 3],
|
||||
textAlign: 'center',
|
||||
my: 4
|
||||
}}
|
||||
>
|
||||
Hack Club is partnering with{' '}
|
||||
<NextLink href="https://www.firstinspires.org" passHref>
|
||||
<Link target="_blank">
|
||||
<i>FIRST®</i>
|
||||
</Link>
|
||||
</NextLink>{' '}
|
||||
to provide $500 grants (and waiving{' '}
|
||||
<Link href="/bank" target="_blank">
|
||||
Hack Club Bank
|
||||
</Link>{' '}
|
||||
fees) to <a sx={{ whiteSpace: 'nowrap' }}>in-person</a>{' '}
|
||||
<a sx={{ whiteSpace: 'nowrap' }}>high school</a> hackathons
|
||||
happening this semester.
|
||||
</Box>
|
||||
<Button variant="ctaLg" as="a" href="#apply" sx={{ mt: 2 }}>
|
||||
{open ? 'Apply Now' : 'Coming Soon'}
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Container sx={{ py: 5 }}>
|
||||
<Text
|
||||
as="h1"
|
||||
variant="heading"
|
||||
mt={4}
|
||||
mb={3}
|
||||
sx={{ fontSize: [28, 30, 40], textAlign: 'center' }}
|
||||
>
|
||||
Check if your hackathon qualifies
|
||||
</Text>
|
||||
|
||||
<Grid columns={[1, 1, 2, 2]} gap={4}>
|
||||
<Requirement
|
||||
title="Running this semester"
|
||||
checkmark="clock-fill"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:clock.svg"
|
||||
size="36"
|
||||
>
|
||||
We want to bring back high schooler-led events acround the world,
|
||||
so we're only offering this grant for high school hackathons that
|
||||
take place this semester (from August 19th to December 31st 2022).
|
||||
<br />
|
||||
<br />
|
||||
<Text
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
This is not an annual program and is only available this semester.
|
||||
</Text>
|
||||
</Requirement>
|
||||
<Requirement
|
||||
title={
|
||||
<>
|
||||
By <a sx={{ whiteSpace: 'nowrap' }}>high schoolers</a>, for{' '}
|
||||
<a sx={{ whiteSpace: 'nowrap' }}>high schoolers</a>
|
||||
</>
|
||||
}
|
||||
checkmark="profile-fill"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:profile.svg"
|
||||
size="36"
|
||||
>
|
||||
To create a uniquely tailored high school hackathon, your
|
||||
hackathon should be organized by high school students*. All
|
||||
attendees should be 18 & under <u>AND</u> not full-time college
|
||||
students.
|
||||
<br />
|
||||
<br />
|
||||
<Text
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
Maximum of 1 college student is allowed on your organizing team.
|
||||
</Text>
|
||||
</Requirement>
|
||||
<Requirement
|
||||
title="Fully in-person"
|
||||
checkmark="flag-fill"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:flag.svg"
|
||||
size="36"
|
||||
>
|
||||
Hacking is a social activity, and we're supporting hackathons that
|
||||
bring hackers together IRL. We believe that fully IRL (not hybrid)
|
||||
events allow organisers to maximize the unique hackathon
|
||||
experience for attendees.
|
||||
</Requirement>
|
||||
<Requirement
|
||||
title="Venue secured"
|
||||
checkmark="pin-fill"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:pin.svg"
|
||||
>
|
||||
You will need to provide a scan of an email, contract, or an{' '}
|
||||
<Link
|
||||
href="https://www.investopedia.com/terms/m/mou.asp"
|
||||
target="_blank"
|
||||
>
|
||||
MOU
|
||||
</Link>{' '}
|
||||
with your venue. Your scan should have the date of your hackathon
|
||||
and address, contact details, and the specific commitment of your
|
||||
venue.
|
||||
</Requirement>
|
||||
<Requirement
|
||||
title="Handmade website"
|
||||
checkmark="web"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:web.svg"
|
||||
size="36"
|
||||
>
|
||||
We believe the best hackathons embody the hacker spirit by
|
||||
building their own website. Complex or simple, beautiful or janky–
|
||||
build your own instead of using nontechnical tools like Wix or
|
||||
Devpost.
|
||||
<br />
|
||||
<br />
|
||||
<Text
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
You will need to share a link to your website. Don't have a
|
||||
domain?{' '}
|
||||
<Link href="/bank" target="_blank">
|
||||
Hack Club Bank
|
||||
</Link>{' '}
|
||||
provides a free domain. Check out{' '}
|
||||
<Link
|
||||
href="https://notebook.lachlanjc.com/2019-09-06_making_a_hackathon_site"
|
||||
target="_blank"
|
||||
>
|
||||
a guide on building hackathon websites
|
||||
</Link>{' '}
|
||||
or ask in{' '}
|
||||
<Link
|
||||
href="/slack"
|
||||
target="_blank"
|
||||
sx={{
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
Slack
|
||||
</Link>{' '}
|
||||
if you need help.
|
||||
</Text>
|
||||
</Requirement>
|
||||
<Requirement
|
||||
title="Open Sourced finances"
|
||||
checkmark="bank-circle"
|
||||
background="https://icons.hackclub.com/api/icons/0x212025/glyph:bank-account.svg"
|
||||
size="28"
|
||||
>
|
||||
You'll receive your grant through{' '}
|
||||
<NextLink href="/bank" passHref>
|
||||
<Link target="_blank">Hack Club Bank</Link>
|
||||
</NextLink>
|
||||
, our financial platform for hackathons, and spend it in the open
|
||||
with{' '}
|
||||
<Link
|
||||
href="https://changelog.bank.hackclub.com/transparent-finances-(optional-feature)-151427"
|
||||
target="_blank"
|
||||
>
|
||||
Transparency Mode
|
||||
</Link>
|
||||
. Sign up for a{' '}
|
||||
<Link
|
||||
href="/bank"
|
||||
target="_blank"
|
||||
sx={{
|
||||
color: 'white'
|
||||
}}
|
||||
>
|
||||
Hack Club Bank
|
||||
</Link>{' '}
|
||||
project before applying.
|
||||
<br />
|
||||
<br />
|
||||
<Text
|
||||
sx={{
|
||||
fontSize: ['14px', 1, 1],
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
If you're unable to use{' '}
|
||||
<Link
|
||||
href="/bank"
|
||||
target="_blank"
|
||||
sx={{
|
||||
color: 'muted'
|
||||
}}
|
||||
>
|
||||
Hack Club Bank
|
||||
</Link>{' '}
|
||||
, we're unfortunately unable to support you through this grant
|
||||
program.
|
||||
</Text>
|
||||
</Requirement>
|
||||
</Grid>
|
||||
|
||||
{open ? (
|
||||
<>
|
||||
{/* <Apply channel={channel} /> */}
|
||||
<Apply2 channel={channel} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Heading
|
||||
sx={{ textAlign: 'center', mb: 3, fontSize: 5 }}
|
||||
id="apply"
|
||||
>
|
||||
Applications opening soon.
|
||||
</Heading>
|
||||
|
||||
<Form />
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
</Box>
|
||||
<Zoom>
|
||||
<Card
|
||||
as="a"
|
||||
variant="interactive"
|
||||
href="mailto:bank@hackclub.com"
|
||||
sx={{
|
||||
mx: 'auto',
|
||||
maxWidth: '52rem',
|
||||
width: '90%',
|
||||
textAlign: 'left',
|
||||
textDecoration: 'none',
|
||||
lineHeight: 'caption',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
fontSize: [1, 2, 2],
|
||||
mb: [3, 4],
|
||||
p: '16px !important',
|
||||
svg: { flexShrink: 'none' }
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
glyph="emoji"
|
||||
color="#ec3750"
|
||||
sx={{
|
||||
mr: [2, 3],
|
||||
ml: 2,
|
||||
display: ['none', 'block'],
|
||||
width: 56,
|
||||
height: 'auto'
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
as="p"
|
||||
sx={{
|
||||
flex: '1 1 auto',
|
||||
strong: { display: ['inline', 'block'], pl: 3 }
|
||||
}}
|
||||
>
|
||||
<strong>Questions?</strong>
|
||||
<Text as="span" variant="caption" color="secondary" sx={{ pl: 3 }}>
|
||||
Reach out to <Link>bank@hackclub.com</Link>
|
||||
</Text>
|
||||
</Text>
|
||||
</Card>
|
||||
</Zoom>
|
||||
<Footer dark key="footer" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default HackathonGrant
|
||||
BIN
public/hackathon-grant/first.png
Normal file
BIN
public/hackathon-grant/first.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
BIN
public/hackathon-grant/step1.gif
Normal file
BIN
public/hackathon-grant/step1.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 707 KiB |
BIN
public/hackathon-grant/step2.png
Normal file
BIN
public/hackathon-grant/step2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
BIN
public/hackathon-grant/step3.png
Normal file
BIN
public/hackathon-grant/step3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
Loading…
Add table
Reference in a new issue