migrate on nuxt3

This commit is contained in:
2025-06-17 17:46:03 +04:00
parent 7634a3d616
commit 727fa976bd
123 changed files with 20963 additions and 1815 deletions

281
pages/books/[slug].vue Normal file
View File

@ -0,0 +1,281 @@
<template>
<template v-if="book">
<div class="relative z-50 min-h-screen text-white mb-[208px]">
<template v-if="!route.params.titlesSlug">
<!--верхний блок-->
<section
class="flex flex-row relative z-40 before:content-[''] before:absolute before:top-[-140px] before:bg-top before:left-0 before:w-[1280px] before:h-[1000px] before:bg-[url(/assets/img/webp/vino-galante.webp)] before:bg-no-repeat before:bg-contain mt-40"
>
<!--левый блок контента-->
<section class="relative top-[-20px] min-w-[570px]">
<div class="flex flex-col items-center">
<img
:src="book.img"
:alt="book.buttonText"
width="100%"
height="100%"
/>
</div>
</section>
<!--правый блок контента-->
<section>
<div class="w-11/12 h-full flex flex-col justify-start">
<div>
<UiHeading
tag="H1"
class="whitespace-pre-line [&]:font-bold"
size="300"
>
{{ book.title }}
</UiHeading>
<UiParagraph class="mb-10" size="250">
{{ book.subtitle }}
</UiParagraph>
<UiParagraph size="250" class="mb-20">
{{ book.subdesc }}
</UiParagraph>
<UiParagraph size="250" class="whitespace-pre-line min-h-62">
{{ book.description }}
</UiParagraph>
</div>
</div>
</section>
</section>
<!--средний блок-->
<section class="flex flex-row items-center ml-20 justify-between">
<!--левый-->
<div class="flex flex-col items-center min-h-[310px]">
<div class="flex flex-row">
<UiParagraph class="[&]:text-6xl"
>{{ book.price }}&nbsp;</UiParagraph
>
<img src="/img/svg/books/ruble.svg" alt="ruble" />
</div>
<div class="mr-10 flex items-center flex-col gap-3">
<UiButton class="max-w-[380px] !font-normal !px-2 !py-4 mt-24">
{{ book.buttonText }}
</UiButton>
<UiParagraph size="200">
{{ book.buttonFormat }}
</UiParagraph>
</div>
</div>
<!--правый-->
<div class="min-h-[310px]">
<!--о книге-->
<div>
<ul
class="flex flex-row mr-14 items-center justify-between lg:whitespace-nowrap"
>
<li class="flex flex-row mr-14 gap-3 items-center">
<img
src="/img/svg/books/book-pages.svg"
alt="страниц"
width="100%"
height="100%"
/>
<UiParagraph size="250" as="span">
{{ book.pages }}
</UiParagraph>
</li>
<li class="flex flex-row mr-14 gap-3 items-center">
<img
src="/img/svg/books/book-illustrations.svg"
alt="иллюстраций"
width="100%"
height="100%"
/>
<UiParagraph size="250" as="span">
{{ book.illust }}
</UiParagraph>
</li>
<li class="flex flex-row mr-14 gap-3 items-center">
<img
src="/img/svg/books/book-formats.svg"
alt="формат"
width="100%"
height="100%"
/>
<UiParagraph size="250" as="span">
{{ book.format }}
</UiParagraph>
</li>
</ul>
</div>
<!--навигация по книге-->
<div class="mt-24">
<ul
class="flex flex-row mr-32 items-end justify-between lg:whitespace-nowrap"
>
<li class="flex flex-row items-center">
<NuxtLink
to="#"
class="flex flex-col items-center cursor-pointer"
>
<div class="w-[62px] h-[58px]">
<img
src="/img/svg/books/read.svg"
alt="Читай отрывок"
width="62"
height="53"
/>
</div>
<UiParagraph size="250" as="span">
Читай отрывок
</UiParagraph>
</NuxtLink>
</li>
<li class="flex flex-row gap-3 items-center">
<NuxtLink
to="#"
class="flex flex-col items-center gap-4 cursor-pointer"
>
<div class="w-[62px] h-[53px]">
<img
src="/img/svg/books/download.svg"
alt="Скачай отрывок"
width="62"
height="53"
/>
</div>
<UiParagraph size="250" as="span">
Скачай отрывок
</UiParagraph>
</NuxtLink>
</li>
<li class="flex flex-row gap-3 items-center">
<NuxtLink
:to="`/books/${route.params.slug}/${book.hrefTitles}`"
class="flex flex-col items-center gap-3 cursor-pointer"
>
<div class="w-[62px] h-[53px]">
<img
src="/img/svg/books/down2.svg"
alt="Содержание"
width="62"
height="53"
/>
</div>
<UiParagraph size="250" as="span"> Содержание </UiParagraph>
</NuxtLink>
</li>
</ul>
</div>
</div>
</section>
<!--нижний блок-->
<section class="ml-20 mt-32">
<div>
<UiHeading tag="H2" size="300" class="text-three">
Что ты узнаешь
</UiHeading>
<ul class="flex mt-20 flex-row items-center justify-between">
<li
class="flex flex-col-reverse justify-end w-32 gap-4 h-64 items-center transition-transform transform hover:scale-110"
v-for="({ svg, text }, index) in book.whoUKnows"
:key="index"
>
<UiParagraph class="text-center" size="250">
{{ text }}
</UiParagraph>
<img :src="`${svg}`" alt="Вопрос" width="45" height="45" />
</li>
</ul>
</div>
<div class="flex justify-center text-center mt-36">
<UiParagraph>
Или купи на ЛитРес - <br /><a
class="text-three"
:href="book.href"
target="_blank"
>Реферальная ссылка для поддержки автора</a
>
</UiParagraph>
</div>
</section>
</template>
<NuxtPage />
</div>
</template>
<div v-else class="text-white text-center py-20">Книга не найдена.</div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useRoute } from "#app";
import UiHeading from "@/components/Typography/UiHeading.vue";
import UiParagraph from "@/components/Typography/UiParagraph.vue";
import UiButton from "@/components/UiButton/UiButton.vue";
interface BookDetail {
id: number;
title: string;
metaTitle: string;
subtitle: string;
subdesc: string;
description: string;
img: string;
price: string;
buttonText: string;
buttonFormat: string;
pages: string;
illust: string;
format: string;
whoUKnows: Array<{
text: string;
svg: string;
}>;
href: string;
hrefTitles: string;
}
const route = useRoute();
const currentBookData = ref<BookDetail | null>(null);
const book = computed(() => currentBookData.value);
const loadBookData = async (slug: string) => {
try {
const module = await import(`./_data/${slug}.json`);
currentBookData.value = module.default as BookDetail;
} catch (error) {
console.error(`Ошибка при загрузке книги с slug '${slug}':`, error);
currentBookData.value = null;
}
};
watch(
() => route.params.slug,
async (newSlug) => {
if (newSlug) {
await loadBookData(newSlug as string);
}
},
{ immediate: true }
);
watch(book, (newBook) => {
if (newBook) {
useHead({
title: `${newBook.metaTitle} | Vino Galante`,
meta: [
{
name: "description",
content: "Онлайн магазин книг автора Vino Galante",
},
],
link: [
{
rel: "canonical",
href: `https://ebook.miduway.space/books/${route.params.slug}`,
},
],
});
}
});
</script>

