Files
sublogue/frontend/src/components/AppSidebar.svelte
T

157 lines
4.7 KiB
Svelte
Raw Normal View History

2026-01-17 21:49:22 +13:00
<script>
import { Button } from "../lib/components/ui/button";
import { Separator } from "../lib/components/ui/separator";
import { Badge } from "../lib/components/ui/badge";
import {
ChevronLeft,
ChevronRight,
Github,
Scan,
Settings,
2026-01-17 22:51:42 +13:00
History,
Library,
Zap,
2026-01-17 21:49:22 +13:00
} from "lucide-svelte";
import ThemeSelector from "./ThemeSelector.svelte";
2026-01-18 00:48:29 +13:00
import sublogueLogo from "../assets/sublogue_v2.png";
2026-01-17 21:49:22 +13:00
export let currentView = "scanner";
export let onNavigate;
export let onToggleSidebar;
export let open = true;
export let collapsed = false;
export let isMobile = false;
2026-02-28 21:48:25 +13:00
const navItems = [
{ id: "scanner", label: "Scanner", icon: Scan },
{ id: "automation", label: "Automations", icon: Zap },
{ id: "history", label: "History", icon: History },
{ id: "library", label: "Library", icon: Library },
{ id: "settings", label: "Settings", icon: Settings },
];
2026-01-17 21:49:22 +13:00
</script>
<aside
2026-02-28 21:48:25 +13:00
class={`fixed inset-y-0 left-0 z-40 h-screen w-[--sidebar-width] border-r border-border bg-[color:var(--bg-secondary)] text-text-primary transition-transform duration-200 ease-out md:sticky md:top-0 flex flex-col ${
2026-01-17 21:49:22 +13:00
!open && isMobile
? "-translate-x-full pointer-events-none"
: "translate-x-0"
}`}
>
2026-02-28 21:48:25 +13:00
<!-- Logo area -->
<div
class={`relative flex items-center gap-3 py-5 border-b border-border ${collapsed ? "px-2 justify-center" : "px-4"}`}
>
{#if collapsed}
<div class="h-8 w-8 rounded-lg overflow-hidden">
<img
src={sublogueLogo}
alt="Sublogue"
class="h-full w-full object-cover"
/>
</div>
{:else}
<div class="flex items-center -ml-5 flex-1 min-w-0">
<img
src={sublogueLogo}
alt="Sublogue"
class="h-8 w-auto max-w-[200px] object-contain"
/>
</div>
{/if}
<button
class="shrink-0 h-7 w-7 rounded-lg flex items-center justify-center text-text-tertiary hover:text-text-primary hover:bg-bg-hover transition-all duration-150"
on:click={onToggleSidebar}
aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"}
2026-01-17 21:49:22 +13:00
>
2026-01-18 00:48:29 +13:00
{#if collapsed}
2026-02-28 21:48:25 +13:00
<ChevronRight class="h-3.5 w-3.5" />
2026-01-18 00:48:29 +13:00
{:else}
2026-02-28 21:48:25 +13:00
<ChevronLeft class="h-3.5 w-3.5" />
2026-01-17 21:49:22 +13:00
{/if}
2026-02-28 21:48:25 +13:00
</button>
</div>
2026-01-17 21:49:22 +13:00
2026-02-28 21:48:25 +13:00
<!-- Navigation -->
<nav
class={`flex-1 min-h-0 overflow-y-auto py-3 space-y-0.5 ${collapsed ? "px-2" : "px-2"}`}
>
{#each navItems as item}
{@const isActive = currentView === item.id}
<button
class={`w-full flex items-center gap-2.5 rounded-lg text-[13px] font-medium transition-all duration-150 relative
${collapsed ? "justify-center px-0 h-9" : "px-3 h-9"}
${
isActive
? "bg-bg-hover text-text-primary"
: "text-text-secondary hover:text-text-primary hover:bg-bg-hover/60"
}`}
on:click={() => onNavigate(item.id)}
aria-current={isActive ? "page" : undefined}
2026-01-17 21:49:22 +13:00
>
2026-02-28 21:48:25 +13:00
{#if isActive && !collapsed}
<span
class="absolute left-0 top-1/2 -translate-y-1/2 h-4 w-0.5 rounded-full bg-accent"
></span>
2026-01-17 21:49:22 +13:00
{/if}
2026-02-28 21:48:25 +13:00
<svelte:component this={item.icon} class="h-4 w-4 shrink-0" />
2026-01-17 21:49:22 +13:00
{#if !collapsed}
2026-02-28 21:48:25 +13:00
<span>{item.label}</span>
2026-01-17 21:49:22 +13:00
{/if}
2026-02-28 21:48:25 +13:00
</button>
{/each}
</nav>
2026-01-17 21:49:22 +13:00
2026-02-28 21:48:25 +13:00
<!-- Footer -->
<div
class={`border-t border-border pb-4 pt-3 space-y-2 ${collapsed ? "px-2" : "px-2"}`}
>
{#if !collapsed}
<div class="px-1">
2026-01-17 21:49:22 +13:00
<ThemeSelector className="w-full" />
</div>
2026-02-28 21:48:25 +13:00
{/if}
<div
class={`flex items-center px-1 ${collapsed ? "justify-center" : "justify-between"}`}
>
{#if !collapsed}
<span class="text-[11px] text-text-tertiary"
>&copy; 2026 ponzischeme89</span
>
<div class="flex items-center gap-2">
<Badge
variant="outline"
class="text-[10px] text-text-tertiary border-border py-0"
>v1.1.4</Badge
>
<a
href="https://github.com/ponzischeme89/Sublogue"
target="_blank"
rel="noopener noreferrer"
2026-02-28 21:48:25 +13:00
class="text-text-tertiary hover:text-text-primary transition-colors"
aria-label="GitHub"
>
2026-02-28 21:48:25 +13:00
<Github class="h-3.5 w-3.5" />
</a>
2026-02-28 21:48:25 +13:00
</div>
{:else}
<a
href="https://github.com/ponzischeme89/Sublogue"
target="_blank"
rel="noopener noreferrer"
class="text-text-tertiary hover:text-text-primary transition-colors"
aria-label="GitHub"
>
<Github class="h-3.5 w-3.5" />
</a>
{/if}
2026-01-17 21:49:22 +13:00
</div>
</div>
</aside>
<style>
2026-02-28 21:48:25 +13:00
nav button {
2026-01-17 21:49:22 +13:00
letter-spacing: -0.01em;
}
</style>