diff --git a/netlify/functions/airtable.mts b/netlify/functions/airtable.mts index ec0ce45..ace251e 100644 --- a/netlify/functions/airtable.mts +++ b/netlify/functions/airtable.mts @@ -11,29 +11,37 @@ const handler = async (request: Request, context: Context) => { } = await request.json(); const { base, table } = meta; - console.log({ data, url: `https://api.airtable.com/v0/${base}/${table}` }); - - // // Make the request using fetch - fetch(`https://api.airtable.com/v0/${base}/${table}`, { - method: "POST", - headers: { - Authorization: `Bearer ${process.env.AIRTABLE_RECORD}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - fields: { - id, - ...data, + 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, + }, + }, + ], + }), }, - }), - }) - .then((response) => response.json()) // Convert the response to JSON - .then((data) => { - // Handle the data from the response - console.log(data); - }); - // .. - return new Response("ok"); + ); + 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; diff --git a/src/pages/census/2023.js b/src/pages/census/2023.js index b4fd7f2..363a759 100644 --- a/src/pages/census/2023.js +++ b/src/pages/census/2023.js @@ -1,60 +1,80 @@ import React from "react"; -import { useForm, Controller } from "react-hook-form"; import styled from "styled-components"; -import { Layout, Button } from "@components"; +import { Layout } from "@components"; +import { TextareaInner } from "@components/Form/Input"; -import { Employment } from "@components/Census/2023/Employment"; -import { OrgSize } from "@components/Census/2023/OrgSize"; -import { OtherDiscords } from "@components/Census/2023/OtherDiscords"; -import { ProExperience } from "@components/Census/2023/ProExperience"; -import { ReactExperience } from "@components/Census/2023/ReactExperience"; -import { VisitFrequency } from "@components/Census/2023/VisitFrequency"; +import { Professional } from "../../components/Census/2023/Professional"; +import { Demographics } from "../../components/Census/2023/Demographics"; -const Demographics = ({ onSubmit: afterSubmit }) => { - const form = useForm(); - const { handleSubmit } = form; +const TextareaEl = styled(TextareaInner)` + font-size: 0.8em; +`; - return ( -
- ); -}; - -const Professional = ({ submissionId, onSubmit: afterSubmit }) => { - const form = useForm(); - const { handleSubmit } = form; - - return ( - - ); +const generateUniqueId = () => { + const timestamp = new Date().getTime().toString(36); + const randomString = Math.random().toString(36).substring(2, 15); + const uniqueId = timestamp + randomString; + return uniqueId; }; export const Census2023 = () => { + const id = React.useMemo(() => generateUniqueId(), []); const [submissionStep, setSubmissionStep] = React.useState(0); - const next = () => setSubmissionStep((i) => i + 0); - const back = () => setSubmissionStep((i) => i - 0); + const next = () => setSubmissionStep((i) => i + 1); + React.useEffect(() => { + setSubmissionStep(Number(localStorage.getItem("2023-census-key"))); + }, []); + React.useEffect(() => { + localStorage.setItem("2023-census-key", submissionStep.toString()); + }, [submissionStep]); + + const onSubmit = async (data) => { + // Snag all possible inputs, filter out false-y values, put it together. + // This is a cheap way to make updates easier, we can just post everything we + // get both times and trust that nothing will get overwritten. + const finalData = Object.fromEntries( + Object.entries({ + id, + employment: data["employment"], + "org-size": data["org-size"], + "other-discords": data["other-discords"]?.join(","), + "pro-experience": data["pro-experience"], + "react-experience": data["react-experience"], + "visit-frequency": data["visit-frequency"], + "other-discords-custom": data["other-discords-custom"], + age: data["age"], + disability: data["disability"], + "free-response": data["free-response"], + gender: data["gender"], + marginalized: data["marginalized"], + "marginalized-free-response": data["marginalized-free-response"], + region: data["region"], + religion: data["religion"], + represented: data["represented"], + "sexual-orientation": data["sexual-orientation"], + subregion: data["subregion"], + trans: data["trans"], + }).filter((pair) => pair[1]), + ); + + try { + await fetch("/.netlify/functions/airtable", { + method: "POST", + headers: { "Content-Type": "text/plain" }, + body: JSON.stringify({ + meta: { base: AIRTABLE_BASE, table: AIRTABLE_TABLE }, + data: finalData, + }), + }); + next(); + } catch (error) { + console.error("Error posting data:", error); + } + }; const title = "Reactiflux 2023 Census"; return ( @@ -69,11 +89,9 @@ export const Census2023 = () => { {(() => { switch (submissionStep) { case 0: - return