Group Invitations
Group Invitations
Section titled “Group Invitations”Summary
Section titled “Summary”Group Invitations enable admins to invite participants to Secret Santa groups through multiple channels: manual phone/email entry or shareable invitation links.
User Story
Section titled “User Story”As a group admin,
I want to invite friends to my Secret Santa group,
So that they can join and participate in the gift exchange.
Acceptance Criteria
Section titled “Acceptance Criteria”- ✅ Admin can invite by phone number (SMS sent)
- ✅ Admin can invite by email
- ✅ Admin can generate shareable invitation link
- ✅ Invitees receive notification with group details
- ✅ Invitees can accept or decline invitation
- ✅ Admin can view pending invitations
- ✅ Admin can cancel pending invitations
- ✅ Link invitations work for authenticated and unauthenticated users
Inputs and Outputs
Section titled “Inputs and Outputs”Inputs:
- Phone numbers or emails (array of strings)
- Group ID (number)
Outputs:
- Sent invitations with status
- Shareable link:
/invite/:sharedId - Invitation acceptance confirmation
Manual Invitation Flow
Section titled “Manual Invitation Flow”Admin clicks "Invite Participants" │ ▼Enter contacts (one per line or comma-separated): +1234567890, john@example.com +0987654321, jane@example.com │ ▼Click "Send Invitations" │ ▼POST /groups/:groupId/invite [{ name: "John", phone: "+1234567890" }, ...] │ ▼Backend sends SMS/email to each contact │ ▼Show "X invitations sent" toast │ ▼Display pending invitations listShareable Link Flow
Section titled “Shareable Link Flow”Admin clicks "Share Link" │ ▼Backend generates unique sharedId │ ▼Display link: redngift.com/invite/abc123xyz │ ├─ Copy to clipboard ──────────┐ │ │ │ ▼ │ Show "Link copied" toast │ └─ Share via WhatsApp/etc ─────┐ │ ▼ Open share dialogInvitation Acceptance Flow
Section titled “Invitation Acceptance Flow”Invitee clicks invitation link │ ▼Open /invite/:sharedId │ ├─ User not logged in ─────────┐ │ │ │ ▼ │ Redirect to /auth/login │ (with returnUrl=/invite/:sharedId) │ │ │ ▼ │ After login, return to invite page │ └─ User logged in ─────────────┐ │ ▼ GET /groups/shared/:sharedId │ ▼ Display group preview: - Group name - Admin name - Event date - Member count │ ▼ User clicks "Join Group" │ ▼ POST /groups/shared/:sharedId/join │ ├─ Success ──────┐ │ │ │ ▼ │ Add user to group │ │ │ ▼ │ Show "You've joined!" toast │ │ │ ▼ │ Navigate to /group/:id │ └─ Error ────────┐ │ ▼ Show error toast "Unable to join group"API/Contracts
Section titled “API/Contracts”Send Manual Invitations
Section titled “Send Manual Invitations”Request:
POST /groups/5/inviteAuthorization: Bearer {token}Content-Type: application/json
[ { "name": "John Smith", "phone": "+1234567890" }, { "name": "Jane Doe", "phone": "+0987654321" }]Response:
{ "success": true, "invitations": [ { "id": 1, "userName": "John Smith", "userPhone": "+1234567890", "userProfilePhoto": null }, { "id": 2, "userName": "Jane Doe", "userPhone": "+0987654321", "userProfilePhoto": null } ]}Get Group by Shared ID
Section titled “Get Group by Shared ID”Request:
GET /groups/shared/abc123xyzResponse:
{ "success": true, "group": { "id": 5, "name": "Office Secret Santa", "image": "https://cdn.rnb.la/group5.jpg", "admin": { "id": 1, "name": "Jane Doe" }, "date": "2025-12-25", "memberCount": 8 }}Join Group via Link
Section titled “Join Group via Link”Request:
POST /groups/shared/abc123xyz/joinAuthorization: Bearer {token}Response:
{ "success": true, "group": { "id": 5, "name": "Office Secret Santa", ... }}Cancel Invitation
Section titled “Cancel Invitation”Request:
DELETE /groups/5/invitation/10Authorization: Bearer {token}Response:
{ "success": true, "message": "Invitation canceled"}Error Handling
Section titled “Error Handling”- Invalid phone format: “Please enter valid phone numbers”
- User already in group: Backend returns 409 Conflict
- Expired link: “This invitation link is no longer valid”
- Group at capacity: “This group is full”
Example
Section titled “Example”const handleSendInvitations = async (contacts: Contact[]) => { try { const result = await groupsHandlers.inviteParticipants(groupId, contacts); toast.success(`${result.invitations.length} invitations sent`); dispatch(fetchOneGroup(groupId)); // Refresh group data } catch (error) { toast.error('Failed to send invitations'); }};
const handleCopyLink = () => { const link = `${window.location.origin}/invite/${group.sharedId}`; navigator.clipboard.writeText(link); toast.success('Link copied to clipboard');};Further Reading
Section titled “Further Reading”- Secret Santa Groups - Full group management
- Authentication - Login flow for invitees