Skip to content

Commit

Permalink
Merge pull request #12 from DSC-McMaster-U/feature/MB-19-newsletter
Browse files Browse the repository at this point in the history
Feature/mb 19 newsletter
  • Loading branch information
aidanfroggatt authored Nov 6, 2024
2 parents 986cfc0 + c183f1e commit 3380415
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 54 deletions.
44 changes: 28 additions & 16 deletions app/events/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 (
<div>
<h1 className="text-2xl font-bold">{Event.title}</h1>
<h2 className="text-lg text-gray-600">{Event.description}</h2>
<p className="text-xs text-gray-400">
{new Date(Event._updatedAt).toLocaleDateString()}
</p>
<p>{Event.startTime} - {Event.endTime}</p>
<p>{Event.location}</p>
<p>{Event.organizer}</p>
<p>{Event.contactEmail}</p>
<h1 className="text-2xl font-bold">{event.title}</h1>
<h2 className="text-lg text-gray-600">{event.description}</h2>
<p className="text-xs text-gray-400">
{new Date(event._updatedAt).toLocaleDateString()}
</p>
<p>{event.startTime} - {event.endTime}</p>
<p>{event.location}</p>
<p>{event.organizer}</p>
<p>{event.contactEmail}</p>
</div>
);
};
Expand Down
48 changes: 46 additions & 2 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -58,4 +58,48 @@ header {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
}
}

.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;
}
110 changes: 93 additions & 17 deletions app/newsletters/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,89 @@
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 }
);

return newsletter;
};

const serializers: Partial<PortableTextReactComponents> = {
types: {
image: ({ value }: { value: { asset: { url: string }; alt?: string } }) => (
<div className="my-4">
<Image
src={value.asset.url}
alt={value.alt || "Image"}
width={600}
height={400}
className="rounded-lg"
/>
</div>
),
},
marks: {
link: ({ children, value }: { children: React.ReactNode; value?: { href: string } }) => (
<Link href={value?.href ?? "#"} target="_blank" rel="noopener noreferrer" className="newsletter-a">
{children}
</Link>
),
strong: ({ children }: { children: React.ReactNode }) => (
<strong className="font-bold">{children}</strong>
),
em: ({ children }: { children: React.ReactNode }) => (
<em className="italic">{children}</em>
),
},
block: {
h1: ({ children }: PortableTextComponentProps<unknown>) => <h1 className="newsletter-h1">{children}</h1>,
h2: ({ children }: PortableTextComponentProps<unknown>) => <h2 className="newsletter-h2">{children}</h2>,
h3: ({ children }: PortableTextComponentProps<unknown>) => <h3 className="newsletter-h3">{children}</h3>,
normal: ({ children }: PortableTextComponentProps<unknown>) => <p className="newsletter-p">{children}</p>,
ul: ({ children }: PortableTextComponentProps<unknown>) => (
<ul className="newsletter-ul">{children}</ul>
),
li: ({ children }: PortableTextComponentProps<unknown>) => (
<li className="newsletter-li">{children}</li>
),
},
listItem: {
bullet: ({ children }: PortableTextComponentProps<unknown>) => <li className="newsletter-bullet">{children}</li>,
number: ({ children }: PortableTextComponentProps<unknown>) => (
<li className="newsletter-number">{children}</li>
),
}
};

const NewsletterDetailPage = async ({ params }: { params: { slug: string } }) => {
const { slug } = params;
const newsletter: Newsletter = await fetchNewsletter(slug);
Expand All @@ -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 (
<div>
<h1 className="text-2xl font-bold">{newsletter.title}</h1>
<h2 className="text-lg text-gray-600">{newsletter.description}</h2>
<p className="text-xs text-gray-400">
{new Date(newsletter._updatedAt).toLocaleDateString()}
</p>
{/* Render the body of the newsletter */}
</div>
<>
<Header />
<main>
<section id="newsletter" className="flex flex-col gap-y-4">
<div className="flex flex-col gap-y-4 pb-12 mb-12 border-b-2 border-google-darkGrey dark:border-google-lightGrey">
<h2>{newsletter.title}</h2>
<h5>{newsletter.description}</h5>
<p>{formattedDate}</p>
</div>
{/* Render the newsletter body using PortableText */}
<PortableText value={newsletter.body} components={serializers} />
</section>
</main>
<Footer />
</>
);
};

Expand Down
34 changes: 17 additions & 17 deletions app/newsletters/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import LinkTitleCard from "@/app/components/LinkTitleCard";
export const metadata: Metadata = {
title: "Newsletters | GDSC McMaster U",
description: "Newsletters from GDSC McMaster U",
};
};

const fetchNewsletters = async () => {
const newsletters = await client.fetch(
Expand All @@ -30,22 +30,22 @@ const NewslettersPage = async () => {
<>
<Header />
<main>
<section id="newsletters" className="flex flex-col gap-y-4">
<h2>Newsletters</h2>
<p>Through GDSC McMaster University&apos;s monthly newsletter, stay updated on the latest tech news, events, and innovations. Featuring industry trends, club highlights, and upcoming activities, the newsletter connects members to valuable insights and opportunities in the tech world.</p>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 pt-10">
{newsletters.map((newsletter) => (
<LinkTitleCard
key={newsletter.slug.current}
title={newsletter.title}
link={`/newsletters/${newsletter.slug.current}`}
>
<p>{newsletter.description}</p>
</LinkTitleCard>
))}
</div>
</section>
</main>
<section id="newsletters" className="flex flex-col gap-y-4">
<h2>Newsletters</h2>
<p>Through GDSC McMaster University&apos;s monthly newsletter, stay updated on the latest tech news, events, and innovations. Featuring industry trends, club highlights, and upcoming activities, the newsletter connects members to valuable insights and opportunities in the tech world.</p>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 pt-10">
{newsletters.map((newsletter) => (
<LinkTitleCard
key={newsletter.slug.current}
title={newsletter.title}
link={`/newsletters/${newsletter.slug.current}`}
>
<p>{newsletter.description}</p>
</LinkTitleCard>
))}
</div>
</section>
</main>
<Footer />
</>
);
Expand Down
4 changes: 2 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const EventsSection = async () => {
<span className="text-sm">{event.type}</span>
</Tag><div className="transition-transform duration-300 ease-in-out">
<h5>{event.title}</h5>
<p className="text-google-grey dark:text-google-lightGrey">{event.description}</p>
<p>{event.description}</p>
</div>
</>
}
Expand Down Expand Up @@ -182,7 +182,7 @@ const NewslettersSection = async () => {
<section id="newsletters" className="flex flex-col gap-y-8">
<h2>Newsletters</h2>
<div className="flex flex-col md:flex-row md:gap-x-8 md:gap-y-0 gap-y-8 md:items-center">
<h6 className="md:w-4/5 dark:text-google-lightGrey text-google-grey">Through GDSC McMaster University&apos;s monthly newsletter, stay updated on the latest tech news, events, and innovations. Featuring industry trends, club highlights, and upcoming activities, the newsletter connects members to valuable insights and opportunities in the tech world.</h6>
<h6 className="md:w-4/5">Through GDSC McMaster University&apos;s monthly newsletter, stay updated on the latest tech news, events, and innovations. Featuring industry trends, club highlights, and upcoming activities, the newsletter connects members to valuable insights and opportunities in the tech world.</h6>
<div className="md:w-1/5 flex flex-col gap-y-2">
<h5>{newsletterCount}</h5>
<p className="text-sm"><span className="text-google-darkGrey dark:text-google-lightGrey">Monthly newsletters</span> available to read.</p>
Expand Down

0 comments on commit 3380415

Please sign in to comment.