From 0c9c7ad511eac9f9a4f6e51eb056e4e7bc95b19a Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 3 Oct 2025 19:13:03 +0000 Subject: [PATCH] fix dashboard generation --- generate_kpis.php | 62 ++++++++++++++++++++++++++----- profile.php | 93 +++++++++++++++++++++++++++++++++++++++++------ save_kpis.php | 42 +++++++++++++++++++++ 3 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 save_kpis.php diff --git a/generate_kpis.php b/generate_kpis.php index 18f2cd8..b21f453 100644 --- a/generate_kpis.php +++ b/generate_kpis.php @@ -12,28 +12,72 @@ if (!$profile_id) { // Basic AI/Rule-based KPI generation function generate_kpi_data($profile) { - // In a real scenario, you'd have a more complex logic or an API call to an AI model + // Default values + $base_mrr = 5000; + $base_cac = 400; + $base_nrr = 95; + + // Adjust KPIs based on profile data + if (isset($profile['organization_size'])) { + switch ($profile['organization_size']) { + case '1-10': + $base_mrr = 5000; + break; + case '11-50': + $base_mrr = 25000; + break; + case '51-200': + $base_mrr = 75000; + break; + case '201+': + $base_mrr = 200000; + break; + } + } + + if (isset($profile['market_approach'])) { + if ($profile['market_approach'] === 'Product-led') { + $base_nrr = 110; + $base_cac = 200; + } elseif ($profile['market_approach'] === 'Sales-led') { + $base_nrr = 98; + $base_cac = 800; + } + } + + $current_mrr = $base_mrr * (rand(80, 120) / 100); + $target_mrr = $base_mrr * 2; + + $current_cac = $base_cac * (rand(90, 130) / 100); + $target_cac = $base_cac * 0.8; + + $current_nrr = $base_nrr * (rand(95, 105) / 100); + $target_nrr = $base_nrr * 1.1; + $kpis = [ - ['name' => 'Monthly Recurring Revenue (MRR)', 'current' => '$' . number_format(rand(5000, 15000)), 'target' => '$25,000'], - ['name' => 'Customer Acquisition Cost (CAC)', 'current' => '$' . number_format(rand(300, 800)), 'target' => '$400'], - ['name' => 'Net Revenue Retention (NRR)', 'current' => rand(95, 110) . '%', 'target' => '115%'] + ['name' => 'Monthly Recurring Revenue (MRR)', 'current' => number_format($current_mrr), 'target' => number_format($target_mrr)], + ['name' => 'Customer Acquisition Cost (CAC)', 'current' => number_format($current_cac), 'target' => number_format($target_cac)], + ['name' => 'Net Revenue Retention (NRR)', 'current' => round($current_nrr) . '%', 'target' => round($target_nrr) . '%'] ]; // Generate sample data for the chart $labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']; + + $mrr_growth_rate = ($target_mrr - $current_mrr) / 5; + $datasets = [ [ 'label' => 'MRR (Actual)', - 'data' => array_map(fn() => rand(5000, 18000), range(1, 6)), + 'data' => array_map(fn($i) => $current_mrr + ($mrr_growth_rate * $i * (rand(80,120)/100)), range(0, 5)), 'borderColor' => '#0d6efd', - 'tension' => 0.1 + 'tension' => 0.2 ], [ 'label' => 'MRR (Target)', - 'data' => array_map(fn($i) => 15000 + ($i * 1500), range(1, 6)), + 'data' => array_map(fn($i) => $current_mrr + ($mrr_growth_rate * $i), range(0, 5)), 'borderColor' => '#dc3545', 'borderDash' => [5, 5], - 'tension' => 0.1 + 'tension' => 0.2 ] ]; @@ -69,4 +113,4 @@ try { } catch (PDOException $e) { error_log('KPI Generation Error: ' . $e->getMessage()); echo json_encode(['error' => 'Database error during KPI generation.']); -} +} \ No newline at end of file diff --git a/profile.php b/profile.php index e31165a..4a30e6b 100644 --- a/profile.php +++ b/profile.php @@ -93,13 +93,15 @@ if ($profile_id) {
-
AI-Generated KPI Dashboard
-

Set and refine KPIs, and track them with an auto-generated dashboard.

-
- - - +
+
AI-Generated KPI Dashboard
+
+ + +
+

Set and refine KPIs, and track them with an auto-generated dashboard.

+
@@ -248,26 +250,36 @@ if ($profile_id) { const renderKpiDashboard = (kpiData) => { if (!kpiData) return; - let kpiHtml = '
'; - kpiData.kpis.forEach(kpi => { + let kpiHtml = '
'; + kpiData.kpis.forEach((kpi, index) => { kpiHtml += `
${kpi.name}
-

Current: ${kpi.current} | Target: ${kpi.target}

+
+ + +
+
+ + +
`; }); - kpiHtml += '
'; + kpiHtml += '
'; kpiHtml += '
'; kpiContainer.innerHTML = kpiHtml; const ctx = document.getElementById('kpi-chart').getContext('2d'); - new Chart(ctx, { + if(window.kpiChart instanceof Chart) { + window.kpiChart.destroy(); + } + window.kpiChart = new Chart(ctx, { type: 'line', data: kpiData.chartData, options: { @@ -279,6 +291,8 @@ if ($profile_id) { } } }); + + document.getElementById('edit-kpi-btn').style.display = 'inline-block'; }; const existingKpiData = ; @@ -311,6 +325,63 @@ if ($profile_id) { }); } + const editKpiBtn = document.getElementById('edit-kpi-btn'); + if (editKpiBtn) { + editKpiBtn.addEventListener('click', function() { + const kpiForm = document.getElementById('kpi-form'); + const inputs = kpiForm.getElementsByTagName('input'); + const isEditing = this.textContent === 'Save KPIs'; + + if (isEditing) { + // Save logic + const formData = new FormData(kpiForm); + const kpis = []; + const kpiData = ; + + kpiData.kpis.forEach((kpi, index) => { + kpis.push({ + name: kpi.name, + current: formData.get(`kpi_${index}_current`), + target: formData.get(`kpi_${index}_target`) + }); + }); + + const updatedKpiData = { kpis: kpis }; + + fetch('save_kpis.php', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `id=${profileId}&kpi_data=${JSON.stringify(updatedKpiData)}` + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + // Re-render with new data + renderKpiDashboard(data.updated_kpi_data); + // Toggle back to edit mode + this.textContent = 'Edit KPIs'; + for (let input of inputs) { + input.setAttribute('readonly', true); + } + } else { + alert('Error saving KPIs: ' + data.error); + } + }) + .catch(error => { + console.error('Error saving KPIs:', error); + alert('An unexpected error occurred while saving KPIs.'); + }); + + } else { + // Edit logic + this.textContent = 'Save KPIs'; + for (let input of inputs) { + input.removeAttribute('readonly'); + } + } + }); + } + // Load existing diagram on page load const existingDiagram = ; diff --git a/save_kpis.php b/save_kpis.php new file mode 100644 index 0000000..ef14b72 --- /dev/null +++ b/save_kpis.php @@ -0,0 +1,42 @@ + 'Profile ID or KPI data is missing.']); + exit; +} + +try { + $kpi_data = json_decode($kpi_data_json, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception('Invalid JSON format for KPI data.'); + } + + $pdo = db(); + + // Fetch existing data to merge, preserving the chart data + $stmt = $pdo->prepare("SELECT kpi_data FROM gtm_profiles WHERE id = ?"); + $stmt->execute([$profile_id]); + $existing_data_row = $stmt->fetch(PDO::FETCH_ASSOC); + $existing_data = $existing_data_row ? json_decode($existing_data_row['kpi_data'], true) : []; + + // We only want to update the 'kpis' part, not the chart data + $existing_data['kpis'] = $kpi_data['kpis']; + + $updated_kpi_data_json = json_encode($existing_data); + + $update_stmt = $pdo->prepare("UPDATE gtm_profiles SET kpi_data = ? WHERE id = ?"); + $update_stmt->execute([$updated_kpi_data_json, $profile_id]); + + echo json_encode(['success' => true, 'message' => 'KPIs updated successfully.', 'updated_kpi_data' => $existing_data]); + +} catch (Exception $e) { + error_log('KPI Save Error: ' . $e->getMessage()); + echo json_encode(['error' => 'Error saving KPIs: ' . $e->getMessage()]); +}