Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSVP confirmation page #69

Merged
merged 3 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/lib/strapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,39 @@ export const createRecord = async <T>(endpoint: string, data: T) => {
}
};

/**
* The following GETs a record by ID from the Strapi API
* @param endpoint - The endpoint to fetch from
* @param id - The ID of the record to fetch
* @returns The record fetched
*/
export const getRecordById = async (endpoint: string, id: string) => {
try {
const response = await fetch(`${markketplace.STRAPI_URL}/api/${endpoint}/${id}`);
return response.json();
}
catch (error) {
console.error('Record fetch failed:', error);
return false;
}
};

/**
* The following GETs a record by slug from the Strapi API
* @param endpoint
* @param slug
* @returns
*/
export const getRecordBySlug = async (endpoint: string, slug: string) => {
try {
const response = await fetch(`${markketplace.STRAPI_URL}/api/${endpoint}?filters[slug]=${slug}`);
return response.json();
} catch (error) {
console.error('Record fetch failed:', error);
return false;
}
};

/**
* Fetches data from the Strapi API
* @param endpoint - The endpoint to fetch from
Expand Down
10 changes: 9 additions & 1 deletion src/pages/events/[slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,15 @@ const selectedImage =
</button>
)
}
<RSVPModal client:load eventId={event?.id as string} onClose={() => {}} />
{
!event?.data?.SEO?.metaUrl && (
<RSVPModal
client:load
eventId={event?.id as string}
onClose={() => {}}
/>
)
}
</div>
</main>
<Footer />
Expand Down
122 changes: 122 additions & 0 deletions src/pages/events/confirmation.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
import Layout from "../../layouts/Layout.astro";
import { getRecordById, getRecordBySlug } from "../../lib/strapi";

// @TODO : Retrieve event data
// @TODO: Change RSVP id to UUID & retrieve record
const event = {
id: 6,
Name: "Brooklyn Tech Expo, Feb 2025",
startDate: "2025-02-11T16:00:00.000Z",
endDate: "2025-02-11T21:00:00.000Z",
Description: "Brooklyn Tech Expo TECH4LIFE Edition on February 11, 2025",
slug: "brooklyn-tech-expo-2025",
};

// Example RSVP data - in real app this would come from your API
const rsvp = {
name: "John Smith",
email: "j***[email protected]",
};

const formatDate = (date: string) => {
return new Date(date).toLocaleDateString("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
};

const formatTime = (date: string) => {
return new Date(date).toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
});
};
---

<Layout title="RSVP Confirmation - Markkët">
<script define:vars={{ getRecordById, getRecordBySlug }}>
/** reads the ?slug&rsvp_uid from the URL to fetch records from the API */
const params = new URLSearchParams(window.location.search);

async function load({ request }) {
console.log("Confirmation page loading");
const { slug, rsvp_uid } = request.query;
const event = await getRecordBySlug("events", slug);
const rsvp = await getRecordById("rsvps", rsvp_uid);
return { event, rsvp };
}

document.addEventListener("astro:page-load", () => {
const slug = params.get("slug");

console.log({ a: "x", slug });
const rsvp_uid = params.get("rsvp_uid");
console.log({ slug, rsvp_uid });

load({
request: { query: { slug, rsvp_uid } },
});
});
</script>
<div class="confirmation-container mx-auto max-w-[600px] bg-white font-sans">
<header
class="company-name confirmation-header bg-brand-blue p-6 text-center"
>
<h1 class="text-brand-yellow m-0 text-3xl font-bold tracking-wide">
Markkët
</h1>
</header>

<div class="yellow-divider bg-brand-yellow h-1"></div>

<main class="confirmation-content p-8 leading-relaxed text-gray-800">
<div class="mb-8">
<h2 class="mb-4 text-2xl font-bold">RSVP Confirmed! 🎉</h2>
<!-- <p class="mb-2">
Dear <span class="text-brand-magenta font-semibold">
{rsvp.name}
</span>,
</p> -->
<p class="mb-4">
Thank you for confirming your attendance to our upcoming event. We're
excited to have you join us!
</p>
</div>

