Skip to content

Commit 76c2e75

Browse files
authored
Merge pull request #106 from UoaWDCC/feat/global-util-file
feat: global util file
2 parents 189d46f + ad5f2bf commit 76c2e75

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+730
-534
lines changed

README.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
11
# AUSCO Project
22

3-
### TODOs
4-
5-
1. verify a or Link usage for internal/external navigation
6-
2. clean data/content types (required fields cannot be null but add anyway for type safety)
7-
3. make colours/colour variables consistent across website (including logos)
8-
4. check text uses p, h1, etc. tags for seo
9-
5. add secondary global font to repo
10-
6. routing? (with dashes) \*\*
11-
7. blur when image is rendering
12-
8. global util file (stringToList, url checker for Media, etc.) \*\*
13-
9. some links have fallbacks (e.g. constitution/youtube video, etc.) \*
14-
153
### BUGS
164

175
1. font (fraunces) not being applied globally
186
2. double check parallax effect on phone ui screen
19-
3. min-h-screen doesn't account for footer height.
7+
3. min-h-screen doesn't account for footer height. \*
208

219
## Project Setup
2210

next.config.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { withPayload } from "@payloadcms/next/withPayload";
33
/** @type {import('next').NextConfig} */
44
const nextConfig = {
55
// Your Next.js config here
6+
images: {
7+
qualities: [75, 80, 85, 90],
8+
},
69
};
710

811
export default withPayload(nextConfig, { devBundleServerPackages: false });

src/actions/globalActions.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,58 @@
11
"use server";
22

33
import { cache } from "react";
4-
import { getPayload } from "@libs/payload";
4+
import { getPayload } from "payload";
55

6+
import config from "@payload-config";
67
import { Header, Footer, SiteSetting } from "@/payload-types";
78

89
export const getHeader = cache(async (): Promise<Header> => {
9-
const payload = await getPayload();
10+
const payload = await getPayload({ config });
1011
return payload.findGlobal({ slug: "header", depth: 1 });
1112
});
1213

1314
export const getFooter = cache(async (): Promise<Footer> => {
14-
const payload = await getPayload();
15+
const payload = await getPayload({ config });
1516
return payload.findGlobal({ slug: "footer", depth: 1 });
1617
});
1718

18-
export const getSiteSetting = cache(async (): Promise<SiteSetting> => {
19-
const payload = await getPayload();
20-
return payload.findGlobal({ slug: "site-settings", depth: 1 });
21-
});
19+
// TODO: fill in remaining fallbacks (e.g. engage page, feedback form, sign up form, proof of registration, email)
20+
// TODO: edit the admin placeholder text in the sitesetting payload schema
21+
const LINK_FALLBACKS: Record<string, string> = {
22+
facebook: "https://www.facebook.com/ausco.ausa",
23+
instagram: "https://www.instagram.com/ausco.uoa/",
24+
youtube: "https://www.youtube.com/@AUSCO-UoA",
25+
spotify:
26+
"https://open.spotify.com/user/31b5qnnkievulqbuxajy5etbmo7u?si=d4f38d8f71e349b7&nd=1&dlsi=456d9aa5404649b4",
27+
feedbackForm: "https://google.com", // TODO
28+
email: "mailto:[email protected]", // TODO
29+
constitution:
30+
"https://auckland.campuslabs.com/engage/organization/auckland-university-student-chamber-orchestra",
31+
signUpForm: "https://google.com", // TODO
32+
engage: "https://google.com", // TODO
33+
registration: "https://google.com", // TODO
34+
};
35+
export const getSiteSetting = cache(
36+
async (): Promise<SiteSetting & { linksMap: Record<string, string> }> => {
37+
const payload = await getPayload({ config });
38+
39+
const content = await payload.findGlobal({
40+
slug: "site-settings",
41+
depth: 1,
42+
});
43+
44+
const links = content.links ?? [];
45+
46+
const linksMap: Record<string, string> = {};
47+
48+
Object.keys(LINK_FALLBACKS).forEach((platform) => {
49+
const link = links.find((l) => l.platform === platform && l.url?.trim());
50+
linksMap[platform] = link?.url ?? LINK_FALLBACKS[platform];
51+
});
52+
53+
return {
54+
...content,
55+
linksMap,
56+
};
57+
},
58+
);

src/actions/pageActions.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"use server";
22

33
import { cache } from "react";
4-
import { getPayload } from "@libs/payload";
4+
import { getPayload } from "payload";
55

