mirror of
https://github.com/System-End/site.git
synced 2026-04-19 19:45:07 +00:00
From question and copy edits with Mel
This commit is contained in:
parent
4c79cf99e0
commit
afa8fad66e
15 changed files with 357 additions and 217 deletions
|
|
@ -1,11 +1,10 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { useRef, useState } from 'react'
|
||||
import { Alert, Heading, Button } from 'theme-ui'
|
||||
import { Alert, Button, Text } from 'theme-ui'
|
||||
import FormContainer from './form-container'
|
||||
import OrganizationInfoForm from './org-form'
|
||||
import PersonalInfoForm from './personal-form'
|
||||
import { onSubmit } from './submit'
|
||||
import Callout from './callout'
|
||||
import TeenagerOrAdultForm from './teenager-or-adult-form'
|
||||
import MultiStepForm from './multi-step-form'
|
||||
|
||||
|
|
@ -18,18 +17,27 @@ export default function ApplicationForm() {
|
|||
const requiredFields = {
|
||||
// Key: form field name
|
||||
// Value: humanize field name used in error message
|
||||
eventName: 'organization name',
|
||||
eventLocation: 'organization country',
|
||||
eventPostalCode: 'organization zip/postal code',
|
||||
eventDescription: 'organization description',
|
||||
eventTeenagerLed: 'are you a teenager?',
|
||||
eventPoliticalActivity: "organization's political activity",
|
||||
eventAnnualBudget: 'organization annual budget',
|
||||
eventName: 'project name',
|
||||
eventPostalCode: 'project zip/postal code',
|
||||
eventDescription: 'project description',
|
||||
eventIsPolitical: "project's political activity",
|
||||
eventPoliticalActivity: "project's political activity",
|
||||
eventHasWebsite: 'project website',
|
||||
eventWebsite: 'project website',
|
||||
eventAnnualBudget: 'project annual budget',
|
||||
firstName: 'first name',
|
||||
lastName: 'last name',
|
||||
userEmail: 'email',
|
||||
userPhone: 'phone number',
|
||||
userBirthday: 'birthday'
|
||||
userBirthday: 'birthday',
|
||||
userAddressLine1: 'address line 1',
|
||||
userAddressCity: 'city',
|
||||
userAddressProvince: 'state/province',
|
||||
userAddressPostalCode: 'ZIP/postal code',
|
||||
userAddressCountry: 'country',
|
||||
|
||||
referredBy: 'how did you hear about HCB?'
|
||||
}
|
||||
|
||||
const submitButton = (
|
||||
|
|
@ -66,14 +74,27 @@ export default function ApplicationForm() {
|
|||
})
|
||||
}
|
||||
>
|
||||
<MultiStepForm submitButton={submitButton}>
|
||||
<MultiStepForm
|
||||
submitButton={submitButton}
|
||||
validationErrors={
|
||||
formError && (
|
||||
<Alert bg="primary" sx={{ mt: 4 }}>
|
||||
{formError}
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
>
|
||||
{/* Step 1 */}
|
||||
<MultiStepForm.Step title="Let's get started">
|
||||
<Callout />
|
||||
<Text as="p" variant="caption" sx={{ marginBottom: '2rem' }}>
|
||||
Fill out this quick application to run your project on HCB. If you
|
||||
are a teenager, there is a very high likelihood we will accept your
|
||||
project. We just need to collect a few pieces of information first.
|
||||
</Text>
|
||||
<TeenagerOrAdultForm requiredFields={requiredFields} />
|
||||
</MultiStepForm.Step>
|
||||
{/* Step 2 */}
|
||||
<MultiStepForm.Step title="Your organization">
|
||||
<MultiStepForm.Step>
|
||||
<OrganizationInfoForm requiredFields={requiredFields} />
|
||||
</MultiStepForm.Step>
|
||||
{/* Step 3 */}
|
||||
|
|
@ -81,7 +102,6 @@ export default function ApplicationForm() {
|
|||
<PersonalInfoForm requiredFields={requiredFields} />
|
||||
</MultiStepForm.Step>
|
||||
</MultiStepForm>
|
||||
{formError && <Alert bg="primary">{formError}</Alert>}
|
||||
</FormContainer>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
import { Box, Text } from 'theme-ui'
|
||||
|
||||
export default function Callout() {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
borderLeft: '3px solid',
|
||||
borderLeftColor: 'blue',
|
||||
paddingLeft: 2,
|
||||
color: 'blue',
|
||||
fontSize: 1,
|
||||
textWrap: 'pretty',
|
||||
lineHeight: 1.375,
|
||||
marginBottom: '2rem'
|
||||
}}
|
||||
>
|
||||
<Text as="p" sx={{ fontWeight: 'bold' }}>
|
||||
HCB is a fiscal sponsor primarily for teenage-led organizations
|
||||
</Text>
|
||||
<Text as="p" sx={{ mt: 1, textWrap: 'balance' }}>
|
||||
Although we would love to be able to support organizations across all
|
||||
ages and missions, we are currently prioritizing applications from
|
||||
teenagers.
|
||||
</Text>
|
||||
<Text as="p" sx={{ mt: 1, textWrap: 'balance' }}>
|
||||
We are accepting adult-led organizations on a case-by-case basis.
|
||||
</Text>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
|
@ -18,10 +18,17 @@ export default function Field({
|
|||
useEffect(() => {
|
||||
const value =
|
||||
router.query[name] || sessionStorage.getItem('bank-signup-' + name)
|
||||
if (value) {
|
||||
const input = document.getElementById(name)
|
||||
if (input) input.value = value
|
||||
if (!value) return
|
||||
|
||||
let input = document.getElementById(name)
|
||||
if (input) {
|
||||
input.value = value
|
||||
return
|
||||
}
|
||||
|
||||
// Maybe it's radio buttons
|
||||
input = document.querySelector(`input[name='${name}']`)
|
||||
if (input) input.checked = true
|
||||
}, [router.query, name])
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -12,10 +12,14 @@ const formContainer = forwardRef(({ children, ...props }, ref) => {
|
|||
bg: 'snow',
|
||||
px: [3, 5],
|
||||
py: [1, 5],
|
||||
minHeight: '100dvb',
|
||||
pb: 5,
|
||||
minHeight: [null, null, '100dvb'],
|
||||
'&.has-errors div[aria-required="true"] input:placeholder-shown': {
|
||||
borderColor: 'primary'
|
||||
},
|
||||
'&.has-errors div[aria-required="true"] input[type="date"]': {
|
||||
borderColor: 'primary'
|
||||
},
|
||||
'&.has-errors div[aria-required="true"] textarea:placeholder-shown': {
|
||||
borderColor: 'primary'
|
||||
}
|
||||
|
|
@ -26,10 +30,6 @@ const formContainer = forwardRef(({ children, ...props }, ref) => {
|
|||
variant="copy"
|
||||
sx={{
|
||||
ml: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
columnGap: 4,
|
||||
rowGap: 3,
|
||||
px: 0
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Box, Link, Heading } from 'theme-ui'
|
||||
import { Box, Link, Heading, Grid } from 'theme-ui'
|
||||
import Icon from '../../icon'
|
||||
import { useMultiStepContext } from './multi-step-context'
|
||||
import { useEffect } from 'react'
|
||||
|
|
@ -19,7 +19,7 @@ export default function HCBInfo() {
|
|||
}}
|
||||
>
|
||||
<Heading variant="subheadline">
|
||||
HCB is a{' '}
|
||||
HCB is not a bank, we're a{' '}
|
||||
<Link
|
||||
href="https://en.wikipedia.org/wiki/Fiscal_sponsorship"
|
||||
target="_blank"
|
||||
|
|
@ -33,26 +33,23 @@ export default function HCBInfo() {
|
|||
<Icon glyph="external" size={24} aria-hidden />
|
||||
</Link>
|
||||
</Heading>
|
||||
{/* <Grid columns={2} bg="white" sx={{ color: 'muted', border: 'slate 1px' }}>
|
||||
<Box>Gives your project nonprofit status.</Box>
|
||||
</Grid> */}
|
||||
|
||||
<ul>
|
||||
<li>Gives your project nonprofit status.</li>
|
||||
<li>Enables tax-deductible donations.</li>
|
||||
<li>
|
||||
HCB is not a bank. We partner partner with{' '}
|
||||
<Link href="https://column.com" target="_blank">
|
||||
Column N.A.
|
||||
</Link>{' '}
|
||||
to offer restricted funds to fiscally-sponsored projects.
|
||||
</li>
|
||||
</ul>
|
||||
<Heading variant="subheadline">
|
||||
HCB provides a financial platform.
|
||||
</Heading>
|
||||
<ul>
|
||||
<li>Accessed via a beautiful, modern interface.</li>
|
||||
<li>Provides a donation page and invoicing system.</li>
|
||||
<li>Transfer money electronically.</li>
|
||||
<li>Order cards for you and your team to make purchases.</li>
|
||||
<li>HCB gives your project nonprofit status.</li>
|
||||
<li>Allows you to raise tax-deductible donations.</li>
|
||||
<li>Provides a financial platform.</li>
|
||||
<li>Allows you to order cards to make purchases.</li>
|
||||
</ul>
|
||||
<p>
|
||||
HCB partners with{' '}
|
||||
<Link href="https://column.com" target="_blank">
|
||||
Column N.A.
|
||||
</Link>{' '}
|
||||
to provide restricted funds to fiscally-sponsored projects.
|
||||
</p>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ import { Box, Button, Heading } from 'theme-ui'
|
|||
import { useMultiStepContext } from './multi-step-context'
|
||||
import { Children } from 'react'
|
||||
|
||||
export default function MultiStepForm({ children, submitButton }) {
|
||||
export default function MultiStepForm({
|
||||
children,
|
||||
submitButton,
|
||||
validationErrors
|
||||
}) {
|
||||
const { step, useStepper } = useMultiStepContext()
|
||||
const steps = Children.toArray(children)
|
||||
const { nextStep, previousStep } = useStepper(steps)
|
||||
|
|
@ -14,17 +18,27 @@ export default function MultiStepForm({ children, submitButton }) {
|
|||
with the form. So, we simple hide all non-current steps.
|
||||
*/}
|
||||
{steps.map((stepComponent, index) => (
|
||||
<Box key={index} sx={step !== index ? { display: 'none' } : {}}>
|
||||
<Box
|
||||
key={index}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
rowGap: 3,
|
||||
...(step !== index ? { display: 'none' } : {})
|
||||
}}
|
||||
>
|
||||
{stepComponent}
|
||||
</Box>
|
||||
))}
|
||||
|
||||
{validationErrors}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
marginTop: '2rem',
|
||||
marginLeft: 'auto'
|
||||
justifyContent: 'flex-end'
|
||||
}}
|
||||
>
|
||||
{step > 0 && (
|
||||
|
|
|
|||
|
|
@ -11,23 +11,6 @@ export default function OrganizationAdultForm({ requiredFields }) {
|
|||
<>
|
||||
{teenagerLed !== 'true' && (
|
||||
<>
|
||||
<Field
|
||||
name="eventPoliticalActivity"
|
||||
label={`Please describe any political activity your ${org.toLowerCase()} is involved in, if any`}
|
||||
description="This includes but is not limited to protests, public demonstrations, political education, and lobbying."
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Textarea
|
||||
name="eventPoliticalActivity"
|
||||
id="eventPoliticalActivity"
|
||||
placeholder="We are involved in..."
|
||||
rows={3}
|
||||
sx={{
|
||||
resize: 'vertical'
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="eventAnnualBudget"
|
||||
label="What is your estimated annual budget (USD) for this year?"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,51 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { Input, Select, Textarea } from 'theme-ui'
|
||||
import { Input, Link, Select, Text, Textarea } from 'theme-ui'
|
||||
import Checkbox from './checkbox'
|
||||
import Field from './field'
|
||||
// This is using country-list instead of country-list-js as it has a smaller bundle size
|
||||
import { getNames } from 'country-list'
|
||||
import useOrganizationI18n from '../organizationI18n'
|
||||
import OrganizationAdultForm from './org-adult-form'
|
||||
import { useTeenagerLedContext } from './teenager-led-context'
|
||||
|
||||
export default function OrganizationInfoForm({ requiredFields }) {
|
||||
const org = useOrganizationI18n()
|
||||
|
||||
const { teenagerLed } = useTeenagerLedContext()
|
||||
|
||||
const [hasWebsite, setHasWebsite] = useState(true)
|
||||
const onHasWebsiteChange = e => {
|
||||
const newValue = e.target.value === 'true'
|
||||
setHasWebsite(newValue)
|
||||
}
|
||||
|
||||
const [isPolitical, setIsPolitical] = useState(null)
|
||||
const onIsPoliticalChange = e => {
|
||||
const newValue = e.target.value === 'true'
|
||||
setIsPolitical(newValue)
|
||||
}
|
||||
|
||||
const politicalActivityTextarea = admittedToActivity => (
|
||||
<Field
|
||||
name="eventPoliticalActivity"
|
||||
label={`Please describe ${admittedToActivity ? 'the' : 'any'} political activity your ${org.toLowerCase()} is involved in${admittedToActivity ? '.' : ', if any.'}`}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Textarea
|
||||
name="eventPoliticalActivity"
|
||||
id="eventPoliticalActivity"
|
||||
placeholder="We are involved in..."
|
||||
rows={3}
|
||||
sx={{
|
||||
resize: 'vertical'
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
)
|
||||
|
||||
const noPoliticalActivity = (
|
||||
<input type="hidden" name="eventPoliticalActivity" value="None." />
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Field
|
||||
|
|
@ -23,48 +59,102 @@ export default function OrganizationInfoForm({ requiredFields }) {
|
|||
placeholder="Shelburne School Hackathon"
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="eventWebsite"
|
||||
label={`${org} website`}
|
||||
description="If you don’t have one yet, you can leave this blank."
|
||||
name="eventDescription"
|
||||
label={`Tell us about your ${org.toLowerCase()}`}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input
|
||||
name="eventWebsite"
|
||||
id="eventWebsite"
|
||||
inputMode="url"
|
||||
placeholder="hackclub.com"
|
||||
<Text variant="caption">
|
||||
Are you running a hackathon, robotics team, organizing a nonprofit,
|
||||
building a project, etc.?
|
||||
</Text>
|
||||
<Textarea
|
||||
name="eventDescription"
|
||||
id="eventDescription"
|
||||
rows={3}
|
||||
sx={{
|
||||
resize: 'vertical'
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
name="eventLocation"
|
||||
label={`Primary country of operations`}
|
||||
label="Does your project have a website?"
|
||||
name="eventHasWebsite"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Select name="eventLocation" id="eventLocation">
|
||||
{getNames()
|
||||
.sort()
|
||||
.sort(item => (item === 'United States of America' ? -1 : 1))
|
||||
.map(country => (
|
||||
<option key={country} value={country}>
|
||||
{country}
|
||||
</option>
|
||||
))}
|
||||
<Select
|
||||
onChange={onHasWebsiteChange}
|
||||
value={hasWebsite ? 'true' : 'false'}
|
||||
>
|
||||
{Object.entries({ Yes: 'true', No: 'false' }).map(([name, value]) => (
|
||||
<option key={name} value={value}>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</Field>
|
||||
<Field
|
||||
name="eventPostalCode"
|
||||
label={`ZIP code / postal code`}
|
||||
description="If your organization runs online, please put your own postal code."
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input
|
||||
name="eventPostalCode"
|
||||
id="eventPostalCode"
|
||||
placeholder="90069"
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
|
||||
{
|
||||
hasWebsite ? (
|
||||
<Field
|
||||
name="eventWebsite"
|
||||
label={`${org} website`}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input
|
||||
name="eventWebsite"
|
||||
id="eventWebsite"
|
||||
inputMode="url"
|
||||
placeholder="hackclub.com"
|
||||
/>
|
||||
</Field>
|
||||
) : teenagerLed === 'true' ? (
|
||||
<Text variant="caption">
|
||||
A website is not required to apply for HCB. However, most successful
|
||||
projects that raise money have a custom-build website. If you've
|
||||
never built a website before, checkout{' '}
|
||||
<Link href="https://boba.hackclub.com/">Boba Drops</Link>, a Hack
|
||||
Club workshop on how to build a website.
|
||||
</Text>
|
||||
) : null /* don't show Boba Drops to adult-led orgs lol*/
|
||||
}
|
||||
|
||||
{teenagerLed === 'true' ? (
|
||||
<>
|
||||
<Field
|
||||
name="eventIsPolitical"
|
||||
label="Is your project involved with political activity?"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Select
|
||||
name="eventIsPolitical"
|
||||
onChange={onIsPoliticalChange}
|
||||
value={isPolitical ? 'true' : 'false'}
|
||||
>
|
||||
{Object.entries({ Yes: 'true', No: 'false' }).map(
|
||||
([name, value]) => (
|
||||
<option key={name} value={value}>
|
||||
{name}
|
||||
</option>
|
||||
)
|
||||
)}
|
||||
</Select>
|
||||
</Field>
|
||||
{isPolitical ? politicalActivityTextarea(true) : noPoliticalActivity}
|
||||
</>
|
||||
) : (
|
||||
// Adults always get the text area
|
||||
politicalActivityTextarea(false)
|
||||
)}
|
||||
<Text variant="caption">
|
||||
This includes but is not limited to protests, public demonstrations,
|
||||
political education, and lobbying.
|
||||
</Text>
|
||||
|
||||
{/* Move transparency mode prompt to HCB onboarding */}
|
||||
{/* <Field
|
||||
name="transparent"
|
||||
label="Transparency mode"
|
||||
col={true}
|
||||
|
|
@ -77,22 +167,7 @@ export default function OrganizationInfoForm({ requiredFields }) {
|
|||
requiredFields={requiredFields}
|
||||
>
|
||||
<Checkbox defaultChecked={true} name="transparent" />
|
||||
</Field>
|
||||
<Field
|
||||
name="eventDescription"
|
||||
label={`Tell us about your ${org.toLowerCase()}`}
|
||||
description="2–4 sentences will suffice."
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Textarea
|
||||
name="eventDescription"
|
||||
id="eventDescription"
|
||||
rows={3}
|
||||
sx={{
|
||||
resize: 'vertical'
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
</Field> */}
|
||||
|
||||
<OrganizationAdultForm requiredFields={requiredFields} />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { Input, Flex, Label, Radio, Grid, Select } from 'theme-ui'
|
||||
import { Input, Flex, Label, Radio, Grid, Select, Box, Text } from 'theme-ui'
|
||||
import Field from './field'
|
||||
import Checkbox from './checkbox'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTeenagerLedContext } from './teenager-led-context'
|
||||
import { getNames } from 'country-list'
|
||||
|
||||
export default function PersonalInfoForm({ requiredFields }) {
|
||||
const [selectedContactOption, setSelectedContactOption] = useState('Email')
|
||||
|
|
@ -41,9 +42,9 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
label="Preferred contact channel"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Grid
|
||||
columns={[null, 2]}
|
||||
<Flex
|
||||
sx={{
|
||||
flexDirection: ['column', 'row'],
|
||||
rowGap: 2,
|
||||
columnGap: 4,
|
||||
width: '100%'
|
||||
|
|
@ -52,7 +53,8 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
<Label
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
width: 'fit-content'
|
||||
}}
|
||||
>
|
||||
<Radio
|
||||
|
|
@ -67,7 +69,8 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
sx={{
|
||||
columnGap: 0,
|
||||
rowGap: 2,
|
||||
gridTemplateColumns: 'auto 1fr'
|
||||
gridTemplateColumns: 'auto 1fr',
|
||||
flexGrow: 1
|
||||
}}
|
||||
>
|
||||
<Label
|
||||
|
|
@ -104,7 +107,7 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
</>
|
||||
) : null}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Field>
|
||||
) : (
|
||||
// When not teenage-led, default to "email" as preferred contact channel
|
||||
|
|
@ -126,37 +129,77 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
</Field>
|
||||
<Field
|
||||
name="userBirthday"
|
||||
label="Birth year"
|
||||
label="Birthday"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Select name="userBirthday" id="userBirthday" defaultValue="">
|
||||
<option value="" disabled>
|
||||
Select a year
|
||||
</option>
|
||||
{/* show a century of years starting from 13 years ago */}
|
||||
{Array.from({ length: 98 }, (_, i) => {
|
||||
const year = new Date().getFullYear() - 13 - i
|
||||
return (
|
||||
<option key={year} value={year}>
|
||||
{year}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
<Input type="date" name="userBirthday" />
|
||||
</Field>
|
||||
|
||||
{/* <Field
|
||||
<Flex sx={{ flexDirection: 'column', gap: 1 }}>
|
||||
<Field
|
||||
name="userAddressLine1"
|
||||
label={'Your personal address'}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input
|
||||
name="userAddressLine1"
|
||||
placeholder="8605 Santa Monica Blvd, Suite 86294"
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Grid columns={2} gap={1}>
|
||||
<Field
|
||||
name="userAddressCity"
|
||||
label={<Text sx={{ fontSize: 1 }}>City</Text>}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input name="userAddressCity" placeholder="Santa Monica" />
|
||||
</Field>
|
||||
<Field
|
||||
name="userAddressProvince"
|
||||
label={<Text sx={{ fontSize: 1 }}>State / Province</Text>}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input name="userAddressProvince" placeholder="California" />
|
||||
</Field>
|
||||
<Field
|
||||
name="userAddressPostalCode"
|
||||
label={<Text sx={{ fontSize: 1 }}>ZIP / Postal code</Text>}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input name="userAddressPostalCode" placeholder="90069" />
|
||||
</Field>
|
||||
<Field
|
||||
name="userAddressCountry"
|
||||
label={<Text sx={{ fontSize: 1 }}>Country</Text>}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Select name="userAddressCountry" id="userAddressCountry">
|
||||
{getNames()
|
||||
.sort()
|
||||
.sort(item => (item === 'United States of America' ? -1 : 1))
|
||||
.map(country => (
|
||||
<option key={country} value={country}>
|
||||
{country}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</Field>
|
||||
</Grid>
|
||||
</Flex>
|
||||
|
||||
<Field
|
||||
name="referredBy"
|
||||
label="Who were you referred by?"
|
||||
label="How did you hear about HCB?"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Input
|
||||
name="referredBy"
|
||||
id="referredBy"
|
||||
placeholder="Max"
|
||||
placeholder="Word of mouth, an event, etc. Be specific!"
|
||||
/>
|
||||
</Field>
|
||||
*/}
|
||||
|
||||
<Field
|
||||
name="returningUser"
|
||||
label="Have you used HCB before?"
|
||||
|
|
@ -165,19 +208,7 @@ export default function PersonalInfoForm({ requiredFields }) {
|
|||
>
|
||||
<Checkbox name="returningUser" />
|
||||
</Field>
|
||||
{/* <Field
|
||||
name="userAddress"
|
||||
label="Address"
|
||||
description="This is so we can send you some swag and goodies if you ever request them!"
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<AddressInput
|
||||
name="userAddress"
|
||||
isPersonalAddressInput={true}
|
||||
setValidationResult={setValidationResult}
|
||||
/>
|
||||
</Field>
|
||||
*/}
|
||||
|
||||
<Field
|
||||
name="accommodations"
|
||||
label="Accessibility needs"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export function onSubmit({
|
|||
const isAdult = formData.get('eventTeenagerLed') !== 'true'
|
||||
const acceptanceEta = isAdult
|
||||
? 'within two weeks'
|
||||
: 'within two business days'
|
||||
: 'within 24 hours on weekdays and 48 hours on weekends'
|
||||
|
||||
router.push(`/fiscal-sponsorship/apply/success?eta=${acceptanceEta}`)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const TeenagerLedContext = createContext()
|
|||
const useTeenagerLedContext = () => useContext(TeenagerLedContext)
|
||||
|
||||
const TeenagerLedProvider = ({ children }) => {
|
||||
const [teenagerLed, setTeenagerLed] = useState('false')
|
||||
const [teenagerLed, setTeenagerLed] = useState('true')
|
||||
|
||||
return (
|
||||
<TeenagerLedContext.Provider value={{ teenagerLed, setTeenagerLed }}>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect } from 'react'
|
||||
import { Select } from 'theme-ui'
|
||||
import { Flex, Input, Label, Radio, Select } from 'theme-ui'
|
||||
import Field from './field'
|
||||
import { useTeenagerLedContext } from './teenager-led-context'
|
||||
|
||||
|
|
@ -24,37 +24,72 @@ export default function TeenagerOrAdultForm({ requiredFields }) {
|
|||
// `teenagerLed` state may not be synced with the DOM input value. This code
|
||||
// syncs `teenagerLed` with the DOM input value.
|
||||
// NOTE: This depends on Field's useEffect hook to run first.
|
||||
const eventTeenagerLedElm = document.getElementById('eventTeenagerLed')
|
||||
setTeenagerLed(eventTeenagerLedElm.value)
|
||||
const eventTeenagerLedElm = document.querySelector(
|
||||
'input[name="eventTeenagerLed"]:checked'
|
||||
)
|
||||
if (eventTeenagerLedElm) setTeenagerLed(eventTeenagerLedElm.value)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Field
|
||||
name="eventTeenagerLed"
|
||||
label={'Are you a teenager?'}
|
||||
col={true}
|
||||
description={'18 and under'}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Select
|
||||
name="eventTeenagerLed"
|
||||
id="eventTeenagerLed"
|
||||
onChange={onTeenagerLedChange}
|
||||
value={teenagerLed}
|
||||
<Field
|
||||
name="eventTeenagerLed"
|
||||
label={'Are you a teenager?'}
|
||||
col={true}
|
||||
description={'18 and under'}
|
||||
requiredFields={requiredFields}
|
||||
>
|
||||
<Flex columns={2} sx={{ gap: 3 }}>
|
||||
<Label
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
backgroundColor: ' rgba(91,192,222,.25)',
|
||||
borderRadius: '.75rem',
|
||||
color: '#338eda',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
lineHeight: '1.25',
|
||||
padding: '1rem',
|
||||
textAlign: 'center',
|
||||
boxShadow:
|
||||
teenagerLed === 'true' ? '0 0 0 1px #fff,0 0 0 3px #338eda' : null
|
||||
}}
|
||||
>
|
||||
{Object.entries({ Yes: 'true', No: 'false' }).map(([name, value]) => (
|
||||
<option key={name} value={value}>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</Field>
|
||||
<p>
|
||||
NOTE: this kinda ugly rn, i plan on making this teenager question look a
|
||||
bit better by having two boxes side by side. one box/button for teen,
|
||||
another for adult
|
||||
</p>
|
||||
</>
|
||||
<Radio
|
||||
name="eventTeenagerLed"
|
||||
value="true"
|
||||
onChange={onTeenagerLedChange}
|
||||
sx={{ display: 'none!important' }}
|
||||
/>
|
||||
Yes, I'm a teenager
|
||||
</Label>
|
||||
<Label
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
backgroundColor: ' rgba(91,192,222,.25)',
|
||||
borderRadius: '.75rem',
|
||||
color: '#338eda',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
lineHeight: '1.25',
|
||||
padding: '1rem',
|
||||
textAlign: 'center',
|
||||
boxShadow:
|
||||
teenagerLed === 'false'
|
||||
? '0 0 0 1px #fff,0 0 0 3px #338eda'
|
||||
: null
|
||||
}}
|
||||
>
|
||||
<Radio
|
||||
name="eventTeenagerLed"
|
||||
value="false"
|
||||
onChange={onTeenagerLedChange}
|
||||
sx={{ display: 'none!important' }}
|
||||
/>
|
||||
I'm an adult
|
||||
</Label>
|
||||
</Flex>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function useOrganizationI18n() {
|
||||
const [org, setOrg] = useState('Organization')
|
||||
const [org, setOrg] = useState('Project')
|
||||
|
||||
useEffect(() => {
|
||||
if (navigator.language === 'en-GB') setOrg('Organisation')
|
||||
if (navigator.language === 'en-GB') setOrg('Project')
|
||||
}, [])
|
||||
|
||||
return org
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default function Apply() {
|
|||
px: [3, 5],
|
||||
py: 4,
|
||||
gap: 4,
|
||||
height: [null, '100svh'],
|
||||
height: [null, null, '100svh'],
|
||||
position: [null, null, 'sticky'],
|
||||
top: 0,
|
||||
overflowY: [null, null, 'auto']
|
||||
|
|
@ -62,10 +62,18 @@ export default function Apply() {
|
|||
Back
|
||||
</Text>
|
||||
</Link>
|
||||
<Heading as="h1" variant="title">
|
||||
Apply to join
|
||||
<Heading as="h1" variant="headline">
|
||||
Turn your ideas into
|
||||
<br />
|
||||
<Flex sx={{ alignItems: 'center', gap: 3 }}>
|
||||
reality with{' '}
|
||||
<Flex
|
||||
sx={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 2,
|
||||
verticalAlign: 'middle'
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/fiscal-sponsorship/hcb-icon-small.png"
|
||||
width={48}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ export default function Page() {
|
|||
}}
|
||||
>
|
||||
<Stat value="$30M+" label="processed transactions" reversed />
|
||||
<Stat value="2000+" label="projects" reversed />
|
||||
<Stat value="6500+" label="projects" reversed />
|
||||
<Stat value="2018" label="serving nonprofits since" reversed />
|
||||
</Flex>
|
||||
<Grid columns={[1, 2]} gap={[3, 4]} sx={{ mt: 4 }}>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue