✨ feat(src/composables/useFeed.ts): добавляет поддержку бесконечной прокрутки для ленты новостей
✨ feat(package.json): добавляет скрипт для генерации спрайта и обновляет зависимости 🔧 refactor(src/composables/useChat.ts): упрощает логику управления чатом, убирает устаревшие функции 🔧 refactor(src/views/chat/ChatRoomView.vue): обновляет логику загрузки сообщений с использованием новых хуков 🔧 refactor(src/views/matches/MatchesView.vue): улучшает обработку совпадений с использованием новых хуков ✨ feat(src/App.vue): добавляет загрузку справочных данных с использованием Vue Query ✨ feat(src/main.ts): интегрирует Vue Query в приложение для управления состоянием запросов ✨ feat(src/views/profile/MyProfileView.vue): добавляет мутацию для удаления профиля с использованием Vue Query 🔧 refactor(src/components/layout/BottomNav.vue): заменяет компонент иконки на более универсальный компонент AppIcon
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<h1 class="matches-view__title">
|
||||
Совпадения
|
||||
</h1>
|
||||
<span class="meta">{{ matches.length }} {{ matches.length === 1 ? 'человек' : 'людей' }}</span>
|
||||
<span class="meta">{{ (matches ?? []).length }} {{ (matches ?? []).length === 1 ? 'человек' : 'людей' }}</span>
|
||||
</header>
|
||||
|
||||
<div v-if="loading" class="matches-view__loading">
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
|
||||
<EmptyState
|
||||
v-else-if="matches.length === 0"
|
||||
v-else-if="(matches ?? []).length === 0"
|
||||
title="Пока нет совпадений"
|
||||
description="Ставьте лайки, чтобы находить тех, кто ответит взаимностью"
|
||||
icon="heart"
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<div v-else class="matches-list">
|
||||
<article
|
||||
v-for="match in matches"
|
||||
v-for="match in (matches ?? [])"
|
||||
:key="match.id"
|
||||
class="match-card"
|
||||
>
|
||||
@@ -61,26 +61,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { MatchDto, ProfileResponseDto } from '@/api/api'
|
||||
import { apiClient } from '@/api/client'
|
||||
import AppButton from '@/components/common/AppButton.vue'
|
||||
import EmptyState from '@/components/common/EmptyState.vue'
|
||||
import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import { useChat } from '@/composables/useChat'
|
||||
import { useUi } from '@/composables/useUi'
|
||||
|
||||
type EnrichedMatch = MatchDto & { partnerProfile: ProfileResponseDto }
|
||||
import { useChatsQuery } from '@/queries/useChatsQuery'
|
||||
import { useMatchesQuery } from '@/queries/useMatchesQuery'
|
||||
import type { EnrichedMatch } from '@/queries/useMatchesQuery'
|
||||
|
||||
const authStore = useAuth()
|
||||
const chatStore = useChat()
|
||||
const uiStore = useUi()
|
||||
const router = useRouter()
|
||||
|
||||
const matches = ref<EnrichedMatch[]>([])
|
||||
const loading = ref(false)
|
||||
const profileId = computed(() => authStore.activeProfile?.id)
|
||||
|
||||
const { data: matches, isLoading: loading } = useMatchesQuery(profileId)
|
||||
const { openChat: openChatMutation } = useChatsQuery(profileId)
|
||||
|
||||
function calcAge(birthDate: string): number | undefined {
|
||||
const birth = new Date(birthDate)
|
||||
@@ -93,42 +92,14 @@ function calcAge(birthDate: string): number | undefined {
|
||||
return age
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const profileId = authStore.activeProfile?.id
|
||||
if (!profileId)
|
||||
return
|
||||
loading.value = true
|
||||
try {
|
||||
const matchDtos = await apiClient.api.likesControllerGetMyMatches({ profileId })
|
||||
matches.value = await Promise.all(
|
||||
matchDtos.map(async (m) => {
|
||||
const partnerProfileId = m.profile1Id === profileId ? m.profile2Id : m.profile1Id
|
||||
const partnerProfile = await apiClient.api.profilesControllerFindOne(partnerProfileId)
|
||||
return { ...m, partnerProfile }
|
||||
}),
|
||||
)
|
||||
}
|
||||
catch {
|
||||
uiStore.addToast('Не удалось загрузить совпадения', 'error')
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
async function openChat(match: EnrichedMatch) {
|
||||
const profileId = authStore.activeProfile?.id
|
||||
if (!profileId)
|
||||
return
|
||||
try {
|
||||
const chat = await chatStore.openChat(profileId, match.id)
|
||||
const chat = await openChatMutation.mutateAsync({ matchId: match.id })
|
||||
router.push(`/chats/${chat.id}`)
|
||||
}
|
||||
catch (err: unknown) {
|
||||
const msg = (err as { response?: { data?: { message?: string } } })
|
||||
?.response
|
||||
?.data
|
||||
?.message ?? 'Не удалось открыть чат'
|
||||
?.response?.data?.message ?? 'Не удалось открыть чат'
|
||||
uiStore.addToast(msg, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user