From fa8498ef4c44f77775c18dbd1b24ac452fab928f Mon Sep 17 00:00:00 2001 From: austnv Date: Sun, 7 Jun 2026 01:19:02 +0300 Subject: [PATCH] v0.4.0 add: - legal .md files - routers - home view - rewrite App.vue - update footer / header - update features --- package-lock.json | 87 ++++++++++++++++++++++- package.json | 5 +- public/docs/agreement.md | 107 +++++++++++++++++++++++++++++ public/docs/policy.md | 64 +++++++++++++++++ src/App.vue | 23 ++----- src/assets/styles.css | 3 +- src/components/AppFooter.vue | 6 +- src/components/AppHeader.vue | 34 +++++---- src/components/DocViewer.vue | 85 +++++++++++++++++++++++ src/components/FeaturesSection.vue | 2 +- src/main.js | 7 +- src/router/index.js | 34 +++++++++ src/views/HomeView.vue | 21 ++++++ vite.config.js | 2 - 14 files changed, 435 insertions(+), 45 deletions(-) create mode 100644 public/docs/agreement.md create mode 100644 public/docs/policy.md create mode 100644 src/components/DocViewer.vue create mode 100644 src/router/index.js create mode 100644 src/views/HomeView.vue diff --git a/package-lock.json b/package-lock.json index 209e320..e55d24f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,27 @@ { "name": "uvpn.shop", - "version": "0.2.0", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "uvpn.shop", - "version": "0.2.0", + "version": "0.3.1", "dependencies": { "@lucide/vue": "^1.16.0", "@tailwindcss/vite": "^4.3.0", "@tresjs/cientos": "^5.7.1", "@tresjs/core": "^5.8.1", + "marked": "^18.0.5", "swiper": "^12.1.4", "tailwindcss": "^4.3.0", "three": "^0.184.0", "vue": "^3.5.32", + "vue-router": "^4.6.4", "vue3-simple-icons": "^16.10.0" }, "devDependencies": { + "@tailwindcss/typography": "^0.5.19", "@vitejs/plugin-vue": "^6.0.6", "vite": "^8.0.8", "vite-plugin-vue-devtools": "^8.1.1" @@ -1134,6 +1137,19 @@ "node": ">= 20" } }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, "node_modules/@tailwindcss/vite": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", @@ -1665,6 +1681,19 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -2289,6 +2318,18 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/marked": { + "version": "18.0.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", + "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/meshoptimizer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz", @@ -2441,6 +2482,20 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/potpack": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", @@ -2799,6 +2854,13 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/vite": { "version": "8.0.14", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", @@ -3001,6 +3063,27 @@ } } }, + "node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, "node_modules/vue3-simple-icons": { "version": "16.10.0", "resolved": "https://registry.npmjs.org/vue3-simple-icons/-/vue3-simple-icons-16.10.0.tgz", diff --git a/package.json b/package.json index 37f4af8..afe066f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uvpn.shop", - "version": "0.3.1", + "version": "0.4.0", "private": true, "type": "module", "scripts": { @@ -13,13 +13,16 @@ "@tailwindcss/vite": "^4.3.0", "@tresjs/cientos": "^5.7.1", "@tresjs/core": "^5.8.1", + "marked": "^18.0.5", "swiper": "^12.1.4", "tailwindcss": "^4.3.0", "three": "^0.184.0", "vue": "^3.5.32", + "vue-router": "^4.6.4", "vue3-simple-icons": "^16.10.0" }, "devDependencies": { + "@tailwindcss/typography": "^0.5.19", "@vitejs/plugin-vue": "^6.0.6", "vite": "^8.0.8", "vite-plugin-vue-devtools": "^8.1.1" diff --git a/public/docs/agreement.md b/public/docs/agreement.md new file mode 100644 index 0000000..c666f03 --- /dev/null +++ b/public/docs/agreement.md @@ -0,0 +1,107 @@ +# Пользовательское соглашение + +### 1. Общие положения + +1.1. Настоящее Пользовательское соглашение (далее — **«Соглашение»** ) регулирует порядок использования онлайн-сервиса (далее — **«Сервис»** ), предоставляемого Администрацией. + +1.2. Используя Сервис, включая запуск бота, регистрацию, оплату услуг или получение доступа к материалам, Пользователь подтверждает, что полностью ознакомился с условиями настоящего Соглашения и принимает их в полном объёме. + +1.3. В случае несогласия с условиями Соглашения Пользователь обязан прекратить использование Сервиса. + +### 2. Характер услуг и цифровых товаров + +2.1. Сервис предоставляет цифровые товары и услуги нематериального характера, включая, но не ограничиваясь: информационные материалы, обучающие программы, консультации, цифровые продукты и сервисные услуги. + +2.2. Материалы, предоставляемые через Сервис, могут включать: + +* информацию из открытых источников; +* авторские материалы Администрации и/или третьих лиц; +* аналитические обзоры, подборки, рекомендации, структурированные данные. + +2.3. Пользователь осознаёт и соглашается, что ценность цифровых товаров и услуг Сервиса заключается **в систематизации, анализе, форме подачи, сопровождении, поддержке и обновлениях** , а не в эксклюзивности отдельных фрагментов информации. + +2.4. Сервис не заявляет и не гарантирует уникальность, исключительность или недоступность отдельных элементов материалов вне Сервиса. + +### 3. Отказ от гарантий и ответственности + +3.1. Сервис предоставляется на условиях **«AS IS» («как есть»)** . + +3.2. Администрация не гарантирует: + +* соответствие Сервиса ожиданиям Пользователя; +* достижение каких-либо финансовых, коммерческих, профессиональных или иных результатов; +* бесперебойную и безошибочную работу Сервиса. + +3.3. Администрация не несёт ответственности за: + +* любые прямые или косвенные убытки, включая упущенную выгоду; +* последствия применения Пользователем полученных материалов; +* действия или бездействие третьих лиц; +* временные технические сбои и ограничения доступа. + +3.4. Все решения о применении материалов, рекомендаций и услуг принимаются Пользователем **самостоятельно и на его риск** . + +### 4. Законность использования + +4.1. Сервис не предназначен для поощрения, организации или содействия противоправной деятельности. + +4.2. Пользователь обязуется использовать Сервис исключительно в рамках применимого законодательства и правил третьих сторон. + +4.3. Ответственность за законность использования материалов и услуг Сервиса полностью возлагается на Пользователя. + +### 5. Интеллектуальная собственность + +5.1. Все материалы, размещённые в Сервисе, охраняются законодательством об интеллектуальной собственности. + +5.2. Пользователю запрещается копировать, распространять, перепродавать, передавать третьим лицам или иным образом использовать материалы Сервиса без разрешения правообладателя. + +5.3. Нарушение прав интеллектуальной собственности может повлечь ограничение доступа к Сервису без компенсации. + +### 6. Ограничение доступа + +6.1. Администрация вправе приостановить или ограничить доступ Пользователя к Сервису в случае: + +* нарушения условий настоящего Соглашения; +* выявления злоупотреблений; +* требований законодательства или платёжных провайдеров. + +6.2. Ограничение доступа не освобождает Пользователя от обязательств, возникших ранее. + +6.3. Администрация оставляет за собой право отказывать в обслуживании Пользователям, чьи действия могут создавать повышенные риски для Сервиса, платёжных провайдеров или третьих лиц. + +### 7. Платежи и возвраты + +7.1. Оплата услуг и цифровых товаров производится на условиях, указанных в Сервисе до момента оплаты. + +7.2. В связи с нематериальным характером цифровых товаров и услуг, **возврат денежных средств после предоставления доступа не осуществляется** , за исключением случаев, указанных ниже. + +7.3. Возврат средств возможен только если: + +* услуга не была оказана по технической вине Сервиса; +* доступ к цифровому товару фактически не был предоставлен. + +7.4. Для рассмотрения вопроса о возврате Пользователь обязан обратиться в службу поддержки в течение **24 часов** с момента оплаты. + +7.5. Решение о возврате принимается Администрацией индивидуально. + +7.6. Пользователь подтверждает, что обязуется **не инициировать возврат платежа (chargeback)** через платёжные системы без предварительного обращения в службу поддержки Сервиса. + +### 8. Конфиденциальность + +8.1. Администрация может собирать минимально необходимые технические данные для обеспечения работы Сервиса. + +8.2. Администрация принимает разумные меры для защиты данных, однако не гарантирует абсолютную безопасность передаваемой информации. + +### 9. Изменение условий + +9.1. Администрация вправе вносить изменения в настоящее Соглашение. + +9.2. Актуальная версия Соглашения публикуется в Сервисе. + +9.3. Продолжение использования Сервиса означает согласие Пользователя с обновлёнными условиями. + +### 10. Контактная информация + +10.1. По всем вопросам Пользователь может обратиться в службу поддержки через форму в самом боте. + +**Используя Сервис (в том числе запуская бота и/или вводя команду /start), Пользователь подтверждает, что ознакомлен с настоящим Соглашением и принимает его условия в полном объёме.** diff --git a/public/docs/policy.md b/public/docs/policy.md new file mode 100644 index 0000000..e379148 --- /dev/null +++ b/public/docs/policy.md @@ -0,0 +1,64 @@ +# Политика конфиденциальности + +Политика конфиденциальности регулирует сбор, использование и защиту информации пользователей сервиса. Собираются идентификаторы аккаунта, техническая информация и история взаимодействий. Данные используются для обеспечения работы сервиса, связи с пользователем и анализа. Передача информации третьим лицам возможна только в законодательно установленных случаях или с согласия пользователя. Хранение данных осуществляется в течение необходимого срока, их защита — в разумных пределах. Пользователь самостоятельно несёт ответственность за риски, связанные с передачей данных. Администрация вправе вносить изменения в Политику без уведомления — согласие считается принятым при дальнейшем использовании сервиса. + +**1. Общие положения** + + 1.1. Настоящая Политика конфиденциальности (далее — «Политика») регулирует порядок обработки и защиты информации, которую Пользователь передаёт при использовании сервиса (далее — «Сервис»). + + 1.2. Используя Сервис, Пользователь подтверждает своё согласие с условиями Политики. Если Пользователь не согласен с условиями — он обязан прекратить использование Сервиса. + +--- + +**2. Сбор информации** + + 2.1. Сервис может собирать следующие типы данных: + +* идентификаторы аккаунта (логин, ID, никнейм и т.п.); +* техническую информацию (IP-адрес, данные о браузере, устройстве и операционной системе); +* историю взаимодействий с Сервисом. +* 2.2. Сервис не требует от Пользователя предоставления паспортных данных, документов, фотографий или другой личной информации, кроме минимально необходимой для работы. + +--- + +**3. Использование информации** + + 3.1. Сервис может использовать полученную информацию исключительно для: + +* обеспечения работы функционала; +* связи с Пользователем (в том числе для уведомлений и поддержки); +* анализа и улучшения работы Сервиса. + +--- + +**4. Передача информации третьим лицам** + + 4.1. Администрация не передаёт полученные данные третьим лицам, за исключением случаев: + +* если это требуется по закону; +* если это необходимо для исполнения обязательств перед Пользователем (например, при работе с платёжными системами); +* если Пользователь сам дал на это согласие. + +--- + +**5. Хранение и защита данных** + + 5.1. Данные хранятся в течение срока, необходимого для достижения целей обработки. + + 5.2. Администрация принимает разумные меры для защиты данных, но не гарантирует абсолютную безопасность информации при передаче через интернет. + +--- + +**6. Отказ от ответственности** + + 6.1. Пользователь понимает и соглашается, что передача информации через интернет всегда сопряжена с рисками. + + 6.2. Администрация не несёт ответственности за утрату, кражу или раскрытие данных, если это произошло по вине третьих лиц или самого Пользователя. + +--- + +**7. Изменения в Политике** + + 7.1. Администрация вправе изменять условия Политики без предварительного уведомления. + + 7.2. Продолжение использования Сервиса после внесения изменений означает согласие Пользователя с новой редакцией Политики. diff --git a/src/App.vue b/src/App.vue index 29c9e04..db0c4c7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,25 +1,16 @@ \ No newline at end of file + diff --git a/src/assets/styles.css b/src/assets/styles.css index a461c50..3571db7 100644 --- a/src/assets/styles.css +++ b/src/assets/styles.css @@ -1 +1,2 @@ -@import "tailwindcss"; \ No newline at end of file +@import "tailwindcss"; +@plugin "@tailwindcss/typography"; diff --git a/src/components/AppFooter.vue b/src/components/AppFooter.vue index c46831c..96f8bf8 100644 --- a/src/components/AppFooter.vue +++ b/src/components/AppFooter.vue @@ -6,9 +6,9 @@ uVPN
- Политика конфиденциальности - Условия использования - Поддержка + Политика конфиденциальности + Условия использования + Поддержка

