import { AlertTriangle, ChevronRight, Inbox } from 'lucide-react' import { Badge, Button, cn } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns' import type { AdvisorItem } from './AdvisorPanel.types' import { formatItemDate, getAdvisorItemSecondaryText, getAdvisorPanelItemDisplayTitle, severityBadgeVariants, severityColorClasses, severityLabels, tabIconMap, } from './AdvisorPanel.utils' import { EmptyAdvisor } from './EmptyAdvisor' import type { Notification } from '@/data/notifications/notifications-v2-query' import type { AdvisorSeverity, AdvisorTab } from '@/state/advisor-state' const NoProjectNotice = () => { return (

Project required

Select a project to view security and performance advisories

) } interface AdvisorPanelBodyProps { isLoading: boolean isError: boolean filteredItems: AdvisorItem[] activeTab: AdvisorTab severityFilters: AdvisorSeverity[] onItemClick: (item: AdvisorItem) => void onClearFilters: () => void hiddenItemsCount: number hasAnyFilters: boolean hasProjectRef?: boolean projectNameByRef?: ReadonlyMap } export const AdvisorPanelBody = ({ isLoading, isError, filteredItems, activeTab, severityFilters, onItemClick, onClearFilters, hiddenItemsCount, hasAnyFilters, hasProjectRef = true, projectNameByRef, }: AdvisorPanelBodyProps) => { // Show notice if no project ref and trying to view project-specific tabs if (!hasProjectRef && activeTab !== 'messages' && activeTab !== 'all') { return } if (isLoading) { return (
) } if (isError) { return (

Error loading advisories

Please try again later.

) } if (filteredItems.length === 0) { return ( ) } return ( <>
{filteredItems.map((item) => { const SeverityIcon = tabIconMap[item.tab as Exclude] const severityClass = severityColorClasses[item.severity] const isNotification = item.source === 'notification' const notification = isNotification ? (item.original as Notification) : null const isUnread = notification?.status === 'new' const primaryText = getAdvisorPanelItemDisplayTitle(item) const secondaryText = getAdvisorItemSecondaryText(item, projectNameByRef) const metadataText = secondaryText ?? (item.createdAt ? formatItemDate(item.createdAt) : undefined) // Date strings (e.g. "a few seconds ago") come from formatItemDate and // need sentence-case capitalisation; entity strings (lint / signal) don't. const metadataCapitalize = secondaryText === undefined && item.createdAt !== undefined return (
) })}
{severityFilters.length > 0 && hiddenItemsCount > 0 && (
)} ) }