roles & tools
This commit is contained in:
parent
b2cba70f79
commit
ee17043571
1
db/migrations/003_add_roles_text_to_profiles.sql
Normal file
1
db/migrations/003_add_roles_text_to_profiles.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `gtm_profiles` ADD `roles_text` TEXT;
|
||||
1
db/migrations/004_add_tools_text_to_profiles.sql
Normal file
1
db/migrations/004_add_tools_text_to_profiles.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `gtm_profiles` ADD `tools_text` TEXT;
|
||||
1
db/migrations/005_add_kpi_data_to_profiles.sql
Normal file
1
db/migrations/005_add_kpi_data_to_profiles.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE gtm_profiles ADD COLUMN kpi_data TEXT;
|
||||
72
generate_kpis.php
Normal file
72
generate_kpis.php
Normal 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.']);
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
142
profile.php
142
profile.php
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user