Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSVP Modals #282

Merged
merged 2 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
import React from "react";
import styles from "./page.module.scss";
// import Olympian from "@/components/Home/Olympian/Olympian";
// import Footer from "@/components/Home/Footer/Footer";
// import FAQJoinUs from "@/components/Home/FAQJoinUs/FAQJoinUs";
// import Sponsors from "@/components/Home/Sponsors/Sponsors";
// import FAQSection from "@/components/Home/FAQ/FAQ";
import Accepted from "@/components/Profile/RSVP/ModalViews/Accepted";
import Rejected from "@/components/Profile/RSVP/ModalViews/Rejected";
import ConfirmReject from "@/components/Profile/RSVP/ModalViews/ConfirmReject";
import Olympian from "@/components/Home/Olympian/Olympian";
import Footer from "@/components/Home/Footer/Footer";
import FAQJoinUs from "@/components/Home/FAQJoinUs/FAQJoinUs";
import Sponsors from "@/components/Home/Sponsors/Sponsors";
import FAQSection from "@/components/Home/FAQ/FAQ";

const Home: React.FC = () => {
return (
<main className={styles.main}>
<ConfirmReject
handleAPIDecline={() => {}}
handleGoBack={() => {}}
/>
<Accepted
reimburse={120.23}
handleConfirm={() => {}}
handleDecline={() => {}}
>
<b>Congrats, stuff is happening</b>
</Accepted>
<Rejected handleCancel={() => {}} />
{/* <Olympian />
<Olympian />
<FAQJoinUs />
<FAQSection />
<Sponsors />
<Footer /> */}
<Footer />
</main>
);
};
Expand Down
247 changes: 120 additions & 127 deletions app/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import { QRCodeSVG } from "qrcode.react";
import Modal from "react-modal";
import OlympianButton from "@/components/OlympianButton/OlympianButton";
import useWindowSize from "@/hooks/use-window-size";
import UserRejected from "@/components/RSVPContent/UserRejected";
import UserGeneralAcceptedToGeneral from "@/components/RSVPContent/UserGeneralAcceptedToGeneral";
import UserProAcceptedToGeneral from "@/components/RSVPContent/UserProAcceptedToGeneral";
import UserProAcceptedToPro from "@/components/RSVPContent/UserProAcceptedToPro";
import {
Rejected,
Waitlisted
} from "@/components/Profile/RSVP/ModalViews/Rejected";
import Accepted from "@/components/Profile/RSVP/ModalViews/Accepted";

