all repos — stealth-developers @ ec1288b7069276a5ae7a7d415a9e456e7e9d3364

frontend/src/App.vue (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
<script setup lang="ts">
import { RouterView, RouterLink } from 'vue-router'

import { useAuthStore } from './stores/auth'
import { computed, onMounted } from 'vue'
import { avatar } from './utils/discord'

const authStore = useAuthStore()

const user = computed(() => authStore.user)

onMounted(async () => {
	await authStore.getUser()
})
</script>

<template>
	<div class="layout">
		<aside class="sidebar">
			<div class="links">
				<RouterLink to="/">Home</RouterLink>
				<RouterLink to="/tickets">Tickets</RouterLink>
			</div>

			<div class="user" v-if="user">
				<div class="profile-picture">
					<img :src="avatar(user)" alt="Profile Picture" />
				</div>
				<div class="username">{{ user.nick || user.user.global_name || user.user.username }}</div>
			</div>
		</aside>
		<main class="main">
			<RouterView v-slot="{ Component }">
				<KeepAlive include="TicketsView">
					<component :is="Component" />
				</KeepAlive>
			</RouterView>
		</main>
	</div>
</template>

<style scoped>
.layout {
	display: flex;
	flex-direction: row;
	align-items: stretch;
	justify-content: flex-start;

	height: 100vh;
	padding: 0.5rem;
	gap: 0.5rem;

	aside.sidebar {
		flex: 0 0 auto;
		width: 200px;

		display: flex;
		flex-direction: column;
		align-items: stretch;
		justify-content: space-between;
		gap: 0.5rem;

		.links {
			display: flex;
			flex-direction: column;
			align-items: stretch;
			gap: 0.5rem;

			a {
				padding: 0.5rem 1rem;
				border-radius: 5rem;
				background-color: hsla(var(--mantle));
				text-decoration: none;
				color: hsla(var(--subtext1));
				font-weight: 550;

				&:hover {
					background-color: hsla(var(--surface1));
				}
				&:active {
					filter: brightness(0.75);
				}

				&.router-link-active {
					background-color: hsla(var(--accent));
					color: hsla(var(--on-accent));
				}
			}
		}

		.user {
			display: flex;
			flex-direction: row;
			align-items: center;
			padding: 0.5rem;
			border-radius: 2rem;
			background-color: hsla(var(--mantle));
			gap: 0.5rem;
			font-weight: 550;

			.profile-picture {
				flex: 0 0 auto;
				width: 40px;
				height: 40px;
				border-radius: 50%;

				img {
					width: 100%;
					height: 100%;
					object-fit: cover;
					border-radius: 50%;
				}
			}
		}
	}

	main {
		flex: 1;
		background-color: hsla(var(--mantle));
		border-radius: 2rem;
		height: 100%;
		overflow-y: auto;
	}
}
</style>