diff --git a/components/fiscal-sponsorship/apply/address-input.js b/components/fiscal-sponsorship/apply/address-input.js deleted file mode 100644 index bf0cbc81..00000000 --- a/components/fiscal-sponsorship/apply/address-input.js +++ /dev/null @@ -1,179 +0,0 @@ -import { useEffect, useRef, useState, useCallback } from 'react' -import { Box, Flex, Input, Text } from 'theme-ui' -import FlexCol from '../../flex-col' -import AutofillColourFix from './autofill-colour-fix' -import { geocode, search } from '../../../lib/fiscal-sponsorship/apply/address-validation' -import Icon from '../../icon' - -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() - const [predictions, setPredictions] = useState(null) - const [countryCode, setCountryCode] = useState(null) - - const optionClicked = async prediction => { - input.current.value = prediction.name - // Needs to match the shape of the event object because onInput takes an event object. - await onInput({ target: { value: prediction.name } }) - setPredictions(null) - } - const clickOutside = e => { - if (input.current && !input.current.contains(e.target)) { - setPredictions(null) - } - } - - const onInput = useCallback( - async e => { - if (!e.target.value) return - const value = e.target.value - - setPredictions(value ? (await search(value)).results : null) - - if (isPersonalAddressInput) return - geocode(value) - .then(res => { - const country = res?.results[0]?.country - const countryCode = res?.results[0]?.countryCode - - setCountryCode(countryCode) - - sessionStorage.setItem('bank-signup-eventCountry', country) - sessionStorage.setItem('bank-signup-eventCountryCode', countryCode) - }) - .catch(err => console.error(err)) - }, - [isPersonalAddressInput] - ) - - //TODO: Close suggestions view when focus is lost via tabbing. - //TODO: Navigate suggestions with arrow keys. - - useEffect(() => { - const inputEl = input.current - if (!inputEl) return - - document.addEventListener('click', clickOutside) - inputEl.addEventListener('input', onInput) - inputEl.addEventListener('focus', onInput) - - return () => { - document.removeEventListener('click', clickOutside) - inputEl.removeEventListener('input', onInput) - inputEl.removeEventListener('focus', onInput) - } - }, [onInput]) - - return ( - - - - - {/* {String(countryCode)} */} - {countryCode && !approvedCountries.includes(countryCode) && ( - - - - Currently, we only have first-class support for organizations in - select countries. -
- If you're somewhere else, you can still use HCB! -
- Please contact us at hcb@hackclub.com -
-
- )} -
-
- {predictions && predictions.length > 0 && ( - - - {predictions.map((prediction, idx) => ( - <> - optionClicked(prediction)} - sx={{ - cursor: 'pointer', - border: 'none', - background: 'none', - color: '#d1cbe7', - '&:hover': { - color: 'white' - }, - fontFamily: 'inherit', - fontSize: 'inherit', - textAlign: 'inherit' - }} - key={idx} - > - {prediction.name} - - - {idx < predictions.length - 1 && ( -
- )} - - ))} -
-
- )} -
- ) -} diff --git a/components/fiscal-sponsorship/apply/alert-modal.js b/components/fiscal-sponsorship/apply/alert-modal.js deleted file mode 100644 index 09b06f79..00000000 --- a/components/fiscal-sponsorship/apply/alert-modal.js +++ /dev/null @@ -1,42 +0,0 @@ -import { Box, Button, Flex, Text } from 'theme-ui' -import Icon from '../../icon' - -export default function AlertModal({ formError, setFormError }) { - if (!formError) return null - - const close = () => setFormError(null) - - return ( - - - - Oops! - {formError} - - - - ) -} diff --git a/components/fiscal-sponsorship/apply/autofill-colour-fix.js b/components/fiscal-sponsorship/apply/autofill-colour-fix.js deleted file mode 100644 index b9aa59d1..00000000 --- a/components/fiscal-sponsorship/apply/autofill-colour-fix.js +++ /dev/null @@ -1,10 +0,0 @@ -//TODO: Move to main theme - -const autofillColourFix = { - '&:-webkit-autofill': { - boxShadow: '0 0 0 100px #252429 inset !important', - WebkitTextFillColor: 'white' - } -} - -export default autofillColourFix diff --git a/components/fiscal-sponsorship/apply/checkbox.js b/components/fiscal-sponsorship/apply/checkbox.js deleted file mode 100644 index 5ec96ed8..00000000 --- a/components/fiscal-sponsorship/apply/checkbox.js +++ /dev/null @@ -1,37 +0,0 @@ -import { useEffect, useState } from 'react' -import Icon from '../../icon' -import { useRouter } from 'next/router' - -export default function Checkbox({ name, defaultChecked = false, size = 38 }) { - const [checked, setChecked] = useState(defaultChecked) - const toggle = () => setChecked(!checked) - const router = useRouter() - - /* Fill in the field with the value from sessionStorage. - For other input elements, the value is set in the Field component, - but these checkboxes hold their state in useState rather than in the DOM. */ - useEffect(() => { - const value = router.query[name] || sessionStorage.getItem('bank-signup-' + name) - if (value) { - const input = document.getElementById(name) - input && setChecked(!!value) - } - }, [router.query, name]) - - return ( - <> - - toggle()} - onKeyDown={e => e.key === 'Enter' && toggle()} - /> - - ) -} diff --git a/components/fiscal-sponsorship/apply/field.js b/components/fiscal-sponsorship/apply/field.js index 4dab2c1f..b81c00e5 100644 --- a/components/fiscal-sponsorship/apply/field.js +++ b/components/fiscal-sponsorship/apply/field.js @@ -1,7 +1,6 @@ import { useRouter } from 'next/router' import { useEffect } from 'react' -import { Box, Flex, Label, Text } from 'theme-ui' -import FlexCol from '../../flex-col' +import { Flex, Label, Text } from 'theme-ui' export default function Field({ name, @@ -12,8 +11,7 @@ export default function Field({ children }) { const router = useRouter() - const isRequired = - requiredFields[parseInt(router.query.step) - 1].includes(name) + const isRequired = requiredFields.includes(name) /* Fill in the field input element with the value from sessionStorage. Note: the custom checkbox component does this in its own useEffect hook. */ @@ -27,43 +25,56 @@ export default function Field({ }, [router.query, name]) return ( - - div': { + width: '100%' + }, + 'input, select, textarea': { + border: '1px solid', + borderColor: 'smoke', + outlineColor: 'blue', + '&:-webkit-autofill': { + boxShadow: '0 0 0 100px white inset !important', + WebkitTextFillColor: 'black !important' + } + } + }} + > + + * + + )} + + {children} {description && ( - {description} + + {description} + )} - + ) } diff --git a/components/fiscal-sponsorship/apply/form-container.js b/components/fiscal-sponsorship/apply/form-container.js index f9ff0fd9..d544335a 100644 --- a/components/fiscal-sponsorship/apply/form-container.js +++ b/components/fiscal-sponsorship/apply/form-container.js @@ -1,25 +1,35 @@ import { forwardRef } from 'react' -import { Box } from 'theme-ui' +import { Box, Container } from 'theme-ui' -const formContainer = forwardRef(({ children }, ref) => { +const formContainer = forwardRef(({ children, ...props }, ref) => { return ( - {children} + + {children} + ) }) diff --git a/components/fiscal-sponsorship/apply/hcb-info.js b/components/fiscal-sponsorship/apply/hcb-info.js index cd94142c..55312a94 100644 --- a/components/fiscal-sponsorship/apply/hcb-info.js +++ b/components/fiscal-sponsorship/apply/hcb-info.js @@ -1,89 +1,66 @@ -import { Box, Flex, Link, Text } from 'theme-ui' +import { Box, Link, Heading } from 'theme-ui' import Icon from '../../icon' -import FlexCol from '../../flex-col' export default function HCBInfo() { return ( - - - - - What HCB is - - - - - - A fiscal sponsor - - - - -
    -
  • Nonprofit status.
  • -
  • Tax-deductable donations.
  • -
