87 lines
No EOL
2.4 KiB
Vue
87 lines
No EOL
2.4 KiB
Vue
<template>
|
|
<div v-if="isSetupCompleted" class="mb-12">
|
|
<div class="w-full mx-auto">
|
|
<nav
|
|
class="flex flex-wrap items-center space-x-1 font-mono uppercase justify-self-center"
|
|
>
|
|
<NuxtLink
|
|
v-for="item in coopBuilderItems"
|
|
:key="item.id"
|
|
:to="item.path"
|
|
class="inline-flex items-center px-3 py-2 text-sm font-bold transition-colors whitespace-nowrap underline"
|
|
:class="
|
|
isActive(item.path)
|
|
? 'bg-black text-white dark:bg-white dark:text-black no-underline'
|
|
: ''
|
|
"
|
|
>
|
|
{{ item.name }}
|
|
</NuxtLink>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const route = useRoute();
|
|
const coop = useCoopBuilder();
|
|
|
|
const coopBuilderItems = [
|
|
{
|
|
id: "coop-builder",
|
|
name: "Settings",
|
|
path: "/coop-builder",
|
|
},
|
|
{
|
|
id: "budget",
|
|
name: "Studio Budget",
|
|
path: "/budget",
|
|
},
|
|
{
|
|
id: "project-budget",
|
|
name: "Project Budget",
|
|
path: "/project-budget",
|
|
},
|
|
];
|
|
|
|
// Check if setup wizard is completed using the same validation logic as coop-builder page
|
|
const isSetupCompleted = computed(() => {
|
|
// Members validation: at least one member with name and positive hours
|
|
const membersValid = coop.members.value.some((m: any) => {
|
|
const hasName = typeof m.name === "string" && m.name.trim().length > 0;
|
|
const hours = Number((m as any).hoursPerMonth ?? 0);
|
|
return hasName && Number.isFinite(hours) && hours > 0;
|
|
});
|
|
|
|
// Streams validation: at least one stream with name and non-negative monthly amount
|
|
const streamsValid = coop.streams.value.length > 0 &&
|
|
coop.streams.value.every((s: any) => {
|
|
const monthly = Number((s as any).monthly ?? 0);
|
|
return (s.label || "").toString().trim().length > 0 && monthly >= 0;
|
|
});
|
|
|
|
// Policies validation: has members (same logic as coop-builder page)
|
|
const policiesValid = coop.members.value.length > 0;
|
|
|
|
// Costs are always valid (optional)
|
|
const costsValid = true;
|
|
|
|
return policiesValid && membersValid && costsValid && streamsValid;
|
|
});
|
|
|
|
function isActive(path: string): boolean {
|
|
return route.path === path;
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* Ensure horizontal scroll on mobile */
|
|
nav {
|
|
scrollbar-width: none; /* Firefox */
|
|
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
|
}
|
|
|
|
nav::-webkit-scrollbar {
|
|
display: none; /* WebKit */
|
|
}
|
|
</style> |