Uploads and fixes now bust browser cache via file-mtime keys in API responses. Debug upload shows a centered loading overlay and blocks search while uploading. Prod DB restore skips curator_audit_log. Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
import { useRef, type ChangeEvent } from 'react';
|
|
|
|
interface Props {
|
|
uploading: boolean;
|
|
disabled?: boolean;
|
|
onUploadPress?: () => void;
|
|
onFileSelected: (file: File) => void | Promise<void>;
|
|
}
|
|
|
|
export default function DebugUploadButton({
|
|
uploading,
|
|
disabled = false,
|
|
onUploadPress,
|
|
onFileSelected,
|
|
}: Props) {
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const inactive = disabled || uploading;
|
|
|
|
const handleChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
|
const input = e.currentTarget;
|
|
const file = input.files?.[0];
|
|
if (!file || inactive) return;
|
|
|
|
try {
|
|
await onFileSelected(file);
|
|
} finally {
|
|
input.value = '';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<label
|
|
className={`debug-upload-btn${inactive ? ' debug-upload-btn-disabled' : ''}`}
|
|
aria-busy={uploading}
|
|
onClick={() => {
|
|
if (!inactive) onUploadPress?.();
|
|
}}
|
|
>
|
|
{uploading ? (
|
|
<span className="debug-upload-btn-loading">
|
|
<span className="debug-upload-btn-spinner" aria-hidden />
|
|
Uploading…
|
|
</span>
|
|
) : (
|
|
'Upload'
|
|
)}
|
|
<input
|
|
ref={inputRef}
|
|
className="debug-upload-input"
|
|
type="file"
|
|
accept="image/jpeg,image/png,image/webp,image/gif,image/avif,.jpg,.jpeg,.png,.webp,.gif,.avif"
|
|
disabled={inactive}
|
|
onChange={handleChange}
|
|
/>
|
|
</label>
|
|
);
|
|
}
|