Repository navigation
Conversation
* added cache for professors in review cards * change variable names * Merge branch 'main' of https://github.com/icssc/peterportal-client into professor-cache * fix net ID showing up instead of prof names
* RecentOfferingsTooltip changed to MUI * Made a MUI version of PPCOverlayTrigger * clone children to inject handlers instead of wrapping in box * clean up unnecessary states * MUI for profile popover * Styling changes and renamed the overlay * fixed RecentOfferingsTooltip and styling issues * removed comments and adjusted anchor/transform origin options * changed background color of recent offerings tooltip * fixed another issue with recent offtering tooltip * Fixed hovering/mousing behavior for PPCOverlayTrigger * don't use !important * profile popover styling changes * rename ppcoverlaytrigger to overlaytrigger * remove more unnecessary app.scss styling * fix mousing behavior * use overlaytrigger for prereq tree and move popover-body styling into app.scss * use overlaytrigger for recentofferingstooltip * fix anchoring and remove unnecessary recentofferingstooltip styles * refactor prereqtree popover content * remove beta tag in header GH and feedback are in the footer now * polish up colors for profile popover * Change quarter indicator to tooltip * change prereq tree and review card to tooltip * clean up class names * don't show tooltip for dragged courses --------- Co-authored-by: Jeremiah Soe <soejeremiah@gmail.com> Co-authored-by: Jeremiah <40682211+fiveminus1@users.noreply.github.com> Co-authored-by: Awesome-E <54484616+Awesome-E@users.noreply.github.com>
💰 * Consolidate course menus (credits, catalog, search) in the left sidebar on desktop (#839) * Pull catalog browser into a separate component - eventually, major, minor, ge, etc. tabs should also be moved into `sidebar/catalog` * Tabs working, minus the style * Adjust container styles for Catalog and Credits * Consolidate roadmap search styles * formatting * recategorize folders in `src/app/roadmap` * reimplement unread transfer badge * Implement Catalog Saved Tab * refactor component names/calls * fix bug with switching w/o viewing if tab was seen * Transfers Menu Visuals - addresses PR comment & makes heading size more reasonable * `showTransfersMenu` → `showMobileCreditsMenu` * `showSearch` → `showMobileCatalog` * combine duplicate styles * re-remove next/nav compat - this is automatically removed when running `pnpm dev`, so best to not have that in code base * Fullscreen mobile search (#849) * Add search icon to navbar * Remove week number from navbar - See #461; This will likely be moved for AA Planner anyway * Add fullscreen search overlay * Only show search button on roadmap page * Search replaces planner rather than overlay * Remove unnecessary props from SearchHitContainer * Course preview and styling fixes * Search filters toggle * Only show search filter toggle if filters available * Remove non-null assertions * Remove !important * Remove completed TODO * Refactor mobile fullscreen search rendering - Replaces early return for MobileSearchMenu with conditional rendering inside the main component tree. Fixes issue with toasts not showing while fullscreen search is open. * Only render CoursePreview when a course is selected Co-authored-by: Caden Lee <149259302+CadenLee2@users.noreply.github.com> * Wrap MobileSearchMenu * Fix error toast for course data failure --------- Co-authored-by: Caden Lee <149259302+CadenLee2@users.noreply.github.com> * Remove search pages (#875) * Remove sidebar and search pages * Remove sidebar state and related styles - Eliminated sidebarOpen state and its Redux logic from uiSlice and userSlice. Removed unused sidebar width variables from globals.scss and adjusted layout calculation in ResultPageContent.scss to no longer depend on sidebar width. * Update changelog modal * Remove old changelog screenshot * Rm comment * Add back button to non-roadmap pages * Change back arrow to home button * Make home button Nextjs Link - "Home button should not be a hard page reload to navigate; use the Component prop to make sure it's a nextjs link" * Automatically detect whether searches are of courses or professors (#865) * fix GE categories filter * Automatically show course/prof (kinda) in Roadmap * fix: saved courses should never render profs * render professors * extract components for nicer type-ing * show result type switcher (mostly complete) * Create professor preview * input padding fix * feat: hide switcher when no other results * feat: compare result indices by total rank * fix pagination issues & show universal * fix placeholders/empty queries in full mobile * only show profs if not in mobile catalog * visual fixes * lint fix * don't initiate prof searches from mobile catalog * When opening/closing one preview, close the other * (see desc) Fix showing previous query on catalog - When opening mobile catalog after a prof search, it now properly shows "no results" - When the screen width changes while catalog is open, it sets mobile catalog to closed so that search result headers render properly in desktop sidebar search. Note that if the query is an instructor-first query, it will need to be re-entered, though changing screen size to close that menu and enter a new query really should not be common * reset filters based on query changes - good bot * don't change index if no results - when searching for a course and narrowing down results via a query, it should not change to professors if both courses and profs yield no results * make copy in the correct place * empty menu + in progress search improvements * fix handling undefined responses --------- Co-authored-by: Caden Lee <149259302+CadenLee2@users.noreply.github.com> * merge useProfessorData * merge desktop/mobile result previews * fix add course popup table thing * Remove unused files * Create a shared ICSSC Projects footer component (#878) * Footer component * Add week number back. #lessevilpeterportal * shorten text on mobile footer * delete old sidebar * remove beta tag in header - GH and feedback are in the footer now * fix missing transition className on screen resize * clicking course names in prof results show preview * Change mobile cutoff to avoid small desktop planner * Remove dead code * fix small cutoff differences --------- Co-authored-by: Anthony Jenanian <55033931+anthonyj33@users.noreply.github.com> Co-authored-by: Caden Lee <149259302+CadenLee2@users.noreply.github.com>
* feat: oidc auth * chore: cleanup * fix: production domain * fix: production client domain * fix: misc * fix: authentication * feat: simplify prod domain secret * feat: onConflictDoUpdate on email and googleId * fix: fix * fix: fix * docs: todo * feat: add isAdmin to session --------- Co-authored-by: Awesome-E <54484616+Awesome-E@users.noreply.github.com>
* remove bootstrap deps/leftover styles, adjust styling * bump next.js version * fix up more styles * clean up global styles * sweep sweep sweep * restore styles * remove unnecessary theme override * th text-align * re-add cursor: pointer * cursor: pointer for buttons * bump next again
* Update planner.ts * fix lint errors * Update site/src/helpers/planner.ts Co-authored-by: Awesome-E <54484616+Awesome-E@users.noreply.github.com> * Update planner.ts * fix typo --------- Co-authored-by: Awesome-E <54484616+Awesome-E@users.noreply.github.com>
* change buttons to divs * cursor pointer in app.scss * convert menusection * fix minorcourselist * remove comment
* Implement new mobile course result design * Apply spacing correctly in hit-items * Wrap tags and cut off text in mobile search * Remove extra commented code * Update styling to match figma design * Use CourseDescription component in mobile search * Replace course-synopsis with CourseDescription
* conditional rendering to recently taught courses added * conditionally rendered dots in professor synopsis * refactor no recent course data * improved type usage * style change on no courses
* fix: popover restore focus breaks selects * fix: nonexistent bootstrap hidden prop * fix: search filter interaction * refactor: hiding logic readability
* fix: hide description for course in quarter * refactor: rename course description to synopsis * style: nest course synopsis title rule
* Prevent installation of packages < 1 day old * upgrade to pnpm v10 * bump pnpm setup version * regenerate lockfile
* removed years column in planner table * removed insert years --------- Co-authored-by: Caden Lee <maltyg3332@gmail.com>
* Set default SoC to be the most recent quarter with offerings * Added history icon tooltip as indicator for past quarter * merge pnpm update changes from main * resolve requested review changes
* (mostly) replaced mobile full search's pagination w/ infinite scroll * misc comments (temporary) * removed type.d.ts change (idk) * removed searchpagination folder * removed unused SearchModule param * got inf scroll to mostly work for desktop sidebar search (not yet mobile; not 100% there) * gitignored ts config file (nextjs docs says to gitignore it) * undid proev commit * got inf scroll to mostly work for mobile sidebar * updated next-env.d.ts * undid SearchModule change * removed constants.ts * added end to inf scroll * removed console.logs * removed next-env.d.ts * fixed conditional bug * actually fixed conditional bug
* Add CHC select * Support for saving CHC status * Disable 2 year CHC for now * Drizzle migration for CHC * Rm comment
* fix: external roadmaps with new google ids * feat: expect non prefixed google id
* fixed course preview toasts * Add review and voting buttons are disabled when not logged in and display a tooltip * Fixed review form toasts * added an open prop to logged out tooltip
* Store which majors/minors have been expanded/collapsed * Also stores minor collapsed/expanded state * review comments :) * set expandedGroups for major and minor to be true on add so that undefined can default to false when determining open state --------- Co-authored-by: Cindy Liang <cindy.liang69@gmail.com> Co-authored-by: CLiang531 <73400286+CLiang531@users.noreply.github.com>
* workflows for deploying and removing staging * add unlock workflow * change formatting * change environment url
* Fix styles in Quarter.scss to target correct classes * Add navigation stack * Remove old preview hooks * Change preview dispatch and swap button order * Rename coursePreview to preview * Finish rename and review card links * Rename course-description to course-synopsis * Fix multiple prof previews * Move handleLinkClick() up to fix lint error * Implement review suggestions * Add previous preview tooltip * Featured reviews open in preview * Remove unneeded current preview check --------- Co-authored-by: Jeremiah Soe <soejeremiah@gmail.com>
* fix: remove domain on cookies * fix: remove domain on session cookies
There was a problem hiding this comment.
29 issues found across 912 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/antalmanac-planner/api/src/controllers/courseMaterials.ts">
<violation number="1" location="apps/antalmanac-planner/api/src/controllers/courseMaterials.ts:16">
P2: `number` is accepted as any string but inserted raw into the query, so reserved characters can change or truncate the upstream request. Encode it in both procedures or build the query with `URLSearchParams`.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/component/InfiniteScrollContainer/InfiniteScrollContainer.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/component/InfiniteScrollContainer/InfiniteScrollContainer.tsx:34">
P2: This compares saved-course length with the stale search-result count, so scrolling saved courses can request another page for a cleared query. Pass whether these are paginated search results and set `hasMore` false for saved courses.</violation>
</file>
<file name="apps/antalmanac-planner/api/scripts/transfersRoadmapMajorMinorData.ts">
<violation number="1" location="apps/antalmanac-planner/api/scripts/transfersRoadmapMajorMinorData.ts:66">
P2: This comment claims the inserts are commented out, but the `tx.insert(userMajor)` block below actually executes and writes to the database. Either comment out the mutation blocks or remove the misleading comment; as written, a script runner will expect no data to change.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/CatalogYears.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/CatalogYears.tsx:21">
P2: This state never follows later `catalogYear` prop changes, so saved-year hydration can leave the control showing the default and confirming can overwrite the saved year. Synchronize the draft with the prop or initialize it when editing begins.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/MajorCourseList.scss">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/MajorCourseList.scss:39">
P2: `margin-bottom: 12;` is unitless and invalid CSS, so the declaration is dropped. Add the `px` unit.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/course/CoursePage.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/course/CoursePage.tsx:38">
P2: Both the error and the loading branches here are unreachable, so a failed course lookup renders placeholder data forever instead of any error or loading feedback. `error` is initialized to `''` and only ever assigned `''` (`setError('')`), and `useCourseData` never returns a falsy value — it returns `LOADING_COURSE_PLACEHOLDER` (a full `CourseGQLData` object) while loading and keeps it on fetch failure (see `src/hooks/catalog.ts`). The `if (error)` and `else if (!courseGQLData)` guards can never fire. Either surface a real error from the hook (and check `courseGQLData.id === LOADING_COURSE_PLACEHOLDER.id` for loading, as `CoursePreview.tsx` does), or remove these dead branches so the intended states are actually reachable.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/search/ProfessorResult.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/search/ProfessorResult.tsx:26">
P2: Both click handlers prevent the browser's modified-click behavior, so Ctrl/Cmd-click opens the preview in the current tab instead of opening the detail link in a new tab. Prevent default only for an unmodified primary click in both handlers.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/admin/reports/ReportGroup.scss">
<violation number="1" location="apps/antalmanac-planner/site/src/app/admin/reports/ReportGroup.scss:69">
P2: The subreport background uses an undefined CSS variable, so this declaration is ignored. Use the defined `--mui-palette-overlay-overlay3` token.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/search/CourseHitItem.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/search/CourseHitItem.tsx:45">
P2: Keyboard activation of this bookmark also triggers the enclosing course selection because the parent handles bubbled Enter/Space keydowns. Stop keydown propagation on the bookmark button so keyboard users can save without opening the preview.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/toolbar/ImportZot4PlanPopup.scss">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/toolbar/ImportZot4PlanPopup.scss:6">
P2: This selector does not match the warning icon's `import-schedule-icon` class, so its sizing and spacing styles never apply. Rename the selector to match the JSX class.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/transfers/MenuSection.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/transfers/MenuSection.tsx:25">
P2: The expand icon is a focusable button nested inside the header’s button-like `ClickableDiv`; its Enter/Space keydown toggles the section, then its native click bubbles and toggles it back. Use one interactive control for the header and render the chevron as decorative content.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/sidebar/TabSelector.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/sidebar/TabSelector.tsx:26">
P2: These buttons expose the selected choice only visually, so screen-reader users cannot tell which tab is active. Add `aria-pressed={isSelected}` to each button.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/component/ExpandMore/ExpandMore.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/component/ExpandMore/ExpandMore.tsx:11">
P2: Most usages render this icon-only button without an accessible name. Give it a default `aria-label` based on `expanded` (while allowing callers to override it).</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/toolbar/Header.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/toolbar/Header.tsx:62">
P2: The undo and redo icon-only buttons have no accessible names, so assistive technology announces them as unnamed buttons. Add `aria-label="Undo"` and `aria-label="Redo"` to the respective `IconButton`s.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/instructor/ProfessorPage.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/instructor/ProfessorPage.tsx:39">
P2: A rejected professor query leaves this page on the spinner indefinitely because `useProfessorData` does not expose or catch the rejection, and `error` is only ever cleared. Catch or expose the request error and render the error state.</violation>
</file>
<file name="apps/antalmanac-planner/api/drizzle/0029_planner_course_custom_card.sql">
<violation number="1" location="apps/antalmanac-planner/api/drizzle/0029_planner_course_custom_card.sql:3">
P2: This migration creates two mutually contradictory constraints on `planner_course.custom_card_id`: the FK with `ON DELETE set null` and the CHECK `(custom_card_id IS NOT NULL) = (course_id = 'CUSTOM')`. Deleting a `custom_card` that is referenced by a `course_id = 'CUSTOM'` row makes Postgres set `custom_card_id` to NULL, and PostgreSQL enforces constraints on referential-action updates ("these do not excuse you from observing any constraints"), so the DELETE fails with a check-constraint violation "is violated by some row". The app's `deleteCustomCard` (customCourses.ts) works around this by deleting the `planner_course` rows first, but any other deletion path breaks — notably `custom_card.user_id` is `ON DELETE cascade` (migration 0028), so deleting a user cascades into `custom_card` deletion and aborts with an error, and updating one of the orphaned rows later also re-evaluates and fails the CHECK. Use `ON DELETE cascade` on the FK (delete the placement with the card) or drop the CHECK, so the delete action cannot leave a row that violates the constraint.</violation>
</file>
<file name="apps/antalmanac-planner/api/drizzle/0004_sad_zzzax.sql">
<violation number="1" location="apps/antalmanac-planner/api/drizzle/0004_sad_zzzax.sql:3">
P2: This makes the default `now()` timestamp the only discriminator for imports of one schedule. Concurrent requests can share a microsecond timestamp, causing the second insert to violate this PK and fail `getScheduleFormatted`; existing duplicate pairs would also make this migration fail. Use a surrogate key and resolve any existing duplicates before adding the constraint.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/component/GradeDist/Chart.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/component/GradeDist/Chart.tsx:34">
P2: This component only renders a bar chart, so selecting the exposed `pie` option hides the chart entirely in minified grade distributions. Implement the pie variant or remove that option.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/CustomCourseCard.scss">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/CustomCourseCard.scss:14">
P2: The truncation rules target `.title`, but the description is rendered as `.description-body`, so long descriptions wrap and can spill beyond the fixed-height card. Apply these rules to `.description-body` instead.</violation>
</file>
<file name="apps/antalmanac-planner/infra/redirect-handler.mjs">
<violation number="1" location="apps/antalmanac-planner/infra/redirect-handler.mjs:7">
P2: This redirect also handles non-GET requests, but a 301 can turn POSTs into GETs and discard their bodies, breaking clients posting to legacy Planner APIs. Use 308 to preserve the method and body.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/search/ProfessorHitItem.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/search/ProfessorHitItem.tsx:24">
P2: Keyboard activation of a nested course link bubbles to `ClickableDiv`'s Enter/Space handler, which pushes the professor query instead. Stop the link's keydown from bubbling so it activates only the course preview.</violation>
</file>
<file name="apps/antalmanac-planner/api/src/helpers/platform.ts">
<violation number="1" location="apps/antalmanac-planner/api/src/helpers/platform.ts:19">
P2: Match the complete cookie pair instead of a substring; otherwise an unrelated cookie containing this text can send a web login through the native callback. Split the header on `;` and compare each trimmed pair exactly.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/SavedCourses.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/SavedCourses.tsx:42">
P2: This effect re-expands every department group whenever `savedCourses` changes, undoing a user's collapse after adding or removing a course. Expand only newly appearing groups instead of resetting all `saved-*` keys.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/GERequiredCourseList.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/GERequiredCourseList.tsx:41">
P2: If either query rejects, its success callback never resets the loading flag, leaving the CHC or GE pane on a spinner indefinitely. Handle failures and reset loading in a `finally` block.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/component/GradeDist/GradeDist.scss">
<violation number="1" location="apps/antalmanac-planner/site/src/component/GradeDist/GradeDist.scss:1">
P2: This unscoped rule also recolors Scheduler’s MUI card contents wherever GradeDist’s stylesheet is loaded. Scope it to `.gradedist-module-container` so the overlay applies only to GradeDist cards.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/Library.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/Library.tsx:73">
P2: `onStart` sets global drag state, but this source never clears it; add `onEnd` to reset it so quarter drop zones don't stay highlighted after release.</violation>
</file>
<file name="apps/antalmanac-planner/site/src/app/roadmap/catalog/MinorCourseList.tsx">
<violation number="1" location="apps/antalmanac-planner/site/src/app/roadmap/catalog/MinorCourseList.tsx:66">
P2: A successful empty result is treated as not-yet-loaded, so every response writes a new empty array and immediately triggers another request. Track fetch completion separately from the requirements length so an empty result does not create an endless API loop.</violation>
</file>
<file name="apps/antalmanac-planner/api/scripts/splitPlannerTables.ts">
<violation number="1" location="apps/antalmanac-planner/api/scripts/splitPlannerTables.ts:60">
P2: This stores legacy `CUSTOM#<id>` identifiers verbatim and leaves `custom_card_id` null. The current save path normalizes them to `course_id='CUSTOM'` plus the card ID; mirror that conversion so card lookup and deletion keep working.</violation>
</file>
<file name="apps/antalmanac-planner/api/src/next/session.ts">
<violation number="1" location="apps/antalmanac-planner/api/src/next/session.ts:33">
P2: A copied `planner_session` remains accepted indefinitely: cookie `Max-Age` only limits browser storage, while `deserializeSession` never checks an expiry. Put an expiry in the signed payload and reject it during deserialization.</violation>
</file>
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Re-trigger cubic
Choollol
left a comment
There was a problem hiding this comment.
Findings from a first pass:
App behavior
- Auth seems to work, besides a planner hiccup described in a comment
- Posthog network requests are sent on both sides
- Navigating between apps work. There are some inconsistencies, but I think we can fix them after the merge
- Features seem to work on both sides
- Search with planner works
Not sure how to test aants or pwa
Also left some comments about setting up dev environment
I haven't looked at any code yet, will review again after I do
| 3. Start the local PostgreSQL database using Docker Compose. | ||
|
|
||
| ```bash | ||
| docker compose up -d --build |
There was a problem hiding this comment.
Should we add a note about needing to have docker desktop/the engine background process open? Ran into this problem myself
There was a problem hiding this comment.
good idea will do
- Add note about docker desktop
There was a problem hiding this comment.
Should we add the BEGIN; ... COMMIT; fix mentioned by anthony? Rn the migrations fail
There was a problem hiding this comment.
yeah i will do
- Fix the migration issue
There was a problem hiding this comment.
We made a recent change that means anyone who has logged into a staging recently will need to clear cookies
Won't affect users who have only been to prod and it will be fixed if you clear cookies
There was a problem hiding this comment.
On localhost, signing in on scheduler side then navigating to planner causes the app to crash if the planner-auth env variables, which are gotten from the planner team, aren't set. Don't know if we want to fix this before the merge, but definitely should be top priority after the merge
There was a problem hiding this comment.
PLANNER_SESSION_SECRET just needs to be set to a random string. Maybe we can add a note to the .env.example to indicate that
We could put a dummy string like "randomstringgoeshere" in .env.example because it doesn't really matter if it's secure for local dev. That way even if someone doesn't change it that can just act as the secret
|
Notes for after the merge:
Will edit this comment if I add more |
There was a problem hiding this comment.
(not related to the file, just commenting here so it's replyable)
Was there a particular reason the sub-folders have the "antalmanac-" prefix? Could we rename them to just "scheduler" and "planner"? Not a huge deal, but it would make things like project-specific searching in VSCode easier.
This is because some pages on Planner use the Planner button as the only way to navigate "back" to the roadmap page (e.g. https://antalmanac.com/planner/instructor/thornton) The reasoning for this, in short, is that if someone finds this page from a search engine, having a back arrow to go to the roadmap wouldn't actually be going back to where they came from. For the most part, these pages are typically used by people who a) used a search engine or b) had a link shared to them |

Summary
Introduces AntAlmanac Planner as part of the AntAlmanac repository. The entirety of Scheduler and Planner are now run and deployed as a singular Next.js app. Aside from very few exceptions (see below), the site's behavior should be unchanged.
Structure
The project is now reorganized into:
Planner has already migrated to Next.js routing so minimal changes were needed on the Planner side aside from formatting.
Major code changes:
antalmanac(auth is still separate)PLANNER_DB_URL)staging-shared)Known changes in behavior
Aside from these specific changes, behavior should be identical:
planner/*files are now accessed byplanner-public/(avoids OpenNext public folder name collision from overridingplanner)planner/robots.txtno longer existsContributor experience
.envis now inapps/antalmanacand requires variables for both appsplan:db:generatefor the planner DB)staging-rather thanscheduler-Test Plan
Future followup
Non-exhaustive list of tasks:
PLANNER_CLIENT_API_KEY