150 lines
6.3 KiB
PHP
150 lines
6.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
@ini_set('display_errors', '1');
|
|
@error_reporting(E_ALL);
|
|
@date_default_timezone_set('UTC');
|
|
|
|
require_once __DIR__ . '/db/config.php';
|
|
|
|
$phpVersion = PHP_VERSION;
|
|
$now = date('Y-m-d H:i:s');
|
|
$message = $_GET['message'] ?? '';
|
|
|
|
$expenses = [];
|
|
try {
|
|
$pdo = db();
|
|
$stmt = $pdo->query("
|
|
SELECT
|
|
e.*,
|
|
c.name as category_name,
|
|
u.name as user_name,
|
|
a.name as account_name
|
|
FROM
|
|
expenses e
|
|
LEFT JOIN
|
|
categories c ON e.category_id = c.id
|
|
LEFT JOIN
|
|
users u ON e.user_id = u.id
|
|
LEFT JOIN
|
|
accounts a ON e.account_id = a.id
|
|
ORDER BY
|
|
e.expense_date DESC
|
|
");
|
|
$expenses = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
error_log("DB Error: " . $e->getMessage());
|
|
// You might want to display a user-friendly error message
|
|
}
|
|
|
|
?>
|
|
<!doctype html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Gestor de Gastos</title>
|
|
<?php
|
|
// Read project preview data from environment
|
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
|
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|
?>
|
|
<?php if ($projectDescription): ?>
|
|
<!-- Meta description -->
|
|
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
|
<!-- Open Graph meta tags -->
|
|
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<!-- Twitter meta tags -->
|
|
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<?php endif; ?>
|
|
<?php if ($projectImageUrl): ?>
|
|
<!-- Open Graph image -->
|
|
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
<!-- Twitter image -->
|
|
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
<?php endif; ?>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css">
|
|
</head>
|
|
<body style="background-color: #F3F4F6;">
|
|
|
|
<main class="container py-5">
|
|
<div class="text-center mb-4">
|
|
<h1 class="display-5 fw-bold">Gestor de Gastos Familiar</h1>
|
|
<p class="lead text-muted">Bienvenido a tu espacio financiero. Registra y controla tus gastos.</p>
|
|
</div>
|
|
|
|
<?php if ($message === 'success'): ?>
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
¡Gasto añadido correctamente!
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h2 class="h5 mb-0">Resumen de Gastos</h2>
|
|
<div class="btn-group">
|
|
<a href="import.php" class="btn btn-warning">Importar</a>
|
|
<a href="export.php" class="btn btn-success">Exportar</a>
|
|
<a href="accounts.php" class="btn btn-info">Cuentas</a>
|
|
<a href="users.php" class="btn btn-info">Usuarios</a>
|
|
<a href="categories.php" class="btn btn-info">Categorías</a>
|
|
<a href="add_expense.php" class="btn btn-primary">Añadir Gasto</a>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<?php if (empty($expenses)): ?>
|
|
<div class="text-center p-3">
|
|
<p>No hay gastos registrados. ¡Empieza añadiendo uno!</p>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Fecha</th>
|
|
<th>Título</th>
|
|
<th>Categoría</th>
|
|
<th>Cuenta</th>
|
|
<th>Usuario</th>
|
|
<th>Tipo</th>
|
|
<th class="text-end">Monto</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($expenses as $expense): ?>
|
|
<tr>
|
|
<td><?= htmlspecialchars(date("d/m/Y", strtotime($expense['expense_date']))) ?></td>
|
|
<td><?= htmlspecialchars($expense['title']) ?></td>
|
|
<td><span class="badge bg-secondary"><?= htmlspecialchars($expense['category_name'] ?? 'N/A') ?></span></td>
|
|
<td><?= htmlspecialchars($expense['account_name'] ?? 'N/A') ?></td>
|
|
<td><?= htmlspecialchars($expense['user_name'] ?? 'N/A') ?></td>
|
|
<td>
|
|
<?php
|
|
$type = $expense['expense_type'];
|
|
$badge_class = 'bg-secondary';
|
|
if ($type == 'income') $badge_class = 'bg-success';
|
|
if ($type == 'expense') $badge_class = 'bg-danger';
|
|
if ($type == 'transfer') $badge_class = 'bg-info';
|
|
?>
|
|
<span class="badge <?= $badge_class ?>"><?= ucfirst($type) ?></span>
|
|
</td>
|
|
<td class="text-end font-monospace"><?= htmlspecialchars(number_format((float)$expense['amount'], 2)) ?> <?= htmlspecialchars($expense['currency']) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<footer class="text-center text-muted py-3">
|
|
<small>Page updated: <?= htmlspecialchars($now) ?> (UTC)</small>
|
|
</footer>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
</body>
|
|
</html>
|