Skip to content

Group Invitations

Group Invitations enable admins to invite participants to Secret Santa groups through multiple channels: manual phone/email entry or shareable invitation links.

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.

  • ✅ 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:

  • Phone numbers or emails (array of strings)
  • Group ID (number)

Outputs:

  • Sent invitations with status
  • Shareable link: /invite/:sharedId
  • Invitation acceptance confirmation
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 list
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 dialog
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"

Request:

POST /groups/5/invite
Authorization: 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
}
]
}

Request:

GET /groups/shared/abc123xyz

Response:

{
"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
}
}

Request:

POST /groups/shared/abc123xyz/join
Authorization: Bearer {token}

Response:

{
"success": true,
"group": {
"id": 5,
"name": "Office Secret Santa",
...
}
}

Request:

DELETE /groups/5/invitation/10
Authorization: Bearer {token}

Response:

{
"success": true,
"message": "Invitation canceled"
}
  • 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”
src/sections/invitation/invite-view.tsx
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');
};