mirror of
https://github.com/System-End/site.git
synced 2026-04-19 20:55:09 +00:00
Create initial bin rsvp website
This commit is contained in:
parent
eff96b203e
commit
c74bfe5f36
3 changed files with 239 additions and 0 deletions
63
components/bin/rsvp-form.js
Normal file
63
components/bin/rsvp-form.js
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { Checkbox, Input, Label, Text } from 'theme-ui'
|
||||||
|
import useForm from '../../lib/use-form'
|
||||||
|
import Submit from '../submit'
|
||||||
|
import { Slide } from 'react-reveal'
|
||||||
|
|
||||||
|
export default function RsvpForm() {
|
||||||
|
const { status, formProps, useField } = useForm(
|
||||||
|
'/api/bin/rsvp',
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
clearOnSubmit: 60000,
|
||||||
|
method: 'POST',
|
||||||
|
initData: {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<form {...formProps}>
|
||||||
|
<Label>
|
||||||
|
<Text>Email</Text>
|
||||||
|
<Input
|
||||||
|
{...useField('email')}
|
||||||
|
placeholder="fiona@hackclub.com"
|
||||||
|
required
|
||||||
|
sx={{ border: '1px solid', borderColor: 'muted' }}
|
||||||
|
/>
|
||||||
|
</Label>
|
||||||
|
<Label variant="labelHoriz" sx={{ fontSize: 1, pt: 1 }}>
|
||||||
|
<Checkbox {...useField('high_schooler', 'checkbox')} defaultChecked={false} />I am a current high
|
||||||
|
school student or younger.
|
||||||
|
</Label>
|
||||||
|
<Label variant="labelHoriz" sx={{ fontSize: 1, pt: 1 }}>
|
||||||
|
<Checkbox {...useField('stickers', 'checkbox')} />
|
||||||
|
I want a sticker sheet.
|
||||||
|
</Label>
|
||||||
|
{(useField('stickers', 'checkbox').checked) && (
|
||||||
|
<Slide left delay={20}>
|
||||||
|
<Label>
|
||||||
|
Address (line 1)
|
||||||
|
<Input
|
||||||
|
{...useField('address_line_1')}
|
||||||
|
placeholder="1 Hacker Way"
|
||||||
|
required
|
||||||
|
sx={{ border: '1px solid', borderColor: 'muted' }}
|
||||||
|
/>
|
||||||
|
</Label>
|
||||||
|
<Label>
|
||||||
|
Address (zip code)
|
||||||
|
<Input
|
||||||
|
{...useField('address_zip')}
|
||||||
|
placeholder="01337"
|
||||||
|
required
|
||||||
|
sx={{ border: '1px solid', borderColor: 'muted' }}
|
||||||
|
/>
|
||||||
|
</Label>
|
||||||
|
</Slide>
|
||||||
|
)}
|
||||||
|
<Submit status={status} />
|
||||||
|
</form>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
30
pages/api/bin/rsvp.js
Normal file
30
pages/api/bin/rsvp.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// https://airtable.com/appKjALSnOoA0EmPk/tblYYhxN9TaPPMMRV/viwJFvTlmRNHj0Toh?blocks=hide
|
||||||
|
import AirtablePlus from 'airtable-plus'
|
||||||
|
|
||||||
|
const rsvpsTable = new AirtablePlus({
|
||||||
|
apiKey: process.env.AIRTABLE_API_KEY,
|
||||||
|
baseID: 'appKjALSnOoA0EmPk',
|
||||||
|
tableName: 'RSVPs'
|
||||||
|
})
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
const { email, high_schooler, stickers, address_line_1, address_zip } = req.body
|
||||||
|
|
||||||
|
const fields = {
|
||||||
|
Email: email,
|
||||||
|
'High Schooler': '' + high_schooler,
|
||||||
|
Stickers: '' + stickers,
|
||||||
|
'Address (line 1)': address_line_1,
|
||||||
|
'Address (zip code)': address_zip
|
||||||
|
}
|
||||||
|
|
||||||
|
await rsvpsTable.create(fields)
|
||||||
|
|
||||||
|
res.status(200).json({ success: true })
|
||||||
|
} else if (req.method == 'GET') {
|
||||||
|
const result = await rsvpsTable.read({ field: 'Status' })
|
||||||
|
|
||||||
|
res.status(200).json(result.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
146
pages/bin.js
Normal file
146
pages/bin.js
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { Box, Container, Text, Heading, Card, Flex, Image, Link } from "theme-ui";
|
||||||
|
import Head from 'next/head'
|
||||||
|
import Meta from '@hackclub/meta'
|
||||||
|
import Nav from '../components/nav'
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import Footer from "../components/footer";
|
||||||
|
import { keyframes } from "@emotion/react";
|
||||||
|
import RsvpForm from "../components/bin/rsvp-form";
|
||||||
|
|
||||||
|
const RsvpCount = () => {
|
||||||
|
const [rsvpCount, setRsvpCount] = useState(0)
|
||||||
|
useEffect(async () => {
|
||||||
|
// const url = 'https://api2.hackclub.com/v0.1/The Bin/rsvp' <- switch to this once we have api2 back up and running
|
||||||
|
const url = '/api/bin/rsvp'
|
||||||
|
const results = await fetch(url).then(r => r.json())
|
||||||
|
setRsvpCount(results)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text>{100 - rsvpCount} RSVPs until the start of...</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const wobble = keyframes({
|
||||||
|
from: { transform: 'rotate(15deg)' },
|
||||||
|
to: { transform: 'rotate(20deg)' }
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function Bin() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Meta
|
||||||
|
as={Head}
|
||||||
|
title="The Bin"
|
||||||
|
description="Jump in the trash!"
|
||||||
|
/>
|
||||||
|
<Nav light />
|
||||||
|
<Box as="main" sx={{ pt: '3em', bg: '#ECE9E0', textAlign: 'center' }}>
|
||||||
|
<Container sx={{ position: 'relative' }}>
|
||||||
|
<Box as="section" sx={{ textAlign: 'center', pt: '4em' }}>
|
||||||
|
<Heading
|
||||||
|
as="h1"
|
||||||
|
variant="ultratitle"
|
||||||
|
py={3}
|
||||||
|
sx={{
|
||||||
|
fontSize: "6em",
|
||||||
|
'@media (prefers-reduced-motion: no-preference)': {
|
||||||
|
animation: `${wobble} 2.5s ease-in-out infinite alternate`
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
🗑️
|
||||||
|
</Heading>
|
||||||
|
<RsvpCount />
|
||||||
|
<Heading
|
||||||
|
as="h1"
|
||||||
|
variant="ultratitle"
|
||||||
|
py={3}
|
||||||
|
>
|
||||||
|
The Bin
|
||||||
|
</Heading>
|
||||||
|
<Text sx={{ fontWeight: 'bold' }}>An electronics starter kit, customized for <em>your</em> project</Text>
|
||||||
|
</Box>
|
||||||
|
<Box as="section" sx={{ textAlign: 'center' }}>
|
||||||
|
<Card sx={{ p: 3, mt: 4, mx: 'auto', maxWidth: '40ch' }}>
|
||||||
|
<Text as="p">High schoolers can get a kit of electronics parts for free to build their first project.</Text>
|
||||||
|
<Text as="p" sx={{ color: 'muted' }}>RSVP to get notified when applications open.</Text>
|
||||||
|
<RsvpForm />
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
<Box as="section" sx={{ textAlign: 'center', pt: '4em' }}>
|
||||||
|
<Heading as="h2" variant="headline">Motors & lasers & mics, oh my!</Heading>
|
||||||
|
<Box sx={{ textAlign: 'left' }}>
|
||||||
|
<Flex sx={{ my: 4 }}>
|
||||||
|
<Box>
|
||||||
|
<Text as="p"><b>1. Rummage</b></Text>
|
||||||
|
<Text>Dig through the bin to get a randomly generated set of parts (<em>or you can choose your own</em>).</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Image src="https://cloud-i547pyt1f-hack-club-bot.vercel.app/0idea.png" />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex sx={{ my: 4 }}>
|
||||||
|
<Box>
|
||||||
|
<Image src="https://cloud-i547pyt1f-hack-club-bot.vercel.app/0idea.png" />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text as="p"><b>2. Ideas</b></Text>
|
||||||
|
<Text>With your parts picked out, <b>what will you make?</b> A voice activated laser? A portable disco party? A flashlight that only turns on in the daytime?</Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex sx={{ my: 4 }}>
|
||||||
|
<Box>
|
||||||
|
<Text as="p"><b>3. Prototype</b></Text>
|
||||||
|
<Text>Turn your idea into something almost real: simulate your project in an online editor for beginners.</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Image src="https://cloud-i547pyt1f-hack-club-bot.vercel.app/0idea.png" />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex sx={{ my: 4 }}>
|
||||||
|
<Box>
|
||||||
|
<Image src="https://cloud-i547pyt1f-hack-club-bot.vercel.app/0idea.png" />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text as="p"><b>4. Show off & ship it!</b></Text>
|
||||||
|
<Text>Show off your circuit! If it works in simulation, <b>we’ll send you the parts to build it in real life.</b></Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ a: { color: 'blue' }, pb: 4 }}>
|
||||||
|
<Heading as="h3" variant="subheadline" mb={2}>
|
||||||
|
A project by <a href="https://hackclub.com/">Hack Club</a>.
|
||||||
|
</Heading>
|
||||||
|
<Text as="p" variant="caption" mb={3} sx={{ width: ['85%', '75%', '60%'] }}>
|
||||||
|
Hack Club is a registered 501(c)3 nonprofit organization that supports a
|
||||||
|
network of 20k+ technical high schoolers. We believe you learn best by
|
||||||
|
building so we're removing barriers to hardware access so any teenager can
|
||||||
|
explore. In the past few years, we've{' '}
|
||||||
|
<Link href="https://summer.hackclub.com" target="_blank">
|
||||||
|
partnered with GitHub to give away $50k of hardware
|
||||||
|
</Link>
|
||||||
|
,{' '}
|
||||||
|
<Link
|
||||||
|
href="https://github.com/hackclub/the-hacker-zephyr"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
hosted the world's longest hackathon on land
|
||||||
|
</Link>
|
||||||
|
, and{' '}
|
||||||
|
<Link href="https://github.com/hackclub/assemble" target="_blank">
|
||||||
|
brought 183 teenagers to SF for a hackathon
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</Text>
|
||||||
|
<Text as="p" variant="caption" mb={1}>
|
||||||
|
Illustrations by Ripley.
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue