import * as React from "react" import { ChevronRightIcon, FilmIcon, FolderIcon, FolderOpenIcon, HeartIcon, ImagesIcon, LibraryIcon, MoreHorizontalIcon, PencilIcon, PlusIcon, Trash2Icon, UnlinkIcon, } from "@workspace/ui/components/icon" import { useTranslate } from "@workspace/i18n" import { Button } from "@workspace/ui/components/button" import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@workspace/ui/components/collapsible" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@workspace/ui/components/dropdown-menu" import { cn } from "@workspace/ui/lib/utils" import { mediaMessages } from "./messages" import type { MediaFilter, MediaFolder, MediaFolderSelection, MediaId, MediaKind, } from "./types" import { getChildMediaFolders, getMediaFolderDepth, getMediaFolderPath, } from "./utils" const filters = [ { icon: LibraryIcon, message: mediaMessages.allMedia, value: "all" }, { icon: ImagesIcon, message: mediaMessages.image, value: "image" }, { icon: FilmIcon, message: mediaMessages.video, value: "video" }, { icon: HeartIcon, message: mediaMessages.favorite, value: "favorite" }, ] as const satisfies readonly { icon: React.ComponentType<{ className?: string }> message: (typeof mediaMessages)[keyof typeof mediaMessages] value: MediaFilter }[] export interface MediaSidebarProps { allowedKinds?: readonly MediaKind[] className?: string filter: MediaFilter folder: MediaFolderSelection folders: readonly MediaFolder[] onCreateFolder: (parentId: MediaId | null) => void onDeleteFolder: (folder: MediaFolder) => void onFilterChange: (filter: MediaFilter) => void onFolderChange: (folder: MediaFolderSelection) => void onRenameFolder: (folder: MediaFolder) => void } function visibleFilters(allowedKinds?: readonly MediaKind[]) { return filters.filter( (filter) => filter.value === "all" || filter.value === "favorite" || !allowedKinds || allowedKinds.includes(filter.value) ) } export function MediaSidebar({ allowedKinds, className, filter, folder, folders, onCreateFolder, onDeleteFolder, onFilterChange, onFolderChange, onRenameFolder, }: MediaSidebarProps) { const t = useTranslate() const rootFolders = getChildMediaFolders(folders, null) return ( ) } export function MediaFilterTabs({ allowedKinds, filter, folder, folders, onFilterChange, onFolderChange, }: Omit< MediaSidebarProps, "className" | "onCreateFolder" | "onDeleteFolder" | "onRenameFolder" >) { const t = useTranslate() return (
{visibleFilters(allowedKinds).map(({ icon: Icon, message, value }) => ( ))}
) } function SidebarButton({ active, icon: Icon, label, onClick, }: { active: boolean icon: React.ComponentType<{ className?: string }> label: string onClick: VoidFunction }) { return ( ) } function FolderItem({ folder, folders, depth, activeFolder, onSelect, onCreateFolder, onRename, onDelete, }: { folder: MediaFolder folders: readonly MediaFolder[] depth: number activeFolder: MediaFolderSelection onSelect: (folder: MediaFolderSelection) => void onCreateFolder: (parentId: MediaId | null) => void onRename: (folder: MediaFolder) => void onDelete: (folder: MediaFolder) => void }) { const t = useTranslate() const children = getChildMediaFolders(folders, folder.id) const [open, setOpen] = React.useState(true) const hasChildren = children.length > 0 const active = activeFolder === folder.id const Folder = active || (hasChildren && open) ? FolderOpenIcon : FolderIcon return (
  • {hasChildren ? ( } > ) : ( )} } > {depth < 2 && ( onCreateFolder(folder.id)}> {t(mediaMessages.newChildFolder)} )} onRename(folder)}> {t(mediaMessages.rename)} onDelete(folder)} > {t(mediaMessages.delete)}
    {hasChildren && (
      {children.map((child) => ( ))}
    )}
  • ) }