Skip to content

feat(VOC-131): add GenerateButton component and dashboard integration - #29

Open
FSS3096 wants to merge 1 commit into
Arthakram:mainfrom
FSS3096:feat/VOC-131-generate-button-trigger
Open

feat(VOC-131): add GenerateButton component and dashboard integration#29
FSS3096 wants to merge 1 commit into
Arthakram:mainfrom
FSS3096:feat/VOC-131-generate-button-trigger

Conversation

@FSS3096

@FSS3096 FSS3096 commented Jul 15, 2026

Copy link
Copy Markdown
  • Create components/GenerateButton.tsx with all required states:

    • Idle (no repo): disabled button with muted 'Select a repo first' label
    • Idle (repo selected): primary blue CTA — 'Generate Post from Latest Activity'
    • Loading: button replaced by LoadingView spinner (no double-submit possible)
    • Error: ErrorView with retry + button reappears for retry
    • Success: stores response in sessionStorage['voca_drafts'], push('/drafts)
  • Create components/DashboardClient.tsx — Client Component boundary that owns selectedRepo state and passes it to both RepoSelector and GenerateButton. This cleanly solves the Server Component → state ownership problem without prop drilling.

  • Refactor components/RepoSelector.tsx to support controlled mode:

    • New optional props: onRepoSelect (callback) + selectedRepo (controlled value)
    • Controlled mode: used by DashboardClient for VOC-131 flow
    • Uncontrolled/legacy mode: original behaviour preserved for existing callers
  • Update app/dashboard/page.tsx to use DashboardClient instead of bare RepoSelector; page stays a Server Component for auth guard.

Acceptance criteria covered:
✅ Button visible after repo selection ✅ Button disabled (not hidden) when no repo selected ✅ POST /api/generate called with { repoFullName } ✅ Loading state replaces button (no double-submit) ✅ Error state with retry (coordinates with #18) ✅ sessionStorage key 'voca_drafts' on success ✅ router.push('/drafts') on success ✅ Mobile: w-full, capped at max-w-[400px] centered on desktop ✅ Accessible: aria-label, aria-disabled, role=status/alert, focus-visible ring

Placeholder stubs for LoadingView and ErrorView are intentionally co-located in GenerateButton.tsx — swap to real components (#17, #18) is a one-line import change.

Relates to: VOC-131
Blocks: #17 (loading state), #18 (error handling)
Depends on: /api/generate endpoint (#15)

Summary

Type of Change

  • 🐛 Bug fix

  • - [ ] ✨ New feature

  • - [ ] 🔨 Refactor / tech debt

  • - [ ] 📝 Documentation update

  • - [ ] 🚀 Performance improvement

  • - [ ] 🔧 Config / tooling change

  • ## What Changed

  • -

  • -

  • ## Testing

  • - [ ] Manual testing done

  • - [ ] Existing tests pass

  • - [ ] New tests added (if applicable)

  • ## Screenshots / Demo

  • ## Checklist

  • - [ ] Self-reviewed the code

  • - [ ] No console errors or warnings

  • - [ ] PR title follows type: short description convention

  • - [ ] Linked to relevant issue (closes #)

  • - [ ] Ready for review (not a draft)

- Create components/GenerateButton.tsx with all required states:
  - Idle (no repo): disabled button with muted 'Select a repo first' label
  - Idle (repo selected): primary blue CTA — 'Generate Post from Latest Activity'
  - Loading: button replaced by LoadingView spinner (no double-submit possible)
  - Error: ErrorView with retry + button reappears for retry
  - Success: stores response in sessionStorage['voca_drafts'], push('/drafts)

- Create components/DashboardClient.tsx — Client Component boundary that owns
  selectedRepo state and passes it to both RepoSelector and GenerateButton.
  This cleanly solves the Server Component → state ownership problem without
  prop drilling.

- Refactor components/RepoSelector.tsx to support controlled mode:
  - New optional props: onRepoSelect (callback) + selectedRepo (controlled value)
  - Controlled mode: used by DashboardClient for VOC-131 flow
  - Uncontrolled/legacy mode: original behaviour preserved for existing callers

- Update app/dashboard/page.tsx to use DashboardClient instead of bare
  RepoSelector; page stays a Server Component for auth guard.

Acceptance criteria covered:
  ✅ Button visible after repo selection
  ✅ Button disabled (not hidden) when no repo selected
  ✅ POST /api/generate called with { repoFullName }
  ✅ Loading state replaces button (no double-submit)
  ✅ Error state with retry (coordinates with Arthakram#18)
  ✅ sessionStorage key 'voca_drafts' on success
  ✅ router.push('/drafts') on success
  ✅ Mobile: w-full, capped at max-w-[400px] centered on desktop
  ✅ Accessible: aria-label, aria-disabled, role=status/alert, focus-visible ring

Placeholder stubs for LoadingView and ErrorView are intentionally co-located
in GenerateButton.tsx — swap to real components (Arthakram#17, Arthakram#18) is a one-line
import change.

Relates to: VOC-131
Blocks: Arthakram#17 (loading state), Arthakram#18 (error handling)
Depends on: /api/generate endpoint (Arthakram#15)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant