feat(catalogue): coller une image depuis le presse-papier (Ctrl+V)
Écoute l'événement paste sur window quand le formulaire est ouvert. Si le presse-papier contient une image, déclenche le même upload que le bouton fichier. Indice visuel "ou Ctrl+V" affiché sous le bouton. Les deux méthodes (fichier + coller) coexistent. v0.4.13 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "homehub-frontend",
|
||||
"private": true,
|
||||
"version": "0.4.12",
|
||||
"version": "0.4.13",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -147,9 +147,7 @@ export default function CatalogueModal({ stores, onClose }: CatalogueModalProps)
|
||||
}
|
||||
}
|
||||
|
||||
async function handlePhotoChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
const file = e.target.files?.[0]
|
||||
if (!file) return
|
||||
async function uploadFile(file: File) {
|
||||
setUploading(true)
|
||||
setError(null)
|
||||
try {
|
||||
@@ -167,6 +165,11 @@ export default function CatalogueModal({ stores, onClose }: CatalogueModalProps)
|
||||
}
|
||||
}
|
||||
|
||||
async function handlePhotoChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
const file = e.target.files?.[0]
|
||||
if (file) await uploadFile(file)
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
if (!form.name.trim()) return
|
||||
setSaving(true)
|
||||
@@ -200,6 +203,18 @@ export default function CatalogueModal({ stores, onClose }: CatalogueModalProps)
|
||||
const isFormOpen = creating || editing !== null
|
||||
const previewSrc = form.thumbnail_path ?? form.image_path
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFormOpen) return
|
||||
function onPaste(e: ClipboardEvent) {
|
||||
const item = Array.from(e.clipboardData?.items ?? []).find(i => i.type.startsWith('image/'))
|
||||
if (!item) return
|
||||
const file = item.getAsFile()
|
||||
if (file) void uploadFile(file)
|
||||
}
|
||||
window.addEventListener('paste', onPaste)
|
||||
return () => window.removeEventListener('paste', onPaste)
|
||||
}, [isFormOpen])
|
||||
|
||||
return (
|
||||
<Modal title="Catalogue d'articles" onClose={onClose} width={580}>
|
||||
{error && (
|
||||
@@ -226,12 +241,17 @@ export default function CatalogueModal({ stores, onClose }: CatalogueModalProps)
|
||||
}}>📷</div>
|
||||
)}
|
||||
<input ref={photoRef} type="file" accept="image/*" capture="environment" style={{ display: 'none' }} onChange={handlePhotoChange} />
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => photoRef.current?.click()}
|
||||
disabled={uploading}
|
||||
style={{ padding: '6px 14px', borderRadius: 8, border: '1px solid var(--bg-5)', background: 'var(--bg-4)', color: 'var(--ink-2)', cursor: 'pointer', fontFamily: 'var(--font-ui)', fontSize: 13 }}
|
||||
>{uploading ? '…' : previewSrc ? 'Changer' : 'Ajouter photo'}</button>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => photoRef.current?.click()}
|
||||
disabled={uploading}
|
||||
style={{ padding: '6px 14px', borderRadius: 8, border: '1px solid var(--bg-5)', background: 'var(--bg-4)', color: 'var(--ink-2)', cursor: 'pointer', fontFamily: 'var(--font-ui)', fontSize: 13 }}
|
||||
>{uploading ? '…' : previewSrc ? 'Changer' : 'Ajouter photo'}</button>
|
||||
{!uploading && (
|
||||
<span style={{ color: 'var(--ink-4)', fontSize: 11, fontFamily: 'var(--font-ui)', paddingLeft: 4 }}>ou Ctrl+V pour coller</span>
|
||||
)}
|
||||
</div>
|
||||
{previewSrc && (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user