Files
money.sori.studio/layouts/default.vue
2026-08-13 17:25:49 +09:00

99 lines
3.4 KiB
Vue

<template>
<div class="min-h-dvh bg-paper text-ink">
<aside
v-if="showNav"
class="fixed inset-y-0 left-0 z-20 hidden w-64 border-r border-line bg-white md:block"
>
<div class="flex h-16 items-center gap-3 border-b border-line px-5">
<div class="flex h-9 w-9 items-center justify-center rounded-md bg-red-500 text-lg font-bold text-white">M</div>
<strong>Money 가계부</strong>
</div>
<nav class="px-3 py-5">
<NuxtLink
v-for="item in items"
:key="item.to"
:to="item.to"
class="mb-2 flex min-h-12 items-center gap-3 rounded-md px-4 text-sm font-semibold"
:class="isActive(item.to) ? 'bg-red-50 text-red-600' : 'text-muted hover:bg-paper'"
>
<span
class="flex h-8 w-8 items-center justify-center rounded-md"
:class="isActive(item.to) ? 'bg-red-100' : ''"
aria-hidden="true"
>
<span class="h-6 w-6 bg-current" :style="iconStyle(item.icon)" />
</span>
<span>{{ item.label }}</span>
</NuxtLink>
</nav>
</aside>
<main class="min-h-dvh w-full bg-white md:ml-64 md:bg-paper" :class="showNav ? 'pb-20 md:pb-0' : ''">
<div class="mx-auto min-h-dvh w-full md:max-w-7xl md:bg-transparent">
<slot />
</div>
</main>
<nav
v-if="showNav"
class="fixed inset-x-0 bottom-0 z-20 border-t border-line bg-white/95 backdrop-blur md:hidden"
>
<div class="mx-auto grid max-w-lg grid-cols-4">
<NuxtLink
v-for="item in items"
:key="item.to"
:to="item.to"
class="flex min-h-14 flex-col items-center justify-center gap-0.5 text-[11px] font-bold"
:class="isActive(item.to) ? 'text-red-600' : 'text-muted'"
>
<span
class="flex h-7 w-7 items-center justify-center rounded-md"
:class="isActive(item.to) ? 'bg-red-50' : ''"
aria-hidden="true"
>
<span class="h-5 w-5 bg-current" :style="iconStyle(item.icon)" />
</span>
<span>{{ item.label }}</span>
</NuxtLink>
</div>
</nav>
<NuxtLink
v-if="showFab"
to="/add"
class="fixed bottom-20 right-4 z-30 flex h-14 w-14 items-center justify-center rounded-full bg-red-500 text-3xl leading-none text-white shadow-soft active:scale-95 md:bottom-10 md:right-10"
aria-label="거래 추가"
>
+
</NuxtLink>
</div>
</template>
<script setup lang="ts">
import assetIcon from '~/assets/icons/account_balance_wallet.svg?url'
import reportIcon from '~/assets/icons/bar_chart.svg?url'
import receiptIcon from '~/assets/icons/receipt_long.svg?url'
import settingsIcon from '~/assets/icons/settings.svg?url'
const route = useRoute()
const items = [
{ to: '/', label: '내역', icon: receiptIcon },
{ to: '/stats', label: '통계', icon: reportIcon },
{ to: '/assets', label: '자산', icon: assetIcon },
{ to: '/settings', label: '설정', icon: settingsIcon }
]
const showNav = computed(() => route.path !== '/login')
const showFab = computed(() => showNav.value && route.path !== '/add' && !route.path.startsWith('/transactions/'))
function isActive(to: string) {
return to === '/' ? route.path === '/' : route.path.startsWith(to)
}
function iconStyle(icon: string) {
return {
mask: `url(${icon}) center / contain no-repeat`,
WebkitMask: `url(${icon}) center / contain no-repeat`
}
}
</script>