roles & tools

This commit is contained in:
Flatlogic Bot 2025-10-03 19:04:16 +00:00
parent b2cba70f79
commit ee17043571
7 changed files with 199 additions and 24 deletions

View File

@ -0,0 +1 @@
ALTER TABLE `gtm_profiles` ADD `roles_text` TEXT;

View File

@ -0,0 +1 @@
ALTER TABLE `gtm_profiles` ADD `tools_text` TEXT;

View File

@ -0,0 +1 @@
ALTER TABLE gtm_profiles ADD COLUMN kpi_data TEXT;

72
generate_kpis.php Normal file
View File

@ -0,0 +1,72 @@
<?php
require_once 'db/config.php';
header('Content-Type: application/json');
$profile_id = $_GET['id'] ?? null;
if (!$profile_id) {
echo json_encode(['error' => 'Profile ID is missing.']);
exit;
}
// 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
$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%']
];
// Generate sample data for the chart
$labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
$datasets = [
[
'label' => 'MRR (Actual)',
'data' => array_map(fn() => rand(5000, 18000), range(1, 6)),
'borderColor' => '#0d6efd',
'tension' => 0.1
],
[
'label' => 'MRR (Target)',
'data' => array_map(fn($i) => 15000 + ($i * 1500), range(1, 6)),
'borderColor' => '#dc3545',
'borderDash' => [5, 5],
'tension' => 0.1
]
];
return [
'kpis' => $kpis,
'chartData' => [
'labels' => $labels,
'datasets' => $datasets
]
];
}
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM gtm_profiles WHERE id = ?");
$stmt->execute([$profile_id]);
$profile = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$profile) {
echo json_encode(['error' => 'Profile not found.']);
exit;
}
$kpi_data = generate_kpi_data($profile);
$kpi_data_json = json_encode($kpi_data);
// Save the generated data to the database
$update_stmt = $pdo->prepare("UPDATE gtm_profiles SET kpi_data = ? WHERE id = ?");
$update_stmt->execute([$kpi_data_json, $profile_id]);
echo json_encode(['success' => true, 'kpi_data' => $kpi_data]);
} catch (PDOException $e) {
error_log('KPI Generation Error: ' . $e->getMessage());
echo json_encode(['error' => 'Database error during KPI generation.']);
}

View File