-
-
- - A financial platform - -
    -
  • A donations page and invoicing system.
  • -
  • Transfer money electronically.
  • -
  • Order cards for you and your team to make purchases.
  • -
-
-
-
-
- - - What HCB is not - - - - - A bank!{' '} - (we're better) - - -
    -
  • - Rather than setting up a standard bank account, you'll get a - restricted fund within Hack Club accounts. -
  • -
  • - You can't deposit or withdraw cash. But you can receive any - kind of electronic payment! -
  • -
-
-
- - For-profit - -
    -
  • - If you’re a for-profit entity, then HCB is not for you. - Consider setting up a business. -
  • -
-
-
-
-
-
+ + + HCB is a{' '} + + fiscal sponsor + + + +
    +
  • Nonprofit status.
  • +
  • Tax-deductable donations.
  • +
+ + HCB provides a financial platform. + +
    +
  • A donations page and invoicing system.
  • +
  • Transfer money electronically.
  • +
  • Order cards for you and your team to make purchases.
  • +
+ HCB is not a bank. +
    +
  • + We partner with{' '} + + Column Bank + {' '} + to offer a bank account to fiscally-sponsored projects. +
  • +
  • + You can't deposit or withdraw cash. But you can receive any kind of + electronic payment! +
  • +
+ HCB is not for for-profits. +

+ If you’re looking to set up a for-profit entity, consider{' '} + + Stripe Atlas + + . +

) } diff --git a/components/fiscal-sponsorship/apply/nav-button.js b/components/fiscal-sponsorship/apply/nav-button.js deleted file mode 100644 index c80c3447..00000000 --- a/components/fiscal-sponsorship/apply/nav-button.js +++ /dev/null @@ -1,178 +0,0 @@ -import { useRouter } from 'next/router' -import { useEffect, useState } from 'react' -import { Button, Flex, Text, Spinner } from 'theme-ui' - -async function sendApplication() { - // Get the form data from sessionStorage - const data = {} - for (let i = 0; i < sessionStorage.length; i++) { - const key = sessionStorage.key(i) - if (key.startsWith('bank-signup-')) { - data[key.replace('bank-signup-', '')] = sessionStorage.getItem(key) - } - } - console.dir('Sending data:', data) - - // Send the data - try { - const res = await fetch('/api/fiscal-sponsorship/apply', { - method: 'POST', - cors: 'no-cors', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data) - }) - } catch (error) { - console.error(error) - } -} - -function NavIcon({ isBack }) { - const style = { - height: '1em', - fill: 'white', - margin: 0, - flexShrink: 0 - } - - return isBack ? ( - - - - - - ) : ( - - - - - - ) -} - -export default function NavButton({ - isBack, - form, - clickHandler, - requiredFields, - setFormError -}) { - const router = useRouter() - const [spinner, setSpinner] = useState(false) - - useEffect(() => { - setSpinner(false) - }, [router.query.step]) - - const minStep = 1 - const maxStep = 3 - - const click = async () => { - setSpinner(true) - - let step = parseInt(router.query.step) - - async function setStep(s) { - await router.push( - { - pathname: router.pathname, - query: { ...router.query, step: s } - }, - undefined, - {} - ) - } - - if (!step) { - // Set the step query param to minStep if it's not there. - await setStep(minStep) - } else if (step === minStep && isBack) { - await router.push('/hcb') - return - } else if (step < minStep) { - // Set the step query param to minStep if it's lower than that. - await setStep(minStep) - } - - /* Don't return from inside the loop since - we want all input values to be saved every time */ - let wasError = false - - const formData = new FormData(form.current) - - // Save form data - formData.forEach((value, key) => { - sessionStorage.setItem('bank-signup-' + key, value) - - // Check if there are empty required fields. - if ( - (!isBack && - (!value || value.trim() === '') && - requiredFields[step - 1].includes(key)) || - (!isBack && - formData.get('contactOption') === 'slack' && - !formData.get('slackUsername')) // I'm so sorry for this - ) { - setFormError('Please fill all required fields') - wasError = true - setSpinner(false) - } - }) - if (wasError) return - - // Run the parent's click handler for this button. - if (clickHandler) await clickHandler() - - if (step >= maxStep && !isBack) { - await sendApplication() - await router.push('/fiscal-sponsorship/apply/success') - return - } else { - step += isBack ? -1 : 1 - } - await setStep(step) - } - - return ( - - ) -} diff --git a/components/fiscal-sponsorship/apply/org-form.js b/components/fiscal-sponsorship/apply/org-form.js index 18496e54..c418b492 100644 --- a/components/fiscal-sponsorship/apply/org-form.js +++ b/components/fiscal-sponsorship/apply/org-form.js @@ -1,9 +1,9 @@ import { useState, useEffect } from 'react' -import { Input, Textarea } from 'theme-ui' -import Checkbox from './checkbox' -import AddressInput from './address-input' +import { Input, Select, Textarea } from 'theme-ui' +// import Checkbox from './checkbox' import Field from './field' -import AutofillColourFix from './autofill-colour-fix' +// This is using country-list instead of country-list-js as it has a smaller bundle size +import { getNames } from 'country-list' export default function OrganizationInfoForm({ requiredFields }) { const [org, setOrg] = useState('Organization') @@ -23,7 +23,6 @@ export default function OrganizationInfoForm({ requiredFields }) { name="eventName" id="eventName" placeholder="Shelburne School Hackathon" - sx={{ ...AutofillColourFix }} /> - + {/* */}