Disruplab · Innovation Navigator Gerenciador de Projetos
Crie, renomeie ou exclua projetos.
Projeto ativo
Nenhum projeto selecionado.
Direcionamento de Inovação
Descreva o foco da sua inovação.
Pipeline IA
JTBD: aguardando
TRIZ: aguardando
Relatório: aguardando
0% — Iniciando
Gap (Importância − Satisfação)
Contradições & Princípios TRIZ
Encadeamento (JTBD → TRIZ → OKRs)
OKRs & Gestão
Objetivos estratégicos com KRs mensuráveis e iniciativas detalhadas.
');
win.document.close(); setTimeout(() => win.print(), 300);
}// ===== PROBABILIDADE =====
function renderizarProbabilidade() {
const p = projetoAtivo(); if (!p) return;
const score = calcularScore(p), prob = calcularProbabilidade(p, score);
desenharProbabilidade('chart-prob', prob.percent);
document.getElementById('prob-note').innerHTML = `
Score base: ${score.overall}/100Probabilidade: ${prob.percent}%`;
}function calcularScore(p) {
const j = p.jtbd?.length||0, t = p.triz?.contradicoes?.length||0, o = p.okrs?.length||0;
return { overall: Math.round((0.35*Math.min(100,j/10*100)+0.4*Math.min(100,t/6*100)+0.25*Math.min(100,o/3*100))*10)/10 };
}function calcularProbabilidade(p, score) {
const barr = p.triz?.barreira_tecnologica||'media', adj = {baixa:10,media:2,alta:-8}[barr]||0;
const riscos = (p.triz?.riscos_regulatorios||[]).length+(p.relatorio?.riscos_setoriais||[]).length;
const bonus = (p.jtbd?.length>=8?6:0)+(p.triz?.contradicoes?.length>=6?5:0)+(p.okrs?.length>=3?5:0);
return { percent: Math.round(Math.min(100,Math.max(0, 0.72*score.overall+adj-1.8*riscos+bonus))) };
}function desenharProbabilidade(elId, percent) {
const el = document.getElementById(elId), W=400, H=150, cx=W/2, cy=75, R=55, SW=10;
const circ = 2*Math.PI*R, arc = circ*(Math.min(100,Math.max(0,percent))/100);
el.innerHTML = `
`;
}// ===== CONFIG MODAL =====
function abrirConfigModal() {
atualizarStatusChave();
renderizarListaUsuarios();
document.getElementById('config-modal').style.display = 'flex';
}document.getElementById('btn-close-modal').addEventListener('click', () => document.getElementById('config-modal').style.display = 'none');
document.getElementById('config-modal').addEventListener('click', e => { if (e.target === document.getElementById('config-modal')) document.getElementById('config-modal').style.display = 'none'; });document.getElementById('btn-save-api-key').addEventListener('click', () => {
const key = document.getElementById('api-key-input-modal').value.trim();
if (!key.startsWith(SK_PREFIX)) return alert('Chave deve iniciar com sk-');
localStorage.setItem(API_KEY_STORAGE, key); currentApiKey = key; atualizarStatusChave();
});function atualizarStatusChave() {
const inp = document.getElementById('api-key-input-modal'), st = document.getElementById('api-key-status-modal');
if (currentApiKey?.startsWith(SK_PREFIX)) { st.textContent = '✓ Chave configurada'; st.style.color = '#166534'; inp.value = currentApiKey; }
else { st.textContent = currentApiKey ? '⚠️ Chave inválida' : 'Nenhuma chave.'; st.style.color = '#b45309'; inp.value = currentApiKey||''; }
}function renderizarListaUsuarios() {
const users = carregarUsuarios();
document.getElementById('user-list-container').innerHTML = users.map(u => `
${u.nome} ${u.admin?'Admin':''}${!u.admin?``:''}
`).join('');
}function removerUsuario(nome) {
if (!confirm(`Remover ${nome}?`)) return;
let users = carregarUsuarios(); users = users.filter(u => u.nome !== nome); salvarUsuarios(users); renderizarListaUsuarios();
}document.getElementById('btn-add-user').addEventListener('click', () => {
const nome = document.getElementById('new-user-name').value.trim(), senha = document.getElementById('new-user-pass').value;
if (!nome || !senha) return;
let users = carregarUsuarios();
if (users.some(u => u.nome === nome)) return alert('Usuário já existe.');
users.push({ nome, senha, admin: false }); salvarUsuarios(users);
document.getElementById('new-user-name').value = ''; document.getElementById('new-user-pass').value = ''; renderizarListaUsuarios();
});document.getElementById('btn-export-db').addEventListener('click', () => {
const db = { projetos: JSON.parse(localStorage.getItem(STORAGE_KEY)||'{}'), usuarios: carregarUsuarios(), apiKey: localStorage.getItem(API_KEY_STORAGE)||'' };
const blob = new Blob([JSON.stringify(db)], { type:'application/json' });
const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `backup_${new Date().toISOString().slice(0,10)}.json`; a.click();
});document.getElementById('import-file').addEventListener('change', e => {
const file = e.target.files[0]; if (!file) return;
const reader = new FileReader();
reader.onload = ev => {
try {
const db = JSON.parse(ev.target.result);
if (!db.projetos || !db.usuarios) throw new Error('Inválido');
if (!confirm('Substituir todos os dados?')) return;
localStorage.setItem(STORAGE_KEY, JSON.stringify(db.projetos));
salvarUsuarios(db.usuarios);
if (db.apiKey) localStorage.setItem(API_KEY_STORAGE, db.apiKey);
currentApiKey = db.apiKey||'';
document.getElementById('import-status').textContent = '✓ Importado com sucesso!';
} catch(ex) { document.getElementById('import-status').textContent = 'Erro: arquivo inválido.'; }
};
reader.readAsText(file);
});function limparTudo() {
['dir-text','jtbd-list','triz-list','okr-container','relatorio-content','okr-checklist-container'].forEach(id => { const el = document.getElementById(id); if (el) el.innerHTML = ''; });
['chart-jtbd-gap','chart-triz-freq','chart-prob','prob-note','trace-list'].forEach(id => { const el = document.getElementById(id); if (el) el.innerHTML = ''; });
}loginOverlay.style.display = 'flex';
appContainer.style.display = 'none';
})();