{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "logistics-network",
  "title": "Logistics Network",
  "description": "Domestic logistics map with a sidebar of stats.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "@mapcn/map",
    "sidebar",
    "separator"
  ],
  "files": [
    {
      "path": "src/registry/blocks/logistics-network/page.tsx",
      "content": "\"use client\";\n\nimport { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\nimport { hubs, routes } from \"./data\";\nimport { FilterSidebar } from \"./components/filter-sidebar\";\nimport { NetworkMap } from \"./components/network-map\";\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <FilterSidebar hubs={hubs} routes={routes} />\n      <SidebarInset>\n        <NetworkMap hubs={hubs} routes={routes} />\n      </SidebarInset>\n    </SidebarProvider>\n  );\n}\n",
      "type": "registry:page",
      "target": "app/logistics/page.tsx"
    },
    {
      "path": "src/registry/blocks/logistics-network/data.ts",
      "content": "export interface Hub {\n  id: string;\n  city: string;\n  lng: number;\n  lat: number;\n  type: \"primary\" | \"secondary\";\n  shipments: number;\n  region: \"west\" | \"midwest\" | \"south\" | \"northeast\";\n}\n\nexport interface Route {\n  from: string;\n  to: string;\n  mode: \"air\" | \"ground\";\n  shipments: number;\n  status: \"active\" | \"delayed\";\n}\n\nexport const hubs: Hub[] = [\n  {\n    id: \"ord\",\n    city: \"Chicago\",\n    lng: -87.6298,\n    lat: 41.8781,\n    type: \"primary\",\n    shipments: 1247,\n    region: \"midwest\",\n  },\n  {\n    id: \"lax\",\n    city: \"Los Angeles\",\n    lng: -118.2437,\n    lat: 34.0522,\n    type: \"primary\",\n    shipments: 1102,\n    region: \"west\",\n  },\n  {\n    id: \"jfk\",\n    city: \"New York\",\n    lng: -73.9352,\n    lat: 40.6413,\n    type: \"primary\",\n    shipments: 983,\n    region: \"northeast\",\n  },\n  {\n    id: \"dfw\",\n    city: \"Dallas\",\n    lng: -96.797,\n    lat: 32.8968,\n    type: \"primary\",\n    shipments: 856,\n    region: \"south\",\n  },\n  {\n    id: \"atl\",\n    city: \"Atlanta\",\n    lng: -84.4281,\n    lat: 33.6407,\n    type: \"primary\",\n    shipments: 914,\n    region: \"south\",\n  },\n  {\n    id: \"den\",\n    city: \"Denver\",\n    lng: -104.6731,\n    lat: 39.8617,\n    type: \"secondary\",\n    shipments: 634,\n    region: \"west\",\n  },\n  {\n    id: \"sea\",\n    city: \"Seattle\",\n    lng: -122.3321,\n    lat: 47.6062,\n    type: \"secondary\",\n    shipments: 723,\n    region: \"west\",\n  },\n  {\n    id: \"mia\",\n    city: \"Miami\",\n    lng: -80.1918,\n    lat: 25.7617,\n    type: \"secondary\",\n    shipments: 478,\n    region: \"south\",\n  },\n  {\n    id: \"phx\",\n    city: \"Phoenix\",\n    lng: -112.074,\n    lat: 33.4484,\n    type: \"secondary\",\n    shipments: 512,\n    region: \"west\",\n  },\n  {\n    id: \"iah\",\n    city: \"Houston\",\n    lng: -95.3698,\n    lat: 29.9844,\n    type: \"secondary\",\n    shipments: 698,\n    region: \"south\",\n  },\n  {\n    id: \"bos\",\n    city: \"Boston\",\n    lng: -71.0054,\n    lat: 42.3643,\n    type: \"secondary\",\n    shipments: 534,\n    region: \"northeast\",\n  },\n  {\n    id: \"sfo\",\n    city: \"San Francisco\",\n    lng: -122.4194,\n    lat: 37.7749,\n    type: \"secondary\",\n    shipments: 789,\n    region: \"west\",\n  },\n  {\n    id: \"msp\",\n    city: \"Minneapolis\",\n    lng: -93.2219,\n    lat: 44.8848,\n    type: \"secondary\",\n    shipments: 423,\n    region: \"midwest\",\n  },\n  {\n    id: \"dtw\",\n    city: \"Detroit\",\n    lng: -83.0458,\n    lat: 42.2162,\n    type: \"secondary\",\n    shipments: 456,\n    region: \"midwest\",\n  },\n  {\n    id: \"slc\",\n    city: \"Salt Lake City\",\n    lng: -111.978,\n    lat: 40.758,\n    type: \"secondary\",\n    shipments: 342,\n    region: \"west\",\n  },\n];\n\nexport const routes: Route[] = [\n  { from: \"ord\", to: \"lax\", mode: \"air\", shipments: 234, status: \"active\" },\n  { from: \"ord\", to: \"jfk\", mode: \"ground\", shipments: 312, status: \"active\" },\n  { from: \"ord\", to: \"dfw\", mode: \"air\", shipments: 189, status: \"active\" },\n  { from: \"ord\", to: \"atl\", mode: \"air\", shipments: 213, status: \"active\" },\n  { from: \"ord\", to: \"den\", mode: \"ground\", shipments: 156, status: \"active\" },\n  { from: \"ord\", to: \"msp\", mode: \"ground\", shipments: 198, status: \"active\" },\n  { from: \"ord\", to: \"dtw\", mode: \"ground\", shipments: 167, status: \"delayed\" },\n  { from: \"lax\", to: \"sfo\", mode: \"ground\", shipments: 245, status: \"active\" },\n  { from: \"lax\", to: \"sea\", mode: \"air\", shipments: 178, status: \"active\" },\n  { from: \"lax\", to: \"den\", mode: \"air\", shipments: 198, status: \"active\" },\n  { from: \"lax\", to: \"phx\", mode: \"ground\", shipments: 212, status: \"active\" },\n  { from: \"lax\", to: \"dfw\", mode: \"air\", shipments: 223, status: \"active\" },\n  { from: \"jfk\", to: \"atl\", mode: \"air\", shipments: 267, status: \"active\" },\n  { from: \"jfk\", to: \"mia\", mode: \"air\", shipments: 234, status: \"active\" },\n  { from: \"jfk\", to: \"bos\", mode: \"ground\", shipments: 189, status: \"active\" },\n  { from: \"jfk\", to: \"ord\", mode: \"air\", shipments: 278, status: \"active\" },\n  { from: \"dfw\", to: \"atl\", mode: \"air\", shipments: 198, status: \"active\" },\n  { from: \"dfw\", to: \"iah\", mode: \"ground\", shipments: 245, status: \"active\" },\n  { from: \"dfw\", to: \"den\", mode: \"air\", shipments: 167, status: \"active\" },\n  { from: \"dfw\", to: \"phx\", mode: \"ground\", shipments: 156, status: \"delayed\" },\n  { from: \"atl\", to: \"mia\", mode: \"ground\", shipments: 234, status: \"active\" },\n  { from: \"atl\", to: \"iah\", mode: \"air\", shipments: 189, status: \"active\" },\n  { from: \"den\", to: \"sea\", mode: \"air\", shipments: 178, status: \"active\" },\n  { from: \"den\", to: \"slc\", mode: \"ground\", shipments: 198, status: \"active\" },\n  { from: \"den\", to: \"phx\", mode: \"air\", shipments: 167, status: \"active\" },\n  { from: \"sea\", to: \"sfo\", mode: \"air\", shipments: 212, status: \"active\" },\n  { from: \"sfo\", to: \"phx\", mode: \"air\", shipments: 156, status: \"active\" },\n  { from: \"mia\", to: \"iah\", mode: \"air\", shipments: 198, status: \"active\" },\n  { from: \"msp\", to: \"ord\", mode: \"ground\", shipments: 189, status: \"active\" },\n  { from: \"msp\", to: \"den\", mode: \"air\", shipments: 145, status: \"active\" },\n  { from: \"dtw\", to: \"ord\", mode: \"ground\", shipments: 167, status: \"active\" },\n  { from: \"dtw\", to: \"jfk\", mode: \"air\", shipments: 178, status: \"active\" },\n  { from: \"bos\", to: \"jfk\", mode: \"ground\", shipments: 156, status: \"active\" },\n  { from: \"slc\", to: \"den\", mode: \"ground\", shipments: 134, status: \"active\" },\n  { from: \"slc\", to: \"phx\", mode: \"air\", shipments: 123, status: \"delayed\" },\n  { from: \"ord\", to: \"sfo\", mode: \"air\", shipments: 198, status: \"active\" },\n  { from: \"ord\", to: \"mia\", mode: \"air\", shipments: 245, status: \"active\" },\n  { from: \"lax\", to: \"atl\", mode: \"air\", shipments: 289, status: \"active\" },\n  { from: \"jfk\", to: \"dfw\", mode: \"air\", shipments: 234, status: \"active\" },\n  { from: \"atl\", to: \"ord\", mode: \"air\", shipments: 267, status: \"active\" },\n  { from: \"sfo\", to: \"den\", mode: \"air\", shipments: 189, status: \"active\" },\n];\n\nexport const modeConfig = {\n  air: { color: \"#3b82f6\", label: \"Air\" },\n  ground: { color: \"#22c55e\", label: \"Ground\" },\n} as const;\n\nexport const statusConfig = {\n  active: { color: \"#10b981\", label: \"Active\" },\n  delayed: { color: \"#f59e0b\", label: \"Delayed\" },\n} as const;\n\nexport const regionLabels: Record<Hub[\"region\"], string> = {\n  west: \"West\",\n  midwest: \"Midwest\",\n  south: \"South\",\n  northeast: \"Northeast\",\n};\n",
      "type": "registry:component",
      "target": "app/logistics/data.ts"
    },
    {
      "path": "src/registry/blocks/logistics-network/components/filter-sidebar.tsx",
      "content": "\"use client\";\n\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarGroupLabel,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuBadge,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarSeparator,\n} from \"@/components/ui/sidebar\";\nimport { Network, Plane, Truck } from \"lucide-react\";\nimport { regionLabels, statusConfig, type Hub, type Route } from \"../data\";\n\nconst regionIcons: Record<Hub[\"region\"], string> = {\n  west: \"W\",\n  midwest: \"MW\",\n  south: \"S\",\n  northeast: \"NE\",\n};\n\ninterface FilterSidebarProps {\n  hubs: Hub[];\n  routes: Route[];\n}\n\nexport function FilterSidebar({ hubs, routes }: FilterSidebarProps) {\n  const totalShipments = routes.reduce((s, r) => s + r.shipments, 0);\n  const activeCount = routes.filter((r) => r.status === \"active\").length;\n  const delayedCount = routes.filter((r) => r.status === \"delayed\").length;\n  const airRouteCount = routes.filter((r) => r.mode === \"air\").length;\n  const groundRouteCount = routes.filter((r) => r.mode === \"ground\").length;\n\n  return (\n    <Sidebar collapsible=\"offcanvas\">\n      <SidebarHeader className=\"p-4\">\n        <div className=\"flex items-center gap-2\">\n          <div className=\"bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg\">\n            <Network className=\"size-4\" />\n          </div>\n          <div className=\"flex flex-col gap-0.5 leading-none\">\n            <span className=\"text-sm font-medium\">Logistics Network</span>\n            <span className=\"text-muted-foreground text-xs\">\n              Domestic Routes\n            </span>\n          </div>\n        </div>\n        <div className=\"mt-3 grid grid-cols-3 gap-2\">\n          <div className=\"bg-background rounded-md border px-2.5 py-2 text-center\">\n            <p className=\"text-lg leading-none font-bold tabular-nums\">\n              {hubs.length}\n            </p>\n            <p className=\"text-muted-foreground mt-1 text-[10px]\">Hubs</p>\n          </div>\n          <div className=\"bg-background rounded-md border px-2.5 py-2 text-center\">\n            <p className=\"text-lg leading-none font-bold tabular-nums\">\n              {activeCount}\n            </p>\n            <p className=\"text-muted-foreground mt-1 text-[10px]\">Active</p>\n          </div>\n          <div className=\"bg-background rounded-md border px-2.5 py-2 text-center\">\n            <p className=\"text-lg leading-none font-bold tabular-nums\">\n              {delayedCount}\n            </p>\n            <p className=\"text-muted-foreground mt-1 text-[10px]\">Delayed</p>\n          </div>\n        </div>\n      </SidebarHeader>\n\n      <SidebarSeparator className=\"mx-0\" />\n\n      <SidebarContent>\n        <SidebarGroup>\n          <SidebarGroupLabel>Transport Mode</SidebarGroupLabel>\n          <SidebarGroupContent>\n            <SidebarMenu>\n              <SidebarMenuItem>\n                <SidebarMenuButton\n                  tooltip=\"Air\"\n                  className=\"pointer-events-none\"\n                >\n                  <Plane className=\"size-4\" />\n                  <span>Air Freight</span>\n                </SidebarMenuButton>\n                <SidebarMenuBadge>{airRouteCount}</SidebarMenuBadge>\n              </SidebarMenuItem>\n              <SidebarMenuItem>\n                <SidebarMenuButton\n                  tooltip=\"Ground\"\n                  className=\"pointer-events-none\"\n                >\n                  <Truck className=\"size-4\" />\n                  <span>Ground</span>\n                </SidebarMenuButton>\n                <SidebarMenuBadge>{groundRouteCount}</SidebarMenuBadge>\n              </SidebarMenuItem>\n            </SidebarMenu>\n          </SidebarGroupContent>\n        </SidebarGroup>\n\n        <SidebarGroup>\n          <SidebarGroupLabel>Status</SidebarGroupLabel>\n          <SidebarGroupContent>\n            <SidebarMenu>\n              <SidebarMenuItem>\n                <SidebarMenuButton\n                  tooltip={statusConfig.active.label}\n                  className=\"pointer-events-none\"\n                >\n                  <span className=\"flex size-4 items-center justify-center\">\n                    <span\n                      className=\"size-2 rounded-full\"\n                      style={{ backgroundColor: statusConfig.active.color }}\n                    />\n                  </span>\n                  <span>{statusConfig.active.label}</span>\n                </SidebarMenuButton>\n                <SidebarMenuBadge>{activeCount}</SidebarMenuBadge>\n              </SidebarMenuItem>\n              <SidebarMenuItem>\n                <SidebarMenuButton\n                  tooltip={statusConfig.delayed.label}\n                  className=\"pointer-events-none\"\n                >\n                  <span className=\"flex size-4 items-center justify-center\">\n                    <span\n                      className=\"size-2 rounded-full\"\n                      style={{ backgroundColor: statusConfig.delayed.color }}\n                    />\n                  </span>\n                  <span>{statusConfig.delayed.label}</span>\n                </SidebarMenuButton>\n                <SidebarMenuBadge>{delayedCount}</SidebarMenuBadge>\n              </SidebarMenuItem>\n            </SidebarMenu>\n          </SidebarGroupContent>\n        </SidebarGroup>\n\n        <SidebarGroup>\n          <SidebarGroupLabel>Region</SidebarGroupLabel>\n          <SidebarGroupContent>\n            <SidebarMenu>\n              {([\"west\", \"midwest\", \"south\", \"northeast\"] as const).map(\n                (region) => {\n                  const hubsInRegion = hubs.filter((h) => h.region === region);\n                  return (\n                    <SidebarMenuItem key={region}>\n                      <SidebarMenuButton\n                        tooltip={regionLabels[region]}\n                        className=\"pointer-events-none\"\n                      >\n                        <span className=\"bg-muted text-muted-foreground flex size-4 items-center justify-center rounded text-[9px] font-bold\">\n                          {regionIcons[region]}\n                        </span>\n                        <span>{regionLabels[region]}</span>\n                      </SidebarMenuButton>\n                      <SidebarMenuBadge>{hubsInRegion.length}</SidebarMenuBadge>\n                    </SidebarMenuItem>\n                  );\n                },\n              )}\n            </SidebarMenu>\n          </SidebarGroupContent>\n        </SidebarGroup>\n      </SidebarContent>\n\n      <SidebarFooter className=\"p-4 pt-0\">\n        <p className=\"text-muted-foreground mb-2 text-[11px] font-medium tracking-wider uppercase\">\n          Summary\n        </p>\n        <div className=\"bg-background space-y-1.5 rounded-md border px-3 py-2 text-xs\">\n          <div className=\"flex justify-between\">\n            <span className=\"text-muted-foreground\">Shipments</span>\n            <span className=\"font-medium tabular-nums\">\n              {totalShipments.toLocaleString()}\n            </span>\n          </div>\n          <div className=\"flex justify-between\">\n            <span className=\"text-muted-foreground\">Routes</span>\n            <span className=\"font-medium tabular-nums\">{routes.length}</span>\n          </div>\n        </div>\n      </SidebarFooter>\n    </Sidebar>\n  );\n}\n",
      "type": "registry:component",
      "target": "app/logistics/components/filter-sidebar.tsx"
    },
    {
      "path": "src/registry/blocks/logistics-network/components/network-map.tsx",
      "content": "\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n  Map,\n  MapArc,\n  MapControls,\n  MapMarker,\n  MarkerContent,\n  MarkerTooltip,\n} from \"@/components/ui/map\";\nimport { SidebarTrigger } from \"@/components/ui/sidebar\";\nimport {\n  modeConfig,\n  regionLabels,\n  statusConfig,\n  type Hub,\n  type Route,\n} from \"../data\";\nimport { Separator } from \"@/components/ui/separator\";\n\ninterface NetworkMapProps {\n  hubs: Hub[];\n  routes: Route[];\n}\n\nfunction MapControlsCard() {\n  return (\n    <div className=\"border-border/40 bg-background/70 absolute top-4 left-4 z-20 flex items-center gap-3 rounded-lg border px-2.5 py-1.5 backdrop-blur-sm\">\n      <SidebarTrigger />\n      <Separator orientation=\"vertical\" className=\"h-4!\" />\n      <div className=\"flex items-center gap-3 text-xs\">\n        <div className=\"flex items-center gap-1.5\">\n          <span\n            className=\"h-0.5 w-4 shrink-0 rounded-full\"\n            style={{ backgroundColor: modeConfig.air.color }}\n          />\n          <span>{modeConfig.air.label}</span>\n        </div>\n        <div className=\"flex items-center gap-1.5\">\n          <span\n            className=\"h-0.5 w-4 shrink-0 rounded-full\"\n            style={{ backgroundColor: modeConfig.ground.color }}\n          />\n          <span>{modeConfig.ground.label}</span>\n        </div>\n        <div className=\"flex items-center gap-1.5\">\n          <span\n            className=\"h-0.5 w-4 shrink-0 rounded-full\"\n            style={{ backgroundColor: statusConfig.delayed.color }}\n          />\n          <span>{statusConfig.delayed.label}</span>\n        </div>\n        <Separator orientation=\"vertical\" className=\"h-4!\" />\n        <div className=\"flex items-center gap-1.5\">\n          <div className=\"size-2.5 shrink-0 rounded-full border border-white bg-blue-500 shadow-sm\" />\n          <span>Hub</span>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport function NetworkMap({ hubs, routes }: NetworkMapProps) {\n  const arcs = useMemo(() => {\n    const hubById: Record<string, Hub> = Object.fromEntries(\n      hubs.map((hub) => [hub.id, hub]),\n    );\n    return routes.flatMap((route) => {\n      const fromHub = hubById[route.from];\n      const toHub = hubById[route.to];\n      if (!fromHub || !toHub) return [];\n      return [\n        {\n          id: `${route.from}-${route.to}`,\n          from: [fromHub.lng, fromHub.lat] as [number, number],\n          to: [toHub.lng, toHub.lat] as [number, number],\n          color:\n            route.status === \"delayed\"\n              ? statusConfig.delayed.color\n              : modeConfig[route.mode].color,\n        },\n      ];\n    });\n  }, [hubs, routes]);\n\n  return (\n    <div className=\"relative h-full\">\n      <MapControlsCard />\n\n      <Map center={[-98, 39]} zoom={4} projection={{ type: \"globe\" }}>\n        <MapControls />\n        <MapArc\n          data={arcs}\n          curvature={0.3}\n          paint={{\n            \"line-color\": [\"get\", \"color\"],\n            \"line-width\": 2,\n            \"line-opacity\": 0.65,\n          }}\n          interactive={false}\n        />\n\n        {hubs.map((hub) => (\n          <MapMarker key={hub.id} longitude={hub.lng} latitude={hub.lat}>\n            <MarkerContent>\n              <div className=\"size-3 rounded-full border-2 border-white bg-blue-500 shadow-md\" />\n            </MarkerContent>\n            <MarkerTooltip\n              offset={16}\n              className=\"bg-background text-foreground border px-2.5 py-1.5\"\n            >\n              <p className=\"font-medium\">{hub.city}</p>\n              <p className=\"text-muted-foreground mt-1\">\n                {hub.shipments.toLocaleString()} shipments\n                <span className=\"mx-1\">•</span>\n                {regionLabels[hub.region]}\n              </p>\n            </MarkerTooltip>\n          </MapMarker>\n        ))}\n      </Map>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "app/logistics/components/network-map.tsx"
    }
  ],
  "meta": {
    "iframeHeight": "800px"
  },
  "categories": [
    "logistics",
    "network"
  ],
  "type": "registry:block"
}
