Skip to content

Feat: Implement action confirmation on ApplicationCard#217

Merged
Jagadeeshftw merged 2 commits into
Grainlify:mainfrom
cristianFleita:feat/applicationcard-confirm
Jun 23, 2026
Merged

Feat: Implement action confirmation on ApplicationCard#217
Jagadeeshftw merged 2 commits into
Grainlify:mainfrom
cristianFleita:feat/applicationcard-confirm

Conversation

@cristianFleita

Copy link
Copy Markdown
Contributor

Summary

ApplicationCard previously fired Assign/Reject/Unassign immediately with no confirmation for destructive actions, no loading/disabled state during the request, and could crash if applicant was missing. This PR adds a confirmation step for destructive actions, pending/disabled UI with spinners, a null guard, and full keyboard/ARIA accessibility — backed by a comprehensive test suite at 100% coverage.

Closes #188

What changed

  • Confirmation for destructive actions — Reject and Unassign now require an inline two-step confirm (Reject this application?Confirm reject / Cancel). The handler only fires after explicit confirmation, so a single misclick can no longer trigger an irreversible request. Assign (non-destructive) still fires directly.
  • Pending / disabled state — Action handlers may return a promise; while one is in flight, all action buttons are disabled and the active button shows a Loader2 spinner with aria-busy. A second click on an in-flight button is ignored, preventing duplicate submissions.
  • Null guard — A null/undefined applicant renders nothing instead of dereferencing applicant.name; the optional badge remains conditionally rendered.
  • Accessibility — All controls are native <button type="button"> (keyboard-operable by default) with explicit aria-labels (e.g. "Reject octocat"); the confirm prompt is a labelled role="group", and decorative icons are aria-hidden.
  • Unmount safety — A mountedRef prevents post-unmount state updates (the card often unmounts as a result of its own reject).
  • Wiring — Added optional onAssign / onReject / onUnassign props (each receiving the applicant, sync or async). The component is standalone (only referenced by the feature README), so no live callers needed updating.
  • Docs — Added inline TSDoc on the component, its props, and helpers.

Files

  • src/features/maintainers/components/issues/ApplicationCard.tsx
  • src/features/maintainers/components/issues/ApplicationCard.test.tsx (new)

Acceptance criteria

  • Destructive actions require confirmation
  • Buttons disable + show spinner while pending
  • Null badge / null applicant does not crash
  • Tests cover confirm / cancel / pending

Tests

13/13 passing · 100% coverage (statements / branches / functions / lines) for the file.

@Jagadeeshftw Jagadeeshftw merged commit 5c38328 into Grainlify:main Jun 23, 2026
@Jagadeeshftw

Copy link
Copy Markdown
Contributor

adding an action confirmation step on the ApplicationCard is a sensible guard against accidental approve/reject clicks. rebased on latest main and merged. thanks!

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.

Add confirmation dialogs and loading state to ApplicationCard assign/reject actions

3 participants