Намутил фронтенда

This commit is contained in:
p.belezov 2024-06-26 11:24:48 +08:00
parent 07c26791b7
commit 4eb5d8d5b8
8 changed files with 368 additions and 33 deletions

15
package-lock.json generated
View File

@ -10,6 +10,7 @@
"pinia": "^2.1.7", "pinia": "^2.1.7",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vue": "^3.4.14", "vue": "^3.4.14",
"vue-router": "^4.4.0",
"vuetify": "^3.4.10" "vuetify": "^3.4.10"
}, },
"devDependencies": { "devDependencies": {
@ -1196,6 +1197,20 @@
} }
} }
}, },
"node_modules/vue-router": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.0.tgz",
"integrity": "sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==",
"dependencies": {
"@vue/devtools-api": "^6.5.1"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/vuetify": { "node_modules/vuetify": {
"version": "3.6.1", "version": "3.6.1",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.6.1.tgz", "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.6.1.tgz",

View File

@ -17,6 +17,7 @@
"pinia": "^2.1.7", "pinia": "^2.1.7",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vue": "^3.4.14", "vue": "^3.4.14",
"vue-router": "^4.4.0",
"vuetify": "^3.4.10" "vuetify": "^3.4.10"
} }
} }

View File

@ -1,52 +1,87 @@
<template> <template>
<v-app> <v-app>
<v-sheet class="bg-gradient justify-center d-flex flex-column" style="height: 100%"> <v-sheet class="bg-gradient justify-center d-flex flex-column" style="height: 100%">
<v-sheet class="rounded-lg main-bg h-auto mt-10 mr-10 ml-10 mb-3 pa-5"> <div v-if="!isWide" class="d-flex justify-end mr-10 mt-3">
<p class="text-h3">Меню</p> <v-btn
class="bg-grey-darken-3 d-flex justify-center"
size="large"
density="compact"
rounded="xl"
@click="openMenu"
icon
>
<v-icon>
<svg class="ham hamRotate ham1" viewBox="0 0 100 100" onclick="this.classList.toggle('active')">
<path
class="line top"
d="m 30,33 h 40 c 0,0 9.044436,-0.654587 9.044436,-8.508902 0,-7.854315 -8.024349,-11.958003 -14.89975,-10.85914 -6.875401,1.098863 -13.637059,4.171617 -13.637059,16.368042 v 40" />
<path
class="line middle"
d="m 30,50 h 40" />
<path
class="line bottom"
d="m 30,67 h 40 c 12.796276,0 15.357889,-11.717785 15.357889,-26.851538 0,-15.133752 -4.786586,-27.274118 -16.667516,-27.274118 -11.88093,0 -18.499247,6.994427 -18.435284,17.125656 l 0.252538,40" />
</svg>
</v-icon>
</v-btn>
</div>
<v-sheet
v-if="isWide || menuOpen"
class="d-flex justify-end rounded-lg main-bg h-auto mr-10 ml-10"
:class="menuOpen ? 'mt-2 mb-2 pa-2' : 'mt-10 mb-3 pa-5'"
>
<p class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/" class="nav-link text-decoration-none">Главная</RouterLink></p>
<p class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/login" class="nav-link text-decoration-none">Войти</RouterLink></p>
<p class="ml-3 mr-3" :class="menuOpen ? 'text-body-1' : 'text-h6'"><RouterLink to="/register" class="nav-link text-decoration-none">Регистрация</RouterLink></p>
</v-sheet> </v-sheet>
<v-sheet class="rounded-lg main-bg h-100 mt-3 mr-10 ml-10 mb-10 pa-5"> <v-sheet class="rounded-lg main-bg h-100 mt-3 mr-10 ml-10 mb-10 pa-5">
<Login></Login> <RouterView v-slot="{ Component }">
<Component
:is="Component"
:is-wide="isWide"
/>
</RouterView>
</v-sheet> </v-sheet>
</v-sheet> </v-sheet>
</v-app> </v-app>
</template> </template>
<script> <script>
import Login from "./views/Login.vue"; import {th} from "vuetify/locale";
export default { export default {
name: "App", name: "App",
components: {Login} data: () => ({
windowHeight: document.documentElement.clientHeight,
windowWidth: document.documentElement.clientWidth,
isWide: window.innerWidth >= 460,
menuOpen: false
}),
methods: {
resizeEventHandler(e) {
this.windowHeight = document.documentElement.clientHeight;
this.windowWidth = document.documentElement.clientWidth;
this.isWide = this.windowWidth >= 460;
if (this.isWide){
this.menuOpen = false;
}
},
openMenu(){
this.menuOpen = !this.menuOpen;
}
},
created() {
window.addEventListener("resize", this.resizeEventHandler);
},
mounted() {
this.resizeEventHandler();
window.addEventListener("resize", this.resizeEventHandler, { passive: true });
}
} }
</script> </script>
<style scoped> <style scoped>
.main-bg {
background-color: #424242;
color: #e0e0e0;
text-decoration-color: #e0e0e0;
}
.bg-gradient {
background: linear-gradient(-45deg, #f103b0, #f0a068, #4fdbfeff);
background-size: 200% 200%;
animation: gradient 15s ease infinite;
height: 200vh;
}
@keyframes gradient {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
</style> </style>

View File

@ -6,10 +6,25 @@ import 'vuetify/styles'
import * as components from 'vuetify/components' import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives' import * as directives from 'vuetify/directives'
import '@mdi/font/css/materialdesignicons.css' import '@mdi/font/css/materialdesignicons.css'
import Login from "./views/Login.vue";
import About from "./views/About.vue";
import Register from "./views/Register.vue";
import {createMemoryHistory, createRouter} from "vue-router";
const routes = [
{path: '/', component: About, props: true},
{path: '/login', component: Login, props: true},
{path: '/register', component: Register, props: true}
]
const router = createRouter({
history: createMemoryHistory(),
routes,
})
const vuetify = createVuetify({ const vuetify = createVuetify({
components, components,
directives directives
}) })
createApp(App).use(vuetify).mount("#app") createApp(App).use(vuetify).use(router).mount("#app")

View File

@ -0,0 +1,209 @@
.main-bg {
background-color: #424242!important;
color: #e0e0e0!important;
text-decoration-color: #e0e0e0!important;
}
.bg-gradient {
background: linear-gradient(-45deg, #f103b0, #f0a068, #4fdbfeff)!important;
background-size: 200% 200%!important;
animation: gradient 15s ease infinite!important;
height: 100vh!important;
}
@keyframes gradient {
0% {
background-position: 0 50%!important;
}
50% {
background-position: 100% 50%!important;
}
100% {
background-position: 0 50%!important;
}
}
.nav-link:link {
color: #4FDBFEFF!important;
}
.nav-link:visited {
color: #F0A068FF!important;
}
.nav-link:hover {
color: #F103B0FF!important;
}
.nav-link:active {
color: #F103B0FF!important;
}
.link-no-color:link {
color: #000000 !important;
}
.link-no-color:visited {
color: #000000 !important;
}
.link-no-color:hover {
color: #000000 !important;
}
.link-no-color:active {
color: #000000 !important;
}
.ham {
cursor: pointer;
-webkit-tap-highlight-color: transparent;
transition: transform 400ms;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.hamRotate.active {
transform: rotate(45deg);
}
.hamRotate180.active {
transform: rotate(180deg);
}
.line {
fill:none;
transition: stroke-dasharray 400ms, stroke-dashoffset 400ms;
stroke: #ffffff;
stroke-width:5.5;
stroke-linecap:round;
}
.ham1 .top {
stroke-dasharray: 40 139;
}
.ham1 .bottom {
stroke-dasharray: 40 180;
}
.ham1.active .top {
stroke-dashoffset: -98px;
}
.ham1.active .bottom {
stroke-dashoffset: -138px;
}
.ham2 .top {
stroke-dasharray: 40 121;
}
.ham2 .bottom {
stroke-dasharray: 40 121;
}
.ham2.active .top {
stroke-dashoffset: -102px;
}
.ham2.active .bottom {
stroke-dashoffset: -102px;
}
.ham3 .top {
stroke-dasharray: 40 130;
}
.ham3 .middle {
stroke-dasharray: 40 140;
}
.ham3 .bottom {
stroke-dasharray: 40 205;
}
.ham3.active .top {
stroke-dasharray: 75 130;
stroke-dashoffset: -63px;
}
.ham3.active .middle {
stroke-dashoffset: -102px;
}
.ham3.active .bottom {
stroke-dasharray: 110 205;
stroke-dashoffset: -86px;
}
.ham4 .top {
stroke-dasharray: 40 121;
}
.ham4 .bottom {
stroke-dasharray: 40 121;
}
.ham4.active .top {
stroke-dashoffset: -68px;
}
.ham4.active .bottom {
stroke-dashoffset: -68px;
}
.ham5 .top {
stroke-dasharray: 40 82;
}
.ham5 .bottom {
stroke-dasharray: 40 82;
}
.ham5.active .top {
stroke-dasharray: 14 82;
stroke-dashoffset: -72px;
}
.ham5.active .bottom {
stroke-dasharray: 14 82;
stroke-dashoffset: -72px;
}
.ham6 .top {
stroke-dasharray: 40 172;
}
.ham6 .middle {
stroke-dasharray: 40 111;
}
.ham6 .bottom {
stroke-dasharray: 40 172;
}
.ham6.active .top {
stroke-dashoffset: -132px;
}
.ham6.active .middle {
stroke-dashoffset: -71px;
}
.ham6.active .bottom {
stroke-dashoffset: -132px;
}
.ham7 .top {
stroke-dasharray: 40 82;
}
.ham7 .middle {
stroke-dasharray: 40 111;
}
.ham7 .bottom {
stroke-dasharray: 40 161;
}
.ham7.active .top {
stroke-dasharray: 17 82;
stroke-dashoffset: -62px;
}
.ham7.active .middle {
stroke-dashoffset: 23px;
}
.ham7.active .bottom {
stroke-dashoffset: -83px;
}
.ham8 .top {
stroke-dasharray: 40 160;
}
.ham8 .middle {
stroke-dasharray: 40 142;
transform-origin: 50%;
transition: transform 400ms;
}
.ham8 .bottom {
stroke-dasharray: 40 85;
transform-origin: 50%;
transition: transform 400ms, stroke-dashoffset 400ms;
}
.ham8.active .top {
stroke-dashoffset: -64px;
}
.ham8.active .middle {
//stroke-dashoffset: -20px;
transform: rotate(90deg);
}
.ham8.active .bottom {
stroke-dashoffset: -64px;
}

13
resources/views/About.vue Normal file
View File

@ -0,0 +1,13 @@
<script>
export default {
name: "About"
}
</script>
<template>
<v-label class="text-h3">Hello World!</v-label>
</template>
<style scoped>
</style>

View File

@ -1,10 +1,26 @@
<template> <template>
<p class="text-h1">Hello world!</p> <div class="w-100 h-100 d-flex justify-center">
<div class="d-flex flex-column justify-center h-100" :class="isWide ? 'w-50' : 'w-75'">
<v-label>Логин:</v-label>
<v-text-field label="Логин" class="flex-grow-0"></v-text-field>
<v-label>Пароль:</v-label>
<v-text-field label="Пароль" class="flex-grow-0"></v-text-field>
<div class="d-flex justify-center" :class="isWide ? '' : 'flex-column align-center'">
<v-btn color="#F0A068FF" class="ma-5" :class="isWide ? 'w-25' : 'w-100 text-body-1'">Войти</v-btn>
<router-link to="/register" class="text-decoration-none link-no-color ma-5" :class="isWide ? 'w-25' : 'w-100'">
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Регистрация</v-btn>
</router-link>
</div>
</div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "Login" name: "Login",
props: {
isWide: Boolean
}
} }
</script> </script>

View File

@ -0,0 +1,31 @@
<script>
export default {
name: "Register",
props: {
isWide: Boolean
}
}
</script>
<template>
<div class="w-100 h-100 d-flex justify-center">
<div class="d-flex flex-column justify-center h-100" :class="isWide ? 'w-50' : 'w-75'">
<v-label>Логин:</v-label>
<v-text-field label="Логин" class="flex-grow-0"></v-text-field>
<v-label>E-mail:</v-label>
<v-text-field label="E-mail" class="flex-grow-0"></v-text-field>
<v-label>Пароль:</v-label>
<v-text-field label="Пароль" class="flex-grow-0"></v-text-field>
<div class="d-flex justify-center" :class="isWide ? '' : 'flex-column align-center'">
<v-btn color="#F0A068FF" class="ma-5" :class="isWide ? 'w-25' : 'w-100 text-body-1'">Зарегистрироваться</v-btn>
<router-link to="/login" class="text-decoration-none link-no-color ma-5" :class="isWide ? 'w-25' : 'w-100'">
<v-btn color="#F0A068FF" :class="isWide ? 'w-100' : 'w-100 text-body-1'">Вход</v-btn>
</router-link>
</div>
</div>
</div>
</template>
<style scoped>
</style>