Merge pull request #5 from VikingEngineers/YuryTest

Yury test
This commit is contained in:
lazyseal 2023-05-21 12:36:39 +01:00 committed by GitHub
commit a733d4f63a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1143 additions and 949 deletions

View File

@ -12,33 +12,7 @@ defineProps({
route: "/" route: "/"
}) })
}, },
socials: {
type: Array,
icon: String,
link: String,
default: () => [
{
icon: '<i class="fab fa-facebook text-lg opacity-8"></i>',
link: "https://www.facebook.com/CreativeTim/"
},
{
icon: '<i class="fab fa-twitter text-lg opacity-8"></i>',
link: "https://twitter.com/creativetim"
},
{
icon: '<i class="fab fa-dribbble text-lg opacity-8"></i>',
link: "https://dribbble.com/creativetim"
},
{
icon: '<i class="fab fa-github text-lg opacity-8"></i>',
link: "https://github.com/creativetimofficial"
},
{
icon: '<i class="fab fa-youtube text-lg opacity-8"></i>',
link: "https://www.youtube.com/channel/UCVyTG4sCw-rOvB9oHkzZD1w"
}
]
},
menus: { menus: {
type: Array, type: Array,
name: String, name: String,
@ -127,51 +101,17 @@ defineProps({
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-3 mb-4 ms-auto"> <div class="col-md-3 mb-4 ms-auto">
<div>
<a :href="brand.route">
<img :src="brand.logo" class="mb-3 footer-logo" alt="main_logo" />
</a>
<h6 class="font-weight-bolder mb-4">{{ brand.name }}</h6>
</div>
<div>
<ul class="d-flex flex-row ms-n3 nav">
<li
class="nav-item"
v-for="{ icon, link } of socials"
:key="link"
>
<a
class="nav-link pe-1"
:href="link"
target="_blank"
v-html="icon"
>
</a>
</li>
</ul>
</div>
</div>
<div
class="col-md-2 col-sm-6 col-6 mb-4"
v-for="{ name, items } of menus"
:key="name"
>
<h6 class="text-sm">{{ name }}</h6>
<ul class="flex-column ms-n3 nav">
<li class="nav-item" v-for="item of items" :key="item.name">
<a class="nav-link" :href="item.href" target="_blank">
{{ item.name }}
</a>
</li>
</ul>
</div> </div>
<div class="col-12"> <div class="col-12">
<div class="text-center"> <div class="text-center">
<p class="text-dark my-4 text-sm font-weight-normal"> <p class="text-dark my-4 text-sm font-weight-normal">
All rights reserved. Copyright © Екатерина Кузнецова, Ирина Комарова.
{{ new Date().getFullYear() }} {{ new Date().getFullYear() }}
Material Kit by . Использованы материалы
<a href="https://www.creative-tim.com" target="_blank" <a href="https://www.creative-tim.com" target="_blank"
>Creative Tim</a >Creative Tim</a
>. >.

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { RouterLink } from "vue-router"; import { RouterLink } from "vue-router";
import { ref, watch } from "vue"; import { ref, watch, computed } from "vue";
import { useWindowsWidth } from "../../assets/js/useWindowsWidth"; import { useWindowsWidth } from "../../assets/js/useWindowsWidth";
// images // images
@ -8,6 +8,8 @@ import ArrDark from "@/assets/img/down-arrow-dark.svg";
import downArrow from "@/assets/img/down-arrow.svg"; import downArrow from "@/assets/img/down-arrow.svg";
import DownArrWhite from "@/assets/img/down-arrow-white.svg"; import DownArrWhite from "@/assets/img/down-arrow-white.svg";
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); // Computed property to check if the user is authenticated
const props = defineProps({ const props = defineProps({
action: { action: {
type: Object, type: Object,
@ -117,7 +119,7 @@ watch(
]" ]"
:to="{ name: 'presentation' }" :to="{ name: 'presentation' }"
rel="tooltip" rel="tooltip"
title="Цифровое портфолио и деловые контакты" title="Designed and Coded by Creative Tim"
data-placement="bottom" data-placement="bottom"
> >
LinkedMin LinkedMin
@ -131,15 +133,15 @@ watch(
" "
to="/" to="/"
rel="tooltip" rel="tooltip"
title="Цифровое портфолио и деловые контакты" title="Designed and Coded by Creative Tim"
data-placement="bottom" data-placement="bottom"
> >
Material Design LinkedMin
</RouterLink> </RouterLink>
<a <a
href="https://www.creative-tim.com/product/vue-material-kit-pro" href="/pages/landing-pages/basic"
class="btn btn-sm bg-gradient-success mb-0 ms-auto d-lg-none d-block" class="btn btn-sm bg-gradient-success mb-0 ms-auto d-lg-none d-block"
>Buy Now</a >Вход/Регистрация</a
> >
<button <button
class="navbar-toggler shadow-none ms-2" class="navbar-toggler shadow-none ms-2"
@ -175,7 +177,7 @@ watch(
:class="getTextColor()" :class="getTextColor()"
>dashboard</i >dashboard</i
> >
Люди Пользователи
<img <img
:src="getArrowColor()" :src="getArrowColor()"
alt="down-arrow" alt="down-arrow"
@ -198,37 +200,15 @@ watch(
<div <div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-1" class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-1"
> >
Landing Pages Все пользователи
</div> </div>
<RouterLink <RouterLink
:to="{ name: 'about' }" :to="{ name: 'profiles' }"
class="dropdown-item border-radius-md" class="dropdown-item border-radius-md"
> >
<span>About Us</span> <span>Все пользователи</span>
</RouterLink>
<RouterLink
:to="{ name: 'contactus' }"
class="dropdown-item border-radius-md"
>
<span>Contact Us</span>
</RouterLink>
<RouterLink
:to="{ name: 'author' }"
class="dropdown-item border-radius-md"
>
<span>Author</span>
</RouterLink>
<div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0 mt-3"
>
Account
</div>
<RouterLink
:to="{ name: 'signin-basic' }"
class="dropdown-item border-radius-md"
>
<span>Sign In</span>
</RouterLink> </RouterLink>
</div> </div>
</div> </div>
</div> </div>
@ -237,40 +217,20 @@ watch(
<div <div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0" class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0"
> >
Landing Pages Все пользователи
</div> </div>
<RouterLink <RouterLink
:to="{ name: 'about' }" :to="{ name: 'profiles' }"
class="dropdown-item border-radius-md" class="dropdown-item border-radius-md"
> >
<span>About Us</span> <span>Все пользователи</span>
</RouterLink>
<RouterLink
:to="{ name: 'contactus' }"
class="dropdown-item border-radius-md"
>
<span>Contact Us</span>
</RouterLink>
<RouterLink
:to="{ name: 'author' }"
class="dropdown-item border-radius-md"
>
<span>Author</span>
</RouterLink>
<div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0 mt-3"
>
Account
</div>
<RouterLink
:to="{ name: 'signin-basic' }"
class="dropdown-item border-radius-md"
>
<span>Sign In</span>
</RouterLink> </RouterLink>
</div> </div>
</div> </div>
</li> </li>
<li class="nav-item dropdown dropdown-hover mx-2"> <li class="nav-item dropdown dropdown-hover mx-2">
<a <a
role="button" role="button"
@ -308,37 +268,15 @@ watch(
<div <div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-1" class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-1"
> >
Landing Pages Все проекты
</div> </div>
<RouterLink <RouterLink
:to="{ name: 'about' }" :to="{ name: 'projects' }"
class="dropdown-item border-radius-md" class="dropdown-item border-radius-md"
> >
<span>About Us</span> <span>Все проекты</span>
</RouterLink>
<RouterLink
:to="{ name: 'contactus' }"
class="dropdown-item border-radius-md"
>
<span>Contact Us</span>
</RouterLink>
<RouterLink
:to="{ name: 'author' }"
class="dropdown-item border-radius-md"
>
<span>Author</span>
</RouterLink>
<div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0 mt-3"
>
Account
</div>
<RouterLink
:to="{ name: 'signin-basic' }"
class="dropdown-item border-radius-md"
>
<span>Sign In</span>
</RouterLink> </RouterLink>
</div> </div>
</div> </div>
</div> </div>
@ -347,524 +285,22 @@ watch(
<div <div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0" class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0"
> >
Landing Pages Все проекты
</div> </div>
<RouterLink <RouterLink
:to="{ name: 'about' }" :to="{ name: 'projects' }"
class="dropdown-item border-radius-md" class="dropdown-item border-radius-md"
> >
<span>About Us</span> <span>Все проекты</span>
</RouterLink>
<RouterLink
:to="{ name: 'contactus' }"
class="dropdown-item border-radius-md"
>
<span>Contact Us</span>
</RouterLink>
<RouterLink
:to="{ name: 'author' }"
class="dropdown-item border-radius-md"
>
<span>Author</span>
</RouterLink>
<div
class="dropdown-header text-dark font-weight-bolder d-flex align-items-center px-0 mt-3"
>
Account
</div>
<RouterLink
:to="{ name: 'signin-basic' }"
class="dropdown-item border-radius-md"
>
<span>Sign In</span>
</RouterLink> </RouterLink>
</div> </div>
</div> </div>
</li> </li>
<li class="nav-item dropdown dropdown-hover mx-2">
<a
role="button"
class="nav-link ps-2 d-flex cursor-pointer align-items-center" <li v-if="isAuthenticated" class="nav-item dropdown dropdown-hover mx-2">
:class="getTextColor()"
id="dropdownMenuBlocks"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i
class="material-icons opacity-6 me-2 text-md"
:class="getTextColor()"
>view_day</i
>
Sections
<img
:src="getArrowColor()"
alt="down-arrow"
class="arrow ms-2 d-lg-block d-none"
/>
<img
:src="getArrowColor()"
alt="down-arrow"
class="arrow ms-1 d-lg-none d-block ms-auto"
/>
</a>
<div
class="dropdown-menu dropdown-menu-end dropdown-menu-animation dropdown-md dropdown-md-responsive p-3 border-radius-lg mt-0 mt-lg-3"
aria-labelledby="dropdownMenuBlocks"
>
<div class="d-none d-lg-block">
<ul class="list-group">
<li
class="nav-item dropdown dropdown-hover dropdown-subitem list-group-item border-0 p-0"
>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="javascript:;"
>
<div class="d-flex">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Page Sections
</h6>
<span class="text-sm">See all sections</span>
</div>
<img
:src="downArrow"
alt="down-arrow"
class="arrow"
/>
</div>
</div>
</a>
<div class="dropdown-menu mt-0 py-3 px-2 mt-3">
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'page-headers' }"
>
Page Headers
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'page-features' }"
>
Features
</RouterLink>
</div>
</li>
<li
class="nav-item dropdown dropdown-hover dropdown-subitem list-group-item border-0 p-0"
>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="javascript:;"
>
<div class="d-flex">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Navigation
</h6>
<span class="text-sm">See all navigations</span>
</div>
<img
:src="downArrow"
alt="down-arrow"
class="arrow"
/>
</div>
</div>
</a>
<div class="dropdown-menu mt-0 py-3 px-2 mt-3">
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-navbars' }"
>
Navbars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-navtabs' }"
>
Nav Tabs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-pagination' }"
>
Pagination
</RouterLink>
</div>
</li>
<li
class="nav-item dropdown dropdown-hover dropdown-subitem list-group-item border-0 p-0"
>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="javascript:;"
>
<div class="d-flex">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Input Areas
</h6>
<span class="text-sm">See all input areas</span>
</div>
<img
:src="downArrow"
alt="down-arrow"
class="arrow"
/>
</div>
</div>
</a>
<div class="dropdown-menu mt-0 py-3 px-2 mt-3">
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'inputareas-inputs' }"
>
Inputs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'inputareas-forms' }"
>
Forms
</RouterLink>
</div>
</li>
<li
class="nav-item dropdown dropdown-hover dropdown-subitem list-group-item border-0 p-0"
>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="javascript:;"
>
<div class="d-flex">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Attention Catchers
</h6>
<span class="text-sm">See all examples</span>
</div>
<img
:src="downArrow"
alt="down-arrow"
class="arrow"
/>
</div>
</div>
</a>
<div class="dropdown-menu mt-0 py-3 px-2 mt-3">
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-alerts' }"
>
Alerts
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-modals' }"
>
Modals
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-tooltips-popovers' }"
>
Tooltips & Popovers
</RouterLink>
</div>
</li>
<li
class="nav-item dropdown dropdown-hover dropdown-subitem list-group-item border-0 p-0"
>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="javascript:;"
>
<div class="d-flex">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Elements
</h6>
<span class="text-sm">See all elements</span>
</div>
<img
:src="downArrow"
alt="down-arrow"
class="arrow"
/>
</div>
</div>
</a>
<div class="dropdown-menu mt-0 py-3 px-2 mt-3">
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-avatars' }"
>
Avatars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-badges' }"
>
Badges
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-breadcrumbs' }"
>
Breadcrumbs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-buttons' }"
>
Buttons
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-button-groups' }"
>
Button Groups
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-dropdowns' }"
>
Dropdowns
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-progress-bars' }"
>
Progress Bars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-toggles' }"
>
Toggles
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-typography' }"
>
Typography
</RouterLink>
</div>
</li>
</ul>
</div>
<div class="row d-lg-none">
<div class="col-md-12">
<div class="d-flex mb-2">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Page Sections
</h6>
</div>
</div>
</div>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'page-headers' }"
>
Page Headers
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'page-features' }"
>
Features
</RouterLink>
<div class="d-flex mb-2 mt-3">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Navigation
</h6>
</div>
</div>
</div>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-navbars' }"
>
Navbars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-navtabs' }"
>
Nav Tabs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'navigation-pagination' }"
>
Pagination
</RouterLink>
<div class="d-flex mb-2 mt-3">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Input Areas
</h6>
</div>
</div>
</div>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'inputareas-inputs' }"
>
Inputs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'inputareas-forms' }"
>
Forms
</RouterLink>
<div class="d-flex mb-2 mt-3">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Attention Catchers
</h6>
</div>
</div>
</div>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-alerts' }"
>
Alerts
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-modals' }"
>
Modals
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'ac-tooltips-popovers' }"
>
Tooltips & Popovers
</RouterLink>
<div class="d-flex mb-2 mt-3">
<div
class="w-100 d-flex align-items-center justify-content-between"
>
<div>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Elements
</h6>
</div>
</div>
</div>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-avatars' }"
>
Avatars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-badges' }"
>
Badges
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-breadcrumbs' }"
>
Breadcrumbs
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-buttons' }"
>
Buttons
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-button-groups' }"
>
Button Groups
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-dropdowns' }"
>
Dropdowns
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-progress-bars' }"
>
Progress Bars
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-toggles' }"
>
Toggles
</RouterLink>
<RouterLink
class="dropdown-item ps-3 border-radius-md mb-1"
:to="{ name: 'el-typography' }"
>
Typography
</RouterLink>
</div>
</div>
</div>
</li>
<li class="nav-item dropdown dropdown-hover mx-2">
<a <a
role="button" role="button"
class="nav-link ps-2 d-flex cursor-pointer align-items-center" class="nav-link ps-2 d-flex cursor-pointer align-items-center"
@ -878,7 +314,7 @@ watch(
:class="getTextColor()" :class="getTextColor()"
>article</i >article</i
> >
Мой профиль Профиль
<img <img
:src="getArrowColor()" :src="getArrowColor()"
alt="down-arrow" alt="down-arrow"
@ -899,7 +335,40 @@ watch(
<li class="nav-item list-group-item border-0 p-0"> <li class="nav-item list-group-item border-0 p-0">
<a <a
class="dropdown-item py-2 ps-3 border-radius-md" class="dropdown-item py-2 ps-3 border-radius-md"
href=" https://www.creative-tim.com/learning-lab/vue/overview/material-kit/" href="/ViewMyProfile"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Мой Профиль
</h6>
<span class="text-sm"
>Рассказ о том, какой я классный</span
>
</a>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="/CreateProject"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Создать проект
</h6>
<span class="text-sm"
>Чтобы стать ещё более классным</span
>
</a>
</li>
</ul>
</div>
<div class="row d-lg-none">
<div class="col-md-12 g-0">
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="/ViewMyProfile"
> >
<h6 <h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0" class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
@ -907,136 +376,15 @@ watch(
Мой профиль Мой профиль
</h6> </h6>
<span class="text-sm" <span class="text-sm"
>Просмотр и редактирование профиля</span >Рассказ о том, какой я классный</span
>
</a>
</li>
<li class="nav-item list-group-item border-0 p-0">
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href=" https://www.creative-tim.com/learning-lab/vue/colors/material-kit/"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Мои проекты
</h6>
<span class="text-sm"
>Просмотр и редактирование проектов, в которых я принимаю участие</span
>
</a>
</li>
<li class="nav-item list-group-item border-0 p-0">
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href=" https://www.creative-tim.com/learning-lab/vue/alerts/material-kit/"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Мои сообщения
</h6>
<span class="text-sm"
>Просмотр и отправка личных сообщений</span
>
</a>
</li>
</ul>
</div>
<div class="row d-lg-none">
<div class="col-md-12 g-0">
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="./pages/about-us.html"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Getting Started
</h6>
<span class="text-sm"
>All about overview, quick start, license and
contents</span
>
</a>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="./pages/about-us.html"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Foundation
</h6>
<span class="text-sm"
>See our colors, icons and typography</span
>
</a>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="./pages/about-us.html"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Components
</h6>
<span class="text-sm"
>Explore our collection of fully designed components</span
>
</a>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="./pages/about-us.html"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Plugins
</h6>
<span class="text-sm"
>Check how you can integrate our plugins</span
>
</a>
<a
class="dropdown-item py-2 ps-3 border-radius-md"
href="./pages/about-us.html"
>
<h6
class="dropdown-header text-dark font-weight-bolder d-flex justify-content-cente align-items-center p-0"
>
Utility Classes
</h6>
<span class="text-sm"
>For those who want flexibility, use our utility
classes</span
> >
</a> </a>
</div> </div>
</div> </div>
</div> </div>
</li> </li>
<!-- <li class="nav-item dropdown dropdown-hover mx-2">
<a
href="hhttps://github.com/VikingEngineers"
class="nav-link d-flex cursor-pointer align-items-center"
>
<svg
width="20px"
height="20px"
class="material-icons me-2 opacity-6"
viewBox="0 0 24 24"
aria-hidden="true"
data-testid="GitHubIcon"
:fill="props.transparent && '#fff'"
>
<path
d="M12 1.27a11 11 0 00-3.48 21.46c.55.09.73-.28.73-.55v-1.84c-3.03.64-3.67-1.46-3.67-1.46-.55-1.29-1.28-1.65-1.28-1.65-.92-.65.1-.65.1-.65 1.1 0 1.73 1.1 1.73 1.1.92 1.65 2.57 1.2 3.21.92a2 2 0 01.64-1.47c-2.47-.27-5.04-1.19-5.04-5.5 0-1.1.46-2.1 1.2-2.84a3.76 3.76 0 010-2.93s.91-.28 3.11 1.1c1.8-.49 3.7-.49 5.5 0 2.1-1.38 3.02-1.1 3.02-1.1a3.76 3.76 0 010 2.93c.83.74 1.2 1.74 1.2 2.94 0 4.21-2.57 5.13-5.04 5.4.45.37.82.92.82 2.02v3.03c0 .27.1.64.73.55A11 11 0 0012 1.27"
></path>
</svg>
Github
</a>
</li> -->
</ul> </ul>
<ul class="navbar-nav d-lg-block d-none"> <ul class="navbar-nav d-lg-block d-none">
<li class="nav-item"> <li class="nav-item">

View File

@ -4,28 +4,17 @@ import AboutView from "../views/LandingPages/AboutUs/AboutView.vue";
import ContactView from "../views/LandingPages/ContactUs/ContactView.vue"; import ContactView from "../views/LandingPages/ContactUs/ContactView.vue";
import AuthorView from "../views/LandingPages/Author/AuthorView.vue"; import AuthorView from "../views/LandingPages/Author/AuthorView.vue";
import SignInBasicView from "../views/LandingPages/SignIn/BasicView.vue"; import SignInBasicView from "../views/LandingPages/SignIn/BasicView.vue";
import PageHeaders from "../layouts/sections/page-sections/page-headers/HeadersView.vue";
import PageFeatures from "../layouts/sections/page-sections/features/FeaturesView.vue";
import NavigationNavbars from "../layouts/sections/navigation/navbars/NavbarsView.vue";
import NavigationNavTabs from "../layouts/sections/navigation/nav-tabs/NavTabsView.vue";
import NavigationPagination from "../layouts/sections/navigation/pagination/PaginationView.vue";
import InputAreasInputs from "../layouts/sections/input-areas/inputs/InputsView.vue";
import InputAreasForms from "../layouts/sections/input-areas/forms/FormsView.vue";
import ACAlerts from "../layouts/sections/attention-catchers/alerts/AlertsView.vue";
import ACModals from "../layouts/sections/attention-catchers/modals/ModalsView.vue";
import ACTooltipsPopovers from "../layouts/sections/attention-catchers/tooltips-popovers/TooltipsPopoversView.vue";
import ElAvatars from "../layouts/sections/elements/avatars/AvatarsView.vue";
import ElBadges from "../layouts/sections/elements/badges/BadgesView.vue";
import ElBreadcrumbs from "../layouts/sections/elements/breadcrumbs/BreadcrumbsView.vue";
import ElButtons from "../layouts/sections/elements/buttons/ButtonsView.vue";
import ElButtonGroups from "../layouts/sections/elements/button-groups/ButtonGroupsView.vue";
import ElDropdowns from "../layouts/sections/elements/dropdowns/DropdownsView.vue";
import ElProgressBars from "../layouts/sections/elements/progress-bars/ProgressBarsView.vue";
import ElToggles from "../layouts/sections/elements/toggles/TogglesView.vue";
import ElTypography from "../layouts/sections/elements/typography/TypographyView.vue";
import Project from "../views/LandingPages/Project/Project.vue"; import Project from "../views/LandingPages/Project/Project.vue";
import Profile from "../views/LandingPages/Profile/Profile.vue"; import Profile from "../views/LandingPages/Profile/Profile.vue";
import TopSecretProject from "../views/LandingPages/Project/TopSecretProject.vue"; import TopSecretProject from "../views/LandingPages/Project/TopSecretProject.vue";
import BasicRegister from "../views/LandingPages/SignIn/BasicRegister.vue";
import ForgotPassword from "../views/LandingPages/SignIn/ForgotPassword.vue";
import Projects from "../views/LandingPages/Project/AllProjects.vue";
import Profiles from "../views/LandingPages/Profile/AllProfiles.vue";
import ViewMyProfile from "../views/LandingPages/Profile/AdmireProfile.vue";
import EditMyProfile from "../views/LandingPages/Profile/EditProfile.vue";
import CreateProject from "../views/LandingPages/Project/AddProject.vue";
import EditProject from "../views/LandingPages/Project/EditProject.vue";
const router = createRouter({ const router = createRouter({
@ -43,6 +32,24 @@ const router = createRouter({
component: Project component: Project
}, },
{
path: '/projects',
name: 'projects',
component: Projects
},
{
path: '/CreateProject',
name: 'createproject',
component: CreateProject
},
{
path: '/EditProject/:id',
name: 'editproject',
component: EditProject
},
{ {
path: '/TopSecret', path: '/TopSecret',
name: 'topsecretproject', name: 'topsecretproject',
@ -55,6 +62,36 @@ const router = createRouter({
component: Profile component: Profile
}, },
{
path: '/ViewMyProfile',
name: 'viewmyprofile',
component: ViewMyProfile
},
{
path: '/EditMyProfile',
name: 'editmyprofile',
component: EditMyProfile
},
{
path: '/profiles',
name: 'profiles',
component: Profiles
},
{
path: "/register",
name: "register",
component: BasicRegister,
},
{
path: "/forgot",
name: "forgot",
component: ForgotPassword,
},
{ {
path: "/pages/landing-pages/about-us", path: "/pages/landing-pages/about-us",
name: "about", name: "about",
@ -75,101 +112,8 @@ const router = createRouter({
name: "signin-basic", name: "signin-basic",
component: SignInBasicView, component: SignInBasicView,
}, },
{
path: "/sections/page-sections/page-headers",
name: "page-headers",
component: PageHeaders,
},
{
path: "/sections/page-sections/features",
name: "page-features",
component: PageFeatures,
},
{
path: "/sections/navigation/navbars",
name: "navigation-navbars",
component: NavigationNavbars,
},
{
path: "/sections/navigation/nav-tabs",
name: "navigation-navtabs",
component: NavigationNavTabs,
},
{
path: "/sections/navigation/pagination",
name: "navigation-pagination",
component: NavigationPagination,
},
{
path: "/sections/input-areas/inputs",
name: "inputareas-inputs",
component: InputAreasInputs,
},
{
path: "/sections/input-areas/forms",
name: "inputareas-forms",
component: InputAreasForms,
},
{
path: "/sections/attention-catchers/alerts",
name: "ac-alerts",
component: ACAlerts,
},
{
path: "/sections/attention-catchers/modals",
name: "ac-modals",
component: ACModals,
},
{
path: "/sections/attention-catchers/tooltips-popovers",
name: "ac-tooltips-popovers",
component: ACTooltipsPopovers,
},
{
path: "/sections/elements/avatars",
name: "el-avatars",
component: ElAvatars,
},
{
path: "/sections/elements/badges",
name: "el-badges",
component: ElBadges,
},
{
path: "/sections/elements/breadcrumbs",
name: "el-breadcrumbs",
component: ElBreadcrumbs,
},
{
path: "/sections/elements/buttons",
name: "el-buttons",
component: ElButtons,
},
{
path: "/sections/elements/button-groups",
name: "el-button-groups",
component: ElButtonGroups,
},
{
path: "/sections/elements/dropdowns",
name: "el-dropdowns",
component: ElDropdowns,
},
{
path: "/sections/elements/progress-bars",
name: "el-progress-bars",
component: ElProgressBars,
},
{
path: "/sections/elements/toggles",
name: "el-toggles",
component: ElToggles,
},
{
path: "/sections/elements/typography",
name: "el-typography",
component: ElTypography,
},
], ],
}); });

View File

@ -0,0 +1,90 @@
<script setup>
import axios from 'axios';
import { onMounted, ref, computed } from "vue";
import NavbarDefault from "../../../examples/navbars/NavbarDefault.vue";
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token'));
const userId = computed(() => sessionStorage.getItem('user_id'));
const loggedUserName = computed(() => sessionStorage.getItem('username'));
const profileData = ref([]);
const getProfile = async () => {
const profileDataRecieved = await axios.get(`http://somebodyhire.me/api/profile/${userId.value}/`);
profileData.value = processProfileData(profileDataRecieved.data);
};
const processProfileData = (data) => {
return {
...data,
name: data.name || '🤷 No Name Provided',
location: data.location || '🌍 No Location Provided',
short_intro: data.short_intro || '📝 No Short Intro Provided',
bio: data.bio || '📘 No Bio Provided',
profile_image: data.profile_image || '📷 No Image Provided',
social_github: data.social_github || '👨‍💻 No Github Provided',
social_twitter: data.social_twitter || '🐦 No Twitter Provided',
social_vk: data.social_vk || '🔵 No VK Provided',
social_youtube: data.social_youtube || '▶️ No YouTube Provided',
social_website: data.social_website || '🌐 No Website Provided',
};
};
onMounted(async() => {
await getProfile();
});
</script>
<script>
</script>
<template>
<NavbarDefault />
<div class="profile-container">
<h1>Профиль пользователя {{ loggedUserName }}</h1>
<h2>{{ profileData.username }}</h2>
<p>{{ profileData.email }}</p>
<P>Имя: {{ profileData.name }}</P>
<p>Местоположение: {{ profileData.location }}</p>
<p>Краткое описание: {{ profileData.short_intro }}</p>
<p>Биография: {{ profileData.bio }}</p>
<p>Ссылка на изображение: {{ profileData.profile_image }}</p>
<p>Ссылка на GitHub: {{ profileData.social_github }}</p>
<p>Ссылка на Twitter: {{ profileData.social_twitter }}</p>
<p>Ссылка на VK: {{ profileData.social_vk }}</p>
<p>Ссылка на YouTube: {{ profileData.social_youtube }}</p>
<p>Ссылка на сайт: {{ profileData.social_website }}</p>
</div>
</template>
<style scoped>
.profile-container {
display: flex;
flex-direction: column;
align-items: center;
width: 80%;
margin: auto;
padding: 20px;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1);
}
.profile-container img {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 20px;
}
</style>

View File

@ -0,0 +1,124 @@
<script setup>
import { onMounted, onUnmounted } from "vue";
import axios from 'axios';
import { ref } from "vue";
const searchQuery = ref('');
const searchResultProjects = ref([]);
const searchResultUsers = ref([]);
const search = async () => {
try {
const projectsResponse = await axios.get(`http://somebodyhire.me/api/search/projects/?search_query=${searchQuery.value}`);
searchResultProjects.value = projectsResponse.data;
const usersResponse = await axios.get(`http://somebodyhire.me/api/search/profiles/?search_query=${searchQuery.value}`);
searchResultUsers.value = usersResponse.data;
} catch (error) {
console.error('There was an error fetching the search results', error);
}
};
onMounted(() => {
search();
});
</script>
<template>
<div>
<h2 class="result-header">Найдено людей: {{ searchResultUsers.length}} </h2>
<div class="result-grid">
<div class="result-card" v-for="user in searchResultUsers" :key="user.id">
<h3>{{ user.username }} with id {{ user.id }}</h3>
<p>{{ user.email }}</p>
<a :href="`http://somebodyhire.me/profile/${user.id}`">Страница пользователя</a>
</div>
</div>
</div>
</template>
<style scoped>
.searchBar {
display: flex;
justify-content: center;
align-items: center;
}
.searchInput {
/* Makes the search input take up the maximum available width */
flex-grow: 1;
/* Adds some padding inside the input field */
padding: 10px;
/* Adds some margin to the right side of the input field */
margin-right: 10px;
/* Increased the font size a bit */
font-size: 16px;
}
.searchButton {
/* Adds some padding inside the button */
padding: 10px 20px;
/* Changes the font size */
font-size: 16px;
/* Changes the background color of the button */
background-color: #3d9132;
/* Changes the color of the text inside the button */
color: white;
/* Makes the border corners rounded */
border-radius: 4px;
/* Removes the default button border */
border: none;
/* Changes the cursor to a hand pointer when hovering over the button */
cursor: pointer;
}
.searchButton:hover {
/* Changes the background color of the button when hovering over it */
background-color: #25581e;
}
.result-header {
color: #fff;
background-color: #333;
padding: 10px;
text-align: center;
margin-top: 20px;
}
.result-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.result-card {
display: flex;
flex-direction: column;
background-color: rgba(255, 255, 255, 0.5);
padding: 10px;
margin: 10px;
border-radius: 10px;
width: calc(100% / 3 - 20px);
box-sizing: border-box;
}
@media screen and (max-width: 992px) {
.result-card {
width: calc(100% / 2 - 20px);
}
}
@media screen and (max-width: 600px) {
.result-card {
width: 100%;
}
}
</style>

View File

@ -0,0 +1,177 @@
<script setup>
import axios from 'axios';
import { onMounted, ref, computed } from "vue";
import NavbarDefault from "../../../examples/navbars/NavbarDefault.vue";
import { useRouter } from "vue-router";
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token'));
const userId = computed(() => sessionStorage.getItem('user_id'));
const loggedUserName = computed(() => sessionStorage.getItem('username'));
const token = computed(() => sessionStorage.getItem('access_token'));
const profileData = ref([]);
const router = useRouter();
const debugText = ref('');
const getProfile = async () => {
const profileDataRecieved = await axios.get(`http://somebodyhire.me/api/profile/${userId.value}/`);
profileData.value = processProfileData(profileDataRecieved.data);
};
const processProfileData = (data) => {
return {
...data,
name: data.name || '🤷 No Name Provided',
location: data.location || '🌍 No Location Provided',
short_intro: data.short_intro || '📝 No Short Intro Provided',
bio: data.bio || '📘 No Bio Provided',
profile_image: data.profile_image || '📷 No Image Provided',
social_github: data.social_github || '👨‍💻 No Github Provided',
social_twitter: data.social_twitter || '🐦 No Twitter Provided',
social_vk: data.social_vk || '🔵 No VK Provided',
social_youtube: data.social_youtube || '▶️ No YouTube Provided',
social_website: data.social_website || '🌐 No Website Provided',
};
};
// Axios request and response interceptors
axios.interceptors.request.use((request) => {
debugText.value += '\n\nRequest:\n' + JSON.stringify(request, null, 2);
return request;
});
axios.interceptors.response.use((response) => {
debugText.value += '\n\nResponse:\n' + JSON.stringify(response, null, 2);
return response;
}, (error) => {
debugText.value += '\n\nResponse Error:\n' + JSON.stringify(error.toJSON(), null, 2);
return Promise.reject(error);
});
const updateProfile = async () => {
try {
const token = computed(() => sessionStorage.getItem('access_token'));
debugText.value = `Type of token: ${typeof token.value}, Value of token: ${token.value}`;
const headers = { 'Authorization': `Bearer ${token.value}` };
await axios.put(`http://somebodyhire.me/api/profile/${userId.value}/`, profileData.value, { headers });
router.push('/ViewMyProfile');
} catch (error) {
debugText.value = `Error: ${JSON.stringify(error, null, 2)}`;
console.error(error);
}
};
const cancelUpdate = () => {
router.push('/ViewMyProfile');
};
onMounted(async() => {
await getProfile();
});
</script>
<script>
</script>
<template>
<NavbarDefault />
<div class="profile-container">
<h1>Профиль пользователя {{ loggedUserName }}</h1>
<textarea readonly v-model="debugText"></textarea>
<input type="text" v-model="profileData.username" placeholder="Username">
<input type="email" v-model="profileData.email" placeholder="Email">
<input type="text" v-model="profileData.name" placeholder="Имя">
<input type="text" v-model="profileData.short_intro" placeholder="Краткое описание">
<textarea v-model="profileData.bio" placeholder="Биография"></textarea>
<textarea v-model="profileData.profile_image" placeholder="Ссылка на изображение"></textarea>
<textarea v-model="profileData.social_github" placeholder="Ссылка на GitHub"></textarea>
<textarea v-model="profileData.social_twitter" placeholder="Ссылка на Twitter"></textarea>
<textarea v-model="profileData.social_vk" placeholder="Ссылка на VK"></textarea>
<textarea v-model="profileData.social_youtube" placeholder="Ссылка на YouTube"></textarea>
<textarea v-model="profileData.social_website" placeholder="Ссылка на сайт"></textarea>
<button @click="updateProfile" class="btn-submit">Submit</button>
<button @click="cancelUpdate" class="btn-cancel">Cancel</button>
</div>
</template>
<style scoped>
.profile-container {
display: flex;
flex-direction: column;
align-items: center;
width: 80%;
margin: auto;
padding: 20px;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1);
}
.profile-container img {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 20px;
}
.profile-container input, .profile-container textarea {
width: 100%; /* Make inputs and textareas take up the full width of the container */
padding: 10px; /* Add some padding */
margin-bottom: 15px; /* Add some margin */
box-sizing: border-box; /* Ensure padding doesn't affect final dimensions */
border: 1px solid #ccc; /* Add a border */
border-radius: 5px; /* Add rounded corners */
}
/* Style for smaller screens */
@media (max-width: 768px) {
.profile-container {
width: 95%;
}
}
.btn-submit {
color: #fff;
background-color: #4CAF50;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
}
.btn-cancel {
color: #fff;
background-color: #f44336;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
}
</style>

View File

@ -0,0 +1,147 @@
<script setup>
import axios from 'axios';
import { ref, computed } from "vue";
import NavbarDefault from "../../../examples/navbars/NavbarDefault.vue";
import { useRouter } from "vue-router";
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token'));
const userId = computed(() => sessionStorage.getItem('user_id'));
const loggedUserName = computed(() => sessionStorage.getItem('username'));
const token = computed(() => sessionStorage.getItem('access_token'));
const projectData = ref({
title: "",
description: "",
featured_image: "",
demo_link: null,
source_link: null,
vote_total: 0,
vote_ratio: 0,
owner: userId.value,
tags: []
});
const router = useRouter();
const debugText = ref('');
// Axios request and response interceptors
axios.interceptors.request.use((request) => {
debugText.value += '\n\nRequest:\n' + JSON.stringify(request, null, 2);
return request;
});
axios.interceptors.response.use((response) => {
debugText.value += '\n\nResponse:\n' + JSON.stringify(response, null, 2);
return response;
}, (error) => {
debugText.value += '\n\nResponse Error:\n' + JSON.stringify(error.toJSON(), null, 2);
return Promise.reject(error);
});
const createProject = async () => {
try {
const headers = { 'Authorization': `Bearer ${token.value}` };
const data = {
title: projectData.value.title,
description: projectData.value.description,
demo_link: projectData.value.demo_link,
source_link: projectData.value.source_link,
vote_total: projectData.value.vote_total,
vote_ratio: projectData.value.vote_ratio,
owner: userId.value
};
const response = await axios.post('http://somebodyhire.me/api/projects/create/', data, { headers });
router.push(`/project/${response.data.id}`);
} catch (error) {
debugText.value = `Error: ${JSON.stringify(error, null, 2)}`;
console.error(error);
}
};
const cancelCreate = () => {
router.push('/projects');
};
</script>
<template>
<NavbarDefault />
<div class="profile-container">
<h1>Create a Project for {{ loggedUserName }}</h1>
<textarea readonly v-model="debugText"></textarea>
<input type="text" v-model="projectData.title" placeholder="Title">
<input type="text" v-model="projectData.description" placeholder="Description">
<textarea v-model="projectData.featured_image" placeholder="Link to featured image"></textarea>
<textarea v-model="projectData.demo_link" placeholder="Demo link"></textarea>
<textarea v-model="projectData.source_link" placeholder="Source code link"></textarea>
<button @click="createProject" class="btn-submit">Submit</button>
<button @click="cancelCreate" class="btn-cancel">Cancel</button>
</div>
</template>
<style scoped>
.profile-container {
display: flex;
flex-direction: column;
align-items: center;
width: 80%;
margin: auto;
padding: 20px;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1);
}
.profile-container img {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 20px;
}
.profile-container input, .profile-container textarea {
width: 100%; /* Make inputs and textareas take up the full width of the container */
padding: 10px; /* Add some padding */
margin-bottom: 15px; /* Add some margin */
box-sizing: border-box; /* Ensure padding doesn't affect final dimensions */
border: 1px solid #ccc; /* Add a border */
border-radius: 5px; /* Add rounded corners */
}
/* Style for smaller screens */
@media (max-width: 768px) {
.profile-container {
width: 95%;
}
}
.btn-submit {
color: #fff;
background-color: #4CAF50;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
}
.btn-cancel {
color: #fff;
background-color: #f44336;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
}
</style>

View File

@ -0,0 +1,124 @@
<script setup>
import { onMounted, onUnmounted } from "vue";
import axios from 'axios';
import { ref } from "vue";
const searchQuery = ref('');
const searchResultProjects = ref([]);
const searchResultUsers = ref([]);
const search = async () => {
try {
const projectsResponse = await axios.get(`http://somebodyhire.me/api/search/projects/?search_query=${searchQuery.value}`);
searchResultProjects.value = projectsResponse.data;
const usersResponse = await axios.get(`http://somebodyhire.me/api/search/profiles/?search_query=${searchQuery.value}`);
searchResultUsers.value = usersResponse.data;
} catch (error) {
console.error('There was an error fetching the search results', error);
}
};
onMounted(() => {
search();
});
</script>
<template>
<div>
<h2 class="result-header">Найдено проектов: {{ searchResultProjects.length}} </h2>
<div class="result-grid">
<div class="result-card" v-for="project in searchResultProjects" :key="project.id">
<h3>{{ project.title }} with ID {{ project.id }}</h3>
<p>{{ project.description }}</p>
<a :href="`http://somebodyhire.me/project/${project.id}`">Страница проекта</a>
</div>
</div>
</div>
</template>
<style scoped>
.searchBar {
display: flex;
justify-content: center;
align-items: center;
}
.searchInput {
/* Makes the search input take up the maximum available width */
flex-grow: 1;
/* Adds some padding inside the input field */
padding: 10px;
/* Adds some margin to the right side of the input field */
margin-right: 10px;
/* Increased the font size a bit */
font-size: 16px;
}
.searchButton {
/* Adds some padding inside the button */
padding: 10px 20px;
/* Changes the font size */
font-size: 16px;
/* Changes the background color of the button */
background-color: #3d9132;
/* Changes the color of the text inside the button */
color: white;
/* Makes the border corners rounded */
border-radius: 4px;
/* Removes the default button border */
border: none;
/* Changes the cursor to a hand pointer when hovering over the button */
cursor: pointer;
}
.searchButton:hover {
/* Changes the background color of the button when hovering over it */
background-color: #25581e;
}
.result-header {
color: #fff;
background-color: #333;
padding: 10px;
text-align: center;
margin-top: 20px;
}
.result-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.result-card {
display: flex;
flex-direction: column;
background-color: rgba(255, 255, 255, 0.5);
padding: 10px;
margin: 10px;
border-radius: 10px;
width: calc(100% / 3 - 20px);
box-sizing: border-box;
}
@media screen and (max-width: 992px) {
.result-card {
width: calc(100% / 2 - 20px);
}
}
@media screen and (max-width: 600px) {
.result-card {
width: 100%;
}
}
</style>

View File

@ -0,0 +1,177 @@
<script setup>
import { onMounted } from "vue";
import { ref } from "vue";
import axios from 'axios';
import { computed } from "vue";
// example components
import DefaultNavbar from "@/examples/navbars/NavbarDefault.vue";
import Header from "@/examples/Header.vue";
// material-input
import setMaterialInput from "@/assets/js/material-input";
const username = ref('');
const password = ref('');
const email = ref(''); // Add email
const errorMessage = ref('');
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); // Computed property to check if the user is authenticated
// New register function
const register = async () => {
if (!username.value || !password.value || !email.value) {
errorMessage.value = "Please fill in all fields.";
} else {
const url = 'http://somebodyhire.me/api/register/';
const headers = {
'Content-Type': 'application/json',
};
const body = {
username: username.value,
password: password.value,
email: email.value, // include email in the request body
is_staff: false
};
try {
const response = await axios.post(url, body, { headers });
errorMessage.value = `Registration successful. Welcome ${response.data.username}!`; // Display success message
sessionStorage.setItem('access_token', response.data.token); // Save the access token in sessionStorage
} catch (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nResponse:\nStatus: ${error.response.status}\nHeaders: ${JSON.stringify(error.response.headers)}\nBody: ${JSON.stringify(error.response.data)}`;
} else if (error.request) {
// The request was made but no response was received
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nError: No response received from server. Please try again later.`;
} else {
// Something happened in setting up the request that triggered an error
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nError: ${error.message}`;
}
}
}
};
onMounted(() => {
setMaterialInput();
});
</script>
<script>
export default {
data() {
return {
username: '',
password: '',
email: '',
errorMessage: '',
};
},
methods: {
register() {
this.username = username.value;
this.password = password.value;
this.email = email.value;
register(); // Call the register function
},
},
};
</script>
<template>
<DefaultNavbar transparent />
<Header>
<div
class="page-header align-items-start min-vh-100"
:style="{
backgroundImage:
'url(https://images.unsplash.com/photo-1497294815431-9365093b7331?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1950&q=80)'
}"
loading="lazy"
>
<span class="mask bg-gradient-dark opacity-6"></span>
<div class="container my-auto">
<div class="row">
<div class="col-lg-4 col-md-8 col-12 mx-auto">
<div class="card z-index-0 fadeIn3 fadeInBottom">
<div
class="card-header p-0 position-relative mt-n4 mx-3 z-index-2"
>
<div
class="bg-gradient-success shadow-success border-radius-lg py-3 pe-1"
>
<h4
class="text-white font-weight-bolder text-center mt-2 mb-0"
>
Регистрация
</h4>
</div>
</div>
<div class="card-body">
<form role="form" class="text-start">
<div>
<div>
<!-- This will be displayed if the user is not authenticated -->
<p>Пожалуйста, зарегистрируйтесь</p>
<p>Пароль должен быть не менее 8 символов, и не быть похожим на имя пользователя или адрес почты</p>
<div>
<input v-model="username" type="text" placeholder="Имя пользователя" />
</div>
<div>
<input v-model="email" type="email" placeholder="Email" />
</div>
<div>
<input v-model="password" type="password" placeholder="Пароль" />
</div>
<div class="text-center">
<button
type="button"
class="btn bg-gradient-dark w-100 my-4 mb-2"
@click="register"
>
Зарегистрироваться
</button>
</div>
</div>
<div v-if="errorMessage">
<p>{{ errorMessage }}</p>
</div>
</div>
<p class="mt-4 text-sm text-center">
Уже есть аккаунт?
<a
href="/pages/landing-pages/basic"
class="text-success text-gradient font-weight-bold"
>Войти</a
>
</p>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</Header>
</template>

View File

@ -16,7 +16,8 @@ const password = ref('');
const errorMessage = ref(''); const errorMessage = ref('');
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); // Computed property to check if the user is authenticated const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); // Computed property to check if the user is authenticated
const userId = computed(() => sessionStorage.getItem('user_id'));
const loggedUserName = computed(() => sessionStorage.getItem('username'));
const login = async () => { const login = async () => {
if (!username.value || !password.value) { if (!username.value || !password.value) {
@ -33,28 +34,30 @@ const login = async () => {
try { try {
const response = await axios.post(url, body, { headers }); const response = await axios.post(url, body, { headers });
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nResponse:\nStatus: ${response.status}\nHeaders: ${JSON.stringify(response.headers)}\nBody: ${JSON.stringify(response.data)}`; // Removed debug information from output
sessionStorage.setItem('access_token', response.data.access); // Save the access token in sessionStorage (new line) sessionStorage.setItem('access_token', response.data.access);
sessionStorage.setItem('username', username.value); // Save username in sessionStorage
sessionStorage.setItem('user_id', response.data.id); // Save the user id in sessionStorage
location.reload(); // Refresh page
} catch (error) { } catch (error) {
if (error.response) { if (error.response) {
// The request was made and the server responded with a status code that falls out of the range of 2xx errorMessage.value = "Incorrect login or password."; // Simplified error message
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nResponse:\nStatus: ${error.response.status}\nHeaders: ${JSON.stringify(error.response.headers)}\nBody: ${JSON.stringify(error.response.data)}`;
} else if (error.request) { } else if (error.request) {
// The request was made but no response was received errorMessage.value = "No response received from server. Please try again later.";
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nError: No response received from server. Please try again later.`;
} else { } else {
// Something happened in setting up the request that triggered an error errorMessage.value = error.message;
errorMessage.value = `Request:\nPOST ${url}\nHeaders: ${JSON.stringify(headers)}\nBody: ${JSON.stringify(body)}\n\nError: ${error.message}`;
} }
} }
} }
}; };
const logout = () => { // Method to logout the user by clearing the session storage (new function) const logout = () => {
sessionStorage.removeItem('access_token'); sessionStorage.removeItem('access_token');
sessionStorage.removeItem('username'); // Also clear the username from sessionStorage
sessionStorage.removeItem('user_id');
location.reload(); // Refresh page after logout
}; };
onMounted(() => { onMounted(() => {
setMaterialInput(); setMaterialInput();
}); });
@ -117,13 +120,13 @@ export default {
<div> <div>
<div v-if="isAuthenticated"> <div v-if="isAuthenticated">
<!-- This will only be displayed if the user is authenticated --> <!-- This will only be displayed if the user is authenticated -->
<p>Опять Ты!</p> <p>Вы вошли в аккаунт {{ loggedUserName }}, ваш ID {{ userId }}</p>
<button @click="logout">Выход</button> <button @click="logout">Выход</button>
</div> </div>
<div v-else> <div v-else>
<!-- This will be displayed if the user is not authenticated --> <!-- This will be displayed if the user is not authenticated -->
<p>Ты с какого района?</p> <p>Пожалуйста, введите логин и пароль</p>
@ -160,9 +163,17 @@ export default {
<p class="mt-4 text-sm text-center"> <p class="mt-4 text-sm text-center">
Нет аккаунта? Нет аккаунта?
<a <a
href="#" href="/register"
class="text-success text-gradient font-weight-bold" class="text-success text-gradient font-weight-bold"
>Пока что нахер идите</a >Зарегистироваться</a
>
</p>
<p class="mt-4 text-sm text-center">
<a
href="/forgot"
class="text-success text-gradient font-weight-bold"
>Забыли пароль</a
> >
</p> </p>
</form> </form>

View File

@ -0,0 +1,33 @@
<!-- Шаблон для страницы, содержимое которой видно только зарегистрированным пользователям -->
<script setup>
import { computed } from "vue";
// example components
import DefaultNavbar from "@/examples/navbars/NavbarDefault.vue";
import Header from "@/examples/Header.vue";
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); // Computed property to check if the user is authenticated
</script>
<template>
<DefaultNavbar />
<Header>
<div>
<h1>Забыли пароль?</h1>
</div>
<div v-if="isAuthenticated">
<p>Как же ты зашёл тогда?</p>
</div>
<div v-else>
<p>Очень жаль</p>
</div>
</Header>
</template>

View File

@ -22,7 +22,6 @@ import DefaultFooter from "../../examples/footers/FooterDefault.vue";
import Header from "../../examples/Header.vue"; import Header from "../../examples/Header.vue";
// sections // sections
import PresentationCounter from "./Sections/PresentationCounter.vue";
import PresentationSearch from "./Sections/PresentationSearch.vue"; import PresentationSearch from "./Sections/PresentationSearch.vue";
@ -31,6 +30,8 @@ import vueMkHeader from "@/assets/img/space-background.jpg";
//authentification //authentification
const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token')); const isAuthenticated = computed(() => !!sessionStorage.getItem('access_token'));
const userId = computed(() => sessionStorage.getItem('user_id'));
const loggedUserName = computed(() => sessionStorage.getItem('username'));
//hooks //hooks
const body = document.getElementsByTagName("body")[0]; const body = document.getElementsByTagName("body")[0];
@ -46,6 +47,7 @@ onUnmounted(() => {
<script> <script>
import axios from 'axios'; import axios from 'axios';
import PresentationCounter from "./Sections/PresentationCounter.vue";
export default { export default {
data() { data() {
@ -55,12 +57,14 @@ export default {
}, },
async created() { async created() {
try { try {
const response = await axios.get('http://somebodyhire.me/api/projects/'); const response = await axios.get("http://somebodyhire.me/api/projects/");
this.projects = response.data; this.projects = response.data;
} catch (error) { }
console.error('There was an error fetching the projects', error); catch (error) {
console.error("There was an error fetching the projects", error);
} }
}, },
components: { PresentationCounter }
}; };
</script> </script>
@ -85,16 +89,23 @@ export default {
<div class="col-lg-7 text-center mx-auto position-relative"> <div class="col-lg-7 text-center mx-auto position-relative">
<h1 <h1
class="text-white pt-3 mt-n5 me-2" class="text-white pt-3 mt-n5 me-2"
:style="{ display: 'inline-block ' }" :style="{ display: 'inline-block ', fontFamily: 'PressStart2P, sans-serif' }"
> >
LinkedMin LinkedMin
</h1> </h1>
<p>
</p>
<div v-if="isAuthenticated"> <div v-if="isAuthenticated">
<h1 <h2
class="text-white pt-3 mt-n5 me-2" class="text-white pt-3 mt-n5 me-2"
:style="{ display: 'inline-block ', fontFamily: 'PressStart2P, sans-serif' }" :style="{ display: 'inline-block ', fontFamily: 'PressStart2P, sans-serif' }"
> >
Тариф Премиум</h1> Привет, {{ loggedUserName }}</h2>
</div> </div>
<div v-else> <div v-else>
@ -114,19 +125,7 @@ export default {
</div> </div>
</div> </div>
</Header> </Header>
<div class="card card-body blur shadow-blur mx-3 mx-md-4 mt-n6">
<PresentationCounter /> <PresentationCounter />
<div class="project-container">
<div class="project-card" v-for="project in projects" :key="project.id">
<h3>{{ project.title }}</h3>
<p>{{ project.description }}</p>
</div>
</div>
</div>
<DefaultFooter /> <DefaultFooter />
</template> </template>

View File

@ -3,10 +3,11 @@ import { onMounted, onUnmounted } from "vue";
import axios from 'axios'; import axios from 'axios';
import { ref } from "vue"; import { ref } from "vue";
const searchQuery = ref(''); const searchQuery = ref('');
const searchResultProjects = ref([]); const searchResultProjects = ref([]);
const searchResultUsers = ref([]); const searchResultUsers = ref([]);
const searchButtonIsPressed = ref(false);
const search = async () => { const search = async () => {
try { try {
const projectsResponse = await axios.get(`http://somebodyhire.me/api/search/projects/?search_query=${searchQuery.value}`); const projectsResponse = await axios.get(`http://somebodyhire.me/api/search/projects/?search_query=${searchQuery.value}`);
@ -14,6 +15,7 @@ const search = async () => {
const usersResponse = await axios.get(`http://somebodyhire.me/api/search/profiles/?search_query=${searchQuery.value}`); const usersResponse = await axios.get(`http://somebodyhire.me/api/search/profiles/?search_query=${searchQuery.value}`);
searchResultUsers.value = usersResponse.data; searchResultUsers.value = usersResponse.data;
searchButtonIsPressed.value = true;
} catch (error) { } catch (error) {
console.error('There was an error fetching the search results', error); console.error('There was an error fetching the search results', error);
} }
@ -27,27 +29,35 @@ const search = async () => {
<template> <template>
<div class="searchBar"> <div class="searchBar">
<input type="text" v-model="searchQuery" placeholder="Поиск по проектам и людям" /> <!-- Added @keyup.enter="search" to enable searching by pressing Enter key -->
<button type="submit" @click="search">Go</button> <!-- Added class searchInput for styling -->
<input class="searchInput" type="text" v-model="searchQuery" @keyup.enter="search" placeholder="Поиск по проектам и людям" />
<!-- Added class searchButton for styling -->
<button class="searchButton" type="submit" @click="search">Go</button>
</div> </div>
<div> <div v-if="searchResultProjects.length > 0 || searchResultUsers.length > 0">
<h2>Найдено проектов: {{ searchResultProjects.length}} </h2> <h2 class="result-header">Найдено проектов: {{ searchResultProjects.length}} </h2>
<div v-for = "project in searchResultProjects" :key="project.id"> <div class="result-grid">
<div class="result-card" v-for="project in searchResultProjects" :key="project.id">
<h3>{{ project.title }} with ID {{ project.id }}</h3> <h3>{{ project.title }} with ID {{ project.id }}</h3>
<p>{{ project.description }}</p> <p>{{ project.description }}</p>
<a :href="`http://somebodyhire.me/project/${project.id}`">Страница проекта</a> <a :href="`http://somebodyhire.me/project/${project.id}`">Страница проекта</a>
</div> </div>
<h2>Найдено людей: {{ searchResultUsers.length}} </h2> </div>
<div v-for = "user in searchResultUsers" :key="user.id"> <h2 class="result-header">Найдено людей: {{ searchResultUsers.length}} </h2>
<div class="result-grid">
<div class="result-card" v-for="user in searchResultUsers" :key="user.id">
<h3>{{ user.username }} with id {{ user.id }}</h3> <h3>{{ user.username }} with id {{ user.id }}</h3>
<p>{{ user.email }}</p> <p>{{ user.email }}</p>
<a :href="`http://somebodyhire.me/profile/${user.id}`">Страница пользователя</a> <a :href="`http://somebodyhire.me/profile/${user.id}`">Страница пользователя</a>
</div> </div>
</div>
</div>
<div v-else>
<div v-if = "searchQuery.length > 0 && searchButtonIsPressed === true" >
<h2 class="result-header">Ничего не найдено</h2>
</div>
</div> </div>
@ -58,7 +68,77 @@ const search = async () => {
.searchBar { .searchBar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
} }
.searchInput {
/* Makes the search input take up the maximum available width */
flex-grow: 1;
/* Adds some padding inside the input field */
padding: 10px;
/* Adds some margin to the right side of the input field */
margin-right: 10px;
/* Increased the font size a bit */
font-size: 16px;
}
.searchButton {
/* Adds some padding inside the button */
padding: 10px 20px;
/* Changes the font size */
font-size: 16px;
/* Changes the background color of the button */
background-color: #3d9132;
/* Changes the color of the text inside the button */
color: white;
/* Makes the border corners rounded */
border-radius: 4px;
/* Removes the default button border */
border: none;
/* Changes the cursor to a hand pointer when hovering over the button */
cursor: pointer;
}
.searchButton:hover {
/* Changes the background color of the button when hovering over it */
background-color: #25581e;
}
.result-header {
color: #fff;
background-color: #333;
padding: 10px;
text-align: center;
margin-top: 20px;
}
.result-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.result-card {
display: flex;
flex-direction: column;
background-color: rgba(255, 255, 255, 0.5);
padding: 10px;
margin: 10px;
border-radius: 10px;
width: calc(100% / 3 - 20px);
box-sizing: border-box;
}
@media screen and (max-width: 992px) {
.result-card {
width: calc(100% / 2 - 20px);
}
}
@media screen and (max-width: 600px) {
.result-card {
width: 100%;
}
}
</style> </style>