- Add YouTube, Instagram, Facebook, and TikTok URL fields to User model - Create database migration for social media link columns - Add custom validators to ensure URLs contain correct domains - Update profile page with social media input fields - Include social media URLs in GET /api/users/me response - Add icons for each social platform in the UI Users can now add links to their social media profiles. Each field validates that the URL contains the appropriate domain (e.g., instagram.com for Instagram, youtube.com/youtu.be for YouTube).
83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
const express = require('express');
|
|
const { authenticate } = require('../middleware/auth');
|
|
const { prisma } = require('../utils/db');
|
|
const { updateProfile, changePassword } = require('../controllers/user');
|
|
const { updateProfileValidation, changePasswordValidation } = require('../middleware/validators');
|
|
|
|
const router = express.Router();
|
|
|
|
// GET /api/users/me - Get current authenticated user
|
|
router.get('/me', authenticate, async (req, res, next) => {
|
|
try {
|
|
// req.user is set by authenticate middleware
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: req.user.id },
|
|
select: {
|
|
id: true,
|
|
username: true,
|
|
email: true,
|
|
emailVerified: true,
|
|
firstName: true,
|
|
lastName: true,
|
|
wsdcId: true,
|
|
youtubeUrl: true,
|
|
instagramUrl: true,
|
|
facebookUrl: true,
|
|
tiktokUrl: true,
|
|
avatar: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
_count: {
|
|
select: {
|
|
matchesAsUser1: true,
|
|
matchesAsUser2: true,
|
|
ratingsReceived: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!user) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
error: 'User not found',
|
|
});
|
|
}
|
|
|
|
// Calculate total matches
|
|
const totalMatches = user._count.matchesAsUser1 + user._count.matchesAsUser2;
|
|
|
|
// Calculate average rating
|
|
const ratings = await prisma.rating.findMany({
|
|
where: { ratedId: user.id },
|
|
select: { score: true },
|
|
});
|
|
|
|
const averageRating = ratings.length > 0
|
|
? ratings.reduce((sum, r) => sum + r.score, 0) / ratings.length
|
|
: 0;
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
...user,
|
|
stats: {
|
|
matchesCount: totalMatches,
|
|
ratingsCount: user._count.ratingsReceived,
|
|
rating: averageRating.toFixed(1),
|
|
},
|
|
},
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
// PATCH /api/users/me - Update user profile
|
|
router.patch('/me', authenticate, updateProfileValidation, updateProfile);
|
|
|
|
// PATCH /api/users/me/password - Change password
|
|
router.patch('/me/password', authenticate, changePasswordValidation, changePassword);
|
|
|
|
module.exports = router;
|