View File

@ -0,0 +1,172 @@
<template>
<div v-if="titles" class="relative z-50 min-h-screen text-white mb-[208px]">
<section class="flex flex-col relative z-40 mt-40 ml-18">
<UiHeading
tag="H1"
class="whitespace-pre-line [&]:font-normal mb-10 -ml-5"
size="500"
>
{{ titles.title }}
</UiHeading>
<div class="flex flex-col gap-6">
<div
v-for="(section, index) in titles.sections"
:key="index"
class="flex flex-col gap-4"
>
<!-- Main section title -->
<UiHeading tag="H2" size="300" class="text-three [&]:font-normal">
{{ section.title }}
</UiHeading>
<!-- Subsections -->
<div v-if="section.subsections" class="ml-6 flex flex-col gap-4">
<div
v-for="(subsection, subIndex) in section.subsections"
:key="subIndex"
class="flex flex-col gap-2"
>
<!-- Subsection with image -->
<div
v-if="typeof subsection.title === 'object'"
class="flex items-center gap-3 -ml-10"
>
<img
v-if="subsection.title.img"
:src="subsection.title.img"
:alt="subsection.title.text"
class="w-6 h-6"
/>
<UiHeading tag="H3" size="300" class="[&]:font-normal">
{{ subsection.title.text }}
</UiHeading>
</div>
<!-- Regular subsection -->
<UiHeading
v-else
tag="H3"
size="300"
class="[&]:text-gray-200 [&]:font-normal"
>
{{ subsection.title }}
</UiHeading>
<!-- Items list -->
<ul
v-if="subsection.items"
class="ml-6 flex flex-col gap-2 list-decimal"
>
<li
v-for="(item, itemIndex) in subsection.items"
:key="itemIndex"
>
<UiParagraph
size="300"
class="[&]:text-gray-200 [&]:font-normal"
>&nbsp;{{ item }}</UiParagraph
>
</li>
</ul>
<!-- Nested subsections -->
<div v-if="subsection.subsections" class="flex flex-col gap-2">
<div
v-for="(nestedSub, nestedIndex) in subsection.subsections"
:key="nestedIndex"
>
<UiHeading
tag="H4"
size="300"
class="[&]:text-gray-200 [&]:font-normal"
>
{{ nestedSub.title }}
</UiHeading>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<div v-else class="text-white text-center py-20">Содержание не найдено.</div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useRoute } from "vue-router";
import UiHeading from "@/components/Typography/UiHeading.vue";
import UiParagraph from "@/components/Typography/UiParagraph.vue";
// import { useHead } from '@vueuse/head'
interface SubsectionTitle {
text: string;
img?: string;
}
interface Subsection {
title: string | SubsectionTitle;
items?: string[];
subsections?: Array<{
title: string;
}>;
}
interface Section {
title: string;
subsections?: Subsection[];
}
interface TitlesData {
title: string;
titleMeta: string;
sections: Section[];
}
const route = useRoute();
const currentTitlesData = ref<TitlesData | null>(null);
const titles = computed(() => currentTitlesData.value);
const loadTitlesData = async (slug: string) => {
try {
const module = await import(`./_data/${slug}.json`);
currentTitlesData.value = module.default as TitlesData;
} catch (error) {
console.error(`Ошибка при загрузке содержания с slug '${slug}':`, error);
currentTitlesData.value = null;
}
};
watch(
() => route.params.titlesSlug,
async (newSlug) => {
if (newSlug) {
await loadTitlesData(newSlug as string);
}
},
{ immediate: true }
);
watch(titles, (newTitles) => {
if (newTitles) {
useHead({
title: `${newTitles.titleMeta} | Vino Galante`,
meta: [
{
name: "description",
content: "Содержание книги Vino Galante",
},
],
link: [
{
rel: "canonical",
href: `https://ebook.miduway.space/books/${route.params.slug}/${route.params.titlesSlug}`,
},
],
});
}
});
</script>

