Skip to content

Commit

Permalink
2023 census form (#289)
Browse files Browse the repository at this point in the history
* WIP 2023 census form. Only professional questions, no submission

* Add netlify function for connecting to Airtable

* Clean up professional form

* Demographics page

* Form submission

* Submitting state

* Fix glitch on empty Discords list

* Persistent submission ID
  • Loading branch information
vcarl authored Jan 2, 2024
1 parent 289d39c commit b2b0baf
Show file tree
Hide file tree
Showing 12 changed files with 8,432 additions and 161 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ yarn-error.log*
# vercel
.vercel

.netlify
.env

# typescript
*.tsbuildinfo
47 changes: 47 additions & 0 deletions netlify/functions/airtable.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Context } from "@netlify/functions";

const handler = async (request: Request, context: Context) => {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}

const {
meta,
data: { id, ...data },
} = await request.json();
const { base, table } = meta;

try {
// // Make the request using fetch
const response = await fetch(
`https://api.airtable.com/v0/${base}/${table}`,
{
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.AIRTABLE_RECORD}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
performUpsert: {
fieldsToMergeOn: ["id"],
},
records: [
{
fields: {
id,
...data,
},
},
],
}),
},
);
const output = await response.json();
console.log(output);
return new Response("ok");
} catch (e) {
return new Response(JSON.stringify(e), { status: 400 });
}
};

