# Library dashboard

A shadcn/ui block from the [@watermelon](https://ui.watermelon.sh) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/watermelon/library-dashboard).

- Page, with a live preview: https://shadcn.exchange/r/watermelon/library-dashboard
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/watermelon/library-dashboard-light-3b4579a476dce1da.png
- Registry item: https://registry.watermelon.sh/r/library-dashboard.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://registry.watermelon.sh/r/library-dashboard.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`, `recharts`
- Registry items: `button`, `card`, `chart`, `dropdown-menu`, `input-group`, `sheet`, `sidebar`, `tooltip`, `utils`

## Files

### `src/components/dashboards/library-dashboard/components/library/circulation-chart.tsx`

```tsx
'use client';

import { Calendar } from 'lucide-react';
import { useId, useState } from 'react';
import {
  Area,
  AreaChart,
  CartesianGrid,
  Line,
  ReferenceLine,
  XAxis,
} from 'recharts';

import { buttonVariants } from '@/components/ui/button';
import { ArrowDown01Icon } from './icons';
import {
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
} from '@/components/ui/chart';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { circulationData } from '../../data';
import { cn } from '@/lib/utils';

type CirculationTimeframe = 'weekly' | 'monthly' | 'yearly';

type CirculationDataPoint = {
  timestamp: number;
  checkouts: number;
  returns: number;
};

const circulationChartConfig = {
  checkouts: {
    label: 'Checkouts',
    color: 'var(--primary)',
  },
  returns: {
    label: 'Returns',
    color: 'color-mix(in oklch, var(--primary) 55%, black)',
  },
} satisfies ChartConfig;

const chartTicks: Record<CirculationTimeframe, number[]> = {
  weekly: circulationData.weekly.map((point) => point.timestamp),
  monthly: [0, 7, 14, 21].map(
    (dayIndex) => circulationData.monthly[dayIndex].timestamp,
  ),
  yearly: circulationData.yearly
    .filter((_, month) => month % 2 === 0)
    .map((point) => point.timestamp),
};

const chartDomains: Record<CirculationTimeframe, [number, number]> = {
  weekly: [
    circulationData.weekly[0].timestamp,
    circulationData.weekly[circulationData.weekly.length - 1].timestamp,
  ],
  monthly: [
    circulationData.monthly[0].timestamp,
    circulationData.monthly[circulationData.monthly.length - 1].timestamp,
  ],
  yearly: [
    circulationData.yearly[0].timestamp,
    circulationData.yearly[circulationData.yearly.length - 1].timestamp,
  ],
};

const chartMidpoints: Record<CirculationTimeframe, number[]> = {
  weekly: getMidpoints(chartTicks.weekly, chartDomains.weekly[1]),
  monthly: getMidpoints(chartTicks.monthly, chartDomains.monthly[1]),
  yearly: getMidpoints(chartTicks.yearly, chartDomains.yearly[1]),
};

function getMidpoints(ticks: number[], domainEnd: number) {
  const points = ticks.at(-1) === domainEnd ? ticks : [...ticks, domainEnd];

  return points.slice(0, -1).map((tick, index) => {
    return tick + (points[index + 1] - tick) / 2;
  });
}

const shortWeekdayFormatter = new Intl.DateTimeFormat('en-US', {
  weekday: 'short',
  timeZone: 'UTC',
});
const shortDateFormatter = new Intl.DateTimeFormat('en-US', {
  month: 'short',
  day: 'numeric',
  timeZone: 'UTC',
});
const shortMonthFormatter = new Intl.DateTimeFormat('en-US', {
  month: 'short',
  timeZone: 'UTC',
});

const chartFormatters: Record<CirculationTimeframe, (value: number) => string> =
  {
    weekly: (value) => shortWeekdayFormatter.format(value),
    monthly: (value) => shortDateFormatter.format(value),
    yearly: (value) => shortMonthFormatter.format(value),
  };

const weeklyTooltipFormatter = new Intl.DateTimeFormat('en-US', {
  weekday: 'short',
  month: 'short',
  day: 'numeric',
  year: 'numeric',
  timeZone: 'UTC',
});
const datedTooltipFormatter = new Intl.DateTimeFormat('en-US', {
  month: 'short',
  day: 'numeric',
  year: 'numeric',
  timeZone: 'UTC',
});
const monthlyTooltipFormatter = new Intl.DateTimeFormat('en-US', {
  month: 'long',
  year: 'numeric',
  timeZone: 'UTC',
});

function formatTooltipDate(timeframe: CirculationTimeframe, value: number) {
  if (timeframe === 'weekly') return weeklyTooltipFormatter.format(value);
  if (timeframe === 'monthly') return datedTooltipFormatter.format(value);
  return monthlyTooltipFormatter.format(value);
}

export function CirculationChart() {
  const [timeframe, setTimeframe] = useState<CirculationTimeframe>('weekly');
  const [activeLabel, setActiveLabel] = useState<number | null>(null);
  const gradientId = useId().replace(/:/g, '');

  return (
    <div className="flex h-full flex-col">
      <div className="flex w-full items-center justify-between">
        <h2 className="text-lg font-medium">Collection Circulation</h2>
        <DropdownMenu>
          <DropdownMenuTrigger
            className={cn(
              buttonVariants({ variant: 'ghost', size: 'lg' }),
              'text-accent-foreground capitalize',
            )}
          >
            {timeframe}
            <ArrowDown01Icon className="size-4" />
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" className="w-32 p-1.5 shadow-lg">
            <DropdownMenuGroup>
              {(['weekly', 'monthly', 'yearly'] as const).map((option) => (
                <DropdownMenuItem
                  key={option}
                  onClick={() => setTimeframe(option)}
                  className={cn(
                    'rounded-lg capitalize',
                    timeframe === option && 'text-primary font-medium',
                  )}
                >
                  {option}
                </DropdownMenuItem>
              ))}
            </DropdownMenuGroup>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>

      <ChartContainer
        config={circulationChartConfig}
        className="mt-5 aspect-auto h-72 w-full grow [&_.recharts-surface]:overflow-visible"
        onMouseDown={(event) => event.preventDefault()}
      >
        <AreaChart
          data={circulationData[timeframe]}
          accessibilityLayer={false}
          margin={{ left: 4, right: 4, top: 12, bottom: 4 }}
          style={{ overflow: 'visible' }}
          onMouseMove={(state) => {
            const label = state?.activeLabel;
            setActiveLabel(
              typeof label === 'number'
                ? label
                : label != null
                  ? Number(label)
                  : null,
            );
          }}
          onMouseLeave={() => setActiveLabel(null)}
        >
          <defs>
            <linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="var(--primary)" stopOpacity={0.18} />
              <stop
                offset="95%"
                stopColor="var(--primary)"
                stopOpacity={0.02}
              />
            </linearGradient>
          </defs>
          <CartesianGrid
            vertical
            horizontal={false}
            stroke="var(--border)"
            strokeDasharray="0"
          />
          {chartMidpoints[timeframe].map((midpoint) => (
            <ReferenceLine
              key={midpoint}
              x={midpoint}
              stroke="var(--border)"
              strokeDasharray="6 6"
            />
          ))}
          <XAxis
            dataKey="timestamp"
            type="number"
            domain={chartDomains[timeframe]}
            stroke="var(--muted-foreground)"
            fontSize={14}
            tickLine={false}
            axisLine={false}
            ticks={chartTicks[timeframe]}
            minTickGap={0}
            interval={0}
            padding={{ left: 0, right: 0 }}
            tick={({ x, y, payload }) => {
              const isActive = activeLabel === payload.value;
              return (
                <text
                  x={x}
                  y={y}
                  dy={14}
                  fill={
                    isActive
                      ? 'var(--secondary-foreground)'
                      : 'var(--muted-foreground)'
                  }
                  fontSize={14}
                  textAnchor="middle"
                  className="font-medium"
                >
                  {chartFormatters[timeframe](payload.value)}
                </text>
              );
            }}
          />
          <ChartTooltip
            cursor={{
              stroke: 'var(--primary)',
              strokeWidth: 1.5,
            }}
            content={({ active, payload }) => {
              if (!active || !payload?.length) return null;

              const point = payload[0].payload as CirculationDataPoint;

              return (
                <div className="bg-foreground text-background z-50 flex min-w-40 flex-col rounded-[6px] shadow-[0px_6px_14px_rgba(24,39,75,0.12),0px_10px_32px_rgba(24,39,75,0.1)]">
                  <div className="flex items-center gap-1 px-2.5 py-1.5">
                    <Calendar className="size-3 opacity-80" />
                    <span className="text-[9px] tracking-tight opacity-90">
                      {formatTooltipDate(timeframe, point.timestamp)}
                    </span>
                  </div>
                  <div className="flex flex-col gap-2 px-2 pb-2">
                    <div className="flex items-center justify-between gap-4">
                      <div className="flex items-center gap-1">
                        <span className="bg-primary size-1.5 shrink-0 rounded-[1px]" />
                        <span className="text-[10px] leading-[1.2] opacity-80">
                          Checkouts
                        </span>
                      </div>
                      <span className="text-[10px] leading-[1.2] font-medium">
                        {point.checkouts.toLocaleString()}
                      </span>
                    </div>
                    <div className="flex items-center justify-between gap-4">
                      <div className="flex items-center gap-1">
                        <span className="bg-primary/60 size-1.5 shrink-0 rounded-[1px]" />
                        <span className="text-[10px] leading-[1.2] opacity-80">
                          Returns
                        </span>
                      </div>
                      <span className="text-[10px] leading-[1.2] font-medium">
                        {point.returns.toLocaleString()}
                      </span>
                    </div>
                  </div>
                </div>
              );
            }}
          />
          <Area
            type="linear"
            dataKey="checkouts"
            stroke="var(--primary)"
            strokeWidth={1.75}
            fillOpacity={1}
            fill={`url(#${gradientId})`}
            dot={false}
            activeDot={{
              r: 4,
              stroke: 'var(--primary)',
              strokeWidth: 2,
              fill: 'var(--card)',
            }}
          />
          <Line
            type="linear"
            dataKey="returns"
            stroke="color-mix(in oklch, var(--primary) 55%, black)"
            strokeWidth={1.5}
            dot={false}
            activeDot={{
              r: 4,
              stroke: 'color-mix(in oklch, var(--primary) 55%, black)',
              strokeWidth: 2,
              fill: 'var(--card)',
            }}
          />
        </AreaChart>
      </ChartContainer>
    </div>
  );
}
```

### `src/components/dashboards/library-dashboard/components/library/collection-donut-chart.tsx`

```tsx
'use client';

import { useState } from 'react';
import { Cell, Pie, PieChart, Tooltip } from 'recharts';

export type CollectionDonutDatum = {
  name: string;
  value: number;
  fill: string;
};

type CollectionDonutChartProps = {
  data: CollectionDonutDatum[];
  total: number;
  label: string;
  size?: number;
  activeIndex?: number | null;
  onActiveIndexChange?: (index: number | null) => void;
};

