🗑️ Auto-deploy: Adicionada opção de deletar histórico no Garatujas e BrincarAtivo

This commit is contained in:
2026-06-05 00:45:18 +00:00
parent be92525fbd
commit 029ab13e0d
2 changed files with 114 additions and 3 deletions
+54 -3
View File
@@ -4983,13 +4983,39 @@ const initApp = () => {
div.style.padding = '12px'; div.style.padding = '12px';
div.innerHTML = ` div.innerHTML = `
<div style="width: 100%; aspect-ratio: 4/3; overflow: hidden; border-radius: 6px; background: rgba(0,0,0,0.2);"> <div style="position: relative; width: 100%; aspect-ratio: 4/3; overflow: hidden; border-radius: 6px; background: rgba(0,0,0,0.2);">
<img src="${item.imageUrl}" style="width: 100%; height: 100%; object-fit: cover;"> <img src="${item.imageUrl}" style="width: 100%; height: 100%; object-fit: cover;">
<button class="delete-btn" data-id="${item.id}" style="position: absolute; top: 6px; right: 6px; background: rgba(0,0,0,0.5); border: none; width: 26px; height: 26px; border-radius: 50%; color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 0.8rem; transition: background 0.2s, transform 0.2s; z-index: 10;" title="Deletar análise" onmouseover="this.style.background='rgba(220,53,69,0.95)'; this.style.transform='scale(1.1)';" onmouseout="this.style.background='rgba(0,0,0,0.5)'; this.style.transform='scale(1)';">
🗑️
</button>
</div> </div>
<div style="font-weight: 600; color: var(--text-primary); font-size: 0.9rem;">${escapeHtml(item.alunoName)}</div> <div style="font-weight: 600; color: var(--text-primary); font-size: 0.9rem;">${escapeHtml(item.alunoName)}</div>
<div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div> <div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div>
`; `;
const deleteBtn = div.querySelector('.delete-btn');
deleteBtn.addEventListener('click', async (e) => {
e.stopPropagation();
if (confirm(`Deseja realmente excluir a análise de desenho do aluno "${item.alunoName}"?`)) {
try {
const delResp = await fetch(`/api/garatujas/${item.id}`, { method: 'DELETE' });
if (!delResp.ok) throw new Error('Falha ao deletar');
alert('Análise deletada com sucesso.');
loadGaratujasHistory();
if (activeGaratujaReport && activeGaratujaReport.id === item.id) {
activeGaratujaReport = null;
garatujasAlunoInput.value = '';
garatujaImgPreview.src = '';
garatujaPreviewContainer.style.display = 'none';
garatujaReportArea.innerHTML = '';
garatujaResultArea.style.display = 'none';
}
} catch (err) {
alert('Erro ao excluir análise: ' + err.message);
}
}
});
div.addEventListener('click', async () => { div.addEventListener('click', async () => {
try { try {
const detailResp = await fetch(`/api/garatujas/${item.id}`); const detailResp = await fetch(`/api/garatujas/${item.id}`);
@@ -5242,13 +5268,38 @@ const initApp = () => {
const previewText = lines.length > 60 ? lines.substring(0, 60) + '...' : lines; const previewText = lines.length > 60 ? lines.substring(0, 60) + '...' : lines;
div.innerHTML = ` div.innerHTML = `
<div style="font-weight: 600; color: var(--text-primary); font-size: 0.92rem; display: flex; align-items: center; gap: 6px;"> <div style="font-weight: 600; color: var(--text-primary); font-size: 0.92rem; display: flex; align-items: center; justify-content: space-between; gap: 6px;">
<span>🏃‍♂️</span> ${escapeHtml(item.faixaEtaria.split(' ')[0])} (${item.faixaEtaria.includes('bem pequenas') ? 'Bem Pequenas' : (item.faixaEtaria.includes('pequenas') ? 'Pequenas' : 'Bebês')}) <span>🏃‍♂️ ${escapeHtml(item.faixaEtaria.split(' ')[0])} (${item.faixaEtaria.includes('bem pequenas') ? 'Bem Pequenas' : (item.faixaEtaria.includes('pequenas') ? 'Pequenas' : 'Bebês')})</span>
<button class="delete-btn" data-id="${item.id}" style="background: transparent; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.95rem; padding: 2px 6px; border-radius: 4px; transition: color 0.2s, background 0.2s; display: flex; align-items: center; justify-content: center; z-index: 10;" title="Deletar atividade" onmouseover="this.style.color='#ff4d4f'; this.style.background='rgba(255, 77, 79, 0.1)'" onmouseout="this.style.color='var(--text-muted)'; this.style.background='transparent'">
🗑️
</button>
</div> </div>
<div style="font-size: 0.8rem; color: var(--text-secondary);">Recursos: ${escapeHtml(previewText)}</div> <div style="font-size: 0.8rem; color: var(--text-secondary);">Recursos: ${escapeHtml(previewText)}</div>
<div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div> <div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div>
`; `;
const deleteBtn = div.querySelector('.delete-btn');
deleteBtn.addEventListener('click', async (e) => {
e.stopPropagation();
if (confirm(`Deseja realmente excluir esta atividade psicomotora do histórico?`)) {
try {
const delResp = await fetch(`/api/brincar-ativo/${item.id}`, { method: 'DELETE' });
if (!delResp.ok) throw new Error('Falha ao deletar');
alert('Atividade deletada com sucesso.');
loadBrincarAtivoHistory();
if (activeBrincarAtivoReport && activeBrincarAtivoReport.id === item.id) {
activeBrincarAtivoReport = null;
brincarAtivoFaixaSelect.value = '';
brincarAtivoRecursosInput.value = '';
brincarAtivoReportArea.innerHTML = '';
brincarAtivoResultArea.style.display = 'none';
}
} catch (err) {
alert('Erro ao excluir atividade: ' + err.message);
}
}
});
div.addEventListener('click', async () => { div.addEventListener('click', async () => {
try { try {
const detailResp = await fetch(`/api/brincar-ativo/${item.id}`); const detailResp = await fetch(`/api/brincar-ativo/${item.id}`);
+60
View File
@@ -970,6 +970,47 @@ app.get('/api/garatujas/:id', requireAuth, async (req, res) => {
} }
}); });
app.delete('/api/garatujas/:id', requireAuth, async (req, res) => {
const { id } = req.params;
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const imageRes = await dbPool.query(
`SELECT image_url FROM escola.garatujas WHERE id = $1 AND usuario_id = $2`,
[id, usuarioId]
);
const dbRes = await dbPool.query(
`DELETE FROM escola.garatujas WHERE id = $1 AND usuario_id = $2`,
[id, usuarioId]
);
if (dbRes.rowCount === 0) {
return res.status(404).json({ error: 'Análise não encontrada ou não pertence ao usuário.' });
}
if (imageRes.rows.length > 0 && imageRes.rows[0].image_url) {
const imgUrl = imageRes.rows[0].image_url;
if (imgUrl.startsWith('/generated-media/')) {
const fs = require('fs');
const filename = imgUrl.replace('/generated-media/', '');
const filepath = path.join(__dirname, 'public', 'generated-media', filename);
if (fs.existsSync(filepath)) {
try {
fs.unlinkSync(filepath);
} catch (unlinkErr) {
console.error('Erro ao deletar arquivo de imagem fisicamente:', unlinkErr);
}
}
}
}
res.json({ success: true, message: 'Análise de desenho deletada com sucesso.' });
} catch (err) {
console.error('Erro ao deletar garatuja:', err);
res.status(500).json({ error: 'Erro ao deletar análise.' });
}
});
// ============================================================ // ============================================================
// ROTAS DO BRINCARATIVO (CIRCUITOS PSICOMOTORES E BRINCADEIRAS) // ROTAS DO BRINCARATIVO (CIRCUITOS PSICOMOTORES E BRINCADEIRAS)
// ============================================================ // ============================================================
@@ -1077,6 +1118,25 @@ app.get('/api/brincar-ativo/:id', requireAuth, async (req, res) => {
} }
}); });
app.delete('/api/brincar-ativo/:id', requireAuth, async (req, res) => {
const { id } = req.params;
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
try {
const dbRes = await dbPool.query(
`DELETE FROM escola.brincar_ativo WHERE id = $1 AND usuario_id = $2`,
[id, usuarioId]
);
if (dbRes.rowCount === 0) {
return res.status(404).json({ error: 'Atividade não encontrada ou não pertence ao usuário.' });
}
res.json({ success: true, message: 'Atividade deletada com sucesso.' });
} catch (err) {
console.error('Erro ao deletar brincar-ativo:', err);
res.status(500).json({ error: 'Erro ao deletar atividade.' });
}
});
// Rota GET para obter configurações do agente // Rota GET para obter configurações do agente
app.get('/api/agent-config', requireAuth, (req, res) => { app.get('/api/agent-config', requireAuth, (req, res) => {
const config = readAgentConfig(); const config = readAgentConfig();