feat: add country and city fields to user profile

- Add country and city fields to User model
- Create database migration for location fields
- Add validation for country and city (max 100 characters)
- Create countries.js with complete list of 195 countries
- Add country dropdown select and city text input to profile page
- Include country and city in GET /api/users/me response
- Update profile form to support location data

Users can now select their country from a dropdown list of all
countries and enter their city name.
This commit is contained in:
Radosław Gierwiało
2025-11-13 20:57:43 +01:00
parent 48f9dfe1b4
commit 144b13a0cf
7 changed files with 276 additions and 2 deletions

View File

@@ -10,7 +10,7 @@ const { sanitizeForEmail } = require('../utils/sanitize');
async function updateProfile(req, res, next) {
try {
const userId = req.user.id;
const { firstName, lastName, email, wsdcId, youtubeUrl, instagramUrl, facebookUrl, tiktokUrl } = req.body;
const { firstName, lastName, email, wsdcId, youtubeUrl, instagramUrl, facebookUrl, tiktokUrl, country, city } = req.body;
// Build update data
const updateData = {};
@@ -21,6 +21,8 @@ async function updateProfile(req, res, next) {
if (instagramUrl !== undefined) updateData.instagramUrl = instagramUrl || null;
if (facebookUrl !== undefined) updateData.facebookUrl = facebookUrl || null;
if (tiktokUrl !== undefined) updateData.tiktokUrl = tiktokUrl || null;
if (country !== undefined) updateData.country = country || null;
if (city !== undefined) updateData.city = city || null;
// Check if email is being changed
const currentUser = await prisma.user.findUnique({

View File

@@ -168,6 +168,16 @@ const updateProfileValidation = [
return value.includes('tiktok.com');
})
.withMessage('Must be a valid TikTok URL (tiktok.com)'),
body('country')
.optional()
.trim()
.isLength({ max: 100 })
.withMessage('Country must be less than 100 characters'),
body('city')
.optional()
.trim()
.isLength({ max: 100 })
.withMessage('City must be less than 100 characters'),
handleValidationErrors,
];

View File

@@ -24,6 +24,8 @@ router.get('/me', authenticate, async (req, res, next) => {
instagramUrl: true,
facebookUrl: true,
tiktokUrl: true,
country: true,
city: true,
avatar: true,
createdAt: true,
updatedAt: true,