diff --git a/.env.example b/.env.example index 27fc379..6e8dd33 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ AIRTABLE_API_KEY=your_airtable_api_key_here AIRTABLE_BASE_ID=your_airtable_base_id_here AIRTABLE_EMAILS_TABLE=your_airtable_emails_table_here +AIRTABLE_RSVPS_TABLE=your_airtable_rsvps_table_here GEOCODER_API_KEY=your_geocoder_api_key_here \ No newline at end of file diff --git a/src/lib/components/ParticipantSignUp.svelte b/src/lib/components/ParticipantSignUp.svelte new file mode 100644 index 0000000..9088b4f --- /dev/null +++ b/src/lib/components/ParticipantSignUp.svelte @@ -0,0 +1,107 @@ + + + + +
+
+
+ + + +
+ + + {#if submitted} +
+ RSVPed! +
+ {/if} +
+ + Get free stickers + + + +
diff --git a/src/routes/api/rsvp/+server.js b/src/routes/api/rsvp/+server.js new file mode 100644 index 0000000..75fa739 --- /dev/null +++ b/src/routes/api/rsvp/+server.js @@ -0,0 +1,49 @@ +import Airtable from 'airtable'; +import { json } from '@sveltejs/kit'; +import { AIRTABLE_API_KEY, AIRTABLE_BASE_ID, AIRTABLE_RSVPS_TABLE } from '$env/static/private'; + +if (!AIRTABLE_API_KEY || !AIRTABLE_BASE_ID) { + console.warn('Airtable environment variables not configured, email saving will be skipped'); +} + +const base = AIRTABLE_API_KEY && AIRTABLE_BASE_ID + ? new Airtable({ + apiKey: AIRTABLE_API_KEY + }).base(AIRTABLE_BASE_ID) + : null; + +export async function POST({ request, getClientAddress }) { + try { + const { email } = await request.json(); + + if (!email) { + return json({ error: 'Email is required' }, { status: 400 }); + } + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(email)) { + return json({ error: 'Invalid email format' }, { status: 400 }); + } + + // get IP address + const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || getClientAddress(); + + if (base) { + await base(AIRTABLE_RSVPS_TABLE || 'participant_rsvps').create([ + { + fields: { + email, + ip, + } + } + ]); + } + + return new Response(null, { status: 200 }); + + } catch (error) { + console.error('Error saving email to Airtable:', error); + + return new Response(null, { status: 418 }); + } +} diff --git a/src/routes/api/submit-email/+server.js b/src/routes/api/submit-email/+server.js index 25e4e64..b5b743f 100644 --- a/src/routes/api/submit-email/+server.js +++ b/src/routes/api/submit-email/+server.js @@ -26,11 +26,10 @@ export async function POST({ request, getClientAddress }) { } // get IP address - const ip = getClientAddress(); + const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || getClientAddress(); - let recordId = null; if (base) { - const record = await base(AIRTABLE_EMAILS_TABLE || 'email_addresses').create([ + await base(AIRTABLE_EMAILS_TABLE || 'email_addresses').create([ { fields: { email, @@ -38,7 +37,6 @@ export async function POST({ request, getClientAddress }) { } } ]); - recordId = record[0].id; } return new Response(null, { status: 200 }); diff --git a/src/routes/example/+page.svelte b/src/routes/example/+page.svelte index 0fd3adc..da57010 100644 --- a/src/routes/example/+page.svelte +++ b/src/routes/example/+page.svelte @@ -2,6 +2,7 @@ import { onMount } from "svelte"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; + import ParticipantSignUp from "$lib/components/ParticipantSignUp.svelte"; /** * This is the template site! Create a copy of this folder (src/routes/example) @@ -333,26 +334,7 @@ Mumbai`.split("\n") showVideoPopup = false; } - function handleFormSubmit(event: Event) { - event.preventDefault(); - const form = event.target as HTMLFormElement; - const emailInput = form.querySelector('input[name="email"]') as HTMLInputElement; - const email = emailInput.value; - - fetch('/api/submit-email', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ email }) - }).catch(error => { - console.warn('Failed to save email:', error); - }); - - window.open(`https://forms.hackclub.com/daydream?email=${encodeURIComponent(email)}`, '_blank'); - - emailInput.value = ''; - } + async function typeText(text: string) { isTyping = true; @@ -797,39 +779,7 @@ Mumbai`.split("\n") -
-
- - - -
- - Get free stickers - - - -
+