Added navbar on public pages
This commit is contained in:
@@ -42,21 +42,13 @@
|
||||
|
||||
/* Normal link */
|
||||
p a:not([class]) {
|
||||
color: var(--color-sky-600);
|
||||
color: var(--color-primary);
|
||||
text-underline-offset: .25rem;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-sky-500);
|
||||
color: var(--color-accent);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@variant dark {
|
||||
color: var(--color-teal-500);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-teal-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
|
||||
39
app/components/global/Navbar.vue
Normal file
39
app/components/global/Navbar.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<header role="banner" class="sticky top-0 border-b-1 border-border py-4 px-2 z-50 backdrop-blur">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="md:flex-1 flex justify-start" />
|
||||
|
||||
<nav class="md:flex-1">
|
||||
<menu class="text-sm flex items-center justify-center gap-4">
|
||||
<li>
|
||||
<NuxtLink to="/" class="block p-1 font-medium text-foreground/70 hover:text-foreground transition-colors" active-class="text-primary">
|
||||
{{ $t('breadcrumbs.home') }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/explore" class="block p-1 font-medium text-foreground/70 hover:text-foreground transition-colors" active-class="text-primary">
|
||||
{{ $t('pages.explore.menuLabel') }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/about" class="block p-1 font-medium text-foreground/70 hover:text-foreground transition-colors" active-class="text-primary">
|
||||
{{ $t('pages.about.menuLabel') }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</menu>
|
||||
</nav>
|
||||
|
||||
<div class="md:flex-1 flex justify-end">
|
||||
<UserDashboardLink size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
header {
|
||||
background-color: color-mix(in srgb, var(--color-background) 75%, transparent);
|
||||
}
|
||||
</style>
|
||||
@@ -40,7 +40,7 @@ const breakpoints = useBreakpoints(
|
||||
<nav
|
||||
ref="sidebarRef"
|
||||
:class="cn(
|
||||
['md:relative md:isolate w-16 py-6 grid gap-4 grid-rows-[1fr_auto] justify-center md:transition-colors'], // Base appearance
|
||||
['md:relative md:isolate w-16 py-6 grid gap-4 grid-rows-[1fr_auto] bg-background justify-center md:transition-colors'], // Base appearance
|
||||
['after:opacity-50 after:contrast-125 dark:after:opacity-75'], // After styling
|
||||
['border-r-[1px] border-r-border dark:border-r-border'], // Colours
|
||||
['max-md:justify-stretch max-md:px-4 max-md:py-4 max-md:absolute max-md:left-0 max-md:inset-0 max-md:z-50 max-md:w-40 max-md:max-w-full max-md:transition-all'], // Responsive behaviours
|
||||
|
||||
45
app/components/global/user/DashboardLink.vue
Normal file
45
app/components/global/user/DashboardLink.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script lang="ts" setup>
|
||||
import type { PrimitiveProps } from 'radix-vue'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
|
||||
const { auth } = useSupabaseClient()
|
||||
const user = useSupabaseUser()
|
||||
const profileUrl: string = `${useRequestURL().origin}/my/`
|
||||
|
||||
interface Props extends PrimitiveProps {
|
||||
size?: ButtonVariants["size"]
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
|
||||
async function handleGoogleLogin() {
|
||||
const { error } = await auth.signInWithOAuth({
|
||||
provider: "google",
|
||||
options: {
|
||||
queryParams: {
|
||||
access_type: "offline",
|
||||
prompt: "consent"
|
||||
},
|
||||
redirectTo: profileUrl
|
||||
}
|
||||
})
|
||||
|
||||
if (error) {
|
||||
console.log(error.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TransitionGroup name="fade-group" appear>
|
||||
<UiButton v-if="user" as-child :size>
|
||||
<NuxtLink to="/my">
|
||||
Dashboard
|
||||
</NuxtLink>
|
||||
</UiButton>
|
||||
<UiButton v-else @click="handleGoogleLogin" :size>
|
||||
Log in
|
||||
</UiButton>
|
||||
</TransitionGroup>
|
||||
</template>
|
||||
@@ -60,38 +60,32 @@ switch (statusCode) {
|
||||
|
||||
<template>
|
||||
<div class="h-screen">
|
||||
<div class="h-full grid grid-cols-[auto_1fr] transition-colors">
|
||||
<Sidebar />
|
||||
<div class="h-full w-full grid place-items-center transition-colors">
|
||||
<Head>
|
||||
<Title>{{ $t(titleKey) }}</Title>
|
||||
</Head>
|
||||
|
||||
<div class="wrapper shadow-body-light dark:shadow-body-dark transition-all">
|
||||
<div class="h-full w-full grid place-items-center">
|
||||
<Head>
|
||||
<Title>{{ $t(titleKey) }}</Title>
|
||||
</Head>
|
||||
<div class="grid text-center justify-items-center opacity-80">
|
||||
<PhImageBroken v-if="statusCode === 404" size="100" class="opacity-60" />
|
||||
<PhLinkBreak v-else-if="statusCode === 500" size="100" class="opacity-60" />
|
||||
<PhBugBeetle v-else size="100" class="opacity-60" />
|
||||
|
||||
<div class="grid text-center justify-items-center opacity-80">
|
||||
<PhImageBroken v-if="statusCode === 404" size="100" class="opacity-60" />
|
||||
<PhLinkBreak v-else-if="statusCode === 500" size="100" class="opacity-60" />
|
||||
<PhBugBeetle v-else size="100" class="opacity-60" />
|
||||
<Heading level="h0">
|
||||
{{ $t(titleKey) }}
|
||||
</Heading>
|
||||
|
||||
<Heading level="h0">
|
||||
{{ $t(titleKey) }}
|
||||
</Heading>
|
||||
|
||||
<div class="mt-6 md:text-lg">
|
||||
<p>{{ $t(descriptionKey) }}</p>
|
||||
<p>{{ $t(subDescriptionKey) }}</p>
|
||||
</div>
|
||||
|
||||
<UiButton variant="default" class="mt-6 gap-2" as-child>
|
||||
<RouterLink to="/">
|
||||
<PhArrowBendDoubleUpLeft size="24" />
|
||||
|
||||
{{ $t('ui.backToHome') }}
|
||||
</RouterLink>
|
||||
</UiButton>
|
||||
</div>
|
||||
<div class="mt-6 md:text-lg">
|
||||
<p>{{ $t(descriptionKey) }}</p>
|
||||
<p>{{ $t(subDescriptionKey) }}</p>
|
||||
</div>
|
||||
|
||||
<UiButton variant="default" class="mt-6 gap-2" as-child>
|
||||
<RouterLink to="/">
|
||||
<PhArrowBendDoubleUpLeft size="24" />
|
||||
|
||||
{{ $t('ui.backToHome') }}
|
||||
</RouterLink>
|
||||
</UiButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,36 @@
|
||||
<template>
|
||||
<div
|
||||
class="wrapper max-h-screen h-full transition-all overflow-y-auto"
|
||||
class="wrapper max-h-screen h-full transition-all overflow-y-auto grid grid-rows-[auto_1fr]"
|
||||
>
|
||||
<slot />
|
||||
<Navbar />
|
||||
|
||||
<div class="inner-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.inner-content {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
inset-inline: 0;
|
||||
top: 0;
|
||||
display: block;
|
||||
content: '';
|
||||
height: .1rem;
|
||||
max-width: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
transparent 10%,
|
||||
color-mix(in srgb, var(--color-primary) 50%, transparent) 25%,
|
||||
color-mix(in srgb, var(--color-primary) 50%, transparent) 75%,
|
||||
transparent 90%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -34,6 +34,6 @@ watch(locale, () => refresh())
|
||||
<PhCircleNotch size="50" class="opacity-33 animate-spin"/>
|
||||
</div>
|
||||
|
||||
<LazyContentRenderer v-else-if="status === 'success' && page" :value="page" class="content max-w-5xl" />
|
||||
<LazyContentRenderer v-else-if="status === 'success' && page" :value="page" class="content max-w-4xl" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -6,27 +6,6 @@ useHead({
|
||||
definePageMeta({
|
||||
layout: "public"
|
||||
})
|
||||
|
||||
const { auth } = useSupabaseClient()
|
||||
const user = useSupabaseUser()
|
||||
const profileUrl: string = `${useRequestURL().origin}/my/`
|
||||
|
||||
async function handleGoogleLogin() {
|
||||
const { error } = await auth.signInWithOAuth({
|
||||
provider: "google",
|
||||
options: {
|
||||
queryParams: {
|
||||
access_type: "offline",
|
||||
prompt: "consent"
|
||||
},
|
||||
redirectTo: profileUrl
|
||||
}
|
||||
})
|
||||
|
||||
if (error) {
|
||||
console.log(error.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -39,20 +18,15 @@ async function handleGoogleLogin() {
|
||||
</Head>
|
||||
|
||||
<div class="py-8 md:py-24 px-4">
|
||||
<div class="flow text-center max-w-2xl mx-auto">
|
||||
<h1 class="text-3xl md:text-5xl font-bold md:font-semibold">A home for your creativity</h1>
|
||||
<p class="text-sm">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ipsam eos rem accusantium voluptates? Inventore dolorum reprehenderit quibusdam consequatur, totam iusto velit neque dolor dicta possimus cum, deleniti, saepe expedita culpa!</p>
|
||||
<div class="flow text-center max-w-4xl mx-auto">
|
||||
<h1 class="text-3xl md:text-5xl font-bold md:font-semibold">
|
||||
{{ $t('pages.home.h1') }}
|
||||
</h1>
|
||||
<p class="text-sm">
|
||||
{{ $t('pages.home.tagline') }}
|
||||
</p>
|
||||
|
||||
<TransitionGroup name="fade-group" appear>
|
||||
<UiButton v-if="user" as-child>
|
||||
<NuxtLink to="/my">
|
||||
Dashboard
|
||||
</NuxtLink>
|
||||
</UiButton>
|
||||
<UiButton v-else @click="handleGoogleLogin">
|
||||
Log in
|
||||
</UiButton>
|
||||
</TransitionGroup>
|
||||
<UserDashboardLink />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -327,6 +327,10 @@ export default defineI18nConfig(() => ({
|
||||
}
|
||||
},
|
||||
pages: {
|
||||
home: {
|
||||
h1: "A home for your creativity",
|
||||
tagline: "Visualize your fantasy or sci-fi worlds with our interactive calendars"
|
||||
},
|
||||
explore: {
|
||||
menuLabel: "Explore",
|
||||
title: "Explore worlds",
|
||||
@@ -677,6 +681,10 @@ export default defineI18nConfig(() => ({
|
||||
}
|
||||
},
|
||||
pages: {
|
||||
home: {
|
||||
h1: "Un espace pour votre créativité",
|
||||
tagline: "Visualisez vos mondes fantasy ou de science-fiction grâce à nos calendriers interactifs"
|
||||
},
|
||||
explore: {
|
||||
menuLabel: "Explorer",
|
||||
title: "Explorer les mondes",
|
||||
|
||||
Reference in New Issue
Block a user