export function CollectionDonutChart({
  data,
  total,
  label,
  size = 180,
  activeIndex: activeIndexProp,
  onActiveIndexChange,
}: CollectionDonutChartProps) {
  const [uncontrolledActiveIndex, setUncontrolledActiveIndex] = useState<
    number | null
  >(null);
  const isControlled = activeIndexProp !== undefined;
  const activeIndex = isControlled ? activeIndexProp : uncontrolledActiveIndex;
  const setActiveIndex = (index: number | null) => {
    if (!isControlled) setUncontrolledActiveIndex(index);
    onActiveIndexChange?.(index);
  };

  const activeDatum = activeIndex !== null ? data[activeIndex] : null;
  const displayValue = activeDatum ? activeDatum.value : total;
  const displayLabel = activeDatum ? activeDatum.name : label;

  const center = size / 2;
  // Thin deep outer rim + thicker lighter body (proportions from data values)
  const deepOuter = center - 1;
  const deepInner = deepOuter - 8;
  const lightOuter = deepInner;
  const lightInner = deepOuter - 31;
  const paddingAngle = 2.5;
  const animationDuration = 800;

  return (
    <div
      className="relative shrink-0"
      style={{ width: size, height: size }}
      onMouseDown={(event) => event.preventDefault()}
    >
      <PieChart
        width={size}
        height={size}
        margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
      >
        {/* Thick lighter inner body */}
        <Pie
          data={data}
          cx={center}
          cy={center}
          dataKey="value"
          innerRadius={lightInner}
          outerRadius={lightOuter}
          paddingAngle={paddingAngle}
          startAngle={90}
          endAngle={-270}
          stroke="none"
          isAnimationActive
          animationBegin={0}
          animationDuration={animationDuration}
          onMouseEnter={(_, index) => setActiveIndex(index)}
          onMouseLeave={() => setActiveIndex(null)}
        >
          {data.map((entry, index) => (
            <Cell
              key={`light-${index}`}
              fill={entry.fill}
              fillOpacity={0.45}
              opacity={activeIndex === null || activeIndex === index ? 1 : 0.4}
              style={{ transition: 'opacity 200ms ease-in-out' }}
            />
          ))}
        </Pie>

        {/* Thin deep outer strip — same data/angles as inner */}
        <Pie
          data={data}
          cx={center}
          cy={center}
          dataKey="value"
          innerRadius={deepInner}
          outerRadius={deepOuter}
          paddingAngle={paddingAngle}
          startAngle={90}
          endAngle={-270}
          stroke="none"
          isAnimationActive
          animationBegin={0}
          animationDuration={animationDuration}
          pointerEvents="none"
        >
          {data.map((entry, index) => (
            <Cell
              key={`deep-${index}`}
              fill={entry.fill}
              opacity={activeIndex === null || activeIndex === index ? 1 : 0.4}
              style={{ transition: 'opacity 200ms ease-in-out' }}
            />
          ))}
        </Pie>
        <Tooltip content={() => null} cursor={false} />
      </PieChart>

      <div
        className="pointer-events-none absolute flex flex-col items-center justify-center text-center"
        style={{
          width: lightInner * 2,
          height: lightInner * 2,
          top: center - lightInner,
          left: center - lightInner,
        }}
      >
        <div
          key={displayLabel}
          aria-live="polite"
          className="animate-in fade-in slide-in-from-bottom-1 animation-duration-300 flex flex-col items-center gap-0.5"
        >
          <span className="text-foreground text-[23px] leading-normal font-medium tracking-[-0.02em]">
            {displayValue.toLocaleString()}
          </span>
          <span className="text-accent-foreground text-xs leading-[1.45]">
            {displayLabel}
          </span>
        </div>
      </div>
    </div>
  );
}
```

### `src/components/dashboards/library-dashboard/components/library/dashboard-content.tsx`

```tsx
import { useState } from 'react';
import { CirculationChart } from './circulation-chart';
import { CollectionDonutChart } from './collection-donut-chart';
import {
  ArrowDown01Icon,
  BookPlusIcon,
  CancelIcon,
  CheckoutIcon,
  Download01Icon,
  ReturnIcon,
  SparklesIcon,
  UserAdd02Icon,
} from './icons';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import {
  collectionOverview,
  intelligenceCards,
  metrics,
  recentActivity,
} from '../../data';
import { cn } from '@/lib/utils';

const quickActions = [
  { label: 'Checkout Items', icon: CheckoutIcon },
  { label: 'Process Return', icon: ReturnIcon },
  { label: 'Add New Item', icon: BookPlusIcon },
  { label: 'Add New Member', icon: UserAdd02Icon },
];

export function DashboardContent() {
  return (
    <>
      <DashboardHeader />
      <div className="@container/dashboard space-y-10">
        <section>
          <SectionTitle>Top Metrics</SectionTitle>
          <div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
            {metrics.map((metric) => (
              <MetricCard key={metric.label} {...metric} />
            ))}
          </div>
        </section>

        <section>
          <SectionTitle>Quick Actions</SectionTitle>
          <div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
            {quickActions.map((action) => (
              <Card
                key={action.label}
                className="bg-secondary text-secondary-foreground cursor-pointer rounded-lg py-0 shadow-none ring-0 transition-colors hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]"
              >
                <CardContent className="flex h-full items-center justify-between p-3">
                  <div className="flex items-center gap-2">
                    <div className="bg-background flex size-11 items-center justify-center rounded-lg">
                      <action.icon className="size-5" />
                    </div>
                    <span className="text-secondary-foreground/80 text-base font-medium">
                      {action.label}
                    </span>
                  </div>
                  <ArrowDown01Icon className="text-muted-foreground size-6 -rotate-90 transition-transform duration-200 ease-out group-hover/card:translate-x-0.5 motion-reduce:transform-none" />
                </CardContent>
              </Card>
            ))}
          </div>
        </section>

        <section className="grid grid-cols-1 items-stretch gap-8 @4xl/dashboard:grid-cols-3">
          <div className="@4xl/dashboard:col-span-2">
            <CirculationChart />
          </div>
          <div className="min-h-84">
            <CollectionOverview />
          </div>
        </section>

        <section className="grid grid-cols-1 gap-8 @4xl/dashboard:grid-cols-2">
          <RecentActivity />
          <LibraryIntelligence />
        </section>
      </div>
    </>
  );
}

function SectionTitle({ children }: { children: React.ReactNode }) {
  return <h2 className="text-lg font-medium">{children}</h2>;
}

function DashboardHeader() {
  return (
    <div className="mb-6 flex flex-col items-start justify-between gap-4 sm:mb-10 sm:flex-row sm:items-end">
      <div className="flex flex-col gap-2">
        <h1 className="text-xl leading-[1.4] font-medium italic">
          Good Morning Librarian
        </h1>
        <div className="flex flex-col gap-2 text-base leading-[1.4] sm:flex-row sm:items-center">
          <p className="text-muted-foreground italic">
            Springfield Public Library
          </p>
          <div className="bg-foreground hidden size-1.5 rounded-full sm:inline-block" />
          <p className="text-secondary-foreground/80">Saturday, Feb 19, 2026</p>
        </div>
      </div>
      <Button
        variant="secondary"
        className="h-11 gap-3 pr-3 pl-4.5 text-[15px] font-medium tracking-[-0.02em]"
      >
        <span>Export</span>
        <Download01Icon className="size-5 -scale-y-100" />
      </Button>
    </div>
  );
}

function MetricCard({
  icon: Icon,
  iconClassName,
  label,
  note,
  noteIcon: NoteIcon,
  value,
}: {
  label: string;
  value: string;
  note: string;
  icon: React.ComponentType<{ className?: string }>;
  iconClassName: string;
  noteIcon?: React.ComponentType<{ className?: string }>;
}) {
  const noteParts = note.match(/^([+-]?\d+(?:\.\d+)?%?|↓\s*\d+)\s+(.*)$/);

  return (
    <Card className="bg-secondary text-secondary-foreground gap-6 rounded-lg p-4 shadow-none ring-0">
      <div className="flex items-center gap-2">
        <Icon className={cn('size-5 shrink-0', iconClassName)} />
        <span className="text-secondary-foreground/80 text-sm leading-[1.4] font-medium">
          {label}
        </span>
      </div>
      <div className="flex flex-col gap-3">
        <h3 className="text-foreground text-[32px] leading-none font-medium">
          {value}
        </h3>
        <p className="flex items-center gap-1 text-xs">
          {NoteIcon && <NoteIcon className="size-3.5 shrink-0" />}
          {noteParts ? (
            <>
              <span className="text-secondary-foreground font-medium">
                {noteParts[1]}
              </span>{' '}
              <span className="text-muted-foreground">{noteParts[2]}</span>
            </>
          ) : (
            <span className="text-muted-foreground">{note}</span>
          )}
        </p>
      </div>
    </Card>
  );
}

