Feature: Historial, DELETE de movimientos y sistema de modales
- Nueva pantalla historial.html con movimientos agrupados por mes - Botón eliminar en cada movimiento con modal de confirmación - js/ui.js: sistema de modales y toasts reutilizables (reemplaza alert/confirm nativos) - API: endpoint GET ?view=historial y método DELETE en movimientos.php - add.html: categorías cargadas dinámicamente desde la API - index.html: "Ver todo" e ícono de nav apuntan a historial.html - Docker: eliminado volumen nombrado db_data para evitar problemas de permisos Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5a54fdcfde
commit
1db200343d
+43
-14
@@ -8,32 +8,41 @@ $pdo = getDB();
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
if ($method === 'GET') {
|
||||
// Retornar balance, datos para gráfico y últimos movimientos
|
||||
$view = $_GET['view'] ?? 'dashboard';
|
||||
|
||||
try {
|
||||
// 1. Balance total
|
||||
$stmtBalance = $pdo->query("SELECT
|
||||
SUM(CASE WHEN tipo = 'ingreso' THEN monto ELSE -monto END) as balance
|
||||
if ($view === 'historial') {
|
||||
$stmt = $pdo->query("SELECT m.*, c.nombre as categoria_nombre, c.icono as categoria_icono
|
||||
FROM movimientos m
|
||||
LEFT JOIN categorias c ON m.id_categoria = c.id
|
||||
ORDER BY m.fecha DESC, m.id DESC");
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'movimientos' => $stmt->fetchAll(PDO::FETCH_ASSOC)
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Dashboard view
|
||||
$stmtBalance = $pdo->query("SELECT
|
||||
SUM(CASE WHEN tipo = 'ingreso' THEN monto ELSE -monto END) as balance
|
||||
FROM movimientos");
|
||||
$balance = $stmtBalance->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
|
||||
|
||||
// 2. Últimos movimientos
|
||||
$stmtMovi = $pdo->query("SELECT m.*, c.nombre as categoria_nombre, c.icono as categoria_icono
|
||||
FROM movimientos m
|
||||
LEFT JOIN categorias c ON m.id_categoria = c.id
|
||||
$stmtMovi = $pdo->query("SELECT m.*, c.nombre as categoria_nombre, c.icono as categoria_icono
|
||||
FROM movimientos m
|
||||
LEFT JOIN categorias c ON m.id_categoria = c.id
|
||||
ORDER BY m.fecha DESC, m.id DESC LIMIT 5");
|
||||
$movimientos = $stmtMovi->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 3. Agrupación por categoría para gráfico donut (sólo gastos de este mes/año)
|
||||
// Por simplicidad traemos todos los gastos
|
||||
$stmtGraph = $pdo->query("SELECT c.nombre, c.color_hex, SUM(m.monto) as total
|
||||
FROM movimientos m
|
||||
JOIN categorias c ON m.id_categoria = c.id
|
||||
FROM movimientos m
|
||||
JOIN categorias c ON m.id_categoria = c.id
|
||||
WHERE m.tipo = 'gasto'
|
||||
GROUP BY c.id
|
||||
ORDER BY total DESC");
|
||||
$grafico = $stmtGraph->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 4. Categorías para el modal de nuevo registro
|
||||
|
||||
$stmtCat = $pdo->query("SELECT * FROM categorias");
|
||||
$categorias = $stmtCat->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
@@ -49,6 +58,26 @@ if ($method === 'GET') {
|
||||
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
} elseif ($method === 'DELETE') {
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!isset($data['id'])) {
|
||||
http_response_code(400);
|
||||
die(json_encode(['status' => 'error', 'message' => 'Falta el ID']));
|
||||
}
|
||||
try {
|
||||
$stmt = $pdo->prepare("DELETE FROM movimientos WHERE id = ?");
|
||||
$stmt->execute([(int) $data['id']]);
|
||||
if ($stmt->rowCount() === 0) {
|
||||
http_response_code(404);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Movimiento no encontrado']);
|
||||
} else {
|
||||
echo json_encode(['status' => 'success']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
} elseif ($method === 'POST') {
|
||||
// Insertar nuevo movimiento
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
Reference in New Issue
Block a user