### Connect the Your gymnasts page to the GraphQL API **Goal:** Make the "Your gymnasts" page (`/gymnasts`, built in #67) show and create the logged-in coach's real gymnasts. Today the page starts from `exampleGymnasts` in `src/lib/gymnasts.ts` and keeps new gymnasts only in React state, so they are lost on reload. #67 kept the data access behind a small adapter so it could be connected later; this issue does that. The page is for logged-in coaches only (see [UI_PLANS.md](docs/UI_PLANS.md)). The API is in `dev`: `me { gymnasts }`, `createGymnast`, and the errors listed in [API.md](docs/API.md). #### Implementation checklist - [ ] **Load the gymnasts** - [ ] Replace `exampleGymnasts` with a query for the coach's gymnasts (`me { id gymnasts { id name } }`) through Apollo Client (#75). - [ ] Show a loading state, an error state with a retry button, and the existing empty state. Keep the list in the same order as the API gives it. - [ ] Remove `exampleGymnasts` when it is no longer used (the tests may keep their own sample data). - [ ] **Add a gymnast** - [ ] Call `createGymnast(name)` from the existing form, and update the Apollo cache so the new gymnast appears without reloading the list. - [ ] Keep the checks in the form that already exist (a name is needed, at most 70 characters), and show the server's answer when it still refuses: `BAD_USER_INPUT` (name), `LIMIT_REACHED` (a coach can have 200 gymnasts) and `UNAUTHENTICATED`. - [ ] Keep the focus handling and the screen reader announcement ("… added to your gymnasts.") that the page has now, and disable the save button while the request runs so a double click does not create two. - [ ] Decide if the name rules should live in one place. `normalizeGymnastName` also collapses spaces inside the name, and the server only trims (1–70 characters, see "Names" in [API.md](docs/API.md)). The two must not disagree about what a valid name is. - [ ] **Logged-out visitors** - [ ] When `me` is `null` (not logged in, or the session has expired), do not show an empty list as if the coach had no gymnasts. Show a message with a way to log in, or send the visitor to the login page. - [ ] This needs the login to exist in the frontend (see "Depends on"). - [ ] **Tests** - [ ] Component tests with a mocked Apollo provider: the loading, error, empty and filled states; adding a gymnast updates the list; each error code gives its message; the logged-out state. - [ ] Keep the existing tests for the list, the initials and the name checks passing. #### Depends on - The login in the frontend: a "Log in with Google" button that calls `login` and keeps the session (the client side is in `src/lib/apollo/`, from #75). The backend login is #70 (pull request #71). There is no issue for the button and the login page yet. - On the course server (plain http) Sign in with Google does not work, so the page can only be tried with a login on `localhost` (see "Login" in the README). #### Not in this issue - Renaming and deleting a gymnast (`renameGymnast`, `deleteGymnast`). The page has no controls for them yet. - The gymnast page that opens from a row (mockup `docs/design/gymnastDetail.png`), with the routines and the list of elements.