Add S3 MinIO upload feature for lesson cover images in admin manager
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 4m26s
Details
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 4m26s
Details
This commit is contained in:
parent
279a1510d3
commit
1f18813b41
|
|
@ -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">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue