diff --git a/app/events/[slug]/page.tsx b/app/events/[slug]/page.tsx index 458dd71..d4d2c88 100644 --- a/app/events/[slug]/page.tsx +++ b/app/events/[slug]/page.tsx @@ -2,17 +2,29 @@ import { client } from '@/sanity/lib/client'; import { Event } from '@/types/sanity'; export async function generateMetadata({ params }: { params: { slug: string } }) { + // Fetch the event using the slug + const event = await fetchEvent(params.slug); + + // If no event is found, return default metadata + if (!event) { + return { + title: "Event | GDSC McMaster U", + description: "Event details not found", + }; + } + + // Use the event title for the metadata return { - title: `${params.slug} | GDSC McMaster U`, - description: `Event | ${params.slug}`, + title: `${event.title} | GDSC McMaster U`, + description: `Event | ${event.title}`, }; } const fetchEvent = async (slug: string) => { - const Event = await client.fetch( + const event = await client.fetch( `*[_type == 'event' && slug.current == $slug][0]{ title, - subtitle, + description, startTime, endTime, location, @@ -32,28 +44,28 @@ const fetchEvent = async (slug: string) => { { slug } ); - return Event; + return event; }; const EventDetailPage = async ({ params }: { params: { slug: string } }) => { const { slug } = params; - const Event: Event = await fetchEvent(slug); + const event: Event = await fetchEvent(slug); - if (!Event) { + if (!event) { throw new Response("Not Found", { status: 404 }); } return (
-

{Event.title}

-

{Event.description}

-

- {new Date(Event._updatedAt).toLocaleDateString()} -

-

{Event.startTime} - {Event.endTime}

-

{Event.location}

-

{Event.organizer}

-

{Event.contactEmail}

+

{event.title}

+

{event.description}

+

+ {new Date(event._updatedAt).toLocaleDateString()} +

+

{event.startTime} - {event.endTime}

+

{event.location}

+

{event.organizer}

+

{event.contactEmail}

); }; diff --git a/app/globals.css b/app/globals.css index a8b0802..5bc0ad1 100644 --- a/app/globals.css +++ b/app/globals.css @@ -32,7 +32,7 @@ h6 { } p { - @apply text-sm sm:text-base lg:text-lg dark:text-google-lightGrey text-google-grey; + @apply text-sm sm:text-base lg:text-lg dark:text-google-lightGrey text-google-darkGrey; } main { @@ -58,4 +58,48 @@ header { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } -} \ No newline at end of file +} + +.newsletter-h1 { + @apply text-3xl sm:text-4xl lg:text-5xl font-bold text-black dark:text-white pt-10; +} + +.newsletter-h2 { + @apply text-2xl sm:text-3xl lg:text-4xl font-bold text-black dark:text-white pt-8; +} + +.newsletter-h3 { + @apply text-xl sm:text-2xl lg:text-3xl font-medium text-black dark:text-white pt-6; +} + +.newsletter-h4 { + @apply text-lg sm:text-xl lg:text-2xl dark:text-black text-white pt-4; +} + +.newsletter-p { + @apply text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey; +} + +.newsletter-a { + @apply text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey underline transition-colors duration-200; +} + +.newsletter-a:hover { + @apply text-google-blue dark:text-google-yellow; +} + +.newsletter-ul { + @apply list-disc list-inside text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey; +} + +.newsletter-li { + @apply text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey; +} + +.newsletter-bullet { + @apply list-inside list-disc text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey; +} + +.newsletter-number { + @apply list-inside list-decimal text-base sm:text-lg lg:text-xl dark:text-google-lightGrey text-google-darkGrey; +} diff --git a/app/newsletters/[slug]/page.tsx b/app/newsletters/[slug]/page.tsx index 72a290c..e5a2390 100644 --- a/app/newsletters/[slug]/page.tsx +++ b/app/newsletters/[slug]/page.tsx @@ -1,21 +1,35 @@ -import { client } from '@/sanity/lib/client'; -import { Newsletter } from '@/types/sanity'; +import { PortableText, PortableTextComponentProps, PortableTextReactComponents } from "@portabletext/react"; +import { client } from "@/sanity/lib/client"; +import { Newsletter } from "@/types/sanity"; +import Image from "next/image"; +import Link from "next/link"; +import Footer from "@/app/components/Footer"; +import Header from "@/app/components/Header"; export async function generateMetadata({ params }: { params: { slug: string } }) { + const newsletter = await fetchNewsletter(params.slug); + + if (!newsletter) { + return { + title: "Newsletter | GDSC McMaster U", + description: "Newsletter content not found", + }; + } + return { - title: `${params.slug} | GDSC McMaster U`, - description: `Newsletter | ${params.slug}`, + title: `${newsletter.title} | GDSC McMaster U`, + description: `Newsletter | ${newsletter.title}`, }; } const fetchNewsletter = async (slug: string) => { const newsletter = await client.fetch( `*[_type == 'newsletter' && slug.current == $slug][0]{ - title, - description, - slug, - body, - _updatedAt + title, + description, + slug, + body, + _updatedAt }`, { slug } ); @@ -23,6 +37,53 @@ const fetchNewsletter = async (slug: string) => { return newsletter; }; +const serializers: Partial = { + types: { + image: ({ value }: { value: { asset: { url: string }; alt?: string } }) => ( +
+ {value.alt +
+ ), + }, + marks: { + link: ({ children, value }: { children: React.ReactNode; value?: { href: string } }) => ( + + {children} + + ), + strong: ({ children }: { children: React.ReactNode }) => ( + {children} + ), + em: ({ children }: { children: React.ReactNode }) => ( + {children} + ), + }, + block: { + h1: ({ children }: PortableTextComponentProps) =>

{children}

, + h2: ({ children }: PortableTextComponentProps) =>

{children}

, + h3: ({ children }: PortableTextComponentProps) =>

{children}

, + normal: ({ children }: PortableTextComponentProps) =>

{children}

, + ul: ({ children }: PortableTextComponentProps) => ( +
    {children}
+ ), + li: ({ children }: PortableTextComponentProps) => ( +
  • {children}
  • + ), + }, + listItem: { + bullet: ({ children }: PortableTextComponentProps) =>
  • {children}
  • , + number: ({ children }: PortableTextComponentProps) => ( +
  • {children}
  • + ), + } +}; + const NewsletterDetailPage = async ({ params }: { params: { slug: string } }) => { const { slug } = params; const newsletter: Newsletter = await fetchNewsletter(slug); @@ -31,15 +92,30 @@ const NewsletterDetailPage = async ({ params }: { params: { slug: string } }) => throw new Response("Not Found", { status: 404 }); } + // Format the date as "Monday, September 16, 2024" + const formattedDate = new Date(newsletter._updatedAt).toLocaleDateString("en-US", { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", + }); + return ( -
    -

    {newsletter.title}

    -

    {newsletter.description}

    -

    - {new Date(newsletter._updatedAt).toLocaleDateString()} -

    - {/* Render the body of the newsletter */} -
    + <> +
    +
    +
    +
    +

    {newsletter.title}

    +
    {newsletter.description}
    +

    {formattedDate}

    +
    + {/* Render the newsletter body using PortableText */} + +
    +
    +