Initial commit

This commit is contained in:
Zdeněk Burda
2026-01-09 21:26:40 +01:00
parent e83aec6dca
commit 41e3ce6f25
404 changed files with 61250 additions and 28 deletions

View File

@@ -0,0 +1,62 @@
import React from "react";
type FileDropZoneProps = {
disabled?: boolean;
multiple?: boolean;
selectedFiles: FileList | null;
label: string;
hint: string;
onFiles: (files: FileList | null) => void;
};
export default function FileDropZone({ disabled = false, multiple = false, selectedFiles, label, hint, onFiles }: FileDropZoneProps) {
const [isDragOver, setIsDragOver] = React.useState(false);
const fileInputRef = React.useRef<HTMLInputElement | null>(null);
const fileCount = selectedFiles?.length ?? 0;
const fileNames = selectedFiles ? Array.from(selectedFiles).map((file) => file.name) : [];
const selectedLabel =
fileCount > 1 ? `${fileCount} souborů vybráno` : selectedFiles && fileCount === 1 ? selectedFiles[0]?.name : label;
const selectedHint =
fileCount > 1 ? `Vybráno: ${fileNames.slice(0, 3).join(", ")}${fileCount > 3 ? ", ..." : ""}` : hint;
return (
<>
<input
ref={fileInputRef}
type="file"
multiple={multiple}
onChange={(e) => onFiles(e.target.files)}
aria-label={label}
className="sr-only"
disabled={disabled}
/>
<div
onClick={() => !disabled && fileInputRef.current?.click()}
onDragOver={(e) => {
if (disabled) return;
e.preventDefault();
setIsDragOver(true);
}}
onDragLeave={(e) => {
if (disabled) return;
e.preventDefault();
setIsDragOver(false);
}}
onDrop={(e) => {
if (disabled) return;
e.preventDefault();
setIsDragOver(false);
onFiles(e.dataTransfer.files);
}}
className={`flex-1 min-w-[240px] cursor-pointer rounded border-2 border-dashed p-4 ${
isDragOver ? "border-primary bg-green-50" : "border-default-300 bg-green-50"
} ${disabled ? "opacity-60 cursor-not-allowed" : ""}`}
>
<div className="flex flex-col items-start gap-1 text-sm">
<span className="font-semibold">{selectedLabel}</span>
<span className="text-foreground-500">{selectedHint}</span>
</div>
</div>
</>
);
}