Skip to content
Open
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
9 changes: 9 additions & 0 deletions apps/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const Landing = lazy(() => import("@/app/Landing"));
const Profile = {
Root: lazy(() => import("@/app/Profile")),
Account: lazy(() => import("@/app/Profile/Account")),
Notifications: lazy(() => import("@/app/Profile/Notifications")),
Support: lazy(() => import("@/app/Profile/Support")),
Ratings: lazy(() => import("@/app/Profile/Ratings")),
Settings: lazy(() => import("@/app/Profile/Settings")),
Expand Down Expand Up @@ -183,6 +184,14 @@ const router = createBrowserRouter([
),
index: true,
},
{
element: (
<SuspenseBoundary key="notifications">
<Profile.Notifications />
</SuspenseBoundary>
),
path: "notifications",
},
{
element: (
<SuspenseBoundary key="support">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.body {
align-items: center;
color: var(--heading-color);
}
.icon {
margin-top: 40px;
width: 70px;
height: 70px;
color: var(--blue-500);
}
.red {
color: var(--red-500);
}

.title {
margin-top: 28px;
margin-bottom: 14px;
font-size: 28px;
font-weight: 600;
}

.subtitle {
margin: 0px 20px;
color: var(--paragraph-color);
text-align: center;
font-size: 15px;
line-height: 1.5;
margin-bottom: 28px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useState } from "react";

import classNames from "classnames";
import {
ArrowRight,
CheckCircleSolid,
WarningTriangleSolid,
} from "iconoir-react";
Comment on lines +4 to +8

import { Button, Dialog } from "@repo/theme";

import styles from "./ConfirmationPopups.module.scss";

interface RemoveClassPopupProps {
isOpen: boolean;
onClose: () => void;
onConfirmRemove: () => Promise<void>;
}

export function RemoveClassPopup({
isOpen,
onClose,
onConfirmRemove,
}: RemoveClassPopupProps) {
const [isRemoving, setIsRemoving] = useState(false);

const handleRemove = async () => {
setIsRemoving(true);
try {
await onConfirmRemove();
onClose();
} finally {
setIsRemoving(false);
}
};

return (
<Dialog.Root open={isOpen} onOpenChange={onClose}>
<Dialog.Portal>
<Dialog.Overlay />
<Dialog.Card>
<Dialog.Body className={styles.body}>
<WarningTriangleSolid
className={classNames(styles.icon, styles.red)}
/>
<div className={styles.title}>Stop Tracking Class</div>
<div className={styles.subtitle}>
You will no longer receive notifications about <br />
enrollment changes for this class.
</div>
</Dialog.Body>
<Dialog.Footer>
{!isRemoving && (
<Button onClick={onClose} variant="tertiary" isDelete>
Cancel
</Button>
)}
<Button onClick={handleRemove} disabled={isRemoving} isDelete>
{isRemoving ? "Removing..." : "Yes, stop tracking"}
</Button>
</Dialog.Footer>
</Dialog.Card>
</Dialog.Portal>
</Dialog.Root>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
.cardWrapper {
position: relative;
overflow: visible;
height: auto;

&.popupOpen {
z-index: 100;
}

> * {
height: 100% !important;
overflow: visible !important;
}
}

.cardColumnHeader {
height: 100%;
}

.cardBodyWrapper {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.cardHeading {
font-size: 16px !important;
font-weight: 600 !important;
margin-bottom: 8px !important;
color: var(--heading-color);
}

.sectionNumber {
color: var(--paragraph-color) !important;
font-weight: 600 !important;
}

.description {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
color: var(--paragraph-color);
}

.enrollmentText {
font-size: 14px;
font-weight: 400;
line-height: 1;
}

.gradeWrapper {
padding-right: 4px;
}

.bellWrapper {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
gap: 2px;
min-width: 28px;
height: 28px;
z-index: 100;
padding: 0 6px;
margin-top: -3.5px;
border: 1px solid var(--border-color);
border-radius: 4px;
transition: background-color 150ms ease-in-out;
cursor: pointer;

&:hover {
background-color: var(--background-color);
}

&.active {
color: var(--blue-500);
}
}

.popup {
background-color: var(--foreground-color);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
z-index: 10000;
width: 280px;
display: flex;
flex-direction: column;
position: absolute;
top: 45px;
right: 15px;

.checkboxOption {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 8px;
border-radius: 6px;
cursor: pointer;

&:hover {
label {
color: var(--heading-color);
}
}

label {
font-size: 14px;
color: var(--paragraph-color);
white-space: nowrap;
cursor: pointer;
transition: color 100ms ease-in-out;
}

.checkbox {
width: 16px;
height: 16px;
display: grid;
place-items: center;
border-radius: 4px;
flex-shrink: 0;

&[data-state="checked"] {
background-color: var(--blue-500);
color: white;
}

&[data-state="unchecked"] {
border: 2px solid var(--paragraph-color);
}
}
}
}

.arrowRotated {
transform: rotate(180deg);
}
Loading
Loading