/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { type ReactNode } from 'react' import { useTranslation } from 'react-i18next' import { Skeleton } from '@/components/ui/skeleton' import { cn } from '@/lib/utils' interface PanelWrapperProps { title: ReactNode description?: ReactNode loading?: boolean empty?: boolean emptyMessage?: string height?: string className?: string contentClassName?: string headerActions?: ReactNode children?: ReactNode } function PanelHeader(props: { title: ReactNode description?: ReactNode actions?: ReactNode }) { const heading = (
{props.title}
{props.description != null && (
{props.description}
)}
) return (
{props.actions != null ? (
{heading} {props.actions}
) : ( heading )}
) } export function PanelWrapper(props: PanelWrapperProps) { const { t } = useTranslation() const resolvedEmptyMessage = props.emptyMessage ?? t('No data available') const height = props.height ?? 'h-64' const frameClassName = cn( 'overflow-hidden rounded-2xl border bg-card shadow-xs', props.className ) if (props.loading) { return (
) } if (props.empty) { return (
{resolvedEmptyMessage}
) } return (
{props.children}
) }