uark_front/src/layouts/NavBar.vue

240 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<nav
class="w-full h-[64px] bg-white bg-opacity-50 shadow-md flex justify-between items-center px-8"
>
<!-- 左側 logo選單區 -->
<div class="flex justify-start items-center gap-12">
<RouterLink to="/" class="h-[45px]">
<img src="/img/logo.png" alt="Logo" class="w-full h-full" />
</RouterLink>
<div class="relative">
<div
ref="triggerRef"
class="btn text-white bg-brand-green hover:opacity-90 shadow-md border-none rounded-full px-8 tracking-widest"
role="button"
tabindex="0"
aria-haspopup="true"
:aria-expanded="isOpen ? 'true' : 'false'"
@click="toggle"
@keydown.enter.prevent="toggle"
@keydown.space.prevent="toggle"
>
{{ displayLabel }}
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 512 512"
>
<path
fill="currentColor"
d="m98 190.06l139.78 163.12a24 24 0 0 0 36.44 0L414 190.06c13.34-15.57 2.28-39.62-18.22-39.62h-279.6c-20.5 0-31.56 24.05-18.18 39.62"
/>
</svg>
</span>
</div>
<!-- Modal定位在按鈕右下方 -->
<div
v-show="isOpen"
ref="panelRef"
class="absolute top-16 left-0 z-50 w-64 rounded-md border border-gray-100 bg-white shadow-lg p-2"
@click.stop
>
<ul class="max-h-48 overflow-y-auto text-brand-black">
<li
v-for="item in facilities"
:key="item"
@click="selectItem(item)"
class="px-3 py-2 rounded-md cursor-pointer hover:bg-gray-100"
:class="selectedItem === item ? 'bg-brand-green-light' : ''"
>
{{ item }}
</li>
</ul>
</div>
</div>
</div>
<!-- 中間 導覽按鈕區 -->
<div
class="min-w-[300px] text-brand-black bg-white shadow-md rounded-full grid grid-cols-3 items-center"
>
<RouterLink to="/" v-slot="{ href, navigate, isExactActive }">
<a
:href="href"
@click="navigate"
:class="[
'px-5 py-2 rounded-full flex justify-center items-center transition-colors',
isExactActive ? 'bg-brand-green-light' : 'hover:bg-gray-100',
]"
>
首頁
</a>
</RouterLink>
<RouterLink to="/operation" v-slot="{ href, navigate, isActive }">
<a
:href="href"
@click="navigate"
:class="[
'px-5 py-2 rounded-full flex justify-center items-center transition-colors',
isActive ? 'bg-brand-green-light' : 'hover:bg-gray-100',
]"
>
營運
</a>
</RouterLink>
<RouterLink to="/nursing" v-slot="{ href, navigate, isActive }">
<a
:href="href"
@click="navigate"
:class="[
'px-5 py-2 rounded-full flex justify-center items-center transition-colors',
isActive ? 'bg-brand-green-light' : 'hover:bg-gray-100',
]"
>
照護
</a>
</RouterLink>
</div>
<!-- 右側 登入區 -->
<div class="flex justify-end items-center gap-8">
<div
class="btn text-brand-black bg-white hover:opacity-90 shadow-md border-none rounded-full p-2 flex justify-center items-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 16 16"
>
<path
fill="currentColor"
d="M8 2a4.5 4.5 0 0 0-4.5 4.5v2.401l-.964 2.414A.5.5 0 0 0 3 12h3c0 1.108.892 2 2 2s2-.892 2-2h3a.5.5 0 0 0 .464-.685L12.5 8.9V6.5A4.5 4.5 0 0 0 8 2m1 10c0 .556-.444 1-1 1s-1-.444-1-1zM4.5 6.5a3.5 3.5 0 1 1 7 0v2.498a.5.5 0 0 0 .036.185L12.262 11H3.738l.726-1.817a.5.5 0 0 0 .036-.185z"
/>
</svg>
</div>
<div
class="btn text-brand-black bg-white hover:opacity-90 shadow-md border-none rounded-full px-6 flex justify-center items-center gap-3"
>
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
fill="currentColor"
d="M11 7c0 1.66-1.34 3-3 3S5 8.66 5 7s1.34-3 3-3s3 1.34 3 3"
/>
<path
fill="currentColor"
fill-rule="evenodd"
d="M16 8c0 4.42-3.58 8-8 8s-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8M4 13.75C4.16 13.484 5.71 11 7.99 11c2.27 0 3.83 2.49 3.99 2.75A6.98 6.98 0 0 0 14.99 8c0-3.87-3.13-7-7-7s-7 3.13-7 7c0 2.38 1.19 4.49 3.01 5.75"
clip-rule="evenodd"
/>
</svg>
</span>
<p>使用者</p>
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 512 512"
>
<path
fill="currentColor"
d="m98 190.06l139.78 163.12a24 24 0 0 0 36.44 0L414 190.06c13.34-15.57 2.28-39.62-18.22-39.62h-279.6c-20.5 0-31.56 24.05-18.18 39.62"
/>
</svg>
</span>
</div>
</div>
</nav>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted, defineOptions } from "vue";
// modal 操作
const selectItem = (item) => {
selectedItem.value = item;
isOpen.value = false;
};
// 按鈕顯示文字(>4 字就加 …)
const displayLabel = computed(() => {
const label = String(selectedItem.value ?? "護祐");
return label.length > 4 ? label.slice(0, 4) + "..." : label;
});
defineOptions({ name: "NavBar" });
const isOpen = ref(false);
const triggerRef = ref(null);
const panelRef = ref(null);
// 機構名稱清單
const facilities = [
"總部",
"護祐護理之家",
"崇祐護理之家",
"崇祐長照中心(養護型)",
"育祐護理之家",
"崇恩長照中心(養護型)",
"崇恩護理之家",
"崇恩居家護理所",
"傳心日間照顧中心",
"敬慈居家服務中心",
"傳祐長照中心(養護型)",
"中安崇恩長照中心(養護型)",
"崇智護理之家",
"慈祐長照中心(養護型)",
];
// 預設選中第一筆同時讓按鈕顯示第一筆、li 也保持選中底色)
const selectedItem = ref(facilities[0]);
// 切換開/關
const toggle = () => {
isOpen.value = !isOpen.value;
};
// 點空白處關閉
const onClickOutside = (e) => {
const t = e.target;
if (!triggerRef.value || !panelRef.value) return;
const clickedInsideTrigger = triggerRef.value.contains(t);
const clickedInsidePanel = panelRef.value.contains(t);
if (!clickedInsideTrigger && !clickedInsidePanel) {
isOpen.value = false;
}
};
// Esc 關閉
const onKeydown = (e) => {
if (e.key === "Escape") isOpen.value = false;
};
onMounted(() => {
document.addEventListener("click", onClickOutside);
document.addEventListener("keydown", onKeydown);
});
onUnmounted(() => {
document.removeEventListener("click", onClickOutside);
document.removeEventListener("keydown", onKeydown);
});
</script>
<style scoped></style>