Changed the way the sidebar works
This commit is contained in:
@@ -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 />
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
4
middleware/resetMenu.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default defineNuxtRouteMiddleware(() => {
|
||||
const { resetMenu } = useUiStore()
|
||||
resetMenu()
|
||||
})
|
||||
@@ -2,6 +2,10 @@
|
||||
useHead({
|
||||
titleTemplate: null
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
middleware: ["reset-menu"]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 ===
|
||||
*/
|
||||
|
||||
@@ -7,8 +7,13 @@ export const useUiStore = defineStore("ui", () => {
|
||||
currentMenu.value = items
|
||||
}
|
||||
|
||||
function resetMenu() {
|
||||
currentMenu.value = []
|
||||
}
|
||||
|
||||
return {
|
||||
currentMenu,
|
||||
setCurrentMenu
|
||||
setCurrentMenu,
|
||||
resetMenu
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user