eslint --fix
This commit is contained in:
@@ -1,63 +1,3 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useAuth } from '@/composables/useAuth';
|
||||
import { useUi } from '@/composables/useUi';
|
||||
import { useChat } from '@/composables/useChat';
|
||||
import { apiClient } from '@/api/client';
|
||||
import type { UserProfile } from '@/composables/useAuth';
|
||||
import AppButton from '@/components/common/AppButton.vue';
|
||||
import AppModal from '@/components/common/AppModal.vue';
|
||||
import ReportModal from '@/components/reports/ReportModal.vue';
|
||||
import DateProposalForm from '@/components/dates/DateProposalForm.vue';
|
||||
import LoadingSpinner from '@/components/common/LoadingSpinner.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const authStore = useAuth();
|
||||
const uiStore = useUi();
|
||||
const chatStore = useChat();
|
||||
|
||||
const profileId = route.params.profileId as string;
|
||||
const profile = ref<UserProfile | null>(null);
|
||||
const loading = ref(false);
|
||||
const reportOpen = ref(false);
|
||||
const dateOpen = ref(false);
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await apiClient.api.profilesControllerFindOne(profileId) as unknown as UserProfile;
|
||||
profile.value = res;
|
||||
} catch {
|
||||
uiStore.addToast('Не удалось загрузить профиль', 'error');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
const age = computed(() => {
|
||||
if (!profile.value?.birthDate) return null;
|
||||
const b = new Date(profile.value.birthDate);
|
||||
const now = new Date();
|
||||
let a = now.getFullYear() - b.getFullYear();
|
||||
if (now.getMonth() < b.getMonth() || (now.getMonth() === b.getMonth() && now.getDate() < b.getDate())) a--;
|
||||
return a;
|
||||
});
|
||||
|
||||
const cityName = computed(() => {
|
||||
const cid = profile.value?.cityId;
|
||||
return cid ? uiStore.cities.find((c) => c.id === cid)?.name ?? '' : '';
|
||||
});
|
||||
const tagNames = computed(() => profile.value?.tags?.map((t) => t.value) ?? []);
|
||||
const currentImageIndex = ref(0);
|
||||
|
||||
const isOwnProfile = computed(() =>
|
||||
authStore.profiles.some((p) => p.id === profileId),
|
||||
);
|
||||
|
||||
function goBack() { window.history.back(); }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="profile-detail">
|
||||
<div v-if="loading" class="profile-detail__loading">
|
||||
@@ -72,27 +12,31 @@ function goBack() { window.history.back(); }
|
||||
:src="profile.media[currentImageIndex].path"
|
||||
:alt="profile.name"
|
||||
class="profile-detail__cover-img"
|
||||
/>
|
||||
>
|
||||
<div v-else class="profile-detail__cover-placeholder" />
|
||||
|
||||
<!-- Navigation -->
|
||||
<button
|
||||
v-if="currentImageIndex > 0"
|
||||
class="profile-detail__img-nav profile-detail__img-nav--prev"
|
||||
@click="currentImageIndex--"
|
||||
aria-label="Предыдущее фото"
|
||||
>‹</button>
|
||||
@click="currentImageIndex--"
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
<button
|
||||
v-if="currentImageIndex < (profile.media?.length ?? 1) - 1"
|
||||
class="profile-detail__img-nav profile-detail__img-nav--next"
|
||||
@click="currentImageIndex++"
|
||||
aria-label="Следующее фото"
|
||||
>›</button>
|
||||
@click="currentImageIndex++"
|
||||
>
|
||||
›
|
||||
</button>
|
||||
|
||||
<!-- Back button -->
|
||||
<button class="profile-detail__back" @click="goBack()" aria-label="Назад">
|
||||
<button class="profile-detail__back" aria-label="Назад" @click="goBack()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20">
|
||||
<path d="M19 12H5M12 5l-7 7 7 7"/>
|
||||
<path d="M19 12H5M12 5l-7 7 7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -110,13 +54,19 @@ function goBack() { window.history.back(); }
|
||||
|
||||
<!-- Actions (non-own) -->
|
||||
<div v-if="!isOwnProfile" class="profile-detail__actions">
|
||||
<AppButton size="sm" variant="primary" @click="dateOpen = true">Встреча</AppButton>
|
||||
<AppButton size="sm" variant="ghost" @click="reportOpen = true">Пожаловаться</AppButton>
|
||||
<AppButton size="sm" variant="primary" @click="dateOpen = true">
|
||||
Встреча
|
||||
</AppButton>
|
||||
<AppButton size="sm" variant="ghost" @click="reportOpen = true">
|
||||
Пожаловаться
|
||||
</AppButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<p v-if="profile.description" class="profile-detail__bio">{{ profile.description }}</p>
|
||||
<p v-if="profile.description" class="profile-detail__bio">
|
||||
{{ profile.description }}
|
||||
</p>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="profile-detail__stats">
|
||||
@@ -162,6 +112,70 @@ function goBack() { window.history.back(); }
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { UserProfile } from '@/composables/useAuth'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { apiClient } from '@/api/client'
|
||||
import AppButton from '@/components/common/AppButton.vue'
|
||||
import AppModal from '@/components/common/AppModal.vue'
|
||||
import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
|
||||
import DateProposalForm from '@/components/dates/DateProposalForm.vue'
|
||||
import ReportModal from '@/components/reports/ReportModal.vue'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import { useChat } from '@/composables/useChat'
|
||||
import { useUi } from '@/composables/useUi'
|
||||
|
||||
const route = useRoute()
|
||||
const authStore = useAuth()
|
||||
const uiStore = useUi()
|
||||
const chatStore = useChat()
|
||||
|
||||
const profileId = route.params.profileId as string
|
||||
const profile = ref<UserProfile | null>(null)
|
||||
const loading = ref(false)
|
||||
const reportOpen = ref(false)
|
||||
const dateOpen = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await apiClient.api.profilesControllerFindOne(profileId) as unknown as UserProfile
|
||||
profile.value = res
|
||||
}
|
||||
catch {
|
||||
uiStore.addToast('Не удалось загрузить профиль', 'error')
|
||||
}
|
||||
finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const age = computed(() => {
|
||||
if (!profile.value?.birthDate)
|
||||
return null
|
||||
const b = new Date(profile.value.birthDate)
|
||||
const now = new Date()
|
||||
let a = now.getFullYear() - b.getFullYear()
|
||||
if (now.getMonth() < b.getMonth() || (now.getMonth() === b.getMonth() && now.getDate() < b.getDate()))
|
||||
a--
|
||||
return a
|
||||
})
|
||||
|
||||
const cityName = computed(() => {
|
||||
const cid = profile.value?.cityId
|
||||
return cid ? uiStore.cities.find(c => c.id === cid)?.name ?? '' : ''
|
||||
})
|
||||
const tagNames = computed(() => profile.value?.tags?.map(t => t.value) ?? [])
|
||||
const currentImageIndex = ref(0)
|
||||
|
||||
const isOwnProfile = computed(() =>
|
||||
authStore.profiles.some(p => p.id === profileId),
|
||||
)
|
||||
|
||||
function goBack() { window.history.back() }
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.profile-detail {
|
||||
height: 100%;
|
||||
@@ -179,7 +193,9 @@ function goBack() { window.history.back(); }
|
||||
height: 60dvh;
|
||||
background: var(--color-surface-2);
|
||||
|
||||
@include mobile { height: 50dvh; }
|
||||
@include mobile {
|
||||
height: 50dvh;
|
||||
}
|
||||
}
|
||||
|
||||
&__cover-img {
|
||||
@@ -212,10 +228,16 @@ function goBack() { window.history.back(); }
|
||||
transition: background var(--transition-fast);
|
||||
backdrop-filter: blur(8px);
|
||||
|
||||
&:hover { background: rgba(13, 13, 13, 0.85); }
|
||||
&:hover {
|
||||
background: rgba(13, 13, 13, 0.85);
|
||||
}
|
||||
|
||||
&--prev { left: 12px; }
|
||||
&--next { right: 12px; }
|
||||
&--prev {
|
||||
left: 12px;
|
||||
}
|
||||
&--next {
|
||||
right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&__back {
|
||||
@@ -235,7 +257,9 @@ function goBack() { window.history.back(); }
|
||||
backdrop-filter: blur(8px);
|
||||
transition: background var(--transition-fast);
|
||||
|
||||
&:hover { background: rgba(13, 13, 13, 0.85); }
|
||||
&:hover {
|
||||
background: rgba(13, 13, 13, 0.85);
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
@@ -260,9 +284,14 @@ function goBack() { window.history.back(); }
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
&__age { opacity: 0.6; font-size: 1.5rem; }
|
||||
&__age {
|
||||
opacity: 0.6;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
&__location { color: var(--color-muted); }
|
||||
&__location {
|
||||
color: var(--color-muted);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user