Added navbar on public pages

This commit is contained in:
Alexis
2025-08-11 20:00:04 +02:00
parent 20045b125e
commit a5a232bac7
9 changed files with 157 additions and 76 deletions

View File

@@ -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 {

View 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>

View File

@@ -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

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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",