Skip to content

cbfacademy/ts-react-exercises-lifting-state

Repository files navigation

Session 8: Lifting state and the mini-project

What you are practising: everything at once. Callbacks as props, lifting state to a common parent, composition, and shipping a small working application: the travel bucket list.

Bring your Session 7 work

DestinationList.tsx and AddDestinationForm.tsx ship as empty shells again, because the finished versions are Session 7's exercise answers. Paste in your Session 7 components, or rebuild them. The API client, the data, and the styling are all identical to Session 7.

Setup

Accept the assignment, clone your repository, then install once:

npm install

Run: two terminals

# Terminal 1
npm run api

# Terminal 2
npm run dev

Offline fallback: set USE_MOCK = true at the top of src/api.ts. Reset your data: npm run reset-db.

What is in the starter

  • src/api.ts and db.json: identical to Session 7.
  • src/components/Card.tsx: carried forward.
  • src/components/DestinationList.tsx and AddDestinationForm.tsx: shells; bring your Session 7 work.
  • src/components/FilterBar.tsx and DestinationDetail.tsx: new shells for the mini-project.
  • src/App.tsx: the three regions of the app (filter, results, detail) scaffolded with TODOs. Keep the aria-labels on those <section>s — the grader uses them to find each region.
  • src/index.css: the full baseline plus .filter-bar and .detail.

The mini-project: a travel bucket list

An app that fetches the destinations, filters them by phase and name, shows a detail panel for the selected destination, and adds new destinations through a form. Work through the milestones in order; each leaves the app in a working state.

  1. Scaffold <App> with filter, results, and detail regions (done for you).
  2. Fetch destinations on mount through api.listDestinations() with the discriminated-union state.
  3. Render the list with correct keys and the <Card> from earlier sessions.
  4. Wire the filter bar (search + phase) with lifted state; filter results client-side.
  5. Selection: clicking a card sets the selected id; the detail panel renders the selected destination. Clicking the selected card again clears it.
  6. Add form: a controlled form that calls api.addDestination(...) and inserts the new destination into the list without refetching.
  7. Polish: disable the submit while the request is in flight, show a friendly error on failure, keep the form cleared on success.

Incomplete is fine. The point is an end-to-end working feature, not a finished product.

Done when

You have something you could show a friend: the list loads, the filters narrow it, selection drives the detail panel, and a new destination appears without a refetch. npm run typecheck passes and your work is committed and pushed.

How your work is graded

Every push runs two GitHub Actions checks:

  • Type check — runs tsc -b on your project.
  • Autograding — renders your <App /> with a mocked network and checks the core pipeline: the destinations load and list, clicking a card shows it in the Detail region, clicking it again clears the detail, and the search box narrows the Results. Plus an automated code-quality review of the whole mini-project (including the add form). To let the grader drive it: keep the aria-label="Results" / aria-label="Detail" sections, render each card's name in an <h2> inside a .card, and give the search input an accessible name containing "search" (a label or placeholder).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages