Extracted Header component from main App view
This commit is contained in:
parent
703b12428b
commit
ac327e2d4c
4 changed files with 152 additions and 32 deletions
frontend/src
|
@ -1,25 +1,6 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<header v-if="user">
|
||||
<div class="wrapper">
|
||||
<nav>
|
||||
<li class="main">
|
||||
<RouterLink to="/">
|
||||
<font-awesome-icon icon="map-marker-alt" /> GPSTracker
|
||||
</RouterLink>
|
||||
</li>
|
||||
|
||||
<div class="spacer" />
|
||||
|
||||
<li class="right">
|
||||
<RouterLink to="/logout">
|
||||
<font-awesome-icon icon="sign-out-alt" />
|
||||
<span class="logout-text">Logout</span>
|
||||
</RouterLink>
|
||||
</li>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<Header :user="user" />
|
||||
|
||||
<div class="body">
|
||||
<Loading v-if="loading" />
|
||||
|
@ -35,13 +16,19 @@ import { RouterLink, RouterView } from 'vue-router'
|
|||
|
||||
import { type Optional } from './models/Types';
|
||||
import Api from './mixins/Api.vue';
|
||||
import Dropdowns from './mixins/Dropdowns.vue';
|
||||
import Header from './components/Header.vue';
|
||||
import Loading from './elements/Loading.vue';
|
||||
import Messages from './components/Messages.vue'
|
||||
import User from './models/User';
|
||||
|
||||
export default {
|
||||
mixins: [Api],
|
||||
mixins: [
|
||||
Api,
|
||||
Dropdowns,
|
||||
],
|
||||
components: {
|
||||
Header,
|
||||
Loading,
|
||||
Messages,
|
||||
RouterLink,
|
||||
|
@ -57,6 +44,7 @@ export default {
|
|||
|
||||
async mounted() {
|
||||
this.loading = true
|
||||
this.installDropdownHandler()
|
||||
|
||||
try {
|
||||
const auth = await this.fetchUser()
|
||||
|
@ -93,8 +81,6 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
@use "@/styles/common.scss" as *;
|
||||
|
||||
$header-height: 3rem;
|
||||
|
||||
.app-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
|
132
frontend/src/components/Header.vue
Normal file
132
frontend/src/components/Header.vue
Normal file
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<header v-if="user">
|
||||
<div class="wrapper">
|
||||
<nav>
|
||||
<li class="main">
|
||||
<RouterLink :to="{ name: 'home', hash: $route.hash }">
|
||||
<font-awesome-icon icon="map-marker-alt" /> GPSTracker
|
||||
</RouterLink>
|
||||
</li>
|
||||
|
||||
<div class="spacer" />
|
||||
|
||||
<li class="right">
|
||||
<Dropdown>
|
||||
<template #button>
|
||||
<button class="options" title="Options">
|
||||
<font-awesome-icon icon="user" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<DropdownItem>
|
||||
<RouterLink to="/devices">
|
||||
<font-awesome-icon icon="mobile-alt" />
|
||||
<span class="item-text">Devices</span>
|
||||
</RouterLink>
|
||||
</DropdownItem>
|
||||
|
||||
<DropdownItem>
|
||||
<RouterLink to="/logout">
|
||||
<font-awesome-icon icon="sign-out-alt" />
|
||||
<span class="item-text">Logout</span>
|
||||
</RouterLink>
|
||||
</DropdownItem>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import { type Optional } from '../models/Types';
|
||||
import Dropdown from './Dropdown.vue';
|
||||
import DropdownItem from './DropdownItem.vue';
|
||||
import User from '../models/User';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
RouterLink,
|
||||
},
|
||||
|
||||
props: {
|
||||
user: {
|
||||
type: Object as () => Optional<User>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@/styles/common.scss" as *;
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
height: $header-height;
|
||||
margin-bottom: 0.2rem;
|
||||
padding: 0.5rem 0;
|
||||
box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, 0.5);
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
&.main {
|
||||
font-size: 1.25rem;
|
||||
margin-left: 0.5rem;
|
||||
|
||||
:deep(a) {
|
||||
&:hover {
|
||||
background: none;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
margin-top: -0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.main) {
|
||||
:deep(a) {
|
||||
color: var(--color-text);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.logout-text {
|
||||
@include mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.25rem;
|
||||
margin-right: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -440,15 +440,6 @@ main {
|
|||
box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
@keyframes unroll {
|
||||
from {
|
||||
transform: translateY(7.5em);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ol-viewport) {
|
||||
.ol-attribution {
|
||||
position: absolute !important;
|
||||
|
|
|
@ -4,6 +4,8 @@ $screen-sm: 768px;
|
|||
$screen-md: 992px;
|
||||
$screen-lg: 1200px;
|
||||
|
||||
$header-height: 3.5rem;
|
||||
|
||||
// @media utilities for common screen sizes
|
||||
@mixin mobile {
|
||||
@media (max-width: $screen-sm) {
|
||||
|
@ -112,3 +114,12 @@ button {
|
|||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes unroll {
|
||||
from {
|
||||
transform: translateY(7.5em);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue