support dark theme closes #25
This commit is contained in:
Vendored
+1
@@ -48,6 +48,7 @@ declare module 'vue' {
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
TabBar: typeof import('./src/components/layout/TabBar.vue')['default']
|
||||
TabMenuItem: typeof import('./src/components/layout/TabMenuItem.vue')['default']
|
||||
Textarea: typeof import('primevue/textarea')['default']
|
||||
TheWelcome: typeof import('./src/components/TheWelcome/TheWelcome.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
"postcss": "^8.4.49",
|
||||
"prettier": "^3.3.3",
|
||||
"rollup-plugin-manifest-json": "^1.7.0",
|
||||
"sass-embedded": "^1.82.0",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"tailwindcss-safe-area": "^0.6.0",
|
||||
"typescript": "~5.6.3",
|
||||
|
||||
@@ -29,6 +29,22 @@ registerServiceWorker()
|
||||
// })
|
||||
// })
|
||||
// .catch(console.error)
|
||||
|
||||
// import { usePrefersColorSchemeStore } from '@/stores/usePrefersColorSchemeStore'
|
||||
// import { watch } from 'vue'
|
||||
// const { isDarkMode } = usePrefersColorSchemeStore()
|
||||
//
|
||||
// watch(
|
||||
// () => isDarkMode,
|
||||
// () => {
|
||||
// if (isDarkMode) {
|
||||
// document.documentElement.classList.add('dark')
|
||||
// } else {
|
||||
// document.documentElement.classList.remove('dark')
|
||||
// }
|
||||
// },
|
||||
// { immediate: true },
|
||||
// )
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
<template>
|
||||
<RouterLink :to="route" class="p-4 rounded-lg bg-white shadow-md">
|
||||
<RouterLink
|
||||
:to="route"
|
||||
class="p-4 rounded-lg bg-white dark:bg-gray-800 shadow-md text-gray-800 dark:text-gray-300"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2" v-if="qrCodeDoc">
|
||||
<div class="flex items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<QRCodePlacementIcon :placement="qrCodeDoc.placement" />
|
||||
<h2 class="text-lg font-semibold">{{ qrCodeDoc.name }}</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100">
|
||||
{{ qrCodeDoc.name }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-gray-500">
|
||||
<div class="text-gray-500 dark:text-gray-400">
|
||||
<span class="text-nowrap">{{ formatedCreatedAt }}</span>
|
||||
</div>
|
||||
</RouterLink>
|
||||
|
||||
@@ -6,44 +6,53 @@
|
||||
</div>
|
||||
<Checkbox v-else v-model="enabled" inputId="webPush" name="delivery" binary />
|
||||
|
||||
<label for="webPush">Прислать уведомление, когда придет ответ</label>
|
||||
<label for="webPush" class="text-gray-800 dark:text-gray-300">
|
||||
Прислать уведомление, когда придет ответ
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Инструкции для iOS -->
|
||||
<div
|
||||
v-if="showRequireStandaloneInstructionsForIOS"
|
||||
class="bg-yellow-100 text-yellow-800 p-4 rounded my-4"
|
||||
class="bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-300 p-4 rounded my-4"
|
||||
>
|
||||
<p class="mb-2">Чтобы включить уведомления, добавьте это приложение на главный экран:</p>
|
||||
<p class="mb-2 dark:text-yellow-200">
|
||||
Чтобы включить уведомления, добавьте это приложение на главный экран:
|
||||
</p>
|
||||
<ul class="list-disc pl-5">
|
||||
<li class="mb-1">
|
||||
<li class="mb-1 dark:text-yellow-200">
|
||||
Нажмите
|
||||
<strong class="font-semibold">
|
||||
"<img
|
||||
src="@/assets/icons/apple-share.svg?url"
|
||||
alt="Поделиться"
|
||||
class="h-7 -mt-2 inline-block"
|
||||
class="h-7 -mt-2 inline-block dark:filter dark:invert"
|
||||
/>"
|
||||
</strong>
|
||||
внизу экрана
|
||||
</li>
|
||||
<li class="mb-1">
|
||||
<li class="mb-1 dark:text-yellow-200">
|
||||
Выберите
|
||||
<strong class="inline-flex items-baseline font-semibold">
|
||||
<span class="me-1">"На экран «Домой»</span>
|
||||
<img
|
||||
src="@/assets/icons/apple-system-plus.svg?url"
|
||||
alt=""
|
||||
class="h-4 inline-block self-center"
|
||||
/>"
|
||||
class="h-4 inline-block self-center dark:filter dark:invert"
|
||||
/>
|
||||
"
|
||||
</strong>
|
||||
</li>
|
||||
<li>Откройте приложение с главного экрана и повторите попытку.</li>
|
||||
<li class="dark:text-yellow-200">
|
||||
Откройте приложение с главного экрана и повторите попытку.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Ошибка разрешений -->
|
||||
<p v-else-if="isError" class="text-red-500 mb-2">{{ error?.message || error }}<br /></p>
|
||||
<p v-else-if="isError" class="text-red-500 dark:text-red-400 mb-2">
|
||||
{{ error?.message || error }}<br />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -240,6 +249,6 @@ watch(
|
||||
)
|
||||
|
||||
const showRequireStandaloneInstructionsForIOS = computed(
|
||||
() => isError.value && isIOS.value && !isStandalone.value && enabled.value,
|
||||
() => true, //isError.value && isIOS.value && !isStandalone.value && enabled.value,
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="max-w-screen-sm mx-auto px-4 md:px-0 font-sans text-gray-800">
|
||||
<div class="max-w-screen-sm mx-auto px-4 md:px-0 font-sans text-gray-800 dark:text-gray-100">
|
||||
<!-- Hero Section -->
|
||||
<section class="text-center py-12">
|
||||
<div class="flex flex-col md:flex-row items-center gap-8">
|
||||
@@ -14,7 +14,7 @@
|
||||
</RouterLink>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold">Создайте уникальный QR‑код для связи</h1>
|
||||
<p class="mt-2 text-lg text-gray-600 text-justify">
|
||||
<p class="mt-2 text-lg text-gray-600 dark:text-gray-400 text-justify">
|
||||
Люди смогут отправлять вам сообщения, сканируя этот QR‑код, без необходимости раскрывать
|
||||
ваши контактные данные.
|
||||
</p>
|
||||
@@ -29,12 +29,12 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr />
|
||||
<hr class="dark:border-gray-700" />
|
||||
|
||||
<!-- Where to Use Section -->
|
||||
<section id="setup" class="py-8 text-center">
|
||||
<h2 class="text-2xl font-semibold">Где использовать?</h2>
|
||||
<p class="mt-2 text-lg text-gray-600 text-justify">
|
||||
<p class="mt-2 text-lg text-gray-600 dark:text-gray-400 text-justify">
|
||||
QR‑код можно будет разместить на вашем автомобиле, на входной двери или на ошейнике вашего
|
||||
питомца — это позволит окружающим легко связаться с вами в случае необходимости, при этом
|
||||
ваши контактные данные останутся конфиденциальными.
|
||||
@@ -46,7 +46,7 @@
|
||||
<!-- Simple Setup Section -->
|
||||
<section id="settings" class="py-8 text-center">
|
||||
<h2 class="text-2xl font-semibold">Легкость настройки</h2>
|
||||
<p class="mt-2 text-lg text-gray-600 text-justify">
|
||||
<p class="mt-2 text-lg text-gray-600 dark:text-gray-400 text-justify">
|
||||
Создайте QR‑код, выберите доступные действия и начните использовать.
|
||||
</p>
|
||||
<div class="flex justify-center mt-6">
|
||||
@@ -61,7 +61,7 @@
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="py-4 border-t text-center">
|
||||
<footer class="py-4 border-t text-center dark:border-gray-700">
|
||||
<p>НаСвязи © 2024</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
<InputText
|
||||
id="newMessage"
|
||||
v-model="newMessage"
|
||||
class="flex-1"
|
||||
class="flex-1 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700"
|
||||
placeholder="Напишите сообщение"
|
||||
/>
|
||||
<Button type="submit" icon="pi pi-send" class="p-button-md" :disabled="!newMessage.trim()" />
|
||||
<Button
|
||||
type="submit"
|
||||
icon="pi pi-send"
|
||||
class="p-button-md dark:bg-primary-600 dark:hover:bg-primary-700"
|
||||
:disabled="!newMessage.trim()"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<ChatSubscribeWebPush :qr_code_uri :chat :user_chat_role="userRole" />
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
<Card
|
||||
class="p-card-sm"
|
||||
:class="{
|
||||
'bg-blue-50 border-blue-300 text-blue-500': message.from === userRole,
|
||||
'bg-gray-50 border-gray-300 text-gray-700': message.from !== userRole,
|
||||
'bg-blue-50 dark:bg-blue-900 border-blue-300 dark:border-blue-700 text-blue-500 dark:text-blue-200':
|
||||
message.from === userRole,
|
||||
'bg-gray-50 dark:bg-gray-800 border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300':
|
||||
message.from !== userRole,
|
||||
}"
|
||||
>
|
||||
<template #content>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold mb-4">Выберите доступные действия</h2>
|
||||
<p class="text-gray-600 mb-4">Укажите, какие действия будут доступны для сканирующих QR‑код.</p>
|
||||
<p class="text-sm text-gray-500 mb-6">Вы сможете изменить эти настройки позже.</p>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Выберите доступные действия
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Укажите, какие действия будут доступны для сканирующих QR‑код.
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
|
||||
Вы сможете изменить эти настройки позже.
|
||||
</p>
|
||||
<div class="flex flex-col gap-3 mb-4">
|
||||
<div v-for="(label, action) in actionsOptions" :key="action" class="flex items-center gap-2">
|
||||
<Checkbox v-model="model" :inputId="action" :value="action" @change="next" />
|
||||
<label :for="action">{{ label }}</label>
|
||||
<label :for="action" class="text-gray-700 dark:text-gray-300">{{ label }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold mb-4">Куда отправлять сообщения?</h2>
|
||||
<p class="text-gray-600 mb-4">Выберите, как вы хотите получать сообщения.</p>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Куда отправлять сообщения?
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">Выберите, как вы хотите получать сообщения.</p>
|
||||
<CreateMessageDeliveryOptions>
|
||||
<template #telegram="{ label, method }">
|
||||
<CreateMessageDeliveryOptionTelegram
|
||||
@@ -9,6 +11,7 @@
|
||||
:method
|
||||
v-model="localModel"
|
||||
@change="onChange"
|
||||
class="text-gray-700 dark:text-gray-300"
|
||||
/>
|
||||
</template>
|
||||
<template #webPush="{ label, method }">
|
||||
@@ -17,10 +20,17 @@
|
||||
:method
|
||||
v-model="localModel"
|
||||
@change="onChange"
|
||||
class="text-gray-700 dark:text-gray-300"
|
||||
/>
|
||||
</template>
|
||||
<template #default="{ label, method }">
|
||||
<CreateMessageDeliveryOption :label :method v-model="localModel" @change="onChange" />
|
||||
<CreateMessageDeliveryOption
|
||||
:label
|
||||
:method
|
||||
v-model="localModel"
|
||||
@change="onChange"
|
||||
class="text-gray-700 dark:text-gray-300"
|
||||
/>
|
||||
</template>
|
||||
</CreateMessageDeliveryOptions>
|
||||
</section>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<CreateMessageDeliveryOption :label :method v-model="model" />
|
||||
|
||||
<!-- Сообщение о недоступности -->
|
||||
<p v-if="telegramNotice" class="text-red-500 mb-2">
|
||||
<p v-if="telegramNotice" class="text-red-500 dark:text-red-400 my-2 outline outline-1 py-2 px-4">
|
||||
Отправка в Telegram пока в разработке.<br />
|
||||
Этот способ отправки сообщений можно будет выбрать позже.
|
||||
</p>
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
<!-- Инструкции для iOS -->
|
||||
<div
|
||||
v-if="showRequireStandaloneInstructionsForIOS"
|
||||
class="bg-yellow-100 text-yellow-800 p-4 rounded my-4"
|
||||
class="bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-300 p-4 rounded my-4"
|
||||
>
|
||||
<p class="mb-2">Чтобы включить уведомления, добавьте это приложение на главный экран:</p>
|
||||
<p class="mb-2 dark:text-yellow-200">
|
||||
Чтобы включить уведомления, добавьте это приложение на главный экран:
|
||||
</p>
|
||||
<ul class="list-disc pl-5">
|
||||
<li class="mb-1">
|
||||
<li class="mb-1 dark:text-yellow-200">
|
||||
Нажмите
|
||||
<strong class="font-semibold">
|
||||
"<img
|
||||
@@ -19,7 +21,7 @@
|
||||
</strong>
|
||||
внизу экрана
|
||||
</li>
|
||||
<li class="mb-1">
|
||||
<li class="mb-1 dark:text-yellow-200">
|
||||
Выберите
|
||||
<strong class="inline-flex items-baseline font-semibold">
|
||||
<span class="me-1">"На экран «Домой»</span>
|
||||
@@ -30,14 +32,16 @@
|
||||
/>"
|
||||
</strong>
|
||||
</li>
|
||||
<li>Откройте приложение с главного экрана и повторите попытку.</li>
|
||||
<li class="dark:text-yellow-200">
|
||||
Откройте приложение с главного экрана и повторите попытку.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Ошибка разрешений -->
|
||||
<p v-else-if="isError && model === method" class="text-red-500 mb-2">
|
||||
<p v-else-if="isError && model === method" class="text-red-500 dark:text-red-400 mb-2">
|
||||
{{ error }}.<br />
|
||||
<button @click="retry()" class="text-blue-500 underline">Повторить</button>
|
||||
<button @click="retry()" class="text-blue-500 dark:text-blue-400 underline">Повторить</button>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold mb-4">Где вы хотите разместить QR‑код?</h2>
|
||||
<p class="text-gray-600 mb-4">Этот выбор поможет настроить QR‑код с подходящими действиями.</p>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Где вы хотите разместить QR‑код?
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Этот выбор поможет настроить QR‑код с подходящими действиями.
|
||||
</p>
|
||||
<div class="flex flex-col gap-3 mb-4">
|
||||
<div v-for="{ label, type } in qrCodePlacements" :key="type" class="flex items-center gap-2">
|
||||
<RadioButton
|
||||
@@ -11,7 +15,7 @@
|
||||
:value="type"
|
||||
@change="$emit('nextStep')"
|
||||
/>
|
||||
<label :for="type">{{ label }}</label>
|
||||
<label :for="type" class="text-gray-700 dark:text-gray-300">{{ label }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold mb-4">Сообщения для отправки</h2>
|
||||
<p class="text-gray-600 mb-4">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Сообщения для отправки
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
После считывания QR‑кода можно будет выбрать одно из этих сообщений или написать своё.
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 mb-6">Вы сможете изменить эти сообщения позже.</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
|
||||
Вы сможете изменить эти сообщения позже.
|
||||
</p>
|
||||
|
||||
<!-- Список сообщений -->
|
||||
<div class="flex flex-col gap-2 mb-4">
|
||||
<div v-for="(message, index) in messages" :key="index" class="flex gap-2" ref="messagesRef">
|
||||
<InputText v-model="messages[index]" class="flex-1" placeholder="Введите сообщение" />
|
||||
<InputText
|
||||
v-model="messages[index]"
|
||||
class="flex-1 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700"
|
||||
placeholder="Введите сообщение"
|
||||
/>
|
||||
<Button
|
||||
icon="pi pi-trash"
|
||||
class="p-button-danger p-button-text"
|
||||
variant="text"
|
||||
@click="removeMessage(index)"
|
||||
title="Удалить сообщение"
|
||||
/>
|
||||
@@ -23,7 +31,7 @@
|
||||
<Button
|
||||
label="Добавить сообщение"
|
||||
icon="pi pi-plus"
|
||||
class="p-button-sm p-button-outlined mb-4"
|
||||
class="p-button-sm p-button-outlined mb-4 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-300"
|
||||
@click="addMessage"
|
||||
/>
|
||||
</section>
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold mb-4">Введите название для вашего QR‑кода</h2>
|
||||
<p class="text-gray-600 mb-4">Название поможет вам организовать ваши QR‑коды.</p>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Введите название для вашего QR‑кода
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Название поможет вам организовать ваши QR‑коды.
|
||||
</p>
|
||||
|
||||
<form @submit.prevent="emit('nextStep')">
|
||||
<label for="name" class="block text-gray-700 font-semibold mb-2">Название</label>
|
||||
<InputText id="name" v-model="name" class="w-full" placeholder="Введите название" />
|
||||
<p v-if="!name" class="text-red-500 text-sm mt-1">Название обязательно.</p>
|
||||
<label for="name" class="block text-gray-700 dark:text-gray-300 font-semibold mb-2">
|
||||
Название
|
||||
</label>
|
||||
<InputText
|
||||
id="name"
|
||||
v-model="name"
|
||||
class="w-full dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700"
|
||||
placeholder="Введите название"
|
||||
/>
|
||||
<p v-if="!name" class="text-red-500 dark:text-red-400 text-sm mt-1">Название обязательно</p>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
:label="buttonLabel"
|
||||
class="p-button-md mt-4 mb-4"
|
||||
class="p-button-md mt-4 mb-4 dark:border-orange-500 dark:hover:border-orange-600 dark:text-gray-300"
|
||||
:loading="isPending"
|
||||
:disabled="!name || isPending"
|
||||
/>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
class="sticky bottom-0 bg-white shadow-md py-safe-or-4 sm:border-b sm:order-first sm:justify-center touch-none"
|
||||
class="sticky bottom-0 bg-white dark:bg-gray-800 shadow-md dark:shadow-lg py-safe-or-4 sm:border-b dark:sm:border-gray-700 sm:order-first sm:justify-center touch-none"
|
||||
>
|
||||
<div
|
||||
class="flex justify-around sm:justify-between sm:gap-8 sm:px-4 sm:flex-row sm:bg-white sm:max-w-prose mx-auto"
|
||||
class="flex justify-around sm:justify-between sm:gap-8 sm:px-4 sm:flex-row sm:bg-white dark:sm:bg-gray-800 sm:max-w-prose mx-auto"
|
||||
>
|
||||
<TabMenuItem
|
||||
v-for="{ route, label, icon, unreadCount } in tabs"
|
||||
@@ -12,6 +12,7 @@
|
||||
:icon
|
||||
:to="{ name: route }"
|
||||
:unreadCount
|
||||
class="dark:text-gray-300 dark:hover:text-gray-100"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,16 +6,26 @@
|
||||
@click="navigate"
|
||||
class="flex flex-col items-center w-full sm:flex-row sm:items-center sm:w-auto gap-1 relative"
|
||||
>
|
||||
<i :class="['pi', `pi-${icon}`, 'text-2xl sm:mr-2', isActive && 'text-primary-700']"></i>
|
||||
<i
|
||||
:class="[
|
||||
'pi',
|
||||
`pi-${icon}`,
|
||||
'text-2xl sm:mr-2',
|
||||
isActive ? 'text-primary-700 dark:text-primary-300' : 'text-gray-700 dark:text-gray-300',
|
||||
]"
|
||||
></i>
|
||||
<span
|
||||
class="text-xs font-medium sm:text-base text-center"
|
||||
:class="{ 'text-primary-700': isActive, 'text-gray-700': !isActive }"
|
||||
:class="{
|
||||
'text-primary-700 dark:text-primary-300': isActive,
|
||||
'text-gray-700 dark:text-gray-300': !isActive,
|
||||
}"
|
||||
>
|
||||
{{ label }}
|
||||
</span>
|
||||
<span
|
||||
v-if="unreadCount && unreadCount > 0"
|
||||
class="absolute top-0 -right-2.5 bg-red-500 text-white text-xs rounded-full px-1"
|
||||
class="absolute top-0 -right-2.5 bg-red-500 dark:bg-red-600 text-white text-xs rounded-full px-1"
|
||||
>
|
||||
{{ unreadCount }}
|
||||
</span>
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
<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"
|
||||
class="font-mono text-nowrap text-sm hover:no-underline"
|
||||
target="_blank"
|
||||
>{{ url }}</a
|
||||
>
|
||||
v-text="url"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
a {
|
||||
color: var(--p-surface-500); // Очень нейтральный цвет для менее акцентной ссылки
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--p-surface-700); // Немного более насыщенный цвет при наведении
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ url: string }>()
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="max-w-3xl mx-auto py-6 px-4 md:px-6">
|
||||
<div v-if="isLoading" class="text-gray-500">Загрузка инструкции...</div>
|
||||
<div v-else-if="data" class="markdown">
|
||||
<div v-if="isLoading" class="text-gray-500 dark:text-gray-400">Загрузка инструкции...</div>
|
||||
<div v-else-if="data" class="markdown dark:text-gray-300">
|
||||
<VueMarkdownIt :source="data" />
|
||||
</div>
|
||||
<p v-else-if="isError" class="text-red-500">Ошибка загрузки инструкции.</p>
|
||||
<p v-else class="text-gray-500">Инструкция для этого типа размещения отсутствует.</p>
|
||||
<p v-else-if="isError" class="text-red-500 dark:text-red-400">Ошибка загрузки инструкции.</p>
|
||||
<p v-else class="text-gray-500 dark:text-gray-400">
|
||||
Инструкция для этого типа размещения отсутствует.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -35,102 +37,97 @@ const { isLoading, isError, data } = useQuery({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.markdown {
|
||||
font-family: 'Inter', sans-serif;
|
||||
line-height: 1.7;
|
||||
color: #333;
|
||||
}
|
||||
color: var(--p-text-color);
|
||||
|
||||
.markdown ::v-deep(h1) {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #111827;
|
||||
font-weight: 700;
|
||||
}
|
||||
& ::v-deep(h1) {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--p-primary-color);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(h2) {
|
||||
font-size: 1.75rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #1f2937;
|
||||
font-weight: 600;
|
||||
}
|
||||
& ::v-deep(h2) {
|
||||
font-size: 1.75rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--p-secondary-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(h3) {
|
||||
font-size: 1.5rem;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.75rem;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
}
|
||||
& ::v-deep(h3) {
|
||||
font-size: 1.5rem;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--p-secondary-light-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(p) {
|
||||
margin-bottom: 1rem;
|
||||
color: #4b5563;
|
||||
}
|
||||
& ::v-deep(p) {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--p-text-secondary-color);
|
||||
}
|
||||
|
||||
.markdown ::v-deep(ul) {
|
||||
list-style: disc;
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
& ::v-deep(ul),
|
||||
& ::v-deep(ol) {
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(ol) {
|
||||
list-style: decimal;
|
||||
margin-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
& ::v-deep(li) {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(li) {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
& ::v-deep(a) {
|
||||
color: var(--p-link-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(a) {
|
||||
color: #2563eb;
|
||||
text-decoration: underline;
|
||||
}
|
||||
& ::v-deep(blockquote) {
|
||||
border-left: 4px solid var(--p-border-color);
|
||||
padding-left: 1rem;
|
||||
color: var(--p-text-secondary-color);
|
||||
margin: 1rem 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(blockquote) {
|
||||
border-left: 4px solid #d1d5db;
|
||||
padding-left: 1rem;
|
||||
color: #6b7280;
|
||||
margin: 1rem 0;
|
||||
font-style: italic;
|
||||
}
|
||||
& ::v-deep(code) {
|
||||
background-color: var(--p-surface-50);
|
||||
border-radius: 4px;
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
color: var(--p-text-color);
|
||||
}
|
||||
|
||||
.markdown ::v-deep(code) {
|
||||
background-color: #f3f4f6;
|
||||
border-radius: 4px;
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
color: #1f2937;
|
||||
}
|
||||
& ::v-deep(pre) {
|
||||
background-color: var(--p-surface-100);
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
color: var(--p-text-color);
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(pre) {
|
||||
background-color: #f9fafb;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
color: #111827;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
& ::v-deep(table) {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(table) {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
& ::v-deep(th),
|
||||
& ::v-deep(td) {
|
||||
border: 1px solid var(--p-border-color);
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(th),
|
||||
.markdown ::v-deep(td) {
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown ::v-deep(th) {
|
||||
background-color: #f9fafb;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
& ::v-deep(th) {
|
||||
background-color: var(--p-surface-200);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
color: var(--p-text-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<template>
|
||||
<RouterLink :to="`/manage/qr/${qrCode.uri}`" class="p-4 rounded-lg bg-white shadow-md">
|
||||
<RouterLink
|
||||
:to="`/manage/qr/${qrCode.uri}`"
|
||||
class="p-4 rounded-lg bg-white dark:bg-gray-800 shadow-md text-gray-800 dark:text-gray-300"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="flex items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<QRCodePlacementIcon :placement="qrCode.placement" />
|
||||
<h2 class="text-lg font-semibold">{{ qrCode.name }}</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100">
|
||||
{{ qrCode.name }}
|
||||
</h2>
|
||||
</div>
|
||||
<!-- <Button-->
|
||||
<!-- label="Настроить"-->
|
||||
<!-- :to="`/manage/${qrCode.uri}/settings`"-->
|
||||
<!-- as="router-link"-->
|
||||
<!-- class="p-button-outlined p-button-sm"-->
|
||||
<!-- />-->
|
||||
</div>
|
||||
<div class="text-gray-500">
|
||||
<div class="text-gray-500 dark:text-gray-400">
|
||||
Создан: <span class="text-nowrap">{{ formatedCreatedAt }}</span>
|
||||
</div>
|
||||
</RouterLink>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<i :class="['pi', iconClass, 'text-gray-500', 'mr-2']" />
|
||||
<i :class="['pi', iconClass, 'text-gray-500', 'dark:text-gray-300', 'mr-2']" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<section class="max-w-prose w-full text-center">
|
||||
<!-- Контактная информация -->
|
||||
<div class="flex items-start bg-gray-100 border rounded-lg p-4">
|
||||
<div
|
||||
class="flex items-start bg-gray-100 dark:bg-gray-800 border dark:border-gray-700 rounded-lg p-4"
|
||||
>
|
||||
<!-- Аватарка Gravatar -->
|
||||
<div v-if="contactInfo.email" class="flex-shrink-0 mr-4">
|
||||
<img
|
||||
@@ -14,18 +16,23 @@
|
||||
|
||||
<!-- Контакты -->
|
||||
<div class="text-left flex-grow">
|
||||
<p v-if="contactInfo.name" class="text-lg font-semibold">{{ contactInfo.name }}</p>
|
||||
<p v-if="contactInfo.name" class="text-lg font-semibold text-gray-900 dark:text-gray-100">
|
||||
{{ contactInfo.name }}
|
||||
</p>
|
||||
|
||||
<p v-if="contactInfo.phone" class="text-gray-700">
|
||||
<p v-if="contactInfo.phone" class="text-gray-700 dark:text-gray-300">
|
||||
Телефон:
|
||||
<a :href="`tel:${formattedPhone}`" class="underline text-blue-600">
|
||||
<a :href="`tel:${formattedPhone}`" class="underline text-blue-600 dark:text-blue-400">
|
||||
{{ contactInfo.phone }}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p v-if="contactInfo.email" class="text-gray-700">
|
||||
<p v-if="contactInfo.email" class="text-gray-700 dark:text-gray-300">
|
||||
Email:
|
||||
<a :href="`mailto:${contactInfo.email}`" class="underline text-blue-600">
|
||||
<a
|
||||
:href="`mailto:${contactInfo.email}`"
|
||||
class="underline text-blue-600 dark:text-blue-400"
|
||||
>
|
||||
{{ contactInfo.email }}
|
||||
</a>
|
||||
</p>
|
||||
@@ -40,8 +47,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p v-if="success" class="text-green-500 mt-4">Контакт успешно добавлен в адресную книгу!</p>
|
||||
<p v-if="error" class="text-red-500 mt-4">Ошибка добавления контакта: {{ error }}</p>
|
||||
<p v-if="success" class="text-green-500 dark:text-green-400 mt-4">
|
||||
Контакт успешно добавлен в адресную книгу!
|
||||
</p>
|
||||
<p v-if="error" class="text-red-500 dark:text-red-400 mt-4">
|
||||
Ошибка добавления контакта: {{ error }}
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<section class="max-w-prose w-full">
|
||||
<p class="text-gray-600 mb-4 text-center" v-if="doc.predefinedMessages?.length">
|
||||
<p
|
||||
class="text-gray-600 dark:text-gray-400 mb-4 text-center"
|
||||
v-if="doc.predefinedMessages?.length"
|
||||
>
|
||||
Выберите сообщение из списка или напишите своё:
|
||||
</p>
|
||||
|
||||
@@ -10,7 +13,7 @@
|
||||
<Button
|
||||
v-for="(message, index) in doc.predefinedMessages"
|
||||
:key="index"
|
||||
class="p-button-outlined w-full text-left"
|
||||
class="w-full p-button-outlined text-left dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700"
|
||||
:disabled="loading"
|
||||
@click="sendPresetMessage(message)"
|
||||
>
|
||||
@@ -24,20 +27,22 @@
|
||||
<InputText
|
||||
id="customMessage"
|
||||
v-model="customMessage"
|
||||
class="flex-1"
|
||||
class="flex-1 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700"
|
||||
placeholder="Напишите сообщение"
|
||||
:disabled="loading"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
icon="pi pi-send"
|
||||
class="p-button-md"
|
||||
class="p-button-md dark:bg-primary-600 dark:hover:bg-primary-700"
|
||||
:disabled="!customMessage.trim() || loading"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<p v-if="success" class="text-green-500 mt-4 text-center">Сообщение отправлено!</p>
|
||||
<p v-if="error" class="text-red-500 mt-4 text-center">Ошибка: {{ error }}</p>
|
||||
<p v-if="success" class="text-green-500 dark:text-green-400 mt-4 text-center">
|
||||
Сообщение отправлено!
|
||||
</p>
|
||||
<p v-if="error" class="text-red-500 dark:text-red-400 mt-4 text-center">Ошибка: {{ error }}</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<div
|
||||
class="grid h-full sm:grid-rows-[auto_1fr_auto] grid-rows-[1fr_auto_auto] overflow-hidden touch-none"
|
||||
>
|
||||
<!-- Content Section -->
|
||||
<div
|
||||
class="flex overflow-hidden overflow-y-auto pb-safe-or-4 sm:pt-safe px-4 overscroll-contain touch-manipulation"
|
||||
ref="contentScrollContainer"
|
||||
@@ -11,20 +12,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Section -->
|
||||
<slot name="footer">
|
||||
<footer
|
||||
v-if="!slots.footer"
|
||||
class="bg-gray-100 text-center py-1.5 border-t text-xs sm:text-base text-gray-700 sm:order-last sm:pb-safe-or-1.5"
|
||||
class="bg-gray-100 dark:bg-gray-800 text-center py-1.5 border-t dark:border-gray-700 text-xs sm:text-base text-gray-700 dark:text-gray-300 sm:order-last sm:pb-safe-or-1.5"
|
||||
>
|
||||
<span class="text-nowrap">Сделайте НаСвязи удобнее.</span>
|
||||
<span> </span>
|
||||
<span class="text-nowrap">
|
||||
Будем рады
|
||||
<a href="/donate" class="underline underline-offset-2">вашей поддержке</a>
|
||||
<a
|
||||
href="/donate"
|
||||
class="underline underline-offset-2 text-primary-600 dark:text-primary-400"
|
||||
>
|
||||
вашей поддержке
|
||||
</a>
|
||||
</span>
|
||||
</footer>
|
||||
</slot>
|
||||
|
||||
<!-- TabBar -->
|
||||
<TabBar />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,29 +6,10 @@ import { VueQueryPlugin, type VueQueryPluginOptions } from '@tanstack/vue-query'
|
||||
import PouchDB from '@/api/PouchDB'
|
||||
|
||||
import PrimeVue from 'primevue/config'
|
||||
import { definePreset } from '@primevue/themes'
|
||||
import Aura from '@primevue/themes/aura'
|
||||
import { PrimeVueHereConnectPreset } from './themes/PrimeVueHereConnectPreset'
|
||||
import './style.css'
|
||||
import 'primeicons/primeicons.css'
|
||||
|
||||
const MyPreset = definePreset(Aura, {
|
||||
semantic: {
|
||||
primary: {
|
||||
50: '{rose.50}',
|
||||
100: '{rose.100}',
|
||||
200: '{rose.200}',
|
||||
300: '{rose.300}',
|
||||
400: '{rose.400}',
|
||||
500: '{rose.500}',
|
||||
600: '{rose.600}',
|
||||
700: '{rose.700}',
|
||||
800: '{rose.800}',
|
||||
900: '{rose.900}',
|
||||
950: '{rose.950}',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
@@ -55,9 +36,9 @@ app.use(VueQueryPlugin, vueQueryPluginOptions)
|
||||
app.use(router)
|
||||
app.use(PrimeVue, {
|
||||
theme: {
|
||||
preset: MyPreset,
|
||||
preset: PrimeVueHereConnectPreset,
|
||||
options: {
|
||||
darkModeSelector: false,
|
||||
darkModeSelector: 'system',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ref, watch } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const usePrefersColorSchemeStore = defineStore('prefersColorScheme', () => {
|
||||
const prefersColorSchemeDarkMatchMedia = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
const isDarkMode = ref<boolean>(prefersColorSchemeDarkMatchMedia.matches)
|
||||
|
||||
prefersColorSchemeDarkMatchMedia.addEventListener('change', (e) => {
|
||||
isDarkMode.value = e.matches
|
||||
})
|
||||
|
||||
return { isDarkMode }
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import { definePreset } from '@primevue/themes'
|
||||
import Aura from '@primevue/themes/aura'
|
||||
|
||||
export const PrimeVueHereConnectPreset = definePreset(Aura, {
|
||||
semantic: {
|
||||
colorScheme: {
|
||||
light: {
|
||||
primary: {
|
||||
50: '{rose.50}',
|
||||
100: '{rose.100}',
|
||||
200: '{rose.200}',
|
||||
300: '{rose.300}',
|
||||
400: '{rose.400}',
|
||||
500: '{rose.500}',
|
||||
600: '{rose.600}',
|
||||
700: '{rose.700}',
|
||||
800: '{rose.800}',
|
||||
900: '{rose.900}',
|
||||
950: '{rose.950}',
|
||||
},
|
||||
highlight: {
|
||||
background: '{rose.100}',
|
||||
focusBackground: '{rose.200}',
|
||||
color: '#000000',
|
||||
focusColor: '#000000',
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
primary: {
|
||||
50: '{orange.50}',
|
||||
100: '{orange.100}',
|
||||
200: '{orange.200}',
|
||||
300: '{orange.300}',
|
||||
400: '{orange.400}',
|
||||
500: '{orange.500}',
|
||||
600: '{orange.600}',
|
||||
700: '{yellow.700}',
|
||||
800: '{orange.800}',
|
||||
900: '{orange.900}',
|
||||
950: '{orange.950}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -39,7 +39,9 @@
|
||||
</template>
|
||||
</CreateSectionManager>
|
||||
|
||||
<p v-if="isError" class="text-red-500 mt-4">Ошибка создания QR‑кода: {{ error }}</p>
|
||||
<p v-if="isError" class="text-red-500 dark:text-red-400 mt-4">
|
||||
Ошибка создания QR‑кода: {{ error }}
|
||||
</p>
|
||||
|
||||
<div class="h-[30dvh] md:h-[10dvh] overflow-hidden"></div>
|
||||
</LayoutWithTabs>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<LayoutWithTabs>
|
||||
<template #footer>
|
||||
<footer class="py-4 border-t text-center text-sm hidden sm:block">
|
||||
<footer
|
||||
class="py-4 border-t text-center text-sm hidden sm:block border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
<p>НаСвязи © 2024</p>
|
||||
</footer>
|
||||
</template>
|
||||
@@ -12,8 +14,10 @@
|
||||
</MetaHead>
|
||||
|
||||
<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">
|
||||
<h1 class="text-2xl font-bold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Поддержите развитие НаСвязи
|
||||
</h1>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-6">
|
||||
Мы делаем всё, чтобы НаСвязи оставался удобным и полезным. Вы можете помочь нам, поддержав
|
||||
проект на Бусти.
|
||||
</p>
|
||||
@@ -24,7 +28,7 @@
|
||||
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"
|
||||
class="inline-block bg-orange-500 text-white font-semibold py-3 px-6 rounded-lg shadow hover:bg-orange-600 transition duration-300 dark:hover:bg-orange-700"
|
||||
>
|
||||
Поддержать через Бусти
|
||||
</a>
|
||||
@@ -32,8 +36,10 @@
|
||||
|
||||
<!-- Рассказать друзьям -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4">Рассказать друзьям</h2>
|
||||
<p class="text-gray-600 mb-4">Поделитесь ссылкой на НаСвязи:</p>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Рассказать друзьям
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">Поделитесь ссылкой на НаСвязи:</p>
|
||||
<div class="flex justify-center gap-6">
|
||||
<!-- Telegram -->
|
||||
<a
|
||||
@@ -56,31 +62,6 @@
|
||||
</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>
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
<!-- Уведомление, если гость отправил только одно сообщение -->
|
||||
<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 my-6"
|
||||
class="flex flex-col items-center justify-center text-center bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-md p-6 my-6"
|
||||
>
|
||||
<p class="text-gray-700 font-medium text-lg">Ваше сообщение отправлено.</p>
|
||||
<p class="text-gray-600 mt-2">
|
||||
<p class="text-gray-700 dark:text-gray-200 font-medium text-lg">
|
||||
Ваше сообщение отправлено.
|
||||
</p>
|
||||
<p class="text-gray-600 dark:text-gray-400 mt-2">
|
||||
Вы можете написать ещё одно сообщение или подождать ответа.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -22,15 +22,21 @@
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="bg-gray-100 text-center py-4 border-t text-sm text-gray-700">
|
||||
<footer
|
||||
class="bg-gray-100 dark:bg-gray-800 text-center py-4 border-t dark:border-gray-700 text-sm text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<p>
|
||||
Нужен такой же?
|
||||
<a href="/create" class="underline underline-offset-2">Создайте свой QR‑код</a>.
|
||||
<a
|
||||
href="/create"
|
||||
class="underline underline-offset-2 text-primary-600 dark:text-primary-400"
|
||||
>Создайте свой QR‑код</a
|
||||
>.
|
||||
</p>
|
||||
<p class="mt-1">
|
||||
Сделайте НаСвязи удобнее. Будем рады вашей <a
|
||||
href="/donate"
|
||||
class="underline underline-offset-2"
|
||||
class="underline underline-offset-2 text-primary-600 dark:text-primary-400"
|
||||
>поддержке</a
|
||||
>.
|
||||
</p>
|
||||
|
||||
@@ -18,24 +18,28 @@
|
||||
<section class="max-w-prose w-full flex flex-col gap-1">
|
||||
<div
|
||||
v-if="svgQueryIsLoading || qrCodeQueryIsLoading"
|
||||
class="text-gray-500 mt-4 text-center"
|
||||
class="text-gray-500 dark:text-gray-400 mt-4 text-center"
|
||||
>
|
||||
<ProgressSpinner styleClass="mt-4" />
|
||||
</div>
|
||||
<p v-else-if="svgQueryIsError" class="text-red-500 mt-4 text-center">
|
||||
<p v-else-if="svgQueryIsError" class="text-red-500 dark:text-red-400 mt-4 text-center">
|
||||
Ошибка генерации QR‑кода: {{ svgQueryError?.message }}
|
||||
</p>
|
||||
<p v-else-if="qrCodeQueryIsError" class="text-red-500 mt-4 text-center">
|
||||
<p v-else-if="qrCodeQueryIsError" class="text-red-500 dark:text-red-400 mt-4 text-center">
|
||||
Ошибка загрузки данных QR‑кода: {{ qrCodeQueryError!.message }}
|
||||
</p>
|
||||
<template v-else>
|
||||
<h2 class="text-xl font-semibold mb-4">Ваш QR‑код готов</h2>
|
||||
<p class="text-gray-600 mb-4">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-gray-100">
|
||||
Ваш QR‑код готов
|
||||
</h2>
|
||||
<p class="text-gray-600 dark:text-gray-400 mb-4">
|
||||
Сохраните его и ознакомьтесь с инструкциями по размещению.
|
||||
</p>
|
||||
|
||||
<!-- Рендер QR‑кода -->
|
||||
<div class="border p-4 bg-white rounded-lg mb-6">
|
||||
<div class="border dark:border-gray-700 p-4 bg-white rounded-lg mb-6">
|
||||
<!-- dark:bg-gray-800 -->
|
||||
|
||||
<img v-if="!svgQueryIsLoading && svgQueryData" :src="svgQueryData" alt="QR‑код" />
|
||||
</div>
|
||||
|
||||
@@ -47,7 +51,7 @@
|
||||
<Button
|
||||
label="Скачать SVG"
|
||||
icon="pi pi-download"
|
||||
class="p-button-sm"
|
||||
class="p-button-sm dark:border-orange-500 dark:hover:border-orange-600 dark:text-gray-300"
|
||||
:href="svgQueryData"
|
||||
:download="`${sanitizedFileName}.svg`"
|
||||
as="a"
|
||||
|
||||
@@ -6,7 +6,18 @@ import tailwindcssSafeArea from 'tailwindcss-safe-area'
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
colors: {
|
||||
// primary: {
|
||||
// 400: '#FFA726', // Светлый акцентный цвет для темной темы
|
||||
// 600: '#FB8C00', // Основной акцентный цвет для светлой темы
|
||||
// },
|
||||
// orange: {
|
||||
// 600: '#FB923C',
|
||||
// 700: '#F97316',
|
||||
// },
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [tailwindScrollbar, tailwindcssPrimeUI, tailwindcssSafeArea],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user