Implementação do banco de dados das Turmas e Alunos no Supabase e Refatoração do Modal de Cadastro
This commit is contained in:
+482
@@ -0,0 +1,482 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const appFile = path.join(__dirname, 'public', 'app.js');
|
||||
let appCode = fs.readFileSync(appFile, 'utf8');
|
||||
|
||||
const startIndex = appCode.indexOf('// ============================================================\n // MODAL: MINHA TURMA');
|
||||
const endIndex = appCode.indexOf('// ============================================================\n // CRUD DE MODELOS DE RELATÓRIO');
|
||||
|
||||
if (startIndex === -1 || endIndex === -1) {
|
||||
console.error("Could not find start or end index for replacement");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const newLogic = `// ============================================================
|
||||
// MODAL: MINHA TURMA (COM MÚLTIPLAS TURMAS E SUPABASE)
|
||||
// ============================================================
|
||||
const minhaTurmaModal = document.getElementById('minhaTurmaModal');
|
||||
const btnMinhaTurma = document.getElementById('btnMinhaTurma');
|
||||
const btnCloseMinhaTurmaModal = document.getElementById('btnCloseMinhaTurmaModal');
|
||||
|
||||
// Turmas List & Form
|
||||
const turmasList = document.getElementById('turmasList');
|
||||
const btnCreateTurma = document.getElementById('btnCreateTurma');
|
||||
const btnCancelTurma = document.getElementById('btnCancelTurma');
|
||||
const btnSaveTurmaConfig = document.getElementById('btnSaveTurmaConfig');
|
||||
const configTurmaId = document.getElementById('configTurmaId');
|
||||
const configTurmaNome = document.getElementById('configTurmaNome');
|
||||
const configTurmaSala = document.getElementById('configTurmaSala');
|
||||
const configTurmaPeriodo = document.getElementById('configTurmaPeriodo');
|
||||
const configTurmaProfTitular = document.getElementById('configTurmaProfTitular');
|
||||
const configTurmaProfAux1 = document.getElementById('configTurmaProfAux1');
|
||||
const configTurmaProfAux2 = document.getElementById('configTurmaProfAux2');
|
||||
const configTurmaCuidadora = document.getElementById('configTurmaCuidadora');
|
||||
const turmaFormTitle = document.getElementById('turmaFormTitle');
|
||||
|
||||
// Alunos List & Form
|
||||
const filterAlunosTurma = document.getElementById('filterAlunosTurma');
|
||||
const childrenList = document.getElementById('childrenList');
|
||||
const btnCreateChild = document.getElementById('btnCreateChild');
|
||||
const btnCancelChild = document.getElementById('btnCancelChild');
|
||||
const btnSaveChild = document.getElementById('btnSaveChild');
|
||||
const childFormTitle = document.getElementById('childFormTitle');
|
||||
const cFormId = document.getElementById('childFormId');
|
||||
const cFormTurma = document.getElementById('childFormTurma');
|
||||
const cFormNome = document.getElementById('childFormNome');
|
||||
const cFormApelido = document.getElementById('childFormApelido');
|
||||
const cFormDataNasc = document.getElementById('childFormDataNasc');
|
||||
const cFormEspecial = document.getElementById('childFormEspecial');
|
||||
const divEspecialDetalhes = document.getElementById('divEspecialDetalhes');
|
||||
const cFormEspecialDetalhes = document.getElementById('childFormEspecialDetalhes');
|
||||
const cFormPais = document.getElementById('childFormPais');
|
||||
const cFormAutorizados = document.getElementById('childFormAutorizados');
|
||||
|
||||
// Tabs
|
||||
const tabTurmaConfig = document.getElementById('tabTurmaConfig');
|
||||
const tabTurmaAlunos = document.getElementById('tabTurmaAlunos');
|
||||
const turmaConfigSection = document.getElementById('turmaConfigSection');
|
||||
const turmaAlunosSection = document.getElementById('turmaAlunosSection');
|
||||
|
||||
let currentTurmas = [];
|
||||
let currentAlunos = [];
|
||||
|
||||
// API Calls
|
||||
const fetchTurmas = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/turmas');
|
||||
currentTurmas = await res.json();
|
||||
populateTurmaSelects();
|
||||
return currentTurmas;
|
||||
} catch(e) { console.error(e); return []; }
|
||||
};
|
||||
|
||||
const fetchAlunos = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/alunos');
|
||||
currentAlunos = await res.json();
|
||||
localStorage.setItem('camila_turma', JSON.stringify(currentAlunos));
|
||||
return currentAlunos;
|
||||
} catch(e) { console.error(e); return []; }
|
||||
};
|
||||
|
||||
const populateTurmaSelects = () => {
|
||||
const opts = '<option value="">Todas as Turmas</option>' + currentTurmas.map(t => \`<option value="\${t.id}">\${t.nome}</option>\`).join('');
|
||||
if(filterAlunosTurma) filterAlunosTurma.innerHTML = opts;
|
||||
const formOpts = '<option value="">Selecione uma turma...</option>' + currentTurmas.map(t => \`<option value="\${t.id}">\${t.nome}</option>\`).join('');
|
||||
if(cFormTurma) cFormTurma.innerHTML = formOpts;
|
||||
if(document.getElementById('emitirFilterTurma')) {
|
||||
document.getElementById('emitirFilterTurma').innerHTML = '<option value="">Todas as turmas</option>' + currentTurmas.map(t => \`<option value="\${t.id}">\${t.nome}</option>\`).join('');
|
||||
}
|
||||
};
|
||||
|
||||
// Tabs Logic
|
||||
if (tabTurmaConfig) {
|
||||
tabTurmaConfig.addEventListener('click', () => {
|
||||
tabTurmaConfig.classList.add('active');
|
||||
tabTurmaConfig.style.borderBottomColor = 'var(--brand-green)';
|
||||
tabTurmaConfig.style.color = 'var(--brand-green)';
|
||||
tabTurmaAlunos.classList.remove('active');
|
||||
tabTurmaAlunos.style.borderBottomColor = 'transparent';
|
||||
tabTurmaAlunos.style.color = 'var(--text-secondary)';
|
||||
turmaConfigSection.style.display = 'flex';
|
||||
turmaAlunosSection.style.display = 'none';
|
||||
});
|
||||
}
|
||||
if (tabTurmaAlunos) {
|
||||
tabTurmaAlunos.addEventListener('click', () => {
|
||||
tabTurmaAlunos.classList.add('active');
|
||||
tabTurmaAlunos.style.borderBottomColor = 'var(--brand-green)';
|
||||
tabTurmaAlunos.style.color = 'var(--brand-green)';
|
||||
tabTurmaConfig.classList.remove('active');
|
||||
tabTurmaConfig.style.borderBottomColor = 'transparent';
|
||||
tabTurmaConfig.style.color = 'var(--text-secondary)';
|
||||
turmaAlunosSection.style.display = 'flex';
|
||||
turmaConfigSection.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Turmas Logic
|
||||
const clearTurmaForm = () => {
|
||||
configTurmaId.value = '';
|
||||
configTurmaNome.value = '';
|
||||
configTurmaSala.value = '';
|
||||
configTurmaPeriodo.value = 'Integral';
|
||||
configTurmaProfTitular.value = '';
|
||||
configTurmaProfAux1.value = '';
|
||||
configTurmaProfAux2.value = '';
|
||||
configTurmaCuidadora.value = '';
|
||||
turmaFormTitle.textContent = 'Cadastrar Turma';
|
||||
};
|
||||
|
||||
const renderTurmasList = () => {
|
||||
if(!turmasList) return;
|
||||
if(currentTurmas.length === 0) {
|
||||
turmasList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Nenhuma turma cadastrada.</div>';
|
||||
return;
|
||||
}
|
||||
turmasList.innerHTML = currentTurmas.map(t => \`
|
||||
<div style="background: var(--bg-secondary); border: 1px solid var(--border-light); padding: 12px; border-radius: 8px; display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<div style="font-weight: 600; color: var(--text-primary);">\${escapeHtml(t.nome)}</div>
|
||||
<div style="font-size: 0.8rem; color: var(--text-secondary);">\${t.periodo || ''} \${t.sala ? '- ' + t.sala : ''}</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button onclick="editTurma('\${t.id}')" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px;" title="Editar">✏️</button>
|
||||
<button onclick="deleteTurma('\${t.id}')" style="background: none; border: none; color: #ef4444; cursor: pointer; padding: 4px;" title="Excluir">🗑️</button>
|
||||
</div>
|
||||
</div>
|
||||
\`).join('');
|
||||
};
|
||||
|
||||
window.editTurma = (id) => {
|
||||
const t = currentTurmas.find(x => x.id === id);
|
||||
if(!t) return;
|
||||
configTurmaId.value = t.id;
|
||||
configTurmaNome.value = t.nome || '';
|
||||
configTurmaSala.value = t.sala || '';
|
||||
configTurmaPeriodo.value = t.periodo || 'Integral';
|
||||
configTurmaProfTitular.value = t.prof_titular || '';
|
||||
configTurmaProfAux1.value = t.prof_aux1 || '';
|
||||
configTurmaProfAux2.value = t.prof_aux2 || '';
|
||||
configTurmaCuidadora.value = t.cuidadora || '';
|
||||
turmaFormTitle.textContent = 'Editar Turma';
|
||||
};
|
||||
|
||||
window.deleteTurma = async (id) => {
|
||||
const isOk = await showCustomConfirm('Excluir Turma', 'Deseja excluir esta turma? Todos os alunos associados a ela também serão excluídos.', true);
|
||||
if(isOk) {
|
||||
await fetch('/api/turmas/' + id, { method: 'DELETE' });
|
||||
await fetchTurmas();
|
||||
await fetchAlunos();
|
||||
renderTurmasList();
|
||||
renderAlunosList();
|
||||
clearTurmaForm();
|
||||
}
|
||||
};
|
||||
|
||||
if(btnCreateTurma) btnCreateTurma.addEventListener('click', clearTurmaForm);
|
||||
if(btnCancelTurma) btnCancelTurma.addEventListener('click', clearTurmaForm);
|
||||
|
||||
if (btnSaveTurmaConfig) {
|
||||
btnSaveTurmaConfig.addEventListener('click', async () => {
|
||||
const nome = configTurmaNome.value.trim();
|
||||
if(!nome) { showCustomAlert('Aviso', 'O Nome da Turma é obrigatório.'); return; }
|
||||
|
||||
const body = {
|
||||
nome,
|
||||
sala: configTurmaSala.value,
|
||||
periodo: configTurmaPeriodo.value,
|
||||
profTitular: configTurmaProfTitular.value,
|
||||
profAux1: configTurmaProfAux1.value,
|
||||
profAux2: configTurmaProfAux2.value,
|
||||
cuidadora: configTurmaCuidadora.value
|
||||
};
|
||||
|
||||
const id = configTurmaId.value;
|
||||
const url = id ? '/api/turmas/' + id : '/api/turmas';
|
||||
const method = id ? 'PUT' : 'POST';
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
if(res.ok) {
|
||||
showCustomAlert('Sucesso', 'Turma salva com sucesso!');
|
||||
await fetchTurmas();
|
||||
renderTurmasList();
|
||||
clearTurmaForm();
|
||||
} else {
|
||||
showCustomAlert('Erro', 'Falha ao salvar turma.');
|
||||
}
|
||||
} catch(e) { console.error(e); }
|
||||
});
|
||||
}
|
||||
|
||||
// Alunos Logic
|
||||
const clearChildForm = () => {
|
||||
cFormId.value = '';
|
||||
cFormTurma.value = filterAlunosTurma ? filterAlunosTurma.value : '';
|
||||
cFormNome.value = '';
|
||||
cFormApelido.value = '';
|
||||
cFormDataNasc.value = '';
|
||||
cFormEspecial.checked = false;
|
||||
cFormEspecialDetalhes.value = '';
|
||||
divEspecialDetalhes.style.display = 'none';
|
||||
cFormPais.value = '';
|
||||
cFormAutorizados.value = '';
|
||||
childFormTitle.textContent = 'Cadastrar Criança';
|
||||
};
|
||||
|
||||
if (cFormEspecial) {
|
||||
cFormEspecial.addEventListener('change', () => {
|
||||
divEspecialDetalhes.style.display = cFormEspecial.checked ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
const renderAlunosList = () => {
|
||||
if (!childrenList) return;
|
||||
const filterTurmaId = filterAlunosTurma ? filterAlunosTurma.value : '';
|
||||
let filtered = currentAlunos;
|
||||
if(filterTurmaId) {
|
||||
filtered = currentAlunos.filter(a => a.turma_id === filterTurmaId);
|
||||
}
|
||||
|
||||
if (filtered.length === 0) {
|
||||
childrenList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Nenhuma criança encontrada.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
filtered.sort((a, b) => (a.nome || '').localeCompare(b.nome || ''));
|
||||
|
||||
childrenList.innerHTML = filtered.map(c => {
|
||||
const turmaObj = currentTurmas.find(t => t.id === c.turma_id);
|
||||
const turmaNome = turmaObj ? turmaObj.nome : 'Sem turma';
|
||||
return \`
|
||||
<div style="background: var(--bg-secondary); border: 1px solid var(--border-light); padding: 12px; border-radius: 8px; display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<div style="font-weight: 600; color: var(--text-primary);">\${escapeHtml(c.nome)} \${c.especial ? '⭐' : ''}</div>
|
||||
<div style="font-size: 0.8rem; color: var(--text-secondary);">\${escapeHtml(turmaNome)} \${c.apelido ? '- ' + escapeHtml(c.apelido) : ''}</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button onclick="editChild('\${c.id}')" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px;" title="Editar">✏️</button>
|
||||
<button onclick="deleteChild('\${c.id}')" style="background: none; border: none; color: #ef4444; cursor: pointer; padding: 4px;" title="Excluir">🗑️</button>
|
||||
</div>
|
||||
</div>
|
||||
\`}).join('');
|
||||
};
|
||||
|
||||
if(filterAlunosTurma) {
|
||||
filterAlunosTurma.addEventListener('change', () => {
|
||||
renderAlunosList();
|
||||
if(cFormTurma) cFormTurma.value = filterAlunosTurma.value;
|
||||
});
|
||||
}
|
||||
|
||||
window.editChild = (id) => {
|
||||
const c = currentAlunos.find(x => x.id === id);
|
||||
if (!c) return;
|
||||
|
||||
cFormId.value = c.id;
|
||||
cFormTurma.value = c.turma_id || '';
|
||||
cFormNome.value = c.nome || '';
|
||||
cFormApelido.value = c.apelido || '';
|
||||
if(c.data_nasc) {
|
||||
cFormDataNasc.value = c.data_nasc.split('T')[0];
|
||||
} else {
|
||||
cFormDataNasc.value = '';
|
||||
}
|
||||
cFormEspecial.checked = !!c.especial;
|
||||
cFormEspecialDetalhes.value = c.especial_detalhes || '';
|
||||
divEspecialDetalhes.style.display = c.especial ? 'flex' : 'none';
|
||||
cFormPais.value = c.pais || '';
|
||||
cFormAutorizados.value = c.autorizados || '';
|
||||
|
||||
childFormTitle.textContent = 'Editar Criança';
|
||||
};
|
||||
|
||||
window.deleteChild = async (id) => {
|
||||
const isOk = await showCustomConfirm('Excluir', 'Deseja excluir esta criança? Isso não removerá as observações já feitas.', true);
|
||||
if (isOk) {
|
||||
await fetch('/api/alunos/' + id, { method: 'DELETE' });
|
||||
await fetchAlunos();
|
||||
renderAlunosList();
|
||||
clearChildForm();
|
||||
}
|
||||
};
|
||||
|
||||
if (btnMinhaTurma) {
|
||||
btnMinhaTurma.addEventListener('click', async () => {
|
||||
minhaTurmaModal.style.display = 'flex';
|
||||
await fetchTurmas();
|
||||
await fetchAlunos();
|
||||
renderTurmasList();
|
||||
renderAlunosList();
|
||||
clearTurmaForm();
|
||||
clearChildForm();
|
||||
});
|
||||
}
|
||||
|
||||
if (btnCloseMinhaTurmaModal) btnCloseMinhaTurmaModal.addEventListener('click', () => minhaTurmaModal.style.display = 'none');
|
||||
if (minhaTurmaModal) {
|
||||
minhaTurmaModal.addEventListener('click', (e) => {
|
||||
if (e.target === minhaTurmaModal) minhaTurmaModal.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
if (btnCreateChild) btnCreateChild.addEventListener('click', clearChildForm);
|
||||
if (btnCancelChild) btnCancelChild.addEventListener('click', clearChildForm);
|
||||
|
||||
if (btnSaveChild) {
|
||||
btnSaveChild.addEventListener('click', async () => {
|
||||
if (!cFormNome.value.trim() || !cFormTurma.value) {
|
||||
showCustomAlert('Aviso', 'O Nome da Criança e a Turma são obrigatórios.');
|
||||
return;
|
||||
}
|
||||
|
||||
const id = cFormId.value;
|
||||
const body = {
|
||||
turma_id: cFormTurma.value,
|
||||
nome: cFormNome.value.trim(),
|
||||
apelido: cFormApelido.value.trim(),
|
||||
data_nasc: cFormDataNasc.value || null,
|
||||
especial: cFormEspecial.checked,
|
||||
especial_detalhes: cFormEspecialDetalhes.value.trim(),
|
||||
pais: cFormPais.value.trim(),
|
||||
autorizados: cFormAutorizados.value.trim()
|
||||
};
|
||||
|
||||
const url = id ? '/api/alunos/' + id : '/api/alunos';
|
||||
const method = id ? 'PUT' : 'POST';
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
if(res.ok) {
|
||||
await fetchAlunos();
|
||||
renderAlunosList();
|
||||
clearChildForm();
|
||||
showCustomAlert('Sucesso', 'Criança salva com sucesso!');
|
||||
} else {
|
||||
showCustomAlert('Erro', 'Falha ao salvar criança.');
|
||||
}
|
||||
} catch(e) { console.error(e); }
|
||||
});
|
||||
}
|
||||
|
||||
// Preencher com Voz
|
||||
const btnVoiceRecordChild = document.getElementById('btnVoiceRecordChild');
|
||||
if (btnVoiceRecordChild && (window.SpeechRecognition || window.webkitSpeechRecognition)) {
|
||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
const formRecognition = new SpeechRecognition();
|
||||
formRecognition.lang = 'pt-BR';
|
||||
formRecognition.continuous = false;
|
||||
formRecognition.interimResults = false;
|
||||
|
||||
formRecognition.onstart = () => {
|
||||
btnVoiceRecordChild.innerHTML = '🛑 Gravando... (Clique para parar)';
|
||||
btnVoiceRecordChild.style.background = 'rgba(239, 68, 68, 0.1)';
|
||||
btnVoiceRecordChild.style.color = '#ef4444';
|
||||
btnVoiceRecordChild.style.borderColor = '#ef4444';
|
||||
};
|
||||
|
||||
formRecognition.onresult = async (event) => {
|
||||
const transcript = event.results[0][0].transcript;
|
||||
btnVoiceRecordChild.innerHTML = '⏳ Processando com IA...';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
messages: [{
|
||||
role: 'user',
|
||||
content: \`A professora ditou as seguintes informações para cadastrar uma criança na turma: "\${transcript}".
|
||||
Por favor, extraia os dados e retorne APENAS um JSON válido com os seguintes campos:
|
||||
"nome", "apelido", "data_nasc" (formato YYYY-MM-DD), "especial" (boolean), "especial_detalhes", "pais", "autorizados".
|
||||
Se algum dado não for mencionado, deixe a string vazia ou false para boolean.\`
|
||||
}],
|
||||
temperature: 0.1
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const assistantReply = data.message;
|
||||
const match = assistantReply.match(/\`\`\`json\\n([\\s\\S]*?)\\n\`\`\`/) || assistantReply.match(/\\{[\\s\\S]*\\}/);
|
||||
if (match) {
|
||||
const parsed = JSON.parse(match[1] || match[0]);
|
||||
if (parsed.nome) cFormNome.value = parsed.nome;
|
||||
if (parsed.apelido) cFormApelido.value = parsed.apelido;
|
||||
if (parsed.data_nasc) cFormDataNasc.value = parsed.data_nasc;
|
||||
if (parsed.especial) cFormEspecial.checked = parsed.especial;
|
||||
divEspecialDetalhes.style.display = cFormEspecial.checked ? 'flex' : 'none';
|
||||
if (parsed.especial_detalhes) cFormEspecialDetalhes.value = parsed.especial_detalhes;
|
||||
if (parsed.pais) cFormPais.value = parsed.pais;
|
||||
if (parsed.autorizados) cFormAutorizados.value = parsed.autorizados;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Erro ao processar voz:', err);
|
||||
showCustomAlert('Erro', 'Não foi possível extrair os dados. Tente novamente ou preencha manualmente.');
|
||||
}
|
||||
};
|
||||
|
||||
formRecognition.onend = () => {
|
||||
btnVoiceRecordChild.innerHTML = '🎤 Preencher com Voz';
|
||||
btnVoiceRecordChild.style.background = 'rgba(16, 163, 127, 0.1)';
|
||||
btnVoiceRecordChild.style.color = 'var(--brand-green)';
|
||||
btnVoiceRecordChild.style.borderColor = 'var(--brand-green)';
|
||||
};
|
||||
|
||||
btnVoiceRecordChild.addEventListener('click', () => {
|
||||
if (btnVoiceRecordChild.innerHTML.includes('Gravando')) {
|
||||
formRecognition.stop();
|
||||
} else {
|
||||
formRecognition.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Mostra detalhe da observação em modal
|
||||
const showObsDetail = (mdText) => {
|
||||
const modal = document.createElement('div');
|
||||
modal.className = 'settings-modal';
|
||||
modal.style.display = 'flex';
|
||||
modal.innerHTML = \`
|
||||
<div class="settings-modal-content obs-modal-content" style="max-width: 680px;">
|
||||
<div class="settings-modal-header">
|
||||
<h3>📋 Observação</h3>
|
||||
<button class="btn-close-modal" onclick="this.closest('.settings-modal').remove()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div style="padding: 20px; overflow-y: auto; max-height: 70vh;">
|
||||
<div class="obs-detail-content" style="color: var(--text-primary); line-height: 1.6;">
|
||||
\${marked.parse(mdText.replace(/^---[\\s\\S]*?---\\n/, ''))}
|
||||
</div>
|
||||
<div style="margin-top: 16px; display: flex; gap: 8px;">
|
||||
<button class="btn-save-report" onclick="navigator.clipboard.writeText(this.closest('.settings-modal').querySelector('.obs-detail-content').innerText).then(()=>alert('Copiado!'))">Copiar Texto</button>
|
||||
<button class="btn-discard" onclick="this.closest('.settings-modal').remove()">Fechar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
\`;
|
||||
document.body.appendChild(modal);
|
||||
modal.addEventListener('click', (e) => {
|
||||
if (e.target === modal) modal.remove();
|
||||
});
|
||||
};
|
||||
|
||||
// `;
|
||||
|
||||
appCode = appCode.slice(0, startIndex) + newLogic + appCode.slice(endIndex);
|
||||
|
||||
fs.writeFileSync(appFile, appCode);
|
||||
Reference in New Issue
Block a user