bugfix
This commit is contained in:
@@ -1,63 +1,58 @@
|
||||
import express from 'express';
|
||||
import { query } from '../db/index.js';
|
||||
import { authMiddleware } from '../middleware/auth.js';
|
||||
import { asyncHandler, AppError } from '../middleware/errorHandler.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all challenges for the current user
|
||||
router.get('/', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const challenges = await query(
|
||||
`SELECT
|
||||
c.*,
|
||||
u.username as creator_username,
|
||||
cp.status as participation_status,
|
||||
(SELECT COUNT(*) FROM predictions WHERE challenge_id = c.id AND status = 'validated' AND user_id = ?) as my_points
|
||||
FROM challenges c
|
||||
INNER JOIN users u ON c.created_by = u.id
|
||||
LEFT JOIN challenge_participants cp ON cp.challenge_id = c.id AND cp.user_id = ?
|
||||
WHERE c.created_by = ? OR cp.user_id IS NOT NULL
|
||||
ORDER BY c.created_at DESC`,
|
||||
[req.user.userId, req.user.userId, req.user.userId]
|
||||
);
|
||||
router.get('/', authMiddleware, asyncHandler(async (req, res) => {
|
||||
const challenges = await query(
|
||||
`SELECT
|
||||
c.*,
|
||||
u.username as creator_username,
|
||||
cp.status as participation_status,
|
||||
(SELECT COUNT(*) FROM predictions WHERE challenge_id = c.id AND status = 'validated' AND user_id = ?) as my_points
|
||||
FROM challenges c
|
||||
INNER JOIN users u ON c.created_by = u.id
|
||||
LEFT JOIN challenge_participants cp ON cp.challenge_id = c.id AND cp.user_id = ?
|
||||
WHERE c.created_by = ? OR cp.user_id IS NOT NULL
|
||||
ORDER BY c.created_at DESC`,
|
||||
[req.user.userId, req.user.userId, req.user.userId]
|
||||
);
|
||||
|
||||
res.json({ challenges });
|
||||
} catch (error) {
|
||||
console.error('Get challenges error:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch challenges' });
|
||||
}
|
||||
});
|
||||
res.json({ challenges });
|
||||
}));
|
||||
|
||||
// Get a single challenge with details
|
||||
router.get('/:id', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const challengeId = req.params.id;
|
||||
router.get('/:id', authMiddleware, asyncHandler(async (req, res) => {
|
||||
const challengeId = req.params.id;
|
||||
|
||||
// Get challenge details
|
||||
const challenges = await query(
|
||||
`SELECT c.*, u.username as creator_username
|
||||
FROM challenges c
|
||||
INNER JOIN users u ON c.created_by = u.id
|
||||
WHERE c.id = ?`,
|
||||
[challengeId]
|
||||
);
|
||||
// Get challenge details
|
||||
const challenges = await query(
|
||||
`SELECT c.*, u.username as creator_username
|
||||
FROM challenges c
|
||||
INNER JOIN users u ON c.created_by = u.id
|
||||
WHERE c.id = ?`,
|
||||
[challengeId]
|
||||
);
|
||||
|
||||
if (challenges.length === 0) {
|
||||
return res.status(404).json({ error: 'Challenge not found' });
|
||||
}
|
||||
if (challenges.length === 0) {
|
||||
throw new AppError('Challenge not found', 404);
|
||||
}
|
||||
|
||||
const challenge = challenges[0];
|
||||
const challenge = challenges[0];
|
||||
|
||||
// Check if user has access
|
||||
const access = await query(
|
||||
`SELECT * FROM challenge_participants
|
||||
WHERE challenge_id = ? AND user_id = ? AND status = 'accepted'`,
|
||||
[challengeId, req.user.userId]
|
||||
);
|
||||
// Check if user has access
|
||||
const access = await query(
|
||||
`SELECT * FROM challenge_participants
|
||||
WHERE challenge_id = ? AND user_id = ? AND status = 'accepted'`,
|
||||
[challengeId, req.user.userId]
|
||||
);
|
||||
|
||||
if (challenge.created_by !== req.user.userId && access.length === 0) {
|
||||
return res.status(403).json({ error: 'Access denied' });
|
||||
}
|
||||
if (challenge.created_by !== req.user.userId && access.length === 0) {
|
||||
throw new AppError('Access denied', 403);
|
||||
}
|
||||
|
||||
// Get participants with their points
|
||||
const participants = await query(
|
||||
@@ -79,25 +74,20 @@ router.get('/:id', authMiddleware, async (req, res) => {
|
||||
[challengeId, challenge.created_by]
|
||||
);
|
||||
|
||||
res.json({
|
||||
challenge,
|
||||
participants,
|
||||
creator_points: creatorPoints[0].points
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Get challenge error:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch challenge' });
|
||||
}
|
||||
});
|
||||
res.json({
|
||||
challenge,
|
||||
participants,
|
||||
creator_points: creatorPoints[0].points
|
||||
});
|
||||
}));
|
||||
|
||||
// Create a new challenge
|
||||
router.post('/', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const { title, cover_image_url, tmdb_id, media_type } = req.body;
|
||||
router.post('/', authMiddleware, asyncHandler(async (req, res) => {
|
||||
const { title, cover_image_url, tmdb_id, media_type } = req.body;
|
||||
|
||||
if (!title) {
|
||||
return res.status(400).json({ error: 'Title is required' });
|
||||
}
|
||||
if (!title) {
|
||||
throw new AppError('Title is required', 400);
|
||||
}
|
||||
|
||||
const result = await query(
|
||||
'INSERT INTO challenges (title, cover_image_url, tmdb_id, media_type, created_by) VALUES (?, ?, ?, ?, ?)',
|
||||
@@ -114,42 +104,37 @@ router.post('/', authMiddleware, async (req, res) => {
|
||||
creator_username: req.user.username
|
||||
};
|
||||
|
||||
res.json({ challenge });
|
||||
} catch (error) {
|
||||
console.error('Create challenge error:', error);
|
||||
res.status(500).json({ error: 'Failed to create challenge' });
|
||||
}
|
||||
});
|
||||
res.json({ challenge });
|
||||
}));
|
||||
|
||||
// Invite users to a challenge
|
||||
router.post('/:id/invite', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const challengeId = req.params.id;
|
||||
const { user_ids, emails } = req.body;
|
||||
router.post('/:id/invite', authMiddleware, asyncHandler(async (req, res) => {
|
||||
const challengeId = req.params.id;
|
||||
const { user_ids, emails } = req.body;
|
||||
|
||||
// Verify user owns the challenge or is a participant
|
||||
const challenges = await query(
|
||||
'SELECT * FROM challenges WHERE id = ?',
|
||||
[challengeId]
|
||||
// Verify user owns the challenge or is a participant
|
||||
const challenges = await query(
|
||||
'SELECT * FROM challenges WHERE id = ?',
|
||||
[challengeId]
|
||||
);
|
||||
|
||||
if (challenges.length === 0) {
|
||||
throw new AppError('Challenge not found', 404);
|
||||
}
|
||||
|
||||
const challenge = challenges[0];
|
||||
|
||||
if (challenge.created_by !== req.user.userId) {
|
||||
// Check if user is an accepted participant
|
||||
const participation = await query(
|
||||
'SELECT * FROM challenge_participants WHERE challenge_id = ? AND user_id = ? AND status = "accepted"',
|
||||
[challengeId, req.user.userId]
|
||||
);
|
||||
|
||||
if (challenges.length === 0) {
|
||||
return res.status(404).json({ error: 'Challenge not found' });
|
||||
}
|
||||
|
||||
const challenge = challenges[0];
|
||||
|
||||
if (challenge.created_by !== req.user.userId) {
|
||||
// Check if user is an accepted participant
|
||||
const participation = await query(
|
||||
'SELECT * FROM challenge_participants WHERE challenge_id = ? AND user_id = ? AND status = "accepted"',
|
||||
[challengeId, req.user.userId]
|
||||
);
|
||||
|
||||
if (participation.length === 0) {
|
||||
return res.status(403).json({ error: 'Only challenge participants can invite others' });
|
||||
}
|
||||
if (participation.length === 0) {
|
||||
throw new AppError('Only challenge participants can invite others', 403);
|
||||
}
|
||||
}
|
||||
|
||||
const invitedUsers = [];
|
||||
|
||||
@@ -186,33 +171,24 @@ router.post('/:id/invite', authMiddleware, async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
res.json({ invited: invitedUsers.length });
|
||||
} catch (error) {
|
||||
console.error('Invite error:', error);
|
||||
res.status(500).json({ error: 'Failed to send invites' });
|
||||
}
|
||||
});
|
||||
res.json({ invited: invitedUsers.length });
|
||||
}));
|
||||
|
||||
// Accept/reject challenge invitation
|
||||
router.post('/:id/respond', authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const challengeId = req.params.id;
|
||||
const { status } = req.body; // 'accepted' or 'rejected'
|
||||
router.post('/:id/respond', authMiddleware, asyncHandler(async (req, res) => {
|
||||
const challengeId = req.params.id;
|
||||
const { status } = req.body; // 'accepted' or 'rejected'
|
||||
|
||||
if (!['accepted', 'rejected'].includes(status)) {
|
||||
return res.status(400).json({ error: 'Invalid status' });
|
||||
}
|
||||
|
||||
await query(
|
||||
'UPDATE challenge_participants SET status = ?, responded_at = NOW() WHERE challenge_id = ? AND user_id = ?',
|
||||
[status, challengeId, req.user.userId]
|
||||
);
|
||||
|
||||
res.json({ status });
|
||||
} catch (error) {
|
||||
console.error('Respond error:', error);
|
||||
res.status(500).json({ error: 'Failed to respond to invitation' });
|
||||
if (!['accepted', 'rejected'].includes(status)) {
|
||||
throw new AppError('Invalid status', 400);
|
||||
}
|
||||
});
|
||||
|
||||
await query(
|
||||
'UPDATE challenge_participants SET status = ?, responded_at = NOW() WHERE challenge_id = ? AND user_id = ?',
|
||||
[status, challengeId, req.user.userId]
|
||||
);
|
||||
|
||||
res.json({ status });
|
||||
}));
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user