добавление открытия чужого профиля из карточки

This commit is contained in:
Professional 2025-05-24 01:46:38 +07:00
parent 3e15bcfba5
commit 95054071f4
6 changed files with 1112 additions and 3 deletions

View File

@ -335,6 +335,63 @@ const deletePhoto = async (req, res, next) => {
}
};
// @desc Получить профиль пользователя по ID (для просмотра чужих профилей)
// @route GET /api/users/:userId
// @access Private
const getUserById = async (req, res, next) => {
try {
const { userId } = req.params;
const currentUserId = req.user._id;
// Проверяем, что пользователь не запрашивает свой собственный профиль
// (для этого есть отдельный роут /auth/me)
if (currentUserId.equals(userId)) {
const error = new Error('Для получения своего профиля используйте /auth/me');
error.statusCode = 400;
return next(error);
}
// Находим пользователя по ID
const user = await User.findById(userId)
.select('name dateOfBirth gender bio photos location createdAt');
if (!user) {
const error = new Error('Пользователь не найден.');
error.statusCode = 404;
return next(error);
}
// Вычисляем возраст, если указана дата рождения
let age = null;
if (user.dateOfBirth) {
const birthDate = new Date(user.dateOfBirth);
const today = new Date();
age = today.getFullYear() - birthDate.getFullYear();
const m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
}
// Формируем ответ
const userProfile = {
_id: user._id,
name: user.name,
age: age,
gender: user.gender,
bio: user.bio,
photos: user.photos,
location: user.location,
memberSince: user.createdAt
};
res.status(200).json(userProfile);
} catch (error) {
console.error('[USER_CTRL] Ошибка при получении профиля пользователя:', error.message);
next(error);
}
};
module.exports = {
updateUserProfile,
@ -342,5 +399,5 @@ module.exports = {
uploadUserProfilePhoto,
setMainPhoto, // <--- Добавлено
deletePhoto, // <--- Добавлено
// getUserById,
getUserById, // <--- Добавлено
};

View File

@ -1,6 +1,6 @@
const express = require('express');
const router = express.Router();
const { updateUserProfile, getUsersForSwiping, uploadUserProfilePhoto, setMainPhoto, deletePhoto } = require('../controllers/userController');
const { updateUserProfile, getUsersForSwiping, uploadUserProfilePhoto, setMainPhoto, deletePhoto, getUserById } = require('../controllers/userController');
const { protect } = require('../middleware/authMiddleware'); // Нам нужен protect для защиты маршрута
const multer = require('multer'); // 1. Импортируем multer
const path = require('path'); // Может понадобиться для фильтрации файлов
@ -44,6 +44,6 @@ router.delete('/profile/photo/:photoId', protect, deletePhoto); // <--- Н
// Маршрут для получения профиля по ID (например, для просмотра чужих профилей, если это нужно)
// GET /api/users/:id
// router.get('/:id', protect, getUserById); // protect здесь может быть опционален или с другой логикой
router.get('/:userId', protect, getUserById); // <--- НОВЫЙ МАРШРУТ
module.exports = router;

View File

@ -43,6 +43,13 @@ const routes = [
component: () => import('../views/ChatView.vue'), // Мы создадим этот компонент позже
meta: { requiresAuth: true },
props: true // Позволяет передавать :conversationId как пропс в компонент
},
{
path: '/user/:userId', // Просмотр профиля пользователя
name: 'UserProfile',
component: () => import('../views/UserProfileView.vue'),
meta: { requiresAuth: true },
props: true // Позволяет передавать :userId как пропс в компонент
}
// ... здесь будут другие маршруты: /profile, /swipe, /chat/:id и т.д.
];

View File

@ -106,5 +106,10 @@ export default {
},
editMessage(conversationId, messageId, newText) {
return apiClient.put(`/conversations/${conversationId}/messages/${messageId}`, { text: newText });
},
// Новый метод для получения профиля пользователя по ID
getUserById(userId) {
return apiClient.get(`/users/${userId}`);
}
};

View File

@ -52,6 +52,8 @@
@touchstart="index === 0 ? startTouch($event) : null"
@touchmove="index === 0 ? moveTouch($event) : null"
@touchend="index === 0 ? endTouch($event) : null"
@mousedown="index === 0 ? startDrag($event) : null"
@click="index === 0 ? handleCardClick($event, user) : null"
>
<!-- Photo Section -->
<div class="card-photo-section">
@ -509,6 +511,33 @@ const endDrag = () => {
document.removeEventListener('mouseup', endDrag);
};
// Обработчик клика на карточку
const handleCardClick = (event, user) => {
// Проверяем, что это был именно клик, а не завершение drag/swipe операции
const dragDuration = Date.now() - dragStartTime.value;
const totalMovement = Math.sqrt(
Math.pow(dragOffset.value.x || 0, 2) + Math.pow(dragOffset.value.y || 0, 2)
);
// Если было реальное перетаскивание или долгое удержание, не обрабатываем как клик
if (hasActuallyMoved.value || totalMovement > 10 || dragDuration > 300) {
console.log('[SwipeView] Клик проигнорирован - было перетаскивание');
return;
}
// Проверяем, что клик не был на элементах управления каруселью
if (event.target.closest('.carousel-nav') ||
event.target.closest('.carousel-dots') ||
event.target.closest('.dot')) {
console.log('[SwipeView] Клик на элементах управления каруселью - не открываем профиль');
return;
}
// Открываем полный профиль пользователя
console.log('[SwipeView] Открытие профиля пользователя:', user.name, user._id);
router.push(`/user/${user._id}`);
};
// Основные функции
const fetchSuggestions = async () => {
loading.value = true;

File diff suppressed because it is too large Load Diff