Skip to content

[NEWBIE-FRONTEND] Wire up course invitation accept/decline buttons #280

@smattymatty

Description

@smattymatty

Claiming This Task

Before you start working, check the Assignees section. If no one is assigned, leave a comment claiming the issue and assign it to yourself. This prevents duplicate work.

See the Community Wiki for contributing guidelines and git workflow.

Goal

Enable the Accept and Decline buttons on the course invitation banner so invited users can respond to course invitations directly from the course detail page.

Right now, when a user is invited to a course and visits it, they see a banner saying "You've been invited to join this course as student" with Accept and Decline buttons — but the buttons are disabled with a "coming soon" tooltip. The backend endpoints and frontend API functions already exist, they just need to be connected.

Task Description

1. Add methods to useEnrollment hook (src/hooks/useEnrollment.ts)

Add two new methods to the hook's return value:

  • acceptInvitation() — calls acceptCourseInvitation(courseId) from coursesApi.ts, shows success toast, calls refetch()
  • declineInvitation() — calls declineCourseInvitation(courseId) from coursesApi.ts, shows success toast, calls refetch()

Both should:

  • Set isLoading = true during the API call
  • Show error toast on failure using getSafeErrorMessage
  • Follow the same try/catch/finally pattern as the existing enroll() and leave() methods

Update the UseEnrollmentReturn interface to include the new methods.

2. Enable buttons in EnrollmentActions (src/components/courses/EnrollmentActions.tsx)

In the status === "invited" block:

  • Remove disabled from both Accept and Decline buttons
  • Remove the title={t("course.enrollment.inviteComingSoon")} tooltip
  • Wire Accept button's onClick to enrollment.acceptInvitation
  • Wire Decline button's onClick to enrollment.declineInvitation
  • Show loading state: disable both buttons and change text to "Accepting..." / "Declining..." while isLoading is true
  • Remove the opacity-50 cursor-not-allowed classes (keep proper disabled styling for loading state only)

3. Remove unused i18n key

The "inviteComingSoon" key in en.json and ar.json is no longer needed after this change. Remove it.

Definition of Done

  • Accept button calls the API and changes the user's status from "invited" to "enrolled" with a success toast
  • Decline button calls the API and removes the invitation with a success toast
  • Both buttons show loading state during API call
  • Error toast appears if the API call fails
  • Tests pass for the new hook methods and button interactions
  • No TypeScript or lint errors

Benefits

This completes the course invitation flow — teachers can now invite users (issue #261) and invited users can respond. This is critical for the courses feature since restricted and private courses rely on invitations.

Skills You'll Practice

  • React hooks (extending an existing custom hook)
  • Async/await with error handling
  • Connecting UI to existing API functions
  • Writing tests for hooks and components
  • TypeScript interfaces

Files to be Altered (if known)

File Change
src/hooks/useEnrollment.ts Add acceptInvitation() and declineInvitation() methods
src/components/courses/EnrollmentActions.tsx Enable buttons, wire to hook methods, add loading state
src/i18n/locales/en.json Remove inviteComingSoon key
src/i18n/locales/ar.json Remove inviteComingSoon key
src/hooks/__tests__/useEnrollment.test.ts Add tests for new methods
src/components/courses/__tests__/EnrollmentActions.test.tsx Update "invited" tests — buttons should be enabled, test click behavior

Testing

Automated

  • useEnrollment hook tests: verify acceptInvitation calls acceptCourseInvitation, shows toast, calls refetch. Same for declineInvitation. Test error handling.
  • EnrollmentActions tests: verify Accept/Decline buttons are enabled for invited status, verify click calls the correct method, verify loading state disables both buttons.

Manual

  1. Have a teacher invite a user to a course (via the Invite Member modal)
  2. Log in as the invited user
  3. Navigate to the course detail page
  4. Verify the invitation banner appears with enabled Accept/Decline buttons
  5. Click Accept — verify status changes to enrolled, success toast appears
  6. (Or click Decline — verify invitation is removed, success toast appears)

Tips (Optional)

  • Look at how enroll() and leave() are implemented in useEnrollment.ts — your new methods follow the exact same pattern
  • The API functions acceptCourseInvitation and declineCourseInvitation are already in src/services/coursesApi.ts — you just need to call them
  • The i18n strings for success/error toasts already exist: course.enrollment.acceptSuccess, course.enrollment.acceptError, course.enrollment.declineSuccess, course.enrollment.declineError
  • This issue does NOT depend on the notification system — it works independently because the user can see the invitation when they visit the course page

Getting started? These wiki pages will help you get set up:

This is a beginner-friendly task. Ask questions in Discord — we're here to help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions