diff --git a/sites/mainweb/app/(portal)/club/bootcamp/page.tsx b/sites/mainweb/app/(portal)/club/bootcamp/page.tsx index b913b7ea..ecafa8a2 100644 --- a/sites/mainweb/app/(portal)/club/bootcamp/page.tsx +++ b/sites/mainweb/app/(portal)/club/bootcamp/page.tsx @@ -8,14 +8,12 @@ import { Clock, ExternalLink, CalendarDays, - Check, } from "lucide-react"; import { LoadingScreen } from "@/components/portal/LoadingScreen"; import { BootcampAddOn } from "@/components/portal/BootcampAddOn"; import { BootcampMaterialsTable } from "@/components/portal/BootcampMaterialsTable"; import { trpc } from "@/lib/trpc"; import { - BOOTCAMP_CURRICULUM, BOOTCAMP_MEETING_TIME, BOOTCAMP_ROOM, BOOTCAMP_START_DATE, @@ -35,15 +33,6 @@ function termLabel(term: string) { return `${season.charAt(0).toUpperCase()}${season.slice(1)} ${year}`; } -const dateLabel = (date: Date) => - new Date(date).toLocaleString(undefined, { - weekday: "short", - month: "short", - day: "numeric", - hour: "numeric", - minute: "2-digit", - }); - /** Where and when it meets — the thing somebody checks walking to class. */ function MeetingCard() { return ( @@ -85,54 +74,6 @@ function WorkspaceLink() { ); } -/** For an enrolled member when there is genuinely nothing to show yet. */ -function NothingScheduledYet({ term }: { term: string }) { - return ( -
- Your spot is confirmed — nothing else to do. We are still putting the - weeks together; sessions, slides and notebooks all appear here as they - are set, and you will hear from us before the first meeting. -
-- Twelve weeks of Python and data science, taught in person, with the + Nine weeks of Python and data science, taught in person, with the notebooks to keep. It runs for one semester, so joining covers this term {isMember ? "" @@ -166,20 +107,6 @@ function NotEnrolled({ term }: { term: string }) { ); } -type Week = { - week: number; - title: string; - desc: string; - deepnoteUrl?: string; - session?: { - id: string; - eventDate: Date; - location: string | null; - attended: boolean; - past: boolean; - }; -}; - export default function BootcampPortalPage() { const { data: session, status } = useSession(); const progress = trpc.bootcamp.myProgress.useQuery(undefined, { @@ -195,29 +122,6 @@ export default function BootcampPortalPage() { const data = progress.data; const enrolled = !!data?.enrolled; - const sessions = data?.sessions ?? []; - const byWeek = new Map(sessions.map((row) => [row.week, row])); - - // Curriculum is the spine, so an unscheduled week still shows. - const extras = sessions.filter( - (row) => !BOOTCAMP_CURRICULUM.some((entry) => entry.week === row.week), - ); - const weeks: Week[] = [ - ...BOOTCAMP_CURRICULUM.map((entry) => ({ - week: entry.week, - title: entry.title, - desc: entry.desc, - deepnoteUrl: entry.deepnoteUrl, - session: byWeek.get(entry.week), - })), - ...extras.map((row) => ({ - week: row.week ?? 0, - title: row.title, - desc: row.description ?? "", - deepnoteUrl: undefined, - session: row, - })), - ]; return (
- Updating soon — the week-by-week syllabus is being written and - will appear here before the first session. -
- )} - -- Week {String(entry.week).padStart(2, "0")} -
-- {entry.desc} -
- )} - - {entry.session && ( -
-
-
- Master Python for data science in 12 weeks. From the fundamentals to + Master Python for data science in 9 weeks. From the fundamentals to machine learning, build the skills you need to succeed.
{BOOTCAMP_START_DATE && ( @@ -80,9 +78,11 @@ export default function BootcampPage() {- {item.desc} -
+ {item.desc && ( ++ {item.desc} +
+ )} diff --git a/sites/mainweb/lib/bootcamp-schedule.test.ts b/sites/mainweb/lib/bootcamp-schedule.test.ts index c51dae8e..d04fdc85 100644 --- a/sites/mainweb/lib/bootcamp-schedule.test.ts +++ b/sites/mainweb/lib/bootcamp-schedule.test.ts @@ -7,9 +7,8 @@ import { weekEntry, } from "./bootcamp-schedule"; -// A hand-edited constant published on a public page. Most of this is vacuous -// while it is empty — these arm themselves the moment the real weeks are typed -// in, which is the one moment nobody runs a test on purpose. +// A hand-edited constant published on a public page, so the guards are here to +// catch a typo in the edit rather than a bug in the code. describe("BOOTCAMP_CURRICULUM", () => { it("numbers each week once", () => { @@ -32,8 +31,9 @@ describe("BOOTCAMP_CURRICULUM", () => { it("gives every week something to render", () => { for (const entry of BOOTCAMP_CURRICULUM) { + // A week may be a title alone, but a blank one renders as an empty card. expect(entry.title.trim()).not.toBe(""); - expect(entry.desc.trim()).not.toBe(""); + if (entry.desc !== undefined) expect(entry.desc.trim()).not.toBe(""); } }); diff --git a/sites/mainweb/lib/bootcamp-schedule.ts b/sites/mainweb/lib/bootcamp-schedule.ts index 52051ed1..a3c5b20a 100644 --- a/sites/mainweb/lib/bootcamp-schedule.ts +++ b/sites/mainweb/lib/bootcamp-schedule.ts @@ -1,12 +1,14 @@ /** - * The public bootcamp syllabus. The portal's downloadable weekly material is - * edited separately, while the marketing page still needs stable public copy. + * The bootcamp syllabus shown on the public marketing page. The portal lists + * real scheduled workshops from the database instead, so nothing here reaches + * a signed-in member. */ export type BootcampWeek = { week: number; title: string; - desc: string; + /** Optional: a week may be published as a title alone. */ + desc?: string; /** Overrides the default room for a week that moves. */ room?: string; /** The notebook for this week, if it has its own link. */ @@ -26,68 +28,16 @@ export const BOOTCAMP_START_DATE: string | null = "September 22, 2026"; /** The Deepnote workspace every session works out of. */ export const BOOTCAMP_WORKSPACE_URL: string | null = null; -// Restored from f515a3d9. Confirm the titles before the term starts. export const BOOTCAMP_CURRICULUM: BootcampWeek[] = [ - { - week: 1, - title: "Python Basics & Setup", - desc: "Variables, data types, and environment configuration.", - }, - { - week: 2, - title: "Control Flow & Structures", - desc: "Loops, conditionals, lists, and dictionaries.", - }, - { - week: 3, - title: "Functions & Modules", - desc: "Writing reusable code and organizing projects.", - }, - { - week: 4, - title: "Object-Oriented Programming", - desc: "Classes, inheritance, and Pythonic design.", - }, - { - week: 5, - title: "File Handling & APIs", - desc: "Reading files, writing data, and making web requests.", - }, - { - week: 6, - title: "Pandas & NumPy", - desc: "Introduction to fast numerical computing and DataFrames.", - }, - { - week: 7, - title: "Data Cleaning", - desc: "Handling missing values, merging, and data transformations.", - }, - { - week: 8, - title: "Exploratory Data Analysis", - desc: "Extracting insights and statistical summaries from data.", - }, - { - week: 9, - title: "Data Visualization", - desc: "Creating stunning charts using Matplotlib and Seaborn.", - }, - { - week: 10, - title: "Intro to Machine Learning", - desc: "Core concepts, train/test splits, and Scikit-Learn.", - }, - { - week: 11, - title: "Supervised Learning", - desc: "Linear regression, logistic regression, and decision trees.", - }, - { - week: 12, - title: "Capstone Project", - desc: "Build an end-to-end data science portfolio piece.", - }, + { week: 1, title: "Core Library & Data Wrangling" }, + { week: 2, title: "Linear Regression" }, + { week: 3, title: "Logistic Regression" }, + { week: 4, title: "Decision Trees / Ensemble Methods" }, + { week: 5, title: "Clustering" }, + { week: 6, title: "Deep Learning" }, + { week: 7, title: "Creative Projects" }, + { week: 8, title: "Creative Projects" }, + { week: 9, title: "Creative Projects" }, ]; /** The curriculum entry a session's week number refers to, if there is one. */