# Incident management

A shadcn/ui block from the [@watermelon](https://ui.watermelon.sh/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/watermelon/incident-management).

- Page, with a live preview: https://shadcn.exchange/r/watermelon/incident-management
- Screenshot: https://shadcn.exchange/shot/watermelon/incident-management/light.png
- Registry item: https://registry.watermelon.sh/r/incident-management.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/watermelon/incident-management.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: `@radix-ui/react-avatar`, `@radix-ui/react-checkbox`, `@radix-ui/react-collapsible`, `@radix-ui/react-dialog`, `@radix-ui/react-dropdown-menu`, `@radix-ui/react-label`, `@radix-ui/react-select`, `@radix-ui/react-separator`, `@radix-ui/react-slot`, `@radix-ui/react-tabs`, `@radix-ui/react-tooltip`, `@tabler/icons-react`, `class-variance-authority`, `lucide-react`, `react-router-dom`, `recharts`
- Registry items: `avatar`, `badge`, `breadcrumb`, `button`, `card`, `chart`, `checkbox`, `collapsible`, `dialog`, `dropdown-menu`, `input`, `label`, `select`, `separator`, `sheet`, `sidebar`, `skeleton`, `table`, `tabs`, `tooltip`, `utils`

## Files

### `src/components/dashboards/incident-management/activeStreamViews.tsx`

```tsx
"use client"

import {
    IconTournament,
    IconLayoutNavbar,
    IconHistory,
    IconFolder,
    IconPlus,
    IconSettings,
    IconClock,
    IconHourglass,
} from "@tabler/icons-react"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue
} from "@/components/ui/select"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { SidebarTrigger } from "@/components/ui/sidebar"
import { KanbanColumn } from "./components/active-streams/kanban-column"
import { detectedCards, acknowledgedCards, investigatingCards, resolvedCards } from "./components/active-streams/constants"

export function ActiveStreamViews() {
    return (
        <div className="flex-1 flex flex-col w-full bg-white dark:bg-neutral-950 overflow-hidden min-h-0">
            {/* Header */}
            <div className="py-4 px-7 flex items-start justify-between">
                <div className="flex flex-col gap-0">
                    <h1 className="text-2xl font-medium tracking-tighter text-neutral-900 dark:text-neutral-100">Activity stream</h1>
                    <p className="text-neutral-500 dark:text-neutral-400 text-base tracking-tight">Real-time system activity across teams</p>
                </div>
                <div className="md:hidden pt-1">
                    <SidebarTrigger className="text-neutral-500" />
                </div>
            </div>

            <Tabs defaultValue="flowView" className="flex-1 flex flex-col min-h-0">
                {/* Tab List */}
                <div className="px-6 border-b dark:border-neutral-800 overflow-x-auto scrollbar-hide">
                    <TabsList className="bg-transparent h-16 p-0 gap-6 max-md:w-max justify-start">
                        {[
                            { value: "flowView", label: "Flow view", icon: IconTournament },
                            { value: "capacityView", label: "Capacity view", icon: IconLayoutNavbar },
                            { value: "history", label: "History", icon: IconHistory },
                            { value: "actionLog", label: "Action log", icon: IconFolder },
                        ].map((tab) => (
                            <TabsTrigger
                                key={tab.value}
                                value={tab.value}
                                disabled={tab.value !== "flowView"}
                                className="group bg-transparent dark:bg-transparent data-[state=active]:bg-transparent dark:data-[state=active]:bg-transparent shadow-none! data-[state=active]:shadow-none! border-t-0! border-x-0! border-b-0! data-[state=active]:border-b-[1.5px]! data-[state=active]:border-orange-500! dark:data-[state=active]:border-orange-500! rounded-none flex items-center gap-2 font-medium data-[state=active]:font-medium tracking-tight data-[state=active]:text-neutral-800 dark:data-[state=active]:text-neutral-200 transition-colors duration-300 text-[15px] px-1 h-9 text-neutral-500 dark:text-neutral-400 max-md:whitespace-nowrap focus:ring-0! focus:outline-none! focus-visible:ring-0! focus-visible:outline-none! focus-visible:border-t-0! focus-visible:border-x-0! cursor-pointer"
                            >
                                <tab.icon className="size-5 text-neutral-400 dark:text-neutral-500 group-data-[state=active]:text-orange-500 dark:group-data-[state=active]:text-orange-500 transition-colors duration-300" strokeWidth={1.5} />
                                <span className="">{tab.label}</span>
                            </TabsTrigger>))}
                    </TabsList>
                </div>

                <TabsContent value="flowView" className="flex-1 flex flex-col p-6 pt-3 bg-white dark:bg-neutral-950 overflow-hidden gap-7 min-h-0">
                    {/* Filters */}
                    <div className="flex flex-wrap items-center gap-4">
                        <Button variant="outline" className="bg-neutral-200/50 dark:bg-neutral-900/50 hover:bg-[#f2f2f2] dark:hover:bg-neutral-800 border-neutral-100/50 dark:border-neutral-800/50 rounded-lg px-3 flex items-center gap-3 font-medium text-neutral-800 dark:text-neutral-200 shadow-none transition-colors duration-300 cursor-pointer">
                            Filter
                            <Badge variant="secondary" className="bg-white dark:bg-neutral-800 text-neutral-500 dark:text-neutral-400 rounded px-2 py-0.5 size-4 flex justify-center shadow border dark:border-neutral-700">0</Badge>
                        </Button>
                        {[
                            {
                                label: "Assigned unit",
                                value: "unit",
                                options: ["All Units", "Frontend Team", "Backend Team", "DevOps", "Security"]
                            },
                            {
                                label: "Service type",
                                value: "service",
                                options: ["All Services", "Authentication", "Database", "Payment Gateway", "API Gateway"]
                            },
                            {
                                label: "Resolution window",
                                value: "resolution",
                                options: ["Any Time", "< 1 Hour", "1-4 Hours", "4-24 Hours", "> 24 Hours"]
                            },
                            {
                                label: "Impact",
                                value: "impact",
                                options: ["All Levels", "Critical", "High", "Medium", "Low"]
                            },
                        ].map((filter) => (
                            <Select key={filter.value}>
                                <SelectTrigger className="w-fit bg-white dark:bg-neutral-900 border-neutral-200 dark:border-neutral-800 rounded-lg pl-3 pr-2 font-medium text-neutral-400 dark:text-neutral-500 hover:bg-neutral-100/50 dark:hover:bg-neutral-800/60 shadow-none transition-colors duration-300 cursor-pointer text-sm focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-neutral-400 dark:focus-visible:border-neutral-600 outline-none hover:text-neutral-700! dark:hover:text-neutral-300!">
                                    <SelectValue placeholder={filter.label} />
                                </SelectTrigger>
                                <SelectContent className="rounded-xl border-neutral-100 dark:border-neutral-800 shadow-xl">
                                    {filter.options.map(option => (
                                        <SelectItem key={option} value={option.toLowerCase().replace(/\s+/g, '-')}>{option}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        ))}
                    </div>

                    {/* Kanban Grid */}
                    <div className="flex-1 flex gap-6 overflow-auto over min-h-0 scrollbar-hide">
                        <KanbanColumn title="Detected" count={12} cards={detectedCards} icon={IconClock} />
                        <KanbanColumn title="Acknowledged" count={4} cards={acknowledgedCards} icon={IconHourglass} />
                        <KanbanColumn title="Investigating" count={1} cards={investigatingCards} icon={IconSettings} />
                        <KanbanColumn title="Resolved" count={1} cards={resolvedCards} icon={IconPlus} />
                    </div>
                </TabsContent>
            </Tabs>
        </div>
    )
}
```

### `src/components/dashboards/incident-management/components/active-streams/constants.tsx`

```tsx
import {
    IconTrolley,
    IconDatabase,
    IconApi,
    IconCreditCard,
    IconSettings,
    IconBolt,
    IconHourglass,
    IconBox
} from "@tabler/icons-react"
import type { StreamCardProps } from "./types"

export const detectedCards: StreamCardProps[] = [
    {
        id: "1",
        title: "Service Flow Interruption",
        code: "#OPS-129",
        avatar: "https://github.com/shadcn.png",
        logo: <IconTrolley className="size-4" />,
        logoBg: "bg-orange-500",
        details: {
            origin: "Customer Mobile App",
            priority: "High Impact",
            handler: "Platform operations",
            process: "Incident resolution",
            date: "Jan 24, 2026",
        },
        tags: [
            { label: "Time-Sensitive", icon: <IconHourglass className="size-4" />, color: "text-amber-600", bg: "bg-amber-50" },
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
            { label: "Live", icon: <IconBolt className="size-4" />, color: "text-orange-600", bg: "bg-orange-50" },
        ],
        messages: 3,
        time: "22hr ago",
    },
    {
        id: "2",
        title: "Database Downtime",
        code: "#OPS-130",
        avatar: "https://i.pravatar.cc/150?u=2",
        logo: <IconDatabase className="size-4" />,
        logoBg: "bg-blue-600",
        details: {
            origin: "User Management System",
            priority: "Moderate",
            handler: "IT Support",
            process: "Database recovery",
            date: "Jan 27, 2026",
        },
        tags: [
            { label: "Time-Sensitive", icon: <IconHourglass className="size-4" />, color: "text-amber-600", bg: "bg-amber-50" },
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
        ],
        messages: 5,
        time: "5hr ago",
    },
]

export const acknowledgedCards: StreamCardProps[] = [
    {
        id: "3",
        title: "API Rate Limiting",
        code: "#OPS-131",
        avatar: "https://i.pravatar.cc/150?u=3",
        logo: <IconApi className="size-4" />,
        logoBg: "bg-emerald-600",
        details: {
            origin: "Third-party Integration",
            priority: "Minor",
            handler: "Integration Team",
            process: "Throttling Policy",
            date: "Jan 26, 2026",
        },
        tags: [
            { label: "Time-Sensitive", icon: <IconHourglass className="size-4" />, color: "text-amber-600", bg: "bg-amber-50" },
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
        ],
        messages: 1,
        time: "10hr ago",
    },
    {
        id: "4",
        title: "Payment Processing Delay",
        code: "#OPS-132",
        avatar: "https://i.pravatar.cc/150?u=4",
        logo: <IconCreditCard className="size-4" />,
        logoBg: "bg-purple-600",
        details: {
            origin: "E-commerce Portal",
            priority: "Critical",
            handler: "Finance Ops",
            process: "Payment Gateway",
            date: "Jan 28, 2026",
        },
        tags: [
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
            { label: "Live", icon: <IconBolt className="size-4" />, color: "text-orange-600", bg: "bg-orange-50" },
        ],
        messages: 2,
        time: "1hr ago",
    },
]

export const investigatingCards: StreamCardProps[] = [
    {
        id: "5",
        title: "Worker Node Failure",
        code: "#OPS-133",
        avatar: "https://i.pravatar.cc/150?u=5",
        logo: <IconSettings className="size-4" />,
        logoBg: "bg-rose-600",
        details: {
            origin: "Cluster Manager",
            priority: "High Impact",
            handler: "SRE Team",
            process: "Node Replacement",
            date: "Jan 28, 2026",
        },
        tags: [
            { label: "Time-Sensitive", icon: <IconHourglass className="size-4" />, color: "text-amber-600", bg: "bg-amber-50" },
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
        ],
        messages: 4,
        time: "30m ago",
    }
]

export const resolvedCards: StreamCardProps[] = [
    {
        id: "6",
        title: "DNS Resolution Error",
        code: "#OPS-128",
        avatar: "https://i.pravatar.cc/150?u=6",
        logo: <IconBolt className="size-4" />,
        logoBg: "bg-neutral-600",
        details: {
            origin: "Internal Network",
            priority: "Major",
            handler: "Networking Team",
            process: "DNS Cache Flush",
            date: "Jan 23, 2026",
        },
        tags: [
            { label: "Platform", icon: <IconBox className="size-4" />, color: "text-indigo-600", bg: "bg-indigo-50" },
        ],
        messages: 12,
        time: "2d ago",
    }
]
```

### `src/components/dashboards/incident-management/components/active-streams/kanban-column.tsx`

```tsx
"use client"

import { IconPlus, IconDots } from "@tabler/icons-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from "@/components/ui/dialog"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuLabel } from "@/components/ui/dropdown-menu"
import type { StreamCardProps } from "./types"
import { StreamCard } from "./stream-card"

export const KanbanColumn = ({
    title,
    count,
    cards,
    icon: Icon
}: {
    title: string
    count: number
    cards: StreamCardProps[]
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    icon: any
}) => (
    <div className="flex-1 min-w-[340px] border-x-[1.5px] p-1.5 flex flex-col gap-4 border-neutral-100 dark:border-neutral-900 min-h-0">
        <div className="flex items-center justify-between">
            <div className="flex items-center gap-1.5 bg-neutral-200/50 dark:bg-neutral-800/50 px-2 py-1.5 rounded-lg group cursor-pointer">
                <Icon className="size-4 text-neutral-600 dark:text-neutral-400" />
                <h3 className="font text-neutral-800 dark:text-neutral-200 text-sm tracking-tight">{title}</h3>
                <Badge variant="secondary" className="bg-white dark:bg-neutral-800 text-neutral-500 dark:text-neutral-400 group-hover:shadow dark:group-hover:bg-neutral-700/50 rounded size-4.5 border-none text-[12px] transition-colors duration-300 cursor-pointer">
                    {count}
                </Badge>
            </div>
            <div className="flex items-center gap-1 text-neutral-400 dark:text-neutral-500">
                <Dialog>
                    <DialogTrigger asChild>
                        <Button variant="ghost" size="icon-sm" className=" hover:bg-neutral-200/50 dark:hover:bg-neutral-800/50 rounded-lg transition-colors duration-300 cursor-pointer">
                            <IconPlus className="size-4" />
                        </Button>
                    </DialogTrigger>
                    <DialogContent className="bg-white dark:bg-neutral-950 border-neutral-100 dark:border-neutral-800 rounded-xl shadow-xl">
                        <DialogHeader>
                            <DialogTitle className="text-neutral-900 dark:text-neutral-100 font-semibold tracking-tight">Add to {title}</DialogTitle>
                            <DialogDescription className="text-neutral-500 dark:text-neutral-400">Create a new stream item in this stage.</DialogDescription>
                        </DialogHeader>
                        <div className="grid gap-4 py-4">
                            <div className="grid gap-2">
                                <label htmlFor="title" className="text-sm font-medium leading-none text-neutral-900 dark:text-neutral-100 tracking-tight">Title</label>
                                <Input id="title" placeholder="e.g. Server Latency Spike" className="rounded-lg border-neutral-200 dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900 text-sm focus-visible:ring-1 focus-visible:ring-orange-500/50 focus-visible:border-orange-500/50 shadow-[inset_0_1px_2px_rgba(0,0,0,0.05)] transition-all" />
                            </div>
                            <div className="grid gap-2">
                                <label htmlFor="priority" className="text-sm font-medium leading-none text-neutral-900 dark:text-neutral-100 tracking-tight">Priority</label>
                                <Input id="priority" placeholder="e.g. High" className="rounded-lg border-neutral-200 dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900 text-sm focus-visible:ring-1 focus-visible:ring-orange-500/50 focus-visible:border-orange-500/50 shadow-[inset_0_1px_2px_rgba(0,0,0,0.05)] transition-all" />
                            </div>
                        </div>
                        <DialogFooter className="bg-transparent dark:bg-transparent border-t-0 p-0 sm:justify-end gap-2 mx-0 mb-0 mt-0">
                            <DialogClose asChild>
                                <Button variant="outline" className="rounded-lg bg-white dark:bg-neutral-900 border-neutral-200 dark:border-neutral-800 text-neutral-600 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 shadow-none font-medium transition-colors">Cancel</Button>
                            </DialogClose>
                            <Button className="bg-orange-500 hover:bg-orange-600 text-white rounded-lg shadow-none border-none font-medium transition-colors">Save Item</Button>
                        </DialogFooter>
                    </DialogContent>
                </Dialog>
                <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                        <Button variant="ghost" size="icon-sm" className="hover:bg-neutral-200/50 dark:hover:bg-neutral-800/50 rounded-lg transition-colors duration-300 cursor-pointer">
                            <IconDots className="size-4" />
                        </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end" className="w-48 rounded-xl shadow-xl dark:border-neutral-800">
                        <DropdownMenuLabel>Column Actions</DropdownMenuLabel>
                        <DropdownMenuSeparator />
                        <DropdownMenuItem className="cursor-pointer">Edit Column</DropdownMenuItem>
                        <DropdownMenuItem className="cursor-pointer">Sort Items</DropdownMenuItem>
                        <DropdownMenuItem className="cursor-pointer text-red-600 dark:text-red-400 focus:text-red-600 dark:focus:text-red-400 focus:bg-red-50 dark:focus:bg-red-950/30">Clear All</DropdownMenuItem>
                    </DropdownMenuContent>
                </DropdownMenu>
            </div>
        </div>
        <div className="flex-1 overflow-y-auto flex flex-col gap-2 pb-2 scrollbar-hide">
            {cards.map((card) => (
                <StreamCard key={card.id} card={card} />
            ))}
        </div>
    </div>
)
```

### `src/components/dashboards/incident-management/components/active-streams/stream-card.tsx`

```tsx
"use client"

import {
    IconUser,
    IconFlag,
    IconAlertTriangle,
    IconTool,
    IconSettings,
    IconCalendar,
    IconMessage,
    IconClock
} from "@tabler/icons-react"
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { cn } from "@/lib/utils"
import type { StreamCardProps } from "./types"

const getDarkBadgeStyles = (bg: string) => {
    const colorMap: Record<string, string> = {
        amber: "dark:bg-amber-900/10 dark:text-amber-500",
        indigo: "dark:bg-indigo-900/10 dark:text-indigo-500",
        orange: "dark:bg-orange-900/10 dark:text-orange-500",
        emerald: "dark:bg-emerald-900/10 dark:text-emerald-500",
        rose: "dark:bg-rose-900/10 dark:text-rose-500",
        blue: "dark:bg-blue-900/10 dark:text-blue-500",
        purple: "dark:bg-purple-900/10 dark:text-purple-500",
    };

    const colorName = Object.keys(colorMap).find((c) => bg.includes(c));
    return colorName ? colorMap[colorName] : "dark:bg-neutral-800 dark:text-neutral-300";
};

export const StreamCard = ({ card }: { card: StreamCardProps }) => (
    <Card className="shadow-none bg-neutral-200/35 dark:bg-neutral-900 rounded-lg border-none px-3 py-2.5 gap-3 transition-colors duration-300 hover:bg-muted/50 cursor-pointer group">
        <CardHeader className="p-0 flex flex-row items-start justify-between space-y-0">
            <div className="flex gap-2">
                <div className={cn("size-7 rounded-sm flex items-center justify-center text-white shadow-sm", card.logoBg)}>
                    {card.logo}
                </div>
                <div className="grid gap-0.5">
                    <h4 className="text-base font-medium leading-tight tracking-tight text-neutral-900 dark:text-neutral-100">{card.title}</h4>
                    <span className="text-[13px] text-neutral-500 dark:text-neutral-400 font-medium">{card.code}</span>
                </div>
            </div>
            <Avatar className="size-8 border-2 border-white dark:border-neutral-800 shadow-sm transition-colors duration-300 hover:ring-2 hover:ring-indigo-500/30 cursor-pointer">
                <AvatarImage src={card.avatar} className="grayscale hover:grayscale-0 transition-colors duration-300" />
                <AvatarFallback>
                    <IconUser className="size-4" />
                </AvatarFallback>
            </Avatar>
        </CardHeader>
        <CardContent className="p-5 pt-2 grid gap-3 bg-white dark:bg-neutral-950 rounded-lg">
            <div className="grid gap-2.5 py-1 dark:border-neutral-800/50">
                {[
                    { label: "Origin", value: card.details.origin, icon: <IconFlag className="size-4" /> },
                    { label: "Priority", value: card.details.priority, icon: <IconAlertTriangle className="size-4" /> },
                    { label: "Handler", value: card.details.handler, icon: <IconTool className="size-4" /> },
                    { label: "Process", value: card.details.process, icon: <IconSettings className="size-4" /> },
                    { label: "Date", value: card.details.date, icon: <IconCalendar className="size-4" /> },
                ].map((detail) => (
                    <div key={detail.label} className="flex items-center gap-12 text-[14px]">
                        <div className="flex items-center gap-2.5 text-neutral-400 dark:text-neutral-500 w-[100px]">
                            <span className="text-neutral-500 dark:text-neutral-400">{detail.icon}</span>
                            <span className="text-neutral-500 dark:text-neutral-400 text-xs font-semibold">{detail.label}</span>
                        </div>
                        <span className="text-neutral-900 dark:text-neutral-100 text-xs font-semibold tracking-tight max-md:truncate max-md:max-w-[100px]">{detail.value}</span>
                    </div>
                ))}
            </div>
            <div className="flex flex-wrap gap-2 mt-1">
                {card.tags.map((tag, i) => (
                    <Badge
                        key={i}
                        variant="secondary"
                        className={cn(
                            "flex items-center gap-1.5 px-2 py-1 rounded-full shadow-none text-[12px] tracking-tight transition-colors duration-300 hover:shadow-sm cursor-pointer border dark:border-neutral-700/50",
                            tag.bg,
                            tag.color,
                            getDarkBadgeStyles(tag.bg)
                        )}
                    >
                        <span className="flex items-center justify-center">{tag.icon}</span>
                        {tag.label}
                    </Badge>
                ))}
            </div>
        </CardContent>
        <CardFooter className="flex items-center gap-5 text-neutral-500 dark:text-neutral-400 text-[11px] font-medium border-neutral-50 dark:border-neutral-800 px-0">
            <div className="flex items-center gap-1 cursor-pointer hover:text-neutral-600 dark:hover:text-neutral-300 transition-colors">
                <IconMessage className="size-3.5" />
                <span>{card.messages}</span>
            </div>
            <div className="flex items-center gap-1">
                <IconClock className="size-3.5" />
                <span>{card.time}</span>
            </div>
        </CardFooter>
    </Card>
)
```

### `src/components/dashboards/incident-management/components/active-streams/types.ts`

```ts
export interface StreamCardProps {
    id: string
    title: string
    code: string
    avatar: string
    logo: React.ReactNode
    logoBg: string
    details: {
        origin: string
        priority: string
        handler: string
        process: string
        date: string
    }
    tags: { label: string; icon: React.ReactNode; color: string; bg: string }[]
    messages: number
    time: string
}
```

### `src/components/dashboards/incident-management/components/app-sidebar.tsx`

```tsx
"use client"
import * as React from "react"
import {
  Activity,
  Bot,
  Users,
  Network,
  Cpu,
  Zap,
  CalendarClock,
  ListOrdered,
  LineChart,
  AlertOctagon,
  GitPullRequestArrow,
  Grid3x3,
  Settings,
  HelpCircle,
  ChevronRight,
  ChevronsUpDown,
  ChevronDown
} from "lucide-react"
import { useLocation } from "react-router-dom"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { DropdownMenu, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarGroup,
  SidebarGroupContent,
  SidebarGroupLabel,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuButton,
  SidebarMenuItem,
  SidebarMenuSub,
  SidebarMenuSubButton,
  SidebarMenuSubItem,
  SidebarRail,
  SidebarTrigger,
} from "@/components/ui/sidebar"
import { SearchForm } from "./search-form"
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible"

const data = {
  user: {
    name: "Stephen S.",
    email: "stephen@srotimi.design",
    avatar: "/avatars/stephen.jpg",
  },
  navMain: [
    {
      title: "Activity stream",
      url: "/active-streams",
      icon: Activity,
      isActive: true,
    },
    {
      title: "Live operations",
      url: "#",
      icon: Bot,
      isDisabled: true,
    },
    {
      title: "Participants",
      url: "#",
      icon: Users,
      isDisabled: true,
    },
    {
      title: "System logic",
      url: "#",
      icon: Network,
      isDisabled: true,
      items: [
        {
          title: "Rules engine",
          url: "#",
          icon: Cpu,
          isDisabled: true,
        },
        {
          title: "Triggers",
          url: "#",
          icon: Zap,
          isDisabled: true,
        },
        {
          title: "Schedules",
          url: "#",
          icon: CalendarClock,
          isDisabled: true,
        },
      ],
    },
    {
      title: "Action queue",
      url: "#",
      icon: ListOrdered,
      isDisabled: true,
    },
    {
      title: "Insights",
      url: "#",
      icon: LineChart,
      isDisabled: true,
    },
  ],
  pinnedMonitors: [
    {
      title: "SLA breaches",
      url: "#",
      icon: AlertOctagon,
      isDisabled: true,
    },
    {
      title: "Escalated requests",
      url: "#",
      icon: GitPullRequestArrow,
      isDisabled: true,
    },
    {
      title: "High load zones",
      url: "#",
      icon: Grid3x3,
      isDisabled: true,
    },
  ],
  operatorConsole: [
    {
      title: "Settings",
      url: "#",
      icon: Settings,
      isDisabled: true,
    },
    {
      title: "Help Center",
      url: "#",
      icon: HelpCircle,
      isDisabled: true,
    },
  ],
}

interface AppSidebarProps extends React.ComponentProps<typeof Sidebar> {
  onNavigate?: (view: string) => void;
  currentView?: string;
}

export function AppSidebar({ onNavigate, currentView, ...props }: AppSidebarProps) {
  const [openPinned, setOpenPinned] = React.useState(true)
  const [openOperator, setOpenOperator] = React.useState(true)
  const location = useLocation()
  const pathname = location.pathname
  return (
    <Sidebar {...props}>
      <SidebarHeader className="px-0 pt-0 border-b">
        <SidebarMenu className="border-b h-15 pl-2.5 justify-center">
          <SidebarMenuItem>
            <SidebarMenuButton size="lg" asChild className="hover:bg-transparent">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <div className="flex aspect-square size-8 items-center justify-center rounded-md shadow-sm">
                    <img src="/logo.png" alt="Logo" width={50} height={50} className="rounded-md" />
                  </div>
                  <span className="font-semibold text-base">OceanLabs</span>
                </div>
                <div className="flex items-center justify-center size-8 rounded-md bg-[#f8f8f8] dark:bg-neutral-900 shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] transition-colors duration-300 cursor-pointer">
                  <SidebarTrigger className="text-neutral-500 dark:text-neutral-400" />
                </div>
              </div>
            </SidebarMenuButton>
          </SidebarMenuItem>
        </SidebarMenu>
        <SearchForm />
      </SidebarHeader>

      <SidebarContent className="gap-0">
        <SidebarGroup>
          <SidebarMenu className="pl-2.5 pt-2">
            {data.navMain.map((item) => (
              <Collapsible
                key={item.title}
                asChild
                defaultOpen={item.isActive}
                className="group/collapsible"
              >
                <SidebarMenuItem>
                  {item.items ? (
                    <>
                      <CollapsibleTrigger asChild>
                        <SidebarMenuButton tooltip={item.title} className="h-10 px-2.5 rounded-lg text-neutral-500 dark:text-neutral-400 font-normal text-[15.5px] tracking-tight data-[active=true]:text-white! data-[active=true]:bg-orange-500 data-[active=true]:shadow-[inset_2px_4px_8px_rgba(255,255,255,0.4),inset_-2px_-4px_8px_rgba(0,0,0,0.3)] hover:bg-[#f8f8f8] dark:hover:bg-neutral-800 hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] hover:text-neutral-500! dark:hover:text-neutral-400! transition-colors duration-300 cursor-pointer">
                          {item.icon && <item.icon className="!size-5" />}
                          <span>{item.title}</span>
                          <ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
                        </SidebarMenuButton>
                      </CollapsibleTrigger>
                      <CollapsibleContent>
                        <SidebarMenuSub>
                          {item.items?.map((subItem) => (
                            <SidebarMenuSubItem key={subItem.title}>
                              <SidebarMenuSubButton
                                asChild
                                isActive={pathname === subItem.url}
                                className="h-10 px-2.5 rounded-lg text-neutral-500 dark:text-neutral-400 font-normal text-[15.5px] tracking-tight data-[active=true]:text-white! data-[active=true]:bg-orange-500 data-[active=true]:shadow-[inset_2px_4px_8px_rgba(255,255,255,0.4),inset_-2px_-4px_8px_rgba(0,0,0,0.3)] hover:bg-[#f8f8f8] dark:hover:bg-neutral-800 hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] hover:text-neutral-500! dark:hover:text-neutral-400! transition-colors duration-300 cursor-pointer"
                              >
                                <a href={subItem.url} onClick={(e) => subItem.isDisabled && e.preventDefault()}>
                                  {subItem.icon && <subItem.icon className="size-5! text-neutral-500! dark:text-neutral-400! data-[active=true]:text-white!" />}
                                  <span>{subItem.title}</span>
                                </a>
                              </SidebarMenuSubButton>
                            </SidebarMenuSubItem>
                          ))}
                        </SidebarMenuSub>
                      </CollapsibleContent>
                    </>
                  ) : (
                    <SidebarMenuButton
                      asChild
                      tooltip={item.title}
                      isActive={currentView ? (item.title === "Activity stream" && currentView === "Activity Stream") : item.isActive}
                      className="h-10 px-2.5 rounded-lg text-neutral-500 dark:text-neutral-400 font-normal text-[15.5px] tracking-tight data-[active=true]:text-white! data-[active=true]:bg-orange-500 data-[active=true]:shadow-[inset_2px_4px_8px_rgba(255,255,255,0.4),inset_-2px_-4px_8px_rgba(0,0,0,0.3)] hover:bg-[#f8f8f8] dark:hover:bg-neutral-800 hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] hover:text-neutral-500 dark:hover:text-neutral-400 transition-colors duration-300 cursor-pointer"
                    >
                      <a
                        href={item.url}
                        onClick={(e) => {
                          if (item.isDisabled) {
                            e.preventDefault()
                            return
                          }
                          if (item.title === "Activity stream" && onNavigate) {
                            e.preventDefault()
                            onNavigate("Activity Stream")
                          }
                        }}
                      >
                        {item.icon && <item.icon className="size-5!" />}
                        <span>{item.title}</span>
                      </a>
                    </SidebarMenuButton>
                  )}
                </SidebarMenuItem>
              </Collapsible>
            ))}
          </SidebarMenu>
        </SidebarGroup>

        <SidebarGroup>
          <SidebarGroupContent className="px-2">
            <Collapsible open={openPinned} onOpenChange={setOpenPinned}>
              <CollapsibleTrigger asChild>
                <SidebarGroupLabel className="cursor-pointer" asChild>
                  <div className="flex items-center justify-between gap-1.5 text-neutral-400! dark:text-neutral-500! font-normal tracking-tight text-[15px]">
                    Pinned monitors <ChevronDown className={`size-3.5! transition-transform ${openPinned ? "rotate-180" : ""}`} />
                  </div>
                </SidebarGroupLabel>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <SidebarMenu className="px-1.5">
                  {data.pinnedMonitors.map((item) => (
                    <SidebarMenuItem key={item.title}>
                      <SidebarMenuButton
                        asChild
                        isActive={pathname === item.url}
                        className="h-9 rounded-sm hover:bg-[#f8f8f8] dark:hover:bg-neutral-800 hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] hover:text-neutral-500 dark:hover:text-neutral-400 data-[active=true]:text-white! data-[active=true]:bg-orange-500 data-[active=true]:shadow-[inset_2px_4px_8px_rgba(255,255,255,0.4),inset_-2px_-4px_8px_rgba(0,0,0,0.3)] text-neutral-500 dark:text-neutral-400 font-normal tracking-tight text-[15px] transition-colors duration-300 cursor-pointer"
                      >
                        <a href={item.url} onClick={(e) => item.isDisabled && e.preventDefault()}>
                          <item.icon className="size-5!" />
                          {item.title}
                        </a>
                      </SidebarMenuButton>
                    </SidebarMenuItem>
                  ))}
                </SidebarMenu>
              </CollapsibleContent>
            </Collapsible>
          </SidebarGroupContent>
        </SidebarGroup>

        <SidebarGroup>
          <SidebarGroupContent className="px-2.5">
            <Collapsible open={openOperator} onOpenChange={setOpenOperator}>
              <CollapsibleTrigger asChild>
                <SidebarGroupLabel className="cursor-pointer" asChild>
                  <div className="flex items-center justify-between gap-1.5 text-neutral-400! dark:text-neutral-500! font-normal tracking-tight text-[15px]">
                    Operator console <ChevronDown className={`size-3.5! transition-transform ${openOperator ? "rotate-180" : ""}`} />
                  </div>
                </SidebarGroupLabel>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <SidebarMenu className="px-1.5">
                  {data.operatorConsole.map((item) => (
                    <SidebarMenuItem key={item.title}>
                      <SidebarMenuButton
                        asChild
                        isActive={pathname === item.url}
                        className="h-9 rounded-sm hover:bg-[#f8f8f8] dark:hover:bg-neutral-800 hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:hover:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)] hover:text-neutral-500 dark:hover:text-neutral-400 data-[active=true]:text-white! data-[active=true]:bg-orange-500 data-[active=true]:shadow-[inset_2px_4px_8px_rgba(255,255,255,0.4),inset_-2px_-4px_8px_rgba(0,0,0,0.3)] text-neutral-500 dark:text-neutral-400 font-normal tracking-tight text-[15px] transition-colors duration-300 cursor-pointer"
                      >
                        <a href={item.url} onClick={(e) => item.isDisabled && e.preventDefault()}>
                          <item.icon className="size-5!" />
                          {item.title}
                        </a>
                      </SidebarMenuButton>
                    </SidebarMenuItem>
                  ))}
                </SidebarMenu>
              </CollapsibleContent>
            </Collapsible>
          </SidebarGroupContent>
        </SidebarGroup>
      </SidebarContent>

      <SidebarFooter>
        <SidebarMenu>
          <SidebarMenuItem>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <SidebarMenuButton
                  size="lg"
                  className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground transition-colors duration-300 cursor-pointer"
                >
                  <Avatar className="h-8 w-8 rounded-full">
                    <AvatarImage
                      src="https://github.com/shadcn.png"
                      alt="@shadcn"
                      className="grayscale"
                    />
                    <AvatarFallback className="rounded-lg">SS</AvatarFallback>
                  </Avatar>
                  <div className="grid flex-1 text-left text-sm leading-tight">
                    <span className="truncate font-medium">{data.user.name}</span>
                    <span className="truncate text-xs">{data.user.email}</span>
                  </div>
                  <ChevronsUpDown className="ml-auto size-4" />
                </SidebarMenuButton>
              </DropdownMenuTrigger>
            </DropdownMenu>
          </SidebarMenuItem>
        </SidebarMenu>
      </SidebarFooter>
      <SidebarRail />
    </Sidebar>
  )
}
```

### `src/components/dashboards/incident-management/components/search-form.tsx`

```tsx
import { CommandIcon, Search } from "lucide-react"

import { Label } from "@/components/ui/label"
import {
  SidebarGroup,
  SidebarGroupContent,
  SidebarInput,
} from "@/components/ui/sidebar"

export function SearchForm({ ...props }: React.ComponentProps<"form">) {
  return (
    <form {...props}>
      <SidebarGroup className="pb-1 pt-2 pl-4 pr-2">
        <SidebarGroupContent className="relative">
          <Label htmlFor="search" className="sr-only">
            Search
          </Label>
          <SidebarInput
            id="search"
            placeholder="Search"
            className="pl-8 bg-neutral-100/50 dark:bg-neutral-900! border-neutral-200 dark:border-neutral-800 text-neutral-900 dark:text-neutral-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 h-9 rounded-lg focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-neutral-400 dark:focus-visible:border-neutral-600 outline-none shadow-none"
          />
          <Search className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-neutral-400 dark:text-neutral-500 select-none" />
          <div className="absolute right-2.5 top-1/2 -translate-y-1/2 flex items-center gap-0.5 px-1.5 py-0.5 border-neutral-200 dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-800 text-neutral-400 dark:text-neutral-500 pointer-events-none rounded-sm shadow-[inset_2px_2px_5px_rgba(0,0,0,0.08),inset_-2px_-2px_5px_rgba(255,255,255,1)] dark:shadow-[inset_2px_2px_5px_rgba(0,0,0,0.4),inset_-2px_-2px_5px_rgba(255,255,255,0.05)]">
            <span className="font-medium"><CommandIcon className="size-3" /></span>
            <span className="text-[12px] font-medium">K</span>
          </div>
        </SidebarGroupContent>
      </SidebarGroup>
    </form>
  )
}
```

### `src/components/dashboards/incident-management/dashboardLayout.tsx`

```tsx
import { AppSidebar } from "./components/app-sidebar"
import {
    SidebarInset,
    SidebarProvider,
} from "@/components/ui/sidebar"


export const DashboardLayout = ({ children, onNavigate, currentView }: { children: React.ReactNode; onNavigate?: (view: string) => void; currentView?: string }) => {
    return (
        <SidebarProvider className="h-svh overflow-hidden">
            <AppSidebar onNavigate={onNavigate} currentView={currentView} />
            <SidebarInset className="overflow-hidden min-h-0">
                {children}
            </SidebarInset>
        </SidebarProvider>
    )
}
```

### `src/components/dashboards/incident-management/demo.tsx`

```tsx
import { useState } from 'react'
import { DashboardLayout } from './dashboardLayout'
import { ActiveStreamViews } from './activeStreamViews'

export default function IncidentManagementDashboardDemo() {
    const [currentView, setCurrentView] = useState("Activity Stream");

    const renderContent = () => {
        switch (currentView) {
            case "Activity Stream":
                return <ActiveStreamViews />;
            default:
                return <ActiveStreamViews />;
        }
    };

    return (
        <DashboardLayout onNavigate={setCurrentView} currentView={currentView}>
            {renderContent()}
        </DashboardLayout>
    )
}
```
