- Replace global AppHeader slots with in-page headers on Calendar, Edit, and Show pages — full-width canvas with the page-specific controls living in their own ink-bordered bar. - Remove sidebar collapse mechanism: drop Cmd+B keyboard shortcut, force defaultOpen=true (ignore persisted cookie), make toggleSidebar a no-op on desktop. Sidebar is permanent on desktop, sheet behavior preserved on mobile. - Redesign Tabs to match the design system: each TabsTrigger renders as a standalone sticker button (border-2 + rounded-md + shadow-xs), with amber-200 active state mirroring the "POST" badge from post-templates. - Show page layout: cap preview Card to max-w-xl, preserve natural aspect for single-image posts (object-contain, max-h-[480px]), drop redundant stats grid, swap header sides (Back button left, status + date right with date first). - Assets: bump GalleryBrowser search inputs to h-12 for comfortable browsing across uploads, Unsplash, and Giphy tabs. - Fix PostPlatformMetrics loading-forever bug: hoist useHttp out of the onMounted callback into setup, and read the response array directly (backend returns the array at root, not under .data). - i18n: rename posts.show.back_to_posts → posts.show.back; remove unused posts.show.summary.* keys.
78 lines
2.1 KiB
Vue
78 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import type { HTMLAttributes, Ref } from "vue"
|
|
import { useMediaQuery, useVModel } from "@vueuse/core"
|
|
import { TooltipProvider } from "reka-ui"
|
|
import { computed, ref } from "vue"
|
|
import { cn } from "@/lib/utils"
|
|
import { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from "./utils"
|
|
|
|
const props = withDefaults(defineProps<{
|
|
defaultOpen?: boolean
|
|
open?: boolean
|
|
class?: HTMLAttributes["class"]
|
|
}>(), {
|
|
defaultOpen: true,
|
|
open: undefined,
|
|
})
|
|
|
|
const emits = defineEmits<{
|
|
"update:open": [open: boolean]
|
|
}>()
|
|
|
|
const isMobile = useMediaQuery("(max-width: 768px)")
|
|
const openMobile = ref(false)
|
|
|
|
const open = useVModel(props, "open", emits, {
|
|
defaultValue: props.defaultOpen ?? false,
|
|
passive: (props.open === undefined) as false,
|
|
}) as Ref<boolean>
|
|
|
|
const setOpen = (value: boolean) => {
|
|
open.value = value // emits('update:open', value)
|
|
|
|
// This sets the cookie to keep the sidebar state.
|
|
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
|
|
}
|
|
|
|
const setOpenMobile = (value: boolean) => {
|
|
openMobile.value = value
|
|
}
|
|
|
|
// Helper to toggle the sidebar. Desktop toggling is intentionally a no-op:
|
|
// the app does not support hiding/collapsing the sidebar on desktop.
|
|
const toggleSidebar = () => {
|
|
if (isMobile.value) {
|
|
setOpenMobile(!openMobile.value)
|
|
}
|
|
}
|
|
|
|
// We add a state so that we can do data-state="expanded" or "collapsed".
|
|
// This makes it easier to style the sidebar with Tailwind classes.
|
|
const state = computed(() => open.value ? "expanded" : "collapsed")
|
|
|
|
provideSidebarContext({
|
|
state,
|
|
open,
|
|
setOpen,
|
|
isMobile,
|
|
openMobile,
|
|
setOpenMobile,
|
|
toggleSidebar,
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<TooltipProvider :delay-duration="0">
|
|
<div
|
|
data-slot="sidebar-wrapper"
|
|
:style="{
|
|
'--sidebar-width': SIDEBAR_WIDTH,
|
|
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
|
}"
|
|
:class="cn('group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex h-svh w-full overflow-hidden', props.class)"
|
|
v-bind="$attrs"
|
|
>
|
|
<slot />
|
|
</div>
|
|
</TooltipProvider>
|
|
</template>
|