Corrigir exclusao e salvamento de projetos com dialogos customizados e botao duplo salvar
This commit is contained in:
+114
-21
@@ -11,6 +11,72 @@ function escapeHtml(text) {
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// Função auxiliar para exibir alerta customizado e elegante (substitui o alert nativo)
|
||||
function showCustomAlert(title, message) {
|
||||
return new Promise((resolve) => {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'custom-dialog-overlay';
|
||||
|
||||
overlay.innerHTML = `
|
||||
<div class="custom-dialog-card">
|
||||
<div class="custom-dialog-header">
|
||||
<span>🔔</span>
|
||||
<span>${escapeHtml(title)}</span>
|
||||
</div>
|
||||
<p class="custom-dialog-body">${escapeHtml(message)}</p>
|
||||
<div class="custom-dialog-footer">
|
||||
<button class="btn-dialog btn-dialog-confirm">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const btn = overlay.querySelector('.btn-dialog-confirm');
|
||||
btn.addEventListener('click', () => {
|
||||
overlay.remove();
|
||||
resolve();
|
||||
});
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
});
|
||||
}
|
||||
|
||||
// Função auxiliar para exibir diálogo de confirmação elegante (substitui o confirm nativo)
|
||||
function showCustomConfirm(title, message, isDanger = false) {
|
||||
return new Promise((resolve) => {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'custom-dialog-overlay';
|
||||
|
||||
overlay.innerHTML = `
|
||||
<div class="custom-dialog-card">
|
||||
<div class="custom-dialog-header">
|
||||
<span>${isDanger ? '⚠️' : '❓'}</span>
|
||||
<span>${escapeHtml(title)}</span>
|
||||
</div>
|
||||
<p class="custom-dialog-body">${escapeHtml(message)}</p>
|
||||
<div class="custom-dialog-footer">
|
||||
<button class="btn-dialog btn-dialog-cancel">Cancelar</button>
|
||||
<button class="btn-dialog ${isDanger ? 'btn-dialog-danger' : 'btn-dialog-confirm'}">${isDanger ? 'Excluir' : 'Confirmar'}</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const btnCancel = overlay.querySelector('.btn-dialog-cancel');
|
||||
const btnConfirm = overlay.querySelector(isDanger ? '.btn-dialog-danger' : '.btn-dialog-confirm');
|
||||
|
||||
btnCancel.addEventListener('click', () => {
|
||||
overlay.remove();
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
btnConfirm.addEventListener('click', () => {
|
||||
overlay.remove();
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
});
|
||||
}
|
||||
|
||||
// Função auxiliar para gerar nome de arquivo de download formatado como <nome_data_hora>.<extensao>
|
||||
function getDownloadFileName(type, ext) {
|
||||
const now = new Date();
|
||||
@@ -3504,6 +3570,7 @@ const initApp = () => {
|
||||
const btnDeleteComicsProject = document.getElementById('btnDeleteComicsProject');
|
||||
const comicsProjectTitleInput = document.getElementById('comicsProjectTitleInput');
|
||||
const btnSaveComicsProject = document.getElementById('btnSaveComicsProject');
|
||||
const btnSaveNewComicsProject = document.getElementById('btnSaveNewComicsProject');
|
||||
|
||||
let currentComicsProjectId = null;
|
||||
let currentComicsCharDescEnglish = '';
|
||||
@@ -3619,6 +3686,7 @@ const initApp = () => {
|
||||
if (comicsProjectSelect) comicsProjectSelect.value = '';
|
||||
if (comicsProjectTitleInput) comicsProjectTitleInput.value = '';
|
||||
if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'none';
|
||||
if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'none';
|
||||
|
||||
comicsTemaInput.value = '';
|
||||
comicsResultArea.style.display = 'none';
|
||||
@@ -3707,6 +3775,7 @@ const initApp = () => {
|
||||
comicsTemaInput.value = project.tema || '';
|
||||
|
||||
if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'block';
|
||||
if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'block';
|
||||
|
||||
// Carregar proporção
|
||||
selectedComicsRatio = project.proporcao || '16:9';
|
||||
@@ -3829,34 +3898,40 @@ const initApp = () => {
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Erro ao carregar projeto: ' + err.message);
|
||||
await showCustomAlert('Erro', 'Erro ao carregar projeto: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const saveComicsProject = async () => {
|
||||
const saveComicsProjectFlow = async (forceNew = false) => {
|
||||
const titulo = comicsProjectTitleInput ? comicsProjectTitleInput.value.trim() : '';
|
||||
if (!titulo) {
|
||||
alert('Por favor, digite um título para salvar seu projeto.');
|
||||
await showCustomAlert('Campo Obrigatório', 'Por favor, digite um título para salvar seu projeto.');
|
||||
return;
|
||||
}
|
||||
|
||||
const characters = [];
|
||||
document.querySelectorAll('.comic-char-row').forEach(row => {
|
||||
const type = row.querySelector('.char-type-input').value.trim();
|
||||
const name = row.querySelector('.char-name-input').value.trim();
|
||||
const isAnimal = row.querySelector('span').textContent === '🐾';
|
||||
if (type || name) {
|
||||
characters.push({ type, name, isAnimal });
|
||||
const typeInput = row.querySelector('.char-type-input');
|
||||
const nameInput = row.querySelector('.char-name-input');
|
||||
if (typeInput && nameInput) {
|
||||
const type = typeInput.value.trim();
|
||||
const name = nameInput.value.trim();
|
||||
const isAnimal = row.querySelector('span').textContent === '🐾';
|
||||
if (type || name) {
|
||||
characters.push({ type, name, isAnimal });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let cenario = comicsCenarioSelect.value;
|
||||
if (cenario === 'custom') {
|
||||
let cenario = comicsCenarioSelect ? comicsCenarioSelect.value : 'no parque de diversões colorido';
|
||||
if (cenario === 'custom' && comicsCenarioCustomInput) {
|
||||
cenario = comicsCenarioCustomInput.value.trim();
|
||||
}
|
||||
|
||||
const targetId = forceNew ? null : currentComicsProjectId;
|
||||
|
||||
const body = {
|
||||
id: currentComicsProjectId,
|
||||
id: targetId,
|
||||
titulo,
|
||||
tema: comicsTemaInput.value.trim(),
|
||||
cenario,
|
||||
@@ -3885,18 +3960,28 @@ const initApp = () => {
|
||||
|
||||
const data = await resp.json();
|
||||
currentComicsProjectId = data.id;
|
||||
alert('Projeto salvo com sucesso!');
|
||||
await showCustomAlert('Sucesso', 'Projeto salvo com sucesso!');
|
||||
|
||||
if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'block';
|
||||
if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'block';
|
||||
await loadComicsProjectsList();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Erro ao salvar projeto: ' + err.message);
|
||||
await showCustomAlert('Erro', 'Erro ao salvar projeto: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
const saveComicsProject = () => saveComicsProjectFlow(false);
|
||||
const saveNewComicsProject = () => saveComicsProjectFlow(true);
|
||||
|
||||
const deleteComicsProject = async () => {
|
||||
if (!currentComicsProjectId) return;
|
||||
if (!confirm('Tem certeza de que deseja excluir este projeto permanentemente?')) return;
|
||||
const confirmed = await showCustomConfirm(
|
||||
'Confirmar Exclusão',
|
||||
'Tem certeza de que deseja excluir este projeto permanentemente?',
|
||||
true
|
||||
);
|
||||
if (!confirmed) return;
|
||||
|
||||
try {
|
||||
const resp = await fetch(`/api/comics/projects/${currentComicsProjectId}`, {
|
||||
@@ -3905,12 +3990,12 @@ const initApp = () => {
|
||||
|
||||
if (!resp.ok) throw new Error('Falha ao excluir projeto');
|
||||
|
||||
alert('Projeto excluído com sucesso!');
|
||||
await showCustomAlert('Excluído', 'Projeto excluído com sucesso!');
|
||||
startNewComicsProject();
|
||||
await loadComicsProjectsList();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Erro ao excluir projeto: ' + err.message);
|
||||
await showCustomAlert('Erro', 'Erro ao excluir projeto: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3929,8 +4014,12 @@ const initApp = () => {
|
||||
}
|
||||
|
||||
if (btnNewComicsProject) {
|
||||
btnNewComicsProject.addEventListener('click', () => {
|
||||
if (confirm('Deseja iniciar um novo projeto? Alterações não salvas serão perdidas.')) {
|
||||
btnNewComicsProject.addEventListener('click', async () => {
|
||||
const confirmed = await showCustomConfirm(
|
||||
'Novo Projeto',
|
||||
'Deseja iniciar um novo projeto? Alterações não salvas serão perdidas.'
|
||||
);
|
||||
if (confirmed) {
|
||||
startNewComicsProject();
|
||||
}
|
||||
});
|
||||
@@ -3940,6 +4029,10 @@ const initApp = () => {
|
||||
btnSaveComicsProject.addEventListener('click', saveComicsProject);
|
||||
}
|
||||
|
||||
if (btnSaveNewComicsProject) {
|
||||
btnSaveNewComicsProject.addEventListener('click', saveNewComicsProject);
|
||||
}
|
||||
|
||||
if (btnDeleteComicsProject) {
|
||||
btnDeleteComicsProject.addEventListener('click', deleteComicsProject);
|
||||
}
|
||||
@@ -3986,7 +4079,7 @@ const initApp = () => {
|
||||
btnGenerateComics.addEventListener('click', async () => {
|
||||
const tema = comicsTemaInput.value.trim();
|
||||
if (!tema) {
|
||||
alert('Por favor, digite um tema para a história.');
|
||||
await showCustomAlert('Campo Requerido', 'Por favor, digite um tema para a história.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4001,7 +4094,7 @@ const initApp = () => {
|
||||
});
|
||||
|
||||
if (personagens.length === 0) {
|
||||
alert('Adicione e preencha pelo menos um personagem principal.');
|
||||
await showCustomAlert('Personagens Faltando', 'Adicione e preencha pelo menos um personagem principal.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4161,7 +4254,7 @@ const initApp = () => {
|
||||
|
||||
} catch (err) {
|
||||
console.error('Erro ao fabricar quadrinhos:', err);
|
||||
alert('Erro ao fabricar quadrinhos: ' + err.message);
|
||||
await showCustomAlert('Erro', 'Erro ao fabricar quadrinhos: ' + err.message);
|
||||
comicsGenerateLoader.style.display = 'none';
|
||||
btnGenerateComics.disabled = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user