Changed the way the sidebar works

This commit is contained in:
Alexis
2025-03-13 18:25:04 +01:00
parent fdb77a20f3
commit f0e3fc2167
10 changed files with 117 additions and 34 deletions

View File

@@ -1,17 +1,26 @@
<script lang="ts" setup>
import { PhCompass, PhList } from "@phosphor-icons/vue"
import type { SidebarMenuActionType } from "./SidebarProps";
import { PhCompass, PhGlobeHemisphereEast, PhHurricane, PhList } from "@phosphor-icons/vue"
import type { SidebarMenuActionType, SidebarMenuIcon } from "./SidebarProps";
const { revealAdvancedSearch } = useCalendar()
const { currentMenu } = storeToRefs(useUiStore())
// const user = useSupabaseUser()
function handleMenuItemAction(actionType: SidebarMenuActionType) {
if (actionType === "event-search") {
revealAdvancedSearch()
}
}
function computeMenuItemIcon(iconString: SidebarMenuIcon) {
switch (iconString) {
case "universe":
return PhHurricane
case "world":
return PhGlobeHemisphereEast
default:
return PhCompass
}
}
</script>
<template>
@@ -27,7 +36,7 @@ function handleMenuItemAction(actionType: SidebarMenuActionType) {
<UiTooltipProvider :delay-duration="50">
<UiTooltip>
<UiTooltipTrigger as-child>
<UiButton variant="ghost" size="icon" class="rounded-full" as-child>
<UiButton variant="ghost" size="icon" class="rounded-full text-indigo-400" as-child>
<RouterLink to="/explore">
<PhCompass size="24" weight="fill" />
</RouterLink>
@@ -42,25 +51,39 @@ function handleMenuItemAction(actionType: SidebarMenuActionType) {
</UiTooltipProvider>
</li>
<li v-for="(item, i) in currentMenu" :key="i">
<UiTooltipProvider :delay-duration="50">
<UiTooltip>
<UiTooltipTrigger as-child>
<UiButton v-if="item.to" variant="ghost" size="icon" class="rounded-full" as-child>
<RouterLink :to="item.to">
<component :is="item.phIcon" size="24" weight="fill" />
</RouterLink>
</UiButton>
<UiButton v-if="item.action" variant="ghost" size="icon" class="rounded-full" @click="handleMenuItemAction(item.action!)">
<component :is="item.phIcon" size="24" weight="fill" />
</UiButton>
</UiTooltipTrigger>
<UiTooltipContent :side="'right'" :side-offset="6">
<p>{{ item.tooltip }}</p>
</UiTooltipContent>
</UiTooltip>
</UiTooltipProvider>
</li>
<ClientOnly>
<li v-for="(item, i) in currentMenu" :key="i">
<UiTooltipProvider :delay-duration="50">
<UiTooltip>
<UiTooltipTrigger as-child>
<UiButton
v-if="item.to"
variant="ghost"
size="icon"
class="rounded-full"
as-child
>
<RouterLink :to="item.to">
<component :is="computeMenuItemIcon(item.phIcon)" size="24" :weight="item.phIconWeight || 'fill'" />
</RouterLink>
</UiButton>
<UiButton
v-if="item.action"
variant="ghost"
size="icon"
class="rounded-full"
@click="handleMenuItemAction(item.action!)"
>
<component :is="computeMenuItemIcon(item.phIcon)" size="24" :weight="item.phIconWeight || 'fill'" />
</UiButton>
</UiTooltipTrigger>
<UiTooltipContent :side="'right'" :side-offset="6">
<p>{{ item.tooltip }}</p>
</UiTooltipContent>
</UiTooltip>
</UiTooltipProvider>
</li>
</ClientOnly>
</menu>
<UserCTA />

View File

@@ -1,9 +1,11 @@
import type { ShallowRef } from "vue"
export type SidebarMenuActionType = "event-search"
export type SidebarMenuIcon = "universe" | "world"
export interface SidebarMenuItem {
phIcon: ShallowRef // use shallowRef to build phIcon
phIcon: SidebarMenuIcon,
phIconWeight?: "regular" | "light" | "fill" | "duotone" | "bold" | "thin"
highlight?: boolean
tooltip: string
action?: SidebarMenuActionType
to?: string

View File

@@ -69,7 +69,7 @@ switch (statusCode) {
<Title>{{ $t(titleKey) }}</Title>
</Head>
<div class="grid justify-items-center opacity-80">
<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" />
@@ -78,7 +78,7 @@ switch (statusCode) {
{{ $t(titleKey) }}
</Heading>
<div class="mt-6 md:text-lg text-center">
<div class="mt-6 md:text-lg">
<p>{{ $t(descriptionKey) }}</p>
<p>{{ $t(subDescriptionKey) }}</p>
</div>

View File

@@ -108,6 +108,8 @@ export default defineI18nConfig(() => ({
world: {
nameSingular: "World",
namePlural: "Worlds",
backToMy: "Back to my universe",
backToSingle: "Back to {world}",
addSingle: "Add a world",
addSingleFirst: "Add your first world !",
editSingle: "Edit world",
@@ -283,6 +285,10 @@ export default defineI18nConfig(() => ({
explore: {
menuLabel: "Explore",
title: "Explore worlds",
},
profile: {
title: "{user} — My universe",
metaTitle: "My universe",
}
}
},
@@ -391,6 +397,8 @@ export default defineI18nConfig(() => ({
world: {
nameSingular: "Monde",
namePlural: "Mondes",
backToMy: "Retourner à mon univers",
backToSingle: "Retourner sur {world}",
addSingle: "Ajouter un monde",
addSingleFirst: "Ajouter votre premier monde !",
editSingle: "Modifier le monde",
@@ -570,6 +578,10 @@ export default defineI18nConfig(() => ({
explore: {
menuLabel: "Explorer",
title: "Explorer les mondes",
},
profile: {
title: "{user} — Mon univers",
metaTitle: "Mon univers",
}
}
}

4
middleware/resetMenu.ts Normal file
View File

@@ -0,0 +1,4 @@
export default defineNuxtRouteMiddleware(() => {
const { resetMenu } = useUiStore()
resetMenu()
})

View File

@@ -2,6 +2,10 @@
useHead({
titleTemplate: null
})
definePageMeta({
middleware: ["reset-menu"]
})
</script>
<template>

View File

@@ -40,6 +40,24 @@ const {
)
const isLoading = computed(() => calendarStatus.value === "pending" || categoriesStatus.value === "pending")
// Set custom menu
const { t } = useI18n()
const { setCurrentMenu } = useUiStore()
setCurrentMenu([
{
tooltip: t("entity.world.backToMy"),
to: "/my",
phIcon: "universe",
phIconWeight: "regular"
},
{
tooltip: t("entity.world.backToSingle", { world: calendar.value?.data.world?.name }),
to: `/my/worlds/${calendar.value?.data.world?.id}`,
phIcon: "world"
},
])
</script>
<template>

View File

@@ -6,7 +6,7 @@ const supabase = useSupabaseClient()
const user = useSupabaseUser()
definePageMeta({
middleware: ["auth-guard"]
middleware: ["auth-guard", "reset-menu"]
})
const { data: worlds } = await useLazyFetch<{ data: World[] }>("/api/worlds/query", { query: { gmId: user?.value!.id } })
@@ -31,7 +31,6 @@ function hideCreateDialog() {
/** Active world channel */
let worldChannel: RealtimeChannel
/** Handles world insertion realtime events */
function handleInsertedWorld(newWorld: WorldChannelPayload) {
if (!worlds.value?.data) return
@@ -121,10 +120,12 @@ function hideEditModal() {
<template>
<main class="p-8">
<Head>
<Title>{{ $t("entity.world.namePlural") }}</Title>
<Title>{{ $t("pages.profile.metaTitle") }}</Title>
</Head>
<Heading level="h1">{{ user?.user_metadata.full_name }}</Heading>
<Heading level="h1">
{{ $t("pages.profile.title", { user: user?.user_metadata.full_name }) }}
</Heading>
<section class="mt-4">
<Spacing size="lg">

View File

@@ -4,6 +4,8 @@ import type { World } from "~/models/World";
import type { Calendar, CalendarChannelPayload } from "~/models/CalendarConfig";
import { PhArrowBendDoubleUpLeft, PhGlobeHemisphereWest, PhPencil } from "@phosphor-icons/vue";
const { t } = useI18n()
const supabase = useSupabaseClient()
const route = useRoute()
const id = route.params.id
@@ -24,6 +26,18 @@ watch(user, (n) => {
}
})
// Set custom menu
const { setCurrentMenu } = useUiStore()
setCurrentMenu([
{
tooltip: t("entity.world.backToMy"),
to: "/my",
phIcon: "universe",
highlight: true
},
])
/**
* === Subscriptions ===
*/

View File

@@ -7,8 +7,13 @@ export const useUiStore = defineStore("ui", () => {
currentMenu.value = items
}
function resetMenu() {
currentMenu.value = []
}
return {
currentMenu,
setCurrentMenu
setCurrentMenu,
resetMenu
}
})