function CollectionOverview() {
  const [activeIndex, setActiveIndex] = useState<number | null>(null);
  const total = collectionOverview.segments.reduce(
    (sum, segment) => sum + segment.count,
    0,
  );
  const segments = collectionOverview.segments.map((segment) => ({
    ...segment,
    percentage: total > 0 ? (segment.count / total) * 100 : 0,
  }));
  const chartData = segments.map((segment) => ({
    name: segment.label,
    value: segment.count,
    fill: segment.color,
  }));

  return (
    <div className="flex h-full flex-col">
      <SectionTitle>Collection Overview</SectionTitle>
      <Card className="border-border mt-5 flex flex-1 flex-col rounded-lg border py-0 shadow-none ring-0">
        <CardContent className="flex h-full flex-col items-center justify-between gap-5 p-4 sm:flex-row sm:items-center sm:gap-8 sm:px-8 @4xl/dashboard:flex-col @4xl/dashboard:gap-5 @4xl/dashboard:px-4">
          <CollectionDonutChart
            data={chartData}
            total={total}
            label={collectionOverview.label}
            size={180}
            activeIndex={activeIndex}
            onActiveIndexChange={setActiveIndex}
          />
          <div className="flex w-full flex-col gap-2 sm:max-w-64 @4xl/dashboard:max-w-none">
            {segments.map((segment, index) => (
              <div
                key={segment.label}
                className={cn(
                  'text-secondary-foreground grid grid-cols-3 items-center text-base leading-[1.4] transition-opacity duration-200',
                  activeIndex !== null && activeIndex !== index && 'opacity-40',
                )}
              >
                <div className="text-secondary-foreground/80 flex min-w-0 items-center gap-2">
                  <span
                    className="size-3.5 shrink-0 rounded"
                    style={{ backgroundColor: segment.color }}
                  />
                  <span className="truncate">{segment.label}</span>
                </div>
                <span className="text-center font-medium tabular-nums">
                  {segment.count.toLocaleString()}
                </span>
                <span className="text-right font-medium tabular-nums">
                  {segment.percentage % 1 === 0
                    ? `${segment.percentage.toFixed(0)}%`
                    : `${segment.percentage.toFixed(1)}%`}
                </span>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

function RecentActivity() {
  return (
    <div>
      <SectionTitle>Recent Activity</SectionTitle>
      <div className="mt-5 flex flex-col gap-6">
        {recentActivity.map((activity) => {
          const ActivityIcon = activity.icon;
          return (
            <div key={activity.id} className="flex items-center gap-3">
              <div className="bg-secondary text-secondary-foreground flex size-11 shrink-0 items-center justify-center rounded-lg">
                <ActivityIcon className="size-5" />
              </div>
              <div className="flex min-w-0 flex-1 items-start justify-between gap-3">
                <p className="text-base leading-[1.4]">
                  {activity.parts.map((part, index) => (
                    <span
                      key={`${activity.id}-${index}`}
                      className={cn(
                        'text-secondary-foreground font-medium',
                        'muted' in part &&
                          part.muted &&
                          'text-muted-foreground font-normal',
                      )}
                    >
                      {part.text}
                    </span>
                  ))}
                </p>
                <time
                  dateTime={activity.dateTime}
                  className="text-secondary-foreground/80 shrink-0 text-sm leading-4 font-medium"
                >
                  {activity.time}
                </time>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function LibraryIntelligence() {
  return (
    <div className="flex h-full flex-col">
      <div className="flex items-center justify-between gap-2">
        <SectionTitle>Library Intelligence</SectionTitle>
        <Button
          variant="ghost"
          size="sm"
          className="text-accent-foreground h-auto gap-1 bg-transparent px-0 py-0 hover:bg-transparent dark:hover:bg-transparent"
        >
          <span className="text-sm font-normal">See all</span>
          <ArrowDown01Icon className="size-4 -rotate-90 transition-transform duration-200 ease-out group-hover/button:translate-x-0.5 motion-reduce:transform-none" />
        </Button>
      </div>
      <div className="mt-5 flex flex-1 flex-col justify-between gap-3">
        {intelligenceCards.map((card) => (
          <Card
            key={card.title}
            className="bg-secondary text-secondary-foreground rounded-lg py-0 shadow-none ring-0"
          >
            <CardContent className="flex flex-col gap-3 p-3">
              <div className="flex items-center justify-between">
                <div
                  className={cn(
                    'flex items-center gap-1 text-sm font-semibold',
                    card.tone === 'insight' && 'text-[#c803c8]',
                    card.tone === 'warning' && 'text-[#d47c01]',
                    card.tone === 'success' && 'text-[#15823e]',
                  )}
                >
                  <SparklesIcon className="size-5" />
                  <span>{card.title}</span>
                </div>
                <Button
                  aria-label={`Dismiss ${card.title}`}
                  variant="ghost"
                  size="icon-xs"
                  className="size-5"
                >
                  <CancelIcon className="size-5" />
                </Button>
              </div>
              <div className="flex items-end gap-3">
                <p className="flex-1 text-base leading-[1.4] text-[#4a5565]">
                  {card.bodyParts.map((part, index) => (
                    <span
                      key={`${card.title}-${index}`}
                      className={cn(
                        'emphasis' in part &&
                          part.emphasis &&
                          'text-secondary-foreground font-medium',
                      )}
                    >
                      {part.text}
                    </span>
                  ))}
                </p>
                <Button
                  variant="ghost"
                  size="sm"
                  className="bg-background text-secondary-foreground/80 h-8 gap-2 rounded-lg px-0 pr-2 pl-3 text-[15px] font-medium tracking-[-0.02em] hover:bg-[color-mix(in_oklch,var(--background),var(--foreground)_5%)]"
                >
                  <span>View</span>
                  <ArrowDown01Icon className="size-4 -rotate-90 transition-transform duration-200 ease-out group-hover/button:translate-x-0.5 motion-reduce:transform-none" />
                </Button>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}
```

### `src/components/dashboards/library-dashboard/components/library/icons.tsx`

```tsx
import type { SVGProps } from "react"

export type IconProps = SVGProps<SVGSVGElement>

export function AiIdeaIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M15.8333 8.01724C15.8333 10.1666 14.7752 11.821 13.1652 12.9098C12.7902 13.1633 12.6027 13.2902 12.5102 13.4343C12.4177 13.5785 12.3861 13.7678 12.323 14.1464L12.2739 14.4407C12.1631 15.1058 12.1077 15.4383 11.8745 15.6358C11.6414 15.8333 11.3043 15.8333 10.6299 15.8333H8.45367C7.7794 15.8333 7.44224 15.8333 7.20913 15.6358C6.976 15.4383 6.92058 15.1058 6.80972 14.4407L6.76067 14.1464C6.69778 13.7691 6.66634 13.5804 6.57473 13.4369C6.48313 13.2934 6.29523 13.165 5.91943 12.9081C4.32658 11.8193 3.33333 10.1655 3.33333 8.01724C3.33333 4.50992 6.13155 1.66667 9.58333 1.66667C10.0114 1.66667 10.4294 1.7104 10.8333 1.7937"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M13.75 1.66667L13.9649 2.24753C14.2468 3.00918 14.3877 3.39002 14.6655 3.66783C14.9433 3.94564 15.3242 4.08656 16.0858 4.3684L16.6667 4.58333L16.0858 4.79827C15.3242 5.0801 14.9433 5.22103 14.6655 5.49884C14.3877 5.77665 14.2468 6.15748 13.9649 6.91914L13.75 7.5L13.5351 6.91914C13.2532 6.15748 13.1123 5.77665 12.8345 5.49884C12.5567 5.22103 12.1758 5.0801 11.4142 4.79827L10.8333 4.58333L11.4142 4.3684C12.1758 4.08656 12.5567 3.94564 12.8345 3.66783C13.1123 3.39002 13.2532 3.00918 13.5351 2.24753L13.75 1.66667Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinejoin="round"
      />
      <path
        d="M11.25 15.8333V16.6667C11.25 17.4523 11.25 17.8452 11.0059 18.0892C10.7618 18.3333 10.369 18.3333 9.58333 18.3333C8.79767 18.3333 8.40483 18.3333 8.16074 18.0892C7.91667 17.8452 7.91667 17.4523 7.91667 16.6667V15.8333"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function Alert02Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M11.604 17.5H8.396C4.5373 17.5 2.60796 17.5 1.89697 16.2449C1.18598 14.9899 2.1728 13.3262 4.14645 9.99875L5.75048 7.29444C7.64633 4.09815 8.59425 2.5 10 2.5C11.4058 2.5 12.3537 4.09814 14.2495 7.29443L15.8536 9.99875C17.8272 13.3262 18.814 14.9899 18.103 16.2449C17.392 17.5 15.4627 17.5 11.604 17.5Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10 7.5V11.25"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10 14.1602V14.1685"
        stroke="currentColor"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function ArrowDown01Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" {...props}>
      <path
        d="M18 9.00005C18 9.00005 13.5811 15 12 15C10.4188 15 6 9 6 9"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.5"
      />
    </svg>
  )
}

export function ArrowDown02Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 14 14" fill="none" aria-hidden="true" {...props}>
      <path
        d="M7 10.7928V2.91781"
        stroke="currentColor"
        strokeWidth="0.875"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10.5 7.58447C10.5 7.58447 7.92231 11.0844 7 11.0845C6.07763 11.0845 3.5 7.58447 3.5 7.58447"
        stroke="currentColor"
        strokeWidth="0.875"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function ArrowDownIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 16 16" fill="none" aria-hidden="true" {...props}>
      <path
        d="M12 6C12 6 9.05407 10 8 10C6.94587 10 4 6 4 6"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function BackwardIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 48 48" fill="none" aria-hidden="true" {...props}>
      <path
        d="M39 9L24 24L39 39"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="4"
      />
      <path
        d="M24 9L9 24L24 39"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="4"
      />
    </svg>
  )
}

export function BellIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M7.5 15C7.5 15.663 7.76339 16.2989 8.23223 16.7678C8.70107 17.2366 9.33696 17.5 10 17.5C10.663 17.5 11.2989 17.2366 11.7678 16.7678C12.2366 16.2989 12.5 15.663 12.5 15"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M4.37499 8.125C4.37499 6.63316 4.96763 5.20242 6.02252 4.14752C7.07741 3.09263 8.50815 2.5 9.99999 2.5C11.4918 2.5 12.9226 3.09263 13.9775 4.14752C15.0324 5.20242 15.625 6.63316 15.625 8.125C15.625 10.9234 16.2734 13.1719 16.7891 14.0625C16.8438 14.1574 16.8727 14.2649 16.8728 14.3745C16.8729 14.484 16.8442 14.5916 16.7896 14.6865C16.735 14.7815 16.6564 14.8604 16.5617 14.9154C16.467 14.9705 16.3595 14.9996 16.25 15H3.74999C3.6406 14.9993 3.5333 14.97 3.43881 14.9149C3.34432 14.8597 3.26596 14.7808 3.21155 14.6859C3.15714 14.591 3.12859 14.4835 3.12875 14.3741C3.12892 14.2647 3.1578 14.1572 3.21249 14.0625C3.72734 13.1719 4.37499 10.9227 4.37499 8.125Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function BookMinusIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M16.25 15C16.25 15 15.4167 15.6357 15.4167 16.6667C15.4167 17.6977 16.25 18.3333 16.25 18.3333"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M12.9215 8.32845H7.08822"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M16.6667 18.3333H5C4.07952 18.3333 3.33333 17.5872 3.33333 16.6667M3.33333 16.6667C3.33333 15.7462 4.07952 15 5 15H16.6667V5C16.6667 3.42865 16.6667 2.64297 16.1785 2.15482C15.6903 1.66667 14.9047 1.66667 13.3333 1.66667H8.33333C5.97631 1.66667 4.7978 1.66667 4.06557 2.3989C3.33333 3.13113 3.33333 4.30964 3.33333 6.66667V16.6667Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function BookOpen02Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M14.5879 1.68229C10.6908 2.36213 10 6.25 10 6.25V18.3333C10 18.3333 10.7389 14.2727 15.0003 13.799C15.4578 13.7482 15.8333 13.3813 15.8333 12.9215V2.82758C15.8333 2.13784 15.268 1.56365 14.5879 1.68229Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M4.44444 4.16667C6.49482 4.16381 8.47375 4.90591 10 6.25V18.3333C8.47375 16.9893 6.49482 16.2472 4.44444 16.25C3.14277 16.25 2.49193 16.25 2.20438 16.066C2.03175 15.9555 1.96122 15.8849 1.85072 15.7123C1.66667 15.4248 1.66667 14.9118 1.66667 13.8858V7.00268C1.66667 5.81286 1.66667 5.21795 2.12395 4.73572C2.58123 4.25348 3.04936 4.2286 3.9856 4.17883C4.1375 4.17076 4.29048 4.16667 4.44444 4.16667Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10 18.3342C11.5263 16.9901 13.5052 16.248 15.5556 16.2508C16.8573 16.2508 17.5081 16.2508 17.7956 16.0668C17.9682 15.9563 18.0388 15.8858 18.1493 15.7132C18.3333 15.4256 18.3333 14.9126 18.3333 13.8866V7.00353C18.3333 5.81371 18.3333 5.2188 17.8761 4.73657C17.4187 4.25433 16.7696 4.21643 15.8333 4.16667"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function BookPlusIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M16.25 15C16.25 15 15.4167 15.6357 15.4167 16.6667C15.4167 17.6977 16.25 18.3333 16.25 18.3333"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M10 5.41667V11.25M12.9215 8.32848H7.08822"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M16.6667 18.3333H5C4.07952 18.3333 3.33333 17.5872 3.33333 16.6667M3.33333 16.6667C3.33333 15.7462 4.07952 15 5 15H16.6667V5C16.6667 3.42865 16.6667 2.64297 16.1785 2.15482C15.6903 1.66667 14.9047 1.66667 13.3333 1.66667H8.33333C5.97631 1.66667 4.7978 1.66667 4.06557 2.3989C3.33333 3.13113 3.33333 4.30964 3.33333 6.66667V16.6667Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function BuildingIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" {...props}>
      <path
        d="M2 22H22"
        stroke="white"
        strokeLinecap="round"
        strokeWidth="1.5"
      />
      <path
        d="M18 9H14C11.518 9 11 9.518 11 12V22H21V12C21 9.518 20.482 9 18 9Z"
        stroke="white"
        strokeLinejoin="round"
        strokeWidth="1.5"
      />
      <path
        d="M15 22H3V5C3 2.518 3.518 2 6 2H12C14.482 2 15 2.518 15 5V9"
        stroke="white"
        strokeLinejoin="round"
        strokeWidth="1.5"
      />
      <path
        d="M3 6H6M3 10H6M3 14H6"
        stroke="white"
        strokeLinecap="round"
        strokeWidth="1.5"
      />
      <path
        d="M15 13H17M15 16H17"
        stroke="white"
        strokeLinecap="round"
        strokeWidth="1.5"
      />
      <path
        d="M16 22V19"
        stroke="white"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.5"
      />
    </svg>
  )
}

export function CancelIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M15 5L5.00068 14.9993M14.9993 15L5 5.00071"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function CatalogIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M1.66663 5.83333C1.66663 4.66656 1.66663 4.08317 1.89369 3.63752C2.09343 3.24552 2.41214 2.92681 2.80414 2.72707C3.24979 2.5 3.83318 2.5 4.99996 2.5C6.16673 2.5 6.75013 2.5 7.19578 2.72707C7.58778 2.92681 7.90648 3.24552 8.10623 3.63752C8.33329 4.08317 8.33329 4.66656 8.33329 5.83333V14.1667C8.33329 15.3334 8.33329 15.9168 8.10623 16.3625C7.90648 16.7545 7.58778 17.0732 7.19578 17.2729C6.75013 17.5 6.16673 17.5 4.99996 17.5C3.83318 17.5 3.24979 17.5 2.80414 17.2729C2.41214 17.0732 2.09343 16.7545 1.89369 16.3625C1.66663 15.9168 1.66663 15.3334 1.66663 14.1667V5.83333Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M5 14.1667H5.00748"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.66667"
      />
      <path
        d="M1.66663 5.83334H8.33329"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M9.54045 6.89036C9.2447 5.78198 9.09687 5.2278 9.1987 4.74666C9.28828 4.32343 9.50895 3.93956 9.8292 3.65004C10.1932 3.3209 10.7451 3.17241 11.8489 2.87542C12.9526 2.57843 13.5045 2.42994 13.9836 2.53221C14.4051 2.62217 14.7874 2.8438 15.0757 3.16534C15.4035 3.53088 15.5514 4.08507 15.8471 5.19344L17.9594 13.1097C18.2552 14.218 18.403 14.7722 18.3012 15.2533C18.2116 15.6766 17.991 16.0604 17.6707 16.35C17.3067 16.6791 16.7548 16.8276 15.651 17.1246C14.5473 17.4216 13.9954 17.5701 13.5163 17.4678C13.0948 17.3778 12.7125 17.1562 12.4242 16.8347C12.0964 16.4691 11.9485 15.9149 11.6528 14.8066L9.54045 6.89036Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M14.8177 13.9127L14.825 13.9108"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.66667"
      />
      <path
        d="M10 6.66682L15.4167 5"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function CheckoutIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M3.66056 3.33406C3.33333 3.84664 3.33333 4.50971 3.33333 5.83586V14.1642C3.33333 15.4902 3.33333 16.1533 3.66056 16.6659C3.71899 16.7575 3.7845 16.8443 3.85647 16.9257C4.25953 17.381 4.89722 17.5632 6.17258 17.9275C7.45117 18.2927 8.09047 18.4753 8.55333 18.2014C8.63367 18.1539 8.70833 18.0976 8.77608 18.0335C9.16667 17.6637 9.16667 16.999 9.16667 15.6695V4.33051C9.16667 3.00101 9.16667 2.33626 8.77608 1.96651C8.70833 1.9024 8.63367 1.84606 8.55333 1.79856C8.09047 1.52463 7.45117 1.70725 6.17258 2.07249C4.89722 2.43681 4.25953 2.61898 3.85647 3.07437C3.7845 3.1557 3.71899 3.24252 3.66056 3.33406Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M9.16667 3.33333H10.8476C12.4323 3.33333 13.2247 3.33333 13.717 3.82149C13.9915 4.09365 14.1129 4.45828 14.1667 5M9.16667 16.6667H10.8476C12.4323 16.6667 13.2247 16.6667 13.717 16.1785C13.9915 15.9063 14.1129 15.5417 14.1667 15"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M17.5 10H11.6667M16.25 7.91667C16.25 7.91667 18.3333 9.45105 18.3333 10C18.3333 10.549 16.25 12.0833 16.25 12.0833"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function ChevronDownIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 18 18" fill="none" aria-hidden="true" {...props}>
      <path
        d="M13.5 6.75004C13.5 6.75004 10.1858 11.25 9 11.25C7.8141 11.25 4.5 6.75 4.5 6.75"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.125"
      />
    </svg>
  )
}

export function CirculationIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M14.1667 10C14.1667 12.3012 12.3012 14.1667 10 14.1667C7.69886 14.1667 5.83337 12.3012 5.83337 10C5.83337 7.69883 7.69886 5.83334 10 5.83334C12.3012 5.83334 14.1667 7.69883 14.1667 10Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
      <path
        d="M15.5384 3.77328C15.2074 4.07787 15 4.51471 15 4.99999C15 5.92046 15.7461 6.66666 16.6666 6.66666C16.9827 6.66666 17.2782 6.57866 17.53 6.42585C18.0115 6.13364 18.3333 5.60438 18.3333 4.99999C18.3333 4.07951 17.5871 3.33332 16.6666 3.33332C16.2315 3.33332 15.8352 3.50012 15.5384 3.77328ZM15.5384 3.77328C14.0661 2.46283 12.126 1.66666 9.99996 1.66666C5.39758 1.66666 1.66663 5.39761 1.66663 9.99999C1.66663 14.6023 5.39758 18.3333 9.99996 18.3333C14.6023 18.3333 18.3333 14.6023 18.3333 9.99999C18.3333 9.71874 18.3194 9.44074 18.2921 9.16666"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function CollapseIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M16.0672 15.8078C16.1253 15.8659 16.1713 15.9348 16.2027 16.0107C16.2342 16.0865 16.2504 16.1679 16.2504 16.25C16.2504 16.3321 16.2342 16.4134 16.2027 16.4893C16.1713 16.5652 16.1253 16.6341 16.0672 16.6922C16.0091 16.7502 15.9402 16.7963 15.8643 16.8277C15.7884 16.8592 15.7071 16.8753 15.625 16.8753C15.5429 16.8753 15.4616 16.8592 15.3857 16.8277C15.3098 16.7963 15.2409 16.7502 15.1828 16.6922L8.93282 10.4422C8.87471 10.3841 8.82861 10.3152 8.79715 10.2393C8.7657 10.1634 8.74951 10.0821 8.74951 9.99998C8.74951 9.91785 8.7657 9.83652 8.79715 9.76064C8.82861 9.68477 8.87471 9.61584 8.93282 9.55779L15.1828 3.30779C15.3001 3.19052 15.4592 3.12463 15.625 3.12463C15.7909 3.12463 15.9499 3.19052 16.0672 3.30779C16.1845 3.42507 16.2504 3.58413 16.2504 3.74998C16.2504 3.91583 16.1845 4.07489 16.0672 4.19217L10.2586 9.99998L16.0672 15.8078ZM4.0086 9.99998L9.81719 4.19217C9.93447 4.07489 10.0004 3.91583 10.0004 3.74998C10.0004 3.58413 9.93447 3.42507 9.81719 3.30779C9.69992 3.19052 9.54086 3.12463 9.375 3.12463C9.20915 3.12463 9.05009 3.19052 8.93282 3.30779L2.68282 9.55779C2.62471 9.61584 2.57861 9.68477 2.54715 9.76064C2.5157 9.83652 2.49951 9.91785 2.49951 9.99998C2.49951 10.0821 2.5157 10.1634 2.54715 10.2393C2.57861 10.3152 2.62471 10.3841 2.68282 10.4422L8.93282 16.6922C8.99088 16.7502 9.05982 16.7963 9.13569 16.8277C9.21156 16.8592 9.29288 16.8753 9.375 16.8753C9.45713 16.8753 9.53844 16.8592 9.61431 16.8277C9.69018 16.7963 9.75912 16.7502 9.81719 16.6922C9.87526 16.6341 9.92132 16.5652 9.95275 16.4893C9.98418 16.4134 10.0004 16.3321 10.0004 16.25C10.0004 16.1679 9.98418 16.0865 9.95275 16.0107C9.92132 15.9348 9.87526 15.8659 9.81719 15.8078L4.0086 9.99998Z"
        fill="currentColor"
      />
    </svg>
  )
}

export function DashboardIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M2.5 9.99131V12.0833C2.5 14.8331 2.5 16.2081 3.35427 17.0624C4.20854 17.9166 5.58347 17.9166 8.33333 17.9166H11.6667C14.4165 17.9166 15.7914 17.9166 16.6457 17.0624C17.5 16.2081 17.5 14.8331 17.5 12.0833V9.99131C17.5 8.59023 17.5 7.88975 17.2034 7.28335C16.9068 6.67695 16.3539 6.24688 15.248 5.38674L13.5813 4.09044C11.8609 2.75235 11.0007 2.08331 10 2.08331C8.99925 2.08331 8.13908 2.75235 6.41868 4.09044L4.75201 5.38674C3.64611 6.24688 3.09316 6.67695 2.79658 7.28335C2.5 7.88975 2.5 8.59023 2.5 9.99131Z"
        fill="currentColor"
      />
      <path
        d="M13.3333 14.1667H6.66663"
        stroke="var(--sidebar)"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function Download01Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M2.49974 14.1668C2.49974 14.9418 2.49974 15.3293 2.58493 15.6472C2.8161 16.5099 3.48997 17.1838 4.3527 17.415C4.67062 17.5002 5.0581 17.5002 5.83308 17.5002H14.1664C14.9414 17.5002 15.3289 17.5002 15.6468 17.415C16.5095 17.1838 17.1834 16.5099 17.4146 15.6472C17.4997 15.3293 17.4998 14.9418 17.4998 14.1668"
        stroke="currentColor"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M13.7498 9.5835C13.7498 9.5835 10.988 13.3335 9.99975 13.3335C9.01158 13.3335 6.2498 9.5835 6.2498 9.5835M9.99975 12.5002V2.50013"
        stroke="currentColor"
        strokeWidth="1.5"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function HelpIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M14.1666 9.83706C14.1666 9.54898 14.1666 9.40498 14.21 9.27665C14.336 8.90365 14.6681 8.75898 15.0009 8.6074C15.375 8.43698 15.562 8.35181 15.7473 8.33681C15.9577 8.3198 16.1685 8.36515 16.3483 8.46606C16.5867 8.59981 16.753 8.85406 16.9232 9.06081C17.7094 10.0156 18.1024 10.4931 18.2462 11.0196C18.3623 11.4445 18.3623 11.8888 18.2462 12.3136C18.0365 13.0816 17.3737 13.7253 16.8831 14.3211C16.6322 14.6259 16.5067 14.7783 16.3483 14.8672C16.1685 14.9681 15.9577 15.0135 15.7473 14.9965C15.562 14.9815 15.375 14.8963 15.0009 14.7259C14.6681 14.5743 14.336 14.4296 14.21 14.0566C14.1666 13.9283 14.1666 13.7843 14.1666 13.4962V9.83706Z"
        stroke="currentColor"
        strokeWidth="1.25"
      />
      <path
        d="M5.83329 9.83712C5.83329 9.47445 5.82311 9.14845 5.52988 8.89345C5.42323 8.8007 5.28183 8.73629 4.99905 8.60746C4.62497 8.43712 4.43793 8.35195 4.25259 8.33695C3.69655 8.29195 3.39739 8.67146 3.07673 9.06096C2.29058 10.0158 1.89751 10.4932 1.75368 11.0197C1.63761 11.4446 1.63761 11.889 1.75368 12.3138C1.96346 13.0817 2.62623 13.7254 3.1168 14.3213C3.42603 14.6969 3.72143 15.0395 4.25259 14.9966C4.43793 14.9816 4.62497 14.8964 4.99905 14.726C5.28183 14.5972 5.42323 14.5328 5.52988 14.44C5.82311 14.185 5.83329 13.8591 5.83329 13.4964V9.83712Z"
        stroke="currentColor"
        strokeWidth="1.25"
      />
      <path
        d="M16.6667 8.75002V7.50002C16.6667 4.27836 13.682 1.66669 10 1.66669C6.31814 1.66669 3.33337 4.27836 3.33337 7.50002V8.75002"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M16.6667 14.5833C16.6667 18.3333 13.3333 18.3333 10 18.3333"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function IntelligenceIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M15.8334 8.01723C15.8334 10.1666 14.7752 11.821 13.1653 12.9097C12.7903 13.1633 12.6028 13.2902 12.5102 13.4343C12.4177 13.5785 12.3861 13.7678 12.323 14.1464L12.274 14.4407C12.1631 15.1058 12.1077 15.4383 11.8745 15.6358C11.6415 15.8333 11.3043 15.8333 10.63 15.8333H8.45371C7.77944 15.8333 7.44228 15.8333 7.20917 15.6358C6.97604 15.4383 6.92062 15.1058 6.80976 14.4407L6.76072 14.1464C6.69782 13.7691 6.66638 13.5804 6.57477 13.4369C6.48317 13.2934 6.29527 13.165 5.91947 12.9081C4.32662 11.8193 3.33337 10.1655 3.33337 8.01723C3.33337 4.50991 6.13159 1.66666 9.58337 1.66666C10.0115 1.66666 10.4295 1.71039 10.8334 1.79369"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M13.75 1.66666L13.965 2.24751C14.2468 3.00917 14.3877 3.39001 14.6655 3.66781C14.9434 3.94563 15.3242 4.08655 16.0859 4.36839L16.6667 4.58332L16.0859 4.79826C15.3242 5.0801 14.9434 5.22102 14.6655 5.49883C14.3877 5.77664 14.2468 6.15747 13.965 6.91913L13.75 7.49999L13.5351 6.91913C13.2533 6.15747 13.1124 5.77664 12.8345 5.49883C12.5567 5.22102 12.1759 5.0801 11.4142 4.79826L10.8334 4.58332L11.4142 4.36839C12.1759 4.08655 12.5567 3.94563 12.8345 3.66781C13.1124 3.39001 13.2533 3.00917 13.5351 2.24751L13.75 1.66666Z"
        stroke="currentColor"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M11.25 15.8333V16.6667C11.25 17.4523 11.25 17.8452 11.0059 18.0893C10.7618 18.3333 10.369 18.3333 9.58329 18.3333C8.79763 18.3333 8.40479 18.3333 8.1607 18.0893C7.91663 17.8452 7.91663 17.4523 7.91663 16.6667V15.8333"
        stroke="currentColor"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function MembersIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M10.8333 9.16668C10.8333 7.32573 9.34088 5.83334 7.49996 5.83334C5.65901 5.83334 4.16663 7.32573 4.16663 9.16668C4.16663 11.0076 5.65901 12.5 7.49996 12.5C9.34088 12.5 10.8333 11.0076 10.8333 9.16668Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M9.19879 6.29811C9.17754 6.14623 9.16663 5.99106 9.16663 5.83333C9.16663 3.99238 10.659 2.5 12.5 2.5C14.3409 2.5 15.8333 3.99238 15.8333 5.83333C15.8333 7.67428 14.3409 9.16667 12.5 9.16667C11.8795 9.16667 11.2986 8.99717 10.8011 8.70192"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M12.5 17.5C12.5 14.7386 10.2614 12.5 7.5 12.5C4.73857 12.5 2.5 14.7386 2.5 17.5"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M17.5 14.1667C17.5 11.4052 15.2614 9.16666 12.5 9.16666"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function OpacIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M9.99996 18.3333C14.1215 18.3333 17.5441 15.3413 18.2144 11.4108C18.2925 10.9522 18.3333 10.4809 18.3333 9.99999C18.3333 5.93213 15.4186 2.54503 11.5638 1.81315C11.0572 1.71698 10.5345 1.66666 9.99996 1.66666C7.7247 1.66666 5.66242 2.5785 4.1586 4.05667C2.6205 5.56855 1.66663 7.67287 1.66663 9.99999C1.66663 14.6023 5.39758 18.3333 9.99996 18.3333ZM9.99996 18.3333C9.19746 17.7387 9.32554 17.0462 9.72813 16.3539C10.3471 15.2895 10.3471 15.2895 10.3471 13.8703C10.3471 12.4512 11.1905 11.7857 14.1666 12.3809C15.5039 12.6484 16.4784 10.8007 18.2144 11.4108M4.1586 4.05667C4.86634 4.13136 5.2626 4.51052 5.92076 5.20596C7.17029 6.52626 8.41979 6.63642 9.25288 6.19632C10.5024 5.53618 9.45238 4.46691 10.9189 3.88581C11.818 3.52958 11.9893 2.59665 11.5638 1.81315"
        stroke="currentColor"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function ReportsIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M12.4838 5.84625C12.4838 5.84625 12.9004 6.26292 13.3171 7.09625C13.3171 7.09625 14.6406 5.01292 15.8171 4.59625"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M8.329 1.6844C6.24694 1.59625 4.63839 1.8361 4.63839 1.8361C3.62268 1.90872 1.67618 2.47815 1.67619 5.80373C1.67621 9.10103 1.65466 13.166 1.67619 14.7865C1.67619 15.7766 2.28921 18.086 4.41101 18.2098C6.99004 18.3603 11.6356 18.3923 13.767 18.2098C14.3376 18.1776 16.2372 17.7297 16.4776 15.6629C16.7267 13.5219 16.6771 12.0339 16.6771 11.6797"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.25"
      />
      <path
        d="M18.3332 5.84625C18.3332 8.14743 16.4659 10.0129 14.1625 10.0129C11.8591 10.0129 9.99182 8.14743 9.99182 5.84625C9.99182 3.54506 11.8591 1.67958 14.1625 1.67958C16.4659 1.67958 18.3332 3.54506 18.3332 5.84625Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
      <path
        d="M5.81702 10.8464H9.15033"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
      <path
        d="M5.81702 14.1797H12.4837"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function ReturnIcon(props: IconProps) {
  return (
    <svg
      viewBox="0 0 20.5333 20.5333"
      fill="none"
      aria-hidden="true"
      {...props}
    >
      <path
        d="M9.41128 5.13327H13.2613C15.3876 5.13327 17.1113 6.85697 17.1113 8.98327C17.1113 11.1096 15.3876 12.8333 13.2613 12.8333H3.4224"
        stroke="currentColor"
        strokeWidth="1.33333"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M5.98905 10.2666C5.98905 10.2666 3.4224 12.157 3.4224 12.8333C3.42239 13.5097 5.98906 15.3999 5.98906 15.3999"
        stroke="currentColor"
        strokeWidth="1.33333"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function SettingsIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M17.7646 5.95114L17.3533 5.23731C17.0422 4.69745 16.8867 4.42752 16.622 4.31988C16.3574 4.21225 16.058 4.29718 15.4595 4.46705L14.4426 4.75346C14.0605 4.8416 13.6595 4.7916 13.3105 4.61231L13.0298 4.45033C12.7305 4.25867 12.5004 3.97609 12.373 3.64393L12.0947 2.81278C11.9117 2.26276 11.8202 1.98776 11.6024 1.83046C11.3846 1.67316 11.0953 1.67316 10.5166 1.67316H9.58762C9.00904 1.67316 8.71971 1.67316 8.50187 1.83046C8.28408 1.98776 8.19259 2.26276 8.00961 2.81278L7.73131 3.64393C7.60391 3.97609 7.37375 4.25867 7.07451 4.45033L6.79378 4.61231C6.44482 4.7916 6.04386 4.8416 5.66169 4.75346L4.64483 4.46705C4.04621 4.29718 3.74691 4.21225 3.48226 4.31988C3.21761 4.42752 3.06208 4.69745 2.751 5.23731L2.33968 5.95114C2.04809 6.45718 1.90229 6.71021 1.93059 6.97956C1.95888 7.24891 2.15406 7.46596 2.54442 7.90008L3.40362 8.86065C3.61362 9.12648 3.76271 9.58981 3.76271 10.0064C3.76271 10.4231 3.61367 10.8863 3.40365 11.1522L2.54442 12.1128C2.15406 12.547 1.95889 12.764 1.93059 13.0334C1.90229 13.3027 2.04809 13.5557 2.33968 14.0617L2.75099 14.7756C3.06206 15.3154 3.21761 15.5854 3.48226 15.693C3.74691 15.8006 4.04622 15.7157 4.64485 15.5458L5.66166 15.2594C6.0439 15.1712 6.44493 15.2213 6.79393 15.4006L7.07462 15.5626C7.3738 15.7543 7.60391 16.0368 7.73129 16.369L8.00961 17.2002C8.19259 17.7502 8.28408 18.0252 8.50187 18.1826C8.71971 18.3398 9.00904 18.3398 9.58762 18.3398H10.5166C11.0953 18.3398 11.3846 18.3398 11.6024 18.1826C11.8202 18.0252 11.9117 17.7502 12.0947 17.2002L12.373 16.369C12.5004 16.0368 12.7305 15.7543 13.0297 15.5626L13.3104 15.4006C13.6594 15.2213 14.0604 15.1712 14.4426 15.2594L15.4595 15.5458C16.058 15.7157 16.3574 15.8006 16.622 15.693C16.8867 15.5854 17.0422 15.3154 17.3533 14.7756L17.7646 14.0617C18.0562 13.5557 18.202 13.3027 18.1737 13.0334C18.1454 12.764 17.9502 12.547 17.5599 12.1128L16.7006 11.1522C16.4906 10.8863 16.3415 10.4231 16.3415 10.0064C16.3415 9.58981 16.4907 9.12648 16.7006 8.86065L17.5599 7.90008C17.9502 7.46596 18.1454 7.24891 18.1737 6.97956C18.202 6.71021 18.0562 6.45718 17.7646 5.95114Z"
        stroke="currentColor"
        strokeLinecap="round"
        strokeWidth="1.25"
      />
      <path
        d="M12.9329 9.99998C12.9329 11.6108 11.6271 12.9166 10.0163 12.9166C8.40542 12.9166 7.09961 11.6108 7.09961 9.99998C7.09961 8.38915 8.40542 7.08331 10.0163 7.08331C11.6271 7.08331 12.9329 8.38915 12.9329 9.99998Z"
        stroke="currentColor"
        strokeWidth="1.25"
      />
    </svg>
  )
}

export function SparklesIcon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M12.5 1.66667L12.9489 3.65964C13.3298 5.35013 14.6498 6.67026 16.3403 7.05106L18.3333 7.5L16.3403 7.94894C14.6498 8.32974 13.3298 9.64983 12.9489 11.3403L12.5 13.3333L12.0511 11.3403C11.6703 9.64983 10.3502 8.32974 8.65967 7.94894L6.66667 7.5L8.65967 7.05106C10.3501 6.67026 11.6703 5.35013 12.0511 3.65965L12.5 1.66667Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinejoin="round"
      />
      <path
        d="M5.83333 10L6.15401 11.4236C6.42601 12.631 7.36896 13.574 8.57642 13.846L10 14.1667L8.57642 14.4873C7.36896 14.7593 6.42601 15.7023 6.15401 16.9098L5.83333 18.3333L5.51266 16.9098C5.24066 15.7023 4.29771 14.7593 3.09022 14.4873L1.66667 14.1667L3.09022 13.846C4.29771 13.574 5.24066 12.6311 5.51266 11.4236L5.83333 10Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinejoin="round"
      />
    </svg>
  )
}

export function ThemeIcon(props: IconProps) {
  return (
    <svg
      viewBox="0 0 30 30"
      fill="currentColor"
      stroke="currentColor"
      strokeWidth="0"
      aria-hidden="true"
      {...props}
    >
      <path d="M3.74 14.44c0-1.52.3-2.98.89-4.37s1.4-2.58 2.4-3.59 2.2-1.81 3.59-2.4 2.84-.89 4.37-.89 2.98.3 4.37.89 2.59 1.4 3.6 2.4 1.81 2.2 2.4 3.59.89 2.84.89 4.37-.3 2.98-.89 4.37-1.4 2.59-2.4 3.6-2.2 1.81-3.6 2.4-2.85.89-4.37.89-2.98-.3-4.37-.89-2.58-1.4-3.59-2.4-1.81-2.2-2.4-3.6-.89-2.84-.89-4.37Zm11.06 10.07h.19c1.37 0 2.67-.27 3.91-.8s2.31-1.25 3.21-2.15 1.61-1.97 2.15-3.21.8-2.54.8-3.91c0-1.36-.27-2.66-.8-3.9s-1.25-2.31-2.15-3.21-1.97-1.61-3.21-2.15-2.54-.8-3.91-.8h-.19v20.13Z" />
    </svg>
  )
}

export function UserAdd02Icon(props: IconProps) {
  return (
    <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" {...props}>
      <path
        d="M11.6667 7.08333C11.6667 4.78215 9.80117 2.91667 7.5 2.91667C5.19882 2.91667 3.33333 4.78215 3.33333 7.08333C3.33333 9.3845 5.19882 11.25 7.5 11.25C9.80117 11.25 11.6667 9.3845 11.6667 7.08333Z"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M13.3333 17.0833C13.3333 13.8617 10.7217 11.25 7.5 11.25C4.27834 11.25 1.66667 13.8617 1.66667 17.0833"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M15.8333 7.5V12.5M18.3333 10H13.3333"
        stroke="currentColor"
        strokeWidth="1.25"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  )
}
```

### `src/components/dashboards/library-dashboard/components/library/logo.tsx`

```tsx
import type { SVGProps } from "react"

export function Logo(props: SVGProps<SVGSVGElement>) {
  return (
    <svg
      viewBox="0 0 512 512"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      {...props}
    >
      <path
        d="M169.572 83.3331H383.899L226.326 316.888H11.9993L169.572 83.3331Z"
        fill="#FB0100"
      />
      <path
        d="M178.965 338.535L117.934 428.997H342.427L500 195.442H334.31L237.769 338.535H178.965Z"
        fill="#FF7979"
      />
    </svg>
  )
}
```

### `src/components/dashboards/library-dashboard/components/library/sidebar.tsx`

```tsx
'use client';

import { Check, Ellipsis } from 'lucide-react';
import { useRef, useState } from 'react';

import { Logo } from './logo';
import { useTheme } from './theme-provider';

import {
  ArrowDown01Icon,
  BackwardIcon,
  BuildingIcon,
  HelpIcon,
  SettingsIcon,
  ThemeIcon,
} from './icons';
import { Button, buttonVariants } from '@/components/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuButton,
  SidebarMenuItem,
  SidebarMenuSub,
  SidebarMenuSubButton,
  SidebarMenuSubItem,
  useSidebar,
} from '@/components/ui/sidebar';
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet';
import { cn } from '@/lib/utils';
import {
  type NavigationItem,
  organizations,
  primaryNavigation,
} from '../../data';

const menuButtonBaseClassName =
  'h-11 gap-3 rounded-lg border border-transparent px-3.5 font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground active:bg-muted active:text-foreground data-active:border-border data-active:bg-card data-active:text-primary data-active:shadow-[1.35px_2.7px_32.45px_rgba(158,158,158,0.08)] data-active:hover:bg-card data-active:hover:text-primary data-active:active:bg-card data-active:active:text-primary [&_svg]:size-5 [&_svg]:text-foreground data-active:[&_svg]:text-primary';

const sidebarMenuButtonClassName = cn(
  menuButtonBaseClassName,
  'group-data-[collapsible=icon]:size-11! group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0!',
);

const sidebarMenuSubButtonClassName = cn(
  menuButtonBaseClassName,
  '[&_svg]:text-foreground! data-active:[&_svg]:text-primary!',
);

const subItemsMenuContentClassName = 'z-100 w-48 p-1.5 shadow-lg';

const bottomNavItemClassName = cn(
  buttonVariants({ variant: 'ghost' }),
  'text-foreground hover:text-primary h-full flex-1 px-0 hover:bg-transparent rounded-none',
);

const moreNavItemClassName = cn(
  menuButtonBaseClassName,
  'flex items-center text-sm',
);

const mobilePrimaryNavigation = primaryNavigation.slice(0, 4);
const mobileMoreNavigation = primaryNavigation.slice(4);

type DashboardSidebarProps = {
  activeSection?: string;
  activeSubsection?: string;
};

export function DashboardSidebar({
  activeSection = 'dashboard',
  activeSubsection,
}: DashboardSidebarProps) {
  const { state, toggleSidebar } = useSidebar();
  const { toggleTheme } = useTheme();
  const collapsed = state === 'collapsed';

  return (
    <>
      <Sidebar collapsible="icon">
        <SidebarHeader
          className={cn(
            'h-21 flex-row items-center border-b p-0 transition-[padding] duration-200 library-dashboard bg-background',
            collapsed ? 'justify-start px-5' : 'justify-between px-4.5',
          )}
        >
          {!collapsed ? (
            <>
              <a
                aria-label="Library dashboard"
                className="flex h-8 items-center gap-2"
                href="#"
                onClick={(e) => e.preventDefault()}
              >
                <Logo className="size-8" />
                <span className="text-xl font-bold tracking-tight">
                  Library
                </span>
              </a>
              <Button
                aria-label="Collapse sidebar"
                variant="secondary"
                size="icon-lg"
                onClick={toggleSidebar}
              >
                <BackwardIcon className="size-5" />
              </Button>
            </>
          ) : (
            <div className="relative size-10">
              <div className="pointer-events-none absolute inset-0 flex items-center justify-center transition-all duration-200 group-hover:scale-75 group-hover:opacity-0">
                <Logo className="size-6" />
              </div>
              <div className="pointer-events-none absolute inset-0 flex scale-75 items-center justify-center opacity-0 transition-all duration-200 group-hover:pointer-events-auto group-hover:scale-100 group-hover:opacity-100">
                <Button
                  aria-label="Expand sidebar"
                  variant="secondary"
                  size="icon-lg"
                  onClick={toggleSidebar}
                >
                  <BackwardIcon className="size-5 rotate-180" />
                </Button>
              </div>
            </div>
          )}
        </SidebarHeader>

        <SidebarContent className="px-4.5 pt-6 pb-2 library-dashboard bg-background">
          <SidebarMenu className="gap-1.5">
            {primaryNavigation.map((item) => (
              <SidebarNavigationItem
                key={item.section}
                active={item.section === activeSection}
                item={item}
                activeSubsection={activeSubsection}
              />
            ))}
          </SidebarMenu>
        </SidebarContent>

        <SidebarFooter className="border-t px-4.5 pt-2 pb-6 library-dashboard bg-background">
          <SidebarMenu>
            <SidebarMenuItem>
              <SidebarMenuButton
                isActive={activeSection === 'help-support'}
                tooltip="Help & Support"
                className={sidebarMenuButtonClassName}
                onClick={(event) => event.preventDefault()}
              >
                <HelpIcon />
                {!collapsed && <span>Help & Support</span>}
              </SidebarMenuButton>
            </SidebarMenuItem>
            <SidebarMenuItem className="flex items-center gap-1">
              <SidebarMenuButton
                isActive={activeSection === 'settings'}
                tooltip="Settings"
                className={cn(sidebarMenuButtonClassName, !collapsed && 'flex-1')}
                onClick={(event) => event.preventDefault()}
              >
                <SettingsIcon />
                {!collapsed && <span>Settings</span>}
              </SidebarMenuButton>
              {!collapsed && (
                <Button
                  aria-label="Toggle theme"
                  variant="ghost"
                  size="icon"
                  className="size-11"
                  onClick={toggleTheme}
                >
                  <ThemeIcon className="size-5" />
                </Button>
              )}
            </SidebarMenuItem>
          </SidebarMenu>
        </SidebarFooter>
      </Sidebar>

      <MobileBottomNavigation
        activeSection={activeSection}
        activeSubsection={activeSubsection}
      />
    </>
  );
}

function MobileBottomNavigation({
  activeSection,
  activeSubsection,
}: {
  activeSection: string;
  activeSubsection?: string;
}) {
  const { toggleTheme } = useTheme();
  const [moreOpen, setMoreOpen] = useState(false);
  const [selectedOrg, setSelectedOrg] = useState<string>(organizations[0]);
  const moreActive = mobileMoreNavigation.some(
    (item) => item.section === activeSection,
  );

  return (
    <div className="bg-sidebar fixed inset-x-0 bottom-0 z-50 flex h-16 items-center justify-around border-t px-2 md:hidden">
      {mobilePrimaryNavigation.map((item) => {
        const active = item.section === activeSection;
        const activeSubItem =
          active && activeSubsection
            ? item.subItems?.find((subItem) =>
              subItem.href.endsWith(`/${activeSubsection}`),
            )
            : undefined;
        const Icon = activeSubItem?.icon ?? item.icon;
        const label = activeSubItem?.label ?? item.label;

        if (item.subItems?.length) {
          return (
            <DropdownMenu key={item.section}>
              <DropdownMenuTrigger
                aria-label={label}
                className={cn(
                  bottomNavItemClassName,
                  active && 'text-primary font-medium',
                )}
              >
                <Icon className="size-5" />
              </DropdownMenuTrigger>
              <DropdownMenuContent
                side="top"
                align="center"
                sideOffset={8}
                className={subItemsMenuContentClassName}
              >
                <NavigationSubItemsMenu
                  item={item}
                  isSubItemActive={(href) =>
                    active && href.endsWith(`/${activeSubsection}`)
                  }
                />
              </DropdownMenuContent>
            </DropdownMenu>
          );
        }

        return (
          <a
            key={item.section}
            href={item.href}
            aria-label={item.label}
            onClick={(e) => e.preventDefault()}
            className={cn(
              bottomNavItemClassName,
              active && 'text-primary font-medium',
            )}
          >
            <Icon className="size-5" />
          </a>
        );
      })}

      <Sheet open={moreOpen} onOpenChange={setMoreOpen}>
        <SheetTrigger
          aria-label="More navigation"
          className={cn(
            bottomNavItemClassName,
            moreActive && 'text-primary font-medium',
          )}
        >
          <Ellipsis className="size-5" />
        </SheetTrigger>
        <SheetContent
          side="bottom"
          showCloseButton={false}
          className="max-h-[85dvh] gap-1.5 rounded-t-3xl px-4 pt-2 pb-[calc(1rem+env(safe-area-inset-bottom))] md:hidden"
        >
          <div className="bg-border mx-auto h-1 w-10 rounded-full" />
          <SheetHeader className="px-0 pt-2 pb-1">
            <SheetTitle className="text-lg font-semibold">More</SheetTitle>
          </SheetHeader>

          <DropdownMenu>
            <DropdownMenuTrigger
              className={cn(
                buttonVariants({ variant: 'ghost' }),
                'h-auto w-full justify-between py-2',
              )}
            >
              <span className="flex min-w-0 items-center gap-3">
                <span className="bg-foreground text-background dark:bg-muted flex size-10 shrink-0 items-center justify-center rounded-lg">
                  <BuildingIcon className="size-5" />
                </span>
                <span className="min-w-0 text-left">
                  <span className="text-muted-foreground block text-xs font-normal">
                    Library branch
                  </span>
                  <span className="block truncate text-sm font-semibold">
                    {selectedOrg}
                  </span>
                </span>
              </span>
              <ArrowDown01Icon className="text-muted-foreground size-5" />
            </DropdownMenuTrigger>
            <DropdownMenuContent
              align="center"
              side="top"
              sideOffset={8}
              className="z-70 w-[calc(100vw-2rem)] max-w-sm rounded-xl p-2 shadow-lg"
            >
              <DropdownMenuGroup>
                <DropdownMenuLabel className="px-2 py-1.5 font-semibold tracking-wider uppercase">
                  Select Branch
                </DropdownMenuLabel>
                <DropdownMenuSeparator />
                {organizations.map((organization) => (
                  <DropdownMenuItem
                    key={organization}
                    onClick={() => setSelectedOrg(organization)}
                    className={cn(
                      'justify-between rounded-lg px-2 py-2.5',
                      organization === selectedOrg
                        ? 'text-primary font-semibold'
                        : 'text-muted-foreground',
                    )}
                  >
                    <span>{organization}</span>
                    {organization === selectedOrg && (
                      <Check className="text-primary size-4" />
                    )}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
            </DropdownMenuContent>
          </DropdownMenu>

          <nav aria-label="More navigation" className="flex flex-col gap-1.5">
            {mobileMoreNavigation.map((item) => {
              const Icon = item.icon;
              const active = item.section === activeSection;

              return (
                <a
                  key={item.section}
                  href={item.href}
                  data-active={active || undefined}
                  onClick={(e) => {
                    e.preventDefault();
                    setMoreOpen(false);
                  }}
                  className={moreNavItemClassName}
                >
                  <Icon />
                  <span>{item.label}</span>
                </a>
              );
            })}
            <a
              href="#"
              data-active={activeSection === 'help-support' || undefined}
              onClick={(e) => {
                e.preventDefault();
                setMoreOpen(false);
              }}
              className={moreNavItemClassName}
            >
              <HelpIcon />
              <span>Help & Support</span>
            </a>
            <div className="flex items-center gap-1">
              <a
                href="#"
                data-active={activeSection === 'settings' || undefined}
                onClick={(e) => {
                  e.preventDefault();
                  setMoreOpen(false);
                }}
                className={cn(moreNavItemClassName, 'flex-1')}
              >
                <SettingsIcon />
                <span>Settings</span>
              </a>
              <Button
                aria-label="Toggle theme"
                variant="ghost"
                size="icon"
                className="size-11"
                onClick={toggleTheme}
              >
                <ThemeIcon className="size-5" />
              </Button>
            </div>
          </nav>
        </SheetContent>
      </Sheet>
    </div>
  );
}

type SidebarNavigationItemProps = {
  active: boolean;
  activeSubsection?: string;
  item: NavigationItem;
};

function SidebarNavigationItem({
  active,
  activeSubsection,
  item,
}: SidebarNavigationItemProps) {
  const { state } = useSidebar();
  const collapsed = state === 'collapsed';
  const [open, setOpen] = useState(false);
  const [flyoutOpen, setFlyoutOpen] = useState(false);
  const flyoutCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const subItems = item.subItems;
  const hasSubItems = Boolean(subItems?.length);
  const showSubItems = !collapsed && open && hasSubItems;

  const activeChild = activeSubsection
    ? subItems?.find((subItem) => subItem.href.endsWith(`/${activeSubsection}`))
    : undefined;
  const DisplayedIcon = active && activeChild ? activeChild.icon : item.icon;
  const displayedLabel = active && activeChild ? activeChild.label : item.label;
  const activeChildHref = activeChild?.href;
  const isActiveSubItem = (href: string) => active && href === activeChildHref;

  function toggleOpen() {
    setOpen((currentOpen) => !currentOpen);
  }

  function openFlyout() {
    if (flyoutCloseTimer.current) {
      clearTimeout(flyoutCloseTimer.current);
    }

    setFlyoutOpen(true);
  }

  function scheduleFlyoutClose() {
    flyoutCloseTimer.current = setTimeout(() => {
      setFlyoutOpen(false);
    }, 120);
  }

  return (
    <SidebarMenuItem>
      {collapsed && hasSubItems ? (
        <DropdownMenu
          modal={false}
          open={flyoutOpen}
          onOpenChange={setFlyoutOpen}
        >
          <DropdownMenuTrigger
            aria-label={displayedLabel}
            data-active={active || undefined}
            onPointerEnter={openFlyout}
            onPointerLeave={scheduleFlyoutClose}
            className={cn(sidebarMenuButtonClassName, 'flex w-full items-center')}
          >
            <DisplayedIcon />
          </DropdownMenuTrigger>
          <DropdownMenuContent
            side="right"
            align="start"
            sideOffset={8}
            onPointerEnter={openFlyout}
            onPointerLeave={scheduleFlyoutClose}
            className={subItemsMenuContentClassName}
          >
            <NavigationSubItemsMenu
              item={item}
              isSubItemActive={isActiveSubItem}
            />
          </DropdownMenuContent>
        </DropdownMenu>
      ) : hasSubItems ? (
        <SidebarMenuButton
          isActive={active}
          onClick={toggleOpen}
          className={sidebarMenuButtonClassName}
        >
          <DisplayedIcon />
          {!collapsed && (
            <>
              <span>{displayedLabel}</span>
              <ArrowDown01Icon
                className={cn(
                  'pointer-events-none ml-auto size-4.5 transition-transform',
                  open && 'rotate-180',
                )}
              />
            </>
          )}
        </SidebarMenuButton>
      ) : (
        <SidebarMenuButton
          isActive={active}
          tooltip={displayedLabel}
          className={sidebarMenuButtonClassName}
          onClick={(event) => event.preventDefault()}
        >
          <DisplayedIcon />
          {!collapsed && <span>{displayedLabel}</span>}
        </SidebarMenuButton>
      )}

      {showSubItems ? (
        <SidebarMenuSub>
          {subItems?.map((subItem) => {
            const SubIcon = subItem.icon;
            return (
              <SidebarMenuSubItem key={subItem.href}>
                <SidebarMenuSubButton
                  isActive={isActiveSubItem(subItem.href)}
                  className={sidebarMenuSubButtonClassName}
                  href={subItem.href}
                  onClick={(event) => event.preventDefault()}
                >
                  <SubIcon />
                  <span>{subItem.label}</span>
                </SidebarMenuSubButton>
              </SidebarMenuSubItem>
            );
          })}
        </SidebarMenuSub>
      ) : null}
    </SidebarMenuItem>
  );
}

function NavigationSubItemsMenu({
  item,
  isSubItemActive,
}: {
  item: NavigationItem;
  isSubItemActive: (href: string) => boolean;
}) {
  return (
    <DropdownMenuGroup>
      <DropdownMenuLabel className="px-2 py-1 font-semibold tracking-wider uppercase">
        {item.label}
      </DropdownMenuLabel>
      <DropdownMenuSeparator />
      {item.subItems?.map((subItem) => {
        const SubIcon = subItem.icon;

        return (
          <DropdownMenuItem
            key={subItem.href}
            data-active={isSubItemActive(subItem.href) || undefined}
            onClick={(event) => event.preventDefault()}
            className={cn(
              sidebarMenuSubButtonClassName,
              'h-10 gap-2.5 px-3 focus:bg-muted focus:text-foreground data-active:focus:bg-card data-active:focus:text-primary',
            )}
          >
            <SubIcon />
            <span>{subItem.label}</span>
          </DropdownMenuItem>
        );
      })}
    </DropdownMenuGroup>
  );
}
```

### `src/components/dashboards/library-dashboard/components/library/theme-provider.tsx`

```tsx
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';

type Theme = 'light' | 'dark';

type ThemeProviderProps = {
  children: ReactNode;
  defaultTheme?: Theme;
  storageKey?: string;
};

type ThemeProviderState = {
  theme: Theme;
  setTheme: (theme: Theme) => void;
  toggleTheme: () => void;
};

const ThemeProviderContext = createContext<ThemeProviderState | null>(null);

export function ThemeProvider({
  children,
  defaultTheme = 'light',
  storageKey = 'theme',
}: ThemeProviderProps) {
  const [theme, setThemeState] = useState<Theme>(() => {
    if (typeof window === 'undefined') return defaultTheme;

    const storedTheme = localStorage.getItem(storageKey);
    if (storedTheme === 'light' || storedTheme === 'dark') {
      return storedTheme;
    }

    return window.matchMedia('(prefers-color-scheme: dark)').matches
      ? 'dark'
      : defaultTheme;
  });

  useEffect(() => {
    document.documentElement.classList.toggle('dark', theme === 'dark');
  }, [theme]);

  const setTheme = useCallback(
    (nextTheme: Theme) => {
      localStorage.setItem(storageKey, nextTheme);
      setThemeState(nextTheme);
    },
    [storageKey],
  );

  const toggleTheme = useCallback(() => {
    setThemeState((currentTheme) => {
      const nextTheme = currentTheme === 'dark' ? 'light' : 'dark';
      localStorage.setItem(storageKey, nextTheme);
      return nextTheme;
    });
  }, [storageKey]);

  const value = useMemo(
    () => ({ theme, setTheme, toggleTheme }),
    [setTheme, theme, toggleTheme],
  );

  return (
    <ThemeProviderContext.Provider value={value}>
      {children}
    </ThemeProviderContext.Provider>
  );
}

export function useTheme() {
  const context = useContext(ThemeProviderContext);

  if (!context) {
    throw new Error('useTheme must be used within a ThemeProvider.');
  }

  return context;
}
```

### `src/components/dashboards/library-dashboard/components/library/topbar.tsx`

```tsx
'use client';

import { useEffect, useRef, useState } from 'react';

import { Check, Search, X } from 'lucide-react';

import {
  ArrowDown01Icon,
  BellIcon,
  BuildingIcon,
  DashboardIcon,
} from './icons';
import { Button, buttonVariants } from '@/components/ui/button';
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from '@/components/ui/input-group';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { SidebarTrigger } from '@/components/ui/sidebar';
import { organizations, topNavNotifications } from '../../data';
import { cn } from '@/lib/utils';

const searchPlaceholder = '“Search catalog, members, ISBN”';

export function DashboardTopbar() {
  const [selectedOrg, setSelectedOrg] = useState<string>(organizations[0]);
  const [searchQuery, setSearchQuery] = useState('');
  const [mobileSearchOpen, setMobileSearchOpen] = useState(false);
  const searchInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (mobileSearchOpen) {
      searchInputRef.current?.focus();
    }
  }, [mobileSearchOpen]);

  return (
    <header className="bg-background sticky top-0 z-30 flex h-16 items-center gap-2 border-b px-4 md:h-21 md:pl-6 md:pr-8">
      <div
        className={cn(
          'mr-auto flex items-center gap-2 md:gap-3 text-lg font-medium',
          mobileSearchOpen && 'hidden md:flex',
        )}
      >
        <SidebarTrigger size="icon-lg" className="size-11 md:hidden" />
        <DashboardIcon className="hidden size-5 md:block" />
        <span className="truncate">Dashboard</span>
      </div>

      <InputGroup
        className={cn(
          'bg-input h-11 gap-1.75 border-none pl-3 md:flex md:w-78 md:flex-none',
          mobileSearchOpen ? 'flex-1' : 'hidden',
        )}
      >
        <InputGroupAddon className="pl-0">
          <Search className="size-5 text-secondary-foreground" />
        </InputGroupAddon>
        <InputGroupInput
          ref={searchInputRef}
          value={searchQuery}
          onChange={(event) => setSearchQuery(event.target.value)}
          aria-label="Search catalog, members, ISBN"
          className="h-full p-0 pl-0!"
          placeholder={searchPlaceholder}
        />
      </InputGroup>

      <Button
        aria-label={mobileSearchOpen ? 'Close search' : 'Search library'}
        aria-pressed={mobileSearchOpen}
        variant="secondary"
        size="icon-lg"
        className="size-11 md:hidden"
        onClick={() => setMobileSearchOpen((open) => !open)}
      >
        {mobileSearchOpen ? (
          <X className="size-5" />
        ) : (
          <Search className="size-5" />
        )}
      </Button>

      <div className={cn(mobileSearchOpen && 'hidden md:block')}>
        <DropdownMenu>
          <DropdownMenuTrigger
            aria-label="Notifications"
            className={cn(
              buttonVariants({ variant: 'secondary', size: 'icon-lg' }),
              'relative size-11',
            )}
          >
            <BellIcon className="size-5" />
            {topNavNotifications.some(
              (notification) => notification.unread,
            ) && (
              <span className="absolute top-3.25 left-6 size-1.5 rounded-full bg-red-500" />
            )}
          </DropdownMenuTrigger>
          <DropdownMenuContent
            align="end"
            className="w-[calc(100vw-2rem)] max-w-80"
          >
            <DropdownMenuGroup>
              <DropdownMenuLabel className="flex items-center justify-between px-2 py-1.5 font-semibold tracking-wider uppercase">
                <span>Notifications</span>
                <span className="font-normal tracking-normal normal-case">
                  {
                    topNavNotifications.filter(
                      (notification) => notification.unread,
                    ).length
                  }{' '}
                  unread
                </span>
              </DropdownMenuLabel>
              <DropdownMenuSeparator />
              <div className="max-h-70 space-y-1 overflow-y-auto py-1">
                {topNavNotifications.slice(0, 3).map((notif) => (
                  <DropdownMenuItem
                    key={notif.id}
                    className="flex h-18 cursor-default flex-col items-start gap-1 rounded-md p-2.5 outline-hidden transition-colors"
                  >
                    <div className="flex w-full items-start justify-between gap-2">
                      <span className="line-clamp-2 text-xs leading-normal font-semibold">
                        {notif.text}
                      </span>
                      {notif.unread && (
                        <span className="mt-1 size-1.5 shrink-0 rounded-full bg-red-500" />
                      )}
                    </div>
                    <span className="text-muted-foreground text-xs">
                      {notif.time}
                    </span>
                  </DropdownMenuItem>
                ))}
              </div>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                className="text-primary justify-center"
                onClick={(event) => event.preventDefault()}
              >
                View all notifications
              </DropdownMenuItem>
            </DropdownMenuGroup>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>

      <div className="hidden md:block">
        <DropdownMenu>
          <DropdownMenuTrigger
            aria-label={`Select library branch. Current branch: ${selectedOrg}`}
            className="flex h-11 cursor-pointer items-center justify-center gap-2"
          >
            <div className="bg-foreground text-background dark:bg-muted flex size-11 items-center justify-center rounded-lg">
              <BuildingIcon className="size-6" />
            </div>
            <ArrowDown01Icon className="size-6" />
          </DropdownMenuTrigger>

          <DropdownMenuContent
            align="end"
            className="w-60 rounded-xl p-2 shadow-lg"
          >
            <DropdownMenuGroup>
              <DropdownMenuLabel className="px-2 py-1.5 font-semibold tracking-wider uppercase">
                Select Branch
              </DropdownMenuLabel>
              <DropdownMenuSeparator />
              {organizations.map((org) => (
                <DropdownMenuItem
                  key={org}
                  onClick={() => setSelectedOrg(org)}
                  className={cn(
                    'justify-between rounded-lg px-2 py-2.5',
                    org === selectedOrg
                      ? 'text-primary font-semibold'
                      : 'text-muted-foreground',
                  )}
                >
                  <span>{org}</span>
                  {org === selectedOrg && (
                    <Check className="text-primary size-4" />
                  )}
                </DropdownMenuItem>
              ))}
            </DropdownMenuGroup>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
    </header>
  );
}
```

### `src/components/dashboards/library-dashboard/dashboard-layout.tsx`

```tsx
import type { CSSProperties, ReactNode } from 'react';
import { DashboardSidebar } from './components/library/sidebar';
import { DashboardTopbar } from './components/library/topbar';
import { SidebarProvider } from '@/components/ui/sidebar';
import { TooltipProvider } from '@/components/ui/tooltip';
import './dashboard.css';

export default function DashboardLayout({ children }: { children: ReactNode }) {
  return (
    <TooltipProvider>
      <SidebarProvider
        defaultOpen={true}
        className="library-dashboard h-svh overflow-hidden"
        style={
          {
            '--sidebar-width': '18.125rem',
            '--sidebar-width-icon': '5rem',
          } as CSSProperties
        }
      >
        <DashboardSidebar />
        <main className="flex-1 overflow-y-auto">
          <DashboardTopbar />
          <div className="px-5 md:px-6 py-6 md:py-8 max-md:mb-16">
            {children}
          </div>
        </main>
      </SidebarProvider>
    </TooltipProvider>
  );
}
```

### `src/components/dashboards/library-dashboard/dashboard.css`

```css
.library-dashboard,
body:has(.library-dashboard) [data-mobile='true'][data-sidebar='sidebar'],
body:has(.library-dashboard) [data-slot='dropdown-menu-content'],
body:has(.library-dashboard) [data-slot='sheet-content'],
body:has(.library-dashboard) [data-slot='tooltip-content'] {
  --background: #ffffff;
  --foreground: #0a1b39;
  --card: #ffffff;
  --card-foreground: #0a1b39;
  --popover: #ffffff;
  --popover-foreground: #0a1b39;
  --primary: #ff5150;
  --primary-foreground: #ffffff;
  --secondary: #f7f7f7;
  --secondary-foreground: #242424;
  --muted: #f8f8f8;
  --muted-foreground: #858585;
  --accent: #edf3fc;
  --accent-foreground: #485066;
  --destructive: #ff5150;
  --border: #ededed;
  --input: var(--secondary);
  --ring: #ff5150;
  --chart-1: #ff5150;
  --chart-2: #0a1b39;
  --chart-3: #edf3fc;
  --chart-4: #858585;
  --chart-5: #242424;
  --radius: 0.5rem;
  --sidebar: #ffffff;
  --sidebar-foreground: #0a1b39;
  --sidebar-primary: #ff5150;
  --sidebar-primary-foreground: #ffffff;
  --sidebar-accent: #fff2f2;
  --sidebar-accent-foreground: #ff5150;
  --sidebar-border: #e4e4e4;
  --sidebar-ring: #ff5150;
  --input-placeholder: #485066;
  background-color: var(--background);
  color: var(--foreground);
}

.library-dashboard.dark,
.dark .library-dashboard,
.dark body:has(.library-dashboard) [data-mobile='true'][data-sidebar='sidebar'],
.dark body:has(.library-dashboard) [data-slot='dropdown-menu-content'],
.dark body:has(.library-dashboard) [data-slot='sheet-content'],
.dark body:has(.library-dashboard) [data-slot='tooltip-content'] {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: #ff5150;
  --primary-foreground: #ffffff;
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --border: oklch(1 0 0 / 10%);
  --input: var(--secondary);
  --ring: oklch(0.556 0 0);
  --sidebar: oklch(0.205 0 0);
  --sidebar-foreground: oklch(0.985 0 0);
  --sidebar-primary: #ff5150;
  --sidebar-primary-foreground: #ffffff;
  --sidebar-accent: oklch(0.269 0 0);
  --sidebar-accent-foreground: oklch(0.985 0 0);
  --sidebar-border: oklch(1 0 0 / 10%);
  --sidebar-ring: oklch(0.556 0 0);
  --input-placeholder: oklch(0.72 0.04 269);
}

body:has(.library-dashboard) [data-slot='tooltip-content'] {
  background-color: var(--foreground) !important;
  color: var(--background) !important;
}

body:has(.library-dashboard) [data-slot='tooltip-content'] > svg {
  background-color: var(--foreground) !important;
  fill: var(--foreground) !important;
}

.library-dashboard .bg-input {
  background-color: var(--input);
}

.library-dashboard input::placeholder,
.library-dashboard textarea::placeholder {
  color: var(--input-placeholder);
}

.library-dashboard * {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.library-dashboard *::-webkit-scrollbar {
  display: none;
}

/* custom classes */
.no-scrollbar,
.no-scrollbar * {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.no-scrollbar::-webkit-scrollbar,
.no-scrollbar *::-webkit-scrollbar {
  display: none;
}
```

### `src/components/dashboards/library-dashboard/data.ts`

```ts
import type { ComponentType, SVGProps } from 'react';

import {
  AiIdeaIcon,
  Alert02Icon,
  ArrowDown02Icon,
  BookMinusIcon,
  BookOpen02Icon,
  BookPlusIcon,
  CatalogIcon,
  CheckoutIcon,
  CirculationIcon,
  DashboardIcon,
  IntelligenceIcon,
  MembersIcon,
  OpacIcon,
  ReportsIcon,
  ReturnIcon,
} from './components/library/icons';

export type NavigationIcon = ComponentType<SVGProps<SVGSVGElement>>;

export type NavigationItem = {
  label: string;
  href: string;
  icon: NavigationIcon;
  section: string;
  subItems?: {
    label: string;
    href: string;
    icon: NavigationIcon;
  }[];
};

export const primaryNavigation: NavigationItem[] = [
  {
    label: 'Dashboard',
    href: '/',
    icon: DashboardIcon,
    section: 'dashboard',
  },
  {
    label: 'Catalog',
    href: '/catalog',
    icon: CatalogIcon,
    section: 'catalog',
    subItems: [
      { label: 'Items', href: '/catalog/items', icon: CatalogIcon },
      {
        label: 'Categories',
        href: '/catalog/categories',
        icon: ReportsIcon,
      },
      { label: 'Authors', href: '/catalog/authors', icon: MembersIcon },
    ],
  },
  {
    label: 'Circulation',
    href: '/circulation',
    icon: CirculationIcon,
    section: 'circulation',
  },
  {
    label: 'Members',
    href: '/members',
    icon: MembersIcon,
    section: 'members',
  },
  {
    label: 'OPAC',
    href: '/opac',
    icon: OpacIcon,
    section: 'opac',
  },
  {
    label: 'Library Intelligence',
    href: '/library-intelligence',
    icon: IntelligenceIcon,
    section: 'library-intelligence',
  },
  {
    label: 'Reports',
    href: '/reports',
    icon: ReportsIcon,
    section: 'reports',
  },
];

export const organizations = [
  'Springfield Public Library',
  'Shelbyville Library',
  'Capitol City Library',
  'Ogdenville Archives',
] as const;

export const topNavNotifications = [
  {
    id: 1,
    text: 'New book added: "The Art of Computer Programming"',
    time: '2 min ago',
    unread: true,
  },
  {
    id: 2,
    text: 'Sarah P. checked out "The Cartographer\'s Secret"',
    time: '12 min ago',
    unread: true,
  },
  {
    id: 3,
    text: 'System generated 47 purchase recommendations',
    time: '1 hr ago',
    unread: false,
  },
  {
    id: 4,
    text: 'Yuki K. returned "Silk Road Chronicles"',
    time: '2 hr ago',
    unread: false,
  },
] as const;

export const metrics = [
  {
    label: 'Total Items',
    value: '12,847',
    note: '+34 vs last month',
    icon: BookOpen02Icon,
    iconClassName: 'text-[#3B82F6]',
  },
  {
    label: 'Active Members',
    value: '140',
    note: '+12 today',
    icon: MembersIcon,
    iconClassName: 'text-[#A855F7]',
  },
  {
    label: 'items Borrowed',
    value: '16',
    note: '9.3% of collection',
    icon: BookMinusIcon,
    iconClassName: 'text-[#22C55E]',
  },
  {
    label: 'Overdue Items',
    value: '47',
    note: '8 from last week',
    icon: Alert02Icon,
    iconClassName: 'text-[#F59E0B]',
    noteIcon: ArrowDown02Icon,
  },
];

type CirculationTimeframe = 'weekly' | 'monthly' | 'yearly';

type CirculationDataPoint = {
  timestamp: number;
  checkouts: number;
  returns: number;
};

const DAY_IN_MS = 24 * 60 * 60 * 1000;

function createDailyCirculationSeries(
  start: number,
  checkouts: number[],
  returns: number[],
): CirculationDataPoint[] {
  return checkouts.map((value, index) => ({
    timestamp: start + index * DAY_IN_MS,
    checkouts: value,
    returns: returns[index],
  }));
}

function createMonthlyCirculationSeries(
  year: number,
  checkouts: number[],
  returns: number[],
): CirculationDataPoint[] {
  return checkouts.map((value, month) => ({
    timestamp: Date.UTC(year, month, 1),
    checkouts: value,
    returns: returns[month],
  }));
}

export const circulationData: Record<
  CirculationTimeframe,
  CirculationDataPoint[]
> = {
  weekly: createDailyCirculationSeries(
    Date.UTC(2026, 1, 15),
    [82, 88, 85, 91, 94, 90, 96],
    [68, 70, 73, 69, 77, 75, 80],
  ),
  monthly: createDailyCirculationSeries(
    Date.UTC(2026, 1, 1),
    [
      580, 592, 600, 594, 610, 625, 638, 646, 652, 660, 641, 632, 628, 620, 618,
      630, 635, 632, 620, 610, 625, 640, 668, 690, 688, 695, 704, 698,
    ],
    [
      430, 438, 445, 448, 452, 460, 472, 480, 486, 490, 482, 475, 468, 472, 478,
      481, 486, 480, 474, 470, 478, 490, 502, 515, 520, 524, 530, 528,
    ],
  ),
  yearly: createMonthlyCirculationSeries(
    2026,
    [4800, 4920, 5100, 5050, 5280, 5400, 5520, 5680, 5900, 6120, 6240, 6380],
    [3600, 3680, 3760, 3820, 3900, 4020, 4100, 4210, 4380, 4500, 4620, 4700],
  ),
};

export const collectionOverview = {
  label: 'Items',
  segments: [
    { label: 'Print', count: 5245, color: '#f10806' },
    { label: 'Digital', count: 4745, color: '#ff5150' },
    { label: 'Media', count: 2497, color: '#ffacac' },
  ],
} as const;

export const recentActivity = [
  {
    id: 'book-added',
    icon: BookPlusIcon,
    parts: [
      { text: 'New book added: ', muted: true },
      { text: '"The Art of Computer Programming"' },
    ],
    time: '2 min ago',
    dateTime: '2026-02-19T08:58:00',
  },
  {
    id: 'checkout',
    icon: CheckoutIcon,
    parts: [
      { text: 'Sarah P. ' },
      { text: 'checked out ', muted: true },
      { text: '"The Cartographer\u2019s Secret"' },
    ],
    time: '2 min ago',
    dateTime: '2026-02-19T08:58:00',
  },
  {
    id: 'titles-flagged',
    icon: AiIdeaIcon,
    parts: [
      { text: 'Intelligence ' },
      { text: 'flagged ', muted: true },
      { text: '3,280 dormant titles ' },
      { text: 'for collection review', muted: true },
    ],
    time: '1 hr ago',
    dateTime: '2026-02-19T08:00:00',
  },
  {
    id: 'return',
    icon: ReturnIcon,
    parts: [
      { text: 'Yuki K. ' },
      { text: 'returned ', muted: true },
      { text: '\u201cSilk Road Chronicles\u201d' },
    ],
    time: '2 hr ago',
    dateTime: '2026-02-19T07:00:00',
  },
  {
    id: 'recommendations',
    icon: AiIdeaIcon,
    parts: [
      { text: 'Intelligence ' },
      { text: 'generated ', muted: true },
      { text: '47 purchase recommendations' },
    ],
    time: '3 hr ago',
    dateTime: '2026-02-19T06:00:00',
  },
] as const;

export const intelligenceCards = [
  {
    tone: 'insight',
    title: 'High Demand Alert',
    bodyParts: [
      { text: '"Project Hail Mary"', emphasis: true },
      {
        text: ' has a 6-member waitlist. 2 additional copies would clear the backlog within 3 weeks.',
      },
    ],
  },
  {
    tone: 'warning',
    title: 'Collection Gap',
    bodyParts: [
      {
        text: "Member searches for 'climate fiction' are up 340% this month, only 2 titles in collection. Consider acquiring more.",
      },
    ],
  },
  {
    tone: 'success',
    title: 'Auto-Sort',
    bodyParts: [
      {
        text: '47 returned items have been categorised and shelf locations assigned. 3 items flagged for condition review.',
      },
    ],
  },
] as const;
```

### `src/components/dashboards/library-dashboard/demo.tsx`

```tsx
import DashboardLayout from './dashboard-layout';
import { DashboardContent } from './components/library/dashboard-content';
import { ThemeProvider } from './components/library/theme-provider';

export default function LibraryDashboardDemo() {
  return (
    <ThemeProvider>
      <DashboardLayout>
        <DashboardContent />
      </DashboardLayout>
    </ThemeProvider>
  );
}
```
