This commit is contained in:
belle 2024-01-03 10:22:29 -05:00
commit 95db9b0909
170 changed files with 7513 additions and 3105 deletions

5
.gitignore vendored
View file

@ -5,4 +5,7 @@ node_modules
.DS_Store
public/sitemap.xml
.vercel
.vscode
.vscode
yarn-error.log
bun.lockb
.idea

View file

@ -18,7 +18,7 @@ Start running the website on your computer:
And then open up your web browser and go to [localhost:3000](http://localhost:3000).
Please note: There are a number of redirects and rewrites essential to the website's functionality, which you can see in `next.config.js`.
Please note: There are a number of redirects and rewrites essential to the website's functionality, which you can see in [next.config.mjs](./next.config.mjs).
Powered by [Next.js] with [MDX], [Theme UI], & [Hack Club Theme].
@ -26,6 +26,52 @@ Code under MIT License, assets may not be re-used or re-distributed.
---
<h1 align="center">Building <a href="https://hackclub.com/">hackclub.com</a></h1>
Join us in building Hack Club's homepage and show new hackers what Hack Club could be for them 💖.
See something that could be better? Make a PR! Have an easter egg idea? Make a PR! Is the site missing something? Make a PR! _(Do you see a trend? :))_
If you need to add content to the site, here's how you can:
<details> <summary>Create a new card</summary>
<img width="600" alt="Screenshot 2023-08-16 at 9 09 55 PM" src="https://github.com/hackclub/site/assets/65808924/fed45800-c834-4e4c-ad87-a21e01414fa9">
Most things on the homepage are cards, modular components that can easily be added and removed according to relevancy to Hack Clubbers. There are 3 main sections: connection, open-source, and IRL community. Most new cards will likely fall within the first two sections!
First, you can create a new file under [components/index/cards]() with the name of your new event/project. Next add `import CardModel from './card-model'` and add whatever you want :) Finally, use a <Buttons> component (`import Buttons from './button'`) to highlight call-to-action buttons. If it's the main button, use the primary prop to add a background color!
Your challenge: try and make the card as unique as possible, like a mini poster! Not sure where to start? Look at other cards on the page :)
</details>
<details>
<summary>Add to the carousel</summary>
<img width="600" alt="Screenshot 2023-08-16 at 9 09 11 PM" src="https://github.com/hackclub/site/assets/65808924/044660eb-fb3d-43b6-a270-64a3fe51f3ca">
If there's a Hack Club or Hack Club community-led project (past or present) that Hack Clubbers can get involved in, please add it to [lib/carousel.json]() and add your card to the end of the json file. An example looks like this:
```
{
"background": "dark",
"titleColor": "white",
"descriptionColor": "white",
"title": "Hackers Wanted",
"description": "Our open love letter to hackers",
"img": "https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-large/1f4bb@2x.png",
"link": "/hackers-wanted"
}
```
</details>
Every week, [thousands of people](https://plausible.io/hackclub.com) visit hackclub.com. What story to you want to tell?
_Have questions? Join us in [#hackclub-site-dev](https://hackclub.slack.com/archives/C036BTDGP43) and to learn more about the style guide at Hack Club check [this](https://hackclub.com/brand/) out_
---
Hack Club, 2023. MIT License.
[next.js]: https://nextjs.org

View file

@ -11,9 +11,9 @@ It was a huge honor last month to have Elon [spend an hour in an ask-me-anything
When hackers see problems in the world, we dont blame someone else: we try to take them on to solve. Elon is very selective about the nonprofits he supports and Im proud Hack&nbsp;Club is one of them.
So…how will Hack&nbsp;Club invest $500,000? We want to use this to help 1,000 more students start and join Hack Clubs in their towns ([see the worldwide map](https://hackclub.com/map/)). For those already in Hack&nbsp;Club, we look to you to help us make a higher-quality experience. We plan to continue much of what were already doing (and [what I wrote about in January](https://zachinto2020.wordpress.com/2019/12/31/as-midnight-approaches/)): spending as little money as possible at all times, growing slowly, adding diverse staff to make Hack&nbsp;Club better (video game designers, software engineers, media producers, and more). We are pushing hard to try and make the [Hack&nbsp;Club Slack](https://hackclub.com/) the best place to be a teenager on the internet and expanding [Hack&nbsp;Club Bank](https://hackclub.com/bank/).
So…how will Hack&nbsp;Club invest $500,000? We want to use this to help 1,000 more students start and join Hack Clubs in their towns ([see the worldwide map](https://hackclub.com/map/)). For those already in Hack&nbsp;Club, we look to you to help us make a higher-quality experience. We plan to continue much of what were already doing (and [what I wrote about in January](https://zachinto2020.wordpress.com/2019/12/31/as-midnight-approaches/)): spending as little money as possible at all times, growing slowly, adding diverse staff to make Hack&nbsp;Club better (video game designers, software engineers, media producers, and more). We are pushing hard to try and make the [Hack&nbsp;Club Slack](https://hackclub.com/) the best place to be a teenager on the internet and expanding [HCB](https://hackclub.com/hcb/).
Well be fully transparent in how we spend this money. One thing weve been working toward after winning the [Frank Grant](https://grant.frank.ly/) is open sourcing our finances. Hack&nbsp;Club HQ has been running on Hack&nbsp;Club Bank since February, and starting today, [**you can see our finances publicly**](https://bank.hackclub.com/hq). Through Hack Club Bank, you can track how we spend every dollar of Elons gift. Soon, well also launch [Franks](https://frank.ly/) transparency tools on [hackclub.com](https://hackclub.com/).
Well be fully transparent in how we spend this money. One thing weve been working toward after winning the [Frank Grant](https://grant.frank.ly/) is open sourcing our finances. Hack&nbsp;Club HQ has been running on HCB since February, and starting today, [**you can see our finances publicly**](https://hcb.hackclub.com/hq). Through HCB, you can track how we spend every dollar of Elons gift. Soon, well also launch [Franks](https://frank.ly/) transparency tools on [hackclub.com](https://hackclub.com/).
Hack&nbsp;Clubs mission is to build a new generation of hackers. This starts in high school, where Hack&nbsp;Club students learn to be technically proficient, build their friend network, learn to raise and spend money, and develop into kind, curious, thoughtful, optimistic, and honest leaders. And now Elon Musk is one of our largest supporters.

View file

@ -4,10 +4,10 @@ In 2014, Hack Club was founded, and Tom joined as Hack Clubs first board memb
Tom and Theresa also helped fund [The Hacker Zephyr](https://hack.af/zephyrdoc), an epic, cross-country train hackathon taken by 42 teen hackers in the summer of 2021. Tom even hacked alongside Hack Clubbers onboard.
With this gift, we will continue to build the engineering team at Hack Club, including a Tech Lead for [Hack Club Bank](https://hackclub.com/bank), and new engineers to support clubs, the Hack Club online community, and events.
With this gift, we will continue to build the engineering team at Hack Club, including a Tech Lead for [HCB](https://hackclub.com/hcb), and new engineers to support clubs, the Hack Club online community, and events.
One of our goals in 2022 is to improve Hack Club and to support more teenagers in joining the community. Thank you Tom and Theresa for helping make this possible.
We thank Tom and Theresa for their generous gift and will carefully use each cent to advance our mission to create a new generation of young, highly-technical teen leaders capable of solving our worlds greatest problems. Every penny will be spent [transparently](https://bank.hackclub.com/hq).
We thank Tom and Theresa for their generous gift and will carefully use each cent to advance our mission to create a new generation of young, highly-technical teen leaders capable of solving our worlds greatest problems. Every penny will be spent [transparently](https://hcb.hackclub.com/hq).
— Christina Asquith, COO, and Zach Latta, founder

View file

@ -10,11 +10,11 @@ Today, we're excited to announce Elon is donating $1 million to Hack Club.
This gift will help launch a number of ideas we've been discussing, including helping more in-person hackathons get off the ground, providing more direct 1:1 technical support on the [Hack Club Slack](https://hackclub.com/slack/), and starting up cool new projects like [The Hacker Zephyr](https://github.com/hackclub/the-hacker-zephyr). We also want to use his gift to help 1,000 more teenagers start and join Hack Clubs in their towns.
We will be spending every dollar as wisely as possible, growing thoughtfully, and adding diverse staff to make Hack Club better. We are pushing hard to try and make the Hack Club Slack the best place to be a teenager on the internet and expanding [Hack Club Bank](https://hackclub.com/bank/).
We will be spending every dollar as wisely as possible, growing thoughtfully, and adding diverse staff to make Hack Club better. We are pushing hard to try and make the Hack Club Slack the best place to be a teenager on the internet and expanding [HCB](https://hackclub.com/hcb/).
Elon is very selective about the nonprofits he supports and we're proud Hack Club is one of them.
Hack Club will be fully transparent in how we spend this money. Hack Club HQ has been running on Hack Club Bank since February 2020, and [you can see our finances publicly here](https://bank.hackclub.com/hq).
Hack Club will be fully transparent in how we spend this money. Hack Club HQ has been running on HCB since February 2020, and [you can see our finances publicly here](https://hcb.hackclub.com/hq).
Hack Club's mission is to help foster a new generation of hackers. This starts in high school, where Hack Clubbers learn to be technically proficient, build their friend network, learn to raise and spend money, and develop into kind, curious, thoughtful, optimistic, and honest leaders. And now Elon Musk is one of our largest supporters.

View file

@ -1,9 +1,9 @@
import { Box, Flex, Grid, Text, Avatar, Card } from 'theme-ui'
import { Box, Flex, Text, Avatar, Card } from 'theme-ui'
import Icon from '@hackclub/icons'
import { useState } from 'react'
export default function Bio({ popup = true, spanTwo = false, ...props }) {
let { img, name, teamRole, pronouns, text, subrole, href } = props
let { img, name, teamRole, pronouns, text, subrole, href, video } = props
const [expand, setExpand] = useState(false)
return (
<>
@ -22,10 +22,10 @@ export default function Bio({ popup = true, spanTwo = false, ...props }) {
maxWidth: '600px',
zIndex: !popup ? 1003 : 5,
maxHeight: '90vh',
overflowY: 'scroll',
overflowY: 'hidden',
overscrollBehavior: 'contain',
gridColumn: !spanTwo ? null : [null, null, `1 / span 2`],
position: 'relative'
position: 'relative',
}}
as={href && !text ? 'a' : 'div'}
href={href}
@ -98,9 +98,30 @@ export default function Bio({ popup = true, spanTwo = false, ...props }) {
</Text>
</Flex>
{!popup && (
<Text mt={2} mb={0} color="black">
{text}
</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
></iframe>
</Flex>
)}
</>
)}
{!popup && href && (
<Flex sx={{ alignItems: 'center' }}>

View file

@ -6,9 +6,7 @@ const pricePerSprig = 100
const SprigForm = () => {
const [count, setCount] = useState(1)
function url() {
const u = new URL(
'https://bank.hackclub.com/donations/start/game-lab-fund/'
)
const u = new URL('https://hcb.hackclub.com/donations/start/game-lab-fund/')
u.searchParams.set(
'amount',
pricePerSprig * count * 100 /* convert to cents */

View file

@ -27,15 +27,14 @@ a lot of what weve already been doing (and [what I wrote about at the beginni
of the year](https://zachinto2020.wordpress.com/2019/12/31/as-midnight-approaches/)):
well spend as little money as possible at all times, and well hire a small
number of diverse staff from video game engineers to media producers to make
Hack Club better. We are pushing hard now to expand users of [Hack Club
Bank](https://hackclub.com/bank/), and continuing to try and make the Hack Club
Slack the best place to be a teenager on the intenet.
Hack Club better. We are pushing hard now to expand users of [HCB](https://hackclub.com/hcb/),
and continuing to try and make the Hack Club Slack the best place to be a teenager on the intenet.
Well have a proper announcement in a few weeks, but one thing were doing after
winning the [Frank Grant](https://grant.frank.ly/) and now receiving Elons
gift, is open sourcing our finances. Hack Club HQ has been running on Hack Club
Bank since February and starting today, you can see our account publicly at
https://bank.hackclub.com/hq. You can track how we spend every single dollar of
gift, is open sourcing our finances. Hack Club HQ has been running on HCB
since February and starting today, you can see our account publicly at
https://hcb.hackclub.com/hq. You can track how we spend every single dollar of
Elons gift. Soon, we will also launch https://frank.ly/ on Hack&nbsp;Clubs
website.

View file

@ -19,6 +19,8 @@ const Base = styled(Box)`
}
`
const Logo = props => (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -40,7 +42,7 @@ const Logo = props => (
const Service = ({ href, icon, name = '', ...props }) => (
<Link
target="_blank"
rel="noopener"
rel="noopener me"
href={href}
title={`Hack Club on ${name ? name : icon}`}
{...props}
@ -108,7 +110,9 @@ const Footer = ({ dark = false, children, ...props }) => (
<Heading as="h2" variant="subheadline" mb={3}>
Resources
</Heading>
<Link href="https://hackclub.com/pizza">Clubs Pizza Grant</Link>
<Link href="https://events.hackclub.com/">Community Events</Link>
<Link href="https://jams.hackclub.com/">Jams</Link>
<Link href="https://toolbox.hackclub.com/">Toolbox</Link>
<Link href="https://directory.hackclub.com/">Clubs Directory</Link>
<Link href="https://hackclub.com/conduct/">Code of Conduct</Link>
@ -155,9 +159,9 @@ const Footer = ({ dark = false, children, ...props }) => (
name="Figma"
/>
<Service
href="https://www.facebook.com/Hack-Club-741805665870458"
icon="facebook"
name="Facebook"
href="https://social.dino.icu/@hackclub"
icon="mastodon"
name="Mastodon"
/>
<Service
href="https://www.youtube.com/c/HackClubHQ"

View file

@ -19,7 +19,7 @@ const Content = () => (
}}
>
<Container maxWidth={28} sx={{ mx: 0, pt: 4, pb: 2 }}>
<Text variant="eyebrow">Hack Club Bank</Text>
<Text variant="eyebrow">HCB</Text>
<br />
<Text as="span" variant="title">
Grants, waived fees, and more!
@ -31,20 +31,13 @@ const Content = () => (
icon="payment"
leadText={
<>
$500 grants (in partnership with <i>FIRST®</i>).
$500 grants.
</>
}
body={
<>
Running on Bank? Get a $500 grant once you have a venue, provided
by Hack Club with the help of{' '}
<Link
href="https://www.firstinspires.org/"
sx={{ fontStyle: 'italic', color: 'white' }}
>
FIRST
</Link>
.
Running on HCB? Get a $500 grant once you have a venue, provided
by Hack Club.
<NextLink href="/hackathons/grant">
<Link sx={{ ml: 2, cursor: 'pointer' }}>Learn more &rarr;</Link>
</NextLink>
@ -56,22 +49,22 @@ const Content = () => (
icon="bolt"
leadText="All fees waived."
body={`
Run your hackathon on Hack Club Bank for free. All the money you raise goes
Run your hackathon on HCB for free. All the money you raise goes
directly towards your hackathon.`}
/>
<ListItem
icon="rep"
leadText="A suite of free tools."
body={`
When you join Hack Club Bank, you'll have access to a suite of free tools including
When you join HCB, you'll have access to a suite of free tools including
debit cards, a domain name, stickers, and more.`}
/>
</List>
<NextLink href="/bank" passHref>
<NextLink href="/hcb" passHref>
<Button as="a" variant="outlineLg" sx={{ width: [null, null, 500] }}>
Apply&nbsp;
<Box as="span" sx={{ display: ['none', 'inline', ''] }}>
for Hack Club Bank
for HCB
</Box>{' '}
</Button>
@ -164,7 +157,7 @@ const Static = () => (
sx={{
position: 'relative',
overflow: 'hidden',
backgroundImage: `url('/bank/bg.webp')`,
backgroundImage: `url('/hcb/bg.webp')`,
backgroundSize: 'cover'
}}
>

View file

@ -168,7 +168,7 @@ const Apply = ({ channel }) => {
<Slide left>
<Photo
src="/hackathons/grant/step3.png"
alt="Screenshot of a grant in the form of a transaction on a Hack Club Bank ledger"
alt="Screenshot of a grant in the form of a transaction on a HCB ledger"
width={3000}
height={2550}
showAlt

View file

@ -61,7 +61,7 @@ export default function Recap() {
icon="slack"
color="white"
name="Slack community"
desc="Join the Slack and get support in anything hackathon organizing from sponsorships to logistics to ordering food."
desc="Chat in Slack for support with organizing your hackathon, from finding a venue to marketing your event."
/>
</Card>
<Card
@ -81,9 +81,7 @@ export default function Recap() {
name="$500 grants"
desc={
<>
Get a $500 grant for your hackathon (thanks to <i>FIRST</i>!),
and access to a suite of financial tools when you join Hack Club
Bank.
Join HCB to receive a $500 grant for your hackathon and a suite of financial tools.
</>
}
/>
@ -103,7 +101,7 @@ export default function Recap() {
icon="event-check"
color="white"
name="Marketing"
desc="List your event on the front page of Google and emailed to high school hackers in your area."
desc="Get your event listed on Google's front page, emailed to nearby teens, and seen by our hackathon calendar's 3K+ monthly users."
/>
</Card>
</Grid>

View file

@ -6,7 +6,7 @@ export default function ApplyButton() {
<Button
variant="ctaLg"
as="a"
href="apply"
href="/hcb/apply"
sx={{
width: '100%',
height: '4.2rem'

View file

@ -2,10 +2,32 @@ import { useEffect, useRef, useState } from 'react'
import { Box, Flex, Input, Text } from 'theme-ui'
import FlexCol from '../../flex-col'
import AutofillColourFix from './autofill-colour-fix'
import { geocode } from '../../../lib/bank/apply/address-validation'
import { geocode, search } from '../../../lib/hcb/apply/address-validation'
import Icon from '../../icon'
const approvedCountries = ['US', 'CA', 'MX']
const approvedCountries = [
'AT',
'FI',
'FR',
'DE',
'GR',
'ES',
'IT',
'SE',
'TR',
'GB',
'NO',
'UA',
'BR',
'CO',
'US',
'CA',
'MX',
'JP',
'PH',
'MY',
'SG'
]
export default function AutoComplete({ name, isPersonalAddressInput }) {
const input = useRef()
@ -13,9 +35,22 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
const [predictions, setPredictions] = useState(null)
const [countryCode, setCountryCode] = useState(null)
const performGeocode = async address => {
const optionClicked = async prediction => {
input.current.value = prediction.name
await onInput(prediction.name)
setPredictions(null)
}
const clickOutside = e => {
if (input.current && !input.current.contains(e.target)) {
setPredictions(null)
}
}
const onInput = async value => {
setPredictions(value ? (await search(value)).results : null)
if (isPersonalAddressInput) return
geocode(address)
geocode(value)
.then(res => {
const country = res?.results[0]?.country
const countryCode = res?.results[0]?.countryCode
@ -28,15 +63,8 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
.catch(err => console.error(err))
}
const optionClicked = async prediction => {
input.current.value = prediction.description
performGeocode(prediction.description)
setPredictions(null)
}
const clickOutside = e => {
if (input.current && !input.current.contains(e.target)) {
setPredictions(null)
}
const onInputWrapper = async e => {
if (e.target.value) await onInput(e.target.value)
}
//TODO: Close suggestions view when focus is lost via tabbing.
@ -44,36 +72,16 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
useEffect(() => {
const inputEl = input.current
if (!window.google || !inputEl) return
const service = new window.google.maps.places.AutocompleteService()
const onInput = async e => {
if (!e.target.value) {
setPredictions(null)
} else {
service.getPlacePredictions(
{ input: e.target.value },
(predictions, status) => {
setPredictions(predictions)
if (status !== window.google.maps.places.PlacesServiceStatus.OK) {
//DEBUG
setPredictions([])
}
}
)
}
}
if (!inputEl) return
document.addEventListener('click', clickOutside)
inputEl.addEventListener('input', onInput)
inputEl.addEventListener('focus', onInput)
inputEl.addEventListener('input', onInputWrapper)
inputEl.addEventListener('focus', onInputWrapper)
return () => {
document.removeEventListener('click', clickOutside)
inputEl.removeEventListener('input', onInput)
inputEl.removeEventListener('focus', onInput)
inputEl.removeEventListener('input', onInputWrapper)
inputEl.removeEventListener('focus', onInputWrapper)
}
}, [])
@ -87,7 +95,6 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
placeholder="Shelburne, VT"
autoComplete="off"
sx={{ ...AutofillColourFix }}
onInput={async e => performGeocode(e.target.value)}
/>
<Box>
{/* {String(countryCode)} */}
@ -107,17 +114,17 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
}}
>
Currently, we only have first-class support for organizations in
the United States, Canada, and Mexico.
select countries.
<br />
If you're somewhere else, you can still use bank!
<br />
Please contact us at bank@hackclub.com
Please contact us at hcb@hackclub.com
</Text>
</Flex>
)}
</Box>
</FlexCol>
{predictions && (
{predictions && predictions.length > 0 && (
<Box
sx={{
background: '#47454f',
@ -147,9 +154,9 @@ export default function AutoComplete({ name, isPersonalAddressInput }) {
fontSize: 'inherit',
textAlign: 'inherit'
}}
key={prediction.id}
key={idx}
>
{prediction.description}
{prediction.name}
</Text>
{idx < predictions.length - 1 && (

View file

@ -24,6 +24,6 @@ const formContainer = forwardRef(({ children }, ref) => {
)
})
//stackoverflow.com/a/67993106/10652680
https: formContainer.displayName = 'formContainer'
// https://stackoverflow.com/a/67993106/10652680
formContainer.displayName = 'formContainer'
export default formContainer

View file

@ -2,20 +2,20 @@ import { Box, Flex, Link, Text } from 'theme-ui'
import Icon from '../../icon'
import FlexCol from '../../flex-col'
export default function BankInfo() {
export default function HCBInfo() {
return (
<Box>
<FlexCol gap={4}>
<FlexCol gap={4}>
<Text sx={{ fontSize: 36 }}>
What Hack Club Bank <i>is</i>
What HCB <i>is</i>
</Text>
<FlexCol gap={3} ml={3}>
<FlexCol gap={2}>
<Flex sx={{ alignItems: 'center', gap: 2 }}>
<Link
color="white"
href="/bank/fiscal-sponsorship"
href="/hcb/fiscal-sponsorship"
target="_blank"
sx={{
fontSize: 3,
@ -49,7 +49,7 @@ export default function BankInfo() {
</FlexCol>
<FlexCol gap={4}>
<Text sx={{ fontSize: 36 }}>
What Hack Club Bank <i>is not</i>
What HCB <i>is not</i>
</Text>
<FlexCol gap={3} ml={3}>
<FlexCol gap={2}>
@ -63,7 +63,7 @@ export default function BankInfo() {
Rather than setting up a standard bank account, you'll get a
restricted fund within Hack Club accounts.
</li>
<li>You can't deposit or withdraw money.</li>
<li>You can't deposit or withdraw cash. But you can receive any kind of electronic payment!</li>
</ul>
</Text>
</FlexCol>
@ -72,7 +72,7 @@ export default function BankInfo() {
<Text sx={{ color: 'muted' }}>
<ul>
<li>
If youre a for-profit entity, then Bank is not for you.
If youre a for-profit entity, then HCB is not for you.
Consider setting up a business.
</li>
</ul>

View file

@ -15,7 +15,7 @@ async function sendApplication() {
// Send the data
try {
const res = await fetch('/api/bank/apply', {
const res = await fetch('/api/hcb/apply', {
method: 'POST',
cors: 'no-cors',
headers: { 'Content-Type': 'application/json' },
@ -86,7 +86,7 @@ export default function NavButton({
// Set the step query param to minStep if it's not there.
await setStep(minStep)
} else if (step === minStep && isBack) {
await router.push('/bank')
await router.push('/hcb')
return
} else if (step < minStep) {
// Set the step query param to minStep if it's lower than that.
@ -124,7 +124,7 @@ export default function NavButton({
if (step >= maxStep && !isBack) {
await sendApplication()
await router.push('/bank/apply/success')
await router.push('/hcb/apply/success')
return
} else {
step += isBack ? -1 : 1

View file

@ -92,7 +92,7 @@ export default function PersonalInfoForm({
</Field>
<Field
name="returningUser"
label="Have you used Bank before?"
label="Have you used HCB before?"
col={false}
requiredFields={requiredFields}
>
@ -161,6 +161,19 @@ export default function PersonalInfoForm({
</div>
) : null}
</Field>
<Field
name="accommodations"
label="Accessibility needs"
description="Please specify any accommodations or accessibility needs you have so we can support you during onboarding and while using HCB"
requiredFields={requiredFields}
>
<Input
name="accommodations"
id="accommodations"
placeholder="I need a screen reader"
sx={{ ...AutofillColourFix }}
/>
</Field>
</>
)
}

View file

@ -1,5 +1,5 @@
import { Card, Badge as ThemeBadge, Box, Heading, Text, Image } from 'theme-ui'
import { Organization } from '../../../pages/bank/climate'
import { Organization } from '../../../pages/hcb/climate'
import Tilt from '../../../components/tilt'
import Icon from '@hackclub/icons'
import Tooltip from '../tooltip'
@ -111,8 +111,8 @@ export const OrganizationCard = ({
}}
>
{badges.map((badge, i) => (
<Tooltip.W key={i} text={badge.label}>
<span class="tooltipped">
<Tooltip.W key={i} text={badge.label} id={badge.id}>
<span class={`tooltipped-${badge.id}`}>
<Badge badge={badge} />
</span>
</Tooltip.W>

View file

@ -31,8 +31,8 @@ export default function Everything({ fee, partner = false }) {
'Transaction data export': 'download',
'Record shared notes on transactions': 'docs',
'24-hour response support': 'clock',
'Reimbursement process': 'enter',
'Instant deposits': 'bolt'
'Reimbursement process': 'enter'
// 'Instant deposits': 'bolt'
}).map(([item, icon = 'enter']) => (
<ListItem key={item} icon={icon}>
{item}
@ -44,7 +44,7 @@ export default function Everything({ fee, partner = false }) {
'Generate attendee legal waivers': '',
'Virtual debit cards (with Apple & Google Pay)': '',
'Debit card transaction paper trail': '',
'Transparency Mode (optional)': ''
'Transparency Mode': ''
}).map(([item, date]) => (
<ListItem
key={item}
@ -113,7 +113,7 @@ export default function Everything({ fee, partner = false }) {
>
<Container variant="narrow">
<Text sx={{ color: 'muted', lineHeight: 1.375 }}>
Hack Club Bank is a{' '}
HCB is a{' '}
<Link
color="primary"
href="https://en.wikipedia.org/wiki/Fiscal_sponsorship"

View file

@ -24,12 +24,9 @@ export default function Features({ partner = false }) {
<Box>
<Module
icon="bank-account"
name="Bank account"
name="Fund"
body={
<>
Bank account under the hood with a custom, beautiful
dashboard.
</>
<>A fund under the hood with a custom, beautiful dashboard.</>
}
/>
<ModuleDetails>
@ -44,7 +41,7 @@ export default function Features({ partner = false }) {
</ModuleDetails>
</Box>
<Laptop
href="https://bank.hackclub.com/the-innovation-circuit"
href="https://hcb.hackclub.com/the-innovation-circuit"
title="See The Innovation Circuits finances in public"
sx={{
gridColumn: [null, null, 'span 2'],
@ -74,12 +71,12 @@ export default function Features({ partner = false }) {
name="Balance &amp; history"
body="Check real-time account balance + transaction history online anytime."
/>
<Module
{/* <Module
icon="bolt"
name="Instant deposits"
body="Receive donations and invoice payments instantly once they're paid."
/>
<Module
/> */}
{/* <Module
icon="payment"
name="Built-in invoicing"
body={
@ -96,7 +93,7 @@ export default function Features({ partner = false }) {
.
</>
}
/>
/> */}
<Module
icon="docs"
name="Pre-written forms"
@ -189,12 +186,12 @@ export default function Features({ partner = false }) {
>
Have more questions? <br /> Check out the{' '}
<Link
href="https://bank.hackclub.com/faq"
href="https://hcb.hackclub.com/faq"
target="_blank"
rel="noreferrer"
hoverline
>
Hack Club Bank FAQ
HCB FAQ
</Link>
.
</Text>
@ -272,7 +269,7 @@ function Laptop({ href, title, sx }) {
height: '100%',
minHeight: '16rem',
backgroundSize: 'auto 115%',
backgroundImage: "url('/bank/laptop-dark.png')",
backgroundImage: "url('/hcb/laptop-dark.png')",
backgroundPosition: 'center top',
backgroundRepeat: 'no-repeat'
}}

View file

@ -10,7 +10,7 @@ export default function Features() {
<Box sx={{ py: 5 }}>
<Box as="a" href="#testimonials">
<Image
src="/bank/meet-teams-using-bank.svg"
src="/hcb/meet-teams-using-hcb.svg"
alt="yeah"
width={200}
height={100}
@ -61,11 +61,11 @@ export default function Features() {
<ModuleDetails>
<Link
href="https://bank.hackclub.com/poseidon-robotics"
href="https://hcb.hackclub.com/poseidon-robotics"
target="_blank"
>
<NextImage
src="/bank/poseidon-dashboard.png"
src="/hcb/poseidon-dashboard.png"
alt="iPad"
width={500}
height={300}
@ -262,7 +262,7 @@ export default function Features() {
>
<Text variant="caption" sx={{ color: 'muted' }}>
Hack Club does not directly provide banking services. Banking services
provided by FDIC-certified financial institutions.
are provided by FDIC-certified financial institutions.
</Text>
</Container>

View file

@ -119,7 +119,7 @@ export default function Signup() {
const handleSubmit = async e => {
e.preventDefault()
await fetch('/api/bank/demo', {
await fetch('/api/hcb/demo', {
method: 'POST',
body: JSON.stringify({
eventName,
@ -144,7 +144,7 @@ export default function Signup() {
<Base
id="form"
method="POST"
action="/api/bank/demo"
action="/api/hcb/demo"
onSubmit={handleSubmit}
>
<Grid sx={{ gridTemplateColumns: '1fr 2fr', alignItems: 'center' }}>

View file

@ -122,7 +122,7 @@ export default function RealTimeline() {
/>
<Step
icon="rep"
name="Meet with the Bank team on a call"
name="Meet with the HCB team on a call"
duration="Step 2"
/>
<Step

View file

@ -24,11 +24,11 @@ export default function Testimonials() {
}}
>
<Heading variant="title">
<i>FIRST</i> teams all over the country run on Bank.
<i>FIRST</i> teams all over the country run on HCB.
</Heading>
<Text variant="lead" color="muted">
Everywhere from San Jose to Boston to New York,
Hack&nbsp;Club&nbsp;Bank powers teams of all sizes.
Everywhere from San Jose to Boston to New York, HCB powers teams of
all sizes.
</Text>
</Container>
<Container>
@ -48,7 +48,7 @@ export default function Testimonials() {
website="evposeidon.wixsite.com"
url="https://evposeidon.wixsite.com/robo/home"
imgSrc="https://cloud-qtng6088u-hack-club-bot.vercel.app/0image.png"
quote="Overall, Hack Club Bank has opened more opportunities for Poseidon, allowing us to undertake larger projects, both on the playing field and in our community."
quote="Overall, [HCB] has opened more opportunities for Poseidon, allowing us to undertake larger projects, both on the playing field and in our community."
hackerName="Ian Marwong"
hackerRole="Team Lead"
hackerAvatarUrl="/hackers/ian-marwong.jpg"
@ -67,7 +67,7 @@ export default function Testimonials() {
hackerName="Brian Cisto"
hackerRole="Team Captain & Software Lead"
imgSrc="https://cloud-oelh6sp7b-hack-club-bot.vercel.app/0screen_shot_2022-11-06_at_8.45.37_pm.png"
quote="Hack Club Bank has been essential to keeping track of our finances as well as giving us the opportunity to establish ourselves as a nonprofit."
quote="[HCB] has been essential to keeping track of our finances as well as giving us the opportunity to establish ourselves as a nonprofit."
/>
</Grid>
</Container>
@ -211,7 +211,7 @@ function Organization({
</Box>
{transparency && (
<Link
href={`https://bank.hackclub.com/${transparency}`}
href={`https://hcb.hackclub.com/${transparency}`}
target="_blank"
rel="noreferrer"
sx={{ mt: ['16px', '0px'] }}

View file

@ -1,8 +1,17 @@
import { Box, Button, Heading, Link, Text, Container, Badge } from 'theme-ui'
import {
Box,
Button,
Heading,
Link,
Flex,
Text,
Container,
Badge
} from 'theme-ui'
import Fade from 'react-reveal/Fade'
import ScrollHint from '../scroll-hint'
import Image from 'next/image'
import hero from '../../public/bank/bg.webp'
import hero from '../../public/hcb/bg.webp'
export default function Landing({ showButton = true, eventsCount }) {
return (
@ -51,9 +60,33 @@ export default function Landing({ showButton = true, eventsCount }) {
}}
as="h1"
>
<Underline>Become a 501(c)(3) nonprofit</Underline> with
Hack&nbsp;Club&nbsp;Bank.
<Underline>Become a nonprofit</Underline> with HCB
</Heading>
<Flex
sx={{
gap: 3,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 4
}}
>
<img
src="/hcb/hcb-icon-icon-dark.png"
alt="HCB Icon"
height={64}
sx={{
margin: 'auto'
}}
/>
<Text as="h2" sx={{ fontSize: 4 }}>
HCB by
</Text>
<img
src="https://assets.hackclub.com/flag-standalone.svg"
alt="hack club flag"
height={48}
/>
</Flex>
<Container variant="copy">
<Text
variant="lead"
@ -75,8 +108,8 @@ export default function Landing({ showButton = true, eventsCount }) {
Innovation Circuit
</Link>{' '}
is one of {Math.round((eventsCount - 50) / 100) * 100}+
teams who use <strong>Hack&nbsp;Club&nbsp;Bank</strong> to
run world-class organizations, hackathons, and clubs.
teams who use <strong>HCB</strong> to run world-class
organizations, hackathons, and clubs.
</Text>
</Container>
</Container>
@ -103,7 +136,7 @@ export default function Landing({ showButton = true, eventsCount }) {
<Button
variant="outlineLg"
as="a"
href="https://bank.hackclub.com"
href="https://hcb.hackclub.com"
target="_blank"
style={{ zIndex: '100' }}
ml={3}

View file

@ -5,7 +5,7 @@ import kebabCase from 'lodash/kebabCase'
const orgs = [
{
logo: '/bank/nonprofits/girlgenius.png',
logo: '/hcb/nonprofits/girlgenius.png',
name: 'Girl Genius',
director: 'Chloe Yan',
role: 'Executive Director',
@ -15,7 +15,7 @@ const orgs = [
'Girl Genius Magazine is a fully student-run publication inspiring the next generation of female and non-binary leaders in STEAM. Their journalism and inclusive online community are dedicated to breaking down techs lingering gender barriers. Becoming fiscally sponsored allowed them to publish more issues, host over 40 workshops, organize a conference, and reach a global audience of 11k readers (and counting).'
},
{
logo: '/bank/nonprofits/techshift.png',
logo: '/hcb/nonprofits/techshift.png',
transparency: 'techshift',
name: 'TechShift',
director: 'Daniel Jin',
@ -23,10 +23,10 @@ const orgs = [
budget: 100,
website: 'techshift.org',
description:
'Founded in 2017, TechShift supports a network of 30+ student-run chapters across 3 continents leading initiatives at the intersection of technology and social impact. With the help of Hack Club Bank, they are bringing about a more equitable technological future through their mentorship programs, community partnerships, microgrants, and the STEM For Social Good Toolkit.'
'Founded in 2017, TechShift supports a network of 30+ student-run chapters across 3 continents leading initiatives at the intersection of technology and social impact. With the help of HCB, they are bringing about a more equitable technological future through their mentorship programs, community partnerships, microgrants, and the STEM For Social Good Toolkit.'
},
{
logo: '/bank/nonprofits/projectboom.jpg',
logo: '/hcb/nonprofits/projectboom.jpg',
transparency: 'projectboom',
name: 'Project Boom',
director: 'Kunal Botla',
@ -36,10 +36,10 @@ const orgs = [
website: 'projectboom.org',
url: 'https://projectboom.org/',
description:
'Project Boom is a student-led organization with a simple mission: getting computers to those who need them. Instead of becoming e-waste, old machines are given new life to deserving students worldwide. Joining Hack Club Bank provided Project Boom with a platform to easily accept and manage donations, helping them to repair and ship more computers than ever before.'
'Project Boom is a student-led organization with a simple mission: getting computers to those who need them. Instead of becoming e-waste, old machines are given new life to deserving students worldwide. Joining HCB provided Project Boom with a platform to easily accept and manage donations, helping them to repair and ship more computers than ever before.'
},
{
logo: '/bank/nonprofits/executebig.png',
logo: '/hcb/nonprofits/executebig.png',
name: 'Execute Big',
director: 'Mingjie Jiang',
role: 'Co-Executive Director',
@ -47,7 +47,7 @@ const orgs = [
budgetLabel: 'funded',
website: 'executebig.org',
description:
'Execute Big began by using leftover hackathon funds to provide travel grants for students. Hack Club Bank helped make possible their array of grants, fellowships, and innovative programs to share computer science with students nationally. Now their own 501(c)(3) nonprofit, they leverage existing resources to make STEM activities accessible to everyone.'
'Execute Big began by using leftover hackathon funds to provide travel grants for students. HCB helped make possible their array of grants, fellowships, and innovative programs to share computer science with students nationally. Now their own 501(c)(3) nonprofit, they leverage existing resources to make STEM activities accessible to everyone.'
}
]
@ -68,9 +68,8 @@ export default function Nonprofits() {
>
<Heading variant="title">Nonprofit? No problem.</Heading>
<Text variant="lead" color="muted">
Hack Club Bank is a powerful, safe, and easy-to-use financial
platform, whether you're receiving your first donation or spending
$100,000 a year.
HCB is a powerful, safe, and easy-to-use money thing, whether you're
receiving your first donation or spending $100,000 a year.
</Text>
</Container>

View file

@ -22,12 +22,12 @@ export default function Run() {
>
<Container maxWidth={28} sx={{ mx: 0, py: 4 }}>
<Text variant="heading" sx={{ fontSize: 48 }}>
Bank doesnt stop at closing ceremony.
HCB doesnt stop at closing ceremony.
</Text>
<br />
<Text variant="lead" sx={{ color: 'muted', fontSize: 28 }}>
Receiving and managing money is just the start. Hack Club Bank helps
you handle ongoing obligations while youre organizing.
Receiving and managing money is just the start. HCB helps you handle
ongoing obligations while youre organizing.
</Text>
</Container>
<List>

View file

@ -18,7 +18,7 @@ export default function Start({ stats }) {
}}
>
<Heading variant="ultratitle" color="white">
Sign up for Hack&nbsp;Club&nbsp;Bank.
Sign up for HCB.
</Heading>
<Text color="muted" variant="lead" m="0 !important">
Open to Hack Clubs, hackathons, and charitable organizations in
@ -32,8 +32,8 @@ export default function Start({ stats }) {
>
<ApplyButton />
<Text color="muted" sx={{ fontSize: 18 }}>
We run Hack Club HQ on Bank!{' '}
<Link href="https://bank.hackclub.com/hq" color="primary">
We run Hack Club HQ on HCB!{' '}
<Link href="https://hcb.hackclub.com/hq" color="primary">
See&nbsp;our&nbsp;finances.
</Link>
</Text>

View file

@ -102,7 +102,7 @@ const Stats = ({ stats }) => {
}
export async function getStaticProps(context) {
const res = await fetch(`https://bank.hackclub.com/stats`)
const res = await fetch(`https://hcb.hackclub.com/stats`)
const stats = await res.json()
return {

View file

@ -22,7 +22,7 @@ const events = [
budget: 15,
attendees: 115,
testimonial:
'For me, Hack Club Bank unlocked organizing hackathons. Even after as a club leader, raising money seemed insurmountable. Bank directly enabled organizing events in my community with event bank accounts & a supportive community. I couldnt recommend it more highly.'
'For me, HCB unlocked organizing hackathons. Even after as a club leader, raising money seemed insurmountable. HCB directly enabled organizing events in my community with event bank accounts [sic] & a supportive community. I couldnt recommend it more highly.'
},
{
name: 'Teenhacks LI',
@ -31,7 +31,7 @@ const events = [
budget: 35,
attendees: 300,
testimonial:
'For our hackathon, Hack Club Bank has given us the tools to make sure our organization is professional with sponsors. Bank and their team have created an easily manageable resource to make sure any event is run successfully. We would highly recommend any organization be a part of the Hack Club ecosystem.'
'For our hackathon, HCB has given us the tools to make sure our organization is professional with sponsors. HCB and their team have created an easily manageable resource to make sure any event is run successfully. We would highly recommend any organization be a part of the Hack Club ecosystem.'
},
{
transparency: 'mahacks',
@ -41,7 +41,7 @@ const events = [
budget: 10,
attendees: 70,
testimonial:
'Hack Club Bank removed the barriers to starting fundraising for MAHacks. In mere days, vs months of nonprofit paperwork, Bank enabled my team to invoice sponsors professionally and manage our finances on a clear, up-to-date dashboard. I highly recommend using Bank & joining the Hack Club community.'
'HCB removed the barriers to starting fundraising for MAHacks. In mere days, vs months of nonprofit paperwork, HCB enabled my team to invoice sponsors professionally and manage our finances on a clear, up-to-date dashboard. I highly recommend using HCB & joining the Hack Club community.'
},
{
transparency: 'dv-hacks',
@ -51,7 +51,7 @@ const events = [
budget: 12,
attendees: 150,
testimonial:
'Hack Club Bank is an essential platform for any hackathon organizer! It made us look both professional and credible in front of our sponsors and it relieved us of legal/financial burdens. Hack Club Bank was there for us every step of the way and for a first-year hackathon, that support was priceless.'
'HCB is an essential platform for any hackathon organizer! It made us look both professional and credible in front of our sponsors and it relieved us of legal/financial burdens. HCB was there for us every step of the way and for a first-year hackathon, that support was priceless.'
}
]
@ -69,11 +69,11 @@ export default function Testimonials() {
}}
>
<Heading variant="title">
The best events across the country run on Bank.
The best events across the country run on HCB.
</Heading>
<Text variant="lead" color="muted">
Everywhere from Philadelphia to Phoenix to Portland,
Hack&nbsp;Club&nbsp;Bank powers events of all sizes.
Everywhere from Philadelphia to Phoenix to Portland, HCB powers
events of all sizes.
</Text>
</Container>
<Container
@ -94,9 +94,7 @@ export default function Testimonials() {
>
{events.map(event => {
const id = kebabCase(event.name)
return (
<Event {...event} img={`/bank/events/${id}.jpg`} key={id} />
)
return <Event {...event} img={`/hcb/events/${id}.jpg`} key={id} />
})}
</Grid>
</Container>
@ -208,7 +206,7 @@ function Event({
</Box>
{transparency && (
<Link
href={`https://bank.hackclub.com/${transparency}`}
href={`https://hcb.hackclub.com/${transparency}`}
target="_blank"
rel="noreferrer"
sx={{ mt: ['16px', '0px'] }}

View file

@ -13,7 +13,7 @@ function Step({ stepIndex, label }) {
}}
>
<Image
src={`/bank/timeline-steps/step${stepIndex}.svg`}
src={`/hcb/timeline-steps/step${stepIndex}.svg`}
sx={{ flexShrink: 0 }}
alt=""
/>
@ -32,9 +32,9 @@ function Step({ stepIndex, label }) {
export default function Timeline() {
const labels = [
'Register your organization for Bank',
'Register your organization for HCB',
'Explore the interface in Playground mode',
'Hop on an intro call with the Bank team',
'Hop on an intro call with our team',
'Start fundraising!'
]
const stepSideLength = 64

View file

@ -1,46 +1,51 @@
import React from "react";
import React from 'react'
const addClassNameToChildren = (children, className) => React.Children.map(children, child => React.cloneElement(child, { className: `${child.props.className || ''} ${className}` }));
const addClassNameToChildren = (children, className) =>
React.Children.map(children, child =>
React.cloneElement(child, {
className: `${child.props.className || ''} ${className}`
})
)
const tooltip = (direction) => function Tooltip ({ children, text }) {
const escapedText = text.replace(/'/g, "\\'");
const directionalStyles = ({
e: `
const tooltip = direction =>
function Tooltip({ children, text, id }) {
const escapedText = text.replace(/'/g, "\\'")
const directionalStyles = {
e: `
left: 100%;
bottom: 50%;
right: 0;
margin-left: 0.5rem;
transform: translateY(50%);
`,
w: `
w: `
right: 100%;
bottom: 50%;
margin-right: 0.5rem;
transform: translateY(50%);
`,
n: `
n: `
right: 50%;
bottom: 100%;
margin-bottom: 0.5rem;
transform: translateX(50%);
`,
s: `
s: `
right: 50%;
top: 100%;
margin-top: 0.5rem;
transform: translateX(50%);
`
})[direction || 'e'];
}[direction || 'e']
return (
<>
<style>{`.tooltipped {
<>
<style>{`.tooltipped${id ? '-' + id : ''} {
position: relative;
}
@media (min-width: 56em) {
.tooltipped:after {
.tooltipped${id ? '-' + id : ''}:after {
background-color: rgba(31, 45, 61, 0.875);
border-radius: 0.5rem;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.0625),
@ -68,29 +73,29 @@ const tooltip = (direction) => function Tooltip ({ children, text }) {
}
.tooltipped:hover:after,
.tooltipped:active:after,
.tooltipped:focus:after {
.tooltipped${id ? '-' + id : ''}:hover:after,
.tooltipped${id ? '-' + id : ''}:active:after,
.tooltipped${id ? '-' + id : ''}:focus:after {
opacity: 1;
z-index: 9000000;
backdrop-filter: blur(2px);
}
.tooltipped:after {
.tooltipped${id ? '-' + id : ''}:after {
${directionalStyles}
}
}`}</style>
{children}
</>
);
}
{children}
</>
)
}
const Tooltip = tooltip();
Tooltip.N = tooltip('n');
Tooltip.S = tooltip('s');
Tooltip.E = tooltip('e');
Tooltip.W = tooltip('w');
const Tooltip = tooltip()
Tooltip.N = tooltip('n')
Tooltip.S = tooltip('s')
Tooltip.E = tooltip('e')
Tooltip.W = tooltip('w')
export { Tooltip };
export default Tooltip;
export { Tooltip }
export default Tooltip

View file

@ -1,10 +1,8 @@
import CardModel from './card-model'
import { Box, Flex, Grid, Image, Link, Text } from 'theme-ui'
import { useState, useEffect } from 'react'
import {Box, Flex, Grid, Image, Link, Text} from 'theme-ui'
import Buttons from './button'
import ScrollingHackathons from '../../hackathons/scrolling-hackathons'
import Dot from '../../dot'
import { formatDate } from '../../../lib/dates'
import {formatDate} from '../../../lib/dates'
/** @jsxImportSource theme-ui */
const Cover = () => (

View file

@ -0,0 +1,56 @@
import CardModel from "./card-model";
import { Box, Flex, Grid, Image, Text, Link } from "theme-ui";
import Buttons from "./button";
/** @jsxImportSource theme-ui */
export default function Haunted() {
return (
<CardModel
github_link="https://github.com/hackclub/www-hauntedhouse"
color="white"
sx={{
backgroundSize: "cover",
backgroundColor: "#95C9E5",
border: "2px solid #EB6424",
}}
position={[null, "bottom", "bottom"]}
highlight="#cc5600"
image="/haunted/bg.webp"
filter="brightness(0.7)"
>
<Grid columns={[1, 2]} sx={{ position: "relative", zIndex: 2 }}>
<Image
src="/haunted/haunted-text.svg"
sx={{
width: ["200px", "250px", "300px"],
mt: ["-10px", "-20px", "-20px"],
position: "relative",
zIndex: 2,
fontSize: ["36px", 4, 5],
color: "white",
}}
alt="Haunted"
/>
<Box></Box>
<Text as="p" variant="subtitle" sx={{ color: 'white' }}>
Haunted House is a Chicago-based event full of sites and frights! Join us from October 28-29
for a weekend of coding pushing the bounds of creativity, where fright meets byte!
</Text>
<Flex
sx={{
flexDirection: "column",
mt: [3, 3, 4],
alignItems: "end",
justifyContent: "flex-end",
}}
></Flex>
<Buttons id="14" link="https://haunted.hackclub.com" icon="welcome" primary="#EB6424">
Sign Up
</Buttons>
</Grid>
</CardModel>
);
}

View file

@ -1,15 +1,13 @@
import CardModel from './card-model'
import { Box, Flex, Grid, Image, Link, Text } from 'theme-ui'
import { Box, Flex, Grid, Text } from 'theme-ui'
import Buttons from './button'
import styled from '@emotion/styled'
import RelativeTime from 'react-relative-time'
/** @jsxImportSource theme-ui */
export default function Haxidraw() {
export default function Haxidraw({ stars }) {
return (
<CardModel
github_link="https://github.com/hackclub/haxidraw/"
github_link="https://github.com/hackclub/blot/"
color="white"
sx={{
backgroundSize: 'cover',
@ -17,11 +15,12 @@ export default function Haxidraw() {
backgroundImage: `linear-gradient(120deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.9) 30%, rgba(0, 0, 0, 0.4) 70%), url('https://cloud-1tnl6uqvw-hack-club-bot.vercel.app/0image.png')`
}}
position={[null, 'bottom', 'bottom']}
highlight="#271932"
highlight="#2b27f8d9"
filter="brightness(0.8)"
stars={stars}
>
<Text variant="title" as="h3" sx={{ fontSize: ['36px', 4, 5] }}>
Haxidraw
Blot
</Text>
<Grid columns={[1, 2]}>
<Box>
@ -30,7 +29,7 @@ export default function Haxidraw() {
variant="subtitle"
sx={{ zIndex: 2, position: 'relative' }}
>
Haxidraw is a W.I.P. open source drawing machine and online editor,
Blot is an open source drawing machine and online editor,
designed to be a fun and beginner friendly introduction to digital
fabrication and generative art.
</Text>
@ -40,7 +39,7 @@ export default function Haxidraw() {
<Buttons
id="51"
icon="align-left"
link="https://haxidraw.hackclub.com"
link="https://blot.hackclub.dev"
primary="rgba(255, 255, 255, 0.9)"
sx={{ color: 'black' }}
>
@ -49,7 +48,7 @@ export default function Haxidraw() {
<Buttons
id="52"
icon="code"
link="https://haxidraw.hackclub.dev"
link="https://blot.hackclub.dev/editor"
primary="rgba(255, 255, 255, 0.9)"
sx={{ color: 'black' }}
>

View file

@ -26,13 +26,13 @@ export default function Bank({ data }) {
variant="title"
sx={{ color: 'red', fontSize: ['36px', 4, 5], mt: [0, 3] }}
>
Hack&nbsp;Club&nbsp;Bank
HCB
</Heading>
<Grid columns={[1, '1.3fr 1fr', 2]}>
<Box>
<Text as="p" variant="subtitle">
Become a 501(c)3 nonprofit and join 700+ teams using
Hack&nbsp;Club Bank to run world-class events.
Become a 501(c)3 nonprofit and join 700+ teams using HCB to run
world-class events.
</Text>
<Text as="p" variant="subtitle">
This platform is built and maintained by the Hack&nbsp;Club team.
@ -40,11 +40,11 @@ export default function Bank({ data }) {
<Buttons
id="27"
icon="bank-account"
link="/bank"
link="/hcb"
primary="red"
sx={{ mt: [0, 2, 3] }}
>
Start banking!
Start fundraising!
</Buttons>
<Box
sx={{
@ -64,7 +64,7 @@ export default function Bank({ data }) {
textAlign: 'center',
'&:before': {
content: '""',
backgroundImage: 'url(/home/bank-mobile.webp)',
backgroundImage: 'url(/home/hcb-mobile.webp)', // image doesn't exist
backgroundSize: '100%',
backgroundRepeat: 'no-repeat',
width: '100%',
@ -76,7 +76,7 @@ export default function Bank({ data }) {
>
{/* <Box
sx={{
backgroundImage: 'url(/home/bank-screen.webp)',
backgroundImage: 'url(/home/hcb-screen.webp)',
zIndex: 2,
position: 'absolute',
margin: 'auto',
@ -112,7 +112,7 @@ export default function Bank({ data }) {
textAlign: 'center',
'&:before': {
content: '""',
backgroundImage: 'url(/home/bank.webp)',
backgroundImage: 'url(/home/hcb.webp)',
backgroundSize: '100%',
backgroundRepeat: 'no-repeat',
width: '100%',
@ -124,7 +124,7 @@ export default function Bank({ data }) {
>
{/* <Box
sx={{
backgroundImage: 'url(/home/bank-screen.webp)',
backgroundImage: 'url(/home/hcb-screen.webp)',
zIndex: 2,
position: 'absolute',
margin: 'auto',

View file

@ -1,19 +1,12 @@
import Icon from '@hackclub/icons'
import { useRef, useState } from 'react'
import {
Box,
Label,
Input,
Button,
Text,
Alert,
Card,
Flex,
Grid
} from 'theme-ui'
import CardModel from './card-model'
import { useEffect, useRef, useState } from 'react'
import { Box, Button, Card, Flex, Grid, Input, Link, Text } from 'theme-ui'
import { format, parse } from 'date-fns'
import BGImg from '../../background-image'
import FooterImgFile from '../../../public/home/footer.png'
import background from '../../../public/home/footer.png'
import MailCard from '../../mail-card'
const markdownToHtml = require('@hackclub/markdown')
const Loading = () => (
<Box
@ -21,18 +14,17 @@ const Loading = () => (
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
width: '100%',
border: '2px solid #f3f3f3',
borderTop: '2px solid #ec3750',
borderRadius: '50%',
width: '10px',
height: '10px',
width: '16px',
height: '16px',
animation: 'spin 2s linear infinite',
mr: '5px',
'@keyframes spin': {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' }
}
'100%': { transform: 'rotate(360deg)' },
},
}}
></Box>
)
@ -40,21 +32,22 @@ const Loading = () => (
const MailingList = () => {
const [submitting, setSubmitting] = useState(false)
const [submitted, setSubmitted] = useState(false)
const [data, setData] = useState({ finalHtml: [], names: [] })
const formRef = useRef(null)
const handleSubmit = async e => {
const handleSubmit = async (e) => {
e.preventDefault()
setSubmitting(true)
let res = await fetch('/api/mailing-list', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: e.target.name.value,
email: e.target.email.value
})
email: e.target.email.value,
}),
})
formRef.current.reset()
@ -65,99 +58,170 @@ const MailingList = () => {
setSubmitting(false)
}
// This lovely concoction of JavaScript basically fetches the last two newsletters from the GitHub repo,
// converts them to HTML, gets rid of those HTML tags, the sets all of that as the state of the component.
// Then, It makes a second fetch request to get the filename, so that can be used to determine the link.
// After that, it removes the file extension, so we can use that as the date.
// Finally, it sets the state of data to the final HTML and the names of the files, so we can map that later on!
useEffect(() => {
Promise.all([
fetch('https://api.github.com/repos/hackclub/leaders-newsletter/contents/updates')
.then(response => response.json())
.then(data => data.sort((a, b) => b.name.localeCompare(a.name))) // Makes sure we only get the latest two newsletters
.then(data => data.slice(0, 2))
.then(data => Promise.all(data.map(item => fetch(item.download_url)))) // Makes a separate fetch request for the content of each newsletter
.then(responses => Promise.all(responses.map(response => response.text())))
.then(markdown => Promise.all(markdown.map(markdown => markdownToHtml(markdown))))
.then(html => html.map(html => html.replace(/<[^>]*>/g, '').replace(/The Hackening/g, ''))), // Chucks out all html tags + 'The Hackening'
fetch('https://api.github.com/repos/hackclub/leaders-newsletter/contents/updates')
.then(response => response.json())
.then(data => data.sort((a, b) => b.name.localeCompare(a.name)))
.then(data => data.map(item => item.name.split('.')[0])) // Grabs the name and gets rid of the file extension
])
.then(([finalHtml, names]) => setData({ finalHtml, names }))
}, [])
return (
<Box sx={{ position: 'relative', py: 6, background: 'darker' }}>
<Card
sx={{
maxWidth: 'narrowPlus',
maxWidth: '1050px',
mx: 'auto',
// mt: [3, 4],
background: 'rgb(255,255,255, 0.45)',
position: 'relative',
zIndex: 2,
backdropFilter: 'blur(8px)'
backdropFilter: 'blur(8px)',
}}
>
<Flex
sx={{
justifyContent: 'space-between',
alignItems: ['left', 'left', 'center'],
flexDirection: ['column', 'column', 'column'],
gap: '10px',
textAlign: 'center'
}}
>
<Box>
<Text
variant="title"
sx={{ fontSize: [4, '36px', '42px', 6], zIndex: 2 }}
>
Stay in Touch
</Text>
<Text sx={{ color: 'darkless', mt: 2, fontSize: 3 }} as="p">
Well send you an email no more than once a month, when we work on
something cool for you.
</Text>
</Box>
<Grid
as="form"
ref={formRef}
onSubmit={handleSubmit}
gap={[2, 3]}
<Flex sx={{ flexDirection: ['column', 'column', 'row'], gridGap: [0, 5] }}>
<Flex
sx={{
textAlign: 'center',
alignItems: 'end',
input: { bg: 'sunken' },
width: '100%'
placeItems: 'center',
justifyContent: 'center',
alignItems: ['left', 'left', 'center'],
flexDirection: 'column',
gap: '10px',
width: ['100%', '100%', '75%'],
}}
>
<Box sx={{ width: '100%' }}>
<Input
autofillBackgroundColor="highlight"
type="text"
name="name"
id="name"
placeholder="Your Name"
required
sx={{ width: '100%', textAlign: 'center', fontSize: 2 }}
/>
<Box>
<Text
variant='title'
sx={{
fontSize: [4, '36px', '42px', 6],
zIndex: 2,
textAlign: 'left',
}}
>
Join the newsletter
</Text>
<Text
sx={{
color: 'darkless',
mt: 2,
fontSize: 3,
textAlign: 'left',
}}
as='p'
>
We&apos;ll send you an email no more than once a month, when we work
on something cool for you. Check out our{' '}
<Link
href='https://workshops.hackclub.com/leader-newsletters/'
target='_blank'
rel='noopener norefferer'
>
previous issues
</Link>.
</Text>
</Box>
<div>
<Input
autofillBackgroundColor="highlight"
type="email"
name="email"
id="email"
placeholder="Your Email"
required
sx={{ width: '100%', textAlign: 'center', fontSize: 2 }}
<Grid
as='form'
ref={formRef}
onSubmit={handleSubmit}
gap={[2, 3]}
sx={{
textAlign: 'center',
alignItems: 'end',
input: { bg: 'sunken' },
width: '100%',
}}
>
<Box sx={{ width: '100%' }}>
<Input
autofillBackgroundColor='highlight'
type='text'
name='name'
id='name'
placeholder='Your Name'
required
sx={{
width: '100%',
textAlign: 'center',
fontSize: 2,
}}
/>
</Box>
<div>
<Input
autofillBackgroundColor='highlight'
type='email'
name='email'
id='email'
placeholder='Your Email'
required
sx={{
width: '100%',
textAlign: 'center',
fontSize: 2,
}}
/>
</div>
<Button type='submit' sx={{ mt: [2, 0], fontSize: 2 }}>
{submitting ? (
<>
<Loading /> Subscribe
</>
) : submitted ? (
<>
<Icon glyph='send' /> You're on the list!
</>
) : (
'Subscribe'
)}
</Button>
</Grid>
</Flex>
<Box
sx={{
display: 'grid',
gridGap: 4,
mt: [4, 0],
width: '100%',
}}
>
{data.finalHtml.map((html, index) => (
<MailCard
issue={index + 1}
body={html}
date={format(parse('', '', new Date(data.names[index])), 'MMMM d, yyyy')}
link={data.names[index]}
key={index}
/>
</div>
<Button type="submit" sx={{ mt: [2, 0], fontSize: 2 }}>
{submitting ? (
<>
<Loading />
&nbsp;Subscribe
</>
) : (
'Subscribe'
)}
</Button>
</Grid>
)).reverse()}
</Box>
</Flex>
{submitted && (
<Alert variant="primary" sx={{ bg: 'green', mt: [2, 3] }}>
<Icon glyph="send" />
<Text sx={{ ml: 2 }}>You're on the list!</Text>
</Alert>
)}
</Card>
<BGImg
gradient="linear-gradient(rgba(0,0,0,0.125), rgba(0,0,0,0.25))"
src={FooterImgFile}
placeholder="blur"
alt="Globe with hundreds of Hack Clubs"
width={2544}
height={2048}
gradient='linear-gradient(rgba(0,0,0,0.125), rgba(0,0,0,0.25))'
src={background}
placeholder='blur'
alt='Globe with hundreds of Hack Clubs'
/>
</Box>
)

View file

@ -0,0 +1,94 @@
import {useEffect, useState} from 'react'
import {Box, Flex, Grid, Text} from 'theme-ui'
import CardModel from './card-model'
import Buttons from './button'
/** @jsxImportSource theme-ui */
export default function Onboard({ stars }) {
const [projects, setProjects] = useState(0)
useEffect(() => {
fetch(
'https://api.github.com/search/issues?q=repo:hackclub/onboard+is:pr+is:merged+label:Submission',
)
.then((response) => response.json())
.then((data) => setProjects(data.total_count))
}, [])
return (
<CardModel
sx={{
backgroundColor: 'rgba(0,0,0)',
backgroundImage: `linear-gradient(120deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.8) 20%, rgba(0, 0, 0, 0.4) 50%), url('https://cloud-fyrwj5rn5-hack-club-bot.vercel.app/0pcb.svg')`,
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
}}
github_link='https://github.com/hackclub/onboard/'
color='white'
highlight='#87ffa1'
stars={stars}
>
<Text
variant='title'
as='h3'
sx={{
fontSize: ['36px', 4, 5],
maxWidth: 'copyPlus',
textShadow: '0 0 30px rgba(42, 252, 88, 0.6)',
color: '#87ffa1',
mt: ['38px', 0, 0],
position: 'relative',
}}
>
OnBoard
</Text>
<Grid columns={[1, 2]}>
<Box>
<Text
as='p'
variant='subheadline'
sx={{
px: 2,
py: 1,
width: 'fit-content',
borderRadius: 'extra',
border: 'rgba(255,255,255,0.2) dashed 1px',
zIndex: 2,
color: 'white',
position: ['absolute', 'relative', 'relative'],
top: ['24px', 0, '5px']
}}
>
{projects} projects built
</Text>
<Text as='p' variant='subtitle'>
Circuit boards are magical. You design one, we'll print it.
Completely for free! Get a $100 grant to fuel the creation of your dream
project with OnBoard.
</Text>
</Box>
<Flex
sx={{ flexDirection: 'column', mt: [3, 3, 4], placeSelf: 'start' }}
>
<Buttons
id='59'
icon='emoji'
link='https://github.com/hackclub/OnBoard/blob/main/README.md'
primary='#87ffa1'
color='black'
>
Get a grant
</Buttons>
<Buttons icon='docs' link='https://jams.hackclub.com/tag/pcb' id='60'>
Learn how to design a PCB
</Buttons>
<Buttons icon='friend' link='/slack?event=onboard' id='61'>
See what other hackers have built
</Buttons>
</Flex>
</Grid>
</CardModel>
)
}

View file

@ -39,28 +39,13 @@ export default function Outernet() {
28th to 31st July, 2023!
</Text>
<Flex
sx={{ flexDirection: 'column', mt: [3, 3, 4], alignItems: 'end', justifyContent: 'flex-end' }}
>
<Buttons
icon="event-add"
href="https://outernet.hackclub.com/"
target="_blank"
rel="noopener"
primary="#484137"
id="43"
>
Join us
</Buttons>
<Buttons
icon="event-add"
href="https://github.com/hackclub/outernet/#readme"
target="_blank"
rel="noopener"
id="44"
>
Create a guild
</Buttons>
</Flex>
sx={{
flexDirection: 'column',
mt: [3, 3, 4],
alignItems: 'end',
justifyContent: 'flex-end'
}}
></Flex>
{/* <Box sx={{ mt: ['-40px', '-40px', '-150px'] }}>

View file

@ -0,0 +1,72 @@
import CardModel from './card-model'
import { Box, Button, Flex, Grid, Image, Text } from 'theme-ui'
import Buttons from './button'
/** @jsxImportSource theme-ui */
export default function Pizza() {
return (
<CardModel
color="white"
sx={{
backgroundSize: 'cover',
backgroundColor: '#95C9E5',
border: "1px solid #EC3750" // Corrected the color value here
}}
position={[null, 'bottom', 'bottom']}
highlight="#271932"
image="https://cloud-4f5ohtb3u-hack-club-bot.vercel.app/0subtlegrain.png"
>
<Grid columns={[1, 2]} sx={{ position: 'relative', alignItems: "center", zIndex: 2 }}>
<Box>
<Text
as="h3"
variant="title"
sx={{
fontSize: ['36px', 4, 5],
zIndex: 2,
color: "#000",
mb: "8px"
}}
>
Start A Hack Club <br/> Get <Text
sx={{
background: ["linear-gradient(180deg, #FF8C37 25%, #EC3750 100%)"],
WebkitBackgroundClip: "text",
WebkitTextStroke: 'currentColor',
WebkitTextFillColor: 'transparent',
}}
> $100 In Pizza</Text>
</Text>
<Text as="p" variant="subtitle" sx={{ color: '#000', mb: 3 }}>
GitHub is providing $100 pizza grants to every teen who starts a Hack Club at their school.
</Text>
<Buttons id="14" link="/pizza" icon="welcome" primary="primary">
Get Your Pizza Grant
</Buttons>
</Box>
<Box>
<Flex
sx={{
flexDirection: 'column',
alignItems: 'end',
justifyContent: 'flex-end',
position: "relative"
}}
>
<Image alt="Group of teenage hackers enjoying GitHub Hack Club Pizza Grant" sx={{borderRadius: "16px",
border: "1px solid #EC3750",
aspectRatio: "16/9", objectFit: "cover"}} src="https://cloud-8tc8qa1ew-hack-club-bot.vercel.app/0img_8975.jpg"/>
<Text sx={{color: "#000", backgroundColor: "#fff", left: "16px", bottom: "16px", padding: "6px 8px", borderRadius: "16px", position: "absolute"}}>Newton South HS Hack Club in Boston</Text>
</Flex>
</Box>
</Grid>
</CardModel>
)
}

View file

@ -1,4 +1,4 @@
import { Box, Grid, Image, Text } from 'theme-ui'
import {Box, Grid, Image, Text} from 'theme-ui'
import Buttons from './button'
import CardModel from './card-model'
import Tilt from '../../tilt'
@ -53,16 +53,16 @@ export default function SprigConsole({ stars, consoleCount }) {
sx={{
px: 2,
py: 1,
mt: 2,
width: 'fit-content',
borderRadius: 'extra',
color: 'white',
border: 'rgba(255,255,255,0.2) dashed 1px',
zIndex: 2,
position: ['absolute', 'relative', 'relative'],
top: ['24px', 0, '5px']
}}
>
{420 - consoleCount} consoles left
Join the other {consoleCount} teenagers with Sprigs!
</Text>
<Grid
columns={[1, 1, '1.2fr 1fr', '1.2fr 1fr']}

View file

@ -159,7 +159,7 @@ function Game({ game, gameImage, gameImage1, ...props }) {
mb: 1
}}
>
<RelativeTime value={game?.addedOn} titleFormat="YYYY-MM-DD" />
<RelativeTime value={game['added on']} titleFormat="YYYY-MM-DD" />
</Text>
</Box>
</Box>

View file

@ -8,6 +8,7 @@ export default function GitHub({
key,
text,
time,
url,
message,
opacity,
url,

View file

@ -55,4 +55,4 @@ Growing fast, we currently work with 10,000 - 20,000 teens in 36 states and 22 c
Located in the heart of Shelburne, Vermont.
Check out the [Hack Club philosophy](https://hackclub.com/philosophy/), our [code of conduct](https://hackclub.com/conduct/), and our real-time [transparent finances](https://bank.hackclub.com/hq).
Check out the [Hack Club philosophy](https://hackclub.com/philosophy/), our [code of conduct](https://hackclub.com/conduct/), and our real-time [transparent finances](https://hcb.hackclub.com/hq).

View file

@ -2,33 +2,33 @@ _As of June 2021, this position has been filled._
At [Hack Club](https://hackclub.com), a 501(c)(3) nonprofit in Shelburne, Vermont, we're building the program we wish we had in high school: a space for [high school hackers](https://en.wikipedia.org/wiki/Hacker_ethic).
As part of this, we're seeking to hire a full-time Bank Operations Assistant to report to the [Bank Operations Lead](https://hackclub.com/jobs/bank-ops-lead/) and join our team of 8 at HQ to support growth of one of our key programs.
As part of this, we're seeking to hire a full-time HCB Operations Assistant to report to the [HCB Operations Lead](https://hackclub.com/jobs/hcb-ops-lead/) and join our team of 8 at HQ to support growth of one of our key programs.
**Title:** Hack Club Bank Operations Associate
**Title:** HCB Operations Associate
**Job Description:**
[Hack Club Bank](https://medium.com/hackclub/hack-club-bank-is-now-live-for-everyone-including-you-884f7f54836f) is our in-house financial software used by 1,500 Hack Clubbers to financially power their Hack Clubs, hackathons, and student-organized nonprofits. When teenagers use Hack Club Bank, we act as their backing financial and legal entity, allowing them to leverage our 501(c)(3) nonprofit status to receive donations and use our beautiful in-house software to manage and spend their funds.
[HCB](https://medium.com/hackclub/hack-club-bank-is-now-live-for-everyone-including-you-884f7f54836f) is our in-house financial software used by 1,500 Hack Clubbers to financially power their Hack Clubs, hackathons, and student-organized nonprofits. When teenagers use HCB, we act as their backing financial and legal entity, allowing them to leverage our 501(c)(3) nonprofit status to receive donations and use our beautiful in-house software to manage and spend their funds.
Recently, we've made the decision to open up Hack Club Bank to anyone looking to power their nonprofit. We have nearly 300 various organizations and events that have partnered with Hack Club Bank within the last 3 years and we're gearing up to grow substantially.
Recently, we've made the decision to open up HCB to anyone looking to power their nonprofit. We have nearly 300 various organizations and events that have partnered with HCB within the last 3 years and we're gearing up to grow substantially.
As the first full-time addition to the Bank Operations team, your role will be to partner with the Bank Operations Lead on managing our fiscal sponsorship program. You will assist with onboarding new nonprofits, daily backend operations, and providing world class support. Large or small, each organization partnering with Hack Club Bank is given exceptional white glove treatment.
As the first full-time addition to the HCB Operations team, your role will be to partner with the HCB Operations Lead on managing our fiscal sponsorship program. You will assist with onboarding new nonprofits, daily backend operations, and providing world class support. Large or small, each organization partnering with HCB is given exceptional white glove treatment.
You will report to the Bank Operations Lead but will have autonomy over your work day. Each staff member that joins Hack Club is expected to manage their own workload and manage up when they require assistance.
You will report to the HCB Operations Lead but will have autonomy over your work day. Each staff member that joins Hack Club is expected to manage their own workload and manage up when they require assistance.
A typical day with Hack Club Bank may look like this:
A typical day with HCB may look like this:
- Responding to various Bank user support requests. Users may contact us via email, Slack, texting, and phone calls. How you manage your response time is up to you but we require a 24hr turn-around time frame on weekdays. Requests that come in over the weekend are expected to be responded to on the following Monday.
- Responding to various HCB user support requests. Users may contact us via email, Slack, texting, and phone calls. How you manage your response time is up to you but we require a 24hr turn-around time frame on weekdays. Requests that come in over the weekend are expected to be responded to on the following Monday.
- Process new applications and set up onboarding calls if appropriate.
- Video calls with Bank users and prospective Bank users.
- Video calls with HCB users and prospective HCB users.
- Daily backend transaction categorization and management. Money doesn't move in Hack Club Bank without human approval. Our team is responsible for making sure donations and expenses are mapped to the correct organization.
- Daily backend transaction categorization and management. Money doesn't move in HCB without human approval. Our team is responsible for making sure donations and expenses are mapped to the correct organization.
- Assist with designing new features. We are always looking to add new and exciting features for Bank users and a good portion of our work is assisting with launching these.
- Assist with designing new features. We are always looking to add new and exciting features for HCB users and a good portion of our work is assisting with launching these.
- Eventually you would help manage a new partnership that Hack Club is entering into. This would mean that you would be responsible for all fiscally sponsored organizations coming through this partnership and would report to the Bank Operations Lead.
- Eventually you would help manage a new partnership that Hack Club is entering into. This would mean that you would be responsible for all fiscally sponsored organizations coming through this partnership and would report to the HCB Operations Lead.
A bit of what we think you'll be like:
@ -52,6 +52,6 @@ To apply, email us at <jobs@hackclub.com> with "I will go down with this ship" i
And last, some details on compensation. This role pays between $38K$43K, depending on your experience—and as a nonprofit we know that's probably less than you'd make elsewhere. We offer healthcare and 4 weeks paid vacation.
\- Melanie Smith, Bank Operations Lead, and Zach Latta, Executive Director
\- Melanie Smith, HCB Operations Lead, and Zach Latta, Executive Director
P.S. If you're technical, you can apply by running `$ ssh jobs.hackclub.com` in your terminal.

View file

@ -4,25 +4,25 @@ At [Hack Club](https://hackclub.com), a 501(c)(3) nonprofit, we're building a gi
Alongside the soccer players, theater kids, and band geeks, we aspire to create and foster a new type of teenager: the teenage hacker. Our goal: to become as ubiquitous, as universal, and as culturally foundational for young people today as the Girl and Boy Scouts were 70 years ago.
**Title:** Hack Club Bank Operations Lead
**Title:** HCB Operations Lead
**Job Description:**
[Hack Club Bank](https://hackclub.com/bank/) is our in-house financial software used by 1,500 Hack Clubbers to financially power their Hack Clubs, hackathons, and student-organized nonprofits. When teenagers use Hack Club Bank, we act as their backing financial and legal entity, allowing them to leverage our 501(c)(3) nonprofit status to receive donations and use our beautiful in-house software to manage and spend their funds.
[HCB](https://hackclub.com/hcb/) is our in-house financial software used by 1,500 Hack Clubbers to financially power their Hack Clubs, hackathons, and student-organized nonprofits. When teenagers use HCB, we act as their backing financial and legal entity, allowing them to leverage our 501(c)(3) nonprofit status to receive donations and use our beautiful in-house software to manage and spend their funds.
As our 7th full-time staff member, your role will be to end-to-end own the human operations essential to Hack Club Bank's success, including onboarding video calls with new Hack Clubbers signing up, daily backend transaction categorization and management through our custom software, and providing a world-class customer success experience over Slack and email to Hack Clubbers. In addition to yourself, in this role you will lead 3 current part-time Hack Clubbers - and grow this team - to help you accomplish Hack Club Bank's human operations.
As our 7th full-time staff member, your role will be to end-to-end own the human operations essential to HCB's success, including onboarding video calls with new Hack Clubbers signing up, daily backend transaction categorization and management through our custom software, and providing a world-class customer success experience over Slack and email to Hack Clubbers. In addition to yourself, in this role you will lead 3 current part-time Hack Clubbers - and grow this team - to help you accomplish HCB's human operations.
In addition to leading human operations to provide a world-class and reliable experience for Hack Clubbers, you'll also work closely with engineering to help identify and design new features for Bank.
In addition to leading human operations to provide a world-class and reliable experience for Hack Clubbers, you'll also work closely with engineering to help identify and design new features for HCB.
You will have autonomy in how you make Hack Clubbers happy and how you manage the operations team for maximum impact. A formal list of your responsibilities would be something like:
- End-to-end owning onboarding new Hack Clubbers onto Bank, from designing and maintaining the application flow, to reviewing and making decisions on new applications, to running interview and onboarding video calls, to designing and executing the contract signing flow.
- Daily backend transaction categorization and management. Money doesn't move in Hack Club Bank without human approval and you and your team will be the humans-in-the-loop on all transactions.
- Providing a world-class customer success experience to Hack Clubbers who reach out over Slack and email for help using Bank.
- Leading our student operations team, having daily communication with them, and organizing them for efficient and impactful work. This team has grown Bank from 0 to almost 1,600 users and almost $1 million raised.
- Designing our support systems and processes to more quickly and more meaningfully serve Bank users.
- End-to-end owning onboarding new Hack Clubbers onto HCB, from designing and maintaining the application flow, to reviewing and making decisions on new applications, to running interview and onboarding video calls, to designing and executing the contract signing flow.
- Daily backend transaction categorization and management. Money doesn't move in HCB without human approval and you and your team will be the humans-in-the-loop on all transactions.
- Providing a world-class customer success experience to Hack Clubbers who reach out over Slack and email for help using HCB.
- Leading our student operations team, having daily communication with them, and organizing them for efficient and impactful work. This team has grown HCB from 0 to almost 1,600 users and almost $1 million raised.
- Designing our support systems and processes to more quickly and more meaningfully serve HCB users.
- Thinking ahead, plan, and identify process improvements and product improvements that can be implemented through a combination of human and software effort.
- Be the top point of contact for all things Bank.
- Be the top point of contact for all things HCB.
And a bit of what we suspect you'll be like:
@ -39,8 +39,8 @@ And a bit of what we suspect you'll be like:
To apply, email us at bankalanker@hackclub.com with "through the looking glass" in the subject line. We don't think we'll be able to identify this person just by looking at their resume, so please include 300-400 words on your background relative to this role and why you're interested.
And last, some details on compensation. This role pays between $45K - $55K, depending on your experienceand as a nonprofit we know that's probably less than you'd make elsewhere. We offer healthcare and 4 weeks paid vacation.
And last, some details on compensation. This role pays between $45K - $55K, depending on your experience-and as a nonprofit we know that's probably less than you'd make elsewhere. We offer healthcare and 4 weeks paid vacation.
\- Christina Asquith, COO, Scott Motte, Engineering Manager for Hack Club Bank, and Zach Latta, Executive Director
\- Christina Asquith, COO, Scott Motte, Engineering Manager for HCB, and Zach Latta, Executive Director
P.S. If you're technical, you can apply by running `$ ssh jobs.hackclub.com` in your terminal.

57
components/mail-card.js Normal file
View file

@ -0,0 +1,57 @@
import { Box, Card, Link, Text } from "theme-ui";
export default function MailCard({ body, date, link }) {
body = body.length > 130 ? body.substring(0, 130) + '...' : body
return (
<Card
variant='interactive'
sx={{
cursor: 'pointer',
padding: '0 !important',
}}
>
<Link
href={`https://workshops.hackclub.com/leader-newsletters/${link}`}
sx={{ textDecoration: 'none' }}
target='_blank'
rel='noopener norefferer'
>
<Box
sx={{
height: '90%',
color: 'black',
textDecoration: 'none !important',
}}
>
<Box
sx={{
width: '100%',
height: '10px',
backgroundRepeat: 'repeat-x',
backgroundSize: '100%',
backgroundImage: `url('/letter-pattern.svg')`,
}}
/>
<Box
sx={{
placeItems: 'center',
display: 'grid',
height: '100%',
paddingY: [3, 4, 0],
}}
>
<Box sx={{ px: [3, 4] }}>
<Text>
{date}
<Text sx={{ color: '#8492a6' }}> From Hack Club, to You</Text>
</Text>
<Text as='h2' sx={{ fontWeight: 'normal' }}>
{body}
</Text>
</Box>
</Box>
</Box>
</Link>
</Card>
)
}

View file

@ -44,7 +44,7 @@ const fixed = props =>
const Root = styled(Box)`
position: fixed;
top: 0;
width: 100%;
width: 100vw;
z-index: 1000;
${fixed};
@media print {
@ -98,7 +98,7 @@ const layout = props =>
height: 64px;
font-weight: bold;
font-size: ${theme.fontSizes[2]}px;
width: 100%;
width: 100vw;
max-width: 18rem;
&:not(:last-child) {
border-bottom: 1px solid rgba(48, 48, 48, 0.125);
@ -139,8 +139,8 @@ const Navigation = props => (
<NextLink href="/clubs" passHref>
<Link>Clubs</Link>
</NextLink>
<NextLink href="/bank" passHref>
<Link>Bank</Link>
<NextLink href="/hcb" passHref>
<Link>Fiscal&nbsp;Sponsorship</Link>
</NextLink>
<NextLink href="/hackathons" passHref>
<Link>Hackathons</Link>
@ -149,7 +149,7 @@ const Navigation = props => (
<Link>Slack</Link>
</NextLink>
<Link href="https://scrapbook.hackclub.com/">Scrapbook</Link>
<Link href="https://workshops.hackclub.com/">Workshops</Link>
<Link href="https://jams.hackclub.com/">Jams</Link>
<NextLink href="/onboard" passHref>
<Link>OnBoard</Link>
</NextLink>

View file

@ -12,16 +12,16 @@ import {
import { useRouter } from 'next/router'
import useForm from '../../lib/use-form'
import Submit from '../submit'
import { getCookie, hasCookie } from 'cookies-next';
import { getCookie, hasCookie } from 'cookies-next'
const JoinForm = ({ sx = {} }) => {
const router = useRouter()
const { status, formProps, useField } = useForm('/api/join/', null, {
clearOnSubmit: 5000,
method: 'POST',
initData: hasCookie("continent")
initData: hasCookie('continent')
? {
continent: getCookie("continent"),
continent: getCookie('continent'),
reason: router.query.reason,
event: router.query.event
}
@ -129,10 +129,12 @@ const JoinForm = ({ sx = {} }) => {
as="div"
sx={{ maxWidth: '600px', textAlign: 'center', mb: 2 }}
>
Hold your horses! <b>Our Slack community is for teenagers</b>, and
as such we're really careful about letting adults join. If you feel
you'd have a place here, reach out to{' '}
<Link href="mailto:slack@hackclub.com">slack@hackclub.com</Link>.
Hold your horses! <b>Our Slack community is for minors</b>! To find
out more about what all we do, check out our{' '}
<Link href="https://github.com/hackclub"> Github </Link>. If you're
a parent or educator & want to talk to a member of our team, send us
a email at{' '}
<Link href="mailto:team@hackclub.com">team@hackclub.com</Link>.
</Text>
)}

View file

@ -13,7 +13,7 @@ const Channel = ({ color, channel }) => (
)
const whitelistedChannels = new Set(
`epoch-tx epoch-ba epoch-vt epoch-satellites lounge counttoamillion code scrapbook hq epoch ship welcome confessions lobby question-of-the-day hack-night announcements assemble community leaders bank college-apps cdn present sprig hackathons 8-ball hackathon-organizers zrl-land design ishan-ded apple out-of-context amas batcave matthews-brain-dump memes epoch-bts poll-of-the-day pasture music too-much-information corgi-states-of-hugo gamedev denio-den india linux neighbourhood packages politics sarthaks-dreams fayd-lives-here bayarea reesericdotci celesticide minecraft cabin -코트니- neon replit-embassy the-democratic-peoples-republic-of-yishun scrapbook-dev speedy-diffusion 10-days-in-public orpheus-legion hq-surroundings annοuncements productivity hackathon-grants secret-santa ian-things-ᴛᴍ emojibot hardware-party koggy-woggy surroundings honest-impressions charlie confessions-meta carot-dev wordle pranavs-lair crypto adventofcode cake one-north mayhaps epoch-food-n-fun toby-shenanigans seattle math fishhead lgbtq chars-corner github-embassy project-ideas rant-about-high-school orpheus-show shoutout rust alumni slack-themes 3d-printing art hacktoberfest newsletter india swim`
`epoch-tx epoch-ba epoch-vt epoch-satellites lounge counttoamillion code scrapbook hq epoch ship welcome confessions lobby question-of-the-day hack-night announcements assemble community leaders bank hcb college-apps cdn present sprig hackathons 8-ball hackathon-organizers zrl-land design ishan-ded apple out-of-context amas batcave matthews-brain-dump memes epoch-bts poll-of-the-day pasture music too-much-information corgi-states-of-hugo gamedev denio-den india linux neighbourhood packages politics sarthaks-dreams fayd-lives-here bayarea reesericdotci celesticide minecraft cabin -코트니- neon replit-embassy the-democratic-peoples-republic-of-yishun scrapbook-dev speedy-diffusion 10-days-in-public orpheus-legion hq-surroundings annοuncements productivity hackathon-grants secret-santa ian-things-ᴛᴍ emojibot hardware-party koggy-woggy surroundings honest-impressions charlie confessions-meta carot-dev wordle pranavs-lair crypto adventofcode cake one-north mayhaps epoch-food-n-fun toby-shenanigans seattle math fishhead lgbtq chars-corner github-embassy project-ideas rant-about-high-school orpheus-show shoutout rust alumni slack-themes 3d-printing art hacktoberfest newsletter india swim`
.split(/\s+/gi)
.filter(i => i.length > 0)
)

View file

@ -88,7 +88,7 @@ export default function Signup() {
const handleSubmit = async e => {
e.preventDefault()
await fetch('/api/bank/demo', {
await fetch('/api/hcb/demo', {
method: 'POST',
body: JSON.stringify({
eventName,
@ -109,7 +109,7 @@ export default function Signup() {
<Base
id="form"
method="POST"
action="/api/bank/demo"
action="/api/hcb/demo"
onSubmit={handleSubmit}
>
<Field

View file

@ -142,7 +142,7 @@ export default function InfoGrid() {
}}
>
<Heading variant="headline">
Receive and spend the grant through Hack Club Bank.
Receive and spend the grant through HCB.
</Heading>
<BulletItem iconGlyph="bank-account" iconColor="#5BC0DE">
Full history and balance, viewed on a powerful web dashbaord

View file

@ -34,7 +34,7 @@ function Recap() {
<BreakdownBox
icon="payment-transfer"
text="$250"
description="grants instantly transferred through Hack Club Bank"
description="grants instantly transferred through HCB"
delay="200"
bg="blue"
/>
@ -62,8 +62,8 @@ function Recap() {
</Text>
<Text variant="caption">
While you wait for your hardware, explore and get familiar with
Hack Club Bank with limited access to features until you get
fully activated.
HCB with limited access to features until you get fully
activated.
</Text>
<Signup />
</Card>

View file

@ -8,33 +8,24 @@
"img": "https://cloud-7xyxcf3f6-hack-club-bot.vercel.app/0new_project__3_.png",
"link": "https://jams.hackclub.com"
},
{
"background": "snow",
"titleColor": "dark",
"descriptionColor": "black",
"title": "Putting The \"You\" In CPU",
"description": "Curious exactly what happens when you run a program on your computer? Read this.",
"img": "https://cloud-eg2ex8nol-hack-club-bot.vercel.app/0favicon-on-light-removebg-preview.png",
"link": "https://cpu.land"
},
{
"background": "#000",
"titleColor": "yellow",
"titleColor": "green",
"descriptionColor": "white",
"title": "Sprig",
"description": "Join hundreds of teenagers making tile-based JavaScript games",
"img": "https://emoji.slack-edge.com/T0266FRGM/sprig-dino/6f01fec60b51b343.png",
"link": "https://sprig.hackclub.com"
},
{
"background": "blue",
"titleColor": "white",
"textColor": "white",
"title": "Clubs network",
"description": "Join one of 400+ coding clubs around the world",
"img": "https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-large/1f5fa-fe0f@2x.png",
"link": "/clubs"
},
{
"background": "dark",
"titleColor": "red",
"textColor": "white",
"title": "Hack Club Bank",
"description": "No. 1 fiscal sponsor for teenagers (we crossed $8 million in transactions)",
"img": "https://emoji.slack-edge.com/T0266FRGM/bank-hackclub-dark/8c6f85f387365072.png",
"link": "/bank"
},
{
"background": "snow",
"titleColor": "dark",
@ -53,38 +44,11 @@
"img": "https://emoji.slack-edge.com/T0266FRGM/sinerider/68a0bc1208e885dd.png",
"link": "https://sinerider.com"
},
{
"background": "#2f070c",
"titleColor": "#ec3750",
"textColor": "white",
"title": "The Orpheus Show",
"description": "The podcast about Hack Club and its community",
"img": "https://emoji.slack-edge.com/T0266FRGM/tos-icon/a4b81adea576bceb.png",
"link": "https://podcast.hackclub.com"
},
{
"background": "black",
"titleColor": "yellow",
"textColor": "white",
"title": "High school hackathons",
"description": "🔍 A curated list of high school hackathons with hundreds of events",
"img": "https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-large/1f469-200d-1f4bb@2x.png",
"link": "/hackathons"
},
{
"background": "snow",
"titleColor": "dark",
"descriptionColor": "black",
"title": "Workshops",
"description": "100+ coding workshops to build a project in under an hour",
"img": "https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-large/1f4bb@2x.png",
"link": "https://workshops.hackclub.com"
},
{
"background": "dark",
"titleColor": "green",
"descriptionColor": "white",
"title": "Circuit boards",
"title": "OnBoard",
"description": "Join 1k teens designing PCBs, learning hardware, and building electronics",
"img": "https://cloud-jrox24mrn.vercel.app/orpheus_leap_micro_final.png",
"link": "/onboard"
@ -93,9 +57,10 @@
"background": "dark",
"titleColor": "blue",
"textColor": "white",
"title": "Haxidraw",
"title": "Blot",
"description": "An open source drawing machine and online editor for generative art",
"img": "https://emoji.slack-edge.com/T0266FRGM/tw_pencil2/c6afadc2280e571d.png",
<<<<<<< HEAD
"link": "https://haxidraw.hackclub.com"
},
{
@ -106,5 +71,8 @@
"description": "Our open love letter to hackers",
"img": "https://cloud-gbwqdsj6z-hack-club-bot.vercel.app/0new_piskel-4.png.png",
"link": "/hackers-wanted"
=======
"link": "https://blot.hackclub.dev"
>>>>>>> origin/main
}
]

View file

@ -31,7 +31,7 @@ async function getOrRefreshToken() {
//TODO: Limit the number of retries
export async function search(query) {
if (!query.trim()) return
if (!query || !query.trim()) return
const token = await getOrRefreshToken()
@ -57,7 +57,7 @@ export async function search(query) {
}
export async function geocode(query) {
if (!query.trim()) return
if (!query || !query.trim()) return
const token = await getOrRefreshToken()

View file

@ -180,3 +180,10 @@ export const formatDate = (format, date, divider = ' ') => {
.map(chunk => formatChunk(chunk, new Date(date)))
.join(divider)
}
export const normalizeGitHubCommitUrl = url => {
return url
.replace('api.', '')
.replace('/repos', '')
.replace('commits', 'commit')
}

View file

@ -1,3 +1,3 @@
export const count = 20000
export const count = 27253
export const formatted = count.toLocaleString('en-US')
export const thousands = Math.round(count / 1000)

View file

@ -19,7 +19,7 @@ async function generateSitemap() {
'!pages/api'
])
const rewrites = [
'/bank',
'/hcb',
'/team',
'/map',
'/vip-newsletters',

View file

@ -47,13 +47,17 @@ const useForm = (
},
body: JSON.stringify(data)
})
.then(r => r.json())
.then(r => {
setStatus('success')
if (callback) callback(r)
setTimeout(() => setStatus('default'), 3500)
if (options.clearOnSubmit) {
setTimeout(() => setData({}), options.clearOnSubmit)
.then(async r => {
const response = await r.json()
if (r.ok) {
setStatus('success')
if (callback) callback(r)
setTimeout(() => setStatus('default'), 3500)
if (options.clearOnSubmit)
setTimeout(() => setData({}), options.clearOnSubmit)
} else {
setStatus('error')
console.error(response)
}
})
.catch(e => {

View file

@ -8,8 +8,15 @@ export function middleware(request) {
if (continent === 'Oceania') {
continent = 'Australia'
}
const response = NextResponse.next();
response.cookies.set("continent", continent || "");
return response;
const response = NextResponse.next()
response.cookies.set('continent', continent || '')
return response
}
if (request.nextUrl.pathname === '/donate/') {
return NextResponse.redirect('https://hackclub.com/philanthropy/');
}
return NextResponse.next();
}

View file

@ -1,4 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
eslint: {
ignoreDuringBuilds: true
},
@ -23,11 +25,15 @@ const nextConfig = {
]
},
webpack: (config, { isServer }) => {
if (isServer) require('./lib/sitemap')
return config
},
async redirects() {
return [
{
source: '/bank/:path*',
destination: '/hcb/:path*',
permanent: true
},
{ source: '/grant/', destination: '/hackathons/grant', permanent: false },
{
source: '/sprig/',
@ -202,10 +208,6 @@ const nextConfig = {
source: '/sunsetting-som/',
destination: '/content/sunsetting-som/'
},
{
source: '/bank/apply/success',
destination: '/bank/success'
},
{
source: '/banner/',
destination: 'https://workshops.hackclub.com/banner/'
@ -281,7 +283,13 @@ const nextConfig = {
}
}
const withMDX = require('@next/mdx')({ extension: /\.mdx?$/ })
const withTM = require('next-transpile-modules')(['animejs'])
import million from 'million/compiler'
import withMDX from '@next/mdx'
import withTM from 'next-transpile-modules'
module.exports = withTM(withMDX(nextConfig))
const withMDXConfig = withMDX({ extension: /\.mdx?$/ })
const withAnimeJS = withTM(['animejs'])
export default million.next(withAnimeJS(withMDXConfig(nextConfig)), {
auto: true
})

View file

@ -12,67 +12,79 @@
"format": "prettier --write ."
},
"dependencies": {
"@apollo/client": "^3.7.12",
"@apollo/client": "^3.8.8",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.10.6",
"@emotion/styled": "^11.11.0",
"@github/time-elements": "^4.0.0",
"@hackclub/icons": "^0.0.12",
"@hackclub/icons": "^0.0.14",
"@hackclub/markdown": "^0.0.43",
"@hackclub/meta": "1.1.32",
"@hackclub/theme": "^0.3.3",
"@mdx-js/loader": "^1.6.22",
"@next/mdx": "^13.4.10",
"@octokit/auth-app": "^4.0.9",
"@octokit/core": "^5.0.0",
"@octokit/rest": "^19.0.7",
"@next/mdx": "^14.0.3",
"@octokit/auth-app": "^6.0.1",
"@octokit/core": "^5.0.1",
"@octokit/rest": "^20.0.2",
"add": "^2.0.6",
"airtable-plus": "^1.0.4",
"animated-value": "^0.2.4",
<<<<<<< HEAD
"anime": "^0.1.2",
"animejs": "^3.2.1",
"axios": "^1.4.0",
"cookies-next": "^2.1.2",
"country-list-js": "^3.1.7",
"cursor-effects": "^1.0.11",
=======
"animejs": "^3.2.2",
"axios": "^1.6.2",
"cookies-next": "^4.0.0",
"country-list-js": "^3.1.8",
"cursor-effects": "^1.0.12",
"date-fns": "^2.30.0",
>>>>>>> origin/main
"devtools-detect": "^4.0.1",
"form-data": "^4.0.0",
"fuzzysort": "^2.0.4",
"geopattern": "^1.2.3",
"globby": "^11.0.4",
"graphql": "^16.7.1",
"graphql": "^16.8.1",
"js-confetti": "^0.11.0",
"lodash": "^4.17.21",
"million": "^2.6.4",
"next": "^12.3.1",
"next-auth": "^4.23.1",
"next-transpile-modules": "^10.0.1",
"react": "^17.0.2",
"react-before-after-slider-component": "^1.1.6",
"react-before-after-slider-component": "^1.1.8",
"react-datepicker": "^4.24.0",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.5",
"react-konami-code": "^2.3.0",
"react-marquee-slider": "^1.1.5",
"react-masonry-css": "^1.0.16",
"react-page-visibility": "^7.0.0",
"react-relative-time": "^0.0.7",
"react-relative-time": "^0.0.9",
"react-reveal": "^1.2.2",
"react-scrolllock": "^5.0.1",
"react-snowfall": "^1.2.1",
"react-ticker": "^1.3.2",
"react-tooltip": "^4.5.1",
"react-tsparticles": "^2.12.1",
"react-use-websocket": "^4.3.1",
"react-wrap-balancer": "^1.0.0",
"react-tsparticles": "^2.12.2",
"react-use-websocket": "^4.5.0",
"react-wrap-balancer": "^1.1.0",
"recharts": "2.1.12",
"styled-components": "^6.0.7",
"swr": "^2.2.1",
"styled-components": "^6.1.1",
"swr": "^2.2.4",
"theme-ui": "^0.14",
"tinytime": "^0.2.6",
"turndown": "^7.1.2",
"vanilla-tilt": "^1.8.0",
"yarn": "^1.22.19"
"vanilla-tilt": "^1.8.1",
"yarn": "^1.22.21"
},
"devDependencies": {
"eslint": "8.47.0",
"eslint-config-next": "13.4.12",
"prettier": "^3.0.1"
"eslint": "8.55.0",
"eslint-config-next": "14.0.3",
"prettier": "^3.0.3"
}
}

View file

@ -160,12 +160,12 @@ const Blinking = styled(Heading)`
&:after {
left: 2px;
text-shadow: -2px 0 ${theme.colors.red};
animation: ${animation1} 2s infinite linear alternate-reverse;
animation: ${animation1} 2s infinite steps(2, jump-end) alternate-reverse;
}
&:before {
left: -2px;
text-shadow: -2px 0 ${theme.colors.cyan};
animation: ${animation2} 4s infinite linear alternate-reverse;
animation: ${animation2} 4s infinite steps(2, jump-end) alternate-reverse;
}
`

View file

@ -4,7 +4,7 @@ export async function getGames() {
).then(res => res.json())
games = games
.sort((a, b) => new Date(b.addedOn) - new Date(a.addedOn))
.slice(0, 4)
.slice(-4)
return games
}

View file

@ -1,15 +1,33 @@
const isRelevantEventType = (type) => ['PushEvent', 'PullRequestEvent', 'WatchEvent'].includes(type);
import { normalizeGitHubCommitUrl } from '../../lib/helpers'
const isRelevantEventType = type =>
['PushEvent', 'PullRequestEvent', 'WatchEvent'].includes(type)
const getMessage = (type, payload, repo) => {
switch (type) {
case 'PushEvent':
return payload.commits?.[0]?.message || 'No commit message';
return payload.commits?.[0]?.message || 'No commit message'
case 'PullRequestEvent':
return payload.pull_request.title;
return payload.pull_request.title
case 'WatchEvent':
return `starred ${repo.name}`;
return `starred ${repo.name}`
default:
return null;
return null
}
}
const getUrl = (type, payload, repo) => {
switch (type) {
case 'PushEvent':
return payload.commits?.[0].url
? normalizeGitHubCommitUrl(payload.commits[0].url)
: 'https://github.com/hackclub'
case 'PullRequestEvent':
return payload.pull_request.html_url
case 'WatchEvent':
return `https://github.com/${repo.name}`
default:
return `https://github.com/hackclub`
}
}
@ -27,7 +45,9 @@ const getURL = (type, payload, repo) => {
}
export async function fetchGitHub() {
const initialGitHubData = await fetch('https://api.github.com/orgs/hackclub/events').then(r => r.json());
const initialGitHubData = await fetch(
'https://api.github.com/orgs/hackclub/events'
).then(r => r.json())
const gitHubData = initialGitHubData
.filter(({ type }) => isRelevantEventType(type))
@ -35,15 +55,16 @@ export async function fetchGitHub() {
type,
user: actor.login,
userImage: actor.avatar_url,
url: getUrl(type, payload, repo),
message: getMessage(type, payload, repo),
time: created_at,
url: getURL(type, payload, repo)
}));
return gitHubData;
return gitHubData
}
export default async function github(req, res) {
const git = await fetchGitHub(req, res);
res.json(git);
const git = await fetchGitHub(req, res)
res.json(git)
}

View file

@ -10,10 +10,12 @@ export default async function handler(req, res) {
if (req.method === 'POST') {
const data = req.body
await fetch('https://bank.hackclub.com/api/v1/events/create_demo', {
await fetch('https://hcb.hackclub.com/api/v1/events/create_demo', {
body: JSON.stringify({
email: data.userEmail,
name: data.eventName
name: data.eventName,
transparent: data.transparent,
country: data.eventCountryCode,
}),
method: 'POST',
headers: {
@ -41,23 +43,24 @@ export default async function handler(req, res) {
'Address Country Code': data.addressCountryCode,
'Event Location': data.eventLocation,
'Event Country Code': data.eventCountryCode,
'Have you used Hack Club Bank for any previous events?':
'Have you used HCB for any previous events?':
data.returningUser === 'true'
? 'Yes, I have used Hack Club Bank before'
? 'Yes, I have used HCB before'
: 'No, first time!',
'How did you hear about HCB?': data.referredBy,
Transparent:
data.transparent === 'true' ? 'Yes, please!' : 'No, thanks.',
'HCB account URL': `https://bank.hackclub.com/${r.slug}`,
'HCB account URL': `https://hcb.hackclub.com/${r.slug}`,
'Contact Option': data.contactOption,
'Slack Username': data.slackUsername
'Slack Username': data.slackUsername,
Accommodations: data.accommodations
})
res.writeHead(302, { Location: '/bank/apply/success' }).end()
res.writeHead(302, { Location: '/hcb/apply/success' }).end()
})
.catch(error => {
console.error(error)
res.writeHead(500, {
Location: `/bank/apply?step=3&airtable-error=${error}`
Location: `/hcb/apply?step=3&airtable-error=${error}`
})
})
} else {

View file

@ -1,4 +1,4 @@
// 1. create a demo account on Bank and invite them to it
// 1. create a demo account on HCB and invite them to it
// 2. add this demo account info to the Applications Table
import AirtablePlus from 'airtable-plus'
@ -13,7 +13,7 @@ export default async function handler(req, res) {
if (req.method === 'POST') {
const data = JSON.parse(req.body)
await fetch('https://bank.hackclub.com/api/v1/events/create_demo', {
await fetch('https://hcb.hackclub.com/api/v1/events/create_demo', {
body: JSON.stringify({
email: data.userEmail,
name: data.eventName,
@ -31,7 +31,7 @@ export default async function handler(req, res) {
'Email Address': data.userEmail,
'Event Name': `${data.eventName} (${data.teamType} ${data.teamNumber})`,
Status: 'Demo Account',
'HCB account URL': `https://bank.hackclub.com/${r.slug}`
'HCB account URL': `https://hcb.hackclub.com/${r.slug}`
})
res
.status(200)

View file

@ -24,21 +24,21 @@ async function postData(url = '', data = {}, headers = {}) {
}
export default async function handler(req, res) {
if (req.method === 'OPTIONS') {
return res.status(200).send('YIPPE YAY. YOU HAVE CLEARANCE TO PROCEED.')
}
if (req.method === 'GET') {
return res
.status(405)
.json({ error: '*GET outta here!* (Method not allowed, use POST)' })
}
if (req.method === 'PUT') {
return res.status(405).json({
error: '*PUT that request away!* (Method not allowed, use POST)'
})
}
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed, use POST' })
switch (req.method) {
case 'OPTIONS':
return res.status(200).send('YIPPE YAY. YOU HAVE CLEARANCE TO PROCEED.')
case 'GET':
return res
.status(405)
.json({ error: '*GET outta here!* (Method not allowed, use POST)' })
case 'PUT':
return res.status(405).json({
error: '*PUT that request away!* (Method not allowed, use POST)'
})
case 'POST':
break
default:
return res.status(405).json({ error: 'Method not allowed, use POST' })
}
const data = req.body || {}
@ -48,16 +48,14 @@ export default async function handler(req, res) {
const secrets = (process.env.NAUGHTY || '').split(',')
for (const secret of secrets) {
if (secret === req.headers['x-forwarded-for']) {
return res.json({
status: 'success',
message: 'Youve been invited to Slack!'
})
}
if (secrets.includes(req.headers['x-forwarded-for'])) {
return res.json({
status: 'success',
message: 'Youve been invited to Slack!'
})
}
await joinTable.create({
const airtablePromise = joinTable.create({
'Full Name': data.name,
'Email Address': data.email,
Student: !isAdult,
@ -68,26 +66,33 @@ export default async function handler(req, res) {
IP: req.headers['x-forwarded-for'] || req.socket.remoteAddress
})
if (!waitlist) {
let result = await postData(
'https://toriel.hackclub.com/slack-invite',
{
email: data.email,
ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress,
continent: data.continent,
teen: !isAdult,
educationLevel: data.educationLevel,
reason: data.reason,
event: data.event,
userAgent: req.headers['user-agent']
},
{ authorization: `Bearer ${process.env.TORIEL_KEY}` }
)
res.json({ status: 'success', message: 'Youve been invited to Slack!' })
} else {
res.json({
if (waitlist) {
return res.json({
status: 'success',
message: 'Your request will be reviewed soon.'
})
}
const slackPromise = postData(
'https://toriel.hackclub.com/slack-invite',
{
email: data.email,
ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress,
continent: data.continent,
teen: !isAdult,
educationLevel: data.educationLevel,
reason: data.reason,
event: data.event,
userAgent: req.headers['user-agent']
},
{ authorization: `Bearer ${process.env.TORIEL_KEY}` }
)
Promise.all([airtablePromise, slackPromise])
.then(() =>
res.json({ status: 'success', message: 'Youve been invited to Slack!' })
)
.catch(error => {
res.status(500).json({ error })
})
}

View file

@ -12,12 +12,21 @@ export async function Slack() {
let slackData = await fetch(
"https://hackclub.slack.com/api/team.stats.timeSeries",
{
<<<<<<< HEAD
method: "POST",
body: `--orpheus\r\nContent-Disposition: form-data; name="token"\r\n\r\n${process.env.SLACK_API_TOKEN}\r\n--orpheus\r\nContent-Disposition: form-data; name="date_range"\r\n\r\n30d\r\n--orpheus\r\nContent-Disposition: form-data;`,
headers: {
"content-type": "multipart/form-data; boundary=orpheus",
cookie: process.env.SLACK_API_COOKIE,
},
=======
method: 'POST',
body: `--orpheus\r\nContent-Disposition: form-data; name="token"\r\n\r\n${process.env.SLACK_API_TOKEN}\r\n--orpheus\r\nContent-Disposition: form-data; name="date_range"\r\n\r\n30d\r\n--orpheus\r\nContent-Disposition: form-data;`,
headers: {
'content-type': 'multipart/form-data; boundary=orpheus',
cookie: process.env.SLACK_API_COOKIE
}
>>>>>>> origin/main
}
).then((r) => r.json());

View file

@ -10,13 +10,18 @@ export async function fetchStars() {
sinerider: '?',
sprigHardware: '?',
hackclub: '?',
hackathons: '?'
hackathons: '?',
blot: '?',
onboard: '?'
}
}
const { organization } = await graphql(
`
{
organization(login: "hackclub") {
blot: repository(name: "blot") {
stargazerCount
}
sinerider: repository(name: "sinerider") {
stargazerCount
}
@ -32,6 +37,9 @@ export async function fetchStars() {
sprigHardware: repository(name: "sprig-hardware") {
stargazerCount
}
onboard: repository(name: "onboard") {
stargazerCount
}
}
}
`,

54
pages/api/steve.js Normal file
View file

@ -0,0 +1,54 @@
export default async (req, res) => {
const calendarId = "c_e7c63a427761b0f300ede97f432ba4af24033daad26be86da0551b40b7968f00@group.calendar.google.com";
const apiKey = "AIzaSyD_8dEnTDle3WmaoOTvEW6L1GW540FU_wg"; // Replace with your API Key
let allBusyDays = new Set();
try {
const currentDateTime = new Date();
const adjustedDateTime = new Date(currentDateTime.getTime() + (currentDateTime.getTimezoneOffset() + 240) * 60 * 1000); // Adjust to GMT-04
const startTime = adjustedDateTime.toISOString();
const endTime = new Date(adjustedDateTime.getTime() + 30 * 24 * 60 * 60 * 1000).toISOString();
const response = await fetch(`https://www.googleapis.com/calendar/v3/freeBusy?key=${apiKey}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
timeMin: startTime,
timeMax: endTime,
items: [{ id: calendarId }]
})
});
const data = await response.json();
if (data.error) {
return res.status(400).json({ error: data.error.message });
}
// Assuming there are time ranges where the calendar is busy:
const busyTimes = data.calendars[calendarId].busy;
// For each busy time range, extract all days that are busy:
for (let busy of busyTimes) {
let startDate = new Date(busy.start);
let endDate = new Date(busy.end);
// Adjust dates to GMT-04
startDate = new Date(startDate.getTime() + (startDate.getTimezoneOffset() + 240) * 60 * 1000);
endDate = new Date(endDate.getTime() + (endDate.getTimezoneOffset() + 240) * 60 * 1000);
while (startDate < endDate) {
allBusyDays.add(startDate.toISOString().split('T')[0]);
startDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000); // Adding 24 hours for the next date
}
}
return res.status(200).json([...allBusyDays]);
} catch (error) {
return res.status(500).json({ error: "Failed to fetch busy times." });
}
};

View file

@ -34,7 +34,8 @@ export const Logo = ({ name }) => (
>
{startCase(name)
.replace('Flag Orpheus', 'Orpheus Flag ')
.replace('Bw', ' (B/W)')}
.replace('Bw', ' (B/W)')
.replace('Hcb', 'HCB')}
</Text>
<Grid
columns="repeat(3, 1fr)"
@ -149,6 +150,7 @@ const Page = ({ css }) => (
'flag-orpheus-top-bw',
'flag-orpheus-left-bw',
'flag-standalone-bw',
'flag-standalone-wtransparent',
'icon-rounded',
'icon-square',
'icon-progress-rounded',
@ -168,20 +170,20 @@ const Page = ({ css }) => (
</Button>
<Heading id="bank" variant="headline">
Hack Club Bank Logos
HCB Logos
</Heading>
<Grid columns={[null, 2, 3]} gap={3}>
<Logo name="hack-club-bank-light" />
<Logo name="hack-club-bank-dark" />
<Logo name="hcb-light" />
<Logo name="hcb-dark" />
</Grid>
<Button
as="a"
href="https://bank.hackclub.com/branding"
href="https://hcb.hackclub.com/branding"
variant="outline"
mt={3}
mb={[4, 5]}
>
See all Bank logos
See all HCB logos
</Button>
<Heading id="banners" variant="headline">

View file

@ -96,7 +96,7 @@ const Page = () => (
<>
<Meta
as={Head}
title="Clubs Hack Club"
title="Clubs"
description="Hack Club is a global nonprofit network of high school makers & student-led coding clubs where young people build the agency, the network, & the technical talent to think big & do big things in the world."
image="https://cloud-epiki4yvg.vercel.app/2020-09-09_drbp62kayjuyyy0ek89mf9fwcp5t4kuz.jpeg"
/>
@ -125,13 +125,6 @@ const Page = () => (
alt="Hack Clubbers assemble at Figma HQ for the first IRL hackathon in SF since 2020: Assemble. 📸 Photo by Kunal Botla, Hack Clubber in MA!"
priority
/>
{/* <Announcement
copy="Epoch: celebrate the New Year with Hack Club."
caption="Join 150+ hackers in Delhi for a magical high-school hackathon!"
href="https://epoch.hackclub.com"
iconLeft="explore"
color="primary"
/> */}
<SlideDown duration={768}>
<Heading
@ -346,16 +339,10 @@ const Page = () => (
<NextLink href="/hackathons" passHref>
<a>hackathons</a>
</NextLink>{' '}
like <a href="https://windyhacks.com">Windy&nbsp;City&nbsp;Hacks</a>{' '}
&{' '}
<a href="https://www.sfchronicle.com/bayarea/article/Hack-the-Fog-makes-history-as-San-12729895.php">
Hack the Fog
</a>
, run summer programs like{' '}
<a href="https://web.archive.org/web/20200808171549/http://thecspn.com/?p=43434">
Hack Camp
</a>
, and compete in events like the{' '}
like <a href="https://lioncityhacks.com">Lion City Hacks</a> &{' '}
<a href="https://www.youtube.com/watch?v=Hs-hMMeHXaY">HackOC</a>, take part in year long
programs like <NextLink href="/onboard">OnBoard</NextLink>, and compete in events
like the{' '}
<a href="http://www.congressionalappchallenge.us">
Congressional App Challenge
</a>
@ -479,8 +466,9 @@ const Page = () => (
<>
Come prepared to every meeting with over 100{' '}
<a href="https://workshops.hackclub.com">workshops</a> (3 years
worth!) that guide your club members through making fun,
creative projects.
worth!) and 18 <a href="https://jams.hackclub.com">Jams</a>{' '}
that guide your club members through making fun, creative
projects.
</>
}
></Feature>
@ -516,12 +504,12 @@ const Page = () => (
<Feature
icon="bank-account"
color="black"
name="A nonprofit bank account"
name="A nonprofit fund"
desc={
<>
Use our 501(c)(3) status and a restricted fund with{' '}
<Link href="/bank">Hack Club Bank</Link> to fundraise, accept
donations, buy things!
<Link href="/hcb">HCB</Link> to fundraise, accept donations, and
buy things!
</>
}
/>
@ -712,14 +700,6 @@ const Page = () => (
}
}}
>
<BGImg
width={2544}
height={2048}
gradient="linear-gradient(rgba(0,0,0,0.125), rgba(0,0,0,0.25))"
src={FooterImgFile}
placeholder="blur"
alt="Globe with hundreds of Hack Clubs"
/>
<style>
{`a{
color: #338eda
@ -730,3 +710,4 @@ const Page = () => (
)
export default Page

View file

@ -27,7 +27,7 @@ _(To summarize: were a donor-supported nonprofit so outside of planned grant
[Hack Club](https://hackclub.com/) is an independent nonprofit, supported by donors, with a responsibility to our supporters to spend our budget directly on our core programs. Therefore, as much as wed like to, **were not in a position to provide financial support to hackathons/other nonprofits**. We occasionally run grant programs, like the [$500 grant for IRL high school hackathons](https://hackclub.com/hackathons/grant). We wish you the best of luck in your sponsorship search—we recommend [Megan Cuis “Meginar”](https://youtu.be/tOmXzA4reTY) and [Lachlan Campbells Flagship talk](https://notebook.lachlanjc.com/2020-01-19_how_to_start_your_first_hackathon/) if youre looking for advice.
If youre looking for [fiscal sponsorship](https://en.wikipedia.org/wiki/Fiscal_sponsorship) (aka becoming a legal nonprofit), weve got your back—[Hack Club Bank](https://hackclub.com/bank/) will set you up with a nonprofit bank account, legal entity, debit cards for your team, automated taxes/accounting, G Suite, an online donation form, ACH/check sending/receiving, discounts on stickers & software for your team, and great support. There are no upfront fees. Sign up at <https://hackclub.com/bank/>.
If youre looking for [fiscal sponsorship](https://en.wikipedia.org/wiki/Fiscal_sponsorship) (aka becoming a legal nonprofit), weve got your back—[HCB](https://hackclub.com/hcb/) will set you up with a nonprofit fund, legal entity, debit cards for your team, automated taxes/accounting, G Suite, an online donation form, ACH/check sending/receiving, discounts on stickers & software for your team, and great support. There are no upfront fees. Sign up at <https://hackclub.com/hcb/>.
## If youre running a hackathon…

View file

@ -24,7 +24,7 @@ A totally transparent nonprofit not only shows others how to do it. It also incr
While a bunch of transactions in a bank account is great, I want to summarize Hack Club's spending in May 2020 publicly. This is something that I wish other nonprofits did when Hack Club was first getting started.
The below summary was calculated from HQ's export from [Hack Club Bank](https://hackclub.com/bank/). You can see our full current account at https://bank.hackclub.com/hq/ using Hack Club Bank's new [Transparency Mode](https://twitter.com/hackclub/status/1262471150963130374).
The below summary was calculated from HQ's export from [HCB](https://hackclub.com/hcb/). You can see our full current account at https://hcb.hackclub.com/hq/ using HCB's new [Transparency Mode](https://twitter.com/hackclub/status/1262471150963130374).
### Revenue (total $20,621.78)
@ -45,7 +45,7 @@ The below summary was calculated from HQ's export from [Hack Club Bank](https://
- $5,000 - Think Together
Thank you to all the new donors to Hack Club this month. You make Hack Club possible. We rely on donations to keep Hack Club free for students. [Donate here.](https://hackclub.com/donate/)
Thank you to all the new donors to Hack Club this month. You make Hack Club possible. We rely on donations to keep Hack Club free for students. [Donate here.](https://hackclub.com/philanthropy/)
Please note that [Elon Musk also donated $500K this month](https://twitter.com/hackclub/status/1263153557945159680), but the gift didn't hit our account until June 3rd, so it will be included in the June finance update.
@ -65,7 +65,7 @@ Please note that [Elon Musk also donated $500K this month](https://twitter.com/h
- $510 - Employer taxes
- $6,500 - Zach Latta - Executive Director
- No taxes pre-withdrawn due to 1099, net pay above
- $5,166.67 - Max Wofford - Clubs, working with Chris, recently owning Hack Club Bank too
- $5,166.67 - Max Wofford - Clubs, working with Chris, recently owning HCB too
- No taxes pre-withdrawn due to 1099, net pay above
- $4,761.90 - Lachlan Campbell - Design, https://hackclub.com
- No taxes pre-withdrawn due to 1099, net pay above
@ -75,7 +75,7 @@ Please note that [Elon Musk also donated $500K this month](https://twitter.com/h
- No taxes pre-withdrawn due to 1099, net pay above
- $3,500 - Theo Bleier - Donor side, working with Christina
- No taxes pre-withdrawn due to 1099, net pay above
- $3,100 - Michael Destefanis - Runs operations on Hack Club Bank
- $3,100 - Michael Destefanis - Runs operations on HCB
- $2,444.13 - Net pay
- $655.87 - Employee taxes
- $237.15 - Employer taxes
@ -104,7 +104,7 @@ Please note that [Elon Musk also donated $500K this month](https://twitter.com/h
- $9 - Unity
- $8.50 - DNSimple
- $1.20 - Mailgun
- **Hack Club Bank ($515.25)**
- **HCB ($515.25)**
- $207 - Expensify
- $181.60 - Earth Class Mail (mail processing service)
- $120 - DocuSign
@ -148,11 +148,11 @@ In some cases, there are expenses that we have committed to in May that have not
- $3,670 paid to Lewis Mudge for rent the 2nd 1/2 April and the first 1/2 of May (place Max and I stayed in). Similarly, I paid Lewis at the time from my personal account and have not yet been reimbursed.
- ~$100 gas for staff trip to Vermont
Please note: there may be errors in this post. While I have pulled the numbers directly from Hack Club Bank, I did mess around a bit in a spreadsheet and have not double checked my work. I believe that all numbers below are approximately correct.
Please note: there may be errors in this post. While I have pulled the numbers directly from HCB, I did mess around a bit in a spreadsheet and have not double checked my work. I believe that all numbers below are approximately correct.
If youre interested in seeing the Google Sheet I used to calculate the above numbers, you can see it at https://docs.google.com/spreadsheets/d/1UDw7YewsS5wJIVm0Uh5wOGlM2Ddv-kZVrD3QqIypvRQ/edit.
Please note that while the above encompasses all of HQ's spending in our Hack Club Bank account, it does not include GitHub grants to clubs, postage bought by Mail Team, or grants made from our internal "Discretionary Fund" to students in need that is funded by Ron Conway.
Please note that while the above encompasses all of HQ's spending in our HCB account, it does not include GitHub grants to clubs, postage bought by Mail Team, or grants made from our internal "Discretionary Fund" to students in need that is funded by Ron Conway.
_Thanks to Christina, Melody, and Lachlan for their help writing this post._

View file

@ -1,547 +0,0 @@
import React, { useEffect } from 'react'
import styled from '@emotion/styled'
import {
Box,
Button,
Container,
Flex,
Heading,
Card,
Grid,
Link as A,
Text,
Avatar
} from 'theme-ui'
import Photo from '../components/photo'
import Image from 'next/image'
import Head from 'next/head'
import Meta from '@hackclub/meta'
import ForceTheme from '../components/force-theme'
import Nav from '../components/nav'
import Footer from '../components/footer'
import SprigForm from '../components/donate/sprigForm'
import SprigMeta from '../components/donate/sprigMeta'
import Sponsors from '../components/donate/sponsors'
import donors from '../components/donate/donors.json'
import Marquee from 'react-marquee-slider'
import ExecuteBig from '../public/donate/codedaydc_hack.jpg'
import HackCamp from '../public/donate/sf.jpg'
import HackerGames from '../public/donate/0img_20210830_161125.jpg'
import LaptopDonations from '../public/donate/0screenshot_2021-10-03_at_4.20.30_pm.png'
import Kerala from '../public/donate/0img-20210918-wa0091.jpg'
import HackPenn from '../public/donate/0color_pop.jpg'
import ElonAMA from '../public/donate/elon.jpg'
import SpaceX from '../public/donate/0spacex_and_hack_club.jpg'
import Flagship from '../public/donate/flagship.png'
import MAHacks from '../public/donate/0screenshot_2021-10-03_at_4.07.51_pm.png'
import HackCamp2020 from '../public/donate/0img_6447.jpg'
import InnovationCircuit from '../public/donate/0screenshot_2021-10-03_at_3.45.54_pm.png'
import WindyCity from '../public/donate/6screenshot_2021-10-03_at_3.29.29_pm.png'
import ZephyrFun from '../public/donate/0screenshot_2021-10-03_at_3.59.34_pm.png'
import GoldenTrain from '../public/home/golden-train.png'
const Header = styled(Box)`
background: url('/pattern.svg');
`
const Sheet = styled(Card)`
position: relative;
overflow: hidden;
border-radius: 8px;
width: 100%;
color: white;
`
Sheet.defaultProps = {
sx: {
bg: 'rgba(255, 255, 255, 0.875)',
p: [3, 4],
color: 'black',
width: 1,
mb: 4
}
}
const Row = styled(Box)`
text-align: left;
@media screen and (min-width: 48em) {
display: grid;
grid-gap: 18px;
grid-template-columns: ${({ reverse }) =>
reverse ? '3fr 2fr' : '2fr 3fr'};
}
`
const Quote = styled(Sheet)`
position: relative;
&:before {
content: '“';
line-height: 1;
font-size: 48px;
padding-left: 6px;
position: absolute;
left: 0;
top: 0;
color: #fff;
opacity: 0.5;
padding: 18px;
}
`
Sheet.defaultProps = {
sx: {
maxWidth: '52rem',
fontSize: 3,
p: [4, 5],
color: 'white'
}
}
const FirstQuote = styled(Quote)`
background-image: radial-gradient(
at left top,
rgb(45, 228, 207),
rgb(41, 206, 104),
rgb(53, 181, 36)
);
`
const SecondQuote = styled(Quote)`
background-image: radial-gradient(
at left bottom,
rgb(45, 158, 228),
rgb(45, 66, 228),
rgb(115, 45, 228)
);
`
const subhline = { fontSize: [3, 4], style: { lineHeight: '1.375' } }
const contentContainer = {
maxWidth: 72,
width: 1,
p: 3,
color: 'black',
style: { position: 'relative' }
}
const content = { maxWidth: 48, mx: 0, color: 'black' }
const title = 'Donate'
const desc =
'Contribute today to empower the next generation and help start a coding club at every high school.'
const DonorGrid = styled(Box)`
display: grid;
grid-gap: 6px;
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
align-items: center;
p,
a {
width: 100%;
}
@media screen and (min-width: 48em) {
grid-gap: 18px;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
`
const DonorCardBase = styled(Sheet)`
display: flex;
justify-content: center;
align-items: center;
@media screen and (max-width: 32em) {
border-radius: 0;
box-shadow: none;
}
`
const DonorCard = ({ name, link = false }) => (
<DonorCardBase bg="white" p="18px!important" mb={0}>
<Text color="black" sx={{ textAlign: 'center', fontSize: '16px' }}>
{name}
</Text>
</DonorCardBase>
)
const PhotoRow = ({ photos }) => (
<Box sx={{ height: '200px', overflow: 'hidden' }}>
<Box sx={{ display: ['block', 'block', 'block', 'block', 'none'] }}>
<Marquee velocity={12}>
{photos.map((photo, index) => (
<Image
placeholder="blur"
src={photo}
objectFit="cover"
className="next-image"
height="200px"
width="300px"
alt="Hack Club students"
key={'image-' + index}
/>
))}
</Marquee>
</Box>
<Box sx={{ display: ['none', 'none', 'none', 'none', 'block'] }}>
<Marquee velocity={12}>
{photos.map((photo, index) => (
<Image
placeholder="blur"
src={photo}
objectFit="cover"
className="next-image"
height="200px"
width="600px"
key={'image-' + index}
alt="Hack Club students"
/>
))}
</Marquee>
</Box>
</Box>
)
const DonorListing = ({ name, url }) => {
if (url) {
return (
<A target="_blank" href={url} color="black" underline>
<DonorCard name={name} link />
</A>
)
} else {
return <DonorCard name={name} />
}
}
export default function Donate({ sprig }) {
useEffect(() => {
if (sprig) {
window.document.getElementById('sprig-donation').scrollIntoView()
}
}, [sprig])
return (
<Box>
<Meta
as={Head}
title={title}
description={desc}
image="https://cloud-cz9a6kt0a-hack-club-bot.vercel.app/0social-photo_2.jpg"
/>
<Nav color="muted" />
<ForceTheme theme="light" />
<Header sx={{ position: 'relative' }}>
<Box
sx={{
background: 'rgba(0,0,0, 0.8)',
zIndex: 1,
position: 'relative',
color: 'white!important',
height: '600px'
}}
pt={[5, 5, '110px']}
>
<Box
sx={{
maxWidth: '64rem',
mx: 'auto',
zIndex: 1,
position: 'relative'
}}
align="center"
py={2}
px={[1, 3]}
>
<Container sx={{ maxWidth: '48rem' }}>
<Heading
sx={{
fontSize: ['42px', '54px', '72px'],
my: 2,
color: 'white'
}}
>
We rely on people like you to bring coding to the world.
</Heading>
<Box
sx={{
fontSize: ['22px', '23px', '28px'],
maxWidth: '40rem',
color: 'white'
}}
>
Contribute today to empower the next generation. Help start a
Hack Club at every high school.
</Box>
<Button
variant="ctaLg"
my={3}
sx={{ width: ['100%', 'auto'] }}
as="a"
href="https://bank.hackclub.com/donations/start/hq"
>
Donate
<Text sx={{ display: ['none', 'inline-block'], ml: 2 }}>
to Hack Club
</Text>
</Button>
<Text
sx={{ mt: 1, display: 'block', opacity: 0.8 }}
fontSize={2}
color="white"
>
Your contribution is tax-deductible.
<br />
Hack Club is a 501(c)(3) nonprofit with the EIN 81-2908499.
</Text>
</Container>
</Box>
</Box>
<Box
sx={{
position: 'absolute',
top: 0,
zIndex: 0,
width: '100%',
display: 'block'
}}
>
<PhotoRow
photos={[
ExecuteBig,
HackCamp,
HackerGames,
LaptopDonations,
Kerala
]}
/>
<PhotoRow
photos={[HackPenn, ElonAMA, SpaceX, GoldenTrain, Flagship]}
/>
<PhotoRow
photos={[
HackCamp2020,
InnovationCircuit,
WindyCity,
MAHacks,
ZephyrFun
]}
/>
</Box>
</Header>
<Container mb={5} id="sprig-donation"></Container>
{sprig && <SprigMeta />}
<Container variant="copy">
<Box pt={[0, 3]} mb={[2, 4]}>
<Heading
sx={{
textAlign: 'center',
fontSize: 4,
textTransform: 'uppercase',
fontWeight: [400, 800],
mb: [0, 0]
}}
>
Now introducing...
</Heading>
<Heading
mt={2}
sx={{
textAlign: 'center',
textTransform: 'uppercase',
fontSize: [5, 7],
lineHeight: [0.8, 1],
mb: 0,
marginBlockEnd: 0,
marginBlockStart: 0,
my: [2, 0]
}}
>
Sprig Consoles
</Heading>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-around'
}}
>
<Heading
variant="subtitle"
pb={[3, 2, 2]}
sx={{
textAlign: 'center',
color: 'blue',
textTransform: 'uppercase',
mt: [2, 0],
fontWeight: 800
}}
>
Inspiring teenagers to both make and code.
</Heading>
<Text sx={{ textAlign: 'center', fontSize: 2 }}>
A donation to the Sprig fund will send a teenager a Hack Club
Sprig Console Kit: containing a custom PCB, buttons, a screen, a
microprocessor, and more (all open source, of course), so that
they can build and then play their own games.
</Text>
</Box>
</Box>
<Grid
columns={[null, '2fr 3fr']}
gap={[2, 3, 4]}
pt={[0, 0]}
mb={[2, 4]}
>
<Box
as="video"
style={{
width: '100%',
borderRadius: '1em',
height: '100%',
objectFit: 'cover'
}}
autoPlay
muted
loop
>
<source
src="https://cloud-5r3ak1pm6-hack-club-bot.vercel.app/0image_from_ios__online-video-cutter.com__1_.mp4"
type="video/mp4"
/>
</Box>
<Photo
src="https://cloud-kcloydjv0-hack-club-bot.vercel.app/0image_from_ios__1_.jpg"
alt="Sprig PCB"
width={3000}
height={2550}
showAlt
sx={{ height: '100%' }}
/>
</Grid>
<Sheet
sx={{
color: 'white',
bg: 'primary',
display: 'flex',
flexDirection: 'row',
flexWrap: ['wrap', 'nowrap'],
justifyContent: 'space-between',
alignItems: 'center',
padding: 4
}}
>
<SprigForm />
</Sheet>
</Container>
<Container variant="copy" mt={5}>
<FirstQuote>
<Heading my={3} sx={{ fontWeight: 'normal', fontSize: '27px' }}>
When I took CS classes in high school, I always found myself
disengaged and feeling like they were just another class. After
getting involved in Hack Club, a career in computer science changed
from a possibility to reality.
</Heading>
<Heading
fontSize={[4, 5]}
sx={{ fontWeight: 'bold', fontSize: ['27px', '36px'] }}
as="h1"
>
Because of Hack Club, I started organizing hackathons with hundreds
of participants, interning for companies including Intuit, and most
importantly, fell in love with building things with code.
</Heading>
<Flex align="center" mt={[3, 4]}>
<Avatar
src="/hackers/selynna.jpg"
sx={{ height: '48px', width: '48px' }}
mr={3}
st
/>
<Box align="left" fontSize={3}>
<Heading>Selynna Sun</Heading>
<Text fontSize={2} color="green.1">
Sophomore & CS Major @ Cal Poly SLO
</Text>
</Box>
</Flex>
</FirstQuote>
<Container maxWidth={'48rem'} sx={{ maxWidth: '48rem' }} py={[3, 4]}>
<Heading as="h1" sx={{ fontSize: ['36px', '48px'] }}>
Contribute beyond just dollars.
</Heading>
<Box mt={2} mb={2} sx={{ fontSize: '27px' }}>
We accept donations of time, technical or hard science fiction
books, stocks/other securities, and cryptocurrency.
</Box>
<Box mb={3} sx={{ fontSize: '27px' }}>
Please get in touch at{' '}
<A sx={{ color: 'blue' }} href="mailto:bank@hackclub.com">
bank@hackclub.com
</A>{' '}
if youre interested in making a contribution with cryptocurrency or
have questions.
</Box>
</Container>
<SecondQuote>
<Heading
fontSize={[4, 5]}
sx={{ fontWeight: 'bold', fontSize: ['27px', '36px'] }}
as="h1"
>
Hack Club has inspired me to grow and become the person I am today.
Being part of the community allows me to meet countless like-minded
individuals who challenge me to become a better person, and a better
hacker.
</Heading>
<Flex align="center" mt={[3, 4]}>
<Avatar
src="/hackers/rashid.jpg"
sx={{ height: '48px', width: '48px' }}
mr={3}
st
/>
<Box align="left" fontSize={3}>
<Heading>Rashid Al-Abri</Heading>
<Text fontSize={2} color="green.1">
Club Leader from Oman in Victoria, BC, Canada
</Text>
</Box>
</Flex>
</SecondQuote>{' '}
</Container>
<Flex justify="center" bg="snow" color="black">
<Container width={1} py={[4, 5]} sx={{ textAlign: ['left', 'center'] }}>
<Heading
px={3}
mt={[3, 4]}
mb={[3, 4]}
mx="auto"
as="h1"
sx={{ fontSize: [5, 6] }}
>
A few of our amazing donors.
</Heading>
<DonorGrid mt={4} mb={4}>
{Object.keys(donors).map(name => (
<DonorListing key={name} name={name} url={donors[name]} />
))}
</DonorGrid>
<Heading px={3} sx={{ fontWeight: 'normal', mt: 2 }}>
and many more
</Heading>
</Container>
</Flex>
<Container {...contentContainer}>
<Row my={5} {...content}>
<Heading {...subhline} mb={4} sx={{ fontSize: [4, 5] }}>
These fabulous companies donate their products to us.
</Heading>
<Sponsors />
</Row>
</Container>
<Footer />
</Box>
)
}
export async function getServerSideProps(context) {
return {
props: {
sprig: Object.keys(context.query).includes('gl')
}
}
}

View file

@ -1,4 +1,16 @@
import { Box, Button, Container, Heading, Card, Text, Grid, Flex, Image as Img, Link, Divider } from 'theme-ui'
import {
Box,
Button,
Container,
Heading,
Card,
Text,
Grid,
Flex,
Image as Img,
Link,
Divider
} from 'theme-ui'
import Head from 'next/head'
import Meta from '@hackclub/meta'
import ForceTheme from '../components/force-theme'
@ -10,8 +22,19 @@ import OuternetPic from '../public/outernet/hack.jpg'
import { compact } from 'lodash'
import theme from '@hackclub/theme'
const events = [
{
name: 'Haunted House',
description: `Where Fright Meets Byte: A Haunted House Hackathon Experience in Downtown Chicago.`,
logo: 'https://emoji.slack-edge.com/T0266FRGM/hauntedhouse/427353c4bd656767.png',
location: 'Chicago, Illinois',
season: 'Fall',
year: '2023',
// repo: 'outernet',
image:
'https://cloud-6vo1bh2dg-hack-club-bot.vercel.app/0image.png',
link: 'https://haunted.hackclub.com'
},
{
name: 'Outernet',
description: `An out-of-doors, make-it-yours programming and camping adventure in Vermont's Northeast Kingdom.`,
@ -19,9 +42,8 @@ const events = [
location: 'Cabot, Vermont',
season: 'Summer',
year: '2023',
video: 'https://www.youtube.com/embed/O1s5HqSqKi0',
repo: 'outernet',
image: 'https://github.com/hackclub/outernet/assets/39828164/368eac86-3c39-4842-be2c-1436a6db6f07',
link: 'https://github.com/hackclub/outernet'
},
{
name: 'Epoch',
@ -32,46 +54,52 @@ const events = [
year: '2022/23',
video: 'https://www.youtube.com/embed/KLx4NZZPzMc',
repo: 'epoch'
},
},
{
name: 'Assemble',
logo: 'https://emoji.slack-edge.com/T0266FRGM/assemble/4f9465eb00175463.png',
description: 'The first high school hackathon since the pandemic! Hosted by a team of Hack Clubbers to kick off a hackathon renaissance.',
description:
'The first high school hackathon since the pandemic! Hosted by a team of Hack Clubbers to kick off a hackathon renaissance.',
location: 'San Francisco, California',
season: 'Summer',
year: '2022',
video: 'https://youtube.com/embed/PnK4gzO6S3Q',
repo: 'assemble'
},
},
{
name: 'The Hacker Zephyr',
logo: 'https://hackclub.com/stickers/zephyr.svg',
description: 'A cross-country hacker adventure on a train and the longest hackathon (by miles) on land.',
description:
'A cross-country hacker adventure on a train and the longest hackathon (by miles) on land.',
location: 'Burlington (VT) to Los Angeles (CA)',
season: 'Summer',
year: '2021',
video: 'https://youtube.com/embed/2BID8_pGuqA',
repo: 'the-hacker-zephyr'
},
},
{
name: 'Summer of Making',
logo: 'https://hackclub.com/stickers/summer_of_making.svg',
description: '$50k in hardware donations to teen hackers around the world and the creation of Scrapbook:',
description:
'$50k in hardware donations to teen hackers around the world and the creation of Scrapbook:',
location: 'Online (thanks COVID-19!)',
season: 'Summer',
year: '2020',
image: 'https://cdn.sanity.io/images/2ejqxsnu/production/ed144128afb78a7095d6c77945efdd2c38078ecf-1637x990.png?w=3840&q=75&fit=clip&auto=format',
image:
'https://cdn.sanity.io/images/2ejqxsnu/production/ed144128afb78a7095d6c77945efdd2c38078ecf-1637x990.png?w=3840&q=75&fit=clip&auto=format',
link: 'https://scrapbook.hackclub.com/r/summer-of-making',
ghTag: 'summer-of-making'
},
},
{
name: 'Flagship',
logo: 'https://hackclub.com/stickers/ship.png',
description: 'An IRL meetup of high school hackathon organizers and coding club leaders. Our first "flagship" event.',
description:
'An IRL meetup of high school hackathon organizers and coding club leaders. Our first "flagship" event.',
location: 'San Francisco, California',
season: 'Summer',
year: '2019',
image: 'https://github.com/hackclub/www-assemble/blob/main/public/hackers-assemble.jpg?raw=true',
image:
'https://github.com/hackclub/www-assemble/blob/main/public/hackers-assemble.jpg?raw=true',
link: 'https://hack.af/flagship-album'
}
]
@ -89,30 +117,63 @@ const Event = ({
image,
link
}) => (
<Card variant="sunken">
<Flex sx={{alignItems: 'center', mb: 2}}>
<Img src={logo} sx={{ height: '24px', mr: 2}} />
<Heading as="h2">{name}</Heading>
</Flex>
<Box>
{description}
</Box>
{video ?
<Box as="iframe" src={video} frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen width='100%' height="250px" border="none" sx={{borderRadius: '8px', mt: 2}} />
: <a href={link}><Img src={image} sx={{borderRadius: '8px', mt: 2, height: '250px', objectFit: 'cover', width: '100%', objectPosition: 'top'}} /></a>
}
<Box sx={{color: 'darkless'}}>
<b>{season}, {year} - {location}</b> </Box><Box> {repo && <Link href={`https://github.com/hackclub/${repo}`}>
<>github.com/hackclub/{repo}</>
</Link>}
{ghTag && <Link href={`https://github.com/topics/${ghTag}`}>
<Card variant="sunken">
<Flex sx={{ alignItems: 'center', mb: 2 }}>
<Img src={logo} sx={{ height: '24px', mr: 2 }} />
<Heading as="h2">{name}</Heading>
</Flex>
<Box>{description}</Box>
{video ? (
<Box
as="iframe"
src={video}
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
width="100%"
height="250px"
border="none"
sx={{ borderRadius: '8px', mt: 2 }}
/>
) : (
<a href={link}>
<Img
src={image}
sx={{
borderRadius: '8px',
mt: 2,
height: '250px',
objectFit: 'cover',
width: '100%',
objectPosition: 'top'
}}
/>
</a>
)}
<Box sx={{ color: 'darkless' }}>
<b>
{season}, {year} - {location}
</b>{' '}
</Box>
<Box>
{' '}
{repo && (
<Link href={`https://github.com/hackclub/${repo}`}>
<>github.com/hackclub/{repo}</>
</Link>
)}
{ghTag && (
<Link href={`https://github.com/topics/${ghTag}`}>
<>github.com/topics/{ghTag}</>
</Link>}
{link && !repo && !ghTag && <Link href={link}>
<>{link.replace("https://", "")}</>
</Link>}
</Box>
</Card>
</Link>
)}
{link && !repo && !ghTag && (
<Link href={link}>
<>{link.replace('https://', '')}</>
</Link>
)}
</Box>
</Card>
)
const Page = ({ jobs }) => (
@ -183,7 +244,8 @@ const Page = ({ jobs }) => (
textShadow: 'small'
}}
>
Every summer and now every winter, Hack Club does something special to bring the community together. Let's take a trip down memory lane.
Every summer and now every winter, Hack Club does something special
to bring the community together. Let's take a trip down memory lane.
</Heading>
<Button
as="a"
@ -206,17 +268,50 @@ const Page = ({ jobs }) => (
align="left"
columns={['1fr', '1fr 1fr']}
>
{
events.map((event, i) => (
<Event key={`event-${i}`} {...event}/>
))
}
{events.map((event, i) => (
<Event key={`event-${i}`} {...event} />
))}
</Grid>
<Card variant="sunken" sx={{textAlign: 'center', background: theme.util.gx('cyan', 'blue'), color: 'white', width: '100%', maxWidth: '64rem', mx: 'auto', mt: 3, fontSize: 2}}>
<Box sx={{maxWidth: '600px', mx: 'auto'}}>
Looking for more? Hack Clubbers often organise their own hackathons!
Check them out at <Link href="https://hackathons.hackclub.com" sx={{color: 'white'}} target="_blank">hackathons.hackclub.com</Link>. Hack Club is also behind a series of <Link href="https://daysofservice.hackclub.com/" sx={{color: 'white'}} target="_blank">Day of Service</Link> events and <Link href="https://events.hackclub.com/" sx={{color: 'white'}} target="_blank">frequent virtual events</Link>.
<Card
variant="sunken"
sx={{
textAlign: 'center',
background: theme.util.gx('cyan', 'blue'),
color: 'white',
width: '100%',
maxWidth: '64rem',
mx: 'auto',
mt: 3,
fontSize: 2
}}
>
<Box sx={{ maxWidth: '600px', mx: 'auto' }}>
Looking for more? Hack Clubbers often organise their own hackathons!
Check them out at{' '}
<Link
href="https://hackathons.hackclub.com"
sx={{ color: 'white' }}
target="_blank"
>
hackathons.hackclub.com
</Link>
. Hack Club is also behind a series of{' '}
<Link
href="https://daysofservice.hackclub.com/"
sx={{ color: 'white' }}
target="_blank"
>
Day of Service
</Link>{' '}
events and{' '}
<Link
href="https://events.hackclub.com/"
sx={{ color: 'white' }}
target="_blank"
>
frequent virtual events
</Link>
.
</Box>
</Card>
</Container>
@ -226,4 +321,4 @@ const Page = ({ jobs }) => (
</>
)
export default Page
export default Page

View file

@ -64,7 +64,7 @@ const HackathonGrant = () => {
<Meta
as={Head}
title="Hackathon Grant"
description="Hack Club is partnering with FIRST to provide $500 grants to in-person high school hackathons happening until June 30th, 2023."
description="Hack Club is providing $500 grants to in-person high school hackathons happening until December 31st, 2024."
image="https://cloud-7yw9f6xnv-hack-club-bot.vercel.app/0grant.png"
/>
<style>{styles}</style>
@ -128,25 +128,6 @@ const HackathonGrant = () => {
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('/hackathons/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.
@ -158,20 +139,13 @@ const HackathonGrant = () => {
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
Hack Club is providing $500 grants (and waiving{' '}
<Link href="/hcb" target="_blank">
HCB
</Link>{' '}
fees) to <a sx={{ whiteSpace: 'nowrap' }}>in-person</a>{' '}
<a sx={{ whiteSpace: 'nowrap' }}>high school</a> hackathons{' '}
<s>this semester between August and December 31, 2022</s> until
December 31st, 2023.
<a sx={{ whiteSpace: 'nowrap' }}>high school</a> hackathons until
December 31st, 2024.
</Box>
<Button variant="ctaLg" as="a" href="#apply" sx={{ mt: 2 }}>
{open ? 'Apply Now' : 'Coming Soon'}
@ -218,14 +192,14 @@ const HackathonGrant = () => {
<Grid columns={[1, 1, 2, 2]} gap={4}>
<Requirement
title="Running this year"
title="Running through next year"
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 around the world,
so we're only offering this grant for high school hackathons that
take place this year (until December 31st).
take place throughout 2024 (until December 31st).
<br />
<br />
<Text
@ -235,7 +209,7 @@ const HackathonGrant = () => {
}}
>
This is not an annual program and has only been renewed until
the end of this year.
the end of 2024.
</Text>
</Requirement>
<Requirement
@ -332,7 +306,7 @@ const HackathonGrant = () => {
}}
>
You will need to share a link to your website. Don't have a
domain? Hack Club Bank provides a free domain. Check out this{' '}
domain? HCB provides a free domain. Check out this{' '}
<Link
href="https://notebook.lachlanjc.com/2019-09-06_making_a_hackathon_site"
target="_blank"
@ -361,17 +335,17 @@ const HackathonGrant = () => {
background="https://icons.hackclub.com/api/icons/0x212025/glyph:bank-account.svg"
size="28"
>
You'll receive your grant through Hack Club Bank, our financial
platform for hackathons, and spend it in the open with{' '}
You'll receive your grant through HCB, our financial platform for
hackathons, and spend it in the open with{' '}
<Link
href="https://changelog.bank.hackclub.com/transparent-finances-(optional-feature)-151427"
href="https://changelog.hcb.hackclub.com/transparent-finances-(optional-feature)-151427"
target="_blank"
>
Transparency Mode
</Link>
. Sign up for{' '}
<Link href="/bank" target="_blank">
Hack Club Bank
<Link href="/hcb" target="_blank">
HCB
</Link>{' '}
before applying.
<br />
@ -382,8 +356,8 @@ const HackathonGrant = () => {
color: 'muted'
}}
>
If you're unable to use Hack Club Bank, we're unfortunately
unable to support you through this grant program.
If you're unable to use HCB, we're unfortunately unable to
support you through this grant program.
</Text>
</Requirement>
</Grid>
@ -399,11 +373,7 @@ const HackathonGrant = () => {
logos found on the respective brand guides for{' '}
<Link href="/brand" target="_blank">
Hack Club
</Link>{' '}
and{' '}
<Link href="https://www.firstinspires.org/brand" target="_blank">
<i>FIRST®</i>
</Link>
</Link>{'.'}
.
</Text>
@ -429,7 +399,7 @@ const HackathonGrant = () => {
<Card
as="a"
variant="interactive"
href="mailto:bank@hackclub.com"
href="mailto:hcb@hackclub.com"
sx={{
mx: 'auto',
maxWidth: '52rem',
@ -465,7 +435,7 @@ const HackathonGrant = () => {
>
<strong>Questions?</strong>
<Text as="span" variant="caption" color="secondary" sx={{ pl: 3 }}>
Reach out to <Link>bank@hackclub.com</Link>
Reach out to <Link>hcb@hackclub.com</Link>
</Text>
</Text>
</Card>

View file

@ -27,8 +27,11 @@ export default function Hackathons({ data }) {
/>
<Box as="main">
<Landing />
<Overview />
<ScrollingHackathons eventData={data} title={true} />
<KeepExploring />
<Money />
<Slack />
@ -42,14 +45,23 @@ export default function Hackathons({ data }) {
</>
)
}
export async function getStaticProps() {
const res = await fetch('https://hackathons.hackclub.com/api/events/upcoming')
const data = await res.json()
let data;
try {
const res = await fetch('https://hackathons.hackclub.com/api/events/upcoming');
if (res.ok) {
data = await res.json();
} else {
data = [];
}
} catch (error) {
data = [];
}
return {
props: {
data
data,
},
revalidate: 10
}
};
}

View file

@ -1,19 +1,19 @@
import { useEffect, useState, useRef } from 'react'
import { useRouter } from 'next/router'
import { Box, Flex, Text } from 'theme-ui'
import ForceTheme from '../../components/force-theme'
import ForceTheme from '../../../components/force-theme'
import Head from 'next/head'
import Meta from '@hackclub/meta'
import FlexCol from '../../components/flex-col'
import Progress from '../../components/bank/apply/progress'
import NavButton from '../../components/bank/apply/nav-button'
import Watermark from '../../components/bank/apply/watermark'
import FormContainer from '../../components/bank/apply/form-container'
import BankInfo from '../../components/bank/apply/bank-info'
import OrganizationInfoForm from '../../components/bank/apply/org-form'
import PersonalInfoForm from '../../components/bank/apply/personal-form'
import AlertModal from '../../components/bank/apply/alert-modal'
import { geocode } from '../../lib/bank/apply/address-validation'
import FlexCol from '../../../components/flex-col'
import Progress from '../../../components/hcb/apply/progress'
import NavButton from '../../../components/hcb/apply/nav-button'
import Watermark from '../../../components/hcb/apply/watermark'
import FormContainer from '../../../components/hcb/apply/form-container'
import HCBInfo from '../../../components/hcb/apply/hcb-info'
import OrganizationInfoForm from '../../../components/hcb/apply/org-form'
import PersonalInfoForm from '../../../components/hcb/apply/personal-form'
import AlertModal from '../../../components/hcb/apply/alert-modal'
import { geocode } from '../../../lib/hcb/apply/address-validation'
const valiadateAddress = async step => {
// Validate the address
@ -25,7 +25,7 @@ const valiadateAddress = async step => {
const result = await geocode(userAddress)
const addrComp = type => result.results[0].structuredAddress[type] ?? ''
const addrComp = type => result.results[0]?.structuredAddress[type] ?? ''
sessionStorage.setItem(
'bank-signup-addressLine1',
@ -39,11 +39,11 @@ const valiadateAddress = async step => {
sessionStorage.setItem('bank-signup-addressZip', addrComp('postCode'))
sessionStorage.setItem(
'bank-signup-addressCountry',
result.results[0].country ?? ''
result.results[0]?.country ?? ''
)
sessionStorage.setItem(
'bank-signup-addressCountryCode',
result.results[0].countryCode ?? ''
result.results[0]?.countryCode ?? ''
)
}
}
@ -80,12 +80,7 @@ export default function Apply() {
return (
<>
<script
async
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyApxZZ8-Eh_6RgHUu8-BAOpx3xhfF2yK9U&libraries=places&mapInit=foo"
></script>
<Meta as={Head} title="Apply for Hack Club Bank" />
<Meta as={Head} title="Apply for HCB" />
<ForceTheme theme="dark" />
<Box
@ -107,14 +102,14 @@ export default function Apply() {
<Text variant="title">
Let's get you
<br />
set up on Bank.
set up on HCB.
</Text>
<Progress />
</FlexCol>
</Box>
<Box sx={{ gridArea: 'form', overflowY: 'auto' }}>
<FormContainer ref={formContainer}>
{step === 1 && <BankInfo />}
{step === 1 && <HCBInfo />}
{step === 2 && (
<OrganizationInfoForm requiredFields={requiredFields} />
)}

View file

@ -11,10 +11,10 @@ import {
Flex,
Image
} from 'theme-ui'
import ForceTheme from '../../components/force-theme'
import ForceTheme from '../../../components/force-theme'
import JSConfetti from 'js-confetti'
import Icon from '../../components/icon'
import FlexCol from '../../components/flex-col'
import Icon from '../../../components/icon'
import FlexCol from '../../../components/flex-col'
function Option({ icon, label, link }) {
const color =
@ -77,14 +77,14 @@ export default function ApplicationSuccess() {
>
<FlexCol gap={4} alignItems="center">
<Image
src="/bank/apply/party-orpheus.svg"
src="/hcb/apply/party-orpheus.svg"
alt="Dinosaur partying"
sx={{ width: '40%' }}
/>
<FlexCol gap={2}>
<Text variant="title">Thanks for applying!</Text>
<Text variant="lead">
Head on over to Bank and explore the dashboard
Head on over to HCB and explore the dashboard
</Text>
</FlexCol>
</FlexCol>
@ -101,30 +101,26 @@ export default function ApplicationSuccess() {
gap: [3, null, 0]
}}
>
<Option icon="email" label="Mail" link="mailto:bank@hackclub.com">
bank@hackclub.com
<Option icon="email" label="Mail" link="mailto:hcb@hackclub.com">
hcb@hackclub.com
</Option>
<Option
icon="slack"
label="Slack"
link="https://hackclub.slack.com/channels/bank"
link="https://hackclub.slack.com/channels/hcb"
>
#bank
#hcb
</Option>
<Option
icon="help"
label="FAQ"
link="https://bank.hackclub.com/faq"
>
<Option icon="help" label="FAQ" link="https://hcb.hackclub.com/faq">
FAQ
</Option>
</Flex>
</FlexCol>
<Button as="a" href="https://bank.hackclub.com">
<Button as="a" href="https://hcb.hackclub.com">
<Flex sx={{ alignItems: 'center', px: [2, null, 3], py: 2 }}>
<Icon glyph="bank-account" size={36} />
<Text sx={{ fontSize: 3 }}>Head to Bank!</Text>
<Text sx={{ fontSize: 3 }}>Head to HCB!</Text>
</Flex>
</Button>
</FlexCol>

View file

@ -16,9 +16,7 @@ import Footer from '../../../components/footer'
import MSparkles from '../../../components/sparkles/money'
import { Text, Button, Card } from 'theme-ui'
import Icon from '@hackclub/icons'
import OrganizationCard, {
Badge
} from '../../../components/bank/directory/card'
import OrganizationCard, { Badge } from '../../../components/hcb/directory/card'
import Zoom from 'react-reveal/Zoom'
import fuzzysort from 'fuzzysort'
import ScrollHint from '../../../components/scroll-hint'
@ -27,7 +25,7 @@ import { useEffect, useState } from 'react'
import NextLink from 'next/link'
import { kebabCase, intersection } from 'lodash'
import theme from '@hackclub/theme'
import Tooltip from '../../../components/bank/tooltip'
import Tooltip from '../../../components/hcb/tooltip'
const styles = `
html {
@ -87,27 +85,26 @@ tags.__proto__.forOrg = function (org) {
return this.filter(tag => tag.match?.(org))
}
export const regions = [
{
label: 'North America',
color: 'secondary',
iconColor: 'red',
icon: 'photo',
image: 'https://cloud-cberabu5z-hack-club-bot.vercel.app/3north_america.png',
ogImage: 'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/3northamerica.png'
image:
'https://cloud-cberabu5z-hack-club-bot.vercel.app/3north_america.png',
ogImage:
'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/3northamerica.png'
},
{
label: 'South America',
color: 'secondary',
iconColor: 'orange',
icon: 'photo',
image: 'https://cloud-cberabu5z-hack-club-bot.vercel.app/4south_america.png',
ogImage: 'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/4southamerica.png'
image:
'https://cloud-cberabu5z-hack-club-bot.vercel.app/4south_america.png',
ogImage:
'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/4southamerica.png'
},
{
label: 'Africa',
@ -132,7 +129,8 @@ export const regions = [
icon: 'explore',
image:
'https://cloud-oax3m4v0t-hack-club-bot.vercel.app/0asia___oceania.png',
ogImage: 'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/1asia_oceania.png'
ogImage:
'https://cloud-p9tu92fwx-hack-club-bot.vercel.app/1asia_oceania.png'
}
]
@ -352,7 +350,7 @@ const RegionPanel = ({ currentRegion, mobile }) => {
display: hiddenOnMobile ? 'none' : 'flex'
}}
>
<NextLink scroll={false} href={'/bank/climate'}>
<NextLink scroll={false} href={'/hcb/climate'}>
<Flex
sx={{
alignItems: 'center',
@ -405,7 +403,7 @@ const RegionPanel = ({ currentRegion, mobile }) => {
<NextLink
key={idx}
scroll={false}
href={`/bank/climate/organizations-in-${kebabCase(item.label)}`}
href={`/hcb/climate/organizations-in-${kebabCase(item.label)}`}
>
<Flex
sx={{
@ -487,7 +485,7 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
const region = pageRegion
// useEffect(() => {
// // history.pushState(null, null, `/bank/climate/organizations-in-${region.toLowerCase().split(' ').join('-')}`);
// // history.pushState(null, null, `/hcb/climate/organizations-in-${region.toLowerCase().split(' ').join('-')}`);
// }, [region]);
const [modalOrganization, setModalOrganization] = useState(null)
@ -496,7 +494,7 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
if (e.key === 'Escape') {
closeModal()
}
};
}
window.addEventListener('keydown', handle)
return () => window.removeEventListener('keydown', handle)
@ -529,14 +527,17 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
as={Head}
title={
'Climate-focused nonprofits' +
(region ? ` in ${region.label}` : ' on Hack Club Bank')
(region ? ` in ${region.label}` : ' on HCB')
}
description={
'Nonprofits are making real environmental impact' +
(region ? ` in ${region.label}` : '') +
" with Hack Club Bank's fiscal sponsorship and financial tools. Explore the climate efforts running on Hack Club Bank."
" with HCB's fiscal sponsorship and financial tools. Explore the climate efforts running on HCB."
}
image={
region?.ogImage ??
'https://cloud-gv8bzwz6z-hack-club-bot.vercel.app/0frame_14__1_.png'
}
image={region?.ogImage ?? "https://cloud-gv8bzwz6z-hack-club-bot.vercel.app/0frame_14__1_.png"}
/>
<style>{styles}</style>
{modalOrganization && (
@ -562,24 +563,29 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
borderRadius: '10px',
position: 'relative',
display: 'flex',
flexDirection: 'column'
boxSizing: 'border-box',
flexDirection: 'column',
maxHeight: '90vh',
overflow: 'scroll'
}}
onClick={e => {
e.stopPropagation()
}}
>
<Flex sx={{
position: 'absolute',
top: '10px',
right: '10px',
width: '40px',
height: '40px',
bg: 'smoke',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer'
}}>
<Flex
sx={{
position: 'absolute',
top: '10px',
right: '10px',
width: '40px',
height: '40px',
bg: 'smoke',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer'
}}
>
<Icon glyph="view-close" size={32} onClick={closeModal} />
</Flex>
<Flex sx={{ flexDirection: 'column', alignItems: 'start', gap: 3 }}>
@ -607,17 +613,19 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
justifyContent: 'start'
}}
>
<img
alt={`${modalOrganization.name}'s logo`}
src={modalOrganization.branding.logo}
sx={{
width: '100px',
height: '100px',
borderRadius: '8px',
marginRight: [0, 4, 4],
boxShadow: '0px 0px 45px 0px rgba(0, 0, 0, 0.72)'
}}
/>
{modalOrganization.branding.logo &&
<img
alt={`${modalOrganization.name}'s logo`}
src={modalOrganization.branding.logo}
sx={{
width: '100px',
height: '100px',
borderRadius: '8px',
marginRight: [0, 4, 4],
boxShadow: '0px 0px 45px 0px rgba(0, 0, 0, 0.72)'
}}
/>
}
<Text
variant="title"
sx={{
@ -666,13 +674,15 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
</ThemeBadge>
))}
{badges.forOrg(modalOrganization).map((badge, i) => (
<Tooltip.N key={i} text={badge.tooltip}>
<span class="tooltipped">
<Badge badge={badge} />
</span>
</Tooltip.N>
))}
{badges.forOrg(modalOrganization).map((badge, i) => {
return (
<Tooltip.N key={i} text={badge.tooltip} id={badge.id}>
<span class={`tooltipped-${badge.id}`}>
<Badge badge={badge} />
</span>
</Tooltip.N>
)
})}
</Flex>
<Flex
@ -738,50 +748,54 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
gap: 1
}}
>
{modalOrganization.links.website && <Flex
as="a"
target="_blank"
href={modalOrganization.links.website}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="web" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Website
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>}
{modalOrganization.links.financials && <Flex
as="a"
target="_blank"
href={modalOrganization.links.financials}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="explore" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Transparent Finances
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>}
{modalOrganization.links.website && (
<Flex
as="a"
target="_blank"
href={modalOrganization.links.website}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="web" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Website
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
{modalOrganization.links.financials && (
<Flex
as="a"
target="_blank"
href={modalOrganization.links.financials}
sx={{
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
color: 'slate',
textDecoration: 'none'
}}
>
<Icon glyph="explore" size={38} />
<Text style={{ fontSize: '20px', marginLeft: '6px' }}>
Transparent Finances
</Text>
<Icon
glyph="external"
size={20}
style={{ marginLeft: '2px', marginBottom: '6px' }}
/>
</Flex>
)}
</Flex>
</Flex>
{/* desktop stats */}
@ -951,24 +965,47 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
viewBox="0 0 512 512"
>
<img
src="/bank/climate/earth-on-bank.svg"
src="/hcb/climate/earth-on-hcb.svg"
alt=""
height="82px"
/>
</MSparkles>
</Flex>
Climate-focused nonprofits on{' '}
<span sx={{ whiteSpace: 'nowrap' }}>Hack Club Bank</span>
{region ? <>
{' '}in
<span sx={{ display: ['none', 'inline'], whiteSpace: 'nowrap', bg: region.iconColor, pl: 3, pr: 18, mx: -1, borderRadius: 8, textShadow: 'none', ml: 2 }}>
<img src={region.image} alt="" sx={{ mr: 3, height: [30, 42, 42, 64] }} />
{region.label}
</span>
<span sx={{ display: ['inline', 'none'], whiteSpace: 'nowrap' }}>
{' ' + region.label}
</span>
</> : ''}
<span sx={{ whiteSpace: 'nowrap' }}>HCB</span>
{region ? (
<>
{' '}
in
<span
sx={{
display: ['none', 'inline'],
whiteSpace: 'nowrap',
bg: region.iconColor,
pl: 3,
pr: 18,
mx: -1,
borderRadius: 8,
textShadow: 'none',
ml: 2
}}
>
<img
src={region.image}
alt=""
sx={{ mr: 3, height: [30, 42, 42, 64] }}
/>
{region.label}
</span>
<span
sx={{ display: ['inline', 'none'], whiteSpace: 'nowrap' }}
>
{' ' + region.label}
</span>
</>
) : (
''
)}
</Heading>
<Box
sx={{
@ -979,9 +1016,9 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
mx: 'auto'
}}
>
Nonprofits are making real environmental impact with Hack Club
Bank's fiscal sponsorship and financial tools. Explore the climate
efforts running on Hack Club Bank.
Nonprofits are making real environmental impact with HCB's fiscal
sponsorship and financial tools. Explore the climate efforts
running on HCB.
</Box>
<Button
variant="ctaLg"
@ -995,23 +1032,7 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
>
EXPLORE IMPACT
</Button>
<Button
variant="outlineLg"
as="a"
href="#apply"
sx={{
mt: [3, 2],
ml: 2,
mb: [4, 0],
borderColor: 'green',
borderWidth: '2px',
boxSizing: 'border-box',
color: 'white',
height: '56px'
}}
>
LEARN MORE
</Button>
</Box>
</Box>
@ -1047,7 +1068,7 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
/>
</Box>
</Container>
<Container pt={4}>
<Container py={4}>
<Flex>
<Box sx={{ flexGrow: 1, pr: [0, 3], mb: 3 }}>
<Input
@ -1084,20 +1105,27 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
/>
</Box>
{organizations.length === 0 && (
<Box sx={{
textAlign: 'center',
p: 5
}}>
<Box
sx={{
textAlign: 'center',
p: 5
}}
>
<Box>
<Text variant="headline" sx={{
textTransform: 'unset',
display: 'block',
mb: 0
}}>No results</Text>
<Text
variant="headline"
sx={{
textTransform: 'unset',
display: 'block',
mb: 0
}}
>
No results
</Text>
</Box>
</Box>
)}
<Grid columns={[1, 2, 3]} gap={[3, 4]} sx={{ mt: 3 }}>
<Grid columns={[1, 2, 3]} gap={[3, 4]} sx={{ my: 3 }}>
{organizations
.map(org => new Organization(org))
.filter(organization => {
@ -1168,13 +1196,13 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
}}
>
Let your money work for change by donating to all climate-focused
nonprofits on Hack Club Bank. Donate to 128 Collectives curated
list of recommended organizations.
nonprofits on HCB. Donate to 128 Collectives curated list of
recommended organizations.
</Box>
<Button
variant="ctaLg"
as="a"
href="https://bank.hackclub.com/donations/start/128-collective-fund"
href="https://hcb.hackclub.com/donations/start/128-collective-fund"
target="_blank"
sx={{
ml: [0, 3],
@ -1182,11 +1210,7 @@ export default function ClimatePage({ rawOrganizations, pageRegion }) {
backgroundImage: t => t.util.gx('green', 'blue')
}}
>
<Text>
Donate to{' '}
the{' '}
climate&nbsp;fund
</Text>
<Text>Donate to the climate&nbsp;fund</Text>
</Button>
</Box>
</Box>
@ -1322,7 +1346,7 @@ export class Organization {
if (this.acceptsDonations) links.donations = this.raw.donation_link
if (this.isTransparent)
links.financials = `https://bank.hackclub.com/${this.slug}`
links.financials = `https://hcb.hackclub.com/${this.slug}`
return links
}
@ -1377,7 +1401,7 @@ export async function fetchRawClimateOrganizations() {
let page = 1
while (lastLength >= 100) {
const json = await fetch(
'https://bank.hackclub.com/api/v3/directory/organizations?per_page=100&page=' +
'https://hcb.hackclub.com/api/v3/directory/organizations?per_page=100&page=' +
page
).then(res => res.json())
lastLength = json.length

View file

@ -15,14 +15,15 @@ import ForceTheme from '../../components/force-theme'
import Nav from '../../components/nav'
import Footer from '../../components/footer'
import Icon from '../../components/icon'
import Features from '../../components/bank/first/features'
import Features from '../../components/hcb/first/features'
import Form from '../../components/bank/first/form'
import Testimonials from '../../components/bank/first/testimonials'
import Steps from '../../components/bank/first/steps'
import Form from '../../components/hcb/first/form'
import Testimonials from '../../components/hcb/first/testimonials'
import Steps from '../../components/hcb/first/steps'
import Start from '../../components/hcb/start'
import theme from '@hackclub/theme'
export default function First() {
export default function First({ stats }) {
return (
<>
<style>
@ -33,10 +34,10 @@ export default function First() {
<Meta
as={Head}
title="Finanical Toolkit for FIRST Teams"
description="Hack Club Bank is the ultimate financial tool for FRC, FTC, and FLL teams to receive grants, fundraise, make purchases, and so much more."
image="/bank/first/og-image.png"
description="HCB is the ultimate financial tool for FRC, FTC, and FLL teams to receive grants, fundraise, make purchases, and so much more."
image="/hcb/first/og-image.png"
>
<title>Financial Toolkit for FIRST Teams Hack Club Bank</title>
<title>Financial Toolkit for FIRST Teams | HCB</title>
</Meta>
<Box as="main" key="main" sx={{ mb: 6 }}>
@ -143,9 +144,9 @@ export default function First() {
}}
variant="copy"
>
Built by <i>FIRST</i> alumni for <i>FIRST</i> teams, Hack Club
Bank is a comprehensive financial platform used by hundreds of
clubs, teams and hackathons.
Built by <i>FIRST</i> alumni for <i>FIRST</i> teams, HCB is a
comprehensive financial platform used by hundreds of clubs, teams
and hackathons.
</Container>
<Box
@ -168,7 +169,7 @@ export default function First() {
}}
variant="ctaLg"
as="a"
href="/bank/first/Hack_Club_Bank_for_FIRST_Teams.pdf"
href="/hcb/first/Hack_Club_Bank_for_FIRST_Teams.pdf"
// @exu3: to edit this PDF, use this Figma file https://www.figma.com/file/LgadOH1lHUBOejA3vaNGgm/Hack-Club-Bank-for-FIRST-Teams-One-Pager?node-id=0%3A1&t=ZtkN2a3aw2IojFvi-1
// message me on Slack if you need edit access
target="_blank"
@ -185,49 +186,23 @@ export default function First() {
<Testimonials />
</Box>
<Container
variant="container"
id="demo"
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
pt: 5
}}
>
<Heading variant="title">Get started in a day.</Heading>
<Text variant="lead" color="muted">
Well help you get set up and running in no time.
</Text>
</Container>
<Flex
sx={{
flexDirection: ['column', null, 'row'],
alignItems: 'center',
justifyContent: 'center'
}}
>
<Steps />
<Card
variant="primary"
sx={{
backgroundColor: 'darkless',
color: 'snow',
width: ['100%', null, 356],
float: [null, null, 'right'],
height: 'fit-content'
}}
>
<Text variant="heading" sx={{ fontSize: 24, lineHeight: 2 }}>
Open a demo account
</Text>
<Form />
</Card>
</Flex>
<Box id="demo">
<Start stats={stats} />
</Box>
</Box>
<Footer dark key="footer" />
</>
)
}
export async function getStaticProps(context) {
const res = await fetch(`https://hcb.hackclub.com/stats`)
const stats = await res.json()
return {
props: {
stats
},
revalidate: 10
}
}

View file

@ -243,9 +243,9 @@ export default function FiscalSponsorship() {
as={Head}
title="Fiscal Sponsorship"
description="What is fiscal sponsorship?"
image="/bank/og-image.png"
image="/hcb/og-image.png"
>
<title>Fiscal Sponsorship Hack&nbsp;Club&nbsp;Bank</title>
<title>Fiscal Sponsorship | HCB</title>
</Meta>
<Container sx={{ textAlign: 'center', mt: 6 }}>
@ -283,7 +283,7 @@ export default function FiscalSponsorship() {
Requirements for fiscal sponsorship
</Link>
<Link sx={{ fontSize: 2 }} href="#partner">
Hack Club Bank, the #1 fiscal sponsor
HCB, the #1 fiscal sponsor
</Link>
</BulletBox>
</FlexCol>
@ -413,12 +413,10 @@ export default function FiscalSponsorship() {
</Section>
<Section id="partner">
<Text variant="title">
Hack&nbsp;Club&nbsp;Bank, the #1 fiscal sponsor
</Text>
<Text variant="title">HCB, the #1 fiscal sponsor</Text>
<Text variant="lead">
While many fiscal sponsors require that their partners relate to
their mission in similar ways, at Hack Club Bank, weve built our
their mission in similar ways, at HCB, weve built our
infrastructure to support hundreds of causes in all areas of
charitability.
</Text>
@ -437,8 +435,8 @@ export default function FiscalSponsorship() {
A customizable and embeddable donations URL
</Bullet>
<Bullet icon="card-add">
A bank account and routing number to connect to external
platforms, like Shopify and GoFundMe
A fun and routing number to connect to external platforms, like
Shopify and GoFundMe
</Bullet>
<Bullet icon="purse">
Perks like PVSA certification, newsletter software, and
@ -449,18 +447,17 @@ export default function FiscalSponsorship() {
Looking for nonprofit status and not a religious or political
organization? Wed love to meet you and chat about working
together. Feel free to apply
<Link href="https://hackclub.com/bank/#apply"> here </Link>or
<Link href="mailto:bank@hackclub.com"> email our team </Link>if
you have more questions about fiscal sponsorship!
<Link href="https://hackclub.com/hcb/#apply"> here </Link>or
<Link href="mailto:hcb@hackclub.com"> email our team </Link>if you
have more questions about fiscal sponsorship!
</Text>
</Section>
<Text variant="lead">
At its core, Hack Club is a nonprofit encouraging students to learn
how to code by building and making cool things.
Hack&nbsp;Club&nbsp;Bank was built out by teenagers at
Hack&nbsp;Club and continues to be a real-world space that high
schoolers can contribute to every day.
how to code by building and making cool things. HCB was built out by
teenagers at Hack&nbsp;Club and continues to be a real-world space
that high schoolers can contribute to every day.
</Text>
</FlexCol>
</Container>

View file

@ -4,12 +4,12 @@ import Head from 'next/head'
import ForceTheme from '../../components/force-theme'
import Nav from '../../components/nav'
import Footer from '../../components/footer'
import Landing from '../../components/bank/landing'
import Features from '../../components/bank/features'
import Testimonials from '../../components/bank/testimonials'
import Everything from '../../components/bank/everything'
import Start from '../../components/bank/start'
import Nonprofits from '../../components/bank/nonprofits'
import Landing from '../../components/hcb/landing'
import Features from '../../components/hcb/features'
import Testimonials from '../../components/hcb/testimonials'
import Everything from '../../components/hcb/everything'
import Start from '../../components/hcb/start'
import Nonprofits from '../../components/hcb/nonprofits'
const styles = `
html {
@ -34,10 +34,10 @@ export default function Bank({ stats }) {
<Meta
as={Head}
title="Fiscal Sponsorship"
description="Hack Club Bank is the largest fiscal sponsor of teen-led organizations in the US. Get a 501(c)(3) status-backed fund optimized for events, nonprofits, and more."
image="/bank/og-image.png"
description="HCB is the largest fiscal sponsor of teen-led organizations in the US. Get a 501(c)(3) status-backed fund optimized for events, nonprofits, and more."
image="/hcb/og-image.png"
>
<title>Fiscal Sponsorship Hack Club Bank</title>
<title>Fiscal Sponsorship HCB</title>
</Meta>
<style>{styles}</style>
<Box>
@ -59,7 +59,7 @@ export default function Bank({ stats }) {
}
export async function getStaticProps(context) {
const res = await fetch(`https://bank.hackclub.com/stats`)
const res = await fetch(`https://hcb.hackclub.com/stats`)
const stats = await res.json()
return {

View file

@ -1,16 +1,7 @@
import {
Box,
Button,
Card,
Grid,
Heading,
Flex,
Badge,
Link,
Text
} from 'theme-ui'
import React, { useEffect, useRef, useState } from 'react'
import {Badge, Box, Button, Card, Flex, Grid, Heading, Link, Text} from 'theme-ui'
import React, {useEffect, useRef, useState} from 'react'
import Head from 'next/head'
import {useRouter} from 'next/router'
import Meta from '@hackclub/meta'
import Nav from '../components/nav'
import BGImg from '../components/background-image'
@ -18,13 +9,13 @@ import ForceTheme from '../components/force-theme'
import Footer from '../components/footer'
import Stage from '../components/stage'
import Carousel from '../components/index/carousel'
import Outernet from '../components/index/cards/outernet'
import Pizza from '../components/index/cards/pizza'
import Sprig from '../components/index/cards/sprig'
import Sinerider from '../components/index/cards/sinerider'
import SprigConsole from '../components/index/cards/sprig-console'
import Clubs from '../components/index/cards/clubs'
import Workshops from '../components/index/cards/workshops'
import Bank from '../components/index/cards/bank'
import HCB from '../components/index/cards/hcb'
import Hackathons from '../components/index/cards/hackathons'
import OuternetImgFile from '../public/home/outernet-110.jpg'
import Announcement from '../components/announcement'
@ -38,6 +29,7 @@ import GitHub from '../components/index/github'
import Photo from '../components/photo'
import Comma from '../components/comma'
import Haxidraw from '../components/index/cards/haxidraw'
import Onboard from '../components/index/cards/onboard'
/** @jsxImportSource theme-ui */
@ -54,7 +46,8 @@ function Page({
game,
gameTitle,
events,
carouselCards
carouselCards,
context
}) {
let [gameImage, setGameImage] = useState('')
let [gameImage1, setGameImage1] = useState('')
@ -64,6 +57,8 @@ function Page({
let [slackKey, setSlackKey] = useState(0)
let [key, setKey] = useState(0)
const { asPath } = useRouter()
let jsConfetti = useRef()
useEffect(() => {
@ -295,7 +290,7 @@ function Page({
}}
title="📸 Photo by Matt Gleich, Hack Clubber in NH!"
>
Hackers at Outernet in VT
Hackers at Outernet in Vermont
</Badge>
</Box>
</Box>
@ -634,7 +629,7 @@ function Page({
and make things together!
</Text>
</Box>
<Outernet />
<Pizza />
<Slack slackKey={slackKey} data={slackData} events={events} />
</Box>
</Box>
@ -734,8 +729,8 @@ function Page({
img={data.userImage}
user={data.user}
time={data.time}
message={data.message}
url={data.url}
message={data.message}
key={key}
opacity={1 / (key/2 + 1)}
/>
@ -751,12 +746,13 @@ function Page({
gameImage={gameImage}
gameImage1={gameImage1}
/>
<Haxidraw />
<Onboard stars={stars.onboard.stargazerCount} delay={100} />
<Haxidraw stars={stars.blot.stargazerCount} delay={100} />
<Sinerider delay={200} stars={stars.sinerider.stargazerCount} />
<Box as="section" id="sprig">
<SprigConsole
delay={300}
stars={stars.sprigHardware.stargazerCount}
stars={stars.sprig.stargazerCount}
consoleCount={consoleCount}
/>
</Box>
@ -840,8 +836,9 @@ function Page({
data={hackathonsData}
stars={stars.hackathons.stargazerCount}
/>
{/* <Events events={events} /> */}
<Bank data={bankData} />
<HCB data={bankData} />
</Box>
</Box>
</Box>
@ -1071,6 +1068,76 @@ function Page({
</Box>
</Box>
</Box>
{new URL(asPath, 'http://example.com').searchParams.get('gen') ===
'z' && (
<>
<Box
sx={{
position: 'fixed',
top: 0,
width: '100%',
zIndex: 1000
}}
>
<Box
sx={{
position: 'relative',
margin: 'auto',
width: 'fit-content',
lineHeight: 0
}}
>
<iframe
width="560"
height="315"
src="https://www.youtube-nocookie.com/embed/sJNK4VKeoBM?si=zvhDKhb9C5G2b4TJ&controls=1&autoplay=1&mute=1"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
</Box>
</Box>
<Box
sx={{
position: 'fixed',
bottom: 0,
right: 0,
zIndex: 1000,
lineHeight: 0
}}
>
<iframe
width="560"
height="315"
src="https://www.youtube-nocookie.com/embed/ChBg4aowzX8?si=X2J_T95yiaKXB2q4&controls=1&autoplay=1&mute=1"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
</Box>
<Box
sx={{
position: 'fixed',
bottom: 0,
left: 0,
zIndex: 1000,
lineHeight: 0
}}
>
<iframe
width="560"
height="315"
src="https://www.youtube-nocookie.com/embed/JDQr1vICu54?si=U6-9AFtk7EdTabfp&autoplay=1&mute=1"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen
></iframe>
</Box>
</>
)}
<MailingList />
<Footer
dark
@ -1103,7 +1170,7 @@ export async function getStaticProps() {
// HCB: get total raised
let bankData = []
let initialBankData = await fetch('https://bank.hackclub.com/stats').then(r =>
let initialBankData = await fetch('https://hcb.hackclub.com/stats').then(r =>
r.json()
)
let raised = initialBankData.raised / 100
@ -1145,9 +1212,20 @@ export async function getStaticProps() {
const consoleCount = await getConsoles()
// Hackathons: get latest hackathons
const hackathonsData = await fetch(
'https://hackathons.hackclub.com/api/events/upcoming'
).then(res => res.json())
let hackathonsData
try {
const response = await fetch(
'https://hackathons.hackclub.com/api/events/upcoming'
)
if (response.ok) {
hackathonsData = await response.json()
} else {
hackathonsData = [] // or some default value if the fetch fails
}
} catch (error) {
hackathonsData = [] // or some default value if an error occurs
}
hackathonsData.sort((a, b) => new Date(a.start) - new Date(b.start));
let events = await fetch(
'https://events.hackclub.com/api/events/upcoming/'

View file

@ -2,16 +2,16 @@ import { BaseStyles, Box, Container, Heading, Text } from 'theme-ui'
import Head from 'next/head'
import Nav from '../../components/nav'
import Meta from '@hackclub/meta'
import JobDescription from '../../components/jobs/bank-ops-associate/jd.mdx'
import JobDescription from '../../components/jobs/hcb-ops-associate/jd.mdx'
import ForceTheme from '../../components/force-theme'
const Page = () => (
<>
<Meta
as={Head}
title="Bank Operations Associate"
description="Hack Club is a hiring a Bank Operations Associate as the 8th full-time member of our team in Burlington, Vermont."
image="https://workshop-cards.hackclub.com/Bank%20Ops%20Associate%20%40%20Hack%20Club.png?fontSize=175px&brand=HQ"
title="HCB Operations Associate"
description="Hack Club is a hiring a HCB Operations Associate as the 8th full-time member of our team in Burlington, Vermont."
image="https://workshop-cards.hackclub.com/hcb%20Ops%20Associate%20%40%20Hack%20Club.png?fontSize=175px&brand=HQ"
/>
<ForceTheme theme="light" />
<Nav />
@ -25,7 +25,7 @@ const Page = () => (
>
<Container sx={{ textAlign: 'center', color: 'white' }}>
<Heading as="h1" variant="title" mb={30}>
Bank Operations Associate
HCB Operations Associate
</Heading>
<Text variant="headline" sx={{ fontWeight: 400 }}>
New job open as of May 21st, 2021.

View file

@ -2,16 +2,16 @@ import { BaseStyles, Box, Container, Heading, Text } from 'theme-ui'
import Head from 'next/head'
import Nav from '../../components/nav'
import Meta from '@hackclub/meta'
import JobDescription from '../../components/jobs/bank-ops-lead/jd.mdx'
import JobDescription from '../../components/jobs/hcb-ops-lead/jd.mdx'
import ForceTheme from '../../components/force-theme'
const Page = () => (
<>
<Meta
as={Head}
title="Bank Operations Lead"
description="Hack Club is a hiring a Bank Operations Lead as the 7th full-time member of our team in Burlington, Vermont."
image="https://workshop-cards.hackclub.com/Bank%20Ops%20Lead%20%40%20Hack%20Club.png?fontSize=175px&brand=HQ"
title="HCB Operations Lead"
description="Hack Club is a hiring a HCB Operations Lead as the 7th full-time member of our team in Burlington, Vermont."
image="https://workshop-cards.hackclub.com/hcb%20Ops%20Lead%20%40%20Hack%20Club.png?fontSize=175px&brand=HQ"
/>
<ForceTheme theme="light" />
<Nav />
@ -25,7 +25,7 @@ const Page = () => (
>
<Container sx={{ textAlign: 'center', color: 'white' }}>
<Heading as="h1" variant="title" mb={30}>
Bank Operations Lead
HCB Operations Lead
</Heading>
<Text variant="headline" sx={{ fontWeight: 400 }}>
Closed as of March 5th, 2021.

View file

@ -11,7 +11,7 @@ const Page = () => (
<Meta
as={Head}
title="Lead Hacker"
description="Hack Club is a hiring a Lead Hacker for Hack Club Bank as the 9th full-time member of our team in Burlington, Vermont."
description="Hack Club is a hiring a Lead Hacker for HCB as the 9th full-time member of our team in Burlington, Vermont."
image="https://workshop-cards.hackclub.com/Lead%20Hacker.png?theme=light&md=1&fontSize=250px&caption=Open%2520Role%2520%2540%2520Hack%2520Club%2520Bank&brand=HQ&md=true"
/>
<ForceTheme theme="light" />
@ -27,7 +27,7 @@ const Page = () => (
>
<Container sx={{ textAlign: 'center', color: 'white' }}>
<Heading as="h1" variant="title" mb={30}>
Lead Hacker @&nbsp;Hack&nbsp;Club Bank
Lead Hacker @&nbsp;HCB
</Heading>
<Text variant="headline" sx={{ fontWeight: 400 }}>
This position has been filled as of June 14th, 2022.
@ -46,20 +46,20 @@ const Page = () => (
variant="headline"
sx={{ fontWeight: 700, fontSize: [4, 5], mb: 4 }}
>
Hack Club is (no longer) hiring a Lead Hacker for Hack Club Bank.
Hack Club is (no longer) hiring a Lead Hacker for HCB.
</Heading>
<Text as="p" mb={4}>
Starting a nonprofit is hard, so we built{' '}
<Link href="/bank" target="_blank">
Hack Club Bank
<Link href="/hcb" target="_blank">
HCB
</Link>{' '}
for our community of {formatted}+ teenage programmers. Within 24 hours
of joining Bank, organizations get 501(c)(3) nonprofit status, access to
of joining HCB, organizations get 501(c)(3) nonprofit status, access to
a beautiful dashboard for managing their finances, and all financial and
legal matters - from tax filings to payroll - handled. 50% of high
school hackathons worldwide run on Hack Club Bank, and Elon Musk has
tweeted that we're a{' '}
school hackathons worldwide run on HCB, and Elon Musk has tweeted that
we're a{' '}
<Link
href="https://twitter.com/elonmusk/status/1263275969743216640"
target="_blank"
@ -71,9 +71,9 @@ const Page = () => (
</Text>
<Text as="p" mb={4}>
Now, Hack Club Bank is expanding beyond just Hack Clubbers.{' '}
Now, HCB is expanding beyond just Hack Clubbers.{' '}
<strong>
Over 500 organizations running on Bank have transacted upwards of
Over 500 organizations running on HCB have transacted upwards of
$5,000,000;
</strong>{' '}
from teenage-run hackathons to{' '}
@ -88,11 +88,11 @@ const Page = () => (
</Text>
<Text as="p">
With the right leadership, we hope to bring Hack Club Bank to thousands
of organizations across the United States and process tens of millions
of dollars in transactions. We think do-gooders need the same tools that
software engineers do. For them, Bank is like GitHub: transformative.
Right now, Bank is the{' '}
With the right leadership, we hope to bring HCB to thousands of
organizations across the United States and process tens of millions of
dollars in transactions. We think do-gooders need the same tools that
software engineers do. For them, HCB is like GitHub: transformative.
Right now, HCB is the{' '}
<strong>
only part of Hack Club that isn't{' '}
<Link
@ -185,41 +185,41 @@ const Page = () => (
variant="headline"
sx={{ fontWeight: 700, fontSize: [4, 5], mb: 4 }}
>
Make Bank even more awesome.
Make HCB even more awesome.
</Heading>
<Box sx={{ p: { my: [3, 4] } }}>
<Text as="p">
Bank has been maintained by a{' '}
HCB has been maintained by a{' '}
<Link href="/team/" target="_blank">
{' '}
small team
</Link>{' '}
of two full-time operations people, and on-and-off contributions by
engineers and various contractors. The majority of{' '}
<Link href="https://changelog.bank.hackclub.com/" target="_blank">
<Link href="https://changelog.hcb.hackclub.com/" target="_blank">
contributions
</Link>{' '}
are actually made by teenagers! In this role, you'll take point on
bringing Bank to its full potential.
bringing HCB to its full potential.
</Text>
<Text as="p">
Hack Club Bank already powers{' '}
<Link href="https://bank.hackclub.com/hq" target="_blank">
HCB already powers{' '}
<Link href="https://hcb.hackclub.com/hq" target="_blank">
our own transparent finances
</Link>{' '}
as well as those of{' '}
<Link
href="https://bank.hackclub.com/miami-hack-week/"
href="https://hcb.hackclub.com/miami-hack-week/"
target="_blank"
>
many
</Link>{' '}
<Link href="https://bank.hackclub.com/mesto/" target="_blank">
<Link href="https://hcb.hackclub.com/mesto/" target="_blank">
other
</Link>{' '}
<Link href="https://bank.hackclub.com/techshift/" target="_blank">
<Link href="https://hcb.hackclub.com/techshift/" target="_blank">
organizations
</Link>
. These are just some of the initiatives we support:
@ -283,11 +283,11 @@ const Page = () => (
</Grid>
<Text as="p">
Like a CTO, you'll work directly with real users to define Bank's
roadmap around <strong>making Bank better for Hack Clubbers.</strong>{' '}
Like a CTO, you'll work directly with real users to define HCB's
roadmap around <strong>making HCB better for Hack Clubbers.</strong>{' '}
You will build and lead a team of Hack Clubbers to create a shipping
culture around Bank, and lead and manage relationships with technical
partners who integrate Bank into their products.
culture around HCB, and lead and manage relationships with technical
partners who integrate HCB into their products.
</Text>
<Text as="p">
@ -306,9 +306,9 @@ const Page = () => (
>
jobs@hackclub.com
</Link>{' '}
with "Hack Club Bank" in the subject line, 3 bullet points
demonstrating why you would be exceptional for the role, and your
resume / GitHub / GitLab / sourcehut.
with "HCB" in the subject line, 3 bullet points demonstrating why you
would be exceptional for the role, and your resume / GitHub / GitLab /
sourcehut.
</Box>
</Box>

View file

@ -99,8 +99,7 @@ const Page = () => (
hang out on a chill call.
</Text>
<Text as="p" variant="subtitle">
Join in Saturdays at 1pm or 11pm UTC, and Wednesdays at 6pm UTC, or
join or start an impromptu Hack session on{' '}
Hack nights are hosted regularly by Hack Clubbers. Come join or start an impromptu Hack session on{' '}
<NextLink href="/slack" passHref>
<Link sx={{ color, opacity: 0.75 }}>#hack-night</Link>
</NextLink>

1194
pages/onboard/first.js Normal file

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more