ghostguild-org/app/components/TopStrip.vue

133 lines
5.3 KiB
Vue

<template>
<div class="top-strip">
<span>
<slot name="left">
<span class="breadcrumb-nav">
<NuxtLink to="/" class="breadcrumb-link">ghostguild.org</NuxtLink>
<template v-for="(crumb, i) in breadcrumbs" :key="i">
<span class="breadcrumb-sep"> / </span>
<NuxtLink :to="crumb.path" class="breadcrumb-link">{{
crumb.label
}}</NuxtLink>
</template>
</span>
</slot>
</span>
<span>
<slot name="right">
<ClientOnly>
<template v-if="memberData">
<NuxtLink to="/member/profile" class="member-link">
<img
v-if="memberData.avatar"
:src="`/ghosties/Ghost-${capitalize(memberData.avatar)}.png`"
:alt="memberData.name"
class="member-avatar"
/>
<svg
v-else
class="member-avatar default-ghost"
viewBox="0 0 136 129"
xmlns="http://www.w3.org/2000/svg"
>
<polygon
fill="currentColor"
points="59.75 0 59.75 1.794 50.792 1.794 50.792 3.585 43.627 3.585 43.627 7.169 34.669 7.169 34.669 10.752 27.5 10.752 27.5 16.127 22.125 16.127 22.125 21.502 16.752 21.502 16.752 28.668 13.167 28.668 13.167 37.626 9.583 37.626 9.583 44.791 7.794 44.791 7.794 53.749 6 53.749 6 75.251 7.794 75.251 7.794 84.209 9.583 84.209 9.583 91.376 13.167 91.376 13.167 100.334 16.752 100.334 16.752 107.498 22.125 107.498 22.125 112.873 27.5 112.873 27.5 118.25 34.669 118.25 34.669 121.831 43.627 121.831 43.627 125.415 50.792 125.415 50.792 127.208 59.75 127.208 59.75 129 81.25 129 81.25 127.208 90.208 127.208 90.208 125.415 97.377 125.415 97.377 121.831 106.335 121.831 106.335 118.25 113.5 118.25 113.5 112.873 118.875 112.873 118.875 107.498 124.252 107.498 124.252 100.334 127.833 100.334 127.833 91.376 131.417 91.376 131.417 84.209 133.21 84.209 133.21 75.251 135 75.251 135 53.749 133.21 53.749 133.21 44.791 131.417 44.791 131.417 37.626 127.833 37.626 127.833 28.668 124.252 28.668 124.252 21.502 118.875 21.502 118.875 16.127 113.5 16.127 113.5 10.752 106.335 10.752 106.335 7.169 97.377 7.169 97.377 3.585 90.208 3.585 90.208 1.794 81.25 1.794 81.25 0"
/>
<polygon
fill="currentColor"
points="1.356 82 1.356 83.308 0 83.308 0 98.999 1.356 98.999 1.356 100.309 9.501 100.309 9.501 104.231 8.143 104.231 8.143 106.847 1.356 106.847 1.356 108.154 0 108.154 0 114.694 1.356 114.694 1.356 116 10.855 116 10.855 114.694 13.57 114.694 13.57 112.08 16.285 112.08 16.285 109.464 17.644 109.464 17.644 104.231 19 104.231 19 83.308 17.644 83.308 17.644 82"
/>
<g transform="translate(50, 38)" fill="#000">
<polygon
points="7.072 0.642 7.072 2.569 7.714 2.569 7.714 4.499 8.358 4.499 8.358 6.427 9 6.427 9 8.356 8.358 8.356 8.358 9 4.501 9 4.501 8.356 3.859 8.356 3.859 6.427 2.571 6.427 2.571 4.499 1.286 4.499 1.286 2.569 0 2.569 0 0.642 0.642 0.642 0.642 0 6.431 0 6.431 0.642"
/>
<polygon
points="40.395 25 40.395 25.599 41 25.599 41 30.399 40.395 30.399 40.395 31 21.605 31 21.605 30.399 21 30.399 21 25.599 21.605 25.599 21.605 25"
/>
<polygon
points="52.072 0.642 52.072 2.569 52.714 2.569 52.714 4.499 53.358 4.499 53.358 6.427 54 6.427 54 8.356 53.358 8.356 53.358 9 49.501 9 49.501 8.356 48.859 8.356 48.859 6.427 47.571 6.427 47.571 4.499 46.286 4.499 46.286 2.569 45 2.569 45 0.642 45.642 0.642 45.642 0 51.431 0 51.431 0.642"
/>
</g>
</svg>
{{ memberData.name }}
</NuxtLink>
</template>
<template v-else> A cooperative for game developers </template>
<template #fallback> A cooperative for game developers </template>
</ClientOnly>
</slot>
</span>
</div>
</template>
<script setup>
const props = defineProps({
pagePath: { type: String, default: "" },
});
const { memberData } = useAuth();
const capitalize = (str) => {
if (!str) return "";
return str.charAt(0).toUpperCase() + str.slice(1);
};
const breadcrumbs = computed(() => {
if (!props.pagePath) return [];
const segments = props.pagePath.split(" / ");
let path = "";
return segments.map((segment) => {
path += "/" + segment.replace(/\s+/g, "-");
return { label: segment, path };
});
});
</script>
<style scoped>
.top-strip {
padding: 0 32px;
min-height: 53px;
border-bottom: 1px dashed var(--border);
font-size: 12px;
color: var(--text-dim);
display: flex;
justify-content: space-between;
align-items: center;
}
.top-strip a {
color: var(--text-faint);
}
.top-strip a:hover {
color: var(--candle);
}
.member-link {
display: inline-flex;
align-items: center;
gap: 6px;
text-decoration: none;
}
.member-avatar {
width: 18px;
height: 18px;
object-fit: contain;
}
.default-ghost {
color: var(--border);
}
.breadcrumb-nav {
display: inline;
}
.breadcrumb-link {
color: var(--text-faint);
text-decoration: none;
}
.breadcrumb-link:hover {
color: var(--candle);
text-decoration: none;
}
.breadcrumb-sep {
color: var(--text-faint);
}
</style>