101 lines
3.3 KiB
Vue
101 lines
3.3 KiB
Vue
<script setup lang="ts">
|
||
import { useQuery } from '@vue/apollo-composable';
|
||
import {
|
||
NotificationTemplatesDocument,
|
||
type NotificationTemplatesQuery,
|
||
} from '~/composables/graphql/generated';
|
||
|
||
definePageMeta({
|
||
middleware: ['manager-only'],
|
||
});
|
||
|
||
type TemplateItem = NotificationTemplatesQuery['notificationTemplates'][number];
|
||
type TemplateChannel = TemplateItem['channels'][number];
|
||
|
||
const templatesQuery = useQuery(NotificationTemplatesDocument);
|
||
|
||
const templates = computed<TemplateItem[]>(() => templatesQuery.result.value?.notificationTemplates ?? []);
|
||
|
||
function channelLabel(channel: TemplateChannel['channel']) {
|
||
if (channel === 'EMAIL') {
|
||
return 'Email';
|
||
}
|
||
if (channel === 'TELEGRAM') {
|
||
return 'Telegram';
|
||
}
|
||
return 'Max';
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<section class="space-y-6">
|
||
<div class="manager-hero">
|
||
<h1 class="manager-title">Реестр шаблонов уведомлений</h1>
|
||
<p class="manager-copy">
|
||
Экран собирается из backend-кода. Здесь только реальные шаблоны и реальные типы взаимодействия с клиентом,
|
||
которые сейчас описаны в системе.
|
||
</p>
|
||
</div>
|
||
|
||
<div v-if="templatesQuery.loading.value" class="manager-empty-state">
|
||
Загружаем шаблоны...
|
||
</div>
|
||
|
||
<div v-else-if="templates.length === 0" class="manager-empty-state">
|
||
Шаблонов пока нет.
|
||
</div>
|
||
|
||
<div v-else class="space-y-4">
|
||
<article
|
||
v-for="template in templates"
|
||
:key="template.id"
|
||
class="surface-card rounded-3xl p-5"
|
||
>
|
||
<h2 class="text-2xl font-black tracking-[-0.03em] text-[#123824]">
|
||
{{ template.title }}
|
||
</h2>
|
||
|
||
<div class="mt-4 grid gap-4 xl:grid-cols-3">
|
||
<section
|
||
v-for="channel in template.channels"
|
||
:key="`${template.id}-${channel.channel}`"
|
||
class="rounded-[24px] border border-[#deebe4] bg-[#fbfdfb] p-4"
|
||
>
|
||
<h3 class="text-sm font-extrabold uppercase tracking-[0.14em] text-[#355947]">
|
||
{{ channelLabel(channel.channel) }}
|
||
</h3>
|
||
|
||
<div class="mt-3 rounded-[20px] bg-white p-4">
|
||
<p
|
||
v-if="channel.subject"
|
||
class="text-xs font-semibold uppercase tracking-[0.12em] text-[#5c7b69]"
|
||
>
|
||
{{ channel.subject }}
|
||
</p>
|
||
|
||
<div class="mt-3 space-y-3 text-sm leading-6 text-[#123824]">
|
||
<p
|
||
v-for="line in channel.body"
|
||
:key="line"
|
||
:class="channel.implemented ? '' : 'text-[#6f8577]'"
|
||
>
|
||
{{ line }}
|
||
</p>
|
||
</div>
|
||
|
||
<div v-if="channel.buttonText" class="mt-4 space-y-1 text-sm leading-6 text-[#355947]">
|
||
<p class="font-semibold text-[#123824]">
|
||
{{ channel.buttonText }}
|
||
</p>
|
||
<p v-if="channel.buttonUrl" class="break-all text-xs text-[#5c7b69]">
|
||
{{ channel.buttonUrl }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
</template>
|