export default handler;
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactiflux.com",
"version": "π",
"version": "0.3.14",
"private": true,
"license": "MIT",
"scripts": {
Expand All @@ -21,10 +21,12 @@
}
},
"dependencies": {
"@netlify/functions": "^2.4.1",
"@types/node": "20.6.0",
"@types/react": "17.0.37",
"@types/styled-components": "^5.1.15",
"@vcarl/remark-headings": "^0.0.1",
"airtable": "^0.12.2",
"date-fns": "^2.27.0",
"eslint": "7",
"eslint-config-next": "12.0.4",
Expand All @@ -33,6 +35,7 @@
"mdast-util-to-string": "^3.1.0",
"minireset.css": "^0.0.6",
"moment": "^2.27.0",
"netlify-cli": "^17.10.2",
"next": "^12.3.4",
"next-sitemap": "^4.2.2",
"polished": "^3.6.5",
Expand All @@ -42,6 +45,7 @@
"react-dom": "17.0.2",
"react-headroom": "^2.1.2",
"react-helmet": "^5.2.1",
"react-hook-form": "^7.49.2",
"rehype-slug": "^5.0.0",
"rehype-stringify": "^9.0.2",
"remark-gfm": "^3.0.1",
Expand Down
Binary file added src/assets/un-geo-regions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
256 changes: 256 additions & 0 deletions src/components/Census/2023/Demographics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
import React from "react";
import { useForm } from "react-hook-form";
import styled from "styled-components";

import { Button } from "@components";
import { TextareaInner } from "@components/Form/Input";

import {
CensusItem,
Explanation,
Question,
} from "@components/Census/2023/Styles";
import { Region } from "@components/Census/2023/Region";

const TextareaEl = styled(TextareaInner)`
font-size: 0.8em;
`;

export const Demographics = ({ onSubmit }) => {
const form = useForm();
const { handleSubmit, register, watch, formState } = form;
const { isSubmitting } = formState;
const religion = watch("religion");
const gender = watch("gender");
const orientation = watch("sexual-orientation");

const inclusionExplanation = (
<Explanation summary="(why we ask)">
<p>
This is a survey of the members of our community, and we don’t make
assumptions about who is here. We ask questions like this so that we can
have a clearer sense of whether we’re achieving our goals.
</p>
<p>
Reactiflux is an inclusive community that strives to be welcoming to
all, regardless of level of experience, gender identity and expression,
sexual orientation, disability, neurodivergence, personal appearance,
body, race, ethnicity, age, religion, nationality, or other similar
characteristic.
</p>
</Explanation>
);

return (
<form onSubmit={handleSubmit(onSubmit)}>
<CensusItem>
<Question>Do you feel well represented within Reactiflux?</Question>
{["Yes", "Somewhat", "No"].map((r) => (
<div key={r}>
<label>
<input {...register("represented")} type="radio" value={r} /> {r}
</label>
</div>
))}
</CensusItem>

<CensusItem>
<Question>
Have you felt marginalized or harassed by another member of
Reactiflux?
</Question>
{["Yes", "Somewhat", "No"].map((r) => (
<div key={r}>
<label>
<input {...register("marginalized")} type="radio" value={r} /> {r}
</label>
</div>
))}
<label>
<TextareaEl
{...register("marginalized-free-response")}
type="text"
placeholder="(free response)"
/>
</label>
</CensusItem>

<CensusItem>
<Question>How old are you?</Question>
{["Under 18", "18–22", "23–27", "28–34", "35–44", "45–59", "60+"].map(
(r) => (
<div key={r}>
<label>
<input {...register("age")} type="radio" value={r} /> {r}
</label>
</div>
),
)}
</CensusItem>

<Region form={form} />

<CensusItem>
<Question>Do you identify as a member of a religious group?</Question>
{[
"Agnostic",
"Buddhism",
"Catholocism",
"Christianity",
"Hinduism",
"Islam",
"Judaism",
"Protestantism",
"Sikhism",
"No religion",
].map((r) => (
<div key={r}>
<label>
<input {...register("religion")} type="radio" value={r} /> {r}
</label>
</div>
))}
<div>
<label>
<input {...register("religion")} type="radio" value="Other" /> Other
(please include)
</label>
{religion && religion.includes("Other") && (
<>
{" "}
<label>
<input {...register("other-religion")} type="text" />
</label>
</>
)}
</div>
{inclusionExplanation}
<Explanation summary="(how did we decide what to include?)">
We reviewed several national census surveys and publicly available
global demographic datasets, including any religions that were
included by several sources and represent a portion of the global
population greater than 0.2%. The religions are presented in
alphabetical order.
</Explanation>
</CensusItem>

<CensusItem>
<Question>What is your gender identity?</Question>
{[
"Male",
"Female",
"Non-binary or genderfluid",
"Agender",
"Prefer not to say",
].map((r) => (
<div key={r}>
<label>
<input {...register("gender")} type="radio" value={r} /> {r}
</label>
</div>
))}
<div>
<label>
<input {...register("gender")} type="radio" value="Other" /> Other
(please include)
</label>
{gender && gender.includes("Other") && (
<>
{" "}
<label>
<input {...register("other-gender")} type="text" />
</label>
</>
)}
</div>
{inclusionExplanation}
</CensusItem>

<CensusItem>
<Question>Do you identify as transgender?</Question>
{["Yes", "No", "Prefer not to say"].map((r) => (
<div key={r}>
<label>
<input {...register("trans")} type="radio" value={r} /> {r}
</label>
</div>
))}
{inclusionExplanation}
</CensusItem>

<CensusItem>
<Question>Are you a person living with a disability?</Question>
{["Yes", "No", "Prefer not to say"].map((r) => (
<div key={r}>
<label>
<input {...register("disability")} type="radio" value={r} /> {r}
</label>
</div>
))}
{inclusionExplanation}
</CensusItem>

<CensusItem>
<Question>What is your sexual orientation?</Question>
{[
"Asexual",
"Bisexual",
"Heterosexual",
"Homosexual",
"Pansexual",
"Queer",
"Prefer not to say",
].map((r) => (
<div key={r}>
<label>
<input
{...register("sexual-orientation")}
type="radio"
value={r}
/>{" "}
{r}
</label>
</div>
))}
<div>
<label>
<input
{...register("sexual-orientation")}
type="radio"
value="Other"
/>{" "}
Other (please include)
</label>
{orientation && orientation.includes("Other") && (
<>
{" "}
<label>
<input {...register("other-sexual-orientation")} type="text" />
</label>
</>
)}
</div>
{inclusionExplanation}
</CensusItem>

<CensusItem>
<Question>
Anything else you’d like to share with the Reactiflux staff?
</Question>
<label>
<TextareaEl
{...register("free-response")}
placeholder="(free response)"
/>
</label>
</CensusItem>

<Button
disabled={isSubmitting}
as="input"
type="submit"
value={isSubmitting ? "…" : "Submit"}
/>
</form>
);
};
Loading

0 comments on commit b2b0baf

Please sign in to comment.