Remove top project tabs in favor of the sidebar's Projects sub-menu

The sidebar already provides Overview/Shots/Assets/Tasks/Settings
navigation for the current project, making the top ProjectTabs bar
redundant. Removed it from ProjectDetailView.vue and deleted the
now-fully-unused ProjectTabs.vue component.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 21:58:30 +08:00
parent 960753b3d6
commit 548d1081ba
2 changed files with 0 additions and 170 deletions
@@ -1,160 +0,0 @@
<template>
<div class="w-full">
<div class="grid w-full grid-cols-5 h-auto bg-muted/50 p-1 rounded-md">
<button
v-for="tab in tabs"
:key="tab.id"
@click="setActiveTab(tab.id)"
:class="[
'flex flex-col sm:flex-row items-center justify-center gap-1 sm:gap-2 py-2 px-1 sm:px-3 min-h-[3rem] sm:min-h-[2.5rem] transition-all duration-200 text-center rounded-sm',
activeTab === tab.id
? 'bg-background shadow-sm text-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-background/50'
]"
>
<div class="flex items-center gap-1 sm:gap-2">
<component :is="tab.icon" class="h-4 w-4 flex-shrink-0" />
<span class="hidden sm:inline text-sm font-medium">{{ tab.label }}</span>
<span class="sm:hidden text-xs font-medium">{{ getMobileLabel(tab) }}</span>
</div>
<Badge
v-if="tab.count !== undefined"
variant="secondary"
class="text-xs hidden sm:inline-flex min-w-[1.5rem] h-5"
>
{{ tab.count }}
</Badge>
<!-- Mobile count display -->
<div
v-if="tab.count !== undefined"
class="sm:hidden text-xs text-muted-foreground font-medium"
>
{{ tab.count }}
</div>
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { LayoutDashboard, Camera, Package, ListTodo, Settings } from "lucide-vue-next";
import { Badge } from "@/components/ui/badge";
interface Tab {
id: string;
label: string;
icon: any;
route: string;
count?: number;
}
interface Props {
projectId: number;
shotCount?: number;
assetCount?: number;
taskCount?: number;
}
const props = defineProps<Props>();
const route = useRoute();
const router = useRouter();
// Define available tabs
const tabs = computed<Tab[]>(() => [
{
id: "overview",
label: "Overview",
icon: LayoutDashboard,
route: `/projects/${props.projectId}`,
},
{
id: "shots",
label: "Shots",
icon: Camera,
route: `/projects/${props.projectId}/shots`,
count: props.shotCount,
},
{
id: "assets",
label: "Assets",
icon: Package,
route: `/projects/${props.projectId}/assets`,
count: props.assetCount,
},
{
id: "tasks",
label: "Tasks",
icon: ListTodo,
route: `/projects/${props.projectId}/tasks`,
count: props.taskCount,
},
{
id: "settings",
label: "Settings",
icon: Settings,
route: `/projects/${props.projectId}/settings`,
},
]);
// Determine active tab based on current route
const activeTab = computed(() => {
const currentPath = route.path;
if (currentPath === `/projects/${props.projectId}`) {
return "overview";
} else if (currentPath.startsWith(`/projects/${props.projectId}/shots`)) {
return "shots";
} else if (currentPath.startsWith(`/projects/${props.projectId}/assets`)) {
return "assets";
} else if (currentPath.startsWith(`/projects/${props.projectId}/tasks`)) {
return "tasks";
} else if (
currentPath.startsWith(`/projects/${props.projectId}/settings`)
) {
return "settings";
}
return "overview";
});
// Set active tab and navigate
const setActiveTab = (tabId: string) => {
const tab = tabs.value.find((t) => t.id === tabId);
if (tab) {
router.push(tab.route).catch(() => {
// Navigation aborted (e.g. duplicate route) — safe to ignore
});
}
};
// Get mobile label for tabs
const getMobileLabel = (tab: Tab) => {
switch (tab.id) {
case "settings":
return "Settings";
case "overview":
return "Info";
case "shots":
return "Shots";
case "assets":
return "Assets";
case "tasks":
return "Tasks";
default:
return tab.label.charAt(0);
}
};
// Watch for route changes to ensure tab state persistence
watch(
() => route.path,
() => {
// Tab state is automatically updated via activeTab computed property
// This ensures tab state persistence during project navigation
},
{ immediate: true }
);
</script>
-10
View File
@@ -38,15 +38,6 @@
<!-- </div> -->
</div>
<!-- Project Tabs -->
<div class="px-0 sm:px-0 pb-0 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60" v-if="project">
<ProjectTabs
:project-id="project.id"
:shot-count="project.shot_count"
:asset-count="project.asset_count"
/>
</div>
<!-- Tab Content Area -->
<div class="flex-1 overflow-auto bg-muted/30">
<router-view :key="route.fullPath" />
@@ -87,7 +78,6 @@ import {
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { useProjectsStore } from '@/stores/projects'
import ProjectTabs from '@/components/project/ProjectTabs.vue'
import type { Project } from '@/stores/projects'
const router = useRouter()