Vendored
+3
@@ -28,6 +28,9 @@ declare module 'vue' {
|
|||||||
ExamplesSection: typeof import('./src/components/TheWelcome/ExamplesSection.vue')['default']
|
ExamplesSection: typeof import('./src/components/TheWelcome/ExamplesSection.vue')['default']
|
||||||
InputText: typeof import('primevue/inputtext')['default']
|
InputText: typeof import('primevue/inputtext')['default']
|
||||||
LinkCopyButton: typeof import('./src/components/link/LinkCopyButton.vue')['default']
|
LinkCopyButton: typeof import('./src/components/link/LinkCopyButton.vue')['default']
|
||||||
|
LinkMono: typeof import('./src/components/link/LinkMono.vue')['default']
|
||||||
|
LinkQrCode: typeof import('./src/components/link/LinkQrCode.vue')['default']
|
||||||
|
LinkQRCode: typeof import('./src/components/link/LinkQRCode.vue')['default']
|
||||||
LinkShareButton: typeof import('./src/components/link/LinkShareButton.vue')['default']
|
LinkShareButton: typeof import('./src/components/link/LinkShareButton.vue')['default']
|
||||||
LinkShareTelegramButton: typeof import('./src/components/link/LinkShareTelegramButton.vue')['default']
|
LinkShareTelegramButton: typeof import('./src/components/link/LinkShareTelegramButton.vue')['default']
|
||||||
ManagePlacementInstructions: typeof import('./src/components/manage/ManagePlacementInstructions.vue')['default']
|
ManagePlacementInstructions: typeof import('./src/components/manage/ManagePlacementInstructions.vue')['default']
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ const { data, error, refetch, isSuccess, isError, isLoading } = query
|
|||||||
<template>
|
<template>
|
||||||
<slot v-if="isSuccess" name="default" :data="data!" />
|
<slot v-if="isSuccess" name="default" :data="data!" />
|
||||||
<slot v-else-if="isLoading" name="loading">
|
<slot v-else-if="isLoading" name="loading">
|
||||||
<p class="text-gray-500" v-if="!slots.loading">Загрузка данных...</p>
|
<div class="text-center text-gray-500" v-if="!slots.loading">
|
||||||
|
<ProgressSpinner styleClass="mt-4" />
|
||||||
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
<slot v-else-if="isError" name="error" :error="error!" :reload="refetch">
|
<slot v-else-if="isError" name="error" :error="error!" :reload="refetch">
|
||||||
<template v-if="!slots.error">
|
<template v-if="!slots.error">
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<a
|
||||||
|
:href="url"
|
||||||
|
class="font-mono text-nowrap text-sm text-gray-600 underline underline-offset-4 hover:text-gray-800 hover:no-underline"
|
||||||
|
target="_blank"
|
||||||
|
>{{ url }}</a
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{ url: string }>()
|
||||||
|
</script>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
icon="pi pi-telegram"
|
icon="pi pi-telegram"
|
||||||
title="Поделиться ссылкой в Telegram"
|
title="Поделиться ссылкой в Telegram"
|
||||||
label="отправить ссылку в Telegram"
|
label="Отправить ссылку в Telegram"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const ROUTE_NAMES = {
|
|||||||
MANAGE_QR_CODE_READY: 'manage-qr-code-ready',
|
MANAGE_QR_CODE_READY: 'manage-qr-code-ready',
|
||||||
MANAGE_QR_CODE_CHAT: 'manage-qr-code-chat',
|
MANAGE_QR_CODE_CHAT: 'manage-qr-code-chat',
|
||||||
MANAGE_DASHBOARD: 'manage-dashboard',
|
MANAGE_DASHBOARD: 'manage-dashboard',
|
||||||
|
MANAGE_DASHBOARD_QR: 'manage-dashboard-qr',
|
||||||
READ_QR_CODE: 'read-qr-code',
|
READ_QR_CODE: 'read-qr-code',
|
||||||
DONATE: 'donate',
|
DONATE: 'donate',
|
||||||
PUBLIC_CHAT: 'public-chat',
|
PUBLIC_CHAT: 'public-chat',
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ const routes = [
|
|||||||
component: () => import('@/views/ManageDashboardView.vue'),
|
component: () => import('@/views/ManageDashboardView.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/manage/qr',
|
||||||
|
name: ROUTE_NAMES.MANAGE_DASHBOARD_QR,
|
||||||
|
component: () => import('@/views/ManageDashboardView.vue'),
|
||||||
|
props: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/manage/qr/:qr_code_uri',
|
path: '/manage/qr/:qr_code_uri',
|
||||||
name: ROUTE_NAMES.MANAGE_QR_CODE,
|
name: ROUTE_NAMES.MANAGE_QR_CODE,
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-6">
|
<MetaHead>
|
||||||
<h1 class="text-2xl font-bold mb-4 text-center">Управление QR-кодами</h1>
|
<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">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-2xl font-bold mb-4 text-center lg:text-left">Управление QR-кодами</h1>
|
||||||
<QueryRender :query="query">
|
<QueryRender :query="query">
|
||||||
<template #default="{ data }">
|
<template #default="{ data }">
|
||||||
<div v-if="data.rows.length > 0" class="flex flex-col gap-5">
|
<div v-if="data.rows.length > 0" class="flex flex-col gap-5">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<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!" />
|
<QRCodeCard
|
||||||
|
v-for="{ doc: qrCode } in data.rows"
|
||||||
|
:key="qrCode!.uri"
|
||||||
|
:qrCode="qrCode!"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<Button
|
<Button
|
||||||
@@ -44,6 +58,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</QueryRender>
|
</QueryRender>
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
|
||||||
|
<p>
|
||||||
|
Нужен еще один?
|
||||||
|
<a href="/create" class="underline">Создайте QR‑код</a>.
|
||||||
|
</p>
|
||||||
|
<p class="mt-1">
|
||||||
|
Сделайте НаСвязи удобнее. Будем рады вашей <a href="/donate" class="underline"
|
||||||
|
>поддержке</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<section class="max-w-prose w-full flex flex-col gap-1">
|
<section class="max-w-prose w-full flex flex-col gap-1">
|
||||||
<p v-if="svgQueryIsLoading || qrCodeQueryIsLoading" class="text-gray-500 mt-4">
|
<div
|
||||||
Загрузка...
|
v-if="svgQueryIsLoading || qrCodeQueryIsLoading"
|
||||||
</p>
|
class="text-gray-500 mt-4 text-center"
|
||||||
|
>
|
||||||
|
<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">
|
||||||
Ошибка генерации QR‑кода: {{ svgQueryError?.message }}
|
Ошибка генерации QR‑кода: {{ svgQueryError?.message }}
|
||||||
</p>
|
</p>
|
||||||
@@ -62,16 +65,7 @@
|
|||||||
<div v-if="qrCodeDoc && qrCodeDoc.url" class="text-center mt-6 text-sm">
|
<div v-if="qrCodeDoc && qrCodeDoc.url" class="text-center mt-6 text-sm">
|
||||||
<div>
|
<div>
|
||||||
Ссылка в QR-коде:
|
Ссылка в QR-коде:
|
||||||
<span class="text-nowrap">
|
<LinkQRCode :url="qrCodeDoc.url" />
|
||||||
<a
|
|
||||||
class="font-mono text-sm text-gray-600 underline underline-offset-4 hover:text-gray-800 hover:no-underline"
|
|
||||||
:href="qrCodeDoc.url"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{{ qrCodeDoc.url }}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2 justify-center mt-2">
|
<div class="flex gap-2 justify-center mt-2">
|
||||||
<LinkCopyButton :url="qrCodeDoc.url" />
|
<LinkCopyButton :url="qrCodeDoc.url" />
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-6">
|
<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>
|
<h1 class="text-2xl font-bold mb-4 text-center lg:text-left">Управление QR-кодом</h1>
|
||||||
<QueryRender :query="qrCodeQuery" #default="{ data: qrCodeDoc }">
|
<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="bg-white p-6 rounded-lg shadow-md mb-6">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -9,15 +19,15 @@
|
|||||||
<h2 class="text-xl font-semibold">{{ qrCodeDoc.name }}</h2>
|
<h2 class="text-xl font-semibold">{{ qrCodeDoc.name }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<Button
|
<!-- <Button-->
|
||||||
icon="pi pi-cog"
|
<!-- icon="pi pi-cog"-->
|
||||||
label="Настроить"
|
<!-- label="Настроить"-->
|
||||||
:to="`/manage/qr/${qrCodeDoc.uri}/settings`"
|
<!-- :to="`/manage/qr/${qrCodeDoc.uri}/settings`"-->
|
||||||
as="router-link"
|
<!-- as="router-link"-->
|
||||||
severity="secondary"
|
<!-- severity="secondary"-->
|
||||||
size="small"
|
<!-- size="small"-->
|
||||||
outlined
|
<!-- outlined-->
|
||||||
/>
|
<!-- />-->
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-qrcode"
|
icon="pi pi-qrcode"
|
||||||
label="QR-код и инструкции"
|
label="QR-код и инструкции"
|
||||||
@@ -29,21 +39,27 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 flex gap-2 items-baseline">
|
<div class="mb-4 flex gap-2 items-baseline flex-wrap">
|
||||||
<strong>Ссылка: </strong>
|
<strong>Ссылка: </strong>
|
||||||
<a :href="qrCodeDoc.url" class="text-blue-500" target="_blank">{{ qrCodeDoc.url }}</a>
|
<LinkQRCode :url="qrCodeDoc.url" />
|
||||||
|
<div class="flex gap-2 items-baseline flex-wrap">
|
||||||
<LinkCopyButton :url="qrCodeDoc.url" />
|
<LinkCopyButton :url="qrCodeDoc.url" />
|
||||||
<LinkShareTelegramButton
|
<LinkShareTelegramButton
|
||||||
:shareUrl="qrCodeDoc.url"
|
:shareUrl="qrCodeDoc.url"
|
||||||
shareText="Используйте эту ссылку НаСвязи!"
|
shareText="Используйте эту ссылку НаСвязи!"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p><strong>Создано:</strong> {{ formatDate(qrCodeDoc.created_at) }}</p>
|
<p>
|
||||||
|
<strong>Создано: </strong>
|
||||||
|
<span class="text-nowrap">{{ formatDate(qrCodeDoc.created_at) }}</span>
|
||||||
|
</p>
|
||||||
<!-- <p><strong>Количество сканирований:</strong> {{ qrCodeDoc.scanCount }}</p>-->
|
<!-- <p><strong>Количество сканирований:</strong> {{ qrCodeDoc.scanCount }}</p>-->
|
||||||
<!-- <p><strong>Последнее сканирование:</strong> {{ formatDate(qrCodeDoc.lastScan) }}</p>-->
|
<!-- <p><strong>Последнее сканирование:</strong> {{ formatDate(qrCodeDoc.lastScan) }}</p>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</QueryRender>
|
</QueryRender>
|
||||||
|
|
||||||
<!-- <div class="bg-white p-6 rounded-lg shadow-md mb-6">-->
|
<!-- <div class="bg-white p-6 rounded-lg shadow-md mb-6">-->
|
||||||
@@ -71,13 +87,26 @@
|
|||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
|
||||||
|
<p>
|
||||||
|
Нужен еще один?
|
||||||
|
<a href="/create" class="underline">Создайте QR‑код</a>.
|
||||||
|
</p>
|
||||||
|
<p class="mt-1">
|
||||||
|
Сделайте НаСвязи удобнее. Будем рады вашей <a href="/donate" class="underline"
|
||||||
|
>поддержке</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import type { QRCodeDocument } from '@hereconnect/types'
|
import type { QRCodeDocument } from '@hereconnect/types'
|
||||||
import { getQrCodeDocument } from '@/api/qrCode'
|
import { getQrCodeDocument } from '@/api/qrCode'
|
||||||
import CopyLinkButton from '@/components/CopyLinkButton.vue'
|
|
||||||
|
|
||||||
const props = defineProps<{ qr_code_uri: QRCodeDocument['uri'] }>()
|
const props = defineProps<{ qr_code_uri: QRCodeDocument['uri'] }>()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user