@ -42,6 +42,9 @@ try {
$recommendations .= '</ul>';
}
$update_stmt = $pdo->prepare("UPDATE gtm_profiles SET roles_text = ? WHERE id = ?");
$update_stmt->execute([$recommendations, $profile_id]);
echo json_encode(['recommendations' => $recommendations]);
} catch (PDOException $e) {

View File

@ -42,6 +42,9 @@ try {
$recommendations .= '</ul>';
}
$update_stmt = $pdo->prepare("UPDATE gtm_profiles SET tools_text = ? WHERE id = ?");
$update_stmt->execute([$recommendations, $profile_id]);
echo json_encode(['recommendations' => $recommendations]);
} catch (PDOException $e) {

View File

@ -28,6 +28,7 @@ if ($profile_id) {
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter&family=Lora:wght@700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
@ -59,6 +60,50 @@ if ($profile_id) {
<main class="container my-5 pt-5">
<h1 class="mb-4">My GTM Profile</h1>
<?php if ($profile): ?>
<div class="row mb-4">
<div class="col-md-6 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">AI-Generated Role Recommendations</h5>
<p class="card-text">Get AI-powered suggestions for marketing and sales roles to execute your GTM strategy.</p>
<div id="roles-container" class="mt-3">
<?php if (!empty($profile['roles_text'])): ?>
<?php echo $profile['roles_text']; ?>
<?php endif; ?>
</div>
<button id="generate-roles-btn" class="btn btn-primary <?php if (!empty($profile['roles_text'])) echo 'd-none'; ?>" data-profile-id="<?php echo htmlspecialchars($profile_id); ?>">Generate Roles</button>
</div>
</div>
</div>
<div class="col-md-6 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">AI-Recommended Tools & Integrations</h5>
<p class="card-text">Discover top industry solutions and integrations to efficiently execute your GTM strategy.</p>
<div id="tools-container" class="mt-3">
<?php if (!empty($profile['tools_text'])): ?>
<?php echo $profile['tools_text']; ?>
<?php endif; ?>
</div>
<button id="generate-tools-btn" class="btn btn-primary <?php if (!empty($profile['tools_text'])) echo 'd-none'; ?>" data-profile-id="<?php echo htmlspecialchars($profile_id); ?>">Generate Tools</button> </div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">AI-Generated KPI Dashboard</h5>
<p class="card-text">Set and refine KPIs, and track them with an auto-generated dashboard.</p>
<div id="kpi-container" class="mt-3">
<?php if (empty($profile['kpi_data'])): ?>
<button id="generate-kpi-btn" class="btn btn-primary" data-profile-id="<?php echo htmlspecialchars($profile_id); ?>">Generate KPI Dashboard</button>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-3">
@ -93,28 +138,6 @@ if ($profile_id) {
<h6 class="card-subtitle mb-2 text-muted">Goals</h6>
<p class="card-text"><strong>Growth Goals:</strong> <?php echo htmlspecialchars($profile['goals']); ?></p>
<hr>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">AI-Generated Role Recommendations</h5>
<p class="card-text">Get AI-powered suggestions for marketing and sales roles to execute your GTM strategy.</p>
<button id="generate-roles-btn" class="btn btn-primary" data-profile-id="<?php echo htmlspecialchars($profile_id); ?>">Generate Roles</button>
<div id="roles-container" class="mt-3"></div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">AI-Recommended Tools & Integrations</h5>
<p class="card-text">Discover top industry solutions and integrations to efficiently execute your GTM strategy.</p>
<button id="generate-tools-btn" class="btn btn-primary" data-profile-id="<?php echo htmlspecialchars($profile_id); ?>">Generate Tools</button>
<div id="tools-container" class="mt-3"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php else: ?>
@ -134,18 +157,20 @@ if ($profile_id) {
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const profileId = "<?php echo $profile_id; ?>";
const generateBtn = document.getElementById('generate-diagram-btn');
const diagramContainer = document.getElementById('diagram-container');
const editorContainer = document.getElementById('diagram-editor-container');
const editor = document.getElementById('diagram-editor');
const saveBtn = document.getElementById('save-diagram-btn');
const saveStatus = document.getElementById('save-status');
const profileId = generateBtn ? generateBtn.dataset.profileId : null;
const generateRolesBtn = document.getElementById('generate-roles-btn');
const rolesContainer = document.getElementById('roles-container');
const generateToolsBtn = document.getElementById('generate-tools-btn');
const toolsContainer = document.getElementById('tools-container');
const generateKpiBtn = document.getElementById('generate-kpi-btn');
const kpiContainer = document.getElementById('kpi-container');
if (generateRolesBtn) {
generateRolesBtn.addEventListener('click', function () {
@ -159,6 +184,7 @@ if ($profile_id) {
rolesContainer.innerHTML = `<div class="alert alert-danger">${data.error}</div>`;
} else {
rolesContainer.innerHTML = data.recommendations;
generateRolesBtn.classList.add('d-none');
}
})
.catch(error => {
@ -183,11 +209,12 @@ if ($profile_id) {
toolsContainer.innerHTML = `<div class="alert alert-danger">${data.error}</div>`;
} else {
toolsContainer.innerHTML = data.recommendations;
generateToolsBtn.classList.add('d-none');
}
})
.catch(error => {
console.error('Error generating tools:', error);
toolsContainer.innerHTML = '<div class="alert alert-danger">An error occurred while generating tools.</div>';
toolsContainerinnerHTML = '<div class="alert alert-danger">An error occurred while generating tools.</div>';
})
.finally(() => {
generateToolsBtn.disabled = false;
@ -218,6 +245,73 @@ if ($profile_id) {
}
};
const renderKpiDashboard = (kpiData) => {
if (!kpiData) return;
let kpiHtml = '<div class="row">';
kpiData.kpis.forEach(kpi => {
kpiHtml += `
<div class="col-md-4">
<div class="card mb-3">
<div class="card-body">
<h6 class="card-title">${kpi.name}</h6>
<p class="card-text">Current: ${kpi.current} | Target: ${kpi.target}</p>
</div>
</div>
</div>
`;
});
kpiHtml += '</div>';
kpiHtml += '<div class="row"><div class="col-12"><canvas id="kpi-chart"></canvas></div></div>';
kpiContainer.innerHTML = kpiHtml;
const ctx = document.getElementById('kpi-chart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: kpiData.chartData,
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
};
const existingKpiData = <?php echo $profile['kpi_data'] ?? 'null'; ?>;
if (existingKpiData) {
renderKpiDashboard(existingKpiData);
}
if (generateKpiBtn) {
generateKpiBtn.addEventListener('click', function() {
kpiContainer.innerHTML = '<div class="text-center"><div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div><p>Generating KPI Dashboard...</p></div>';
this.disabled = true;
fetch(`generate_kpis.php?id=${profileId}`)
.then(response => response.json())
.then(data => {
if (data.error) {
kpiContainer.innerHTML = `<div class="alert alert-danger">${data.error}</div>`;
} else {
renderKpiDashboard(data.kpi_data);
this.classList.add('d-none');
}
})
.catch(error => {
console.error('Error generating KPIs:', error);
kpiContainer.innerHTML = '<div class="alert alert-danger">An error occurred while generating the KPI dashboard.</div>';
})
.finally(() => {
if(generateKpiBtn) generateKpiBtn.disabled = false;
});
});
}
// Load existing diagram on page load
const existingDiagram = <?php echo json_encode($profile['diagram_mermaid_text'] ?? null); ?>;
if (existingDiagram) {