refactor(admin): extract EntityNavSection to eliminate nav markup repetition (#197)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-15 13:54:42 +02:00
parent accfa5373e
commit fe6c247882
3 changed files with 365 additions and 385 deletions

View File

@@ -0,0 +1,90 @@
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
href: string;
label: string;
isActive: boolean;
count?: number;
topBorder?: boolean;
icon: Snippet;
variant?: 'sidebar' | 'flyout';
onTabletTrigger?: (event: MouseEvent) => void;
onFlyoutClick?: () => void;
}
let {
href,
label,
isActive,
count,
topBorder = false,
icon,
variant = 'sidebar',
onTabletTrigger,
onFlyoutClick
}: Props = $props();
</script>
{#if variant === 'sidebar'}
<!-- Tablet button (visible at md, hidden at lg) -->
<button
data-flyout-trigger
type="button"
aria-label={label}
title={label}
onclick={onTabletTrigger}
class="flex min-h-[44px] w-full flex-col items-center justify-center gap-0.5 border-l-[3px] py-3 transition-colors lg:hidden
{topBorder ? 'border-t border-white/10' : ''}
{isActive ? 'border-brand-mint bg-white/10' : (topBorder ? 'border-l-transparent hover:bg-white/5' : 'border-transparent hover:bg-white/5')}"
>
{@render icon()}
{#if count !== undefined}
<span class="text-[9px] font-bold {isActive ? 'text-white/80' : 'text-white/35'}"
>{count}</span
>
{/if}
</button>
<!-- Desktop link (hidden at md, visible at lg) -->
<a
href={href}
class="hidden flex-col items-start justify-center gap-0.5 border-l-[3px] px-3.5 py-2.5 transition-colors lg:flex
{topBorder ? 'border-t border-white/10' : ''}
{isActive ? 'border-brand-mint bg-white/10' : (topBorder ? 'border-l-transparent hover:bg-white/5' : 'border-transparent hover:bg-white/5')}"
aria-current={isActive ? 'page' : undefined}
title={label}
>
{@render icon()}
{#if count !== undefined}
<span class="text-[13px] font-black {isActive ? 'text-white/65' : 'text-white/50'}"
>{count}</span
>
{/if}
<span
class="text-[9px] font-extrabold tracking-[0.5px] uppercase {isActive ? 'text-white' : 'text-white/55'}"
>{label}</span
>
</a>
{:else}
<!-- Flyout link -->
<a
href={href}
onclick={onFlyoutClick}
class="flex flex-col items-start justify-center gap-0.5 border-l-[3px] px-3.5 py-2.5 transition-colors
{topBorder ? 'border-t border-white/10' : ''}
{isActive ? 'border-brand-mint bg-white/10' : (topBorder ? 'border-l-transparent hover:bg-white/5' : 'border-transparent hover:bg-white/5')}"
aria-current={isActive ? 'page' : undefined}
>
{@render icon()}
{#if count !== undefined}
<span class="text-[13px] font-black {isActive ? 'text-white/65' : 'text-white/50'}"
>{count}</span
>
{/if}
<span
class="text-[9px] font-extrabold tracking-[0.5px] uppercase {isActive ? 'text-white' : 'text-white/55'}"
>{label}</span
>
</a>
{/if}