View File

@ -0,0 +1,187 @@
{
"id": "title-1",
"title": "Оглавление",
"titleMeta": "Оглавление - Книга I",
"sections": [
{
"title": "Благодарности"
},
{
"title": "Введение",
"subsections": [
{
"title": "Работа с любым печатным материалом"
}
]
},
{
"title": "Глава 1. Перезагрузка",
"subsections": [
{
"title": "Введение"
},
{
"title": {
"text": "Убеждения соблазнительницы",
"img": "/img/svg/books/1/titles-1/flowbite_wine-glass-solid.svg"
},
"items": [
"Всё всегда хорошо",
"Другие девушки не помеха для меня",
"Парней много, я одна",
"Использовать мужчин это естественно и приятно",
"Отшивать мужчин это естественно",
"Ты имеешь ровно то, что заслужила",
"Ты достойна гораздо больше того, что имеешь на данный момент",
"Все, о чем ты способна мечтать, ты способна иметь",
"Проявлять активность успешной девушке естественно",
"Все мужчины, с которыми ты общаешься до замужества всего лишь твои тренажеры",
"Мужчина должен относиться к тебе уважительно",
"Среди мужчин встречается идиоты",
"Тебе выгодно, если мужчина хочет тебя",
"Мужчина общается с тобой только тогда, когда ему от тебя что-то нужно",
"Пока мужчина тебя не трахнул, ты не проиграла",
"Если ты получаешь удовольствие от общения с мужчиной все идет по плану",
"Ты ничего не должна мужчине, даже если он подарил тебе дворец и яхту",
"Соблазнение всего лишь очень интересная игра, в которой нет проигравших",
"У мужчин две ахиллесовых пяты это и секс. Это в сто раз важнее секса",
"Мужчины очень хорошие создания",
"Мужчины не примитивные",
"Мужчинам нужен далеко не только секс (Мужчине нужен от тебя только секс, если ты больше ничего ему дать не можешь)",
"Смысл жизни развитие",
"Иметь запасной аэродром правильно и естественно для женщины",
"Сексом мужчину не удержать",
"Общение с мужчиной должно приносить радость",
"Мужчины стремятся не к хорошим, а к высокоранговым женщинам",
"Мир вокруг тебя отражение тебя самой"
]
},
{
"title": {
"text": "Секс на первом свидании",
"img": "/img/svg/books/1/titles-1/healthicons_sexual-reproductive-health.svg"
}
}
]
},
{
"title": "Глава 2. Свобода",
"subsections": [
{
"title": "Введение"
},
{
"title": {
"text": "Поля-тараканы",
"img": "/img/svg/books/1/titles-1/simple-icons_cockroachlabs.svg"
}
},
{
"title": "Техника безопасности при работе в полях"
},
{
"title": "Восстановление сил"
},
{
"title": "Главный принцип развития"
},
{
"title": "Техники выхода в аптайм"
},
{
"title": "Действия"
},
{
"title": "Результат"
},
{
"title": {
"text": "Калибровка",
"img": "/img/svg/books/1/titles-1/material-symbols_editor-choice-rounded.svg"
},
"subsections": [
{
"title": "Азбука калибровки"
},
{
"title": "Как наблюдать, не вызывая подозрений"
}
]
},
{
"title": {
"text": "Стратегия сближений",
"img": "/img/svg/books/1/titles-1/ph_strategy-fill.svg"
},
"subsections": [
{
"title": "Определение и классификация"
},
{
"title": "Псевдопассивная. Этап первый"
},
{
"title": "Псевдопассивная. Этап второй"
},
{
"title": "Активный тип стратегии"
},
{
"title": "Третий этап. Степени кокетства"
}
]
}
]
},
{
"title": "Глава 3. Затравка",
"subsections": [
{
"title": "Введение"
},
{
"title": {
"text": "Теория женской привлекательности",
"img": "/img/svg/books/1/titles-1/icon-park-outline_women.svg"
},
"subsections": [
{
"title": "Введение"
}
]
},
{
"title": "Физическое здоровье"
},
{
"title": "Ментальный посыл. Стильность"
},
{
"title": "Ментальный посыл. Внутреннее ощущение мира"
},
{
"title": {
"text": "Ошибки резидента",
"img": "/img/svg/books/1/titles-1/si_error-line.svg"
},
"items": [
"Косак 1",
"Косак 2",
"Полукосак 3",
"Косак 4",
"МетаКосак 5 опасный",
"МетаКосак 6 опасный",
"Косак 7",
"МетаКосак 8 крайне опасно",
"МетаКосак 9 опасно",
"Косак 10",
"Косак 11"
]
},
{
"title": "В следующей книге"
}
]
}
]
}

