analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 43.6 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/NotificationCard/NotificationCard.tsx"],"sourcesContent":["import { DotsThreeVerticalIcon } from '@phosphor-icons/react/dist/csr/DotsThreeVertical';\nimport { BellIcon } from '@phosphor-icons/react/dist/csr/Bell';\nimport { MouseEvent, ReactNode, useState, useEffect } from 'react';\nimport { cn } from '../../utils/utils';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../DropdownMenu/DropdownMenu';\nimport { SkeletonCard } from '../Skeleton/Skeleton';\nimport IconButton from '../IconButton/IconButton';\nimport Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport Badge from '../Badge/Badge';\nimport { useMobile } from '../../hooks/useMobile';\nimport type {\n Notification,\n NotificationGroup,\n NotificationEntityType,\n} from '../../types/notifications';\nimport { formatTimeAgo } from '../../store/notificationStore';\nimport mockContentImage from '../../assets/img/mock-content.png';\n\n/**\n * Default interval (in ms) to auto-refresh the notification center while it is\n * open, so newly received notifications appear without reopening it.\n */\nconst DEFAULT_REFRESH_INTERVAL_MS = 3000;\n\n// Extended notification item for component usage with time string\nexport interface NotificationItem extends Omit<Notification, 'createdAt'> {\n time: string;\n createdAt: string | Date;\n}\n\n// Base props shared across all modes\ninterface BaseNotificationProps {\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Empty state image path\n */\n emptyStateImage?: string;\n /**\n * Empty state title\n */\n emptyStateTitle?: string;\n /**\n * Empty state description\n */\n emptyStateDescription?: string;\n}\n\n// Single notification card mode\ninterface SingleNotificationCardMode extends BaseNotificationProps {\n /**\n * Component mode - single card\n */\n mode: 'single';\n /**\n * The notification title\n */\n title: string;\n /**\n * The notification message content\n */\n message: string;\n /**\n * Time displayed (e.g., \"Há 3h\", \"12 Fev\")\n */\n time: string;\n /**\n * Whether the notification has been read\n */\n isRead: boolean;\n /**\n * Callback when user marks notification as read\n */\n onMarkAsRead: () => void;\n /**\n * Callback when user deletes notification\n */\n onDelete: () => void;\n /**\n * Optional callback for navigation action\n */\n onNavigate?: () => void;\n /**\n * Label for the action button (only shown if onNavigate is provided)\n */\n actionLabel?: string;\n}\n\n// List mode\ninterface NotificationListMode extends BaseNotificationProps {\n /**\n * Component mode - list\n */\n mode: 'list';\n /**\n * Array of notifications for list mode\n */\n notifications?: NotificationItem[];\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for list mode\n */\n loading?: boolean;\n /**\n * Error state for list mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Callback when user marks a notification as read in list mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in list mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in list mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string\n ) => void;\n /**\n * Callback when user clicks on a global notification\n */\n onGlobalNotificationClick?: (notification: Notification) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Custom empty state component\n */\n renderEmpty?: () => ReactNode;\n}\n\n// NotificationCenter mode\ninterface NotificationCenterMode extends BaseNotificationProps {\n /**\n * Component mode - center\n */\n mode: 'center';\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for center mode\n */\n loading?: boolean;\n /**\n * Error state for center mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Whether center mode is currently active (controls dropdown/modal visibility)\n */\n isActive?: boolean;\n /**\n * Callback when center mode is toggled\n */\n onToggleActive?: () => void;\n /**\n * Number of unread notifications for badge display\n */\n unreadCount?: number;\n /**\n * Callback when all notifications should be marked as read\n */\n onMarkAllAsRead?: () => void;\n /**\n * Callback to fetch notifications (called when center opens)\n */\n onFetchNotifications?: () => void;\n /**\n * Callback when user marks a notification as read in center mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in center mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in center mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string\n ) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Callback when dropdown open state changes (for synchronization with parent)\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Interval (in ms) to auto-refresh the list while the center is open, so newly\n * received notifications appear without reopening it. Defaults to 3000 (3s).\n * Set to 0 to disable polling.\n */\n refreshIntervalMs?: number;\n}\n\n// Union type for all modes\nexport type NotificationCardProps =\n | SingleNotificationCardMode\n | NotificationListMode\n | NotificationCenterMode;\n\n// Legacy interface for backward compatibility\nexport interface LegacyNotificationCardProps extends BaseNotificationProps {\n // Single notification mode props\n title?: string;\n message?: string;\n time?: string;\n isRead?: boolean;\n onMarkAsRead?: () => void;\n onDelete?: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n\n // List mode props\n notifications?: NotificationItem[];\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n\n // NotificationCenter mode props\n variant?: 'card' | 'center';\n isActive?: boolean;\n onToggleActive?: () => void;\n unreadCount?: number;\n onMarkAllAsRead?: () => void;\n onFetchNotifications?: () => void;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * Empty state component for notifications\n */\nconst NotificationEmpty = ({\n emptyStateImage,\n emptyStateTitle = 'Nenhuma notificação no momento',\n emptyStateDescription = 'Você está em dia com todas as novidades. Volte depois para conferir atualizações!',\n}: {\n emptyStateImage?: string;\n emptyStateTitle?: string;\n emptyStateDescription?: string;\n}) => {\n return (\n <div className=\"flex flex-col items-center justify-center gap-4 p-6 w-full\">\n {/* Notification Icon */}\n {emptyStateImage && (\n <div className=\"w-20 h-20 flex items-center justify-center\">\n <img\n src={emptyStateImage}\n alt=\"Sem notificações\"\n width={82}\n height={82}\n className=\"object-contain\"\n />\n </div>\n )}\n\n {/* Title */}\n <h3 className=\"text-xl font-semibold text-text-950 text-center leading-[23px]\">\n {emptyStateTitle}\n </h3>\n\n {/* Description */}\n <p className=\"text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]\">\n {emptyStateDescription}\n </p>\n </div>\n );\n};\n\n/**\n * Notification header component\n */\nconst NotificationHeader = ({\n unreadCount,\n variant = 'modal',\n}: {\n unreadCount: number;\n variant?: 'modal' | 'dropdown';\n}) => {\n return (\n <div className=\"flex items-center justify-between gap-2\">\n {variant === 'modal' ? (\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950\">\n Notificações\n </Text>\n ) : (\n <h3 className=\"text-sm font-semibold text-text-950\">Notificações</h3>\n )}\n {unreadCount > 0 && (\n <Badge\n variant=\"solid\"\n action=\"info\"\n size=\"small\"\n iconLeft={<BellIcon size={12} aria-hidden=\"true\" focusable=\"false\" />}\n className=\"border-0\"\n >\n {unreadCount === 1 ? '1 não lida' : `${unreadCount} não lidas`}\n </Badge>\n )}\n </div>\n );\n};\n\n/**\n * Single notification card component\n */\nconst SingleNotificationCard = ({\n title,\n message,\n time,\n isRead,\n onMarkAsRead,\n onDelete,\n onNavigate,\n actionLabel,\n className,\n}: {\n title: string;\n message: string;\n time: string;\n isRead: boolean;\n onMarkAsRead: () => void;\n onDelete: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n className?: string;\n}) => {\n const handleMarkAsRead = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!isRead) {\n onMarkAsRead();\n }\n };\n\n const handleDelete = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onDelete();\n };\n\n const handleNavigate = (e: MouseEvent) => {\n e.stopPropagation();\n if (onNavigate) {\n onNavigate();\n }\n };\n\n return (\n <div\n className={cn(\n 'flex flex-col justify-center items-start p-4 gap-2 w-full bg-background border-b border-border-200',\n 'last:border-b-0',\n className\n )}\n >\n {/* Header with unread indicator and actions menu */}\n <div className=\"flex items-center gap-2 w-full\">\n {/* Unread indicator */}\n {!isRead && (\n <div className=\"w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0\" />\n )}\n\n {/* Title */}\n <h3 className=\"font-bold text-sm leading-4 text-text-950 flex-grow\">\n {title}\n </h3>\n\n {/* Actions dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg\"\n aria-label=\"Menu de ações\"\n >\n <DotsThreeVerticalIcon size={24} />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-[160px]\">\n {!isRead && (\n <DropdownMenuItem\n onClick={handleMarkAsRead}\n className=\"text-text-950\"\n >\n Marcar como lida\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={handleDelete} className=\"text-error-600\">\n Deletar\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Message */}\n <p className=\"text-sm leading-[21px] text-text-800 w-full\">{message}</p>\n\n {/* Time and action button */}\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"text-sm font-medium text-text-400\">{time}</span>\n\n {onNavigate && actionLabel && (\n <button\n type=\"button\"\n onClick={handleNavigate}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer\"\n >\n {actionLabel}\n </button>\n )}\n </div>\n </div>\n );\n};\n\n/**\n * Notification list component for displaying grouped notifications\n */\nconst NotificationList = ({\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n onGlobalNotificationClick,\n getActionLabel,\n renderEmpty,\n className,\n emptyStateImage,\n}: {\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n className?: string;\n emptyStateImage?: string;\n}) => {\n // State for global notification modal when onGlobalNotificationClick is not provided\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Default handler for global notifications when onGlobalNotificationClick is not provided\n const handleGlobalNotificationClick = (notification: Notification) => {\n if (onGlobalNotificationClick) {\n onGlobalNotificationClick(notification);\n } else {\n // Open modal as fallback\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }\n };\n // Error state\n if (error) {\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-error-600\">{error}</p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"text-sm text-info-600 hover:text-info-700\"\n >\n Tentar novamente\n </button>\n )}\n </div>\n );\n }\n\n // Loading state — only show the skeleton on the initial load (empty list).\n // Background refreshes (e.g. while the center polls) keep the list visible.\n if (loading && groupedNotifications.length === 0) {\n return (\n <div className=\"flex flex-col gap-0 w-full\">\n {['skeleton-first', 'skeleton-second', 'skeleton-third'].map(\n (skeletonId) => (\n <SkeletonCard\n key={skeletonId}\n className=\"p-4 border-b border-border-200\"\n />\n )\n )}\n </div>\n );\n }\n\n // Empty state\n if (!groupedNotifications || groupedNotifications.length === 0) {\n return renderEmpty ? (\n <div className=\"w-full\">{renderEmpty()}</div>\n ) : (\n <NotificationEmpty />\n );\n }\n\n return (\n <div className={cn('flex flex-col gap-0 w-full', className)}>\n {groupedNotifications.map((group, idx) => (\n <div key={`${group.label}-${idx}`} className=\"flex flex-col\">\n {/* Group header */}\n <div className=\"flex items-end px-4 py-6 pb-4\">\n <h4 className=\"text-lg font-bold text-text-500 flex-grow\">\n {group.label}\n </h4>\n </div>\n\n {/* Notifications in group */}\n {group.notifications.map((notification) => {\n // Check if this is a global notification\n const isGlobalNotification =\n !notification.entityType &&\n !notification.entityId &&\n !notification.activity &&\n !notification.recommendedClass;\n\n // Determine navigation handler\n let navigationHandler: (() => void) | undefined;\n if (isGlobalNotification) {\n navigationHandler = () =>\n handleGlobalNotificationClick(notification);\n } else if (\n notification.entityType &&\n notification.entityId &&\n onNavigateById\n ) {\n navigationHandler = () =>\n onNavigateById(\n notification.entityType ?? undefined,\n notification.entityId ?? undefined\n );\n }\n\n // Determine action label\n let actionLabel: string | undefined;\n if (isGlobalNotification) {\n // For global notifications, call getActionLabel without parameters or with null\n actionLabel = getActionLabel?.(undefined);\n } else {\n // For entity-specific notifications, pass the entityType\n actionLabel = getActionLabel?.(\n notification.entityType ?? undefined\n );\n }\n\n return (\n <SingleNotificationCard\n key={notification.id}\n title={notification.title}\n message={notification.message}\n time={\n (notification as Partial<NotificationItem>).time ??\n formatTimeAgo(new Date(notification.createdAt))\n }\n isRead={notification.isRead}\n onMarkAsRead={() => onMarkAsReadById?.(notification.id)}\n onDelete={() => onDeleteById?.(notification.id)}\n onNavigate={navigationHandler}\n actionLabel={actionLabel}\n />\n );\n })}\n </div>\n ))}\n\n {/* Global notification modal for list mode */}\n <Modal\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n title={globalNotificationModal.notification?.title || ''}\n description={globalNotificationModal.notification?.message || ''}\n variant=\"activity\"\n image={\n globalNotificationModal.notification?.linkImg ||\n emptyStateImage ||\n mockContentImage\n }\n actionLink={\n globalNotificationModal.notification?.actionLink || undefined\n }\n actionLabel=\"Ver mais\"\n size=\"lg\"\n />\n </div>\n );\n};\n\n// Internal props type for NotificationCenter (without mode)\ntype NotificationCenterProps = Omit<NotificationCenterMode, 'mode'>;\n\n/**\n * NotificationCenter component for modal/dropdown mode\n */\nconst NotificationCenter = ({\n isActive,\n onToggleActive,\n unreadCount = 0,\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n getActionLabel,\n onFetchNotifications,\n onMarkAllAsRead,\n onOpenChange,\n emptyStateImage,\n emptyStateTitle,\n emptyStateDescription,\n className,\n refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS,\n}: NotificationCenterProps) => {\n const { isMobile } = useMobile();\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Handle mobile click\n const handleMobileClick = () => {\n setIsModalOpen(true);\n onFetchNotifications?.();\n };\n\n // Handle desktop click\n const handleDesktopClick = () => {\n onToggleActive?.();\n };\n\n // Handle dropdown open change\n const handleOpenChange = (open: boolean) => {\n const controlledByParent =\n typeof isActive === 'boolean' && typeof onToggleActive === 'function';\n\n // Always notify parent if they want the signal.\n onOpenChange?.(open);\n\n // If parent controls via toggle only (no onOpenChange), keep them in sync on close.\n if (controlledByParent && !onOpenChange && !open && isActive) {\n onToggleActive?.();\n }\n };\n\n // Fetch notifications when dropdown opens\n useEffect(() => {\n if (isActive) {\n onFetchNotifications?.();\n }\n }, [isActive, onFetchNotifications]);\n\n // While the center is open, poll periodically so newly received notifications\n // appear without the user having to reopen it. The list is not replaced by a\n // skeleton on these background refreshes (see NotificationList loading gate).\n const isCenterOpen = isMobile ? isModalOpen : Boolean(isActive);\n useEffect(() => {\n if (!isCenterOpen || !onFetchNotifications || refreshIntervalMs <= 0) {\n return;\n }\n const intervalId = setInterval(() => {\n onFetchNotifications();\n }, refreshIntervalMs);\n return () => clearInterval(intervalId);\n }, [isCenterOpen, onFetchNotifications, refreshIntervalMs]);\n\n const renderEmptyState = () => (\n <NotificationEmpty\n emptyStateImage={emptyStateImage}\n emptyStateTitle={emptyStateTitle}\n emptyStateDescription={emptyStateDescription}\n />\n );\n\n if (isMobile) {\n return (\n <>\n <IconButton\n active={isModalOpen}\n onClick={handleMobileClick}\n icon={\n <>\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className=\"p-0\"\n />\n {unreadCount > 0 && (\n <Text as=\"span\" className=\"sr-only\">\n {unreadCount} notificações não lidas\n </Text>\n )}\n </>\n }\n className={className}\n />\n <Modal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n title=\"Notificações\"\n size=\"md\"\n hideCloseButton={false}\n closeOnEscape={true}\n >\n <div className=\"flex flex-col h-full max-h-[80vh]\">\n <div className=\"px-0 pb-3 border-b border-border-200\">\n <NotificationHeader unreadCount={unreadCount} variant=\"modal\" />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n onNavigateById={(entityType, entityId) => {\n setIsModalOpen(false);\n onNavigateById?.(entityType, entityId);\n }}\n onGlobalNotificationClick={(notification) => {\n setIsModalOpen(false);\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </Modal>\n {/* Global Notification Modal (mobile) */}\n <Modal\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n title={globalNotificationModal.notification?.title || ''}\n variant=\"activity\"\n description={globalNotificationModal.notification?.message}\n image={\n globalNotificationModal.notification?.linkImg ||\n emptyStateImage ||\n mockContentImage\n }\n actionLink={\n globalNotificationModal.notification?.actionLink || undefined\n }\n actionLabel=\"Ver mais\"\n size=\"lg\"\n />\n </>\n );\n }\n\n return (\n <>\n <DropdownMenu\n {...(typeof isActive === 'boolean'\n ? { open: isActive, onOpenChange: handleOpenChange }\n : { onOpenChange: handleOpenChange })}\n >\n <DropdownMenuTrigger className=\"text-primary cursor-pointer\">\n <IconButton\n active={isActive}\n onClick={handleDesktopClick}\n icon={\n <>\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className={cn('p-0', isActive && 'text-primary-950!')}\n />\n {unreadCount > 0 && (\n <Text as=\"span\" className=\"sr-only\">\n {unreadCount} notificações não lidas\n </Text>\n )}\n </>\n }\n className={className}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"min-w-[320px] max-w-[400px] max-h-[500px] overflow-hidden\"\n side=\"bottom\"\n align=\"end\"\n >\n <div className=\"flex flex-col\">\n <div className=\"px-4 py-3 border-b border-border-200\">\n <NotificationHeader\n unreadCount={unreadCount}\n variant=\"dropdown\"\n />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"max-h-[350px] overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n onNavigateById={onNavigateById}\n onGlobalNotificationClick={(notification) => {\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n\n {/* Global Notification Modal */}\n <Modal\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n title={globalNotificationModal.notification?.title || ''}\n variant=\"activity\"\n description={globalNotificationModal.notification?.message}\n image={\n globalNotificationModal.notification?.linkImg ||\n emptyStateImage ||\n mockContentImage\n }\n actionLink={\n globalNotificationModal.notification?.actionLink || undefined\n }\n actionLabel=\"Ver mais\"\n size=\"lg\"\n />\n </>\n );\n};\n\n/**\n * NotificationCard component - can display single notification, list of notifications, or center mode\n *\n * @param props - The notification card properties\n * @returns JSX element representing the notification card, list, or center\n */\nconst NotificationCard = (props: NotificationCardProps) => {\n // Use mode discriminator to determine which component to render\n switch (props.mode) {\n case 'single':\n return (\n <SingleNotificationCard\n title={props.title}\n message={props.message}\n time={props.time}\n isRead={props.isRead}\n onMarkAsRead={props.onMarkAsRead}\n onDelete={props.onDelete}\n onNavigate={props.onNavigate}\n actionLabel={props.actionLabel}\n className={props.className}\n />\n );\n\n case 'list':\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n\n case 'center':\n return <NotificationCenter {...props} />;\n\n default:\n // This should never happen with proper typing, but provides a fallback\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">\n Modo de notificação não reconhecido\n </p>\n </div>\n );\n }\n};\n\n/**\n * Legacy NotificationCard component for backward compatibility\n * Automatically detects mode based on provided props\n */\nexport const LegacyNotificationCard = (props: LegacyNotificationCardProps) => {\n // If variant is center, render NotificationCenter\n if (props.variant === 'center') {\n const centerProps: NotificationCenterMode = {\n mode: 'center',\n ...props,\n };\n return <NotificationCenter {...centerProps} />;\n }\n\n // If we have list-related props, render list mode\n if (\n props.groupedNotifications !== undefined ||\n props.notifications !== undefined ||\n props.loading ||\n props.error\n ) {\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n }\n\n // If we have single notification props, render single card mode\n if (\n props.title !== undefined &&\n props.message !== undefined &&\n props.time !== undefined &&\n props.isRead !== undefined &&\n props.onMarkAsRead &&\n props.onDelete\n ) {\n const singleProps: SingleNotificationCardMode = {\n mode: 'single',\n title: props.title,\n message: props.message,\n time: props.time,\n isRead: props.isRead,\n onMarkAsRead: props.onMarkAsRead,\n onDelete: props.onDelete,\n onNavigate: props.onNavigate,\n actionLabel: props.actionLabel,\n className: props.className,\n emptyStateImage: props.emptyStateImage,\n emptyStateTitle: props.emptyStateTitle,\n emptyStateDescription: props.emptyStateDescription,\n };\n return (\n <SingleNotificationCard\n title={singleProps.title}\n message={singleProps.message}\n time={singleProps.time}\n isRead={singleProps.isRead}\n onMarkAsRead={singleProps.onMarkAsRead}\n onDelete={singleProps.onDelete}\n onNavigate={singleProps.onNavigate}\n actionLabel={singleProps.actionLabel}\n className={singleProps.className}\n />\n );\n }\n\n // Default empty state if no valid props provided\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">Nenhuma notificação configurada</p>\n </div>\n );\n};\n\nexport default NotificationCard;\nexport type { NotificationGroup };\n"],"mappings":"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","names":[]}