Implement authentication system with access control UI
This commit is contained in:
@@ -89,6 +89,8 @@ export interface DragDropUploadProps {
|
||||
maxRetries?: number;
|
||||
tag?: string;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
disabledReason?: string;
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
@@ -230,6 +232,8 @@ export function DragDropUpload({
|
||||
maxRetries = 3,
|
||||
tag,
|
||||
className = '',
|
||||
disabled = false,
|
||||
disabledReason,
|
||||
}: DragDropUploadProps) {
|
||||
const [isDragOver, setIsDragOver] = useState(false);
|
||||
const [uploadQueue, setUploadQueue] = useState<UploadItem[]>([]);
|
||||
@@ -649,20 +653,22 @@ export function DragDropUpload({
|
||||
const handleDragEnter = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (disabled) return;
|
||||
dragCounterRef.current++;
|
||||
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
|
||||
setIsDragOver(true);
|
||||
}
|
||||
}, []);
|
||||
}, [disabled]);
|
||||
|
||||
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (disabled) return;
|
||||
dragCounterRef.current--;
|
||||
if (dragCounterRef.current === 0) {
|
||||
setIsDragOver(false);
|
||||
}
|
||||
}, []);
|
||||
}, [disabled]);
|
||||
|
||||
const handleDragOver = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -675,18 +681,22 @@ export function DragDropUpload({
|
||||
setIsDragOver(false);
|
||||
dragCounterRef.current = 0;
|
||||
|
||||
if (disabled) return;
|
||||
|
||||
const files = e.dataTransfer.files;
|
||||
if (files && files.length > 0) {
|
||||
addFiles(files);
|
||||
}
|
||||
}, [addFiles]);
|
||||
}, [addFiles, disabled]);
|
||||
|
||||
// Click to browse
|
||||
const handleClick = useCallback(() => {
|
||||
if (disabled) return;
|
||||
fileInputRef.current?.click();
|
||||
}, []);
|
||||
}, [disabled]);
|
||||
|
||||
const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (disabled) return;
|
||||
const files = e.target.files;
|
||||
if (files && files.length > 0) {
|
||||
addFiles(files);
|
||||
@@ -695,7 +705,7 @@ export function DragDropUpload({
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
}, [addFiles]);
|
||||
}, [addFiles, disabled]);
|
||||
|
||||
// Remove item from queue
|
||||
const removeItem = useCallback((id: string) => {
|
||||
@@ -738,15 +748,17 @@ export function DragDropUpload({
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`drop-zone ${isDragOver ? 'drop-zone--active' : ''}`}
|
||||
className={`drop-zone ${isDragOver ? 'drop-zone--active' : ''} ${disabled ? 'drop-zone--disabled' : ''}`}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={handleDrop}
|
||||
onClick={handleClick}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
|
||||
aria-disabled={disabled}
|
||||
title={disabled ? disabledReason : undefined}
|
||||
>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
@@ -755,16 +767,23 @@ export function DragDropUpload({
|
||||
onChange={handleFileChange}
|
||||
className="drop-zone__input"
|
||||
accept={!allowAllTypes && allowedTypes ? allowedTypes.join(',') : undefined}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<div className="drop-zone__content">
|
||||
<UploadIcon />
|
||||
<p className="drop-zone__text">
|
||||
<strong>Drag files here</strong> or click to browse
|
||||
</p>
|
||||
<p className="drop-zone__hint">
|
||||
{maxFileSize && `Max file size: ${formatBytes(maxFileSize)}`}
|
||||
{!allowAllTypes && allowedTypes && ` • Accepted: ${allowedTypes.join(', ')}`}
|
||||
{disabled ? (
|
||||
<span>{disabledReason || 'Upload disabled'}</span>
|
||||
) : (
|
||||
<><strong>Drag files here</strong> or click to browse</>
|
||||
)}
|
||||
</p>
|
||||
{!disabled && (
|
||||
<p className="drop-zone__hint">
|
||||
{maxFileSize && `Max file size: ${formatBytes(maxFileSize)}`}
|
||||
{!allowAllTypes && allowedTypes && ` • Accepted: ${allowedTypes.join(', ')}`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user