Skip to content

Commit b70e962

Browse files
authored
Frontend - Copy layout from teaser website, basic components (#17)
* Copy Navbar and Footer from teaser website * Rearrange page layout and navbar for portal * Add common components from Figma (card, heading, button) * make button text smaller on desktop (looks nicer) * set web page to dark mode
1 parent a26e6bc commit b70e962

27 files changed

+2559
-35
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## Hackathon Portal
1+
# Hackathon Portal
22

3-
# Repo Structure
4-
- `server`: backend
5-
- `client`: frontend
3+
## Repo Structure
4+
5+
- [`server`](./server/): backend
6+
- [`client`](./client/): frontend

client/next.config.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/** @type {import('next').NextConfig} */
2-
const nextConfig = {}
2+
const nextConfig = {
3+
webpack(config) {
4+
config.module.rules.push({
5+
test: /\.svg$/,
6+
use: [
7+
{
8+
loader: '@svgr/webpack',
9+
options: {
10+
svgo: true,
11+
svgoConfig: {
12+
plugins: [
13+
{
14+
name: 'removeViewBox',
15+
active: false,
16+
},
17+
],
18+
},
19+
},
20+
},
21+
],
22+
});
323

4-
module.exports = nextConfig
24+
return config;
25+
},
26+
};
27+
28+
module.exports = nextConfig;

client/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
"lint:check": "prettier --check ./src && next lint"
1111
},
1212
"dependencies": {
13+
"@emotion/react": "^11.14.0",
14+
"@emotion/styled": "^11.14.0",
15+
"@mui/icons-material": "^6.2.1",
16+
"@mui/material": "^6.2.1",
17+
"@svgr/webpack": "^8.1.0",
1318
"@types/node": "20.6.0",
1419
"@types/react": "18.2.21",
1520
"@types/react-dom": "18.2.7",
File renamed without changes.
799 KB
Loading
1.52 MB
Loading

client/public/assets/discord.svg

Lines changed: 5 additions & 0 deletions
Loading

client/public/assets/facebook.svg

Lines changed: 3 additions & 0 deletions
Loading

client/public/assets/instagram.svg

Lines changed: 5 additions & 0 deletions
Loading

client/src/app/globals.css

Lines changed: 0 additions & 7 deletions
This file was deleted.

client/src/app/layout.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
import './globals.css';
1+
import Footer from '@/components/Footer';
2+
import Navbar from '@/components/Navbar';
3+
import '@/styles/globals.scss';
24
import type { Metadata } from 'next';
35
import { DM_Sans } from 'next/font/google';
46

5-
const dmSans = DM_Sans({ subsets: ['latin'] });
7+
const dmSans = DM_Sans({ subsets: ['latin'], weight: ['200', '400', '500', '600', '700'] });
68

79
export const metadata: Metadata = {
8-
title: 'ACM Static Site Template',
9-
description: 'Template for making ACM websites!',
10+
title: 'DiamondHacks 2025',
11+
description: "ACM at UCSD's annual hackathon",
1012
};
1113

1214
export default function RootLayout({ children }: { children: React.ReactNode }) {
1315
return (
1416
<html lang="en">
15-
<body className={dmSans.className}>{children}</body>
17+
<body className={dmSans.className}>
18+
<Navbar />
19+
{children}
20+
<Footer />
21+
</body>
1622
</html>
1723
);
1824
}

client/src/app/page.module.scss

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
@use '../styles/vars.scss' as vars;
2+
13
.main {
2-
height: 100%;
3-
width: 100%;
4+
flex: auto;
45
display: flex;
5-
align-items: center;
6-
justify-content: center;
6+
flex-direction: column;
7+
gap: 10rem;
8+
padding: 6rem var(--side-padding);
9+
}
10+
11+
.buttonRow {
12+
display: flex;
13+
justify-content: end;
714
gap: 1rem;
8-
flex-wrap: wrap;
15+
16+
@media screen and (max-width: vars.$breakpoint-md) {
17+
flex-direction: column;
18+
}
919
}

client/src/app/page.tsx

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
1+
import Card from '@/components/Card';
12
import styles from './page.module.scss';
2-
import Image from 'next/image';
3+
import Heading from '@/components/Heading';
4+
import Button from '@/components/Button';
5+
import Typography from '@/components/Typography';
36

47
export default function Home() {
58
return (
69
<main className={styles.main}>
7-
<div>
8-
<Image src="/acm-logo.png" width={100} height={100} alt="ACM Logo" />
9-
</div>
10-
<div>
11-
<h1>Welcome to ACM&apos;s static site template!</h1>
12-
</div>
10+
<Card gap={1}>
11+
<Heading centered>Hello gamers</Heading>
12+
<Typography variant="body/medium" component="p">
13+
The Association for Computing Machinery (ACM) is the world’s largest society for
14+
computing. Created during the beginning of the Computer Revolution, the organization has
15+
played a strong role in the development of the eld. With over 100,000 members, ACM’s
16+
members span the entire globe and are leaders throughout industry and research. The
17+
organization aims to advance the eld of computing as both a science and as a profession,
18+
so that its members can use their knowledge for the greater social good.
19+
</Typography>
20+
<Typography variant="body/medium" component="p">
21+
Chapters of ACM exist at many universities around the world, creating a vast global
22+
network connecting thousands of students together. In 2019, ACM at UC San Diego has been
23+
revived in an effort to foster a diverse community for all students interested in the eld
24+
of computing. This constitution serves to govern its operations. It denes the Chapter’s
25+
goals, its moral code, its membership requirements, its Activity specications, its
26+
organizational structure, its Board responsibilities, its nancial duties, its Advisor’s
27+
role, and its constitutional amendment process. This shall be an all binding document
28+
governing the Chapter’s functions and the actions of its members.
29+
</Typography>
30+
<Typography variant="body/medium" component="p">
31+
Finally, due to the ever-changing nature of the organization, every year the new Executive
32+
board may make changes to the constitution as they see t based on what they feel is
33+
necessary to better lead the organization. These changes should be discussed openly with
34+
the rest of board.
35+
</Typography>
36+
<div className={styles.buttonRow}>
37+
<Button variant="tertiary">Discard Changes</Button>
38+
<Button variant="secondary" href="/">
39+
Save Changes
40+
</Button>
41+
<Button variant="primary">Next</Button>
42+
</div>
43+
</Card>
1344
</main>
1445
);
1546
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import styles from './style.module.scss';
2+
import Link, { LinkProps } from 'next/link';
3+
import { PropsWithChildren } from 'react';
4+
5+
interface ButtonProps {
6+
/**
7+
* Primary buttons are filled blue, secondary buttons are filled white, and
8+
* tertiary buttons are outlined blue.
9+
*
10+
* Default: `primary`.
11+
*/
12+
variant?: 'primary' | 'secondary' | 'tertiary';
13+
href?: string;
14+
onClick?: () => void;
15+
}
16+
17+
const Button = ({ variant, href, onClick, children }: PropsWithChildren<ButtonProps>) => {
18+
const props = { className: styles.button, 'data-variant': variant, onClick, children };
19+
return href ? <Link href={href} {...props} /> : <button type="button" {...props} />;
20+
};
21+
22+
export default Button;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@use '@/styles/vars.scss' as vars;
2+
3+
.button {
4+
display: flex;
5+
border-radius: 2rem;
6+
padding: 0.5rem 2rem;
7+
min-width: 8.75rem;
8+
min-height: 2.5rem;
9+
align-items: center;
10+
justify-content: center;
11+
color: vars.$btn-text;
12+
// Corresponds to diamond-theme/label/small
13+
font-weight: 500;
14+
letter-spacing: 0.5px;
15+
16+
&[data-variant='primary'] {
17+
background-color: vars.$btn-primary;
18+
}
19+
20+
&[data-variant='secondary'] {
21+
background-color: vars.$btn-secondary;
22+
}
23+
24+
&[data-variant='tertiary'] {
25+
border: 1px solid vars.$btn-primary;
26+
color: vars.$btn-primary;
27+
}
28+
}

client/src/components/Card/index.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import styles from './style.module.scss';
2+
import { PropsWithChildren } from 'react';
3+
4+
interface CardProps {
5+
gap: 0 | 1 | 1.5 | 2;
6+
}
7+
8+
const Card = ({ gap, children }: PropsWithChildren<CardProps>) => {
9+
return (
10+
<div className={styles.container} style={{ gap: `${gap}rem` }}>
11+
{children}
12+
</div>
13+
);
14+
};
15+
16+
export default Card;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@use '@/styles/vars.scss' as vars;
2+
3+
.container {
4+
display: flex;
5+
flex-direction: column;
6+
gap: 2rem;
7+
padding: vars.$card-padding;
8+
background-color: vars.$card-bg;
9+
border: 1px solid vars.$card-stroke;
10+
border-radius: 0.5rem;
11+
12+
@media screen and (max-width: vars.$breakpoint-md) {
13+
padding: vars.$card-padding-mobile;
14+
}
15+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Typography from '@/components/Typography';
2+
import styles from './style.module.scss';
3+
import Link from 'next/link';
4+
import Image from 'next/image';
5+
import Instagram from '../../../public/assets/instagram.svg';
6+
import Discord from '../../../public/assets/discord.svg';
7+
import Facebook from '../../../public/assets/facebook.svg';
8+
import DiamondPileLeft from '../../../public/assets/diamond-pile-left.png';
9+
import DiamondPileRight from '../../../public/assets/diamond-pile-right.png';
10+
import AcmLogo from '../../../public/assets/acm-logo.png';
11+
12+
const Footer: React.FC = () => {
13+
return (
14+
<div className={styles.container}>
15+
<Image src={DiamondPileLeft} alt="Pile of diamonds" className={styles.backgroundLeft} />
16+
<Image src={DiamondPileRight} alt="Pile of diamonds" className={styles.backgroundRight} />
17+
<div className={styles.links}>
18+
<Link href="https://acmucsd.com/about">
19+
<Typography variant="body/large">About Us</Typography>
20+
</Link>
21+
<Link href="https://acmucsd.com/">
22+
<Image src={AcmLogo} alt="ACM" width={144} height={144} />
23+
</Link>
24+
<Link href="https://acmucsd.com/#contact">
25+
<Typography variant="body/large">Contact Us</Typography>
26+
</Link>
27+
</div>
28+
<Typography variant="body/large">Made with ♡ by ACM at UC San Diego</Typography>
29+
<div className={styles.socials}>
30+
<Link href="https://www.acmurl.com/instagram/">
31+
<Instagram />
32+
</Link>
33+
<Link href="https://www.acmurl.com/discord/">
34+
<Discord />
35+
</Link>
36+
<Link href="https://www.acmurl.com/facebook/">
37+
<Facebook />
38+
</Link>
39+
</div>
40+
</div>
41+
);
42+
};
43+
44+
export default Footer;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@use '@/styles/vars' as vars;
2+
3+
.container {
4+
display: flex;
5+
flex-direction: column;
6+
gap: 2rem;
7+
justify-content: center;
8+
align-items: center;
9+
padding: 8rem 0;
10+
position: relative;
11+
12+
text-shadow:
13+
0 1px 4px rgba(0, 0, 0, 0.5),
14+
0 3px 15px rgba(0, 0, 0, 0.7);
15+
}
16+
17+
.backgroundLeft {
18+
position: absolute;
19+
left: 0;
20+
bottom: 0;
21+
z-index: -1;
22+
max-width: min(100%, 580px);
23+
height: auto;
24+
object-fit: contain;
25+
}
26+
27+
.backgroundRight {
28+
position: absolute;
29+
right: 0;
30+
bottom: 0;
31+
z-index: -1;
32+
max-width: min(100%, 850px);
33+
height: auto;
34+
object-fit: contain;
35+
}
36+
37+
.links {
38+
display: flex;
39+
gap: 6.5rem;
40+
align-items: center;
41+
margin-bottom: 2rem;
42+
43+
a {
44+
text-decoration: none;
45+
color: vars.$white;
46+
47+
img {
48+
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.7));
49+
}
50+
}
51+
52+
@media screen and (max-width: vars.$breakpoint-md) {
53+
gap: 2rem;
54+
a {
55+
img {
56+
display: none;
57+
}
58+
}
59+
}
60+
}
61+
62+
.socials {
63+
display: flex;
64+
gap: 1rem;
65+
align-items: flex-start;
66+
67+
a {
68+
svg {
69+
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.7));
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)