mirror of
https://github.com/System-End/daydream-phoenix.git
synced 2026-04-19 16:28:17 +00:00
Rewrite hero with email RSVP
This commit is contained in:
parent
9187c5d9e9
commit
a55e66c05d
5 changed files with 162 additions and 57 deletions
|
|
@ -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
|
||||
107
src/lib/components/ParticipantSignUp.svelte
Normal file
107
src/lib/components/ParticipantSignUp.svelte
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<script lang="ts">
|
||||
let submitted = false;
|
||||
let fadeOut = 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/rsvp', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ email })
|
||||
}).catch(error => {
|
||||
console.warn('Failed to save email:', error);
|
||||
});
|
||||
|
||||
submitted = true;
|
||||
|
||||
// Clear the input box while the green overlay is showing
|
||||
emailInput.value = '';
|
||||
|
||||
setTimeout(() => {
|
||||
fadeOut = true;
|
||||
}, 1500);
|
||||
|
||||
// Reset to original position after fade out completes
|
||||
setTimeout(() => {
|
||||
submitted = false;
|
||||
fadeOut = false;
|
||||
}, 1500 + 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes slide-in {
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-slide-in {
|
||||
animation: slide-in 0.3s cubic-bezier(0, 0.55, 0.45, 1);
|
||||
}
|
||||
|
||||
.animate-fade-out {
|
||||
animation: fade-out 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fade-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="mt-8 flex flex-col items-center gap-3 z-5 max-md:scale-90">
|
||||
<div class="relative rounded-full overflow-hidden" style="padding: 2px 2px 5px 2px;">
|
||||
<form on:submit={handleFormSubmit} class="rounded-full bg-white border-2 border-dark font-sans p-2 flex flex-row items-center gap-2 shadow-[0_3px_0_0_theme(colors.dark)] focus-within:border-pink focus-within:shadow-[0_3px_0_0_#E472AB] has-[button:active]:border-dark has-[button:active]:shadow-[0_3px_0_0_theme(colors.dark)] has-[button:focus]:border-dark has-[button:focus]:shadow-[0_3px_0_0_theme(colors.dark)]">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Enter email to RSVP"
|
||||
class="w-80 px-3 py-1 text-dark focus:outline-none flex-1"
|
||||
required
|
||||
/>
|
||||
<input type="hidden" name="mailingLists" value="cmd3c94kz0hvz0iwt7ps28cyd" />
|
||||
<button type="submit" class="bg-light h-full px-5 py-[0.45rem] rounded-full border-b-2 border-[#B3866A] cursor-pointer hover:border-b-4 hover:transform active:border-b-0 active:transform active:translate-y-0.5 focus:outline-none transition-all duration-100 flex-shrink-0">
|
||||
<img src="submit.svg" alt="Go">
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Success overlay that slides in from left -->
|
||||
{#if submitted}
|
||||
<div class="absolute inset-0 -top-4 -bottom-4 bg-[#44DBC8] rounded-full flex items-center justify-center z-20 animate-slide-in {fadeOut ? 'animate-fade-out' : ''}">
|
||||
<span class="text-white font-sans text-lg">RSVPed!</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<a
|
||||
href="https://forms.hackclub.com/daydream-stickers"
|
||||
target="_blank"
|
||||
class="w-max px-4 py-2 bg-pink border-b-2 border-b-pink-dark text-white rounded-full active:transform active:translate-y-0.5 transition-all duration-100 font-sans cursor-pointer mx-auto relative overflow-visible hover:shadow-[0_2px_0_0_theme(colors.pink.dark)] hover:-translate-y-[2px] active:border-transparent active:shadow-none active: mt-4 md:hidden"
|
||||
>
|
||||
Get free stickers
|
||||
<img
|
||||
src="button-clouds.svg"
|
||||
alt=""
|
||||
class="absolute bottom-0 left-1/2 -translate-x-1/2 w-auto object-contain pointer-events-none"
|
||||
>
|
||||
<img
|
||||
src="rock-sticker.png"
|
||||
alt=""
|
||||
class="absolute bottom-2 right-3 translate-2/3 w-18 h-18 object-contain pointer-events-none"
|
||||
style="transform: rotate(-15deg);"
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
49
src/routes/api/rsvp/+server.js
Normal file
49
src/routes/api/rsvp/+server.js
Normal file
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
@ -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 });
|
||||
|
|
|
|||
|
|
@ -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")
|
|||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex flex-col items-center gap-3 z-5 max-md:scale-90">
|
||||
<form on:submit={handleFormSubmit} class="rounded-full bg-white border-2 border-dark font-sans p-2 flex flex-row items-center gap-2 shadow-[0_3px_0_0_theme(colors.dark)] focus-within:border-pink focus-within:shadow-[0_3px_0_0_#E472AB] has-[button:active]:border-dark has-[button:active]:shadow-[0_3px_0_0_theme(colors.dark)] has-[button:focus]:border-dark has-[button:focus]:shadow-[0_3px_0_0_theme(colors.dark)]">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Enter email to sign up"
|
||||
class="w-80 px-3 py-1 text-dark focus:outline-none"
|
||||
required
|
||||
/>
|
||||
<input type="hidden" name="mailingLists" value="cmd3c94kz0hvz0iwt7ps28cyd" />
|
||||
<button type="submit" class="bg-light h-full px-5 rounded-full border-b-2 border-[#B3866A] cursor-pointer hover:border-b-4 hover:transform active:border-b-0 active:transform active:translate-y-0.5 focus:outline-none transition-all duration-100">
|
||||
<img src="submit.svg" alt="Go">
|
||||
</button>
|
||||
</form>
|
||||
<a
|
||||
href="https://forms.hackclub.com/daydream-stickers"
|
||||
target="_blank"
|
||||
class="w-max px-4 py-2 bg-pink border-b-2 border-b-pink-dark text-white rounded-full active:transform active:translate-y-0.5 transition-all duration-100 font-sans cursor-pointer mx-auto relative overflow-visible hover:shadow-[0_2px_0_0_theme(colors.pink.dark)] hover:-translate-y-[2px] active:border-transparent active:shadow-none active: mt-4 md:hidden"
|
||||
>
|
||||
Get free stickers
|
||||
<img
|
||||
src="button-clouds.svg"
|
||||
alt=""
|
||||
class="absolute bottom-0 left-1/2 -translate-x-1/2 w-auto object-contain pointer-events-none"
|
||||
>
|
||||
<img
|
||||
src="rock-sticker.png"
|
||||
alt=""
|
||||
class="absolute bottom-2 right-3 translate-2/3 w-18 h-18 object-contain pointer-events-none"
|
||||
style="transform: rotate(-15deg);"
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
<ParticipantSignUp />
|
||||
</div>
|
||||
|
||||
<!-- <img src="hot-air-balloon.png" alt="" class="absolute w-1/8 right-32 bottom-40 z-20"> -->
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue