Auto commit: 2025-10-26T16:46:07.096Z

This commit is contained in:
Flatlogic Bot 2025-10-26 16:46:07 +00:00
parent 4f6f10c21f
commit 8daee549e1
5 changed files with 284 additions and 8 deletions

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS invoices (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
due_date DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE
);

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS reports (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(100) NOT NULL,
data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -59,7 +59,80 @@ function seed_plans() {
}
}
function seed_invoices() {
$pdo = db();
$customer_stmt = $pdo->query('SELECT id FROM customers');
$customer_ids = $customer_stmt->fetchAll(PDO::FETCH_COLUMN);
if (empty($customer_ids)) {
echo "No customers found to create invoices for.\n";
return;
}
$invoices = [];
$statuses = ['Paid', 'Pending', 'Overdue'];
foreach ($customer_ids as $customer_id) {
for ($i = 0; $i < 3; $i++) {
$invoices[] = [
'customer_id' => $customer_id,
'amount' => rand(2000, 10000) / 100,
'status' => $statuses[array_rand($statuses)],
'due_date' => date('Y-m-d', strtotime('+' . rand(-30, 30) . ' days')),
];
}
}
$stmt = $pdo->prepare("INSERT INTO invoices (customer_id, amount, status, due_date) VALUES (:customer_id, :amount, :status, :due_date)");
foreach ($invoices as $invoice) {
echo "Seeding invoice for customer ID: " . $invoice['customer_id'] . "...\n";
try {
$stmt->execute($invoice);
echo "Success.\n";
} catch (PDOException $e) {
echo "Error seeding invoice: " . $e->getMessage() . "\n";
}
}
}
function seed_reports() {
$pdo = db();
$reports = [
[
'name' => 'Monthly Revenue',
'type' => 'Financial',
'data' => json_encode(['month' => 'October 2025', 'revenue' => 12345.67])
],
[
'name' => 'Active Customers',
'type' => 'User',
'data' => json_encode(['active_customers' => 123])
],
[
'name' => 'Plan Distribution',
'type' => 'Subscription',
'data' => json_encode(['Basic' => 50, 'Premium HD' => 50, 'Family Pack' => 23])
]
];
$stmt = $pdo->prepare("INSERT INTO reports (name, type, data) VALUES (:name, :type, :data)");
foreach ($reports as $report) {
echo "Seeding report: " . $report['name'] . "...\n";
try {
$stmt->execute($report);
echo "Success.\n";
} catch (PDOException $e) {
echo "Error seeding report " . $report['name'] . ": " . $e->getMessage() . "\n";
}
}
}
seed_customers();
seed_plans();
seed_invoices();
seed_reports();

View File

@ -14,10 +14,65 @@ require_once 'templates/header.php';
</div>
</div>
<div class="text-center py-5">
<i class="bi bi-journal-text" style="font-size: 4rem; color: #ccc;"></i>
<h2 class="mt-4">Coming Soon</h2>
<p class="text-muted">The invoices management page is under construction.</p>
<?php
require_once 'db/config.php';
$pdo = db();
$stmt = $pdo->query('SELECT invoices.*, customers.name AS customer_name FROM invoices LEFT JOIN customers ON invoices.customer_id = customers.id ORDER BY invoices.created_at DESC');
$invoices = $stmt->fetchAll(PDO::FETCH_ASSOC);
$status_colors = [
'Paid' => 'success',
'Pending' => 'warning',
'Overdue' => 'danger',
];
?>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Invoice #</th>
<th>Customer</th>
<th>Amount</th>
<th>Status</th>
<th>Due Date</th>
<th>Created</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($invoices)): ?>
<tr>
<td colspan="7" class="text-center py-5">
<i class="bi bi-journal-text" style="font-size: 3rem; color: #ccc;"></i>
<h2 class="mt-3">No Invoices Found</h2>
<p class="text-muted">There are no invoices to display yet.</p>
</td>
</tr>
<?php else: ?>
<?php foreach ($invoices as $invoice): ?>
<tr>
<td>#<?php echo htmlspecialchars($invoice['id']); ?></td>
<td><?php echo htmlspecialchars($invoice['customer_name']); ?></td>
<td>$<?php echo number_format($invoice['amount'], 2); ?></td>
<td>
<span class="badge bg-<?php echo $status_colors[$invoice['status']] ?? 'secondary'; ?>">
<?php echo htmlspecialchars($invoice['status']); ?>
</span>
</td>
<td><?php echo date('M d, Y', strtotime($invoice['due_date'])); ?></td>
<td><?php echo date('M d, Y', strtotime($invoice['created_at'])); ?></td>
<td>
<button class="btn btn-sm btn-outline-secondary"><i class="bi bi-eye"></i></button>
<button class="btn btn-sm btn-outline-secondary"><i class="bi bi-pencil"></i></button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php

