import { Response } from 'express'; import { PrismaClient } from '@prisma/client'; import { AuthRequest } from '../middleware/auth.middleware'; const prisma = new PrismaClient(); export const getEvents = async (req: AuthRequest, res: Response) => { try { const { page = 1, limit = 20, upcoming = 'true' } = req.query; const skip = (Number(page) - 1) * Number(limit); const where: any = { status: 'PUBLISHED' }; if (upcoming === 'true') { where.date = { gte: new Date() }; } const [events, total] = await Promise.all([ prisma.event.findMany({ where, skip, take: Number(limit), include: { creator: { include: { profile: true } }, participants: { where: { status: 'approved' }, include: { user: { include: { profile: true } } } } }, orderBy: { date: 'asc' } }), prisma.event.count({ where }) ]); res.json({ events, pagination: { page: Number(page), limit: Number(limit), total, pages: Math.ceil(total / Number(limit)) } }); } catch (error) { console.error('Erro ao buscar eventos:', error); res.status(500).json({ error: 'Erro ao buscar eventos' }); } }; export const getEvent = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const event = await prisma.event.findUnique({ where: { id }, include: { creator: { include: { profile: true } }, participants: { include: { user: { include: { profile: true } } } } } }); if (!event) { return res.status(404).json({ error: 'Evento não encontrado' }); } // Verificar se é privado e se o usuário tem acesso if (event.isPrivate && event.creatorId !== req.userId) { const isParticipant = event.participants.some( p => p.userId === req.userId && p.status === 'approved' ); if (!isParticipant) { return res.status(403).json({ error: 'Acesso negado' }); } } res.json(event); } catch (error) { console.error('Erro ao buscar evento:', error); res.status(500).json({ error: 'Erro ao buscar evento' }); } }; export const createEvent = async (req: AuthRequest, res: Response) => { try { const { title, description, date, endDate, location, city, state, address, maxParticipants, isPrivate, requiresApproval, tags, price } = req.body; let coverImage = null; if (req.file) { coverImage = `/uploads/photos/${req.file.filename}`; } const event = await prisma.event.create({ data: { creatorId: req.userId!, title, description, date: new Date(date), endDate: endDate ? new Date(endDate) : null, location, city, state, address, coverImage, maxParticipants: maxParticipants ? Number(maxParticipants) : null, isPrivate: isPrivate === 'true', requiresApproval: requiresApproval !== 'false', tags: tags ? JSON.parse(tags) : [], price: price ? parseFloat(price) : null, status: 'PUBLISHED' }, include: { creator: { include: { profile: true } } } }); res.status(201).json(event); } catch (error) { console.error('Erro ao criar evento:', error); res.status(500).json({ error: 'Erro ao criar evento' }); } }; export const updateEvent = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const event = await prisma.event.findUnique({ where: { id } }); if (!event) { return res.status(404).json({ error: 'Evento não encontrado' }); } if (event.creatorId !== req.userId) { return res.status(403).json({ error: 'Acesso negado' }); } const updateData: any = { ...req.body }; if (req.body.date) { updateData.date = new Date(req.body.date); } if (req.body.endDate) { updateData.endDate = new Date(req.body.endDate); } if (req.file) { updateData.coverImage = `/uploads/photos/${req.file.filename}`; } if (req.body.tags) { updateData.tags = JSON.parse(req.body.tags); } const updatedEvent = await prisma.event.update({ where: { id }, data: updateData, include: { creator: { include: { profile: true } }, participants: true } }); res.json(updatedEvent); } catch (error) { console.error('Erro ao atualizar evento:', error); res.status(500).json({ error: 'Erro ao atualizar evento' }); } }; export const deleteEvent = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const event = await prisma.event.findUnique({ where: { id } }); if (!event) { return res.status(404).json({ error: 'Evento não encontrado' }); } if (event.creatorId !== req.userId) { return res.status(403).json({ error: 'Acesso negado' }); } await prisma.event.delete({ where: { id } }); res.json({ message: 'Evento deletado com sucesso' }); } catch (error) { console.error('Erro ao deletar evento:', error); res.status(500).json({ error: 'Erro ao deletar evento' }); } }; export const joinEvent = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const { message } = req.body; const event = await prisma.event.findUnique({ where: { id }, include: { participants: true } }); if (!event) { return res.status(404).json({ error: 'Evento não encontrado' }); } // Verificar se já está participando const existing = await prisma.eventParticipant.findUnique({ where: { eventId_userId: { eventId: id, userId: req.userId! } } }); if (existing) { return res.status(400).json({ error: 'Você já está participando deste evento' }); } // Verificar limite de participantes if (event.maxParticipants) { const approvedCount = event.participants.filter(p => p.status === 'approved').length; if (approvedCount >= event.maxParticipants) { return res.status(400).json({ error: 'Evento lotado' }); } } const status = event.requiresApproval ? 'pending' : 'approved'; const participant = await prisma.eventParticipant.create({ data: { eventId: id, userId: req.userId!, status, message } }); // Notificar criador await prisma.notification.create({ data: { userId: event.creatorId, type: 'event', title: 'Nova Solicitação de Participação', message: `Alguém quer participar do seu evento: ${event.title}`, link: `/events/${id}` } }); res.status(201).json(participant); } catch (error) { console.error('Erro ao participar do evento:', error); res.status(500).json({ error: 'Erro ao participar do evento' }); } }; export const leaveEvent = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; await prisma.eventParticipant.deleteMany({ where: { eventId: id, userId: req.userId } }); res.json({ message: 'Você saiu do evento' }); } catch (error) { console.error('Erro ao sair do evento:', error); res.status(500).json({ error: 'Erro ao sair do evento' }); } }; export const updateParticipantStatus = async (req: AuthRequest, res: Response) => { try { const { id, participantId } = req.params; const { status } = req.body; const event = await prisma.event.findUnique({ where: { id } }); if (!event) { return res.status(404).json({ error: 'Evento não encontrado' }); } if (event.creatorId !== req.userId) { return res.status(403).json({ error: 'Apenas o criador pode aprovar participantes' }); } const participant = await prisma.eventParticipant.update({ where: { id: participantId }, data: { status } }); // Notificar participante await prisma.notification.create({ data: { userId: participant.userId, type: 'event', title: status === 'approved' ? 'Participação Aprovada' : 'Participação Rejeitada', message: `Sua participação no evento "${event.title}" foi ${status === 'approved' ? 'aprovada' : 'rejeitada'}`, link: `/events/${id}` } }); res.json(participant); } catch (error) { console.error('Erro ao atualizar status do participante:', error); res.status(500).json({ error: 'Erro ao atualizar status' }); } };