Skip to content

Commit afdcbb1

Browse files
committed
Add statuses to portal page
1 parent bf7712b commit afdcbb1

16 files changed

Lines changed: 327 additions & 5 deletions
File renamed without changes.
File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import ConfirmationPage from "./ConfirmationPage";
2+
3+
export default function Confirmation() {
4+
return <ConfirmationPage />;
5+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@use "zothacks-theme" as theme;
2+
3+
.container {
4+
min-height: 100vh;
5+
display: flex;
6+
flex-direction: column;
7+
align-items: center;
8+
justify-content: center;
9+
gap: 2rem;
10+
background: url("~@/assets/background/mountains-background.png");
11+
font-family: var(--next-font-reddit-mono), monospace;
12+
13+
* {
14+
font-weight: 600;
15+
}
16+
17+
h1 {
18+
color: theme.$white;
19+
font-size: 4rem;
20+
}
21+
22+
p {
23+
font-weight: 400;
24+
letter-spacing: 1px;
25+
}
26+
27+
div.wrapper {
28+
max-width: 600px;
29+
margin: 0 40px;
30+
display: flex;
31+
flex-direction: column;
32+
gap: 16px;
33+
}
34+
35+
36+
37+
}

apps/site/src/app/portal/ApplicantPortal.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { redirect } from "next/navigation";
44

55
import useUserIdentity from "@/lib/utils/useUserIdentity";
66
import { Status } from "@/lib/userRecord";
7+
import Message from "./components/Message";
8+
import ActionButton from "./components/ActionButton";
9+
import Timeline from "./components/Timeline";
710

8-
import ConfirmationPage from "./ConfirmationPage";
9-
10-
const rolesArray = ["Mentor", "Hacker", "Volunteer"];
11+
import styles from "./ApplicantPortal.module.scss";
1112

1213
function Portal() {
1314
const identity = useUserIdentity();
@@ -16,12 +17,23 @@ function Portal() {
1617
return <div>Loading...</div>;
1718
}
1819

19-
const status = identity.status;
20+
const status = identity.status as Status;
2021

2122
if (status === null) {
2223
redirect("/apply");
2324
} else {
24-
return <ConfirmationPage />;
25+
return <div className={styles.container}>
26+
<h1>Portal</h1>
27+
28+
<div className={styles.wrapper}>
29+
<Timeline status={status} />
30+
31+
<Message status={status} />
32+
33+
<ActionButton status={status} />
34+
35+
</div>
36+
</div>;
2537
}
2638
}
2739

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@use "zothacks-theme" as theme;
2+
3+
.actionButton {
4+
border: 5px solid theme.$dark-green;
5+
background-color: rgba(theme.$dark-green, 0.69);
6+
border-radius: 30px;
7+
padding: 30px 40px;
8+
width: 100%;
9+
box-sizing: border-box;
10+
display: flex;
11+
align-items: center;
12+
justify-content: space-between;
13+
font-size: 1.5rem;
14+
color: theme.$off-white;
15+
font-size: 1.2rem;
16+
justify-content: center;
17+
letter-spacing: 1px;
18+
text-decoration: none;
19+
20+
&:hover {
21+
background-color: rgba(theme.$light-green, 0.69);
22+
}
23+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Status } from "@/lib/userRecord";
2+
import styles from "./ActionButton.module.scss";
3+
import Link from "next/link";
4+
5+
interface ActionButtonProps {
6+
status: Status;
7+
}
8+
9+
export default function ActionButton({ status }: ActionButtonProps) {
10+
let buttonJSX: JSX.Element;
11+
12+
switch (status) {
13+
case Status.Rejected:
14+
case Status.Void: {
15+
buttonJSX = (
16+
<Link href="/" className={styles.actionButton}>Return to Homepage</Link>
17+
);
18+
break;
19+
}
20+
21+
case Status.Signed:
22+
case Status.Confirmed:
23+
case Status.Attending:
24+
case Status.Accepted:
25+
case Status.Waitlisted:
26+
27+
// TODO: Add a button to withdraw from the event
28+
29+
// case Status.Waitlisted: {
30+
// buttonJSX = <button className={styles.actionButton}>I am no longer able to attend ZotHacks 2025</button>;
31+
// break;
32+
// }
33+
34+
case Status.Pending:
35+
case Status.Reviewed: {
36+
buttonJSX = <></>;
37+
break;
38+
}
39+
40+
default: {
41+
const exhaustiveCheck: never = status;
42+
throw new Error(`Unhandled status: ${exhaustiveCheck}`);
43+
}
44+
}
45+
46+
return buttonJSX;
47+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@use "zothacks-theme" as theme;
2+
3+
div.messageWrapper {
4+
display: flex;
5+
flex-direction: column;
6+
gap: 8px;
7+
color: theme.$white;
8+
9+
p {
10+
font-size: 1.1rem;
11+
}
12+
13+
h4 {
14+
font-size: 1.5rem;
15+
margin-bottom: 0;
16+
}
17+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Status } from "@/lib/userRecord";
2+
import styles from "./Message.module.scss";
3+
4+
interface MessageProps {
5+
status: Status;
6+
}
7+
8+
export default function Message({ status }: MessageProps) {
9+
let message: string;
10+
let header: string;
11+
12+
switch (status) {
13+
case Status.Pending:
14+
case Status.Reviewed: {
15+
header = "";
16+
message = `Thank you for submitting your application! We are currently reviewing
17+
applications on a rolling basis, and you will hear back from us soon!`
18+
break;
19+
}
20+
21+
case Status.Accepted: {
22+
header = "Congratulations!";
23+
message = `Congratulations! You have been admitted to ZotHacks 2025! Please check
24+
your email to sign your waiver and confirm your attendance!`;
25+
break;
26+
}
27+
case Status.Waitlisted: {
28+
header = "RSVP";
29+
message = `Thank you for applying to ZotHacks this year. We have read through
30+
many applications so far, and are able to offer you a spot on the
31+
event waitlist. Please check your email for more info about the
32+
waitlist and waitlist walk-ins!`;
33+
break;
34+
}
35+
case Status.Rejected: {
36+
header = "Sorry...";
37+
message = `Thank you for applying to ZotHacks this year. We have read through
38+
many applications so far, and unfortunately are unable to offer you a
39+
spot at our event. We highly encourage you to continue developing your
40+
skills and passion for technology. We would love to see you apply
41+
again next year!`;
42+
break;
43+
}
44+
45+
case Status.Signed:
46+
case Status.Confirmed:
47+
case Status.Attending: {
48+
header = "";
49+
message = ``;
50+
break;
51+
}
52+
53+
case Status.Void: {
54+
header = "";
55+
message = `Unfortunately, you are not able to RSVP for IrvineHacks at this time
56+
and will not be able to come to the event. However, we would love to
57+
see you apply again next year!`;
58+
break;
59+
}
60+
61+
default: {
62+
const exhaustiveCheck: never = status;
63+
throw new Error(`Unhandled status: ${exhaustiveCheck}`);
64+
}
65+
}
66+
67+
return (
68+
<div className={styles.messageWrapper}>
69+
<h4>{header}</h4>
70+
<p>{message}</p>
71+
</div>
72+
);
73+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@use "zothacks-theme" as theme;
2+
3+
.dark {
4+
background-color: rgba(theme.$dark-green, 0.69);
5+
6+
&:hover {
7+
background-color: rgba(theme.$light-green, 0.69);
8+
}
9+
}
10+
11+
.light {
12+
background-color: rgba(theme.$light-green, 0.69);
13+
}
14+
15+
.indicator {
16+
border: 5px solid theme.$dark-green;
17+
border-radius: 30px;
18+
padding: 30px 40px;
19+
width: 100%;
20+
box-sizing: border-box;
21+
display: flex;
22+
align-items: center;
23+
justify-content: space-between;
24+
font-size: 1.3rem;
25+
color: theme.$off-white;
26+
27+
p {
28+
margin: 0;
29+
}
30+
}

0 commit comments

Comments
 (0)