Skip to content

fix(feed): let users change poll votes#366

Open
Zekbot001 wants to merge 3 commits into
profullstack:masterfrom
Zekbot001:money/ugig-poll-revote
Open

fix(feed): let users change poll votes#366
Zekbot001 wants to merge 3 commits into
profullstack:masterfrom
Zekbot001:money/ugig-poll-revote

Conversation

@Zekbot001
Copy link
Copy Markdown

Summary

  • make poll result rows interactive for authenticated viewers
  • allow users to reach the existing API path for changing a previous poll vote
  • keep anonymous result rows read-only and cover the authenticated revote flow with a focused component test

Paid task

https://ugig.net/gigs/abd6b2a0-e728-48cf-a46f-f99e419ed94e

Verification

  • pnpm exec vitest run src/components/feed/PollDisplay.test.tsx
  • pnpm exec eslint src/components/feed/PollDisplay.tsx src/components/feed/PollDisplay.test.tsx
  • git diff --check

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 31, 2026

Greptile Summary

This PR makes poll result rows interactive for authenticated viewers by converting them to <button role="radio"> elements, adds a role="radiogroup" wrapper, and guards against re-submitting the already-selected option. A focused Vitest suite covers the revote flow and the no-op guard.

  • Revote UX: Result rows are now clickable buttons for logged-in users; anonymous viewers still see read-only divs. The optionId === userVote guard prevents redundant API calls.
  • Accessibility semantics: Switches from the incorrect aria-pressed pattern to role="radio" + aria-checked on each option with a role="radiogroup" container, addressing the previous review feedback.
  • Tests: Two new cases validate that a second-fetch cycle completes on vote change and that clicking the current selection fires no additional network request.

Confidence Score: 5/5

Safe to merge — the logic changes are small and well-tested, with no data-loss or security concerns introduced.

The change correctly guards against redundant votes, properly conditionalizes the interactive vs. read-only rendering, and backs it with a passing test suite. The only gap is that the role="radiogroup" pattern conventionally requires roving tabindex and arrow-key handling, which is missing, but this does not affect data correctness or functional behavior.

No files require special attention beyond the accessibility keyboard-navigation gap in PollDisplay.tsx.

Important Files Changed

Filename Overview
src/components/feed/PollDisplay.tsx Makes result rows interactive buttons for authenticated users (role="radio"/aria-checked), adds radiogroup wrapper, and guards handleVote against re-voting the same option. Keyboard navigation (roving tabindex + arrow keys) is not implemented for the radiogroup.
src/components/feed/PollDisplay.test.tsx New test file covering the authenticated revote flow and the same-option no-op guard; mocks fetch correctly for 3-call sequence and validates aria-checked state after vote change.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant PD as PollDisplay
    participant API as /api/posts/:id/poll/vote

    PD->>API: GET (on mount)
    API-->>PD: "{ options, total_votes, user_vote }"
    PD->>PD: Render result rows as radio buttons (isLoggedIn)

    U->>PD: "Click different option (role="radio")"
    PD->>PD: "Guard: optionId === userVote? skip"
    PD->>PD: setVoting(true) disable all buttons
    PD->>API: "POST { option_id }"
    API-->>PD: "{ success: true }"
    PD->>API: GET (refetch)
    API-->>PD: "{ options, total_votes, user_vote }"
    PD->>PD: setVoting(false) re-enable buttons
    PD->>PD: Re-render with updated aria-checked state
Loading

Reviews (3): Last reviewed commit: "fix(feed): label poll choice groups" | Re-trigger Greptile

Comment thread src/components/feed/PollDisplay.tsx
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