import { CopyPlus } from "lucide-react" import React from "react" import { useTranslation } from "react-i18next" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" /** * Интерфейс свойств компонента ContentGroup */ interface ContentGroupProps { /** Заголовок группы */ title: string /** Элементы в группе */ items: T[] /** Режим отображения */ viewMode?: "list" | "grid" | "thumbnails" /** Функция рендеринга элемента */ renderItem: (item: T, index: number) => React.ReactNode /** Функция для получения уникального ключа элемента */ getItemKey?: (item: T, index: number) => string | number /** Функция для добавления всех элементов группы */ onAddAll?: (items: T[]) => void /** Проверка, все ли элементы добавлены */ areAllItemsAdded?: (items: T[]) => boolean /** Текст кнопки добавления */ addButtonText?: string /** Текст кнопки когда все добавлены */ addedButtonText?: string /** CSS классы для контейнера элементов */ itemsContainerClassName?: string /** CSS стили для контейнера элементов */ itemsContainerStyle?: React.CSSProperties } /** * Универсальный компонент для отображения группы контента * * @param {ContentGroupProps} props - Свойства компонента * @returns {JSX.Element | null} Компонент группы контента или null, если группа пуста */ export function ContentGroup({ title, items, viewMode = "thumbnails", renderItem, getItemKey, onAddAll, areAllItemsAdded, addButtonText, addedButtonText, itemsContainerClassName, itemsContainerStyle, }: ContentGroupProps) { const { t } = useTranslation() // Не показываем группу, если в ней нет элементов if (items.length === 0) { return null } // Проверяем, все ли элементы в группе уже добавлены const allItemsAdded = areAllItemsAdded ? areAllItemsAdded(items) : false // Определяем CSS классы для контейнера элементов const getItemsContainerClasses = () => { if (itemsContainerClassName) { return itemsContainerClassName } switch (viewMode) { case "grid": return "items-left flex flex-wrap gap-3" case "thumbnails": return "flex flex-wrap justify-between gap-3" case "list": return "space-y-1" default: return "flex flex-wrap gap-3" } } // Если группа не имеет заголовка, отображаем только элементы if (!title || title === "") { return (
{items.map((item, index) => ( {renderItem(item, index)} ))}
) } // Если группа имеет заголовок, отображаем заголовок и элементы return (

{title}

{onAddAll && ( )}
{items.map((item, index) => ( {renderItem(item, index)} ))}
) }