6+
import config from "@payload-config";
67
import {
78
Home,
89
AboutUs,
@@ -19,65 +20,65 @@ import {
1920
} from "@/payload-types";
2021

2122
export const getHome = cache(async (): Promise<Home> => {
22-
const payload = await getPayload();
23+
const payload = await getPayload({ config });
2324
return payload.findGlobal({ slug: "home", depth: 1 });
2425
});
2526

2627
export const getAboutUs = cache(async (): Promise<AboutUs> => {
27-
const payload = await getPayload();
28+
const payload = await getPayload({ config });
2829
return payload.findGlobal({ slug: "about-us", depth: 1 });
2930
});
3031

3132
export const getOurStory = cache(async (): Promise<OurStory> => {
32-
const payload = await getPayload();
33+
const payload = await getPayload({ config });
3334
return payload.findGlobal({ slug: "our-story", depth: 1 });
3435
});
3536

3637
// Payload Globals are single documents, so the generated TS type is singular (OurPerson) even if the slug is plural (our-people).
3738
// See src\collections\global\OurPeople.ts docs for more information.
3839
export const getOurPeople = cache(async (): Promise<OurPerson> => {
39-
const payload = await getPayload();
40+
const payload = await getPayload({ config });
4041
return payload.findGlobal({ slug: "our-people", depth: 1 });
4142
});
4243

4344
// Concert Pages
4445
export const getConcerts = cache(async (): Promise<Concert> => {
45-
const payload = await getPayload();
46+
const payload = await getPayload({ config });
4647
return payload.findGlobal({ slug: "concerts", depth: 1 });
4748
});
4849

4950
export const getConcertsUpcoming = cache(async (): Promise<ConcertsUpcoming> => {
50-
const payload = await getPayload();
51+
const payload = await getPayload({ config });
5152
return payload.findGlobal({ slug: "concerts-upcoming", depth: 1 });
5253
});
5354

5455
export const getConcertsPast = cache(async (): Promise<ConcertsPast> => {
55-
const payload = await getPayload();
56+
const payload = await getPayload({ config });
5657
return payload.findGlobal({ slug: "concerts-past", depth: 1 });
5758
});
5859

5960
// Gallery Pages
6061
export const getGallery = cache(async (): Promise<Gallery> => {
61-
const payload = await getPayload();
62+
const payload = await getPayload({ config });
6263
return payload.findGlobal({ slug: "gallery", depth: 1 });
6364
});
6465

65-
export const getGalleryConcerts = async (): Promise<GalleryConcert> => {
66-
const payload = await getPayload();
67-
return await payload.findGlobal({ slug: "gallery-concert" });
68-
};
66+
export const getGalleryConcerts = cache(async (): Promise<GalleryConcert> => {
67+
const payload = await getPayload({ config });
68+
return await payload.findGlobal({ slug: "gallery-concert", depth: 1 });
69+
});
6970

7071
export const getGalleryAnnualCamp = cache(async (): Promise<GalleryAnnualcamp> => {
71-
const payload = await getPayload();
72+
const payload = await getPayload({ config });
7273
return payload.findGlobal({ slug: "gallery-annualcamp", depth: 1 });
7374
});
7475

75-
export const getGalleryExecutiveCamp = async (): Promise<GalleryExecutivecamp> => {
76-
const payload = await getPayload();
77-
return await payload.findGlobal({ slug: "gallery-executivecamp" });
78-
};
76+
export const getGalleryExecutiveCamp = cache(async (): Promise<GalleryExecutivecamp> => {
77+
const payload = await getPayload({ config });
78+
return await payload.findGlobal({ slug: "gallery-executivecamp", depth: 1 });
79+
});
7980

80-
export const getGalleryOther = async (): Promise<GalleryOther> => {
81-
const payload = await getPayload();
82-
return await payload.findGlobal({ slug: "gallery-other" });
83-
};
81+
export const getGalleryOther = cache(async (): Promise<GalleryOther> => {
82+
const payload = await getPayload({ config });
83+
return await payload.findGlobal({ slug: "gallery-other", depth: 1 });
84+
});
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
import Hero from "@components/aboutus/Hero";
2-
import CardLayout from "@components/aboutus/CardLayout";
1+
import Hero from "@components/about-us/Hero";
2+
import CardLayout from "@components/about-us/CardLayout";
33

44
import { getAboutUs } from "@/actions/pageActions";
55
import { getSiteSetting } from "@/actions/globalActions";
66

77
export default async function AboutPage() {
88
const [aboutUsContent, siteSettingContent] = await Promise.all([getAboutUs(), getSiteSetting()]);
99

10-
const constitutionLink = siteSettingContent?.links?.find(
11-
(link) => link.platform === "constitution",
12-
)?.url;
1310
const cardContent = {
1411
...aboutUsContent.cards,
15-
constitutionLink,
12+
constitutionLink: siteSettingContent.linksMap.constitution,
1613
};
1714

1815
return (

src/app/(frontend)/components/aboutus/CardLayout.tsx renamed to src/app/(frontend)/components/about-us/CardLayout.tsx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { Media } from "@/payload-types";
55
import DesktopCard from "./DesktopCard";
66
import PhoneCard from "./PhoneCard";
77

8+
import { getImageUrl, getImageAlt } from "@/app/(frontend)/util/media";
9+
810
type CardProps = {
911
background: Media | string | null;
1012
title: string;
@@ -19,28 +21,11 @@ type CardLayoutProps = {
1921
story: CardProps;
2022
constitution: CardProps;
2123
sponsorsAndPartnerships: CardProps;
22-
constitutionLink?: string | null;
24+
constitutionLink: string;
2325
};
2426
};
2527

2628
const CardLayout = ({ content }: CardLayoutProps) => {
27-
const getImageUrl = (image: Media | string | null | undefined): string | null => {
28-
if (!image) return null; // handle undefined or null
29-
if (typeof image === "string") return image; // if it's already a string URL
30-
if (typeof image === "object" && image.url) return image.url; // if it's a Media object, extract the URL
31-
return null;
32-
};
33-
34-
const getImageAlt = (image: Media | string | null | undefined, fallback: string): string => {
35-
if (!image) return fallback; // handle undefined or null
36-
if (typeof image === "object" && image?.alt) return image.alt; // if it's a Media object, extract the alt text
37-
return fallback;
38-
};
39-
40-
const constitutionLink =
41-
content.constitutionLink ??
42-
"https://auckland.campuslabs.com/engage/organization/auckland-university-student-chamber-orchestra";
43-
4429
return (
4530
<section className="flex w-full flex-col">
4631
{/* Desktop Layout: md and above */}
@@ -67,7 +52,7 @@ const CardLayout = ({ content }: CardLayoutProps) => {
6752
title={content.story.title}
6853
summary={content.story.summary}
6954
description={`View ${content.story.title}`}
70-
link={"https://ausco.wdcc.co.nz/ourstory"}
55+
link={"/our-story"}
7156
/>
7257
</div>
7358
</div>
@@ -82,7 +67,7 @@ const CardLayout = ({ content }: CardLayoutProps) => {
8267
title={content.constitution.title}
8368
summary={content.constitution.summary}
8469
description={`View ${content.constitution.title}`}
85-
link={constitutionLink}
70+
link={content.constitutionLink}
8671
/>
8772
</div>
8873

@@ -123,7 +108,7 @@ const CardLayout = ({ content }: CardLayoutProps) => {
123108

124109
<div className="mx-6 h-px bg-(--navy) md:hidden" />
125110

126-
<PhoneCard type="constitution" link={constitutionLink} />
111+
<PhoneCard type="constitution" link={content.constitutionLink} />
127112
</div>
128113
</div>
129114
</section>

src/app/(frontend)/components/aboutus/DesktopCard.tsx renamed to src/app/(frontend)/components/about-us/DesktopCard.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import Image from "next/image";
66
import { motion, useScroll, useSpring, useTransform } from "framer-motion";
77

88
import { Media } from "@/payload-types";
9-
import parallaxConfig from "@/config/parallax";
9+
import { isExternal } from "@/app/(frontend)/util/url";
10+
import parallaxConfig from "@/app/(frontend)/config/parallax";
1011

1112
import { Button } from "../ui/button";
1213
import LogoCarousel from "./LogoCarousel";
14+
import Link from "next/link";
1315

1416
type DesktopCardProps = {
1517
icon: React.ReactNode;
@@ -84,11 +86,19 @@ const DesktopCard = ({
8486
{isSponsored && <LogoCarousel logos={sponsorLogos} />}
8587

8688
{isLinked ? (
87-
<Button variant="link" asChild className="mt-10">
88-
<a href={link} target="_blank" rel="noopener noreferrer">
89-
<h1 className="line-clamp-3 text-3xl">{description}</h1>
90-
</a>
91-
</Button>
89+
link && isExternal(link) ? (
90+
<Button asChild variant="link" className="mt-10">
91+
<a href={link} target="_blank" rel="noopener noreferrer">
92+
<h1 className="line-clamp-3 text-3xl">{description}</h1>
93+
</a>
94+
</Button>
95+
) : (
96+
<Button asChild variant="link" className="mt-10">
97+
<Link href={link ?? "#"}>
98+
<h1 className="line-clamp-3 text-3xl">{description}</h1>
99+
</Link>
100+
</Button>
101+
)
92102
) : (
93103
<p className={`text-center text-base ${isSponsored ? "line-clamp-2" : "line-clamp-6"}`}>
94104
{description}
File renamed without changes.

src/app/(frontend)/components/aboutus/LogoCarousel.tsx renamed to src/app/(frontend)/components/about-us/LogoCarousel.tsx

File renamed without changes.

src/app/(frontend)/components/aboutus/PhoneCard.tsx renamed to src/app/(frontend)/components/about-us/PhoneCard.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import { useState } from "react";
44

55
import Link from "next/link";
6-
import { X, ChevronDown, ArrowUpRight } from "lucide-react";
6+
import { ArrowUpRight, ChevronDown, X } from "lucide-react";
77

88
import { Media } from "@/payload-types";
9+
import { isExternal } from "@/app/(frontend)/util/url";
10+
911
import LogoCarousel from "./LogoCarousel";
1012

1113
type CardType = "vision" | "sponsors" | "story" | "constitution";
@@ -40,10 +42,6 @@ const PhoneCard = ({ type, content, sponsorLogos, link }: PhoneCardProps) => {
4042
const card = CARD_MAP[type];
4143
const [open, setOpen] = useState(false);
4244

43-
const isExternal = (url: string) => {
44-
return url.startsWith("http://") || url.startsWith("https://");
45-
};
46-
4745
if (card.collapsible) {
4846
return (
4947
<>

0 commit comments

Comments
 (0)