add tabs
Deploy app frontend / app frontend (push) Successful in 1m46s

This commit is contained in:
2024-12-06 21:20:27 +02:00
parent 58a5c378ca
commit ef977f5742
17 changed files with 542 additions and 444 deletions
+37 -41
View File
@@ -1,52 +1,48 @@
<template>
<MetaHead>
<title>Создание QR-кода НаСвязи</title>
<meta
name="description"
content="Создайте свой QR-код для безопасного и конфиденциального взаимодействия"
/>
</MetaHead>
<LayoutWithTabs>
<MetaHead>
<title>Создание QR-кода НаСвязи</title>
<meta
name="description"
content="Создайте свой QR-код для безопасного и конфиденциального взаимодействия"
/>
</MetaHead>
<div class="max-w-prose mx-auto py-6 px-4 md:px-6">
<section class="content">
<div class="max-w-prose mx-auto py-8">
<CreateSectionManager
:placement="placement"
:selectedActions="selectedActions"
:messageDeliveryMethod="messageDeliveryMethod"
>
<template #placement>
<CreatePlacementSection v-model="placement" />
</template>
<CreateSectionManager
:placement="placement"
:selectedActions="selectedActions"
:messageDeliveryMethod="messageDeliveryMethod"
>
<template #placement>
<CreatePlacementSection v-model="placement" />
</template>
<template #actions>
<CreateActionsSection v-model="selectedActions" />
</template>
<template #actions>
<CreateActionsSection v-model="selectedActions" />
</template>
<template #delivery>
<CreateMessageDeliveryMethodSection v-model="messageDeliveryMethod" />
</template>
<template #delivery>
<CreateMessageDeliveryMethodSection v-model="messageDeliveryMethod" />
</template>
<template #messages>
<CreatePredefinedMessagesSection :placement v-model="messages" />
</template>
<template #messages>
<CreatePredefinedMessagesSection :placement v-model="messages" />
</template>
<template #summary>
<CreateSummarySection
v-model:name="name"
buttonLabel="Создать QR‑код"
:isPending
@nextStep="createQrCode"
/>
</template>
</CreateSectionManager>
<template #summary>
<CreateSummarySection
v-model:name="name"
buttonLabel="Создать QR‑код"
:isPending
@nextStep="createQrCode"
/>
</template>
</CreateSectionManager>
<p v-if="isError" class="text-red-500 mt-4">Ошибка создания QRкода: {{ error }}</p>
<p v-if="isError" class="text-red-500 mt-4">Ошибка создания QRкода: {{ error }}</p>
<div class="h-[30dvh] md:h-[10dvh] overflow-hidden"></div>
</div>
</section>
</div>
<div class="h-[30dvh] md:h-[10dvh] overflow-hidden"></div>
</LayoutWithTabs>
</template>
<script setup lang="ts">
+74 -66
View File
@@ -1,80 +1,88 @@
<template>
<MetaHead>
<title>Поддержите развитие НаСвязи</title>
<meta name="description" content="" />
</MetaHead>
<LayoutWithTabs>
<template #footer>
<footer class="py-4 border-t text-center text-sm hidden sm:block">
<p>НаСвязи © 2024</p>
</footer>
</template>
<section class="max-w-2xl mx-auto py-8 px-4 text-center">
<h1 class="text-2xl font-bold mb-4">Поддержите развитие НаСвязи</h1>
<p class="text-gray-600 mb-6">
Мы делаем всё, чтобы НаСвязи оставался удобным и полезным. Вы можете помочь нам, поддержав
проект на Бусти.
</p>
<MetaHead>
<title>Поддержите развитие НаСвязи</title>
<meta name="description" content="" />
</MetaHead>
<!-- Ссылка на Бусти -->
<div class="mb-8">
<a
href="https://boosty.to/hereconnect/donate"
target="_blank"
rel="noopener noreferrer"
class="inline-block bg-orange-500 text-white font-semibold py-3 px-6 rounded-lg shadow hover:bg-orange-600 transition duration-300"
>
Поддержать через Бусти
</a>
</div>
<section class="max-w-2xl mx-auto py-8 px-4 text-center">
<h1 class="text-2xl font-bold mb-4">Поддержите развитие НаСвязи</h1>
<p class="text-gray-600 mb-6">
Мы делаем всё, чтобы НаСвязи оставался удобным и полезным. Вы можете помочь нам, поддержав
проект на Бусти.
</p>
<!-- Рассказать друзьям -->
<div class="mb-8">
<h2 class="text-xl font-semibold mb-4">Рассказать друзьям</h2>
<p class="text-gray-600 mb-4">Поделитесь ссылкой на НаСвязи:</p>
<div class="flex justify-center gap-6">
<!-- Telegram -->
<!-- Ссылка на Бусти -->
<div class="mb-8">
<a
:href="telegramShareUrl"
href="https://boosty.to/hereconnect/donate"
target="_blank"
rel="noopener noreferrer"
class="p-button-rounded p-button-text p-button-lg inline-flex items-center justify-center"
class="inline-block bg-orange-500 text-white font-semibold py-3 px-6 rounded-lg shadow hover:bg-orange-600 transition duration-300"
>
<i class="pi pi-telegram !text-3xl text-blue-500"></i>
</a>
<!-- WhatsApp -->
<a
:href="whatsappShareUrl"
target="_blank"
rel="noopener noreferrer"
class="p-button-rounded p-button-text p-button-lg inline-flex items-center justify-center"
>
<i class="pi pi-whatsapp !text-3xl text-green-500"></i>
Поддержать через Бусти
</a>
</div>
</div>
<!-- Обратная связь -->
<!-- <div>-->
<!-- <h2 class="text-xl font-semibold mb-4">Оставить отзыв или идею</h2>-->
<!-- <p class="text-gray-600 mb-4">Мы рады любым предложениям и обратной связи.</p>-->
<!-- <form @submit.prevent="sendFeedback">-->
<!-- <div class="mb-4">-->
<!-- <InputText v-model="email" class="w-full" placeholder="Ваш email" />-->
<!-- </div>-->
<!-- <div class="mb-4">-->
<!-- <Textarea-->
<!-- v-model="message"-->
<!-- rows="4"-->
<!-- class="w-full"-->
<!-- placeholder="Ваше сообщение"-->
<!-- ></Textarea>-->
<!-- </div>-->
<!-- <Button-->
<!-- label="Отправить"-->
<!-- class="p-button-md"-->
<!-- :disabled="!email.trim() || !message.trim()"-->
<!-- />-->
<!-- </form>-->
<!-- <p v-if="success" class="text-green-500 mt-4">Спасибо за ваше сообщение!</p>-->
<!-- </div>-->
</section>
<!-- Рассказать друзьям -->
<div class="mb-8">
<h2 class="text-xl font-semibold mb-4">Рассказать друзьям</h2>
<p class="text-gray-600 mb-4">Поделитесь ссылкой на НаСвязи:</p>
<div class="flex justify-center gap-6">
<!-- Telegram -->
<a
:href="telegramShareUrl"
target="_blank"
rel="noopener noreferrer"
class="p-button-rounded p-button-text p-button-lg inline-flex items-center justify-center"
>
<i class="pi pi-telegram !text-3xl text-blue-500"></i>
</a>
<!-- WhatsApp -->
<a
:href="whatsappShareUrl"
target="_blank"
rel="noopener noreferrer"
class="p-button-rounded p-button-text p-button-lg inline-flex items-center justify-center"
>
<i class="pi pi-whatsapp !text-3xl text-green-500"></i>
</a>
</div>
</div>
<!-- Обратная связь -->
<!-- <div>-->
<!-- <h2 class="text-xl font-semibold mb-4">Оставить отзыв или идею</h2>-->
<!-- <p class="text-gray-600 mb-4">Мы рады любым предложениям и обратной связи.</p>-->
<!-- <form @submit.prevent="sendFeedback">-->
<!-- <div class="mb-4">-->
<!-- <InputText v-model="email" class="w-full" placeholder="Ваш email" />-->
<!-- </div>-->
<!-- <div class="mb-4">-->
<!-- <Textarea-->
<!-- v-model="message"-->
<!-- rows="4"-->
<!-- class="w-full"-->
<!-- placeholder="Ваше сообщение"-->
<!-- ></Textarea>-->
<!-- </div>-->
<!-- <Button-->
<!-- label="Отправить"-->
<!-- class="p-button-md"-->
<!-- :disabled="!email.trim() || !message.trim()"-->
<!-- />-->
<!-- </form>-->
<!-- <p v-if="success" class="text-green-500 mt-4">Спасибо за ваше сообщение!</p>-->
<!-- </div>-->
</section>
</LayoutWithTabs>
</template>
<script setup lang="ts">
@@ -0,0 +1,52 @@
<template>
<LayoutWithTabs>
<MetaHead>
<title>Ваши Чаты НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<QueryRender :query="query">
<template #default="{ data }">
<div
v-if="data.rows.length > 0"
class="flex flex-col gap-5 my-4 grid grid-cols-1 sm:grid-cols-3 gap-4"
/>
<div
v-else
class="flex-1 flex flex-col items-center place-self-center text-center text-gray-500"
>
<h1 class="text-2xl font-bold mb-4 text-center sm:text-left">Страница в разработке</h1>
</div>
</template>
<template #error="{ reload }">
<div class="text-center text-red-500">
<p>Произошла ошибка при загрузке данных. Пожалуйста, попробуйте позже.</p>
<Button label="Повторить попытку" class="p-button mt-4" @click="reload()" />
</div>
</template>
<template #loading>
<div class="text-center text-gray-500">
<p>Загрузка QR-кодов...</p>
<ProgressSpinner styleClass="mt-4" />
</div>
</template>
</QueryRender>
</LayoutWithTabs>
</template>
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
const query = useQuery({
queryKey: ['qrCodes'],
queryFn: async () => {
return { rows: [] } as const
},
})
</script>
@@ -1,107 +0,0 @@
<template>
<MetaHead>
<title>Ваши QR-коды НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<div class="flex flex-col min-h-full">
<main class="flex-grow flex justify-center py-6 px-4 md:px-6">
<QueryRender :query="query">
<template #default="{ data }">
<div v-if="data.rows.length > 0">
<h1 class="text-2xl font-bold mb-4 text-center lg:text-left">Управление QR-кодами</h1>
<div class="flex flex-col gap-5">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<QRCodeCard
v-for="{ doc: qrCode } in data.rows"
:key="qrCode!.uri"
:qrCode="qrCode!"
/>
<RouterLink
to="/create"
class="flex justify-stretch place-items-center p-4 rounded-lg bg-white text-primary shadow-md flex-col items-center gap-2"
>
<i class="pi pi-plus text-4xl" />
<span class="text-lg font-semibold">Создать QRкод</span>
</RouterLink>
</div>
</div>
</div>
<div v-else class="text-center text-gray-500 place-self-center">
<h1 class="text-2xl font-bold mb-4 text-center lg:text-left">Нет созданных QR-кодов</h1>
<p class="mb-6">Вы можете создать их прямо сейчас!</p>
<Button
icon="pi pi-qrcode"
label="Создать QR‑код"
to="/create"
as="router-link"
class="p-button-lg"
/>
</div>
</template>
<template #error="{ reload }">
<div class="text-center text-red-500">
<p>Произошла ошибка при загрузке данных. Пожалуйста, попробуйте позже.</p>
<Button label="Повторить попытку" class="p-button mt-4" @click="reload()" />
</div>
</template>
<template #loading>
<div class="text-center text-gray-500">
<p>Загрузка QR-кодов...</p>
<ProgressSpinner styleClass="mt-4" />
</div>
</template>
</QueryRender>
</main>
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a
href="/donate"
class="underline underline-offset-2"
>поддержке</a
>.
</footer>
</div>
</template>
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
import { qrCodeDbLocal, qrCodeDbRemote } from '@/api/dbs'
import { getUserUuid } from '@/utils/getUserUuid'
import { onMounted } from 'vue'
import type { QRCodeDocument } from '@hereconnect/types'
const query = useQuery({
queryKey: ['qrCodes'],
queryFn: async () => {
return qrCodeDbLocal.allDocs({
include_docs: true,
startkey: 'qr_code:',
endkey: 'qr_code:\uffff',
})
},
})
let replication: PouchDB.Replication.Replication<QRCodeDocument> | null = null
onMounted(() => {
replication = qrCodeDbLocal.replicate.from(qrCodeDbRemote, {
live: true,
selector: {
type: 'qr_code',
user_uuid: getUserUuid(),
},
})
replication.on('change', () => {
query.refetch()
})
})
onBeforeUnmount(() => {
if (replication) {
replication.cancel()
}
})
</script>
@@ -1,55 +1,51 @@
<template>
<MetaHead>
<title>Чат {{ chatDoc?.name ? `«${chatDoc.name}»` : '' }} НаСвязи</title>
<meta
name="description"
content="Ваш QR-код успешно создан! Узнайте, как его использовать и настройте все доступные функции для удобного взаимодействия с окружающими."
/>
</MetaHead>
<LayoutWithTabs>
<MetaHead>
<title>Чат {{ chatDoc?.name ? `«${chatDoc.name}»` : '' }} НаСвязи</title>
<meta
name="description"
content="Ваш QR-код успешно создан! Узнайте, как его использовать и настройте все доступные функции для удобного взаимодействия с окружающими."
/>
</MetaHead>
<div class="flex flex-col min-h-full">
<!-- Основной контент -->
<main class="flex-grow flex flex-col">
<section class="flex flex-col flex-grow max-w-prose w-full mx-auto">
<ChatComponent userRole="owner" :qr_code_uri="qr_code_uri" :chat="chat">
<template #endOfMessages="{ count }">
<!-- Уведомление, если гость отправил только одно сообщение -->
<div
v-if="count === 2"
class="flex flex-col items-center justify-center text-center bg-gray-50 border border-gray-200 rounded-lg shadow-md p-6 mt-6"
>
<p class="text-gray-700 font-medium text-lg">Ваше сообщение отправлено.</p>
<p class="text-gray-600 mt-2">
Вы можете написать ещё одно сообщение или подождать ответа.
</p>
</div>
<div class="flex flex-col min-h-full">
<!-- Основной контент -->
<main class="flex-grow flex flex-col">
<section class="flex flex-col flex-grow max-w-prose w-full mx-auto">
<ChatComponent userRole="owner" :qr_code_uri="qr_code_uri" :chat="chat">
<template #endOfMessages="{ count, lastMessage }">
<div
v-if="!count"
class="flex flex-col items-center justify-center flex-grow text-center text-gray-500"
>
<h1 class="text-2xl font-bold mb-4">Пока нет сообщений</h1>
<p class="text-gray-600">Вы можете начать общение, отправив первое сообщение.</p>
</div>
<div
v-else-if="lastMessage && lastMessage.from === 'owner'"
class="flex flex-col items-center justify-center text-center bg-gray-50 border border-gray-200 rounded-lg shadow-md p-6 mt-6"
>
<p class="text-gray-700 font-medium text-lg">Ваше сообщение отправлено.</p>
<p class="text-gray-600 mt-2">
Вы можете написать ещё одно сообщение или подождать ответа.
</p>
</div>
</template>
</ChatComponent>
</section>
</main>
<p class="mt-10 text-sm text-gray-500 text-center">
Хотите создать еще один QRкод?
<a href="/create" class="underline underline-offset-2">Создайте его здесь</a>.
</p>
<p class="mt-1 text-sm text-gray-500 text-center">
Сделайте НаСвязи удобнее. Мы будем рады вашей&nbsp;<RouterLink
to="/donate"
class="underline"
>поддержке</RouterLink
>.
</p>
</template>
</ChatComponent>
</section>
</main>
<!-- Футер -->
<!-- <footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">-->
<!-- <p><a href="/create" class="underline underline-offset-2">Создайте свой QRкод</a>.</p>-->
<!-- <p class="mt-1">-->
<!-- Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a href="/donate" class="underline underline-offset-2"-->
<!-- >поддержке</a-->
<!-- >.-->
<!-- </p>-->
<!-- </footer>-->
</div>
<!-- Футер -->
<!-- <footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">-->
<!-- <p><a href="/create" class="underline underline-offset-2">Создайте свой QRкод</a>.</p>-->
<!-- <p class="mt-1">-->
<!-- Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a href="/donate" class="underline underline-offset-2"-->
<!-- >поддержке</a-->
<!-- >.-->
<!-- </p>-->
<!-- </footer>-->
</div>
</LayoutWithTabs>
</template>
<script setup lang="ts">
@@ -1,13 +1,13 @@
<template>
<MetaHead>
<title>Ваш QR-код готов НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<LayoutWithTabs>
<MetaHead>
<title>Ваш QR-код готов НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<div class="flex flex-col min-h-full">
<main
class="flex-grow flex justify-center py-6 px-4 md:px-6"
:class="{
@@ -22,10 +22,10 @@
>
<ProgressSpinner styleClass="mt-4" />
</div>
<p v-else-if="svgQueryIsError" class="text-red-500 mt-4">
<p v-else-if="svgQueryIsError" class="text-red-500 mt-4 text-center">
Ошибка генерации QRкода: {{ svgQueryError?.message }}
</p>
<p v-else-if="qrCodeQueryIsError" class="text-red-500 mt-4">
<p v-else-if="qrCodeQueryIsError" class="text-red-500 mt-4 text-center">
Ошибка загрузки данных QRкода: {{ qrCodeQueryError!.message }}
</p>
<template v-else>
@@ -84,21 +84,7 @@
</template>
</section>
</main>
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
<p>
Нужен еще один?
<a href="/create" class="underline underline-offset-2">Создайте QRкод</a>.
</p>
<p class="mt-1">
Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a
href="/donate"
class="underline underline-offset-2"
>поддержке</a
>.
</p>
</footer>
</div>
</LayoutWithTabs>
</template>
<script setup lang="ts">
+70 -101
View File
@@ -1,108 +1,77 @@
<template>
<div class="flex flex-col min-h-full">
<main class="flex-grow flex justify-center py-6 px-4 md:px-6">
<div>
<h1 class="text-2xl font-bold mb-4 text-center lg:text-left">Управление QR-кодом</h1>
<QueryRender :query="qrCodeQuery">
<template #default="{ data: qrCodeDoc }">
<MetaHead>
<title>{{ qrCodeDoc.name }}: управление QR-кодом НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<div class="bg-white p-6 rounded-lg shadow-md mb-6">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center">
<QRCodePlacementIcon :placement="qrCodeDoc.placement" />
<h2 class="text-xl font-semibold">{{ qrCodeDoc.name }}</h2>
</div>
<div class="flex gap-2">
<!-- <Button-->
<!-- icon="pi pi-cog"-->
<!-- label="Настроить"-->
<!-- :to="`/manage/qr/${qrCodeDoc.uri}/settings`"-->
<!-- as="router-link"-->
<!-- severity="secondary"-->
<!-- size="small"-->
<!-- outlined-->
<!-- />-->
<Button
icon="pi pi-qrcode"
label="QR-код и инструкции"
:to="`/manage/qr/${qrCodeDoc.uri}/ready`"
as="router-link"
severity="secondary"
size="small"
outlined
/>
</div>
</div>
<div class="mb-4 flex gap-2 items-baseline flex-wrap">
<strong>Ссылка: </strong>
<LinkQRCode :url="qrCodeDoc.url" />
<div class="flex gap-2 items-baseline flex-wrap">
<LinkCopyButton :url="qrCodeDoc.url" />
<LinkShareTelegramButton
:shareUrl="qrCodeDoc.url"
shareText="Используйте эту ссылку НаСвязи!"
/>
</div>
</div>
<div>
<p>
<strong>Создано: </strong>
<span class="text-nowrap">{{ formatDate(qrCodeDoc.created_at) }}</span>
</p>
<!-- <p><strong>Количество сканирований:</strong> {{ qrCodeDoc.scanCount }}</p>-->
<!-- <p><strong>Последнее сканирование:</strong> {{ formatDate(qrCodeDoc.lastScan) }}</p>-->
</div>
<LayoutWithTabs>
<QueryRender :query="qrCodeQuery">
<template #default="{ data: qrCodeDoc }">
<MetaHead>
<title>{{ qrCodeDoc.name }} НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<div class="bg-white p-6 rounded-lg shadow-md my-5">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center">
<QRCodePlacementIcon :placement="qrCodeDoc.placement" />
<h2 class="text-xl font-semibold">{{ qrCodeDoc.name }}</h2>
</div>
</template>
</QueryRender>
<div class="flex gap-2">
<!-- <Button-->
<!-- icon="pi pi-cog"-->
<!-- label="Настроить"-->
<!-- :to="`/manage/qr/${qrCodeDoc.uri}/settings`"-->
<!-- as="router-link"-->
<!-- severity="secondary"-->
<!-- size="small"-->
<!-- outlined-->
<!-- />-->
<Button
icon="pi pi-qrcode"
label="QR-код и инструкции"
:to="`/manage/qr/${qrCodeDoc.uri}/ready`"
as="router-link"
severity="secondary"
size="small"
outlined
/>
</div>
</div>
<div class="mb-4 flex gap-2 items-baseline flex-wrap">
<strong>Ссылка: </strong>
<LinkQRCode :url="qrCodeDoc.url" />
<div class="flex gap-2 items-baseline flex-wrap">
<LinkCopyButton :url="qrCodeDoc.url" />
<LinkShareTelegramButton
:shareUrl="qrCodeDoc.url"
shareText="Используйте эту ссылку НаСвязи!"
/>
</div>
</div>
<div>
<p>
<strong>Создано: </strong>
<span class="text-nowrap">{{ formatDate(qrCodeDoc.created_at) }}</span>
</p>
<!-- <p><strong>Количество сканирований:</strong> {{ qrCodeDoc.scanCount }}</p>-->
<!-- <p><strong>Последнее сканирование:</strong> {{ formatDate(qrCodeDoc.lastScan) }}</p>-->
</div>
</div>
</template>
<!-- <div class="bg-white p-6 rounded-lg shadow-md mb-6">-->
<!-- <h2 class="text-xl font-bold mb-4">Чаты</h2>-->
<!-- <div v-if="chats.length > 0" class="grid grid-cols-1 gap-4">-->
<!-- <div v-for="chat in chats" :key="chat._id" class="p-4 rounded-lg bg-white shadow-md">-->
<!-- <div class="flex items-center justify-between">-->
<!-- <div>-->
<!-- <p class="text-lg font-semibold">Чат #{{ chat._id }}</p>-->
<!-- <p class="text-gray-500">-->
<!-- Последнее сообщение: {{ formatDate(chat.lastMessageDate) }}-->
<!-- </p>-->
<!-- </div>-->
<!-- <Button-->
<!-- label="Открыть"-->
<!-- :to="`/manage/qr/${qrCodeDoc.uri}/chat/${chat._id}`"-->
<!-- as="router-link"-->
<!-- class="p-button-outlined p-button-sm"-->
<!-- />-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div v-else class="text-center text-gray-500">-->
<!-- <p>Нет активных чатов для этого QR-кода.</p>-->
<!-- </div>-->
<!-- </div>-->
</div>
</main>
<template #loading>
<div class="flex-1 flex items-center place-self-center">
<ProgressSpinner styleClass="mt-4" />
</div>
</template>
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
<p>
Нужен еще один?
<a href="/create" class="underline underline-offset-2">Создайте QRкод</a>.
</p>
<p class="mt-1">
Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a
href="/donate"
class="underline underline-offset-2"
>поддержке</a
>.
</p>
</footer>
</div>
<template #error="{ reload, error }">
<div class="flex-1 flex flex-col items-center place-self-center text-center text-red-500">
<p>Произошла ошибка при загрузке данных: {{ error.message }}</p>
<Button label="Повторить попытку" class="p-button mt-4" @click="reload()" />
</div>
</template>
</QueryRender>
</LayoutWithTabs>
</template>
<script setup lang="ts">
@@ -0,0 +1,93 @@
<template>
<LayoutWithTabs>
<MetaHead>
<title>Ваши QR-коды НаСвязи</title>
<meta
name="description"
content="Просматривайте и управляйте сообщениями, отправленными через ваш QR-код. Полная конфиденциальность и удобный интерфейс чата"
/>
</MetaHead>
<QueryRender :query="query">
<template #default="{ data }">
<div v-if="data.rows.length > 0">
<div class="flex flex-col gap-5 my-5">
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<QRCodeCard
v-for="{ doc: qrCode } in data.rows"
:key="qrCode!.uri"
:qrCode="qrCode!"
/>
</div>
</div>
</div>
<div
v-else
class="flex-1 flex flex-col items-center place-self-center text-center text-gray-500"
>
<h1 class="text-2xl font-bold mb-4 text-center sm:text-left">Нет созданных QR-кодов</h1>
<p class="mb-6">Вы можете создать их прямо сейчас!</p>
<Button
icon="pi pi-qrcode"
label="Создать QR‑код"
to="/create"
as="router-link"
class="p-button-lg"
/>
</div>
</template>
<template #loading>
<div class="flex-1 flex items-center place-self-center">
<ProgressSpinner styleClass="mt-4" />
</div>
</template>
<template #error="{ reload, error }">
<div class="flex-1 flex flex-col items-center place-self-center text-center text-red-500">
<p>Произошла ошибка при загрузке данных: {{ error.message }}</p>
<Button label="Повторить попытку" class="p-button mt-4" @click="reload()" />
</div>
</template>
</QueryRender>
</LayoutWithTabs>
</template>
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
import { qrCodeDbLocal, qrCodeDbRemote } from '@/api/dbs'
import { getUserUuid } from '@/utils/getUserUuid'
import { onMounted } from 'vue'
import type { QRCodeDocument } from '@hereconnect/types'
const query = useQuery({
queryKey: ['qrCodes'],
queryFn: () => {
return qrCodeDbLocal.allDocs({
include_docs: true,
startkey: 'qr_code:',
endkey: 'qr_code:\uffff',
})
},
})
let replication: PouchDB.Replication.Replication<QRCodeDocument> | null = null
onMounted(() => {
replication = qrCodeDbLocal.replicate.from(qrCodeDbRemote, {
live: true,
selector: {
type: 'qr_code',
user_uuid: getUserUuid(),
},
})
replication.on('change', () => {
query.refetch()
})
})
onBeforeUnmount(() => {
if (replication) {
replication.cancel()
}
})
</script>
+39 -49
View File
@@ -1,55 +1,45 @@
<template>
<MetaHead>
<title>Чат НаСвязи</title>
<meta
name="description"
content="Чат QR-кода. Безопасная и конфиденциальная связь для решения всех вопросов"
/>
</MetaHead>
<LayoutWithTabs>
<MetaHead>
<title>Чат НаСвязи</title>
<meta
name="description"
content="Чат QR-кода. Безопасная и конфиденциальная связь для решения всех вопросов"
/>
</MetaHead>
<div class="flex flex-col min-h-full">
<!-- Основной контент -->
<main class="flex-grow flex flex-col">
<section class="flex flex-col flex-grow max-w-prose w-full mx-auto">
<ChatComponent userRole="guest" :qr_code_uri="qr_code_uri" :chat="chat">
<template #endOfMessages="{ count }">
<!-- Уведомление, если гость отправил только одно сообщение -->
<div
v-if="count === 1"
class="flex flex-col items-center justify-center text-center bg-gray-50 border border-gray-200 rounded-lg shadow-md p-6 mt-6"
>
<p class="text-gray-700 font-medium text-lg">Ваше сообщение отправлено.</p>
<p class="text-gray-600 mt-2">
Вы можете написать ещё одно сообщение или подождать ответа.
</p>
</div>
<div class="flex flex-col min-h-full">
<!-- Основной контент -->
<main class="flex-grow flex flex-col">
<section class="flex flex-col flex-grow max-w-prose w-full mx-auto">
<ChatComponent userRole="guest" :qr_code_uri="qr_code_uri" :chat="chat">
<template #endOfMessages="{ count, lastMessage }">
<!-- Уведомление, если гость отправил только одно сообщение -->
<div
v-if="count === 1 && lastMessage && lastMessage.from === 'guest'"
class="flex flex-col items-center justify-center text-center bg-gray-50 border border-gray-200 rounded-lg shadow-md p-6 mt-6"
>
<p class="text-gray-700 font-medium text-lg">Ваше сообщение отправлено.</p>
<p class="text-gray-600 mt-2">
Вы можете написать ещё одно сообщение или подождать ответа.
</p>
</div>
</template>
</ChatComponent>
</section>
</main>
<p class="mt-10 text-sm text-gray-500 text-center">
Хотите создать собственный QRкод?
<a href="/create" class="underline underline-offset-2">Создайте его здесь</a>.
</p>
<p class="mt-1 text-sm text-gray-500 text-center">
Сделайте НаСвязи удобнее. Мы будем рады вашей&nbsp;<RouterLink
to="/donate"
class="underline underline-offset-2"
>поддержке</RouterLink
>.
</p>
</template>
</ChatComponent>
</section>
</main>
<!-- Футер -->
<!-- <footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">-->
<!-- <p><a href="/create" class="underline underline-offset-2">Создайте свой QRкод</a>.</p>-->
<!-- <p class="mt-1">-->
<!-- Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a href="/donate" class="underline underline-offset-2"-->
<!-- >поддержке</a-->
<!-- >.-->
<!-- </p>-->
<!-- </footer>-->
</div>
<!-- Футер -->
<!-- <footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">-->
<!-- <p><a href="/create" class="underline underline-offset-2">Создайте свой QRкод</a>.</p>-->
<!-- <p class="mt-1">-->
<!-- Сделайте НаСвязи удобнее. Будем рады вашей&nbsp;<a href="/donate" class="underline underline-offset-2"-->
<!-- >поддержке</a-->
<!-- >.-->
<!-- </p>-->
<!-- </footer>-->
</div>
</LayoutWithTabs>
</template>
<script setup lang="ts">