View File

@ -0,0 +1,170 @@
{
"id": "title-1",
"title": "Оглавление",
"titleMeta": "Оглавление - Книга II",
"sections": [
{
"title": "Введение"
},
{
"title": "Глава 1. Перед боем",
"subsections": [
{
"title": {
"text": "Закон Вино Галанте или закон неотвратимости успеха",
"img": "/img/svg/books/2/titles-2/octicon_law-24.svg"
}
},
{
"title": {
"text": "Запасной аэродром",
"img": "/img/svg/books/2/titles-2/mingcute_airplane-line.svg"
},
"subsections": [
{
"title": "Экскурс в историю"
},
{
"title": "Правила формирования запасного аэродрома"
},
{
"title": "Подробнее о пятом пункте или как не врать"
},
{
"title": "Следствия наличия запасного аэродрома"
}
]
},
{
"title": {
"text": "Свидания",
"img": "/img/svg/books/2/titles-2/mdi_heart-outline (1).svg"
},
"subsections": [
{
"title": "Одежда"
},
{
"title": "Правильные места для свиданий"
},
{
"title": "Самое важное в свиданиях"
}
]
}
]
},
{
"title": "Глава 2. Ближний бой",
"subsections": [
{
"title": "Введение"
},
{
"title": {
"text": "Техника влюбления",
"img": "/img/svg/books/2/titles-2/Vector (4).svg"
},
"items": [
"Механизм мужской и женской влюбленностей",
"Главный секрет влюбления",
"Ментальная подстройка",
"Подстройка по ценностям",
"Качество девушки",
"Поведение",
"Как правильно хвалить мужчину",
"Игра “Ближе-дальше”",
"Дикий крышечок “Полярный разрыв”",
"Полярный разрыв в действии или крышечок на грани фола",
"Фишка “Рассмеяться как зло”",
"Фишка “АХ”",
"Техника влюбления “Отмененная помощь”",
"Техника влюбления “Не тот поворот”",
"Техника влюбления “Неожиданный разрыв”",
"Техника влюбления “Обещанный звонок”",
"Техника влюбления “Парень подружка”",
"Фишка “Бросок кобры”",
"Фишка “Мягкий язык”",
"Вызов ревности"
]
},
{
"title": {
"text": "Типичные неэффективные фишки девушек",
"img": "/img/svg/books/2/titles-2/Group.svg"
},
"items": ["Я выхожу замуж", "Я скучаю по парню", "Желание казаться круче, чем ты есть"]
},
{
"title": {
"text": "Чего никогда нельзя делать",
"img": "/img/svg/books/2/titles-2/Group (1).svg"
},
"subsections": [
{
"title": "Введение"
},
{
"title": "Оральные ласки"
},
{
"title": "Минет"
}
]
},
{
"title": {
"text": "СМС-переписка",
"img": "/img/svg/books/2/titles-2/Vector (6).svg"
},
"subsections": [
{
"title": "Российские школы соблазнения"
},
{
"title": "Как найти соблазнителя"
},
{
"title": "История рождения одного термина"
}
]
},
{
"title": {
"text": "Секс и девичья невинность",
"img": "/img/svg/books/2/titles-2/Vector (7).svg"
},
"subsections": [
{
"title": "Как парни воспринимают секс"
},
{
"title": "Девичья невинность"
},
{
"title": "Прожим девственницы. Метод Галанте."
},
{
"title": "Прожим девственницы. Классический метод."
},
{
"title": "Прожим девственницы. Метод пикапера."
},
{
"title": "Вместо эпилога"
}
]
},
{
"title": "Что делать, если попался «сложный красавчик»"
},
{
"title": {
"text": "Словарь",
"img": "/img/svg/books/2/titles-2/Vector (8).svg"
}
}
]
}
]
}

