Skip to content
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
13 changes: 11 additions & 2 deletions src/pages/events-new.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import { getEnv } from "../utils/getEnv";
import { fetchEvents, type EventItem } from "../store/eventsClient";
import { eventMetaTags } from "../utils/eventMeta";
import HomeLayout from "../layouts/HomeLayout.astro";
import HomeNavbar from "../components/home/HomeNavbar.astro";
import Button from "../components/ui/Button.astro";
Expand All @@ -10,6 +11,12 @@ const membershipLive = getEnv("MEMBERSHIP_LIVE", Astro.locals) === "true";

const events: EventItem[] = await fetchEvents(Astro.locals).catch(() => []);

// A shared `?event=<id>` link (see the modal's "copy link" button) should
// preview as that specific event, not the generic Events page.
const linkedEventId = Astro.url.searchParams.get("event");
const linkedEvent = linkedEventId ? events.find((e) => e.id === linkedEventId) : undefined;
const meta = linkedEvent ? eventMetaTags(linkedEvent) : null;

// Pick and describe the next event by its instant, not by the organizer-zone
// `date` string — that one is a day off for part of the world.
// `fetchEvents` doesn't return the feed in date order, so pick the soonest
Expand Down Expand Up @@ -42,8 +49,10 @@ const eventSchema = nextEvent && {
---

<HomeLayout
title="Events | Tech for Palestine"
description="Tech for Palestine community events — webinars, workshops, and networking sessions for builders and organizers in the Palestinian liberation movement."
title={meta?.title ?? "Events | Tech for Palestine"}
description={meta?.description ??
"Tech for Palestine community events — webinars, workshops, and networking sessions for builders and organizers in the Palestinian liberation movement."}
image={meta?.image}
noindex={true}
>
<Fragment slot="head">
Expand Down
18 changes: 15 additions & 3 deletions src/pages/events.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,29 @@ import Layout from "../layouts/Layout.astro";
import EventsComponent from "../components/Events.tsx";
import "../styles/base.css";
import PageHeader from "../components/PageHeader.astro";
import type { EventItem } from "../store/eventsClient";
import { fetchEvents, type EventItem } from "../store/eventsClient";
import { eventMetaTags } from "../utils/eventMeta";

let events: EventItem[] = [];
let loading: boolean = true;

// Skip SSR fetch for now - let client handle it

// Exception to the above: a shared `?event=<id>` link (see the modal's "copy
// link" button) needs a real title/description/image for its link preview,
// which only a server-side fetch can provide before the client ever renders.
const linkedEventId = Astro.url.searchParams.get("event");
const linkedEvent = linkedEventId
? (await fetchEvents(Astro.locals).catch(() => [])).find((e) => e.id === linkedEventId)
: undefined;
const meta = linkedEvent ? eventMetaTags(linkedEvent) : null;
---

<Layout
title="Events - Tech for Palestine"
description="Tech for Palestine events bring together builders, organizers, and allies to collaborate, share ideas, and take action in support of Palestinian liberation. Join our community webinars, workshops, and networking sessions."
title={meta?.title ?? "Events - Tech for Palestine"}
description={meta?.description ??
"Tech for Palestine events bring together builders, organizers, and allies to collaborate, share ideas, and take action in support of Palestinian liberation. Join our community webinars, workshops, and networking sessions."}
image={meta?.image}
>
<PageHeader
overline="Tech for Palestine"
Expand Down
32 changes: 32 additions & 0 deletions src/utils/eventMeta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { DEFAULT_EVENT_IMAGE, type EventItem } from "../store/eventsClient";
import { displayTitle } from "./eventSections";
import { getDescriptionExcerpt } from "./eventDescription";

const SITE_ORIGIN = "https://techforpalestine.org";
const DEFAULT_OG_IMAGE = `${SITE_ORIGIN}/t4p-social-logo.png`;
const DEFAULT_DESCRIPTION = "Join Tech for Palestine for this event.";

export interface EventMeta {
title: string;
description: string;
image: string;
}

// Builds the title/description/image for a shared event link's OG/Twitter
// preview, so pasting a `?event=<id>` URL shows the actual event instead of
// the page's generic "Events" meta.
export function eventMetaTags(event: EventItem): EventMeta {
const title = `${displayTitle(event)} - Tech for Palestine Events`;
const description = event.description
? getDescriptionExcerpt(event.description) || DEFAULT_DESCRIPTION
: DEFAULT_DESCRIPTION;

let image = DEFAULT_OG_IMAGE;
if (event.image && event.image !== DEFAULT_EVENT_IMAGE) {
image = event.image.startsWith("http")
? event.image
: new URL(event.image, SITE_ORIGIN).toString();
}

return { title, description, image };
}
Loading