feat: track event participation and show joined events first
Backend: - Add EventParticipant model to track user-event participation - Create database migration for event_participants table - Record participation when user joins event chat via Socket.IO - Update GET /api/events to include isJoined flag for current user - Sort events: joined events first, then by start date - Add authenticate middleware to GET /api/events Frontend: - Replace mock events with real API data from backend - Add loading and error states to EventsPage - Display "Joined" badge on events user has joined - Highlight joined events with colored border - Show "Open chat" vs "Join chat" button text - Auto-refresh events list when navigating back When users join an event chat, this is now recorded in the database. Joined events appear at the top of the list with visual indicators.
This commit is contained in:
@@ -5,12 +5,12 @@ const { authenticate } = require('../middleware/auth');
|
||||
const router = express.Router();
|
||||
|
||||
// GET /api/events - List all events
|
||||
router.get('/', async (req, res, next) => {
|
||||
router.get('/', authenticate, async (req, res, next) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
|
||||
// Fetch all events with participation info
|
||||
const events = await prisma.event.findMany({
|
||||
orderBy: {
|
||||
startDate: 'asc',
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
@@ -21,13 +21,46 @@ router.get('/', async (req, res, next) => {
|
||||
participantsCount: true,
|
||||
description: true,
|
||||
createdAt: true,
|
||||
participants: {
|
||||
where: {
|
||||
userId: userId,
|
||||
},
|
||||
select: {
|
||||
joinedAt: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Transform data and add isJoined flag
|
||||
const eventsWithJoinedStatus = events.map(event => ({
|
||||
id: event.id,
|
||||
name: event.name,
|
||||
location: event.location,
|
||||
startDate: event.startDate,
|
||||
endDate: event.endDate,
|
||||
worldsdcId: event.worldsdcId,
|
||||
participantsCount: event.participantsCount,
|
||||
description: event.description,
|
||||
createdAt: event.createdAt,
|
||||
isJoined: event.participants.length > 0,
|
||||
joinedAt: event.participants[0]?.joinedAt || null,
|
||||
}));
|
||||
|
||||
// Sort: joined events first, then by start date
|
||||
eventsWithJoinedStatus.sort((a, b) => {
|
||||
// First, sort by joined status (joined events first)
|
||||
if (a.isJoined && !b.isJoined) return -1;
|
||||
if (!a.isJoined && b.isJoined) return 1;
|
||||
|
||||
// Then sort by start date
|
||||
return new Date(a.startDate) - new Date(b.startDate);
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
count: events.length,
|
||||
data: events,
|
||||
count: eventsWithJoinedStatus.length,
|
||||
data: eventsWithJoinedStatus,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
@@ -61,6 +61,21 @@ function initializeSocket(httpServer) {
|
||||
socket.currentEventRoom = roomName;
|
||||
socket.currentEventId = eventId;
|
||||
|
||||
// Record event participation in database
|
||||
await prisma.eventParticipant.upsert({
|
||||
where: {
|
||||
userId_eventId: {
|
||||
userId: socket.user.id,
|
||||
eventId: parseInt(eventId),
|
||||
},
|
||||
},
|
||||
update: {}, // Don't update anything if already exists
|
||||
create: {
|
||||
userId: socket.user.id,
|
||||
eventId: parseInt(eventId),
|
||||
},
|
||||
});
|
||||
|
||||
// Add user to active users
|
||||
if (!activeUsers.has(eventId)) {
|
||||
activeUsers.set(eventId, new Set());
|
||||
|
||||
Reference in New Issue
Block a user