Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,27 @@ DevConnect is a full-stack web application that enables developers to:
- 📁 **File Sharing** - Share images and files in conversations
- 🔔 **Live Notifications** - Real-time typing indicators and message notifications
- 👤 **User Presence** - See who's online and their status
- 📅 **Event Management** - Create, manage, and attend developer events and meetups
- 🎟️ **Event Registration** - RSVP system with attendance tracking
- 🌐 **Virtual Events** - Support for online events with meeting links
- 📸 **Event Detail Pages** - Beautiful, comprehensive event pages with banner images and rich details
- 📊 **Real-time Event Stats** - Live updating event statistics and attendee information
- 🎨 **Modern UI** - Dark theme with cyan accents, professional design
- 📱 **Responsive Design** - Works on desktop and mobile

### Event Management Features
- 📅 **Event Creation** - Create virtual or in-person events with detailed information
- 🎟️ **Three-Tier Attendance System**:
- ✅ **Going** - Confirmed attendance
- 🤔 **Maybe** - Tentative interest
- ❌ **Not Attending** - Declined participation
- 👥 **Capacity Management** - Set maximum attendees with real-time capacity tracking
- 📊 **Visual Capacity Indicators** - Progress bars and percentage displays
- 🚫 **Automatic Full-Event Handling** - Prevents over-registration
- 📸 **Rich Event Detail Pages** - Comprehensive event pages with banner images and stats
- 🌐 **Virtual Event Support** - Online events with meeting links (Zoom, Teams, etc.)
- 📍 **Physical Event Support** - In-person events with location details
- 🔔 **Event Notifications** - Toast notifications for registration success/errors
- 📤 **Share Events** - Native share API integration with clipboard fallback
- 🎯 **Smart Registration** - Authentication checks and capacity validation
- 📅 **Past Event Handling** - Automatic disabling of registration for ended events
- 👤 **Attendee Lists** - View all registered attendees with status indicators

## 📁 Project Structure

```
Expand Down
90 changes: 89 additions & 1 deletion docs/EVENT_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,92 @@ const { data, error } = await supabase
.gte('event_date', startDate)
.contains('tags', [tag])
.or(`title.ilike.%${query}%,description.ilike.%${query}%`);
```
```## Event Attendance Management

### Register/Update Attendance Status
```typescript
// Register or update attendance with specific status
const { data, error } = await supabase
.from('EventAttendees')
.upsert({
event_id: eventId,
user_id: user.id,
status: 'attending' // 'attending' | 'maybe' | 'not_attending'
}, {
onConflict: 'event_id,user_id'
})
.select()
.single();
```

### Get User's Current Attendance Status
```typescript
const { data, error } = await supabase
.from('EventAttendees')
.select('status')
.eq('event_id', eventId)
.eq('user_id', user.id)
.maybeSingle();

// Returns: { status: 'attending' | 'maybe' | 'not_attending' } or null
```

### Check Event Capacity Before Registration
```typescript
// Validate if event is full before allowing registration
const { data: event, error } = await supabase
.from('Events')
.select('max_attendees, EventAttendees(count)')
.eq('id', eventId)
.single();

const attendeeCount = event.EventAttendees?.[0]?.count || 0;
const isFull = event.max_attendees && attendeeCount >= event.max_attendees;

if (isFull) {
throw new Error('Event is at full capacity');
}
```

### Get Event with Attendance Details
```typescript
// Fetch event with all attendees and user's status
const { data, error } = await supabase
.from('Events')
.select(
*,
Communities(name),
EventAttendees(id, user_id, status, registered_at)
)
.eq('id', eventId)
.single();

// Calculate attendee count
const attendeeCount = data.EventAttendees.length;

// Find current user's attendance
const userAttendance = data.EventAttendees.find(
a => a.user_id === currentUserId
);
```

### Cancel Event Registration
```typescript
// Remove user from event attendees
const { error } = await supabase
.from('EventAttendees')
.delete()
.eq('event_id', eventId)
.eq('user_id', user.id);
```

### Get Attendees by Status
```typescript
// Get all confirmed attendees
const { data, error } = await supabase
.from('EventAttendees')
.select('*, user:auth.users(id, email, user_metadata)')
.eq('event_id', eventId)
.eq('status', 'attending')
.order('registered_at', { ascending: true });
```
63 changes: 62 additions & 1 deletion docs/EVENT_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,65 @@ export const CreateEventPage = () => {
</div>
);
};
```
```
## Event Attendance Hooks

### useEventAttendance Hook
Manages event registration and attendance status updates with optimistic UI updates and proper error handling.

```typescript
export const useEventAttendance = () => {
const { user } = useAuth();
const queryClient = useQueryClient();

const register = useMutation({
mutationFn: async ({
eventId,
status
}: {
eventId: number;
status: 'attending' | 'maybe' | 'not_attending'
}) => {
if (!user) throw new Error('User not authenticated');

const { data, error } = await supabase
.from('EventAttendees')
.upsert({
event_id: eventId,
user_id: user.id,
status
}, {
onConflict: 'event_id,user_id'
})
.select()
.single();

if (error) throw error;
return data;
},
onSuccess: (_, { eventId }) => {
queryClient.invalidateQueries({ queryKey: ['event', eventId] });
queryClient.invalidateQueries({ queryKey: ['events'] });
}
});

return { register, isRegistering: register.isPending };
};
```

### Usage in EventDetailPage
```typescript
const { register, isRegistering } = useEventAttendance();

const handleAttendance = (status: 'attending' | 'maybe' | 'not_attending') => {
if (!user) {
showError('Please sign in to register for events');
return;
}

register({ eventId, status }, {
onSuccess: () => showSuccess('You are now ' + status + ' this event'),
onError: (error) => showError(error.message || 'Failed to register')
});
};
```
Loading