-
Notifications
You must be signed in to change notification settings - Fork 2
Newcomer workshop
Welcome! This workshop gets you inside the TTS codebase by fixing three real bugs that were introduced on purpose. Each bug teaches you a core React concept. By the end you will have used useState, useEffect, and a custom hook with useSWR.
Before starting, read the File Structure page — especially the React primer at the top.
Follow the full setup in Running the project. The short version:
# 1. Clone the repo (if you haven't already)
git clone git@github.com:NIAEFEUP/tts-fe.git
cd tts-fe
# 2. Switch to the workshop branch
git checkout newcomer-workshop-2025
# 3. Copy the env file and fill in VITE_APP_BACKEND_URL
cp .env.example .env
# 4. Run the app
npm install
npm run devOpen http://localhost:3100 in your browser. You should see the TTS planner — but it's broken in three ways. Your job is to find and fix each one.
What you see: The planner has multiple timetable "options" (Option 1, Option 2, …). Clicking a different option should update the schedule shown on screen. But nothing happens — it always shows Option 1 no matter which one you click.
What to investigate: Find where selectedOption is defined. It should be a piece of React state whose value changes when the user clicks a different option.
Hints:
- Open
src/contexts/CombinedProvider.tsx. - Look for
selectedOption. It should be defined withuseState. Is it? - A
useStatecall looks like this:const [value, setValue] = useState(initialValue). - The initial value should come from
StorageAPI.getSelectedOptionStorage().
Concept practised: useState — how React tracks values that change over time.
What you see: When you open the "Unidades Curriculares" modal and select a course (major), no course units appear. The list stays empty.
What to investigate: The component that shows courses is CoursePicker. It should be fetching course units from the backend using a custom hook. Find where that fetch is supposed to happen.
Hints:
- Open
src/components/planner/sidebar/sessionController/CoursePicker.tsx. - Find the line that defines
courseUnitsandloadingCourseUnits. What is it returning right now? - It should be calling a hook called
useCourseUnits. Look atsrc/hooks/— does that file exist? - If it doesn't exist, you need to create it. It should use
useSWRto callgetCoursesByMajorId(id)from the API. - Look at an existing hook like
src/hooks/useVerifyCourseUnitHashes.tsxfor an example of howuseSWRis used. - The API function you need is
getCoursesByMajorIdfromsrc/api/. - Once the hook exists, import it in
CoursePicker.tsxand replace the static[[], false]with the real hook call.
Concept practised: Custom hooks and useSWR — how React fetches data from a backend.
What you see: When you switch between options, the name shown in the input (e.g. "Option 1", "Option 2") doesn't update. It keeps showing the name of whichever option was active when the page loaded.
What to investigate: There is a component called SelectedOptionController that renders the name input. It stores the name in a local state variable called optionName. The problem is that optionName is never updated when the selected option changes.
Hints:
- Open
src/components/planner/sidebar/SelectedOptionController.tsx. - Find where
optionNameis defined withuseState. - After that line, something is missing. You need to add a
useEffectthat runs wheneverselectedOptionormultipleOptionschanges, and inside it callssetOptionName(multipleOptions[selectedOption].name). - A
useEffectwith dependencies looks like this:useEffect(() => { // runs when any value in the array below changes }, [dep1, dep2])
Concept practised: useEffect — how React reacts to state changes and keeps derived values in sync.
If all three bugs are fixed:
- Switching options updates the schedule
- Selecting a major shows its course units
- Switching options updates the name in the input
Well done! Have a look at the File Structure page for a deeper tour of the codebase, and check out the Contributing guide when you're ready to open your first PR.