type ValueItemProps = {
label: string;
Expand All @@ -47,6 +48,7 @@ const ValueItem: React.FC<ValueItemProps> = ({ label, isHighlighted }) => {
const Profile: React.FC = () => {
const pathname = usePathname();
const router = useRouter();
const windowSizeHook = useWindowSize();

const [registration, setRegistration] = useState<RegistrationData | null>(
null
Expand All @@ -56,24 +58,31 @@ const Profile: React.FC = () => {
const [isLoading, setIsLoading] = useState(true);

const [qrCodeURL, setQRCodeURL] = useState<string | null>(null);
const [qrCodeOpen, setQRCodeOpen] = useState(false);
const [detailsOpen, setDetailsOpen] = useState(false);

const handleOpenQRCode = async () => {
const qrCode = await getQRCode();
setQRCodeURL(qrCode);
setQRCodeOpen(true);
};
const [modalOpen, setModalOpen] = useState(false);

const handleSetDetailsOpen = () => {
setDetailsOpen(true);
};
const getButtonText = () => {
if (RSVP?.status === "REJECTED" || RSVP?.status === "WAITLISTED") {
return "Details";
}

const handleCloseQRCode = () => {
setQRCodeOpen(false);
if (RSVP?.response === "ACCEPTED") {
return "View QR Code";
}

return "Congrats! Click here to RSVP";
};

useEffect(() => {
// setRSVP({
// admittedPro: false,
// reimbursementValue: 0.01,
// response: "PENDING",
// status: "ACCEPTED",
// userId: "0"
// });
// setIsLoading(false);

if (!isAuthenticated()) {
authenticate(pathname);
return;
Expand All @@ -86,35 +95,60 @@ const Profile: React.FC = () => {

setRegistration(registrationFromAPI(registration));
Promise.all([getChallenge(), getRSVP()]).then(
([challenge, RSVP]) => {
async ([challenge, RSVP]) => {
setIsProApplicant(challenge.complete);
setRSVP(RSVP);
if (
RSVP.status === "ACCEPTED" &&
RSVP.response === "ACCEPTED"
) {
const qrCodeUrl = await getQRCode();
setQRCodeURL(qrCodeUrl);
}
setIsLoading(false);
}
);
});
}, []);
}, [pathname, router]);

return (
<>
{isLoading && <Loading />}
<Head>
<title>HackIllinois | Profile</title>
</Head>
<QRModal
qrCodeOpen={qrCodeOpen}
qrCodeURL={qrCodeURL}
handleCloseQRCode={handleCloseQRCode}
/>
{RSVP && (
<DetailsModal
isProApplicant={isProApplicant}
rsvp={RSVP}
detailsOpen={detailsOpen}
handleCloseDetails={() => setDetailsOpen(false)}
/>
{RSVP && RSVP.status !== "TBD" && RSVP.response !== "DECLINED" && (
<Modal
className={styles.modal}
style={{
overlay: { zIndex: 1000 },
content: {
inset:
windowSizeHook?.width &&
windowSizeHook?.width < 768
? "10px"
: "40px"
}
}}
isOpen={modalOpen}
onRequestClose={() => {
setModalOpen(false);
}}
ariaHideApp={false}
>
<div className={styles.modalContent}>
{/* TODO: close button */}
<ModalContent
status={RSVP.status}
response={RSVP.response}
isPro={RSVP.admittedPro}
isProApplicant={isProApplicant}
qrUrl={qrCodeURL}
reimburse={RSVP.reimbursementValue}
/>
</div>
</Modal>
)}

{isLoading && <Loading />}
<div
style={{
backgroundImage: `url(${APPLICATION_STATUS_BACKGROUND?.src})`
Expand All @@ -128,10 +162,14 @@ const Profile: React.FC = () => {
className={styles.container}
>
<h2>
{registration?.preferredName
? `${registration?.preferredName.trim()}'s `
: " "}
Application Status
{registration
? `${
registration?.preferredName
? `${registration?.preferredName.trim()}'s `
: " "
}
Application Status`
: "Loading..."}
</h2>
<div className={styles.content}>
<div className={styles.info}>
Expand Down Expand Up @@ -196,24 +234,14 @@ const Profile: React.FC = () => {
</div>
<div className={clsx(styles.col, styles.qrCodeCol)}>
{RSVP &&
(RSVP.status === "ACCEPTED" &&
RSVP.response === "ACCEPTED" ? (
RSVP.status !== "TBD" &&
RSVP.response !== "DECLINED" && (
<OlympianButton
text="View QR Code"
onClick={handleOpenQRCode}
text={getButtonText()}
onClick={() => setModalOpen(true)}
medium
/>
) : ["ACCEPTED", "REJECTED"].includes(
RSVP.status
) ? (
<OlympianButton
text="Details"
onClick={handleSetDetailsOpen}
medium
/>
) : (
<></>
))}
)}
</div>
</div>
</div>
Expand All @@ -222,92 +250,57 @@ const Profile: React.FC = () => {
);
};

const QRModal: React.FC<{
qrCodeOpen: boolean;
handleCloseQRCode: () => void;
qrCodeURL: string | null;
}> = ({ qrCodeOpen, handleCloseQRCode, qrCodeURL }) => {
const windowSizeHook = useWindowSize();

const QR: React.FC<{ qrUrl: string | null }> = ({ qrUrl }) => {
return (
<Modal
className={styles.modal}
style={{
overlay: { zIndex: 1000 },
content: {
inset:
windowSizeHook?.width && windowSizeHook?.width < 768
? "10px"
: "40px"
}
}}
isOpen={qrCodeOpen}
onRequestClose={handleCloseQRCode}
ariaHideApp={false}
>
<div className={styles.modalContent}>
<h2>Your QR Code</h2>
{qrCodeURL && <QRCodeSVG value={qrCodeURL} />}
<button className={styles.link} onClick={handleCloseQRCode}>
Close
</button>
</div>
</Modal>
<>
<h2>Your QR Code</h2>
{qrUrl && <QRCodeSVG value={qrUrl} />}
</>
);
};

const DetailsModal: React.FC<{
type ModalContentProps = {
status: "ACCEPTED" | "REJECTED" | "WAITLISTED";
response: "ACCEPTED" | "PENDING";
isPro: boolean;
isProApplicant: boolean;
rsvp: RSVPType;
detailsOpen: boolean;
handleCloseDetails: () => void;
}> = ({ isProApplicant, rsvp, detailsOpen, handleCloseDetails }) => {
const pages = {
user_rejected: UserRejected,
user_pro_accepted_to_pro: UserProAcceptedToPro,
user_pro_accepted_to_general: UserProAcceptedToGeneral,
user_general_accepted_to_general: UserGeneralAcceptedToGeneral
};
qrUrl: string | null;
reimburse: number;
};

const [displayedPage, setDisplayedPage] = useState<
keyof typeof pages | undefined
>(undefined);
const ModalContent: React.FC<ModalContentProps> = ({
status,
response,
isPro,
isProApplicant,
qrUrl,
reimburse
}) => {
switch (status) {
case "ACCEPTED":
if (response === "ACCEPTED") {
return <QR qrUrl={qrUrl} />;
}

const handleLoadDisplayedPage = () => {
if (rsvp.response === "DECLINED") {
setDisplayedPage("user_rejected");
return;
}
if (isProApplicant) {
if (rsvp.admittedPro) {
setDisplayedPage("user_pro_accepted_to_pro");
} else {
setDisplayedPage("user_pro_accepted_to_general");
if (isPro) {
return <Accepted acceptedType={"PRO"} reimburse={reimburse} />;
}
} else {
setDisplayedPage("user_general_accepted_to_general");
}
};

useEffect(() => {
handleLoadDisplayedPage();
}, [rsvp?.response, rsvp?.status, rsvp?.admittedPro]);
if (isProApplicant) {
return (
<Accepted
acceptedType={"PRO_TO_GENERAL"}
reimburse={reimburse}
/>
);
}

return (
<Modal
className={styles.modal}
style={{
overlay: { zIndex: 1000 }
}}
isOpen={detailsOpen}
onRequestClose={handleCloseDetails}
ariaHideApp={false}
>
<div className={styles.modalContent}>
{displayedPage && React.createElement(pages[displayedPage])}
</div>
</Modal>
);
return <Accepted acceptedType={"GENERAL"} reimburse={reimburse} />;
case "REJECTED":
return <Rejected />;
case "WAITLISTED":
return <Waitlisted />;
}
};

export default Profile;
Loading