View File

@ -8,10 +8,141 @@ require_once 'templates/header.php';
<h1 class="h2">Reports</h1>
</div>
<div class="text-center py-5">
<i class="bi bi-graph-up" style="font-size: 4rem; color: #ccc;"></i>
<h2 class="mt-4">Coming Soon</h2>
<p class="text-muted">The reports and analytics page is under construction.</p>
<?php
require_once 'db/config.php';
$pdo = db();
// Fetch stats
$total_customers = $pdo->query('SELECT COUNT(*) FROM customers')->fetchColumn();
$active_customers = $pdo->query("SELECT COUNT(*) FROM customers WHERE status = 'Active'")->fetchColumn();
$total_plans = $pdo->query('SELECT COUNT(*) FROM plans')->fetchColumn();
$total_revenue = $pdo->query("SELECT SUM(amount) FROM invoices WHERE status = 'Paid'")->fetchColumn();
$invoice_status_stmt = $pdo->query("SELECT status, COUNT(*) as count FROM invoices GROUP BY status");
$invoice_statuses = $invoice_status_stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$total_invoices = array_sum($invoice_statuses);
$paid_invoices = $invoice_statuses['Paid'] ?? 0;
$pending_invoices = $invoice_statuses['Pending'] ?? 0;
$overdue_invoices = $invoice_statuses['Overdue'] ?? 0;
?>
<div class="row">
<div class="col-md-3 mb-4">
<div class="card text-white bg-primary">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-people-fill"></i> Total Customers</h5>
<p class="card-text fs-4"><?php echo $total_customers; ?></p>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card text-white bg-success">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-person-check-fill"></i> Active Customers</h5>
<p class="card-text fs-4"><?php echo $active_customers; ?></p>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card text-white bg-info">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-tags-fill"></i> Available Plans</h5>
<p class="card-text fs-4"><?php echo $total_plans; ?></p>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card text-white bg-dark">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-cash-stack"></i> Total Revenue</h5>
<p class="card-text fs-4">$<?php echo number_format($total_revenue, 2); ?></p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<i class="bi bi-journal-text"></i> Invoice Status Distribution
</div>
<div class="card-body">
<div class="progress" style="height: 30px;">
<div class="progress-bar bg-success" role="progressbar" style="width: <?php echo ($paid_invoices / $total_invoices) * 100; ?>%" aria-valuenow="<?php echo $paid_invoices; ?>" aria-valuemin="0" aria-valuemax="<?php echo $total_invoices; ?>">Paid</div>
<div class="progress-bar bg-warning" role="progressbar" style="width: <?php echo ($pending_invoices / $total_invoices) * 100; ?>%" aria-valuenow="<?php echo $pending_invoices; ?>" aria-valuemin="0" aria-valuemax="<?php echo $total_invoices; ?>">Pending</div>
<div class="progress-bar bg-danger" role="progressbar" style="width: <?php echo ($overdue_invoices / $total_invoices) * 100; ?>%" aria-valuenow="<?php echo $overdue_invoices; ?>" aria-valuemin="0" aria-valuemax="<?php echo $total_invoices; ?>">Overdue</div>
</div>
<div class="d-flex justify-content-around mt-3 text-center">
<div>
<p class="mb-0 fs-5"><?php echo $paid_invoices; ?></p>
<span class="text-success">Paid</span>
</div>
<div>
<p class="mb-0 fs-5"><?php echo $pending_invoices; ?></p>
<span class="text-warning">Pending</span>
</div>
<div>
<p class="mb-0 fs-5"><?php echo $overdue_invoices; ?></p>
<span class="text-danger">Overdue</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<i class="bi bi-journal-text"></i> Generated Reports
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Report Name</th>
<th>Type</th>
<th>Date Generated</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
$stmt = $pdo->query('SELECT * FROM reports ORDER BY created_at DESC');
$reports = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($reports)):
?>
<tr>
<td colspan="4" class="text-center py-5">
<i class="bi bi-journal-x" style="font-size: 3rem; color: #ccc;"></i>
<h2 class="mt-3">No Reports Found</h2>
<p class="text-muted">There are no generated reports to display yet.</p>
</td>
</tr>
<?php else: ?>
<?php foreach ($reports as $report): ?>
<tr>
<td><?php echo htmlspecialchars($report['name']); ?></td>
<td><span class="badge bg-secondary"><?php echo htmlspecialchars($report['type']); ?></span></td>
<td><?php echo date('M d, Y H:i A', strtotime($report['created_at'])); ?></td>
<td>
<button class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i> View</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<?php