© 2026 uVPN. Все права защищены. diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue index 37f5460..6c65642 100644 --- a/src/components/AppHeader.vue +++ b/src/components/AppHeader.vue @@ -1,31 +1,29 @@ \ No newline at end of file +// Скрипты больше не нужны, всю магию сделает роутер! + diff --git a/src/components/DocViewer.vue b/src/components/DocViewer.vue new file mode 100644 index 0000000..12fae56 --- /dev/null +++ b/src/components/DocViewer.vue @@ -0,0 +1,85 @@ + + + diff --git a/src/components/FeaturesSection.vue b/src/components/FeaturesSection.vue index ac4516a..782a829 100644 --- a/src/components/FeaturesSection.vue +++ b/src/components/FeaturesSection.vue @@ -38,7 +38,7 @@

Стабильная работа

-

Автоматические обновления конфигураций — VPN работает даже при новых блокировках

+

Автоматические обновления конфигураций — мы первые подстраиваемся под новые условия

diff --git a/src/main.js b/src/main.js index 1b812c6..64b2601 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,10 @@ import { createApp } from 'vue' import App from './App.vue' +import router from './router' import './assets/styles.css' -createApp(App).mount('#app') +const app = createApp(App) + +app.use(router) + +app.mount('#app') \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..715e1f4 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,34 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' +import DocViewer from '../components/DocViewer.vue' + +const router = createRouter({ + history: createWebHistory(), + + scrollBehavior(to, from, savedPosition) { + // Если в ссылке есть хэш (например, #pricing) + if (to.hash) { + return new Promise((resolve) => { + // Даем 200 миллисекунд компонентам (Three.js/Swiper) на полную отрисовку + setTimeout(() => { + resolve({ + el: to.hash, + behavior: 'smooth', + // Корректировка отступа сверху, чтобы липкая (sticky) шапка не перекрывала заголовок блока + offset: { x: 0, y: 80 } + }) + }, 200) + }) + } + + // Если хэша нет, при переходе на новую страницу просто скроллим в самый верх + return { top: 0 } + }, + + routes: [ + { path: '/', name: 'home', component: HomeView }, + { path: '/docs/:docName', name: 'documents', component: DocViewer, props: true } + ] +}) + +export default router diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue new file mode 100644 index 0000000..f76c6ec --- /dev/null +++ b/src/views/HomeView.vue @@ -0,0 +1,21 @@ + + + diff --git a/vite.config.js b/vite.config.js index 6f4075e..eb0f7b3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,7 +2,6 @@ import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -import vueDevTools from 'vite-plugin-vue-devtools' import tailwindcss from '@tailwindcss/vite' @@ -10,7 +9,6 @@ import tailwindcss from '@tailwindcss/vite' export default defineConfig({ plugins: [ vue(), - vueDevTools(), tailwindcss(), ], resolve: {