Add S3 MinIO upload feature for lesson cover images in admin manager
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 4m26s Details

This commit is contained in:
Sidney Gomes 2026-07-24 17:56:11 -03:00
parent 279a1510d3
commit 1f18813b41
1 changed files with 51 additions and 7 deletions

View File

@ -102,6 +102,38 @@ export default function AdminContentManager({ token }: AdminContentManagerProps)
} }
}; };
const [uploadingLessonImage, setUploadingLessonImage] = useState(false);
const handleLessonImageUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
setUploadingLessonImage(true);
try {
const res = await fetch('/api/admin/upload', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
const data = await res.json();
if (res.ok && data.url) {
setLessonForm(prev => ({ ...prev, thumbnailUrl: data.url }));
} else {
alert(data.error || 'Erro ao fazer upload da imagem');
}
} catch (err) {
console.error(err);
alert('Erro de conexão ao fazer upload');
} finally {
setUploadingLessonImage(false);
}
};
useEffect(() => { useEffect(() => {
fetchCourses(); fetchCourses();
}, []); }, []);
@ -708,13 +740,25 @@ export default function AdminContentManager({ token }: AdminContentManagerProps)
<div className="md:col-span-3 space-y-2"> <div className="md:col-span-3 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase">Imagem de Capa da Aula (Thumbnail URL - Opcional)</label> <label className="text-xs text-zinc-400 font-bold uppercase">Imagem de Capa da Aula (Thumbnail URL - Opcional)</label>
<input <div className="flex items-center space-x-2">
type="text" <input
value={lessonForm.thumbnailUrl} type="text"
onChange={(e) => setLessonForm({ ...lessonForm, thumbnailUrl: e.target.value })} value={lessonForm.thumbnailUrl}
placeholder="Cole a URL da imagem de capa para esta aula (ex: https://meuservidor.com/capa.jpg)" onChange={(e) => setLessonForm({ ...lessonForm, thumbnailUrl: e.target.value })}
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none" placeholder="Cole a URL ou use o botão para fazer upload para o S3"
/> className="flex-1 glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
<label className="bg-zinc-800 hover:bg-zinc-700 text-white text-[11px] font-bold py-3.5 px-3 rounded-lg border border-white/10 transition-all flex items-center justify-center space-x-1.5 cursor-pointer select-none">
{uploadingLessonImage ? 'Enviando...' : 'Upload S3'}
<input
type="file"
accept="image/*"
onChange={handleLessonImageUpload}
disabled={uploadingLessonImage}
className="hidden"
/>
</label>
</div>
</div> </div>
<div className="md:col-span-3 space-y-2"> <div className="md:col-span-3 space-y-2">