generated from alphane/template
Compare commits
2 Commits
02ef729bf4
...
b7b473d079
| Author | SHA1 | Date | |
|---|---|---|---|
| b7b473d079 | |||
| 1af13091e6 |
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="logo">
|
||||
<RouterLink
|
||||
:to="to"
|
||||
class="d-flex"
|
||||
>
|
||||
<div class="d-flex align-center mt-1 ml-3 terminal-prompt">
|
||||
<span class="term-green">caleb</span>
|
||||
<span class="term-cyan">@</span>
|
||||
<span class="term-green mr-2">burke</span>
|
||||
<span class="term-white">~</span>
|
||||
<span class="term-cyan mr-2">$</span>
|
||||
<span class="term-white">{{ typedText }}</span>
|
||||
<span class="term-cursor">█</span>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from "vue"
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
to?: string
|
||||
animated?: boolean
|
||||
}>(),
|
||||
{
|
||||
to: "/dashboard",
|
||||
animated: false,
|
||||
}
|
||||
)
|
||||
|
||||
const TYPED_PHRASES = [
|
||||
" Hello!",
|
||||
" привет",
|
||||
" クリア",
|
||||
" Εβίβα!",
|
||||
" 干杯",
|
||||
" Будьмо!",
|
||||
" Na zdraví!",
|
||||
" 乾杯!",
|
||||
]
|
||||
const TYPE_DELAY_MS = 150
|
||||
const DELETE_DELAY_MS = 100
|
||||
const PAUSE_AFTER_TYPED_MS = 1500
|
||||
const INITIAL_DELAY_MS = 800
|
||||
|
||||
const typedText = ref("")
|
||||
let currentPhrase = ""
|
||||
let typingTimeoutId: ReturnType<typeof setTimeout>
|
||||
|
||||
function pickRandomPhrase() {
|
||||
return TYPED_PHRASES[Math.floor(Math.random() * TYPED_PHRASES.length)]
|
||||
}
|
||||
|
||||
function typeCharacter(index: number) {
|
||||
typedText.value = currentPhrase.slice(0, index)
|
||||
|
||||
if (index < currentPhrase.length) {
|
||||
typingTimeoutId = setTimeout(() => typeCharacter(index + 1), TYPE_DELAY_MS)
|
||||
} else {
|
||||
typingTimeoutId = setTimeout(() => deleteCharacter(index), PAUSE_AFTER_TYPED_MS)
|
||||
}
|
||||
}
|
||||
|
||||
function deleteCharacter(index: number) {
|
||||
typedText.value = currentPhrase.slice(0, index)
|
||||
|
||||
if (index > 0) {
|
||||
typingTimeoutId = setTimeout(() => deleteCharacter(index - 1), DELETE_DELAY_MS)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!props.animated) return
|
||||
|
||||
currentPhrase = pickRandomPhrase()
|
||||
typingTimeoutId = setTimeout(() => typeCharacter(0), INITIAL_DELAY_MS)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
clearTimeout(typingTimeoutId)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.logo a {
|
||||
text-decoration: none !important;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.terminal-prompt {
|
||||
font-family: ui-monospace, Menlo, Monaco, Consolas, "Ubuntu Mono", "DejaVu Sans Mono", monospace;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.terminal-prompt .term-green {
|
||||
color: #4e9a06;
|
||||
}
|
||||
|
||||
.terminal-prompt .term-cyan {
|
||||
color: #06989a;
|
||||
}
|
||||
|
||||
.terminal-prompt .term-white {
|
||||
color: #d3d7cf;
|
||||
}
|
||||
|
||||
/* .terminal-prompt .term-cursor {
|
||||
color: #d3d7cf;
|
||||
animation: term-blink 1s step-end infinite;
|
||||
} */
|
||||
|
||||
@keyframes term-blink {
|
||||
0%,
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
50.01%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,32 +1,66 @@
|
||||
<template>
|
||||
<v-app-bar
|
||||
id="top"
|
||||
elevation="6"
|
||||
height="60"
|
||||
class="main-head pl-2"
|
||||
>
|
||||
<div class="mr-3">
|
||||
<AppLogo />
|
||||
</div>
|
||||
|
||||
<v-tabs
|
||||
class="ml-2"
|
||||
color="primary"
|
||||
<div v-if="mobile">
|
||||
<v-app-bar
|
||||
id="top"
|
||||
elevation="6"
|
||||
height="60"
|
||||
extension-height="48"
|
||||
class="main-head pl-2"
|
||||
>
|
||||
<v-tab
|
||||
:to="{ name: 'DashboardPage' }"
|
||||
text="Dashboard"
|
||||
/>
|
||||
<v-tab
|
||||
:to="{ name: 'FlashcardsPage' }"
|
||||
text="Flashcards"
|
||||
/>
|
||||
</v-tabs>
|
||||
<div class="mr-3">
|
||||
<AppLogo />
|
||||
</div>
|
||||
|
||||
<v-spacer />
|
||||
<v-spacer />
|
||||
|
||||
<!-- TODO Add notifications -->
|
||||
<!-- <v-btn
|
||||
<ProfileMenu />
|
||||
|
||||
<template #extension>
|
||||
<v-tabs
|
||||
class="ml-2"
|
||||
color="primary"
|
||||
>
|
||||
<v-tab
|
||||
:to="{ name: 'DashboardPage' }"
|
||||
text="Dashboard"
|
||||
/>
|
||||
<v-tab
|
||||
:to="{ name: 'FlashcardsPage' }"
|
||||
text="Flashcards"
|
||||
/>
|
||||
</v-tabs>
|
||||
</template>
|
||||
</v-app-bar>
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-app-bar
|
||||
id="top"
|
||||
elevation="6"
|
||||
height="60"
|
||||
class="main-head pl-2"
|
||||
>
|
||||
<div class="mr-3">
|
||||
<AppLogo />
|
||||
</div>
|
||||
|
||||
<v-tabs
|
||||
class="ml-2"
|
||||
color="primary"
|
||||
>
|
||||
<v-tab
|
||||
:to="{ name: 'DashboardPage' }"
|
||||
text="Dashboard"
|
||||
/>
|
||||
<v-tab
|
||||
:to="{ name: 'FlashcardsPage' }"
|
||||
text="Flashcards"
|
||||
/>
|
||||
</v-tabs>
|
||||
|
||||
<v-spacer />
|
||||
|
||||
<!-- TODO Add notifications -->
|
||||
<!-- <v-btn
|
||||
icon
|
||||
class="mr-1"
|
||||
>
|
||||
@@ -42,11 +76,16 @@
|
||||
</v-badge>
|
||||
</v-btn> -->
|
||||
|
||||
<ProfileMenu />
|
||||
</v-app-bar>
|
||||
<ProfileMenu />
|
||||
</v-app-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDisplay } from "vuetify"
|
||||
|
||||
import AppLogo from "@/components/common/AppLogo.vue"
|
||||
import ProfileMenu from "@/components/layout/ProfileMenu.vue"
|
||||
|
||||
const { mobile } = useDisplay()
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<v-app-bar
|
||||
id="top"
|
||||
elevation="6"
|
||||
height="60"
|
||||
class="main-head pl-2"
|
||||
>
|
||||
<div class="mr-3">
|
||||
<PublicAppLogo
|
||||
to="/"
|
||||
:animated="isHomePage"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<v-spacer />
|
||||
</v-app-bar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
|
||||
import PublicAppLogo from "@/components/common/PublicAppLogo.vue"
|
||||
|
||||
const route = useRoute()
|
||||
const isHomePage = computed(() => route.name === "HomePage")
|
||||
</script>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<PublicAppBar />
|
||||
|
||||
<v-main>
|
||||
<v-container
|
||||
fluid
|
||||
:class="mobile ? 'pa-2' : 'pa-4'"
|
||||
>
|
||||
<router-view />
|
||||
</v-container>
|
||||
</v-main>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDisplay } from "vuetify"
|
||||
|
||||
import PublicAppBar from "@/components/layout/PublicAppBar.vue"
|
||||
|
||||
const { mobile } = useDisplay()
|
||||
</script>
|
||||
@@ -1,50 +0,0 @@
|
||||
<template>
|
||||
<div class="logo">
|
||||
<RouterLink
|
||||
to="/dashboard"
|
||||
class="d-flex"
|
||||
>
|
||||
<img
|
||||
class="ml-0 mt-1"
|
||||
style="height: 36px; transform: rotate(-12deg)"
|
||||
:src="AppLogoSmall"
|
||||
/>
|
||||
<div v-if="sidebarMini || mdAndDown"></div>
|
||||
<div
|
||||
v-else
|
||||
class="d-flex"
|
||||
style="width: 200px"
|
||||
>
|
||||
<div
|
||||
class="mt-1 ml-3"
|
||||
style="font-size: 26px; color: #505682"
|
||||
>
|
||||
CALEB BURKE DEV
|
||||
</div>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AppLogoSmall from "@/assets/app_logo_small.png"
|
||||
|
||||
import { useDisplay } from "vuetify"
|
||||
import useInterface from "@/use/use-interface"
|
||||
import { watch } from "vue"
|
||||
|
||||
const { sidebarMini, setSidebarMini } = useInterface()
|
||||
const { mdAndDown } = useDisplay()
|
||||
|
||||
watch(mdAndDown, (newVal) => {
|
||||
if (newVal === true) setSidebarMini(false)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.logo a {
|
||||
text-decoration: none !important;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
<template><div>HOME PAGE</div></template>
|
||||
@@ -4,10 +4,23 @@ import { authGuard } from "@auth0/auth0-vue"
|
||||
import { APPLICATION_NAME } from "@/config"
|
||||
import administrationRoutes from "@/routes/administration-routes"
|
||||
import { authorizationGuard } from "@/utils/authorization-guards"
|
||||
import publicRoutes from "@/routes/public-routes"
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/",
|
||||
component: () => import("@/layouts/PublicLayout.vue"),
|
||||
meta: { requiresAuth: false },
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "HomePage",
|
||||
component: () => import("@/pages/HomePage.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/sign-in",
|
||||
name: "SignInPage",
|
||||
component: () => import("@/pages/SignInPage.vue"),
|
||||
meta: { requiresAuth: false },
|
||||
@@ -82,6 +95,7 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
...publicRoutes,
|
||||
...administrationRoutes,
|
||||
{
|
||||
name: "StatusPage",
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { RouteRecordRaw } from "vue-router"
|
||||
|
||||
export const publicRoutes: Readonly<RouteRecordRaw[]> = [
|
||||
{
|
||||
path: "/public",
|
||||
component: () => import("@/layouts/PublicLayout.vue"),
|
||||
meta: { requiresAuth: false },
|
||||
children: [],
|
||||
},
|
||||
]
|
||||
|
||||
export default publicRoutes
|
||||
Reference in New Issue
Block a user