39
pages/books/_data/1.json Normal file
View File

@ -0,0 +1,39 @@
{
"id": 1,
"title": "Как влюбить в себя любого\nКнига I",
"metaTitle": "Как влюбить в себя любого - Книга I",
"subtitle": "ОТКРОВЕНИЯ БЫВШЕГО КАЗАНОВЫ",
"subdesc": "💡 Ты красивая, умная, но он не пишет? Эта книга покажет, как влюбить в себя любого — без игр и унижений",
"description": "Думаешь Vino Galante - правнук легендарного Джакомо Казановы? Да, такие слухи ходят. Но здесь дело не в итальянской крови. Просто Galante - очень «тонкий» соблазнитель. Зная все тонкости этого искусства, он филигранно работает «кончиками пальцев».\n\nА эту книгу (ты не поверишь!!) он написал специально для девушек. Однажды влюбившись, Vino перестал соблазнять. Так у тебя появилась возможность узнать основы тонкого искусства соблазнения из легендарного первоисточника.",
"img": "/img/webp/books/1.webp",
"price": "520 ",
"buttonText": "Хочу знать, как работает мужская психология",
"buttonFormat": "PDF + EPUB сразу после оплаты",
"pages": "210 страниц",
"illust": "11 иллюстраций",
"format": "PDF + EPUB",
"whoUKnows": [
{
"text": "Как устроено мужское влечение на самом деле",
"svg": "/img/svg/books/1/mdi_heart-outline.svg"
},
{
"text": "Почему красивые девушки часто одиноки — и что с этим делать",
"svg": "/img/svg/books/1/f7_exclamationmark.svg"
},
{
"text": "Как флиртовать тонко, не теряя себя",
"svg": "/img/svg/books/1/meteor-icons_message.svg"
},
{
"text": "Что делает девушку запоминающейся",
"svg": "/img/svg/books/1/lucide_star.svg"
},
{
"text": "Как не попадать в «запас» и быть единственной",
"svg": "/img/svg/books/1/stash_target.svg"
}
],
"href": "https://www.litres.ru/58125553/",
"hrefTitles": "title-1"
}

39
pages/books/_data/2.json Normal file
View File

@ -0,0 +1,39 @@
{
"id": 2,
"title": "Как влюбить в себя любого\nКнига II",
"metaTitle": "Как влюбить в себя любого - Книга II",
"subtitle": "ТОНКАЯ ИГРА",
"subdesc": "💡 Если ты устала от “не готов к отношениям” — начни играть по своим правилам",
"description": "Ты бывала свидетелем такого, что у красивой девушки личная жизнь не складывается, а у, казалось бы, дурнушки и семья хорошая, и муж и любит, и обеспечивает? Да такое сплошь и рядом!\n\nХочешь узнать, как построить отношения с любым парнем в наш век, когда вокруг полно красавиц, а все мужчины/парни избалованы?\nОтветы ты найдешь в этой книге.",
"img": "/img/webp/books/2.webp",
"price": "520 ",
"buttonText": "Скачать сейчас — и начать менять игру",
"buttonFormat": "PDF + EPUB сразу после оплаты",
"pages": "210 страниц",
"illust": "11 иллюстраций",
"format": "PDF + EPUB",
"whoUKnows": [
{
"text": "Как выстроить притяжение с любым мужчиной",
"svg": "/img/svg/books/1/mdi_heart-outline.svg"
},
{
"text": "Как включить его чувства, а не просто понравиться",
"svg": "/img/svg/books/1/f7_exclamationmark.svg"
},
{
"text": "Какие фишки работают — и почему",
"svg": "/img/svg/books/1/meteor-icons_message.svg"
},
{
"text": "Почему мужчины уходят от «идеальных» и возвращаются к «опасным»",
"svg": "/img/svg/books/1/lucide_star.svg"
},
{
"text": "Как говорить и вести себя, чтобы остаться в его сердце",
"svg": "/img/svg/books/1/stash_target.svg"
}
],
"href": "https://www.litres.ru/vino-galante/kak-vlubit-v-sebya-lubogo-tonkaya-igra/",
"hrefTitles": "title-2"
}

