Skip to content

Latest commit

 

History

History
301 lines (214 loc) · 12.2 KB

File metadata and controls

301 lines (214 loc) · 12.2 KB

PawFinder Hackday — Facilitator Guide

This guide is for the person running the day. It covers setup, pacing, common problems, and how to keep a mixed-ability group moving forward together.


Pre-day Setup (the night before)

Work through this on a clean machine if possible — ideally the same OS as attendees.

Repository check

git clone <repo-url>
cd react-tutorial
npm install
npm run dev
# Should open http://localhost:5173 showing PawFinder header
cd services/animals-api
npm install
npm start
# Should show: PawFinder Animals API running at http://localhost:3001

Visit http://localhost:3001/animals — you should see "total": 34 with animal data.

Section reset scripts

npm run section:1:start   # Should print: Reset to section 1/start
npm run section:2:start   # Should print: Reset to section 2/start
# Verify sections 3 and 4 also work
npm run section:1:start   # Reset back to start before the day

Storybook

npm run storybook
# Should open http://localhost:6006 — mostly empty at section-1/start

TypeScript check

npx tsc --noEmit
# Should produce no output (clean)

Playwright (for Section 6)

npx playwright install chromium
npm run test:e2e
# Should show "No tests found" — that's fine at section-1/start

If anything fails, fix it before the day. Nothing kills momentum faster than a broken setup.


Day Schedule

Time Activity
09:00 Welcome, attendee setup
09:30 Section 1: React Fundamentals
10:30 Section 2: State & Interactivity
11:30 Section 3: Atomic Design + Storybook
12:45 Lunch
13:30 Section 4: Data Fetching
14:30 Section 5: Unit & Component Testing
15:45 Buffer / catch-up
16:15 Section 6 (stretch): E2e with Playwright
17:15 Retrospective
17:30 End

Welcome & Setup (09:00 — 09:30)

What to say

Spend 5 minutes on context:

  • "Today you're building PawFinder — a real animal re-homing app. It will fetch real data, have real routing, and have real tests by the end of the day."
  • Show the finished app (npm run section:4:complete, then npm run dev). Let attendees see what they're building toward, then reset to section 1 start.
  • "We've broken the day into six sections. Each one has a worksheet with step-by-step instructions. The reference solution is always one command away — you're never stuck."

Setup checklist (attendees work through this)

Each attendee needs:

1. VS Code open on the react-tutorial folder
2. Terminal 1: cd services/animals-api && npm install && npm start
3. Terminal 2: npm install && npm run dev
4. Browser open at http://localhost:5173 — see the PawFinder header
5. npm run section:1:start (confirm: "Reset to section 1/start")

Walk the room while attendees set up. Common issues during setup are listed below. Aim to have everyone running by 09:30.


Section-by-Section Facilitation Notes

Section 1 — React Fundamentals (09:30 — 10:30)

Your introduction (10 minutes):

  • Explain components with an analogy: "A component is like a LEGO brick. PetCard is a brick. PetList is made of PetCard bricks. The app is made of PetList bricks."
  • Show JSX: write <h1>Hello</h1> in App.tsx, save, see it render. Then pass a name prop. This takes 3 minutes and makes the concept concrete.
  • Show TypeScript auto-complete working on an Animal prop — hover over a field to see its type.
  • Send them to the worksheet.

Pacing signal: At 10:15, check how the room is doing. If most people have cards rendering, let them continue. If more than half are stuck, do a group walkthrough of Steps 1–4 together before sending them back.

Checkpoint moment (10:25): Anyone not done with Section 1 should: npm run section:1:complete — they can read the solution and move on.


Section 2 — State & Interactivity (10:30 — 11:30)

Your introduction (5 minutes):

  • "The cards look great. Clicking 'Dogs' does nothing. Let's fix that."
  • Show useState in the browser console: in any component, demonstrate that mutating a variable directly doesn't trigger a re-render, but calling setState does. This is the key insight.
  • Show the anti-pattern: "What if I stored the filtered list in state?" — draw a diagram showing two state values that need to be kept in sync. "React idiom: derive it."

Pacing signal: Search bar is fast (step 1–4, ~15 minutes). FilterBar takes longer. If attendees are building the filter logic from scratch, the 30-minute mark is a reasonable check-in point.


Section 3 — Atomic Design + Storybook (11:30 — 12:45)

Your introduction (10 minutes):

  • This is the most conceptual section. Don't rush the explanation.
  • Draw the atom → molecule → organism hierarchy on a whiteboard (or screen). Label the existing components: "PetCard is currently a molecule that does atomic work. We're going to separate those concerns."
  • Start Storybook together: npm run storybook. Show that it's mostly empty. "By lunch you'll have a component library."
  • Emphasise: Storybook is not optional here. The stories are part of the deliverable, not a nice-to-have.

The reorganisation step (Step 10) tends to confuse people because they delete files that something else imports. Tell them: "TypeScript will show you every broken import the moment you delete a file — it's a free checklist."

