feat(profile): add dedicated telegram success page
This commit is contained in:
@@ -185,6 +185,7 @@ async function startMessengerLogin(channel: 'TELEGRAM' | 'MAX') {
|
|||||||
channel,
|
channel,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
email: normalizedEmail.value,
|
email: normalizedEmail.value,
|
||||||
|
redirectPath: `/profile/notifications/success?connected=${channel.toLowerCase()}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ async function connectMessenger(channel: 'TELEGRAM' | 'MAX') {
|
|||||||
await openMessengerBot({
|
await openMessengerBot({
|
||||||
channel,
|
channel,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
redirectPath: `/profile/notifications?status=success&connected=${channel.toLowerCase()}`,
|
redirectPath: `/profile/notifications/success?connected=${channel.toLowerCase()}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ type MessengerItem = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
const route = useRoute();
|
|
||||||
const meQuery = useQuery(MeDocument);
|
const meQuery = useQuery(MeDocument);
|
||||||
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
|
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
|
||||||
const { openMessengerBot, pendingChannel } = useMessengerStart();
|
const { openMessengerBot, pendingChannel } = useMessengerStart();
|
||||||
@@ -51,47 +50,6 @@ function buildBotConnectUrl(baseUrl: string) {
|
|||||||
|
|
||||||
const telegramConnectUrl = computed(() => buildBotConnectUrl(config.public.telegramBotUrl || ''));
|
const telegramConnectUrl = computed(() => buildBotConnectUrl(config.public.telegramBotUrl || ''));
|
||||||
const maxConnectUrl = computed(() => buildBotConnectUrl(config.public.maxBotUrl || ''));
|
const maxConnectUrl = computed(() => buildBotConnectUrl(config.public.maxBotUrl || ''));
|
||||||
const successChannel = computed(() => {
|
|
||||||
const raw = String(route.query.connected || '').trim().toLowerCase();
|
|
||||||
return raw === 'telegram' || raw === 'max' ? raw : '';
|
|
||||||
});
|
|
||||||
const showSuccess = computed(() => route.query.status === 'success' && Boolean(successChannel.value));
|
|
||||||
const profileName = computed(() => meQuery.result.value?.me?.fullName?.trim() || meQuery.result.value?.me?.email || 'Пользователь');
|
|
||||||
const profileInitials = computed(() =>
|
|
||||||
profileName.value
|
|
||||||
.split(' ')
|
|
||||||
.filter(Boolean)
|
|
||||||
.slice(0, 2)
|
|
||||||
.map((part) => part.charAt(0).toUpperCase())
|
|
||||||
.join('') || 'FR',
|
|
||||||
);
|
|
||||||
const successTitle = computed(() =>
|
|
||||||
successChannel.value === 'telegram' ? 'Telegram успешно подключен' : 'Max успешно подключен',
|
|
||||||
);
|
|
||||||
const successText = computed(() =>
|
|
||||||
successChannel.value === 'telegram'
|
|
||||||
? 'Теперь этот Telegram привязан к вашему кабинету, и уведомления будут приходить в него.'
|
|
||||||
: 'Теперь этот Max привязан к вашему кабинету, и уведомления будут приходить в него.',
|
|
||||||
);
|
|
||||||
const successConnection = computed(() =>
|
|
||||||
successChannel.value === 'telegram' ? telegramConnection.value : maxConnection.value,
|
|
||||||
);
|
|
||||||
const successAvatarSrc = computed(() => messengerConnectionAvatarSrc(successConnection.value));
|
|
||||||
const successAvatarInitials = computed(() =>
|
|
||||||
messengerConnectionInitials(
|
|
||||||
successConnection.value,
|
|
||||||
profileInitials.value,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const successConnectionName = computed(() => messengerConnectionName(successConnection.value));
|
|
||||||
const successConnectionHandleValue = computed(() => messengerConnectionHandle(successConnection.value));
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (showSuccess.value) {
|
|
||||||
void connectionsQuery.refetch();
|
|
||||||
void meQuery.refetch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function connectMessenger(channel: 'TELEGRAM' | 'MAX') {
|
async function connectMessenger(channel: 'TELEGRAM' | 'MAX') {
|
||||||
const baseUrl = channel === 'TELEGRAM' ? telegramConnectUrl.value : maxConnectUrl.value;
|
const baseUrl = channel === 'TELEGRAM' ? telegramConnectUrl.value : maxConnectUrl.value;
|
||||||
@@ -102,7 +60,7 @@ async function connectMessenger(channel: 'TELEGRAM' | 'MAX') {
|
|||||||
await openMessengerBot({
|
await openMessengerBot({
|
||||||
channel,
|
channel,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
redirectPath: `/profile/notifications?status=success&connected=${channel.toLowerCase()}`,
|
redirectPath: `/profile/notifications/success?connected=${channel.toLowerCase()}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -112,33 +70,6 @@ async function connectMessenger(channel: 'TELEGRAM' | 'MAX') {
|
|||||||
<NuxtLink to="/profile" class="link link-hover text-sm">← Назад в профиль</NuxtLink>
|
<NuxtLink to="/profile" class="link link-hover text-sm">← Назад в профиль</NuxtLink>
|
||||||
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Уведомления</h1>
|
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Уведомления</h1>
|
||||||
|
|
||||||
<div v-if="showSuccess" class="surface-card rounded-3xl border border-[#c7efd7] bg-[#f4fff8] p-5">
|
|
||||||
<div class="flex flex-col gap-4 md:flex-row md:items-center">
|
|
||||||
<div v-if="successAvatarSrc" class="avatar">
|
|
||||||
<div class="h-18 w-18 rounded-full ring ring-[#c7efd7] ring-offset-2 ring-offset-white">
|
|
||||||
<img :src="successAvatarSrc" :alt="successConnectionName">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="avatar placeholder">
|
|
||||||
<div class="h-18 w-18 rounded-full bg-[#123824] text-xl font-bold text-white">
|
|
||||||
<span>{{ successAvatarInitials }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-1">
|
|
||||||
<div class="badge badge-success badge-outline">Успешно</div>
|
|
||||||
<h2 class="text-2xl font-extrabold text-[#0f2f20]">{{ successTitle }}</h2>
|
|
||||||
<div class="flex flex-wrap items-center gap-2 text-sm text-[#355947]">
|
|
||||||
<span class="font-semibold text-[#123824]">{{ successConnectionName }}</span>
|
|
||||||
<span v-if="successConnectionHandleValue">{{ successConnectionHandleValue }}</span>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-[#355947]">
|
|
||||||
{{ successText }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="surface-card rounded-3xl p-5">
|
<div class="surface-card rounded-3xl p-5">
|
||||||
<p class="text-sm text-[#355947]">
|
<p class="text-sm text-[#355947]">
|
||||||
Подключите Telegram и Max, чтобы получать статусы заказов и важные уведомления в удобном канале.
|
Подключите Telegram и Max, чтобы получать статусы заказов и важные уведомления в удобном канале.
|
||||||
|
|||||||
112
app/pages/profile/notifications/success.vue
Normal file
112
app/pages/profile/notifications/success.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useQuery } from '@vue/apollo-composable';
|
||||||
|
import {
|
||||||
|
MeDocument,
|
||||||
|
MyMessengerConnectionsDocument,
|
||||||
|
} from '~/composables/graphql/generated';
|
||||||
|
import {
|
||||||
|
messengerConnectionAvatarSrc,
|
||||||
|
messengerConnectionHandle,
|
||||||
|
messengerConnectionInitials,
|
||||||
|
messengerConnectionName,
|
||||||
|
} from '~/composables/useMessengerConnectionPresentation';
|
||||||
|
|
||||||
|
type MessengerItem = {
|
||||||
|
id: string;
|
||||||
|
type: 'TELEGRAM' | 'MAX';
|
||||||
|
isActive: boolean;
|
||||||
|
channelId: string;
|
||||||
|
displayName?: string | null;
|
||||||
|
username?: string | null;
|
||||||
|
avatarAvailable?: boolean | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const meQuery = useQuery(MeDocument);
|
||||||
|
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
|
||||||
|
|
||||||
|
const connectedChannel = computed(() => {
|
||||||
|
const raw = String(route.query.connected || '').trim().toLowerCase();
|
||||||
|
return raw === 'telegram' || raw === 'max' ? raw : 'telegram';
|
||||||
|
});
|
||||||
|
|
||||||
|
const telegramConnection = computed(() =>
|
||||||
|
connectionsQuery.result.value?.myMessengerConnections?.find(
|
||||||
|
(item: MessengerItem) => item.type === 'TELEGRAM' && item.isActive,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const maxConnection = computed(() =>
|
||||||
|
connectionsQuery.result.value?.myMessengerConnections?.find(
|
||||||
|
(item: MessengerItem) => item.type === 'MAX' && item.isActive,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const successConnection = computed(() =>
|
||||||
|
connectedChannel.value === 'telegram' ? telegramConnection.value : maxConnection.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
const profileName = computed(() => meQuery.result.value?.me?.fullName?.trim() || meQuery.result.value?.me?.email || 'Пользователь');
|
||||||
|
const successTitle = computed(() =>
|
||||||
|
connectedChannel.value === 'telegram' ? 'Telegram успешно подключен' : 'Канал успешно подключен',
|
||||||
|
);
|
||||||
|
const successText = computed(() =>
|
||||||
|
connectedChannel.value === 'telegram'
|
||||||
|
? 'Теперь этот Telegram привязан к вашему личному кабинету. Все важные уведомления и статусы заказов будут приходить сюда.'
|
||||||
|
: 'Канал успешно привязан к вашему личному кабинету.',
|
||||||
|
);
|
||||||
|
const successAvatarSrc = computed(() => messengerConnectionAvatarSrc(successConnection.value));
|
||||||
|
const successAvatarInitials = computed(() =>
|
||||||
|
messengerConnectionInitials(successConnection.value, profileName.value.slice(0, 2).toUpperCase() || 'FR'),
|
||||||
|
);
|
||||||
|
const successConnectionName = computed(() => messengerConnectionName(successConnection.value));
|
||||||
|
const successConnectionHandleValue = computed(() => messengerConnectionHandle(successConnection.value));
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
void meQuery.refetch();
|
||||||
|
void connectionsQuery.refetch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<section class="mx-auto flex min-h-[calc(100vh-4rem)] w-full max-w-4xl items-center py-8">
|
||||||
|
<div class="surface-card w-full rounded-[2rem] border border-[#c7efd7] bg-[linear-gradient(135deg,#f6fff8_0%,#effbf4_100%)] p-6 md:p-8">
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
|
<div class="badge badge-success badge-outline w-fit">Успешно</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-5 md:flex-row md:items-center">
|
||||||
|
<div v-if="successAvatarSrc" class="avatar">
|
||||||
|
<div class="h-24 w-24 rounded-full ring ring-[#c7efd7] ring-offset-4 ring-offset-white">
|
||||||
|
<img :src="successAvatarSrc" :alt="successConnectionName">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="avatar placeholder">
|
||||||
|
<div class="h-24 w-24 rounded-full bg-[#123824] text-2xl font-bold text-white">
|
||||||
|
<span>{{ successAvatarInitials }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h1 class="text-3xl font-extrabold text-[#0f2f20]">{{ successTitle }}</h1>
|
||||||
|
<div class="flex flex-wrap items-center gap-2 text-sm text-[#355947]">
|
||||||
|
<span class="font-semibold text-[#123824]">{{ successConnectionName }}</span>
|
||||||
|
<span v-if="successConnectionHandleValue">{{ successConnectionHandleValue }}</span>
|
||||||
|
</div>
|
||||||
|
<p class="max-w-2xl text-sm leading-6 text-[#355947]">
|
||||||
|
{{ successText }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-3 sm:flex-row">
|
||||||
|
<NuxtLink to="/profile/notifications" class="btn btn-primary">
|
||||||
|
Перейти к уведомлениям
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/" class="btn btn-ghost">
|
||||||
|
Перейти в каталог
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user