Files
maturity/company/index.html
2025-09-29 21:31:55 +02:00

153 lines
6.4 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Companies · Agile Maturity</title>
<link rel="icon" href="data:,">
<style>
:root{--bg:#0b0d10;--card:#12161b;--text:#e6edf3;--muted:#9da7b3;--brand:#5bb8ff}
*{box-sizing:border-box}
body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;background:var(--bg);color:var(--text)}
.container{max-width:960px;margin:0 auto;padding:20px}
a{color:var(--brand)}
.card{background:var(--card);border:1px solid #222831;border-radius:12px;padding:20px}
input[type="text"],input[type="file"]{background:#0d1117;border:1px solid #1f2630;border-radius:8px;padding:10px;color:var(--text);width:100%}
button{background:var(--brand);color:#00111f;border:0;border-radius:8px;padding:10px 14px;cursor:pointer;font-weight:600}
button.secondary{background:#232b36;color:var(--text);border:1px solid #2c3644}
.row{display:flex;gap:12px;flex-wrap:wrap}
pre{background:#0d1117;border:1px solid #1f2630;border-radius:10px;padding:12px;overflow:auto}
label{display:block;font-size:12px;color:var(--muted);margin-top:8px}
</style>
</head>
<body>
<div class="container">
<p><a href="../index.html">← Back</a></p>
<h1>Companies</h1>
<section class="card">
<h3>Create or edit a company</h3>
<div class="row">
<input id="cName" type="text" placeholder="Name">
<input id="cDomain" type="text" placeholder="Domain (optional)">
<button id="saveCompany">Save</button>
<button class="secondary" id="resetForm">Reset</button>
</div>
<label>Companies</label>
<div id="list"></div>
<div class="row" style="margin-top:12px">
<button class="secondary" id="exportBtn">Export</button>
<input id="importFile" type="file" accept="application/json">
</div>
<pre id="debug" style="display:none"></pre>
</section>
</div>
<script>
const storageKey = 'companies';
let editId = null;
function loadCompanies(){
try{ return JSON.parse(localStorage.getItem(storageKey)||'[]'); }catch{ return []; }
}
function saveCompanies(list){
localStorage.setItem(storageKey, JSON.stringify(list));
}
function uuid(){ return (crypto && crypto.randomUUID) ? crypto.randomUUID() : 'id-'+Math.random().toString(36).slice(2); }
function render(){
const companies = loadCompanies();
const list = document.getElementById('list');
if(companies.length===0){ list.innerHTML = '<p class="small">No companies yet.</p>'; return; }
list.innerHTML = '';
companies.forEach(c=>{
const row = document.createElement('div');
row.className = 'row';
row.style.alignItems = 'center';
row.style.justifyContent = 'space-between';
const info = document.createElement('div');
info.textContent = `${c.name}${c.domain? ' · '+c.domain: ''}`;
const actions = document.createElement('div');
actions.className = 'row';
const btnTeams = document.createElement('button');
btnTeams.className = 'secondary';
btnTeams.textContent = 'Teams';
btnTeams.onclick = ()=>{ window.location.href = `../team/index.html?companyId=${encodeURIComponent(c.id)}` };
const btnEdit = document.createElement('button');
btnEdit.className = 'secondary';
btnEdit.textContent = 'Edit';
btnEdit.onclick = ()=>{
editId = c.id;
document.getElementById('cName').value = c.name || '';
document.getElementById('cDomain').value = c.domain || '';
};
const btnDel = document.createElement('button');
btnDel.textContent = 'Delete';
btnDel.style.background = '#ff6666';
btnDel.onclick = ()=>{
if(!confirm('Delete company and its teams/assessments references?')) return;
const rest = loadCompanies().filter(x=>x.id!==c.id);
saveCompanies(rest);
// cascade delete teams/assessments stored locally
const teams = JSON.parse(localStorage.getItem('teams')||'[]').filter(t=>t.companyId!==c.id);
localStorage.setItem('teams', JSON.stringify(teams));
const assessments = JSON.parse(localStorage.getItem('assessments')||'[]').filter(a=>a.companyId!==c.id);
localStorage.setItem('assessments', JSON.stringify(assessments));
if(editId===c.id) resetForm();
render();
};
actions.append(btnTeams, btnEdit, btnDel);
row.append(info, actions);
list.appendChild(row);
});
}
function resetForm(){
editId = null;
document.getElementById('cName').value = '';
document.getElementById('cDomain').value = '';
}
function onSave(){
const name = document.getElementById('cName').value.trim();
const domain = document.getElementById('cDomain').value.trim();
if(!name){ alert('Name is required'); return; }
const companies = loadCompanies();
if(editId){
const idx = companies.findIndex(c=>c.id===editId);
if(idx>=0){ companies[idx] = { ...companies[idx], name, domain }; }
}else{
companies.push({ id: uuid(), name, domain, createdAt: new Date().toISOString(), version: 1 });
}
saveCompanies(companies);
resetForm();
render();
}
function onExport(){
const data = loadCompanies();
const blob = new Blob([JSON.stringify(data,null,2)], {type:'application/json'});
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'companies.export.json';
a.click();
URL.revokeObjectURL(a.href);
}
function onImport(ev){
const file = ev.target.files && ev.target.files[0];
if(!file) return;
file.text().then(text=>{
try{
const json = JSON.parse(text);
if(!Array.isArray(json)) throw new Error('Expected an array');
saveCompanies(json);
render();
}catch(e){ alert('Invalid JSON: '+e.message); }
});
}
document.getElementById('saveCompany').addEventListener('click', onSave);
document.getElementById('resetForm').addEventListener('click', resetForm);
document.getElementById('exportBtn').addEventListener('click', onExport);
document.getElementById('importFile').addEventListener('change', onImport);
render();
</script>
</body>
</html>