testes/src_2/components/shared/ItemDetailPanel/ItemDetailPanel.jsx

145 lines
5.5 KiB
JavaScript

import React from 'react';
import { X, MoreVertical } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Badge } from '@/components/ui/badge';
import { Card } from '@/components/ui/card';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
/**
* ItemDetailPanel Component
* A modular panel for displaying detailed information about an item, including actions and tabbed content.
*
* @param {Object} props
* @param {string} props.title - Main title of the item (e.g., Client Name).
* @param {string} props.subtitle - Subtitle or ID.
* @param {string} props.status - Status text for the badge.
* @param {string} props.statusColor - specific color class for status (optional).
* @param {Array<{label: string, icon: React.Node, onClick: Function, variant: string, isDestructive: boolean}>} props.actions - Primary actions displayed as buttons.
* @param {Array<{label: string, icon: React.Node, onClick: Function}>} props.menuActions - Secondary actions in a dropdown menu.
* @param {Array<{id: string, label: string, content: React.Node}>} props.tabs - Tabs configuration.
* @param {Function} props.onClose - Handler for the close button.
* @param {string} props.className - Additional CSS classes.
*/
export const ItemDetailPanel = ({
title,
subtitle,
status,
statusColor = "bg-primary/10 text-primary",
actions = [],
menuActions = [],
tabs = [],
onClose,
className
}) => {
return (
<div className={`flex flex-col h-full bg-white dark:bg-[#1b1b1b] border-l shadow-xl w-full max-w-2xl transition-all duration-300 ${className}`}>
{/* Header Section */}
<div className="flex items-start justify-between p-6 pb-2">
<div className="space-y-1">
<div className="flex items-center gap-3">
<h2 className="text-2xl font-bold tracking-tight text-foreground">{title}</h2>
{status && (
<Badge variant="secondary" className={`${statusColor} hover:${statusColor}`}>
{status}
</Badge>
)}
</div>
{subtitle && (
<p className="text-muted-foreground text-sm">{subtitle}</p>
)}
</div>
<Button variant="ghost" size="icon" onClick={onClose} className="h-8 w-8 rounded-full">
<X className="h-4 w-4" />
</Button>
</div>
{/* Actions Toolbar */}
<div className="px-6 py-4 flex items-center justify-between gap-2">
<div className="flex items-center gap-2 overflow-x-auto no-scrollbar">
{actions.map((action, index) => (
<Button
key={index}
variant={action.variant || "outline"}
size="sm"
onClick={action.onClick}
className={`gap-2 ${action.isDestructive ? 'text-destructive hover:bg-destructive/10 border-destructive/20' : ''}`}
>
{action.icon}
{action.label}
</Button>
))}
</div>
{menuActions.length > 0 && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{menuActions.map((action, index) => (
<DropdownMenuItem
key={index}
onClick={action.onClick}
className={action.isDestructive ? 'text-destructive focus:text-destructive' : ''}
>
{action.icon && <span className="mr-2">{action.icon}</span>}
{action.label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
<Separator />
{/* Tabs and Content */}
<div className="flex-1 overflow-hidden flex flex-col">
{tabs.length > 0 ? (
<Tabs defaultValue={tabs[0].id} className="flex flex-col h-full">
<div className="px-6 pt-2 border-b bg-muted/30">
<TabsList className="bg-transparent p-0 w-full justify-start h-auto">
{tabs.map((tab) => (
<TabsTrigger
key={tab.id}
value={tab.id}
className="data-[state=active]:bg-background data-[state=active]:shadow-sm rounded-t-lg rounded-b-none border-t border-l border-r border-transparent data-[state=active]:border-border px-4 py-3"
>
{tab.label}
</TabsTrigger>
))}
</TabsList>
</div>
<ScrollArea className="flex-1 bg-muted/10">
<div className="p-6">
{tabs.map((tab) => (
<TabsContent key={tab.id} value={tab.id} className="m-0 mt-0 space-y-4">
{tab.content}
</TabsContent>
))}
</div>
</ScrollArea>
</Tabs>
) : (
<div className="flex-1 flex items-center justify-center text-muted-foreground">
No details available
</div>
)}
</div>
</div>
);
};
export default ItemDetailPanel;