View File

@ -0,0 +1,16 @@
const feedbackData = [
{
text: 'Классная книга! Понятная и увлекательная. По моему мнению, проблема только в том, что женщине самой (без поддержки), выполнить всё, что написано в книге чрезвычайно сложно.\nИдеи супер: \n первый секс козырный туз женщины и не надо отдавать его в начале :)\n жизнь взяток не берет! Надо действовать.',
},
{
text: 'Интересная книга, читаешь «не отрывая глаз», те рекомендации, которые я применяла действительно рабочие!! Всем советую! По моему мнению видно, что автор действительно очень хорошо знает и понимаем женскую психологию.',
},
{
text: 'Книга содержит знания, которыми жалко делиться ;) нигде ничего подобного не встречала. Очень много авторских формул и примеров, автор - опытный соблазнитель :) кое-что уже успешно применяла на практике',
},
{
text: 'Книга для всех девушек, кто только начинают строить отношения. Это вакцина от девичьих ошибок, дает понимание, чего они хотят. Учит не наступать на их уловки. Благодаря ей я стала более уверена в себе.',
},
]
export default feedbackData

View File

@ -0,0 +1,129 @@
<template>
<section class="feedback-section">
<UiHeading tag="H2" size="300" class="text-three mb-4 pl-16 pr-24">
Что говорят читатели
</UiHeading>
<!-- Slider main container -->
<div class="swiper feedback-swiper relative">
<!-- If we need pagination -->
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div
v-for="(feedback, index) in feedbackData"
:key="index"
class="swiper-slide feedback-slide !w-[356px] !h-[325px]"
>
<div class="feedback-card !w-full !h-full">
<UiParagraph size="250" class="card-text">{{ feedback.text }}</UiParagraph>
</div>
</div>
</div>
</div>
<div class="flex items-center flex-col">
<UiParagraph size="250" class="text-center mt-20">
Твое мнение важно!<br />
Если книга была полезной или вызвала эмоции, оставь отзыв.<br />
Это поможет другим и вдохновит на новые главы. <br />
Спасибо!
</UiParagraph>
<UiButton class="mt-10" variants="secondary">Написать отзыв</UiButton>
</div>
</section>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
import Swiper from 'swiper'
import { Pagination, Autoplay } from 'swiper/modules'
import UiHeading from '@/components/Typography/UiHeading.vue'
import UiParagraph from '@/components/Typography/UiParagraph.vue'
import feedbackData from './_data/feedback.data'
import 'swiper/css'
import 'swiper/css/pagination'
import UiButton from '@/components/UiButton/UiButton.vue'
onMounted(() => {
new Swiper('.feedback-swiper', {
modules: [Pagination, Autoplay],
direction: 'horizontal',
loop: true,
autoplay: {
delay: 3000,
disableOnInteraction: false,
},
slidesPerView: 'auto',
spaceBetween: 72,
pagination: {
el: '.swiper-pagination',
clickable: false,
},
})
})
</script>
<style lang="css" scoped>
.feedback-section {
overflow: hidden;
}
.feedback-swiper {
width: 100%;
height: auto;
padding-bottom: 40px;
position: relative;
}
.feedback-slide {
width: 300px;
display: flex;
justify-content: center;
align-items: flex-start;
}
.feedback-card {
background-color: #1a1a1a;
border-radius: 10px;
padding: 20px;
color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-title {
margin-bottom: 10px;
}
.card-text {
white-space: pre-line;
margin-bottom: 10px;
}
.swiper-pagination {
position: absolute;
bottom: 0px;
left: 50%;
transform: translateX(-50%);
width: auto;
display: flex;
justify-content: center;
}
.swiper-pagination-bullet {
background-color: #fff;
opacity: 0.4;
margin: 0 4px;
}
.swiper-pagination-bullet-active {
background-color: #fff;
opacity: 1;
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<section>
<UiHeading tag="H2" size="300" class="text-three">
Книги для тебя, если ты не знаешь...
</UiHeading>
<ul class="flex mt-20 flex-row items-center justify-between">
<li
class="flex flex-col-reverse justify-end w-38 gap-4 h-64 items-center transition-transform transform hover:scale-110"
v-for="({ img, text }, index) in questions.data"
:key="index"
>
<UiParagraph class="text-center" size="250">
{{ text }}
</UiParagraph>
<img :src="`${img}`" alt="Вопрос" width="101" height="101" />
</li>
</ul>
</section>
</template>
<script setup lang="ts">
import UiHeading from '@/components/Typography/UiHeading.vue'
import UiParagraph from '@/components/Typography/UiParagraph.vue'
import { reactive } from 'vue'
const questions = reactive({
data: [
{
img: '/img/svg/ellipse1.svg',
text: 'Что делать, если у тебя ноги не "от ушей" и ты далеко не Мисс Мира?',
},
{
img: '/img/svg/ellipse2.svg',
text: 'Как начать легко общаться с противоположным полом и о чем надо помолчать?',
},
{
img: '/img/svg/ellipse3.svg',
text: 'Как относиться к сексу и на сколько важна девичья невинность?',
},
{
img: '/img/svg/ellipse4.svg',
text: 'Сколько нужно заниматься, чтобы обрести НОВУЮ себя?',
},
{
img: '/img/svg/ellipse5.svg',
text: 'Как выработать стратегию долгосрочных отношений?',
},
{
img: '/img/svg/ellipse6.svg',
text: 'Как добиться того, чтоб парень делал так, как ты хочешь, но думал, что он сам так решил?',
},
],
})
</script>

View File

@ -0,0 +1,35 @@
import UiParagraph from '@/components/Typography/UiParagraph.vue';
<template>
<div
v-for="({ topContent, button, botContent }, index) in content.data"
:key="index"
class="flex flex-col items-center max-w-96"
>
<UiParagraph size="300" class="mb-12 h-32">{{ topContent }} </UiParagraph>
<UiButton variants="primary" class="mb-3 w-full">{{ button }} </UiButton>
<UiParagraph as="span" size="200"> {{ botContent }}</UiParagraph>
</div>
</template>
<script setup lang="ts">
import UiParagraph from '@/components/Typography/UiParagraph.vue'
import UiButton from '@/components/UiButton/UiButton.vue'
import { reactive } from 'vue'
const content = reactive({
data: [
{
topContent:
'💡 Узнай, как думает мужчина, что его действительно цепляет, и что делает женщину незабываемой.',
button: 'КУПИТЬ КНИГУ I',
botContent: 'PDF + EPUB сразу после оплаты',
},
{
topContent:
'💡 Продолжение для тех, кто готов перейти от флирта к глубокому контакту. Как строить притяжение, не теряя себя.',
button: 'КУПИТЬ КНИГУ II',
botContent: 'PDF + EPUB сразу после оплаты',
},
],
})
</script>

View File

@ -0,0 +1,18 @@
<template>
<section>
<div class="relative z-50">
<img
src="/assets/img/webp/hero-banner-content.webp"
alt="Книги"
width="100%"
height="100%"
/>
</div>
<div class="flex flex-row justify-between pl-16 pr-24">
<BuyContent />
</div>
</section>
</template>
<script setup lang="ts">
import BuyContent from './_ui/buyContent.vue'
</script>

View File

@ -0,0 +1,38 @@
<template>
<section class="flex flex-row">
<div class="lg:w-5/12 pl-5 pr-5 shadow-md bg-[url('/assets/img/png/shadow.png')]">
<UiHeading tag="H2" size="300" class="text-three mb-4 mt-5">
💔 Ты не одна.
<br />Я знаю, через что ты<br />
проходишь.
</UiHeading>
<UiParagraph size="250" class="xl:max-w-[392px] mb-5"
>Когда ты снова и снова отдаёшь сердце, а в ответ тишина или игра, это ранит. Я знаю это
чувство. Я был по ту сторону: манипулировал, очаровывал, уходил.
<br /><br />Я бывший Казанова. И однажды я понял: больше так нельзя.
<br /><br />Эти книги не теория. Это ключ к пониманию, как устроена мужская психология,
чего на самом деле хочет мужчина, и как перестать теряться в отношениях.
<br /><br />Я написал их для тебя чтобы ты могла быть счастливой, не прогибаясь, не
умоляя, не теряя себя. Если ты устала «играть», если хочешь любви по-настоящему начни с
первой страницы. В этих книгах нет воды. Только правда.</UiParagraph
>
</div>
<div class="lg:w-7/12">
<NuxtImg
src="/img/webp/meetingAlone.webp"
alt="meeting"
width="100%"
height="100%"
loading="lazy"
/>
</div>
</section>
</template>
<script setup lang="ts">
import UiHeading from '@/components/Typography/UiHeading.vue'
import UiParagraph from '@/components/Typography/UiParagraph.vue'
</script>

31
pages/index/index.vue Normal file
View File

@ -0,0 +1,31 @@
<template>
<div>
<section class="relative z-50">
<HeroBanner
class="pt-28 bg-[url('/assets/img/png/bg.png')] z-40 bg-no-repeat bg-[400px] rounded-[50px] relative after:absolute after:bg-[url('/assets/img/webp/header-flowers-4.webp')] after:top-0 after:w-[418px] after:right-0 after:h-[230px] after:z-20 after:content-[''] after:bg-contain after:bg-no-repeat after:bg-right"
/>
<ForYouSection class="mt-40 pl-16 pr-24" />
<YouNotAloneSection class="mt-40 pl-16 pr-24 mb-40" />
<FeedbackSection class="mt-40 mb-52" />
</section>
</div>
</template>
<script setup lang="ts">
import FeedbackSection from "./_ui/feedbackSection/feedbackSection.vue";
import ForYouSection from "./_ui/forYouSection/forYouSection.vue";
import HeroBanner from "./_ui/heroBanner/heroBanner.vue";
import YouNotAloneSection from "./_ui/youNotAloneSection/youNotAloneSection.vue";
useHead({
title: "Vino Galante",
meta: [
{ name: "description", content: "Онлайн магазин книг автора Vino Galante" },
],
link: [
{
rel: "canonical",
href: `https://ebook.miduway.space/`,
},
],
});
</script>

104
pages/privacy/index.vue Normal file
View File

@ -0,0 +1,104 @@
<template>
<section>
<UiHeading size="300" tag="H1" class="mb-5">
Политика конфиденциальности
</UiHeading>
<UiParagraph size="300"
>Настоящая политика конфиденциальности описывает, как мы собираем,
используем и защищаем личную информацию, которую пользователи
предоставляют при использовании нашего сайта.</UiParagraph
>
<UiHeading size="300" tag="H2">1. Сбор информации</UiHeading>
<UiParagraph size="300"
>При оформлении заказа на сайте вы предоставляете персональные данные,
которые включают:</UiParagraph
>
<ul class="list-disc pl-5">
<li><UiParagraph size="300">Адрес электронной почты</UiParagraph></li>
<li><UiParagraph size="300">Имя (по желанию)</UiParagraph></li>
</ul>
<UiHeading size="300" tag="H2">2. Использование информации</UiHeading>
<UiParagraph size="300"
>Ваши личные данные используются исключительно для:</UiParagraph
>
<ul class="list-disc pl-5">
<li>
<UiParagraph size="300"
>Обработки и выполнения вашего заказа.</UiParagraph
>
</li>
<li>
<UiParagraph> Связи с вами по вопросам вашего заказа. </UiParagraph>
</li>
<li>
<UiParagraph size="300">
Уведомления о важных обновлениях и новостях сайта (только если вы явно
согласились на рассылку).</UiParagraph
>
</li>
</ul>
<UiHeading size="300" tag="H2">3. Защита личных данных</UiHeading>
<UiParagraph size="300">
Мы предпринимаем необходимые меры для защиты ваших личных данных от
несанкционированного доступа, изменения, разглашения или уничтожения.
Доступ к личным данным имеют только сотрудники, непосредственно
участвующие в обработке заказов.
</UiParagraph>
<UiHeading size="300" tag="H2"
>4. Передача информации третьим лицам</UiHeading
>
<UiParagraph size="300">
Мы не передаём ваши личные данные третьим лицам, за исключением случаев,
предусмотренных законодательством Российской Федерации.
</UiParagraph>
<UiHeading size="300" tag="H2">5. Cookies (Куки-файлы)</UiHeading>
<UiParagraph size="300">
Мы используем файлы cookie, чтобы улучшить ваш пользовательский опыт. Вы
можете отключить файлы cookie в настройках вашего браузера, однако это
может ограничить доступ к некоторым функциям сайта.
</UiParagraph>
<UiHeading size="300" tag="H2"
>6. Изменения в политике конфиденциальности</UiHeading
>
<UiParagraph size="300">
Мы можем периодически обновлять настоящую политику конфиденциальности. Об
изменениях мы уведомим вас, разместив новую версию политики на данной
странице.
</UiParagraph>
<UiHeading size="300" tag="H2">7. Ваше согласие</UiHeading>
<UiParagraph size="300"
>Используя наш сайт, вы соглашаетесь с условиями данной политики
конфиденциальности.</UiParagraph
>
<UiParagraph size="300">
Если у вас возникнут вопросы или пожелания относительно обработки ваших
персональных данных, пожалуйста, свяжитесь с нами по электронной почте:
<a href="mailto:vinogalante@yandex.ru">vinogalante@yandex.ru</a>.
</UiParagraph>
</section>
</template>
<script setup lang="ts">
import UiHeading from "@/components/Typography/UiHeading.vue";
import UiParagraph from "@/components/Typography/UiParagraph.vue";
useHead({
title: "Поликита конфиденциальности | Vino Galante",
meta: [
{ name: "description", content: "Онлайн магазин книг автора Vino Galante" },
],
link: [
{
rel: "canonical",
href: `https://ebook.miduway.space/privacy`,
},
],
});
</script>