feat(pre-matricula): add metadata preview image upload and deletion UI
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s
Details
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s
Details
This commit is contained in:
parent
a47f23d95a
commit
e5e3c6d89e
|
|
@ -4,7 +4,7 @@ import {
|
||||||
Plus, Trash2, Save, Eye, EyeOff, Download, GripVertical, Link2,
|
Plus, Trash2, Save, Eye, EyeOff, Download, GripVertical, Link2,
|
||||||
ClipboardPen, Copy, Check, ChevronDown, ChevronRight, Users, RefreshCw,
|
ClipboardPen, Copy, Check, ChevronDown, ChevronRight, Users, RefreshCw,
|
||||||
FileText, X, Settings2, ArrowLeft, ExternalLink, AlertCircle, UserCheck, Edit, Upload,
|
FileText, X, Settings2, ArrowLeft, ExternalLink, AlertCircle, UserCheck, Edit, Upload,
|
||||||
MessageSquare, Paperclip, Smile
|
MessageSquare, Paperclip, Smile, Image
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { useDialog } from '../DialogContext';
|
import { useDialog } from '../DialogContext';
|
||||||
|
|
||||||
|
|
@ -502,6 +502,63 @@ const PreMatricula: React.FC<Props> = ({ data, onConvert }) => {
|
||||||
<textarea className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:outline-none text-sm font-medium resize-none" rows={2}
|
<textarea className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:outline-none text-sm font-medium resize-none" rows={2}
|
||||||
value={config?.mensagemSucesso || ''} onChange={e => setConfig(prev => prev ? { ...prev, mensagemSucesso: e.target.value } : prev)} />
|
value={config?.mensagemSucesso || ''} onChange={e => setConfig(prev => prev ? { ...prev, mensagemSucesso: e.target.value } : prev)} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Imagem de Pré-Visualização (WhatsApp/Social)</label>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{config?.logoUrl ? (
|
||||||
|
<div className="relative group border border-slate-200 rounded-xl overflow-hidden bg-slate-50 p-2 flex items-center justify-between shadow-sm">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<img src={config.logoUrl} alt="Preview" className="w-12 h-12 object-contain rounded-lg border border-slate-200 bg-white" />
|
||||||
|
<span className="text-[10px] text-slate-400 font-mono truncate max-w-[140px]" title={config.logoUrl}>
|
||||||
|
{config.logoUrl.split('/').pop()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setConfig(prev => prev ? { ...prev, logoUrl: '' } : prev)}
|
||||||
|
className="p-2 bg-red-50 hover:bg-red-100 text-red-600 rounded-lg transition-colors"
|
||||||
|
title="Remover Imagem"
|
||||||
|
>
|
||||||
|
<Trash2 size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center justify-center border-2 border-dashed border-slate-200 hover:border-indigo-400 rounded-xl p-5 bg-slate-50 hover:bg-indigo-50/20 transition-all cursor-pointer relative">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
className="absolute inset-0 opacity-0 cursor-pointer"
|
||||||
|
onChange={async (e) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/prematricula/upload', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
const resData = await res.json();
|
||||||
|
setConfig(prev => prev ? { ...prev, logoUrl: resData.url } : prev);
|
||||||
|
showAlert('Sucesso', 'Imagem de visualização carregada!', 'success');
|
||||||
|
} else {
|
||||||
|
showAlert('Erro', 'Falha ao carregar imagem.', 'error');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showAlert('Erro', 'Erro de conexão ao enviar imagem.', 'error');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="text-center space-y-1">
|
||||||
|
<Image size={24} className="mx-auto text-slate-400 animate-pulse" />
|
||||||
|
<p className="text-xs font-bold text-slate-600">Fazer Upload da Imagem</p>
|
||||||
|
<p className="text-[9px] text-slate-400">JPG, PNG ou WebP até 5MB</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button onClick={saveConfig} disabled={isSaving}
|
<button onClick={saveConfig} disabled={isSaving}
|
||||||
className="w-full py-3 bg-indigo-600 text-white rounded-xl font-bold text-sm hover:bg-indigo-700 transition-all active:scale-95 flex items-center justify-center gap-2 disabled:opacity-50"
|
className="w-full py-3 bg-indigo-600 text-white rounded-xl font-bold text-sm hover:bg-indigo-700 transition-all active:scale-95 flex items-center justify-center gap-2 disabled:opacity-50"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue