Skip to content

Commit 0fd9f7b

Browse files
committed
feat(ui): introduce reusable PageHeader component
1 parent f178eec commit 0fd9f7b

File tree

6 files changed

+122
-50
lines changed

6 files changed

+122
-50
lines changed
Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Metadata } from "next";
22
import { buildPageMetadata, siteConfig } from "@/lib/config";
3+
import { PageHeader } from "@/components/primitives/page-header";
34

45
const description =
56
"The first and only global student initiative based in Hong Kong for constructive peace and humanity. First international student chapter of ALPHA Education.";
@@ -8,26 +9,29 @@ export const metadata: Metadata = buildPageMetadata("/about-us/our-story", { des
89
export default function OurStory() {
910
return (
1011
<section className="py-16">
11-
<h1 className="text-4xl font-bold tracking-tight text-center mb-6">Our Story</h1>
12-
<div className="mx-auto max-w-3xl text-lg text-muted-foreground">
13-
<p>
14-
Carrying{" "}
15-
<a
16-
href={siteConfig.parentOrg}
17-
target="_blank"
18-
rel="noopener"
19-
className="text-primary hover:text-primary/80 underline transition-colors"
20-
>
21-
ALPHA Education
22-
</a>
23-
's mandate, we are an independent student organization, the largest student initiative in HKU,
24-
formed by an installation size of 30 students to spread the message of peace and humanity.
25-
<br />
26-
<br />
27-
This is an initiative with great potential leading to a Global Institute of Peace and Humanity based
28-
in HK by 2027.
29-
</p>
30-
</div>
12+
<PageHeader
13+
title="Our Story"
14+
descriptionClassName="text-left"
15+
description={
16+
<>
17+
Carrying{" "}
18+
<a
19+
href={siteConfig.parentOrg}
20+
target="_blank"
21+
rel="noopener"
22+
className="text-primary hover:text-primary/80 underline transition-colors"
23+
>
24+
ALPHA Education
25+
</a>
26+
{"'"}s mandate, we are an independent student organization, the largest student initiative in HKU,
27+
formed by an installation size of 30 students to spread the message of peace and humanity.
28+
<br />
29+
<br />
30+
This is an initiative with great potential leading to a Global Institute of Peace and Humanity
31+
based in HK by 2027.
32+
</>
33+
}
34+
/>
3135
</section>
3236
);
3337
}

src/app/about-us/partners/page.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Image from "next/image";
33
import { buildPageMetadata } from "@/lib/config";
44
import { partners } from "@/lib/partners";
55
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
6+
import { PageHeader } from "@/components/primitives/page-header";
67

78
const description =
89
"We are collaborating with the following partners to share the message of peace and humanity.";
@@ -11,8 +12,11 @@ export const metadata: Metadata = buildPageMetadata("/about-us/partners", { desc
1112
export default function Partners() {
1213
return (
1314
<section className="flex min-h-[85vh] flex-col items-center justify-center gap-4 text-center m-auto w-fit">
14-
<h1 className="text-4xl font-bold tracking-tight">Partners</h1>
15-
<p className="text-lg text-muted-foreground max-w-2xl">{description}</p>
15+
<PageHeader
16+
title="Partners"
17+
descriptionClassName="max-w-2xl"
18+
description={description}
19+
/>
1620
<div className="mt-6 flex flex-col items-center gap-4 w-full">
1721
{partners.map((partner) => (
1822
<a

src/app/join-us/page.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Metadata } from "next";
22
import { buildPageMetadata } from "@/lib/config";
33
import { AnimatedFillButton } from "@/components/primitives/animated-fill-button";
44
import { siteConfig } from "@/lib/config";
5+
import { PageHeader } from "@/components/primitives/page-header";
56

67
const description =
78
"Join The Team at ALPHA University Chapter at the University of Hong Kong, an initiative with great potential.";
@@ -10,11 +11,12 @@ export const metadata: Metadata = buildPageMetadata("/join-us", { description })
1011
export default function JoinUs() {
1112
return (
1213
<section className="flex min-h-[85vh] flex-col items-center justify-center gap-4 text-center m-auto w-fit">
13-
<h1 className="max-w-4xl text-2xl font-bold tracking-tight md:text-4xl">
14-
Join The Team at ALPHA University Chapter at the University of Hong Kong, an initiative with great
15-
potential.
16-
</h1>
17-
<p className="text-base text-muted-foreground md:text-lg">We provide opportunities for:</p>
14+
<PageHeader
15+
title="Join The Team at ALPHA University Chapter at the University of Hong Kong, an initiative with great potential."
16+
description="We provide opportunities for:"
17+
titleClassName="max-w-4xl mx-auto text-2xl md:text-4xl"
18+
descriptionClassName="text-base md:text-lg"
19+
/>
1820
<div className="flex flex-wrap items-center justify-center gap-4 pt-2">
1921
{[
2022
{ label: "Full Membership", href: "" },
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import type { ReactNode } from "react";
2+
import { cn } from "@/lib/utils";
3+
4+
type PageHeaderProps = {
5+
title: ReactNode;
6+
description?: ReactNode;
7+
as?: "h1" | "h2" | "h3";
8+
size?: "sm" | "md" | "lg";
9+
className?: string;
10+
titleClassName?: string;
11+
descriptionClassName?: string;
12+
childrenClassName?: string;
13+
children?: ReactNode;
14+
};
15+
16+
export function PageHeader({
17+
title,
18+
description,
19+
as = "h1",
20+
size = "md",
21+
className,
22+
titleClassName,
23+
descriptionClassName,
24+
childrenClassName,
25+
children,
26+
}: PageHeaderProps) {
27+
const HeadingTag = as;
28+
const sizeStyles = {
29+
sm: { title: "text-3xl", description: "text-base" },
30+
md: { title: "text-4xl", description: "text-lg" },
31+
lg: { title: "text-5xl", description: "text-xl" },
32+
} as const;
33+
return (
34+
<div className={cn("text-center", className)}>
35+
<HeadingTag className={cn(sizeStyles[size].title, "font-bold", titleClassName)}>{title}</HeadingTag>
36+
{description ? (
37+
<p
38+
className={cn(
39+
"mt-4 text-muted-foreground max-w-3xl mx-auto",
40+
sizeStyles[size].description,
41+
descriptionClassName
42+
)}
43+
>
44+
{description}
45+
</p>
46+
) : null}
47+
{children ? <div className={cn("mt-6", childrenClassName)}>{children}</div> : null}
48+
</div>
49+
);
50+
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { Construction } from "lucide-react";
2+
import { PageHeader } from "@/components/primitives/page-header";
23

34
export const comingSoonText = "We're working hard to bring you this page. Stay tuned for something amazing!";
45

56
export function ComingSoon() {
67
return (
78
<div className="flex flex-col items-center justify-center min-h-[calc(100vh-8rem)] text-center px-4">
89
<Construction className="h-16 w-16 mb-4 text-primary" />
9-
<h1 className="text-4xl font-bold mb-2">Coming Soon!</h1>
10-
<p className="text-lg text-muted-foreground max-w-md">{comingSoonText}</p>
10+
<PageHeader
11+
title="Coming Soon!"
12+
description={comingSoonText}
13+
descriptionClassName="mt-2 max-w-md"
14+
/>
1115
</div>
1216
);
1317
}
Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
11
import { Button } from "@/components/ui/button";
22
import Link from "next/link";
33
import { siteConfig } from "@/lib/config";
4+
import { PageHeader } from "@/components/primitives/page-header";
45

56
export function WhoWeAre() {
67
return (
78
<section className="mx-auto text-center">
8-
<h2 className="text-3xl font-bold mb-4">Who We Are</h2>
9-
<p className="max-w-3xl mx-auto text-muted-foreground mb-6">
10-
Carrying{" "}
11-
<a
12-
href={siteConfig.parentOrg}
13-
target="_blank"
14-
rel="noopener"
15-
className="text-primary hover:text-primary/80 underline transition-colors"
16-
>
17-
ALPHA Education
18-
</a>
19-
's mandate, we are an independent student organization, the largest student initiative in HKU, formed
20-
by an installation size of 30 students to spread the message of peace and humanity.
21-
<br />
22-
<br />
23-
This is an initiative with great potential leading to a Global Institute of Peace and Humanity based
24-
in HK by 2027.
25-
</p>
26-
<Button asChild>
27-
<Link href="/about-us">Explore Our Story</Link>
28-
</Button>
9+
<PageHeader
10+
as="h2"
11+
title="Who We Are"
12+
size="sm"
13+
description={
14+
<>
15+
Carrying{" "}
16+
<a
17+
href={siteConfig.parentOrg}
18+
target="_blank"
19+
rel="noopener"
20+
className="text-primary hover:text-primary/80 underline transition-colors"
21+
>
22+
ALPHA Education
23+
</a>
24+
{"'"}s mandate, we are an independent student organization, the largest student initiative in HKU,
25+
formed by an installation size of 30 students to spread the message of peace and humanity.
26+
<br />
27+
<br />
28+
This is an initiative with great potential leading to a Global Institute of Peace and Humanity
29+
based in HK by 2027.
30+
</>
31+
}
32+
>
33+
<Button asChild>
34+
<Link href="/about-us">Explore Our Story</Link>
35+
</Button>
36+
</PageHeader>
2937
</section>
3038
);
3139
}

0 commit comments

Comments
 (0)