Pacing signal: If it's 12:30 and someone hasn't started the story files yet, help them skip the folder move (just update the imports, don't move files) and focus on getting at least the Badge story working.


Lunch (12:45 — 13:30)

Good time for:

  • A 5-minute retrospective on the morning ("what clicked? what was confusing?")
  • Showing the Storybook component libraries of real teams to inspire what's possible

Section 4 — Data Fetching (13:30 — 14:30)

Your introduction (10 minutes):

  • "Until now, the app has been lying. We've had three fake animals. That changes now."
  • Demo: stop the API, refresh the app — currently it'll show nothing or an error. "We need to handle this gracefully."
  • Explain the fetch lifecycle visually: loading → (success: data) or (failure: error). Most real-world async UI work is just managing these three states.
  • Show useEffect with an empty dependency array — "this runs once, after the first render". Add a console.log inside to prove it.

Watch for: The custom hook step (Step 4) is where attendees sometimes get lost. The concept of "a hook is just a function that uses hooks" is simple but the abstraction jump can confuse people. If you see someone confused, say: "For now, just put the useState and useEffect directly in App.tsx — the hook is a refactor, not a requirement."

The routing bonus (Steps 5–8) is genuinely achievable in 20 minutes if the fetching part went smoothly. Encourage people to try it.


Section 5 — Unit & Component Testing (14:30 — 15:45)

Your introduction (10 minutes):

  • "Every line of code you wrote today has no tests. That means any change could silently break something."
  • Live demo: introduce a deliberate bug in Badge (change 'bg-green-100' to 'bg-blue-100'). Open the app — "looks fine, right?" Then write and run a test — it fails immediately. Fix the bug, test passes.
  • Explain the philosophy: "Test behaviour, not implementation. If your tests break when you rename a variable, they're testing the wrong thing."
  • Run npm test — explain watch mode.

MSW is already configured — don't spend time on it unless asked. The test/setup.ts file handles everything. Attendees just write tests.

The waitFor pattern is often new. Explain: "Your fetch is async — the data doesn't appear instantly. waitFor keeps retrying the assertion until it passes or times out."

Pacing signal: If it's 15:30 and someone has only written the utility test, that's fine — the utility test + one component test shows the pattern. The integration test is the stretch goal for this section.


Buffer / Catch-up (15:45 — 16:15)

Use this time flexibly:

  • If the group is ahead: Start Section 6 early
  • If the group is behind: Pair-program with anyone stuck on Section 5; it's more valuable than moving to E2e
  • Q&A: Common questions at this point are "when do I use useEffect vs useState?", "how do custom hooks work?", and "what's the difference between unit and integration tests?" — have answers ready

Section 6 — E2e (16:15 — 17:15)

Your introduction (5 minutes):

  • "You've tested components in isolation. Now we test the whole journey in a real browser."
  • Run npm run test:e2e:ui — Playwright's visual runner is impressive. Show it to the room.
  • "This runs Chromium, loads your actual app, and clicks things. It catches problems that no unit test ever could."

This section is deliberately optional. Not everyone needs to complete it. The main day's value is sections 1–5.


Retrospective (17:15 — 17:30)

Ask three questions (round-robin, one answer per person):

  1. What clicked today that didn't make sense before?
  2. What would you use on Monday morning?
  3. What would you do differently in the next version of this day?

Capture the answers if you can — they're gold for the next hackday.


Common Problems and Fixes

Port already in use

Error: listen EADDRINUSE: address already in use :::3001

Another process is using port 3001. Find and kill it, or start the API on a different port:

PORT=3002 npm start

Then update the Vite proxy in vite.config.ts to point to localhost:3002.


Tailwind classes not applying

Tailwind v4 requires the @tailwindcss/vite plugin. Check vite.config.ts has tailwindcss() in the plugins array. If you added a class that doesn't seem to work, check for typos — Tailwind won't warn you about unknown classes.


TypeScript errors on first checkout

Usually means node_modules isn't installed, or the wrong Node version:

node -v   # should be v20 or higher
npm install

"Cannot find module '@/...'"

The @/ path alias isn't configured correctly. Check tsconfig.app.json has:

"paths": { "@/*": ["src/*"] }

And vite.config.ts has the matching alias in resolve.alias.


Storybook fails to start

# Clear the cache and retry
rm -rf node_modules/.cache/storybook
npm run storybook

Section reset broke my code

# Reset to a clean known state
npm run section:N:start     # replace N with current section number

If you want to inspect what the reset overwrote, the original files are in sections/section-N/start/ — open them in VS Code without resetting.


"My code is broken and I don't know where"

TypeScript errors are usually the fastest diagnosis. Press Ctrl+Shift+P in VS Code → "TypeScript: Show All Errors" to see every error in the project at once.


MSW isn't intercepting requests in tests

Check that src/test/setup.ts is referenced in vitest.config.ts under setupFiles. The setup file must call server.listen() in beforeAll.


Playwright tests fail because the app isn't running

The playwright.config.ts is configured with a webServer block that starts npm run dev automatically. If you see connection refused errors, check the url field matches your dev server port.


Pacing Summary

If you see the whole group consistently running behind by 20+ minutes, use this protocol:

  1. Call a checkpoint
  2. Everyone runs npm run section:N:start on the next section's start branch
  3. Explain the key new concept in 3 minutes
  4. Move on

No one should spend the whole day stuck on one section. The reset script exists precisely for this.


For Faster Attendees

Every section has "Going further" bonus tasks. Additionally:

  • Section 3: encourage them to explore the Storybook Controls panel and write stories for SearchPanel
  • Section 4: encourage the enquiry form
  • Section 5: encourage them to write tests for the AnimalDetailPage or test error states via MSW overrides
  • Section 6: encourage the visual regression screenshots or Playwright code generation

The best thing a fast attendee can do is help someone sitting next to them — pair programming in this context is genuinely more valuable than solo bonus tasks.