Project Contract Dashboard

Active Contracts

0

Total Contract Value

$0

Expiring in 60 Days

0

Contracts Requiring Attention

    Contracts by Status

    No contracts require attention.

    '; } else { renewalsContainer.innerHTML = expiringSoon.sort((a,b) => new Date(a.ExpiryDate) - new Date(b.ExpiryDate)).map(c => { const daysLeft = Math.ceil((new Date(c.ExpiryDate) - today) / (1000 * 60 * 60 * 24)); return `
  • ${c.Name}

    vs. ${c.Counterparty}
    ${daysLeft}d
  • `; }).join(''); } renderCharts(); } function renderCharts() { const statusColors = {'Active':'#16a34a', 'Draft':'#64748b', 'In Review':'#f59e0b', 'Expired':'#94a3b8', 'Terminated':'#ef4444'}; const statusCounts = contractsData.reduce((acc, c) => { acc[c.Status] = (acc[c.Status] || 0) + 1; return acc; }, {}); const statusCtx = document.getElementById('pcd-status-chart').getContext('2d'); if(charts.status) charts.status.destroy(); charts.status = new Chart(statusCtx, { type: 'doughnut', data: { labels: Object.keys(statusCounts), datasets: [{ data: Object.values(statusCounts), backgroundColor: Object.keys(statusCounts).map(s => statusColors[s]) }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' } } } }); } function renderContractsTable() { const table = document.getElementById('contracts-table'); const headers = ['Contract Name', 'Counterparty', 'Type', 'Status', 'Effective Date', 'Expiry Date', 'Value ($)']; table.innerHTML = `${headers.map(h=>`${h}`).join('')}Actions ${contractsData.sort((a,b)=>new Date(b.ExpiryDate) - new Date(a.ExpiryDate)).map(c => ` `).join('')} `; } // --- CRUD Functions (FIXED) --- window.pcd_updateContract = (id, key, value) => { const contract = contractsData.find(c => c.id === id); if(contract) contract[key] = (key === 'Value') ? parseFloat(value) || 0 : value; renderAll(); }; window.pcd_addContract = () => { contractsData.push({ id: Date.now(), Name: 'New Contract', Counterparty: '', Type: TYPES[0], Status: 'Draft', EffectiveDate: new Date().toISOString().split('T')[0], ExpiryDate: '', Value: 0 }); renderAll(); }; window.pcd_removeContract = (id) => { contractsData = contractsData.filter(c => c.id !== id); renderAll(); }; function initialize() { const today = new Date("2025-07-02"); const createDate = (offsetDays) => { const date = new Date(today); date.setDate(today.getDate() + offsetDays); return date.toISOString().split('T')[0]; }; contractsData = [ { id: 1, Name: 'Master Service Agreement', Counterparty: 'Innovate Corp', Type: 'Retainer', Status: 'Active', EffectiveDate: '2023-01-01', ExpiryDate: '2025-12-31', Value: 250000 }, { id: 2, Name: 'Software License', Counterparty: 'AlphaWare', Type: 'Fixed Price', Status: 'Active', EffectiveDate: '2025-02-15', ExpiryDate: '2026-02-14', Value: 75000 }, { id: 3, Name: 'Cloud Hosting Services', Counterparty: 'Cloud IO', Type: 'Time & Materials', Status: 'Active', EffectiveDate: '2024-08-01', ExpiryDate: createDate(45), Value: 120000 }, { id: 4, Name: 'Consulting SOW', Counterparty: 'Strategy Partners', Type: 'Fixed Price', Status: 'Expired', EffectiveDate: '2024-06-01', ExpiryDate: '2025-05-31', Value: 50000 }, { id: 5, Name: 'Office Lease', Counterparty: 'Metro Properties', Type: 'Fixed Price', Status: 'Active', EffectiveDate: '2022-01-01', ExpiryDate: createDate(25), Value: 180000 }, { id: 6, Name: 'New Client Project', Counterparty: 'Beta Solutions', Type: 'Draft', EffectiveDate: createDate(10), ExpiryDate: createDate(375), Value: 150000 } ]; renderAll(); } initialize(); });
    Scroll to Top