<div class="mb-8 rounded-lg bg-gray-50 p-6">
<h3 class="mb-4 text-xl font-semibold">Event Details</h3>
<div class="space-y-3">
<p><span class="font-semibold">Event:</span> {event.Name}</p>
<p>
<span class="font-semibold">Date:</span>
{formatDate(event.startDate)}
</p>
<p>
<span class="font-semibold">Time:</span>
{formatTime(event.startDate)} - {formatTime(event.endDate)}
</p>
<!-- <p><span class="font-semibold">Your Email:</span> ''</p> -->
</div>
</div>

<div class="mb-8 text-sm text-gray-600">
<p class="mb-2">
If you need to make any changes to your RSVP, please don't hesitate to
contact us.
</p>
</div>
</main>

<footer
class="confirmation-footer border-t border-gray-200 p-6 text-center"
>
<p class="text-sm text-gray-600">
Powered by
<a href="/about" class="text-brand-blue hover:underline">Markkët</a>
</p>
</footer>
</div>
</Layout>
28 changes: 17 additions & 11 deletions src/pages/events/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,21 @@ import { markketplace } from "@config";
const stores = await getCollection("stores");
let events = await getCollection("events");

const today = new Date();

events = events
.filter(event => new Date(event.data.startDate) > today)
.sort((a, b) => {
return (
new Date(a.data.startDate).getTime() -
new Date(b.data.startDate).getTime()
);
});

// @TODO: separate future and past events

const store: { data: Store } = stores.find(
(store: any) => store.data.slug === markketplace.STORE_SLUG
(store: any) => store.data?.slug === markketplace?.STORE_SLUG
) as any;

const pages = await getCollection("pages");
Expand All @@ -49,7 +62,7 @@ const { currentPage, totalPages } = Astro.props;
description,
}}
>
<Header store={store} />
<Header store={store as any as { data: Store }} />
<main id="main-content">
<section id="about" class="mb-10 prose-img:border-0">
{
Expand Down Expand Up @@ -78,16 +91,9 @@ const { currentPage, totalPages } = Astro.props;
frontmatter={{
author: "x",
title: data.Name || data.SEO?.metaTitle || "---",
pubDatetime: new Date(data.createdAt),
modDatetime: new Date(data.updatedAt),
pubDatetime: new Date(data.startDate),
modDatetime: new Date(data.startDate),
description: data.SEO?.metaDescription || data.Description || "",
SEO: {
...data.SEO,
metaTitle: data.SEO?.metaTitle || data.Name || "Store",
socialImage: {
url: data.SEO?.socialImage?.url || data.Thumbnail?.url,
},
},
}}
/>
))
Expand Down
61 changes: 60 additions & 1 deletion src/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,63 @@ html[data-theme="dark"] a {

.product-page .product-slide {
max-height: 180px;
}
}

/**Confirmation Page & Receipt */
.confirmation-container {
max-width: 600px;
margin: 0 auto;
font-family: Arial, sans-serif;
background-color: #ffffff;
}

.confirmation-header {
background-color: #0057ad;
padding: 20px;
text-align: center;
}

.company-name {
color: #fff000;
font-size: 32px;
font-weight: bold;
margin: 0;
letter-spacing: 1px;
}

.yellow-divider {
height: 4px;
background-color: #fff000;
margin: 0;
}

.confirmation-content {
padding: 40px 20px;
color: #333333;
line-height: 1.6;
}

.text-brand-magenta,
.magenta-highlight {
color: #ff00cf;
}

.confirmation-footer {
padding: 20px;
text-align: center;
border-top: 1px solid #dddddd;
}

.footer-text {
color: #666666;
font-size: 14px;
}

.footer-link {
color: #0057ad;
text-decoration: none;
}

.footer-link:hover {
text-decoration: underline;
}