import { useCallback, useMemo } from "react"; import { Paperclip, Plus } from "lucide-react"; import { useQueries, useQuery } from "@tanstack/react-query"; import { DndContext, closestCenter, MouseSensor, useSensor, useSensors, type DragEndEvent, } from "@dnd-kit/core"; import { SortableContext, useSortable, verticalListSortingStrategy, arrayMove, } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { useCompany } from "../context/CompanyContext"; import { useDialogActions } from "../context/DialogContext"; import { cn } from "../lib/utils"; import { queryKeys } from "../lib/queryKeys"; import { sidebarBadgesApi } from "../api/sidebarBadges"; import { heartbeatsApi } from "../api/heartbeats"; import { authApi } from "../api/auth"; import { useCompanyOrder } from "../hooks/useCompanyOrder"; import { useLocation, useNavigate } from "@/lib/router"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip"; import type { Company } from "@paperclipai/shared"; import { CompanyPatternIcon } from "./CompanyPatternIcon"; function SortableCompanyItem({ company, isSelected, hasLiveAgents, hasUnreadInbox, onSelect, }: { company: Company; isSelected: boolean; hasLiveAgents: boolean; hasUnreadInbox: boolean; onSelect: () => void; }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: company.id }); const style = { transform: CSS.Transform.toString(transform), transition, zIndex: isDragging ? 10 : undefined, opacity: isDragging ? 0.8 : 1, }; return (
); } export function CompanyRail() { const { companies, selectedCompanyId, setSelectedCompanyId } = useCompany(); const { openOnboarding } = useDialogActions(); const navigate = useNavigate(); const location = useLocation(); const isInstanceRoute = location.pathname.startsWith("/instance/"); const highlightedCompanyId = isInstanceRoute ? null : selectedCompanyId; const sidebarCompanies = useMemo( () => companies.filter((company) => company.status !== "archived"), [companies], ); const { data: session } = useQuery({ queryKey: queryKeys.auth.session, queryFn: () => authApi.getSession(), }); const currentUserId = session?.user?.id ?? session?.session?.userId ?? null; const companyIds = useMemo(() => sidebarCompanies.map((company) => company.id), [sidebarCompanies]); const liveRunsQueries = useQueries({ queries: companyIds.map((companyId) => ({ queryKey: queryKeys.liveRuns(companyId), queryFn: () => heartbeatsApi.liveRunsForCompany(companyId), refetchInterval: 10_000, })), }); const sidebarBadgeQueries = useQueries({ queries: companyIds.map((companyId) => ({ queryKey: queryKeys.sidebarBadges(companyId), queryFn: () => sidebarBadgesApi.get(companyId), refetchInterval: 15_000, })), }); const hasLiveAgentsByCompanyId = useMemo(() => { const result = new MapAdd company