diff --git a/src/views/ProfileView.vue b/src/views/ProfileView.vue index db01154..818afa8 100644 --- a/src/views/ProfileView.vue +++ b/src/views/ProfileView.vue @@ -419,8 +419,6 @@ const mainPhoto = computed(() => { const toggleEditMode = async () => { // Если сейчас в режиме редактирования и пользователь хочет вернуться в режим просмотра if (isEditMode.value) { - console.log('[ProfileView] Выход из режима редактирования'); - try { // Проверяем, были ли изменения const hasChanges = checkForChanges(); @@ -428,7 +426,7 @@ const toggleEditMode = async () => { if (hasChanges) { console.log('[ProfileView] Сохранение изменений...'); - profileLoading.value = true; // Используем только profileLoading для индикации + profileLoading.value = true; // Устанавливаем индикатор загрузки формы // Подготавливаем данные для отправки на сервер const dataToUpdate = { ...editableProfileData.value }; @@ -436,9 +434,8 @@ const toggleEditMode = async () => { // Обрабатываем дату рождения if (dataToUpdate.dateOfBirth) { try { - // Получаем дату в формате ISO с поправкой на часовой пояс const dateObj = new Date(dataToUpdate.dateOfBirth); - if (!isNaN(dateObj.getTime())) { // Проверяем, что дата валидна + if (!isNaN(dateObj.getTime())) { dataToUpdate.dateOfBirth = dateObj.toISOString(); } } catch (e) { @@ -448,12 +445,31 @@ const toggleEditMode = async () => { // Отправляем запрос на сервер const response = await api.updateUserProfile(dataToUpdate); - console.log('[ProfileView] Ответ от сервера (профиль):', response.data); + console.log('[ProfileView] Профиль успешно обновлен:', response.data); - // Обновляем локальные данные напрямую, без вызова fetchUser - profileData.value = { ...profileData.value, ...dataToUpdate }; + // Обновляем локальный profileData напрямую, не вызывая fetchUser() + profileData.value = { + ...profileData.value, + name: dataToUpdate.name, + bio: dataToUpdate.bio, + dateOfBirth: dataToUpdate.dateOfBirth, + gender: dataToUpdate.gender, + location: dataToUpdate.location + }; + + // Обновляем authUserFromStore напрямую, если он доступен + if (authUserFromStore.value) { + // Копируем новые данные в хранилище авторизации + authUserFromStore.value = { + ...authUserFromStore.value, + name: dataToUpdate.name, + bio: dataToUpdate.bio, + dateOfBirth: dataToUpdate.dateOfBirth, + gender: dataToUpdate.gender, + location: dataToUpdate.location + }; + } - // Показываем сообщение об успешном сохранении profileActionSuccess.value = 'Профиль успешно обновлен!'; // Автоматически скрываем сообщение через 3 секунды @@ -468,28 +484,25 @@ const toggleEditMode = async () => { profileActionError.value = err.response?.data?.message || 'Произошла ошибка при обновлении профиля. Пожалуйста, попробуйте позже.'; } finally { - // В любом случае переключаемся в режим просмотра и сбрасываем состояние загрузки + // Переключаемся в режим просмотра и сбрасываем состояние загрузки isEditMode.value = false; profileLoading.value = false; - clearProfileMessages(); + // Гарантированно сбрасываем индикаторы загрузки + loading.value = false; + initialLoading.value = false; } } else { - // Если сейчас в режиме просмотра и пользователь хочет перейти в режим редактирования - console.log('[ProfileView] Вход в режим редактирования'); - // Переключаемся в режим редактирования isEditMode.value = true; // Копируем данные профиля в редактируемый объект - // Преобразуем формат даты из ISO в yyyy-MM-dd let formattedDate = ''; if (profileData.value && profileData.value.dateOfBirth) { try { const date = new Date(profileData.value.dateOfBirth); - formattedDate = date.toISOString().split('T')[0]; // Получаем только yyyy-MM-dd часть + formattedDate = date.toISOString().split('T')[0]; } catch (e) { console.error('[ProfileView] Ошибка форматирования даты:', e); - formattedDate = ''; } } @@ -499,22 +512,20 @@ const toggleEditMode = async () => { dateOfBirth: formattedDate, gender: profileData.value?.gender || '', location: { - city: profileData.value?.location?.city || '', + city: profileData.value?.location?.city || '' } }; - // Важно! Сохраняем JSON-копию оригинальных данных для последующего сравнения + // Сохраняем копию для сравнения originalProfileData = JSON.stringify(editableProfileData.value); - console.log('[ProfileView] Сохранены оригинальные данные для сравнения:', originalProfileData); - // Устанавливаем поисковый запрос города + // Устанавливаем поля поиска if (profileData.value?.location?.city) { citySearchQuery.value = profileData.value.location.city; } else { citySearchQuery.value = ''; } - // Устанавливаем поисковый запрос пола if (profileData.value?.gender) { const genderOption = genderOptions.value.find(option => option.value === profileData.value.gender); if (genderOption) { @@ -664,7 +675,8 @@ const uploadPhotos = async (files) => { let errorCount = 0; photoActionLoading.value = true; clearMessages(); - try { + + try { let imageCompression; try { // Импортируем библиотеку для сжатия изображений динамически @@ -702,10 +714,37 @@ const uploadPhotos = async (files) => { // Увеличиваем счетчик успешных загрузок successCount++; - // Обновляем данные пользователя после каждой успешной загрузки - await fetchUser(); + // Вместо вызова fetchUser, получаем данные напрямую и обновляем локальный profileData + if (response.data && response.data.photos) { + // Обновляем фотографии в локальном profileData + profileData.value = { + ...profileData.value, + photos: response.data.photos + }; + + // Обновляем глобальный authUserFromStore + if (authUserFromStore.value) { + authUserFromStore.value = { + ...authUserFromStore.value, + photos: response.data.photos + }; + } + } else { + // Если по какой-то причине фотографий нет в ответе, сделаем отдельный запрос + // для получения обновленных данных пользователя, но не через fetchUser + const userResponse = await api.getMe(); + if (userResponse.data) { + profileData.value = userResponse.data; + + // Также обновим глобальное хранилище + if (authUserFromStore.value) { + authUserFromStore.value = userResponse.data; + } + } + } + console.log(`[ProfileView] Данные пользователя обновлены после загрузки фото ${originalFile.name}`); - } catch (err) { + } catch (err) { console.error(`[ProfileView] Ошибка при сжатии или загрузке фото ${originalFile.name}:`, err); errorCount++; @@ -714,6 +753,8 @@ const uploadPhotos = async (files) => { photoActionError.value = 'Ошибка сети при загрузке фото. Пожалуйста, проверьте подключение к интернету.'; } else if (err.response && err.response.status === 413) { photoActionError.value = 'Файл слишком большой. Пожалуйста, выберите фото меньшего размера.'; + } else { + photoActionError.value = 'Произошла ошибка при загрузке фото'; } } } @@ -809,14 +850,19 @@ const setAsMainPhoto = async (photoId) => { // Обновляем локальные данные сразу для быстрого отклика if (profileData.value && profileData.value.photos) { + // Сначала сбрасываем флаг isProfilePhoto для всех фото profileData.value.photos.forEach(photo => { photo.isProfilePhoto = photo._id === photoId; }); + + // Обновляем данные и в глобальном хранилище если оно доступно + if (authUserFromStore.value && authUserFromStore.value.photos) { + authUserFromStore.value.photos.forEach(photo => { + photo.isProfilePhoto = photo._id === photoId; + }); + } } - // Затем получаем актуальные данные с сервера - await fetchUser(); - photoActionSuccess.value = response.data.message || 'Главное фото обновлено.'; // Автоматически скрываем сообщение через 3 секунды @@ -861,11 +907,15 @@ const executeDeletePhoto = async () => { profileData.value.photos = profileData.value.photos.filter( photo => photo._id !== photoToDeleteId.value ); + + // Также обновляем глобальное хранилище + if (authUserFromStore.value && authUserFromStore.value.photos) { + authUserFromStore.value.photos = authUserFromStore.value.photos.filter( + photo => photo._id !== photoToDeleteId.value + ); + } } - // Затем получаем актуальные данные с сервера - await fetchUser(); - photoActionSuccess.value = response.data.message || 'Фотография удалена.'; closeDeleteModal();