diff --git a/apps/frontend/src/components/Header.tsx b/apps/frontend/src/components/Header.tsx index 16cb3e1..ddbf95f 100644 --- a/apps/frontend/src/components/Header.tsx +++ b/apps/frontend/src/components/Header.tsx @@ -7,6 +7,7 @@ import { ArrowRightOnRectangleIcon, } from "@heroicons/react/24/solid"; import DarkModeButton from "./DarkModeButton"; +import MechanizeBanner from "./MechanizeBanner"; import nightwind from "nightwind/helper"; import { SignedIn, @@ -40,9 +41,12 @@ export default function Header(): ReactElement { return (
-
- Spring/Summer 2026 instructors and room information temporarily unavailable due to changes in the Schedule of Classes. -
+ + + {/*
*/} + {/* Spring/Summer 2026 instructors and room information temporarily */} + {/* unavailable due to changes in the Schedule of Classes. */} + {/*
*/}
diff --git a/apps/frontend/src/components/MechanizeBanner.tsx b/apps/frontend/src/components/MechanizeBanner.tsx new file mode 100644 index 0000000..bb2452c --- /dev/null +++ b/apps/frontend/src/components/MechanizeBanner.tsx @@ -0,0 +1,71 @@ +"use client"; + +import { useEffect, useState, type ReactElement } from "react"; +import { ArrowUpRightIcon, XMarkIcon } from "@heroicons/react/24/solid"; +import Link from "./Link"; + +const DISMISS_KEY = "cmucourses-mechanize-banner-dismissed"; + +const PROMPTS = [ + "Mechanize is hiring junior SWEs. $300K base + equity.", + "Better at coding than AI? Prove it.", + "We hire engineers to outsmart AI. It’s harder than you think. 300k + equity.", + "Most engineers can’t beat Claude on our take-home. Think you can? 300k + equity for Jr SWEs at Mechanize.", +]; +const MECHANIZE_APPLY_URL = "https://jobs.ashbyhq.com/mechanize?utm_source=CMU"; + +function pickPrompt(): string { + return PROMPTS[Math.floor(Math.random() * PROMPTS.length)]!; +} + +export default function MechanizeBanner(): ReactElement | null { + const [prompt, setPrompt] = useState(null); + + useEffect(() => { + try { + if (sessionStorage.getItem(DISMISS_KEY) === "1") { + return; + } + } catch { + /* sessionStorage unavailable (e.g. private mode restrictions) */ + } + setPrompt(pickPrompt()); + }, []); + + const handleDismiss = () => { + try { + sessionStorage.setItem(DISMISS_KEY, "1"); + } catch { + /* ignore */ + } + setPrompt(null); + }; + + if (prompt == null) { + return null; + } + + return ( +
+ +
+ {prompt} + + Apply now + + +
+
+ ); +}