refactor: deduplicate sidebar navigation into data-driven loop
This commit is contained in:
@@ -1,12 +1,75 @@
|
||||
{{define "nav_icon_home"}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if .}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
{{end}}
|
||||
|
||||
{{define "nav_icon_browse"}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if .}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="2" width="20" height="20" rx="0" ry="0" />
|
||||
<line x1="7" y1="2" x2="7" y2="22" />
|
||||
<line x1="17" y1="2" x2="17" y2="22" />
|
||||
<line x1="2" y1="12" x2="22" y2="12" />
|
||||
<line x1="2" y1="7" x2="7" y2="7" />
|
||||
<line x1="2" y1="17" x2="7" y2="17" />
|
||||
<line x1="17" y1="17" x2="22" y2="17" />
|
||||
<line x1="17" y1="7" x2="22" y2="7" />
|
||||
</svg>
|
||||
{{end}}
|
||||
|
||||
{{define "nav_icon_discover"}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if .}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" />
|
||||
</svg>
|
||||
{{end}}
|
||||
|
||||
{{define "nav_icon_schedule"}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if .}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
{{end}}
|
||||
|
||||
{{define "nav_icon_watchlist"}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if .}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M17 18.113l-3.256-2.326A2.989 2.989 0 0 0 12 15.228c-.629 0-1.232.194-1.744.559L7 18.113V4h10v14.113zM18 2H6a1 1 0 0 0-1 1v17.056c0 .209.065.412.187.581a.994.994 0 0 0 1.394.233l4.838-3.455a1 1 0 0 1 1.162 0l4.838 3.455A1 1 0 0 0 19 20.056V3a1 1 0 0 0-1-1z" />
|
||||
</svg>
|
||||
{{end}}
|
||||
|
||||
{{define "nav_item"}}
|
||||
{{$isActive := .isActive}}
|
||||
{{$isCollapsed := .isCollapsed}}
|
||||
<a href="{{.href}}" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="{{.label}}"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
{{if eq .key "home"}}{{template "nav_icon_home" $isActive}}
|
||||
{{else if eq .key "browse"}}{{template "nav_icon_browse" $isActive}}
|
||||
{{else if eq .key "discover"}}{{template "nav_icon_discover" $isActive}}
|
||||
{{else if eq .key "schedule"}}{{template "nav_icon_schedule" $isActive}}
|
||||
{{else if eq .key "watchlist"}}{{template "nav_icon_watchlist" $isActive}}
|
||||
{{end}}
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">{{.label}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{define "navigation"}}
|
||||
{{$currentPath := .CurrentPath}}
|
||||
{{$isCollapsed := .IsCollapsed}}
|
||||
{{$navItems := dict
|
||||
"home" (dict "href" "/" "label" "Home")
|
||||
"browse" (dict "href" "/browse" "label" "Browse")
|
||||
"discover" (dict "href" "/discover" "label" "Discover")
|
||||
"schedule" (dict "href" "/schedule" "label" "Schedule")
|
||||
"watchlist" (dict "href" "/watchlist" "label" "Watchlist")
|
||||
{{$navItems := list
|
||||
(dict "key" "home" "href" "/" "label" "Home" "isActive" (eq $currentPath "/"))
|
||||
(dict "key" "browse" "href" "/browse" "label" "Browse" "isActive" (eq $currentPath "/browse"))
|
||||
(dict "key" "discover" "href" "/discover" "label" "Discover" "isActive" (eq $currentPath "/discover"))
|
||||
(dict "key" "schedule" "href" "/schedule" "label" "Schedule" "isActive" (eq $currentPath "/schedule"))
|
||||
(dict "key" "watchlist" "href" "/watchlist" "label" "Watchlist" "isActive" (eq $currentPath "/watchlist"))
|
||||
}}
|
||||
|
||||
<nav class="bg-background-sidebar h-full">
|
||||
@@ -25,99 +88,10 @@
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{{/* Home */}}
|
||||
{{$isActive := eq $currentPath "/"}}
|
||||
<a href="/" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Home"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Home</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Browse */}}
|
||||
{{$isActive := eq $currentPath "/browse"}}
|
||||
<a href="/browse" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Browse"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="2" width="20" height="20" rx="0" ry="0" />
|
||||
<line x1="7" y1="2" x2="7" y2="22" />
|
||||
<line x1="17" y1="2" x2="17" y2="22" />
|
||||
<line x1="2" y1="12" x2="22" y2="12" />
|
||||
<line x1="2" y1="7" x2="7" y2="7" />
|
||||
<line x1="2" y1="17" x2="7" y2="17" />
|
||||
<line x1="17" y1="17" x2="22" y2="17" />
|
||||
<line x1="17" y1="7" x2="22" y2="7" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Browse</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Discover */}}
|
||||
{{$isActive := eq $currentPath "/discover"}}
|
||||
<a href="/discover" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Discover"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Discover</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Schedule */}}
|
||||
{{$isActive := eq $currentPath "/schedule"}}
|
||||
<a href="/schedule" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Schedule"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Schedule</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Watchlist */}}
|
||||
{{$isActive := eq $currentPath "/watchlist"}}
|
||||
<a href="/watchlist" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Watchlist"{{end}} aria-current="{{if $isActive}}page{{end}}">
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-12 w-0.5 -translate-y-1/2 rounded-r-sm"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M17 18.113l-3.256-2.326A2.989 2.989 0 0 0 12 15.228c-.629 0-1.232.194-1.744.559L7 18.113V4h10v14.113zM18 2H6a1 1 0 0 0-1 1v17.056c0 .209.065.412.187.581a.994.994 0 0 0 1.394.233l4.838-3.455a1 1 0 0 1 1.162 0l4.838 3.455A1 1 0 0 0 19 20.056V3a1 1 0 0 0-1-1z" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Watchlist</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{range $navItems}}
|
||||
{{template "nav_item" dict "key" .key "href" .href "label" .label "isActive" .isActive "isCollapsed" $isCollapsed}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
{{end}}
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user