Delete SPA service files, add index.html stabfile, set the docker and docker-compose.yaml files.
@@ -16,6 +16,6 @@ GOOSE_DRIVER=postgres
|
|||||||
GOOSE_DBSTRING='user=postgres dbname=postgres sslmode=disable'
|
GOOSE_DBSTRING='user=postgres dbname=postgres sslmode=disable'
|
||||||
GOOSE_MIGRATION_DIR=migrations
|
GOOSE_MIGRATION_DIR=migrations
|
||||||
|
|
||||||
# SPA on VUE.js
|
# FRONTEND SPA
|
||||||
INNERPORT=80
|
INNERPORT=80
|
||||||
OUTERPORT=8088
|
OUTERPORT=8088
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# Postgres
|
|
||||||
PGHOST=888
|
|
||||||
PGPORT=888
|
|
||||||
PGUSER=888
|
|
||||||
PGPASSWORD=888
|
|
||||||
PGDATABASE=888
|
|
||||||
SSLmode=disable
|
|
||||||
PGURL='888'
|
|
||||||
|
|
||||||
# SERVER
|
|
||||||
SERVER_PORT=888
|
|
||||||
SECRET_KEY=888
|
|
||||||
|
|
||||||
# MIGRATOR
|
|
||||||
MIGRATOR_PORT=888
|
|
||||||
GOOSE_DRIVER=888
|
|
||||||
GOOSE_DBSTRING='user=888 dbname=888 sslmode=888'
|
|
||||||
GOOSE_MIGRATION_DIR=migrations
|
|
||||||
|
|
||||||
# SPA on VUE.js
|
|
||||||
INNERPORT=888
|
|
||||||
OUTERPORT=888
|
|
||||||
@@ -1,32 +1,11 @@
|
|||||||
# Используем официальный образ Node.js на основе Alpine Linux
|
# Используем официальный образ Nginx
|
||||||
FROM node:16-alpine as build-stage
|
FROM nginx:alpine
|
||||||
|
|
||||||
# Устанавливаем рабочую директорию внутри контейнера
|
# Копируем index.html в папку Nginx
|
||||||
WORKDIR /app
|
COPY index.html /usr/share/nginx/html/
|
||||||
|
|
||||||
# Копируем package.json и package-lock.json (если есть)
|
# (Опционально) Можно заменить конфиг Nginx
|
||||||
COPY package*.json ./
|
# COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# Устанавливаем зависимости
|
# Порт, который будет слушать Nginx
|
||||||
RUN npm install
|
EXPOSE 80
|
||||||
|
|
||||||
# Копируем все файлы проекта в рабочую директорию
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Собираем проект
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# Используем легковесный образ Nginx для serving статики
|
|
||||||
FROM nginx:stable-alpine as production-stage
|
|
||||||
|
|
||||||
# Копируем собранные файлы из предыдущего этапа в директорию Nginx
|
|
||||||
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
|
||||||
|
|
||||||
# Копируем конфигурацию Nginx (если нужно)
|
|
||||||
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
# Открываем порт 80
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
# Запускаем Nginx
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# spa
|
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 in Vite.
|
|
||||||
|
|
||||||
## Recommended IDE Setup
|
|
||||||
|
|
||||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
|
||||||
|
|
||||||
## Customize configuration
|
|
||||||
|
|
||||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
|
||||||
|
|
||||||
## Project Setup
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compile and Hot-Reload for Development
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compile and Minify for Production
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
@@ -1,14 +1,134 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="">
|
<html lang="ru">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/src/components/images/logo150x150.png">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="/src/assets/main.css">
|
<title>ЯлАрба - Туристический агрегатор</title>
|
||||||
<title>YalArba</title>
|
<style>
|
||||||
</head>
|
body {
|
||||||
<body>
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
<div id="app"></div>
|
line-height: 1.6;
|
||||||
<script type="module" src="/src/main.js"></script>
|
color: #333;
|
||||||
</body>
|
max-width: 800px;
|
||||||
</html>
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #1e88e5;
|
||||||
|
color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 2.2em;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #1e88e5;
|
||||||
|
border-bottom: 2px solid #1e88e5;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
.developer {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.roadmap {
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.phase {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: 1px dashed #ccc;
|
||||||
|
}
|
||||||
|
.phase:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>ЯлАрба</h1>
|
||||||
|
<p>Инновационный агрегатор мест отдыха с ИИ-планировщиком маршрутов</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>О проекте</h2>
|
||||||
|
<p>ЯлАрба — это супер-приложение для путешественников, объединяющее в себе:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Агрегатор мест отдыха (отели, экскурсии, рестораны)</li>
|
||||||
|
<li>Маркетплейс туров и локальных сувениров</li>
|
||||||
|
<li>ИИ-планировщик маршрутов с учетом здоровья пользователя</li>
|
||||||
|
<li>Систему бронирования и покупки билетов</li>
|
||||||
|
</ul>
|
||||||
|
<p>Наша миссия — сделать планирование путешествий простым, персонализированным и доступным.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="developer">
|
||||||
|
<h2>Разработчик</h2>
|
||||||
|
<p><strong>Валитов Газиз</strong></p>
|
||||||
|
<p>Full-stack разработчик с опытом в travel-tech проектах. Специализация: Python/Django, React, системы рекомендаций на основе ИИ.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="roadmap">
|
||||||
|
<h2>План разработки</h2>
|
||||||
|
|
||||||
|
<div class="phase">
|
||||||
|
<h3>Этап 1: MVP (0-6 месяцев)</h3>
|
||||||
|
<ul>
|
||||||
|
<li>База мест отдыха (1000+ позиций)</li>
|
||||||
|
<li>Интеграция с API бронирования (Booking.com, Ostrovok)</li>
|
||||||
|
<li>Прототип ИИ-рекомендаций</li>
|
||||||
|
<li>Мобильная версия (PWA)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="phase">
|
||||||
|
<h3>Этап 2: Монетизация (6-12 месяцев)</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Система комиссий (10-15% с бронирований)</li>
|
||||||
|
<li>Платные подписки (PRO-аккаунт)</li>
|
||||||
|
<li>Партнерская программа для гидов</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="phase">
|
||||||
|
<h3>Этап 3: Масштабирование (12-24 месяца)</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Выход на рынки СНГ (Казахстан, Узбекистан)</li>
|
||||||
|
<li>Полноценный ИИ-ассистент с рекомендациями по здоровью</li>
|
||||||
|
<li>Интеграция с сервисами аренды авто</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Технологический стек</h2>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Frontend:</strong> React.js, TypeScript, PWA</li>
|
||||||
|
<li><strong>Backend:</strong> Python/Django, PostgreSQL</li>
|
||||||
|
<li><strong>AI:</strong> NLP-модели для обработки запросов, рекомендательные системы</li>
|
||||||
|
<li><strong>DevOps:</strong> Docker, Kubernetes, Yandex Cloud</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>© 2024 ЯлАрба. Все права защищены.</p>
|
||||||
|
<p>Контакты: gaziz.valitov@yalarba.travel</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", "dist"]
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "spa",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vite build",
|
|
||||||
"preview": "vite preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.7.9",
|
|
||||||
"body-parser": "^1.20.3",
|
|
||||||
"cors": "^2.8.5",
|
|
||||||
"express": "^4.21.2",
|
|
||||||
"pg": "^8.13.1",
|
|
||||||
"spa": "file:",
|
|
||||||
"vue": "^3.5.13",
|
|
||||||
"vue-material-design-icons": "^5.3.1",
|
|
||||||
"vue-router": "^4.5.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
|
||||||
"vite": "^6.0.5",
|
|
||||||
"vite-plugin-vue-devtools": "^7.6.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { RouterLink, RouterView } from 'vue-router'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="main">
|
|
||||||
<RouterView />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/* Общие стили */
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: fit-content;
|
|
||||||
width: 100%;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
margin: 2rem;
|
|
||||||
min-height: 90vh;
|
|
||||||
min-width: 320px;
|
|
||||||
max-width: 1024px;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 1rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Адаптивные стили для мобильных устройств */
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
.main {
|
|
||||||
margin: 0.5rem;
|
|
||||||
min-height: 80vh;
|
|
||||||
min-width: auto;
|
|
||||||
max-width: none;
|
|
||||||
width: 95%; /* Можно сделать еще меньше, если требуется */
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="footer">
|
|
||||||
<div class="navigation" v-on:click="goBack">
|
|
||||||
<img src="./images/icons/arrow_back_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg" alt="back">
|
|
||||||
</div>
|
|
||||||
<router-link to="/">
|
|
||||||
<img src="./images/icons/home_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg" alt="home">
|
|
||||||
</router-link>
|
|
||||||
<div class="navigation" v-on:click="goForward">
|
|
||||||
<img src="./images/icons/arrow_forward_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg" alt="forward">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.footer {
|
|
||||||
height: 3rem;
|
|
||||||
background-color: darkmagenta;
|
|
||||||
border-radius: 1rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 2rem;
|
|
||||||
margin: 0 0 0.5rem 0;
|
|
||||||
}
|
|
||||||
.navigation {
|
|
||||||
padding: 0 1rem;
|
|
||||||
margin: 0 1rem;
|
|
||||||
}
|
|
||||||
.navigation:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(112, 48, 171);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import MenuIcon from 'vue-material-design-icons/Menu.vue';
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
MenuIcon,
|
|
||||||
},
|
|
||||||
name: 'footer',
|
|
||||||
methods: {
|
|
||||||
goBack() {
|
|
||||||
this.$router.go(-1);
|
|
||||||
},
|
|
||||||
goForward() {
|
|
||||||
this.$router.go(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>Freedom & Adventure</h1>
|
|
||||||
<p>Приложение для туристов</p>
|
|
||||||
<p>Прошу потдержать проект</p>
|
|
||||||
<button v-on:click="donat" class="donat-coffee">Донат на кофе</button>
|
|
||||||
<img src="../images/photo_2025-01-25_05-57-24.jpg" alt="Донат QRcod" class="QRcod">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.about {
|
|
||||||
background-color: #8B4513; /* коричневый цвет */
|
|
||||||
height: fit-content;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
filter: none;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 1rem;
|
|
||||||
margin: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.donat-coffee {
|
|
||||||
margin: 1rem;
|
|
||||||
background-color: rgb(89, 219, 109);
|
|
||||||
box-shadow: 1px 4px 8px 0 rgba(27, 45, 37, 0.2);
|
|
||||||
border-radius: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.donat-coffee:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(10, 150, 50);
|
|
||||||
color: white;
|
|
||||||
box-shadow: 1px 4px 8px rgb(10, 150, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
.QRcod {
|
|
||||||
height: 200px;
|
|
||||||
display: flexbox;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
methods: {
|
|
||||||
donat() {
|
|
||||||
window.open("https://www.tinkoff.ru/rm/r_fFXNVwPxmH.VMEQXkfWxO/Ho4MN83486", "_blank");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-if="loading">Загрузка...</div>
|
|
||||||
<ul v-else-if="error">
|
|
||||||
Произошла ошибка: {{ error }}
|
|
||||||
</ul>
|
|
||||||
<ul v-else>
|
|
||||||
<li v-for="commit in commits" :key="commit.sha">
|
|
||||||
<strong>{{ commit.commit.author.date.slice(0, 11) }}:</strong> {{ commit.commit.message }} <i>{{ commit.author.login }}</i>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
commits: [],
|
|
||||||
error: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.fetchCommits();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async fetchCommits() {
|
|
||||||
try {
|
|
||||||
const response = await axios.get('https://api.github.com/repos/valitovgaziz/spa_/commits', {
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/vnd.github.v3+json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
this.commits = response.data;
|
|
||||||
} catch (err) {
|
|
||||||
this.error = err.message || 'Произошла неизвестная ошибка';
|
|
||||||
} finally {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
ul {
|
|
||||||
max-width: 1024px;
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>x``
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="developers">
|
|
||||||
<!-- Заголовок -->
|
|
||||||
<h1 class="title">Разработчики</h1>
|
|
||||||
|
|
||||||
<!-- Список разработчиков -->
|
|
||||||
<ul class="developer-list">
|
|
||||||
<li v-for="dev in developers" :key="dev.name" class="developer-item">
|
|
||||||
<a :href="dev.profileUrl" target="_blank" rel="noopener noreferrer">
|
|
||||||
{{ dev.nickname }} ({{ dev.name }})
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'DevelopersList',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
developers: [
|
|
||||||
{ nickname: 'valitovgaziz', name: 'Валитов Газиз', profileUrl: 'https://github.com/valitovgaziz' }
|
|
||||||
// Добавьте больше разработчиков по аналогии...
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.developers {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.developer-list {
|
|
||||||
list-style-type: none;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.developer-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.developer-item a {
|
|
||||||
color: #007bff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.developer-item a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="reviews-container">
|
|
||||||
<h2>Отзывы о приложении</h2>
|
|
||||||
|
|
||||||
<!-- Форма для добавления отзыва -->
|
|
||||||
<div class="add-review">
|
|
||||||
<textarea v-model="newReview" placeholder="Напишите ваш отзыв..." rows="4"></textarea>
|
|
||||||
<button @click="submitReview" :disabled="!newReview.trim()">Оставить отзыв</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Список последних отзывов -->
|
|
||||||
<div class="reviews-list">
|
|
||||||
<div v-for="review in reviews" :key="review.id" class="review-item">
|
|
||||||
<p>{{ review.text }}</p>
|
|
||||||
<small>{{ formatDate(review.created_at) }}</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
reviews: [], // Список отзывов
|
|
||||||
newReview: '', // Текст нового отзыва
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.loadReviews(); // Загружаем отзывы при монтировании компонента
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// Загрузка отзывов из базы данных
|
|
||||||
async loadReviews() {
|
|
||||||
try {
|
|
||||||
const response = await axios.get('http://213.108.4.63:3000/api/reviews');
|
|
||||||
this.reviews = response.data.slice(0, 5); // Показываем только последние 5 отзывов
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Ошибка при загрузке отзывов:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Отправка нового отзыва
|
|
||||||
async submitReview() {
|
|
||||||
if (!this.newReview.trim()) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.post('http://213.108.4.63:3000/api/reviews', {
|
|
||||||
text: this.newReview,
|
|
||||||
});
|
|
||||||
this.reviews.unshift(response.data); // Добавляем новый отзыв в начало списка
|
|
||||||
this.newReview = ''; // Очищаем текстовое поле
|
|
||||||
if (this.reviews.length > 5) {
|
|
||||||
this.reviews.pop(); // Удаляем самый старый отзыв, если их больше 5
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Ошибка при отправке отзыва:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Форматирование даты
|
|
||||||
formatDate(dateString) {
|
|
||||||
const date = new Date(dateString);
|
|
||||||
return date.toLocaleString(); // Форматируем дату в удобный формат
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.reviews-container {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-review textarea {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-review button {
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #42b983;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-review button:disabled {
|
|
||||||
background-color: #ccc;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reviews-list {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-item {
|
|
||||||
background: #f9f9f9;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-item p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-item small {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<!-- Заголовок -->
|
|
||||||
<h1>Trip & Freedom & Adventure</h1>
|
|
||||||
|
|
||||||
<!-- Основной контент -->
|
|
||||||
<p>Разработка приложения Trip&Freedom&Adventure представляет собой вклад в создание полезного продукта для общества. Данная работа играет важную роль в профессиональном росте и развитии. Миссия этого приложения заключается в помощи пользователям в открытии новых горизонтов, планировании путешествий и наслаждении приключениями без излишних хлопот. Приложение принесет пользу как пользователям, так и мне лично, позволяя углубить мои знания в программировании, дизайне интерфейсов и разработке мобильных приложений. Участие в этом проекте также предоставляет возможность проявить креативность и воплотить идеи, способные улучшить качество жизни людей. Ежедневная работа над приложением приближает нас к созданию удобного и функционального продукта, который станет незаменимым инструментом для путешественников. Этот проект вдохновляет на постоянное движение вперёд, обучение новым навыкам и внесение вклада в технологическое и общественное развитие.</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
// Здесь может быть логика вашего компонента, если требуется
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.container {
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 32px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
line-height: 1.6;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.additional-content {
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
.container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="header">
|
|
||||||
<router-link to="/about" id="rl-about"><img src="../images/logo150x150.png" alt="logo"></router-link>
|
|
||||||
<router-link to="/filosofy" id="rl-filosofy">Trip*Freedom*Adventure</router-link>
|
|
||||||
<Menu />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.header {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 1rem;
|
|
||||||
background-color: aquamarine;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#rl-about {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-items: center;
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
width: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#rl-about:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(85, 117, 117);
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 1.5rem;
|
|
||||||
padding: 0 1rem 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#rl-filosofy {
|
|
||||||
all: unset;
|
|
||||||
box-shadow: 1px 2px 3px rgb(63, 145, 130);
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#rl-filosofy:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(143, 202, 202);
|
|
||||||
box-shadow: 2px 3px 4px rgb(64,146, 132);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Menu from './menu.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Menu,
|
|
||||||
},
|
|
||||||
name: 'header',
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="menu" v-on:click="OpenClose">
|
|
||||||
<img src="../images/icons/menu_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg" alt="menu" id="img-m">
|
|
||||||
|
|
||||||
<ul id="ul-m">
|
|
||||||
<li v-on:click="$refs.profile.$el.click()"><router-link to="/profile" ref="profile">Профиль</router-link></li>
|
|
||||||
<li v-on:click="$refs.settings.$el.click()"><router-link to="/settings" ref="settings">Настройки</router-link></li>
|
|
||||||
<li v-on:click="$refs.about.$el.click()"><router-link to="/about" ref="about">О нас</router-link></li>
|
|
||||||
<li v-on:click="$refs.support.$el.click()"><router-link to="/support" ref="support">Написать в техпотдержку</router-link></li>
|
|
||||||
<li v-on:click="$refs.feetback.$el.click()"><router-link to="/feetback" ref="feetback">Оставить отзыв</router-link></li>
|
|
||||||
<li v-on:click="$refs.registration.$el.click()"><router-link to="/registration" ref="registration">Регистрация</router-link></li>
|
|
||||||
<li v-on:click="$refs.login.$el.click()"><router-link to="/login" ref="login">Войти</router-link></li>
|
|
||||||
<li v-on:click="$refs.logout.$el.click()"><router-link to="/logout" ref="logout">Выйти</router-link></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.menu {
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#img-m {
|
|
||||||
height: 2rem;
|
|
||||||
width: 2rem;
|
|
||||||
border: solid 1px rgb(33, 159, 181);
|
|
||||||
border-radius: 1rem;
|
|
||||||
background-color: rgb(37, 78, 78);
|
|
||||||
margin: 0 1rem 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#img-m:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(71, 135, 105);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ul-m {
|
|
||||||
position: absolute;
|
|
||||||
top: 3rem;
|
|
||||||
right: 1rem;
|
|
||||||
width: fit-content;
|
|
||||||
visibility: hidden;
|
|
||||||
margin: auto;
|
|
||||||
border: 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin: 3px 0;
|
|
||||||
border: solid 1px black;
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(153, 204, 204);
|
|
||||||
border-radius: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'menu',
|
|
||||||
methods: {
|
|
||||||
OpenClose: OpenCloseM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function OpenCloseM() {
|
|
||||||
var ul = document.querySelector('ul');
|
|
||||||
if (ul.style.visibility === 'hidden') {
|
|
||||||
ul.style.visibility = 'visible';
|
|
||||||
} else {
|
|
||||||
ul.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="m313-440 224 224-57 56-320-320 320-320 57 56-224 224h487v80H313Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 189 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 190 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 222 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M240-200h120v-240h240v240h120v-360L480-740 240-560v360Zm-80 80v-480l320-240 320 240v480H520v-240h-80v240H160Zm320-350Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 243 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 70 KiB |
@@ -1,116 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="login-form">
|
|
||||||
<h1>Логин</h1>
|
|
||||||
<form @submit.prevent="handleSubmit">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email">Email:</label>
|
|
||||||
<input v-model.trim="email" type="email" id="email" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Пароль:</label>
|
|
||||||
<input v-model.trim="password" type="password" id="password" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit">Войти</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
email: '',
|
|
||||||
password: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSubmit() {
|
|
||||||
if (!this.isValid(this.email, this.password)) {
|
|
||||||
alert("Пожалуйста, заполните все поля корректно.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loginUser({
|
|
||||||
email: this.email,
|
|
||||||
password: this.password
|
|
||||||
}).then(() => {
|
|
||||||
this.$router.push('/'); // Переход на главную страницу
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
alert('Неверный email или пароль. Попробуйте снова.');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isValid(email, password) {
|
|
||||||
if (email.length === 0 || password.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
||||||
if (!emailRegex.test(email)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.length < 6) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
async loginUser(data) {
|
|
||||||
console.log("Login by this data: ", data);
|
|
||||||
// try {
|
|
||||||
// const response = await fetch('/login', {
|
|
||||||
// method: 'POST',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json'
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify(data)
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!response.ok) {
|
|
||||||
// throw new Error('Неверный email или пароль');
|
|
||||||
// }
|
|
||||||
// } catch (error) {
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.login-form {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: 50px auto;
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="logout">
|
|
||||||
<h2>выход</h2>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.logout {
|
|
||||||
background-color: #c68686;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'logout',
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="register-form">
|
|
||||||
<h1>Регистрация</h1>
|
|
||||||
<form @submit.prevent="handleSubmit">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="username">Имя пользователя:</label>
|
|
||||||
<input v-model.trim="username" type="text" id="username" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email">Email:</label>
|
|
||||||
<input v-model.trim="email" type="email" id="email" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Пароль:</label>
|
|
||||||
<input v-model.trim="password" type="password" id="password" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit">Зарегистрироваться</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
username: '',
|
|
||||||
email: '',
|
|
||||||
password: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSubmit() {
|
|
||||||
if (!this.isValid(this.username, this.email, this.password)) {
|
|
||||||
alert("Пожалуйста, заполните все поля корректно.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sendRegistrationData({
|
|
||||||
username: this.username,
|
|
||||||
email: this.email,
|
|
||||||
password: this.password
|
|
||||||
}).then(() => {
|
|
||||||
this.$router.push('/login'); // Переход на страницу логина
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
alert('Что-то пошло не так. Попробуйте еще раз.');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isValid(username, email, password) {
|
|
||||||
if (username.length === 0 || email.length === 0 || password.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
||||||
if (!emailRegex.test(email)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.length < 6) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
async sendRegistrationData(data) {
|
|
||||||
console.log("Register by this data: ", data);
|
|
||||||
// try {
|
|
||||||
// const response = await fetch('/register', {
|
|
||||||
// method: 'POST',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json'
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify(data)
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!response.ok) {
|
|
||||||
// throw new Error('Ошибка при регистрации');
|
|
||||||
// }
|
|
||||||
// } catch (error) {
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.register-form {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: 50px auto;
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-group input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="profile">
|
|
||||||
<h3>This is an profile</h3>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'profile',
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="results">
|
|
||||||
<h1>Results</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.results {
|
|
||||||
background-color: darkslategrey;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
</script>
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="search-container">
|
|
||||||
<div class="search-input-container">
|
|
||||||
<!-- Иконка для вызова меню параметров -->
|
|
||||||
<div class="menu-icon" @click="toggleMenu">
|
|
||||||
<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" fill="currentColor"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<!-- Поле ввода -->
|
|
||||||
<input
|
|
||||||
v-model="searchQuery"
|
|
||||||
@keyup.enter="performSearch"
|
|
||||||
class="search-input"
|
|
||||||
placeholder="Введите место для поиска"
|
|
||||||
/>
|
|
||||||
<!-- Кнопка поиска -->
|
|
||||||
<button @click="performSearch" class="search-button">
|
|
||||||
<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path d="M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16zm8-8a7.95 7.95 0 0 1-1.757 4.95l4.95 4.95-1.414 1.414-4.95-4.95A7.95 7.95 0 0 1 10 18z" fill="currentColor"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<!-- Выпадающее меню для параметров поиска -->
|
|
||||||
<div v-if="isMenuVisible" class="search-menu">
|
|
||||||
<div class="menu-item" v-for="option in searchOptions" :key="option" @click="selectOption(option)">
|
|
||||||
{{ option }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchQuery: '',
|
|
||||||
isMenuVisible: false,
|
|
||||||
searchOptions: ['Пляжи', 'Горы', 'Отели', 'Рестораны']
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
performSearch() {
|
|
||||||
if (this.searchQuery.trim()) {
|
|
||||||
// Переход на страницу результатов поиска с передачей запроса
|
|
||||||
this.$router.push({
|
|
||||||
name: 'results', // Имя маршрута для страницы результатов
|
|
||||||
query: { q: this.searchQuery } // Передача поискового запроса через query-параметры
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleMenu() {
|
|
||||||
this.isMenuVisible = !this.isMenuVisible;
|
|
||||||
},
|
|
||||||
selectOption(option) {
|
|
||||||
this.searchQuery = option;
|
|
||||||
this.isMenuVisible = false;
|
|
||||||
this.performSearch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.search-container {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-input-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 25px;
|
|
||||||
padding: 10px;
|
|
||||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-input {
|
|
||||||
flex-grow: 1;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-menu {
|
|
||||||
position: absolute;
|
|
||||||
top: 60px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item {
|
|
||||||
padding: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item:hover {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="settings">
|
|
||||||
<h1>Settings</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.settings {
|
|
||||||
background-color: #856565;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'Settings',
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="support">
|
|
||||||
<h3>This is an message send to support</h3>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.support {
|
|
||||||
background-color: darkkhaki;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'support',
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import './assets/main.css';
|
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
|
||||||
import App from './App.vue'
|
|
||||||
import router from './router'
|
|
||||||
|
|
||||||
const app = createApp(App)
|
|
||||||
|
|
||||||
app.use(router)
|
|
||||||
|
|
||||||
app.mount('#app')
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'home',
|
|
||||||
component: () => import('../views/HomeView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/about',
|
|
||||||
name: 'about',
|
|
||||||
// route level code-splitting
|
|
||||||
// this generates a separate chunk (About.[hash].js) for this route
|
|
||||||
// which is lazy-loaded when the route is visited.
|
|
||||||
component: () => import('../views/AboutView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/profile',
|
|
||||||
name: 'profile',
|
|
||||||
component: () => import('../views/ProfileView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/support',
|
|
||||||
name: 'support',
|
|
||||||
component: () => import('../views/SupportView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/feetback',
|
|
||||||
name: 'feetback',
|
|
||||||
component: () => import('../views/FeetbackView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/results',
|
|
||||||
name: 'results',
|
|
||||||
component: () => import('../views/ResultsView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/settings',
|
|
||||||
name: 'settings',
|
|
||||||
component: () => import('../views/SettingsView.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/registration',
|
|
||||||
name: 'registration',
|
|
||||||
component: () => import('../views/RegistrationView.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
name: 'login',
|
|
||||||
component: () => import('../views/LogInView.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/logout',
|
|
||||||
name: 'logout',
|
|
||||||
component: () => import('../views/LogOutView.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/filosofy',
|
|
||||||
name: 'filosofy',
|
|
||||||
component: () => import('../views/FilosofyView.vue')
|
|
||||||
}
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<About />
|
|
||||||
<Developers />
|
|
||||||
<Commits />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import About from '../components/about/about.vue';
|
|
||||||
import Commits from '../components/about/commits.vue';
|
|
||||||
import Developers from '../components/about/developers.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
About,
|
|
||||||
Developers,
|
|
||||||
Commits,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Feetback />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Feetback from '../components/feeback/feetback.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Feetback,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Filosofy />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Filosofy from '../components/filosofy.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Footer,
|
|
||||||
Header,
|
|
||||||
Filosofy,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<SearchLine />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<style src="../assets/main.css"></style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import SearchLine from '../components/searchLine/searchLine.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
SearchLine,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<LogIn />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import LogIn from '../components/inout/login.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
LogIn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<LogOut />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import LogOut from '../components/inout/logout.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
LogOut,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Profile />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Profile from '../components/profile.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Profile,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Registration />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Registration from '../components/inout/registration.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Registration,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<SearchLine />
|
|
||||||
<Results />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Results from '../components/saerch_results/results.vue';
|
|
||||||
import searchLine from '@/components/searchLine/searchLine.vue';
|
|
||||||
import SearchLine from '@/components/searchLine/searchLine.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Results,
|
|
||||||
SearchLine,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Settings />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Settings from '../components/settings.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Settings,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<Support />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style></style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Header from '../components/header/header.vue';
|
|
||||||
import Footer from '../components/footer.vue';
|
|
||||||
import Support from '../components/support.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
Footer,
|
|
||||||
Support,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
content: [
|
|
||||||
'./src/**/*.{html,js,vue}',
|
|
||||||
],
|
|
||||||
theme: {
|
|
||||||
extend: {},
|
|
||||||
},
|
|
||||||
plugins: [],
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { fileURLToPath, URL } from 'node:url'
|
|
||||||
|
|
||||||
import { defineConfig } from 'vite'
|
|
||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
||||||
|
|
||||||
// https://vite.dev/config/
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
vue(),
|
|
||||||
vueDevTools(),
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||