Skip to content

GitHub Sync — Frontend (admin dropdown, push button, client polling) #11

@tkowalczyk

Description

@tkowalczyk

Parent PRD

#1

What to build

Wire the admin dashboard and client tracking page to the GitHub sync backend (shipped in #8). Adds the UI layer for repo selection, pushing tasks as GitHub issues, displaying issue links, and reflecting issue status on the client tracking page.

Repo picker (admin): In the admin project view, when a project is in review or active status, show a dropdown of available GitHub repos (fetched via GET /github/repos). Selecting a repo calls PUT /projects/:slug/github-repo and persists. The current selection is shown when the project already has githubRepo set.

Push to GitHub (admin): A single "Push to GitHub" button triggers POST /github/projects/:slug/push. Disabled when no repo selected, no tasks exist, or all tasks already have GitHub issues. While pushing: button shows progress state; on success: refresh task list. Errors surface as inline alert.

GitHub issue links (admin): For each task with a githubIssueNumber, render an external link icon next to the task title that opens githubIssueUrl in a new tab.

Client polling (public): On the client tracking page (/p/:slug), when the project has active or complete status and at least one task has a githubIssueNumber, call POST /github/projects/:slug/sync once on mount. The mutation result refreshes the cached client-view so task statuses (done/pending) reflect the latest GitHub state.

Acceptance criteria

  • Admin sees a "GitHub repo" dropdown on the project review page — populated from GET /github/repos
  • Selecting a repo persists via PUT /projects/:slug/github-repo and shows the saved value on reload
  • "Push to GitHub" button visible on the project review page when project has tasks
  • Button disabled when no repo selected or all tasks have issues; shows loading state during push
  • Successful push refreshes the task list; failed push displays an error alert
  • Each task with a linked GitHub issue shows a clickable issue link (icon → githubIssueUrl, opens in new tab)
  • Client tracking page (/p/:slug) calls sync API once on mount when project is active/complete with linked issues
  • Task status badges on the client tracking page reflect GitHub issue state after sync (done/pending)
  • All new user-facing strings added to both i18n/messages/{en,pl}.json
  • All UI uses theme-aware classes (no hardcoded text-white, bg-gray-*, etc.)

Blocked by

None — backend (#8) shipped in commit cfc6f49.

User stories addressed

  • User story 13
  • User story 14
  • User story 15

TDD slice plan (suggested)

  1. API client functions (lib/github-api-client.ts): listAvailableRepos, setProjectGithubRepo, pushTasksToGithub, syncGithubIssueStatus — mock fetch only at boundary.
  2. Repo picker component (admin): dropdown bound to query + mutation; tests mock the API client functions.
  3. Push button + state: tests cover disabled states, loading state, success cache invalidation, error alert.
  4. Issue link rendering (task list): test that link only appears when githubIssueNumber !== null and href equals githubIssueUrl.
  5. Client polling: test that sync mutation fires once on mount only when conditions met, and updates cached client-view on success.

Backend endpoints (already shipped — issue #8)

Method Path Auth Purpose
GET /github/repos admin List available repos for dropdown
PUT /projects/:slug/github-repo admin Persist selected repo
POST /github/projects/:slug/push admin Create issues for unsynced tasks
POST /github/projects/:slug/sync public Refresh task statuses from GitHub

Notes

  • GITHUB_TOKEN must be set as a Cloudflare Worker secret on staging/production before this UI can work end-to-end (delegate to DevOps).
  • Polling is one-shot on mount, not interval-based — interval/cron polling is a follow-up consideration.
  • Existing admin project view: apps/user-application/src/routes/_auth/app/projects/$slug.tsx
  • Existing client view: apps/user-application/src/routes/p/$slug.tsx and components/spec/spec-tracking-view.tsx

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions