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 = '
';
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()]);
+}