"use client"; import { getFileIcon, type FileEntry } from "@/modules/files/components/file-manager-presenters"; import { FILES_MENU_SHELL, FILES_PANEL_INSET, } from "@/modules/files/components/file-manager-surface"; import { cn } from "@/lib/utils"; import { formatBytesCompact } from "@/lib/client/format"; import type { FileInfoResponse } from "@/lib/shared/contracts/files"; import { File, FileArchive, Folder, Trash2, Upload, X } from "@/components/icons/platform-icons"; const cancelBtn = "rounded-lg px-2.5 py-1 text-xs text-muted-foreground transition-colors hover:bg-background/50 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50"; const inputField = "mt-1 h-8 w-full rounded-lg border border-glass-border bg-background/55 px-2 text-xs text-foreground placeholder:text-muted-foreground/60 outline-none focus:border-primary/40 focus:bg-background/70"; const overlay = "absolute inset-0 z-[205] flex items-center justify-center bg-background/35 px-4 backdrop-blur-[1px]"; export function CreateEntryDialog({ dialog, isCreatePending, onClose, onDialogChange, onSubmit, }: { dialog: { kind: "file" | "folder"; name: string; error: string | null }; isCreatePending: boolean; onClose: () => void; onDialogChange: (value: string) => void; onSubmit: () => void; }) { return (
e.stopPropagation()} >
{dialog.kind === "folder" ? ( ) : ( )} {dialog.kind === "folder" ? "Create New Folder" : "Create New File"}
{dialog.error &&
{dialog.error}
}
); } export function RenameEntryDialog({ dialog, isRenamePending, onClose, onDialogChange, onSubmit, }: { dialog: { entry: FileEntry; name: string; error: string | null }; isRenamePending: boolean; onClose: () => void; onDialogChange: (value: string) => void; onSubmit: () => void; }) { return (
e.stopPropagation()} >
{dialog.entry.type === "folder" ? ( ) : ( )} Rename
{dialog.error &&
{dialog.error}
}
); } export function EmptyTrashConfirmDialog({ itemCount, onCancel, onConfirm, }: { itemCount: number; onCancel: () => void; onConfirm: () => void; }) { return (
e.stopPropagation()} >
Empty Trash

Permanently delete{" "} {itemCount} item{itemCount !== 1 ? "s" : ""} {" "} from Trash? This cannot be undone.

); } function getUploadPercent(progress: { loaded: number; total: number } | null) { if (!progress || progress.total <= 0) return 0; return Math.min(100, Math.max(0, Math.round((progress.loaded / progress.total) * 100))); } export function UploadProgressDialog({ operation = "upload", progress, onCancel, }: { operation?: "upload" | "unzip"; progress: { loaded: number; total: number } | null; onCancel?: () => void; }) { const isUpload = operation === "upload"; const progressPercent = getUploadPercent(progress); const progressText = progress ? `${formatBytesCompact(progress.loaded)} of ${formatBytesCompact(progress.total)}` : isUpload ? "Preparing upload" : "Extracting archive"; const title = isUpload ? "Uploading files" : "Unzipping file"; const status = isUpload ? "Uploading" : "Unzipping"; const progressLabel = isUpload ? "Upload progress" : "Unzip progress"; return (
{onCancel ? ( ) : ( )}
{isUpload ? ( ) : ( )} {title}
{progressText}
{status} {progress ? `${progressPercent}%` : isUpload ? "0%" : "Working"}
{onCancel ? (
) : null}
); } export function FileInfoDialogOverlay({ fileInfo, onClose, }: { fileInfo: FileInfoResponse; onClose: () => void; }) { const rows = [ { label: "Type", value: fileInfo.type === "folder" ? "Folder" : fileInfo.ext ? `${fileInfo.ext.toUpperCase()} file` : "File", }, { label: "Size", value: fileInfo.type === "folder" ? "—" : formatBytesCompact(fileInfo.sizeBytes) }, { label: "Modified", value: new Date(fileInfo.modifiedAt).toLocaleString("en-US", { month: "short", day: "numeric", year: "numeric", hour: "2-digit", minute: "2-digit", }), }, { label: "Created", value: new Date(fileInfo.createdAt).toLocaleString("en-US", { month: "short", day: "numeric", year: "numeric", hour: "2-digit", minute: "2-digit", }), }, { label: "Path", value: fileInfo.path }, { label: "Permissions", value: fileInfo.permissions }, { label: "Starred", value: fileInfo.starred ? "Yes" : "No" }, ]; return (
e.stopPropagation()} >
{getFileIcon({ ...fileInfo, modified: "", modifiedAt: "", mtimeMs: 0 } as FileEntry)} {fileInfo.name}
{rows.map(({ label, value }) => (
{label} {value}
))}
); } export function PasteConflictDialog({ conflictName, onReplace, onKeepBoth, onSkip, onSkipAll, }: { conflictName: string; onReplace: () => void; onKeepBoth: () => void; onSkip: () => void; onSkipAll: () => void; }) { return (
Item Already Exists

{conflictName} already exists in the destination. What would you like to do?

); }