Auto commit: 2025-11-24T23:41:00.323Z

This commit is contained in:
Flatlogic Bot 2025-11-24 23:41:00 +00:00
parent fc7141b6a0
commit 786ed30042
12 changed files with 1129 additions and 470 deletions

View File

@ -27,7 +27,7 @@ try {
case 'get_current_locations':
default:
$stmt = $pdo->query(
"SELECT t.matricula, t.modelo, lt.latitud, lt.longitud, lt.ultima_actualizacion " .
"SELECT t.id, t.matricula, t.modelo, lt.latitud, lt.longitud, lt.ultima_actualizacion " .
"FROM localizacion_taxis lt " .
"JOIN taxis t ON lt.id_taxi = t.id " .
"ORDER BY lt.ultima_actualizacion DESC"

278
citas.php
View File

@ -2,166 +2,252 @@
require_once 'db/config.php';
require_once 'header.php';
$message = '';
$message_type = '';
// --- DB Schema and Data Fetching ---
try {
$pdo = db();
// Create table if it doesn't exist
// Add id_conductor to citas table
$pdo->exec("CREATE TABLE IF NOT EXISTS citas (
id INT AUTO_INCREMENT PRIMARY KEY,
fecha DATE NOT NULL,
hora TIME NOT NULL,
title VARCHAR(255) NOT NULL,
start_event DATETIME NOT NULL,
end_event DATETIME NOT NULL,
id_departamento INT NOT NULL,
id_conductor INT,
lugar VARCHAR(255),
usuarios TEXT,
estado VARCHAR(50) DEFAULT 'Pendiente',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (id_departamento) REFERENCES departamentos(id)
FOREIGN KEY (id_departamento) REFERENCES departamentos(id) ON DELETE CASCADE,
FOREIGN KEY (id_conductor) REFERENCES taxis(id) ON DELETE SET NULL
)");
// Check if id_conductor column exists and add it if not
$stmt = $pdo->query("SHOW COLUMNS FROM citas LIKE 'id_conductor'");
if ($stmt->rowCount() == 0) {
$pdo->exec("ALTER TABLE citas ADD COLUMN id_conductor INT NULL AFTER id_departamento, ADD FOREIGN KEY (id_conductor) REFERENCES taxis(id) ON DELETE SET NULL;");
}
// Fetch departments and conductors
$departamentos = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre")->fetchAll(PDO::FETCH_ASSOC);
$conductores = $pdo->query("SELECT id, matricula FROM taxis ORDER BY matricula")->fetchAll(PDO::FETCH_ASSOC);
// Get selected filters
$selected_depto_id = $_GET['id_departamento'] ?? null;
$selected_conductor_id = $_GET['id_conductor'] ?? null;
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_cita'])) {
$title = $_POST['title'];
$fecha = $_POST['fecha'];
$hora = $_POST['hora'];
$hora_inicio = $_POST['hora_inicio'];
$hora_fin = $_POST['hora_fin'];
$id_departamento = $_POST['id_departamento'];
$id_conductor = $_POST['id_conductor'] ?: null;
$lugar = trim($_POST['lugar']);
$usuarios = trim($_POST['usuarios']);
$estado = $_POST['estado'];
if (!empty($fecha) && !empty($hora) && !empty($id_departamento)) {
$stmt = $pdo->prepare("INSERT INTO citas (fecha, hora, id_departamento, lugar, usuarios, estado) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$fecha, $hora, $id_departamento, $lugar, $usuarios, $estado]);
echo '<div class="alert alert-success" role="alert">Cita añadida con éxito.</div>';
if (!empty($title) && !empty($fecha) && !empty($hora_inicio) && !empty($hora_fin) && !empty($id_departamento)) {
$start_event = $fecha . ' ' . $hora_inicio;
$end_event = $fecha . ' ' . $hora_fin;
$stmt = $pdo->prepare("INSERT INTO citas (title, start_event, end_event, id_departamento, id_conductor, lugar, usuarios, estado) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$title, $start_event, $end_event, $id_departamento, $id_conductor, $lugar, $usuarios, $estado]);
$message = '<div class="alert alert-success">Cita añadida con éxito.</div>';
} else {
echo '<div class="alert alert-danger" role="alert">Fecha, hora y departamento son obligatorios.</div>';
$message = '<div class="alert alert-danger">Título, fecha, horas y departamento son obligatorios.</div>';
}
}
// Fetch all departments for dropdown
$departamentos_stmt = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre");
$departamentos = $departamentos_stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch citas for the calendar and list
$events = [];
$citas_list = [];
// Fetch all citas
$stmt = $pdo->query("SELECT c.id, c.fecha, c.hora, dep.nombre as departamento_nombre, c.lugar, c.usuarios, c.estado, c.created_at
$sql = "SELECT c.id, c.title, c.start_event as start, c.end_event as end, c.estado, c.lugar, c.usuarios, c.created_at, t.matricula as conductor_nombre
FROM citas c
JOIN departamentos dep ON c.id_departamento = dep.id
ORDER BY c.fecha DESC, c.hora DESC");
$citas = $stmt->fetchAll(PDO::FETCH_ASSOC);
LEFT JOIN taxis t ON c.id_conductor = t.id
WHERE 1=1";
$params = [];
if ($selected_depto_id) {
$sql .= " AND c.id_departamento = ?";
$params[] = $selected_depto_id;
}
if ($selected_conductor_id) {
$sql .= " AND c.id_conductor = ?";
$params[] = $selected_conductor_id;
}
$sql .= " ORDER BY c.start_event DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$citas_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Format for FullCalendar
foreach($citas_list as $cita) {
$events[] = [
'title' => $cita['title'],
'start' => $cita['start'],
'end' => $cita['end'],
'extendedProps' => [
'estado' => $cita['estado'],
'conductor' => $cita['conductor_nombre'] ?? 'N/A'
]
];
}
} catch (PDOException $e) {
die("Error de base de datos: " . $e->getMessage());
$message = "Error de base de datos: " . $e->getMessage();
$message_type = 'danger';
}
?>
<!-- FullCalendar CSS -->
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css' rel='stylesheet' />
<div class="container-fluid px-4">
<h1 class="mt-4">Citas</h1>
<h1 class="mt-4">Calendario de Citas</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="index.php">Dashboard</a></li>
<li class="breadcrumb-item active">Citas</li>
</ol>
<?php if ($message): ?>
<div class="alert alert-info alert-dismissible fade show" role="alert">
<?php echo $message; ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Añadir Nueva Cita
</div>
<div class="card-header"><i class="fas fa-filter me-1"></i>Filtros</div>
<div class="card-body">
<form action="citas.php" method="POST">
<div class="row mb-3">
<form action="citas.php" method="GET" id="filter-form">
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
<input class="form-control" id="inputFecha" type="date" name="fecha" required />
<label for="inputFecha">Fecha</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
<input class="form-control" id="inputHora" type="time" name="hora" required />
<label for="inputHora">Hora</label>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3">
<select class="form-select" id="selectDepartamento" name="id_departamento" required>
<select class="form-select" name="id_departamento" onchange="this.form.submit()">
<option value="">Seleccione un departamento</option>
<?php foreach ($departamentos as $departamento): ?>
<option value="<?php echo $departamento['id']; ?>"><?php echo htmlspecialchars($departamento['nombre']); ?></option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>" <?php echo ($depto['id'] == $selected_depto_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
<label for="selectDepartamento">Departamento</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
<input class="form-control" id="inputLugar" type="text" name="lugar" placeholder="Lugar" />
<label for="inputLugar">Lugar (Lat, Lon)</label>
</div>
</div>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" id="inputUsuarios" name="usuarios" placeholder="Usuarios" style="height: 100px;"></textarea>
<label for="inputUsuarios">Usuarios</label>
</div>
<div class="form-floating mb-3">
<select class="form-select" id="selectEstado" name="estado">
<option value="Pendiente">Pendiente</option>
<option value="Confirmada">Confirmada</option>
<option value="Cancelada">Cancelada</option>
<select class="form-select" name="id_conductor" onchange="this.form.submit()">
<option value="">Todos los conductores</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>" <?php echo ($conductor['id'] == $selected_conductor_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($conductor['matricula']); ?></option>
<?php endforeach; ?>
</select>
<label for="selectEstado">Estado</label>
</div>
<div class="mt-4 mb-0">
<div class="d-grid">
<button type="submit" name="add_cita" class="btn btn-primary btn-block">Añadir Cita</button>
</div>
</div>
</form>
</div>
</div>
<?php if ($selected_depto_id || $selected_conductor_id): ?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Lista de Citas
</div>
<div class="card-body">
<table id="datatablesSimple" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Fecha y Hora</th>
<th>Departamento</th>
<th>Lugar</th>
<th>Usuarios</th>
<th>Estado</th>
</tr>
</thead>
<div id='calendar'></div>
</div>
</div>
<div class="card mb-4">
<div class="card-header"><i class="fas fa-list me-1"></i>Listado de Citas</div>
<div class="card-body">
<table class="table">
<thead><tr><th>Título</th><th>Conductor</th><th>Inicio</th><th>Fin</th><th>Estado</th><th>Lugar</th><th>Usuarios</th></tr></thead>
<tbody>
<?php if (!empty($citas)):
foreach ($citas as $cita):
?>
<?php if(empty($citas_list)): ?>
<tr><td colspan="7" class="text-center">No hay citas para los filtros seleccionados.</td></tr>
<?php else: foreach($citas_list as $cita): ?>
<tr>
<td><?php echo htmlspecialchars($cita['id']); ?></td>
<td><?php echo htmlspecialchars($cita['fecha'] . ' ' . $cita['hora']); ?></td>
<td><?php echo htmlspecialchars($cita['departamento_nombre']); ?></td>
<td><?php echo htmlspecialchars($cita['title']); ?></td>
<td><?php echo htmlspecialchars($cita['conductor_nombre'] ?? 'N/A'); ?></td>
<td><?php echo date('d/m/Y H:i', strtotime($cita['start'])); ?></td>
<td><?php echo date('d/m/Y H:i', strtotime($cita['end'])); ?></td>
<td><?php echo htmlspecialchars($cita['estado']); ?></td>
<td><?php echo htmlspecialchars($cita['lugar']); ?></td>
<td><?php echo htmlspecialchars($cita['usuarios']); ?></td>
<td><?php echo htmlspecialchars($cita['estado']); ?></td>
</tr>
<?php
endforeach;
else:
?>
<tr>
<td colspan="6" class="text-center">No hay citas registradas.</td>
</tr>
<?php endif; ?>
<?php endforeach; endif; ?>
</tbody>
</table>
</div>
</div>
<?php else: ?>
<div class="alert alert-info">Por favor, seleccione un departamento o conductor para ver el calendario y las citas.</div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-header"><i class="fas fa-plus me-1"></i>Añadir Nueva Cita</div>
<div class="card-body">
<form action="citas.php?<?php echo http_build_query($_GET); ?>" method="POST">
<div class="form-floating mb-3">
<input class="form-control" type="text" name="title" placeholder="Título" required />
<label>Título de la cita</label>
</div>
<div class="row mb-3">
<div class="col-md-4"><div class="form-floating"><input class="form-control" type="date" name="fecha" required /><label>Fecha</label></div></div>
<div class="col-md-4"><div class="form-floating"><input class="form-control" type="time" name="hora_inicio" required /><label>Hora Inicio</label></div></div>
<div class="col-md-4"><div class="form-floating"><input class="form-control" type="time" name="hora_fin" required /><label>Hora Fin</label></div></div>
</div>
<div class="row mb-3">
<div class="col-md-6"><div class="form-floating"><select class="form-select" name="id_departamento" required>
<option value="">Seleccione departamento</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>" <?php echo ($depto['id'] == $selected_depto_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select><label>Departamento</label></div></div>
<div class="col-md-6"><div class="form-floating"><select class="form-select" name="id_conductor">
<option value="">Seleccione un conductor (Opcional)</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>" <?php echo ($conductor['id'] == $selected_conductor_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($conductor['matricula']); ?></option>
<?php endforeach; ?>
</select><label>Conductor</label></div></div>
</div>
<div class="form-floating mb-3">
<input class="form-control" type="text" name="lugar" placeholder="Lugar" />
<label>Lugar</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" name="usuarios" placeholder="Usuarios" style="height: 80px;"></textarea>
<label>Usuarios</label>
</div>
<div class="form-floating mb-3"><select class="form-select" name="estado">
<option value="Pendiente">Pendiente</option>
<option value="Confirmada">Confirmada</option>
<option value="Cancelada">Cancelada</option>
</select><label>Estado</label></div>
<div class="d-grid"><button type="submit" name="add_cita" class="btn btn-primary">Añadir Cita</button></div>
</form>
</div>
</div>
</div>
<!-- FullCalendar JS -->
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
<?php if ($selected_depto_id || $selected_conductor_id): ?>
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
locale: 'es',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
events: <?php echo json_encode($events); ?>
});
calendar.render();
<?php endif; ?>
});
</script>
<?php
require_once 'footer.php';

View File

@ -2,53 +2,82 @@
require_once 'db/config.php';
require_once 'header.php';
$message = '';
$message_type = '';
// --- DB Schema and Data Fetching ---
try {
$pdo = db();
// Create table if it doesn't exist
// Create/update consultas table
$pdo->exec("CREATE TABLE IF NOT EXISTS consultas (
id INT AUTO_INCREMENT PRIMARY KEY,
id_taxista INT NOT NULL,
id_conductor INT NOT NULL,
id_departamento INT NOT NULL,
asunto VARCHAR(255) NOT NULL,
resultado TEXT,
status VARCHAR(50) DEFAULT 'Pendiente',
fecha_consulta TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (id_taxista) REFERENCES drivers(id),
FOREIGN KEY (id_departamento) REFERENCES departamentos(id)
FOREIGN KEY (id_conductor) REFERENCES taxis(id) ON DELETE CASCADE,
FOREIGN KEY (id_departamento) REFERENCES departamentos(id) ON DELETE CASCADE
)");
// Fetch departments for dropdowns
$departamentos = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre")->fetchAll(PDO::FETCH_ASSOC);
// Fetch taxis/conductores for dropdowns
$conductores = $pdo->query("SELECT id, matricula FROM taxis ORDER BY matricula")->fetchAll(PDO::FETCH_ASSOC);
// Get selected department for filtering
$selected_depto_id = $_GET['id_departamento'] ?? null;
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_consulta'])) {
$id_taxista = $_POST['id_taxista'];
$id_conductor = $_POST['id_conductor'];
$id_departamento = $_POST['id_departamento'];
$asunto = trim($_POST['asunto']);
$resultado = trim($_POST['resultado']);
$status = $_POST['status'];
if (!empty($id_taxista) && !empty($id_departamento)) {
$stmt = $pdo->prepare("INSERT INTO consultas (id_taxista, id_departamento, resultado) VALUES (?, ?, ?)");
$stmt->execute([$id_taxista, $id_departamento, $resultado]);
echo '<div class="alert alert-success" role="alert">Consulta añadida con éxito.</div>';
if (!empty($id_conductor) && !empty($id_departamento) && !empty($asunto)) {
$stmt = $pdo->prepare("INSERT INTO consultas (id_conductor, id_departamento, asunto, resultado, status) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$id_conductor, $id_departamento, $asunto, $resultado, $status]);
$message = '<div class="alert alert-success">Consulta añadida con éxito.</div>';
} else {
echo '<div class="alert alert-danger" role="alert">Taxista y departamento son obligatorios.</div>';
$message = '<div class="alert alert-danger">Conductor, departamento y asunto son obligatorios.</div>';
}
}
// Fetch all drivers for dropdown
$drivers_stmt = $pdo->query("SELECT id, name FROM drivers ORDER BY name");
$drivers = $drivers_stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch all departments for dropdown
$departamentos_stmt = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre");
$departamentos = $departamentos_stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch all consultas
$stmt = $pdo->query("SELECT c.id, d.name as taxista_nombre, dep.nombre as departamento_nombre, c.resultado, c.fecha_consulta
// Fetch consultations
$filter_status = $_GET['status'] ?? null;
$sql = "SELECT c.id, t.matricula as conductor_nombre, dep.nombre as departamento_nombre, c.asunto, c.resultado, c.status, c.fecha_consulta
FROM consultas c
JOIN drivers d ON c.id_taxista = d.id
JOIN departamentos dep ON c.id_departamento = dep.id
ORDER BY c.fecha_consulta DESC");
JOIN taxis t ON c.id_conductor = t.id
JOIN departamentos dep ON c.id_departamento = dep.id";
$conditions = [];
$params = [];
if ($filter_status) {
$conditions[] = "c.status = :status";
$params[':status'] = $filter_status;
}
if ($selected_depto_id) {
$conditions[] = "c.id_departamento = :id_departamento";
$params[':id_departamento'] = $selected_depto_id;
}
if (count($conditions) > 0) {
$sql .= " WHERE " . implode(' AND ', $conditions);
}
$sql .= " ORDER BY c.fecha_consulta DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$consultas = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error de base de datos: " . $e->getMessage());
$message = "Error de base de datos: " . $e->getMessage();
$message_type = 'danger';
}
?>
@ -59,85 +88,101 @@ try {
<li class="breadcrumb-item active">Consultas</li>
</ol>
<?php if ($message): ?>
<div class="alert alert-<?php echo $message_type ? $message_type : 'info'; ?> alert-dismissible fade show" role="alert">
<?php echo $message; ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Añadir Nueva Consulta
</div>
<div class="card-header"><i class="fas fa-filter me-1"></i>Filtro por Departamento</div>
<div class="card-body">
<form action="consultas.php" method="POST">
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3">
<select class="form-select" id="selectTaxista" name="id_taxista" required>
<option value="">Seleccione un taxista</option>
<?php foreach ($drivers as $driver): ?>
<option value="<?php echo $driver['id']; ?>"><?php echo htmlspecialchars($driver['name']); ?></option>
<form action="consultas.php" method="GET" id="depto-select-form">
<div class="input-group">
<select class="form-select" name="id_departamento" onchange="this.form.submit()">
<option value="">Todos los departamentos</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>" <?php echo ($depto['id'] == $selected_depto_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
<label for="selectTaxista">Taxista</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
<select class="form-select" id="selectDepartamento" name="id_departamento" required>
<option value="">Seleccione un departamento</option>
<?php foreach ($departamentos as $departamento): ?>
<option value="<?php echo $departamento['id']; ?>"><?php echo htmlspecialchars($departamento['nombre']); ?></option>
<?php endforeach; ?>
</select>
<label for="selectDepartamento">Departamento</label>
</div>
</div>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" id="inputResultado" name="resultado" placeholder="Resultado de la consulta" style="height: 100px;"></textarea>
<label for="inputResultado">Resultado</label>
</div>
<div class="mt-4 mb-0">
<div class="d-grid">
<button type="submit" name="add_consulta" class="btn btn-primary btn-block">Añadir Consulta</button>
</div>
<?php if($filter_status): ?>
<input type="hidden" name="status" value="<?php echo htmlspecialchars($filter_status); ?>" />
<?php endif; ?>
<a href="consultas.php" class="btn btn-outline-secondary">Limpiar</a>
</div>
</form>
</div>
</div>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Lista de Consultas
</div>
<div class="card-header"><i class="fas fa-plus me-1"></i>Añadir Nueva Consulta</div>
<div class="card-body">
<table id="datatablesSimple" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Taxista</th>
<th>Departamento</th>
<th>Resultado</th>
<th>Fecha</th>
</tr>
</thead>
<form action="consultas.php" method="POST">
<div class="form-floating mb-3">
<input class="form-control" id="inputAsunto" type="text" name="asunto" placeholder="Asunto" required />
<label for="inputAsunto">Asunto</label>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3">
<select class="form-select" name="id_conductor" required>
<option value="">Seleccione un conductor</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>"><?php echo htmlspecialchars($conductor['matricula']); ?></option>
<?php endforeach; ?>
</select>
<label>Conductor</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
<select class="form-select" name="id_departamento" required>
<option value="">Seleccione un departamento</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>"><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
<label>Departamento</label>
</div>
</div>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" name="resultado" placeholder="Resultado" style="height: 100px;"></textarea>
<label>Resultado</label>
</div>
<div class="form-floating mb-3">
<select class="form-select" name="status">
<option value="Pendiente">Pendiente</option>
<option value="En Progreso">En Progreso</option>
<option value="Resuelta">Resuelta</option>
</select>
<label>Estado</label>
</div>
<div class="d-grid">
<button type="submit" name="add_consulta" class="btn btn-primary">Añadir Consulta</button>
</div>
</form>
</div>
</div>
<div class="card mb-4">
<div class="card-header"><i class="fas fa-table me-1"></i>Lista de Consultas</div>
<div class="card-body">
<table class="table table-striped">
<thead><tr><th>Conductor</th><th>Departamento</th><th>Asunto</th><th>Resultado</th><th>Estado</th><th>Fecha</th></tr></thead>
<tbody>
<?php if (!empty($consultas)):
foreach ($consultas as $consulta):
?>
<?php if (empty($consultas)): ?>
<tr><td colspan="6" class="text-center">No hay consultas.</td></tr>
<?php else: foreach ($consultas as $consulta): ?>
<tr>
<td><?php echo htmlspecialchars($consulta['id']); ?></td>
<td><?php echo htmlspecialchars($consulta['taxista_nombre']); ?></td>
<td><?php echo htmlspecialchars($consulta['conductor_nombre']); ?></td>
<td><?php echo htmlspecialchars($consulta['departamento_nombre']); ?></td>
<td><?php echo htmlspecialchars($consulta['asunto']); ?></td>
<td><?php echo htmlspecialchars($consulta['resultado']); ?></td>
<td><?php echo htmlspecialchars($consulta['fecha_consulta']); ?></td>
<td><?php echo htmlspecialchars($consulta['status']); ?></td>
<td><?php echo date("d/m/Y H:i", strtotime($consulta['fecha_consulta'])); ?></td>
</tr>
<?php
endforeach;
else:
?>
<tr>
<td colspan="5" class="text-center">No hay consultas registradas.</td>
</tr>
<?php endif; ?>
<?php endforeach; endif; ?>
</tbody>
</table>
</div>

View File

@ -1,114 +1,160 @@
<?php
require_once 'db/config.php';
require_once 'header.php';
// --- DB Schema and Logic ---
try {
$pdo = db();
// Create table if it doesn't exist
// Create departments table
$pdo->exec("CREATE TABLE IF NOT EXISTS departamentos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(255) NOT NULL,
color VARCHAR(7) DEFAULT '#FFFFFF',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
nombre VARCHAR(255) NOT NULL UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_department'])) {
$message = '';
// Handle POST requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Add new
if (isset($_POST['add_departamento'])) {
$nombre = trim($_POST['nombre']);
$color = trim($_POST['color']);
if (!empty($nombre)) {
$stmt = $pdo->prepare("INSERT INTO departamentos (nombre, color) VALUES (?, ?)");
$stmt->execute([$nombre, $color]);
echo '<div class="alert alert-success" role="alert">Departamento añadido con éxito.</div>';
$stmt = $pdo->prepare("INSERT INTO departamentos (nombre) VALUES (?)");
$stmt->execute([$nombre]);
$message = '<div class="alert alert-success">Departamento añadido.</div>';
} else {
echo '<div class="alert alert-danger" role="alert">El nombre del departamento es obligatorio.</div>';
$message = '<div class="alert alert-danger">El nombre no puede estar vacío.</div>';
}
}
// Update
elseif (isset($_POST['update_departamento'])) {
$id = $_POST['id'];
$nombre = trim($_POST['nombre']);
if (!empty($nombre)) {
$stmt = $pdo->prepare("UPDATE departamentos SET nombre = ? WHERE id = ?");
$stmt->execute([$nombre, $id]);
$message = '<div class="alert alert-success">Departamento actualizado.</div>';
} else {
$message = '<div class="alert alert-danger">El nombre no puede estar vacío.</div>';
}
}
// Delete
elseif (isset($_POST['delete_departamento'])) {
$id = $_POST['id'];
$stmt = $pdo->prepare("DELETE FROM departamentos WHERE id = ?");
$stmt->execute([$id]);
$message = '<div class="alert alert-warning">Departamento eliminado.</div>';
}
}
// Fetch all departments
$stmt = $pdo->query("SELECT id, nombre, color, created_at FROM departamentos ORDER BY created_at DESC");
$departamentos = $stmt->fetchAll(PDO::FETCH_ASSOC);
$departamentos = $pdo->query("SELECT * FROM departamentos ORDER BY nombre")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error de base de datos: " . $e->getMessage());
die("DB ERROR: " . $e->getMessage());
}
include 'header.php';
?>
<div class="container-fluid px-4">
<h1 class="mt-4">Departamentos</h1>
<h1 class="mt-4">Gestión de Departamentos</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="index.php">Dashboard</a></li>
<li class="breadcrumb-item active">Departamentos</li>
</ol>
<?php echo $message; ?>
<div class="row">
<!-- Add Department Form -->
<div class="col-xl-4">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
<i class="fas fa-plus me-1"></i>
Añadir Nuevo Departamento
</div>
<div class="card-body">
<form action="departamentos.php" method="POST">
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<div class="form-floating mb-3">
<input class="form-control" id="inputNombre" type="text" name="nombre" placeholder="Nombre del departamento" required />
<label for="inputNombre">Nombre del departamento</label>
<label for="inputNombre">Nombre del Departamento</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input class="form-control" id="inputColor" type="color" name="color" value="#FFFFFF" />
<label for="inputColor">Color</label>
</div>
</div>
</div>
<div class="mt-4 mb-0">
<div class="d-grid">
<button type="submit" name="add_department" class="btn btn-primary btn-block">Añadir Departamento</button>
</div>
<button type="submit" name="add_departamento" class="btn btn-primary">Añadir</button>
</div>
</form>
</div>
</div>
</div>
<!-- Departments List -->
<div class="col-xl-8">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Lista de Departamentos
<i class="fas fa-building me-1"></i>
Listado de Departamentos
</div>
<div class="card-body">
<table id="datatablesSimple" class="table table-striped">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Color</th>
<th>Fecha de Creación</th>
<th class="text-end">Acciones</th>
</tr>
</thead>
<tbody>
<?php if (!empty($departamentos)): ?>
<?php foreach ($departamentos as $departamento): ?>
<tr>
<td><?php echo htmlspecialchars($departamento['id']); ?></td>
<td><?php echo htmlspecialchars($departamento['nombre']); ?></td>
<td style="background-color: <?php echo htmlspecialchars($departamento['color']); ?>;"><?php echo htmlspecialchars($departamento['color']); ?></td>
<td><?php echo htmlspecialchars($departamento['created_at']); ?></td>
</tr>
<?php endforeach; ?>
<?php if (empty($departamentos)): ?>
<tr><td colspan="2" class="text-center">No hay departamentos.</td></tr>
<?php else: ?>
<?php foreach ($departamentos as $depto): ?>
<tr>
<td colspan="4" class="text-center">No hay departamentos registrados.</td>
<td><?php echo htmlspecialchars($depto['nombre']); ?></td>
<td class="text-end">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#editModal-<?php echo $depto['id']; ?>">
<i class="bi bi-pencil"></i> Editar
</button>
<form action="departamentos.php" method="POST" class="d-inline" onsubmit="return confirm('¿Estás seguro de que quieres eliminar este departamento?');">
<input type="hidden" name="id" value="<?php echo $depto['id']; ?>">
<button type="submit" name="delete_departamento" class="btn btn-sm btn-outline-danger">
<i class="bi bi-trash"></i> Eliminar
</button>
</form>
</td>
</tr>
<!-- Edit Modal -->
<div class="modal fade" id="editModal-<?php echo $depto['id']; ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Editar Departamento</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="departamentos.php" method="POST">
<div class="modal-body">
<input type="hidden" name="id" value="<?php echo $depto['id']; ?>">
<div class="form-floating">
<input type="text" class="form-control" name="nombre" value="<?php echo htmlspecialchars($depto['nombre']); ?>" required>
<label>Nombre</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" name="update_departamento" class="btn btn-primary">Guardar Cambios</button>
</div>
</form>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
require_once 'footer.php';
?>
<?php include 'footer.php'; ?>

View File

@ -4,30 +4,65 @@ require_once 'db/config.php';
// --- DB Schema Setup ---
try {
$pdo = db();
// Create documents table
// Create documents table with new fields
$pdo->exec("CREATE TABLE IF NOT EXISTS documents (
id INT AUTO_INCREMENT PRIMARY KEY,
id_conductor INT,
tipo_documento VARCHAR(255),
title VARCHAR(255) NOT NULL,
description TEXT,
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(255) NOT NULL,
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (id_conductor) REFERENCES taxis(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
// Add columns if they don't exist (for existing tables)
$check_columns = $pdo->query("SHOW COLUMNS FROM documents LIKE 'id_conductor'");
if ($check_columns->rowCount() == 0) {
$pdo->exec("ALTER TABLE documents ADD COLUMN id_conductor INT, ADD FOREIGN KEY (id_conductor) REFERENCES taxis(id) ON DELETE SET NULL;");
}
$check_columns = $pdo->query("SHOW COLUMNS FROM documents LIKE 'tipo_documento'");
if ($check_columns->rowCount() == 0) {
$pdo->exec("ALTER TABLE documents ADD COLUMN tipo_documento VARCHAR(255);");
}
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}
// --- File Upload Logic ---
// --- File Upload & Update Logic ---
$upload_dir = 'uploads/';
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['document'])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo = db();
// Handle Update
if (isset($_POST['update_document'])) {
$id = $_POST['document_id'];
$title = $_POST['title'];
$description = $_POST['description'];
$id_conductor = $_POST['id_conductor'];
$tipo_documento = $_POST['tipo_documento'];
try {
$stmt = $pdo->prepare("UPDATE documents SET title = ?, description = ?, id_conductor = ?, tipo_documento = ? WHERE id = ?");
$stmt->execute([$title, $description, $id_conductor, $tipo_documento, $id]);
$message = '<div class="alert alert-success">Documento actualizado con éxito.</div>';
} catch (PDOException $e) {
$message = '<div class="alert alert-danger">Error al actualizar: ' . $e->getMessage() . '</div>';
}
}
// Handle Upload
elseif (isset($_FILES['document'])) {
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
$title = $_POST['title'] ?? 'Sin Título';
$description = $_POST['description'] ?? '';
$id_conductor = $_POST['id_conductor'] ?? null;
$tipo_documento = $_POST['tipo_documento'] ?? '';
$file_name = basename($_FILES['document']['name']);
$file_tmp = $_FILES['document']['tmp_name'];
$file_error = $_FILES['document']['error'];
@ -38,8 +73,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['document'])) {
if (move_uploaded_file($file_tmp, $file_path)) {
try {
$stmt = $pdo->prepare("INSERT INTO documents (title, description, file_name, file_path) VALUES (?, ?, ?, ?)");
$stmt->execute([$title, $description, $file_name, $file_path]);
$stmt = $pdo->prepare("INSERT INTO documents (title, description, id_conductor, tipo_documento, file_name, file_path) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$title, $description, $id_conductor, $tipo_documento, $file_name, $file_path]);
$message = '<div class="alert alert-success">Documento subido con éxito.</div>';
} catch (PDOException $e) {
$message = '<div class="alert alert-danger">Error al guardar en la base de datos: ' . $e->getMessage() . '</div>';
@ -51,14 +86,43 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['document'])) {
$message = '<div class="alert alert-danger">Error en la subida del fichero: ' . $file_error . '</div>';
}
}
}
// --- Fetch Documents ---
// --- Fetch Data ---
$documents = [];
$conductores = [];
try {
$stmt = $pdo->query("SELECT id, title, description, file_name, file_path, uploaded_at FROM documents ORDER BY uploaded_at DESC");
$pdo = db();
// Fetch drivers (taxis)
$conductores = $pdo->query("SELECT id, matricula, modelo FROM taxis ORDER BY matricula")->fetchAll(PDO::FETCH_ASSOC);
// Fetch documents with driver info
$sort_column = $_GET['sort'] ?? 'uploaded_at';
$sort_order = $_GET['order'] ?? 'DESC';
$valid_columns = ['title', 'tipo_documento', 'conductor', 'uploaded_at'];
if (!in_array($sort_column, $valid_columns)) {
$sort_column = 'uploaded_at';
}
$sql = "SELECT d.id, d.title, d.description, d.file_name, d.file_path, d.uploaded_at, d.tipo_documento, t.matricula as conductor, d.id_conductor
FROM documents d
LEFT JOIN taxis t ON d.id_conductor = t.id
ORDER BY $sort_column $sort_order";
$stmt = $pdo->query($sql);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message .= '<div class="alert alert-danger">Error al obtener los documentos: ' . $e->getMessage() . '</div>';
$message .= '<div class="alert alert-danger">Error al obtener los datos: ' . $e->getMessage() . '</div>';
}
function get_sort_link($column, $display) {
$sort_column = $_GET['sort'] ?? 'uploaded_at';
$sort_order = $_GET['order'] ?? 'DESC';
$order = ($sort_column == $column && $sort_order == 'ASC') ? 'DESC' : 'ASC';
$icon = $sort_column == $column ? ($sort_order == 'ASC' ? 'bi-sort-up' : 'bi-sort-down') : 'bi-arrow-down-up-square';
return '<a href="?sort=' . $column . '&order=' . $order . '">' . $display . ' <i class="bi '.$icon.'"></i></a>';
}
include 'header.php';
@ -79,29 +143,42 @@ include 'header.php';
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Título</th>
<th><?php echo get_sort_link('title', 'Título'); ?></th>
<th>Descripción</th>
<th><?php echo get_sort_link('tipo_documento', 'Tipo'); ?></th>
<th><?php echo get_sort_link('conductor', 'Conductor'); ?></th>
<th>Fichero</th>
<th>Fecha de Subida</th>
<th><?php echo get_sort_link('uploaded_at', 'Fecha de Subida'); ?></th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (empty($documents)): ?>
<tr>
<td colspan="5" class="text-center">No hay documentos todavía.</td>
<td colspan="7" class="text-center">No hay documentos todavía.</td>
</tr>
<?php else: ?>
<?php foreach ($documents as $doc): ?>
<tr>
<td><?php echo htmlspecialchars($doc['title']); ?></td>
<td><?php echo htmlspecialchars($doc['description']); ?></td>
<td><?php echo htmlspecialchars($doc['tipo_documento']); ?></td>
<td><?php echo htmlspecialchars($doc['conductor'] ?? 'N/A'); ?></td>
<td><?php echo htmlspecialchars($doc['file_name']); ?></td>
<td><?php echo date("d/m/Y H:i", strtotime($doc['uploaded_at'])); ?></td>
<td>
<a href="<?php echo htmlspecialchars($doc['file_path']); ?>" class="btn btn-sm btn-outline-primary" download>
<i class="bi bi-download"></i> Descargar
<i class="bi bi-download"></i>
</a>
<button type="button" class="btn btn-sm btn-outline-secondary edit-btn"
data-id="<?php echo $doc['id']; ?>"
data-title="<?php echo htmlspecialchars($doc['title']); ?>"
data-description="<?php echo htmlspecialchars($doc['description']); ?>"
data-id-conductor="<?php echo $doc['id_conductor']; ?>"
data-tipo-documento="<?php echo htmlspecialchars($doc['tipo_documento']); ?>"
data-bs-toggle="modal" data-bs-target="#editModal">
<i class="bi bi-pencil"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
@ -123,12 +200,25 @@ include 'header.php';
<form action="documents.php" method="post" enctype="multipart/form-data">
<div class="modal-body">
<div class="mb-3">
<label for="title" class="form-label">Título del Documento</label>
<label for="title" class="form-label">Título</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Descripción (Opcional)</label>
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
<label for="description" class="form-label">Descripción</label>
<textarea class="form-control" id="description" name="description" rows="2"></textarea>
</div>
<div class="mb-3">
<label for="id_conductor_upload" class="form-label">Conductor</label>
<select class="form-select" id="id_conductor_upload" name="id_conductor">
<option value="">Sin asignar</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>"><?php echo htmlspecialchars($conductor['matricula']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="tipo_documento" class="form-label">Tipo de Documento</label>
<input type="text" class="form-control" id="tipo_documento" name="tipo_documento" placeholder="Ej: ITV, Seguro, DNI...">
</div>
<div class="mb-3">
<label for="document" class="form-label">Seleccionar Fichero</label>
@ -144,4 +234,63 @@ include 'header.php';
</div>
</div>
<!-- Edit Modal -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editModalLabel">Editar Documento</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="documents.php" method="post">
<input type="hidden" name="update_document" value="1">
<input type="hidden" id="edit_document_id" name="document_id">
<div class="modal-body">
<div class="mb-3">
<label for="edit_title" class="form-label">Título</label>
<input type="text" class="form-control" id="edit_title" name="title" required>
</div>
<div class="mb-3">
<label for="edit_description" class="form-label">Descripción</label>
<textarea class="form-control" id="edit_description" name="description" rows="3"></textarea>
</div>
<div class="mb-3">
<label for="edit_id_conductor" class="form-label">Conductor</label>
<select class="form-select" id="edit_id_conductor" name="id_conductor">
<option value="">Sin asignar</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>"><?php echo htmlspecialchars($conductor['matricula']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="edit_tipo_documento" class="form-label">Tipo de Documento</label>
<input type="text" class="form-control" id="edit_tipo_documento" name="tipo_documento">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-primary">Guardar Cambios</button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const editModal = document.getElementById('editModal');
editModal.addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const modal = this;
modal.querySelector('#edit_document_id').value = button.dataset.id;
modal.querySelector('#edit_title').value = button.dataset.title;
modal.querySelector('#edit_description').value = button.dataset.description;
modal.querySelector('#edit_id_conductor').value = button.dataset.idConductor;
modal.querySelector('#edit_tipo_documento').value = button.dataset.tipoDocumento;
});
});
</script>
<?php include 'footer.php'; ?>

View File

@ -1,74 +1,62 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'db/config.php';
require_once 'header.php';
$message = '';
$message_type = '';
// DDL to create table
// --- DB Schema and Data Fetching ---
try {
$pdo = db();
$pdo->exec("CREATE TABLE IF NOT EXISTS drivers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
license_number VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);");
} catch (PDOException $e) {
// die("DB error: " . $e->getMessage()); // Avoid dying on production
$message = 'Error de conexión con la base de datos.';
$message_type = 'danger';
// Add department FK to taxis table
$check_column = $pdo->query("SHOW COLUMNS FROM taxis LIKE 'id_departamento'");
if ($check_column->rowCount() == 0) {
$pdo->exec("ALTER TABLE taxis ADD COLUMN id_departamento INT, ADD FOREIGN KEY (id_departamento) REFERENCES departamentos(id) ON DELETE SET NULL;");
}
// Handle POST request to add a new driver
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_driver'])) {
$name = trim($_POST['name']);
$license_number = trim($_POST['license_number']);
$phone = trim($_POST['phone']);
// Handle POST requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Add new taxi
if (isset($_POST['add_taxi'])) {
$matricula = trim($_POST['matricula']);
$modelo = trim($_POST['modelo']);
$id_departamento = $_POST['id_departamento'] ?: null;
if (!empty($name) && !empty($license_number) && !empty($phone)) {
try {
$sql = "INSERT INTO drivers (name, license_number, phone) VALUES (:name, :license_number, :phone)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':name' => $name,
':license_number' => $license_number,
':phone' => $phone
]);
$message = 'Conductor añadido exitosamente.';
if (!empty($matricula)) {
$sql = "INSERT INTO taxis (matricula, modelo, id_departamento) VALUES (?, ?, ?)";
$pdo->prepare($sql)->execute([$matricula, $modelo, $id_departamento]);
$message = 'Taxi/Conductor añadido exitosamente.';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error al añadir conductor: ' . $e->getMessage();
$message_type = 'danger';
}
} else {
$message = 'Por favor, complete todos los campos.';
$message = 'La matrícula es obligatoria.';
$message_type = 'warning';
}
}
// Fetch all drivers
$drivers = [];
if(isset($pdo)) {
try {
$stmt = $pdo->query("SELECT id, name, license_number, phone, created_at FROM drivers ORDER BY id DESC");
$drivers = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error al obtener los conductores: ' . $e->getMessage();
$message_type = 'danger';
}
// Fetch departments for dropdown
$departamentos = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre")->fetchAll(PDO::FETCH_ASSOC);
// Fetch all taxis with department info
$taxis = $pdo->query(
"SELECT t.*, d.nombre as departamento_nombre
FROM taxis t
LEFT JOIN departamentos d ON t.id_departamento = d.id
ORDER BY t.matricula ASC"
)->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error de base de datos: ' . $e->getMessage();
$message_type = 'danger';
}
?>
<div class="container-fluid px-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Gestión de Conductores</h1>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addDriverModal">
<i class="bi bi-plus-circle"></i> Añadir Conductor
<h1 class="h2">Gestión de Taxis/Conductores</h1>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addTaxiModal">
<i class="bi bi-plus-circle"></i> Añadir Taxi/Conductor
</button>
</div>
@ -85,26 +73,22 @@ if(isset($pdo)) {
<table class="table table-hover">
<thead class="table-light">
<tr>
<th scope="col">ID</th>
<th scope="col">Nombre</th>
<th scope="col"> Licencia</th>
<th scope="col">Teléfono</th>
<th scope="col">Fecha de Registro</th>
<th>Matrícula</th>
<th>Modelo</th>
<th>Departamento</th>
<th>Fecha de Registro</th>
</tr>
</thead>
<tbody>
<?php if (empty($drivers)): ?>
<tr>
<td colspan="5" class="text-center">No hay conductores registrados.</td>
</tr>
<?php if (empty($taxis)): ?>
<tr><td colspan="4" class="text-center">No hay taxis registrados.</td></tr>
<?php else: ?>
<?php foreach ($drivers as $driver): ?>
<?php foreach ($taxis as $taxi): ?>
<tr>
<td><?php echo htmlspecialchars($driver['id']); ?></td>
<td><?php echo htmlspecialchars($driver['name']); ?></td>
<td><?php echo htmlspecialchars($driver['license_number']); ?></td>
<td><?php echo htmlspecialchars($driver['phone']); ?></td>
<td><?php echo htmlspecialchars(date("d/m/Y H:i", strtotime($driver['created_at']))); ?></td>
<td><?php echo htmlspecialchars($taxi['matricula']); ?></td>
<td><?php echo htmlspecialchars($taxi['modelo']); ?></td>
<td><?php echo htmlspecialchars($taxi['departamento_nombre'] ?? 'N/A'); ?></td>
<td><?php echo date("d/m/Y H:i", strtotime($taxi['created_at'])); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
@ -113,34 +97,40 @@ if(isset($pdo)) {
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="addDriverModal" tabindex="-1" aria-labelledby="addDriverModalLabel" aria-hidden="true">
<!-- Add Taxi Modal -->
<div class="modal fade" id="addTaxiModal" tabindex="-1" aria-labelledby="addTaxiModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form action="drivers.php" method="POST">
<div class="modal-header">
<h5 class="modal-title" id="addDriverModalLabel">Añadir Nuevo Conductor</h5>
<h5 class="modal-title" id="addTaxiModalLabel">Añadir Nuevo Taxi/Conductor</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" name="add_driver" value="1">
<input type="hidden" name="add_taxi" value="1">
<div class="mb-3">
<label for="name" class="form-label">Nombre Completo</label>
<input type="text" class="form-control" id="name" name="name" required>
<label for="matricula" class="form-label">Matrícula</label>
<input type="text" class="form-control" id="matricula" name="matricula" required>
</div>
<div class="mb-3">
<label for="license_number" class="form-label">Número de Licencia</label>
<input type="text" class="form-control" id="license_number" name="license_number" required>
<label for="modelo" class="form-label">Modelo</label>
<input type="text" class="form-control" id="modelo" name="modelo">
</div>
<div class="mb-3">
<label for="phone" class="form-label">Teléfono</label>
<input type="tel" class="form-control" id="phone" name="phone" required>
<label for="id_departamento" class="form-label">Departamento</label>
<select class="form-select" id="id_departamento" name="id_departamento">
<option value="">Sin asignar</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>"><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-primary">Guardar Conductor</button>
<button type="submit" class="btn btn-primary">Guardar</button>
</div>
</form>
</div>

175
horarios.php Normal file
View File

@ -0,0 +1,175 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'db/config.php';
require_once 'header.php';
$message = '';
$message_type = '';
// --- DB Schema and Data Fetching ---
try {
$pdo = db();
// Add department FK to appointment_slots table
$pdo->exec("CREATE TABLE IF NOT EXISTS appointment_slots (
id INT AUTO_INCREMENT PRIMARY KEY,
id_departamento INT NOT NULL,
day_of_week TINYINT NOT NULL, -- 1 for Monday, 7 for Sunday
start_time TIME NOT NULL,
end_time TIME NOT NULL,
is_active BOOLEAN DEFAULT true,
UNIQUE KEY (id_departamento, day_of_week, start_time, end_time),
FOREIGN KEY (id_departamento) REFERENCES departamentos(id) ON DELETE CASCADE
);");
// Fetch departments
$departamentos = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre")->fetchAll(PDO::FETCH_ASSOC);
// Get selected department (from GET param or first available)
$selected_depto_id = $_GET['id_departamento'] ?? ($departamentos[0]['id'] ?? null);
} catch (PDOException $e) {
$message = 'Error de conexión con la base de datos: ' . $e->getMessage();
$message_type = 'danger';
}
// Handle POST request to update slots
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($pdo) && isset($_POST['id_departamento'])) {
$id_departamento_post = $_POST['id_departamento'];
try {
// Deactivate all existing slots for the specific department first
$stmt_deactivate = $pdo->prepare("UPDATE appointment_slots SET is_active = false WHERE id_departamento = ?");
$stmt_deactivate->execute([$id_departamento_post]);
if (isset($_POST['slots'])) {
$slots = $_POST['slots'];
$stmt_upsert = $pdo->prepare(
"INSERT INTO appointment_slots (id_departamento, day_of_week, start_time, end_time, is_active)
VALUES (:id_departamento, :day_of_week, :start_time, :end_time, true)
ON DUPLICATE KEY UPDATE is_active = true"
);
foreach ($slots as $day => $times) {
foreach ($times as $time_range => $on) {
list($start_time, $end_time) = explode('-', $time_range);
$stmt_upsert->execute([
':id_departamento' => $id_departamento_post,
':day_of_week' => $day,
':start_time' => $start_time,
':end_time' => $end_time
]);
}
}
}
$message = 'Horarios actualizados correctamente para el departamento seleccionado.';
$message_type = 'success';
$selected_depto_id = $id_departamento_post; // Keep the current department selected
} catch (PDOException $e) {
$message = 'Error al actualizar los horarios: ' . $e->getMessage();
$message_type = 'danger';
}
}
// Fetch current active slots for the selected department
$active_slots = [];
if (isset($pdo) && $selected_depto_id) {
try {
$stmt = $pdo->prepare("SELECT day_of_week, start_time, end_time FROM appointment_slots WHERE is_active = true AND id_departamento = ? ORDER BY day_of_week, start_time");
$stmt->execute([$selected_depto_id]);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$active_slots[$row['day_of_week']][date('H:i', strtotime($row['start_time'])) . '-' . date('H:i', strtotime($row['end_time']))] = true;
}
} catch (PDOException $e) {
$message = 'Error al obtener los horarios: ' . $e->getMessage();
$message_type = 'danger';
}
}
$days_of_week = [1 => 'Lunes', 2 => 'Martes', 3 => 'Miércoles', 4 => 'Jueves', 5 => 'Viernes', 6 => 'Sábado', 7 => 'Domingo'];
$time_ranges = [];
for ($h = 8; $h < 20; $h++) {
$start = str_pad($h, 2, '0', STR_PAD_LEFT) . ':00';
$end = str_pad($h + 1, 2, '0', STR_PAD_LEFT) . ':00';
$time_ranges[] = $start . '-' . $end;
}
?>
<style>
.schedule-grid { display: grid; grid-template-columns: 120px repeat(<?php echo count($time_ranges); ?>, 1fr); gap: 5px; overflow-x: auto; }
.grid-header, .day-label, .slot-checkbox { padding: 10px; text-align: center; background-color: #f8f9fa; font-size: 0.8rem; white-space: nowrap; }
.day-label { font-weight: bold; position: sticky; left: 0; z-index: 1; }
.slot-checkbox { background-color: #fff; }
</style>
<div class="container-fluid px-4">
<h1 class="mt-4">Gestión de Horarios para Citas</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="index.php">Dashboard</a></li>
<li class="breadcrumb-item active">Horarios</li>
</ol>
<?php if ($message): ?>
<div class="alert alert-<?php echo $message_type; ?> alert-dismissible fade show" role="alert">
<?php echo htmlspecialchars($message); ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-calendar-alt me-1"></i>
Seleccionar Departamento
</div>
<div class="card-body">
<form action="horarios.php" method="GET" id="depto-select-form">
<div class="input-group">
<select class="form-select" name="id_departamento" onchange="document.getElementById('depto-select-form').submit();">
<option value="">Seleccione un departamento</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>" <?php echo ($depto['id'] == $selected_depto_id) ? 'selected' : ''; ?>><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
</div>
</form>
</div>
</div>
<?php if ($selected_depto_id): ?>
<div class="card">
<div class="card-body">
<h5 class="card-title">Marque los bloques de tiempo disponibles</h5>
<p class="card-text">Seleccione las franjas horarias disponibles para el departamento seleccionado. Los cambios guardados se aplicarán solo a este departamento.</p>
<form action="horarios.php?id_departamento=<?php echo $selected_depto_id; ?>" method="POST">
<input type="hidden" name="id_departamento" value="<?php echo $selected_depto_id; ?>">
<div class="schedule-grid mb-3">
<div class="grid-header day-label">Día</div>
<?php foreach ($time_ranges as $range): ?>
<div class="grid-header"><?php echo str_replace('-', ' - ', $range); ?></div>
<?php endforeach; ?>
<?php foreach ($days_of_week as $day_num => $day_name): ?>
<div class="day-label"><?php echo $day_name; ?></div>
<?php foreach ($time_ranges as $range): ?>
<div class="slot-checkbox">
<input class="form--input" type="checkbox"
name="slots[<?php echo $day_num; ?>][<?php echo $range; ?>]"
<?php echo isset($active_slots[$day_num][$range]) ? 'checked' : ''; ?>>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
<div class="text-end">
<button type="submit" class="btn btn-primary">Guardar Horarios</button>
</div>
</form>
</div>
</div>
<?php else: ?>
<div class="alert alert-info">Por favor, seleccione un departamento para ver y gestionar sus horarios.</div>
<?php endif; ?>
</div>
<?php
require_once 'footer.php';
?>

204
index.php
View File

@ -1,38 +1,188 @@
<?php
require_once 'db/config.php';
require_once 'header.php';
// Fetch data for selectors
$conductores = [];
$departamentos = [];
try {
$pdo = db();
$conductores = $pdo->query("SELECT id, matricula, nombre FROM taxis ORDER BY nombre ASC")->fetchAll(PDO::FETCH_ASSOC);
$departamentos = $pdo->query("SELECT id, nombre FROM departamentos ORDER BY nombre ASC")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// Silently fail, selectors will be empty
}
?>
<div class="px-4 py-5 my-5 text-center">
<h1 class="display-5 fw-bold">Bienvenido a <?php echo htmlspecialchars(getenv('PROJECT_NAME') ?: 'Taxi HRM'); ?></h1>
<div class="col-lg-6 mx-auto">
<p class="lead mb-4"><?php echo htmlspecialchars(getenv('PROJECT_DESCRIPTION') ?: 'Una solución completa para la gestión de su negocio de taxis.'); ?></p>
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
<a href="drivers.php" class="btn btn-primary btn-lg px-4 gap-3">Gestionar Conductores</a>
<button type="button" class="btn btn-outline-secondary btn-lg px-4">Ver Reportes</button>
<style>
.dashboard-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
padding-top: 1rem;
}
.role-card {
background-color: #fff;
border-radius: 0.75rem;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
padding: 2rem;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.role-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(0,0,0,0.12);
}
.role-card-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid #eee;
padding-bottom: 1rem;
}
.role-card-header i {
font-size: 1.8rem;
color: #0d6efd;
}
.role-card-header h3 {
margin: 0;
font-weight: 600;
color: #343a40;
}
.role-card .form-select {
margin-bottom: 1rem;
}
.action-list {
list-style: none;
padding: 0;
margin: 0;
}
.action-list li a {
display: block;
padding: 0.75rem 1rem;
margin-bottom: 0.5rem;
background-color: #f8f9fa;
border-radius: 0.5rem;
text-decoration: none;
color: #495057;
font-weight: 500;
transition: background-color 0.2s ease, color 0.2s ease;
}
.action-list li a:hover {
background-color: #e9ecef;
color: #0d6efd;
}
.action-list li a i {
margin-right: 0.75rem;
width: 20px;
text-align: center;
}
.hidden-list {
display: none;
}
</style>
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard Interactivo</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Seleccione un rol para empezar</li>
</ol>
<div class="dashboard-container">
<!-- Administrador Card -->
<div class="role-card" id="admin-card">
<div class="role-card-header">
<i class="bi bi-shield-lock-fill"></i>
<h3>Administrador</h3>
</div>
<ul class="action-list">
<li><a href="drivers.php"><i class="bi bi-people-fill"></i>Conductores y Taxis</a></li>
<li><a href="departamentos.php"><i class="bi bi-building"></i>Departamentos</a></li>
<li><a href="documents.php"><i class="bi bi-file-earmark-text"></i>Documentos</a></li>
<li><a href="citas.php"><i class="bi bi-calendar-check"></i>Citas</a></li>
<li><a href="consultas.php"><i class="bi bi-question-circle"></i>Consultas</a></li>
<li><a href="horarios.php"><i class="bi bi-clock"></i>Horarios de Citas</a></li>
<li><a href="localizacion.php"><i class="bi bi-pin-map-fill"></i>Localizaciones de Taxis</a></li>
</ul>
</div>
<!-- Conductor Card -->
<div class="role-card" id="conductor-card">
<div class="role-card-header">
<i class="bi bi-person-badge-fill"></i>
<h3>Conductor</h3>
</div>
<select class="form-select" id="conductor-selector">
<option value="">Seleccione un conductor...</option>
<?php foreach ($conductores as $conductor): ?>
<option value="<?php echo $conductor['id']; ?>"><?php echo htmlspecialchars($conductor['nombre'] . ' (' . $conductor['matricula'] . ')'); ?></option>
<?php endforeach; ?>
</select>
<ul class="action-list hidden-list" id="conductor-actions">
<li><a href="#" data-url="drivers.php?action=edit&id="><i class="bi bi-person-lines-fill"></i>Mi Información</a></li>
<li><a href="#" data-url="documents.php?id_conductor="><i class="bi bi-file-earmark-text"></i>Mis Documentos</a></li>
<li><a href="#" data-url="citas.php?id_conductor="><i class="bi bi-calendar-check"></i>Mis Citas</a></li>
<li><a href="#" data-url="consultas.php?id_conductor="><i class="bi bi-question-circle"></i>Mis Consultas</a></li>
<li><a href="#" data-url="localizacion.php?action=show_history&id_taxi="><i class="bi bi-clock-history"></i>Mi Historial de Ubicaciones</a></li>
</ul>
</div>
<!-- Departamento Card -->
<div class="role-card" id="departamento-card">
<div class="role-card-header">
<i class="bi bi-diagram-3-fill"></i>
<h3>Departamento</h3>
</div>
<select class="form-select" id="departamento-selector">
<option value="">Seleccione un departamento...</option>
<?php foreach ($departamentos as $depto): ?>
<option value="<?php echo $depto['id']; ?>"><?php echo htmlspecialchars($depto['nombre']); ?></option>
<?php endforeach; ?>
</select>
<ul class="action-list hidden-list" id="departamento-actions">
<li><a href="#" data-url="departamentos.php?action=edit&id="><i class="bi bi-pencil-square"></i>Ver/Editar Departamento</a></li>
<li><a href="#" data-url="citas.php?id_departamento="><i class="bi bi-calendar-check"></i>Citas del Departamento</a></li>
<li><a href="#" data-url="consultas.php?id_departamento="><i class="bi bi-question-circle"></i>Consultas del Departamento</a></li>
<li><a href="#" data-url="horarios.php?id_departamento="><i class="bi bi-clock"></i>Horarios del Departamento</a></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-person-badge"></i> Conductores</h5>
<p class="card-text">Administre el personal de conducción, incluyendo sus perfiles, licencias y documentación.</p>
<a href="drivers.php" class="btn btn-primary">Ir a Conductores</a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-geo-alt-fill"></i> Mapa en Tiempo Real</h5>
<p class="card-text">Visualice la ubicación de toda su flota en tiempo real para una gestión eficiente. (Próximamente)</p>
<a href="#" class="btn btn-secondary disabled">Ir al Mapa</a>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const conductorSelector = document.getElementById('conductor-selector');
const conductorActions = document.getElementById('conductor-actions');
const departamentoSelector = document.getElementById('departamento-selector');
const departamentoActions = document.getElementById('departamento-actions');
conductorSelector.addEventListener('change', function() {
const conductorId = this.value;
if (conductorId) {
conductorActions.classList.remove('hidden-list');
conductorActions.querySelectorAll('a').forEach(link => {
const baseUrl = link.getAttribute('data-url');
link.href = baseUrl + conductorId;
});
} else {
conductorActions.classList.add('hidden-list');
}
});
departamentoSelector.addEventListener('change', function() {
const deptoId = this.value;
if (deptoId) {
departamentoActions.classList.remove('hidden-list');
departamentoActions.querySelectorAll('a').forEach(link => {
const baseUrl = link.getAttribute('data-url');
link.href = baseUrl + deptoId;
});
} else {
departamentoActions.classList.add('hidden-list');
}
});
});
</script>
<?php
require_once 'footer.php';

View File

@ -43,30 +43,21 @@ try {
}
}
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_localizacion'])) {
// Handle form submission for historical location
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_localizacion_historica'])) {
$id_taxi = $_POST['id_taxi'];
$latitud = $_POST['latitud'];
$longitud = $_POST['longitud'];
$fecha_registro = $_POST['fecha_registro'];
if (!empty($id_taxi) && is_numeric($latitud) && is_numeric($longitud)) {
$pdo->beginTransaction();
if (!empty($id_taxi) && is_numeric($latitud) && is_numeric($longitud) && !empty($fecha_registro)) {
try {
// Upsert (Update or Insert) the last known location
$stmt_upsert = $pdo->prepare(
"INSERT INTO localizacion_taxis (id_taxi, latitud, longitud) VALUES (?, ?, ?) " .
"ON DUPLICATE KEY UPDATE latitud = VALUES(latitud), longitud = VALUES(longitud)"
);
$stmt_upsert->execute([$id_taxi, $latitud, $longitud]);
// Insert into history with specific timestamp
$stmt_history = $pdo->prepare("INSERT INTO localizacion_historico (id_taxi, latitud, longitud, fecha_registro) VALUES (?, ?, ?, ?)");
$stmt_history->execute([$id_taxi, $latitud, $longitud, $fecha_registro]);
// Insert into history
$stmt_history = $pdo->prepare("INSERT INTO localizacion_historico (id_taxi, latitud, longitud) VALUES (?, ?, ?)");
$stmt_history->execute([$id_taxi, $latitud, $longitud]);
$pdo->commit();
echo '<div class="alert alert-success" role="alert">Localización actualizada con éxito.</div>';
echo '<div class="alert alert-success" role="alert">Ubicación histórica añadida con éxito.</div>';
} catch (Exception $e) {
$pdo->rollBack();
echo '<div class="alert alert-danger" role="alert">Error al guardar los datos: '. $e->getMessage() .'</div>';
}
} else {
@ -136,11 +127,12 @@ try {
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-taxi me-1"></i>
Añadir o Actualizar Localización
<i class="fas fa-plus me-1"></i>
Añadir Ubicación Histórica
</div>
<div class="card-body">
<form action="localizacion.php" method="POST">
<p class="small text-muted">Haz clic en un taxi del mapa para rellenar los datos o haz clic en el mapa para obtener coordenadas.</p>
<div class="form-floating mb-3">
<select class="form-select" id="selectTaxi" name="id_taxi" required>
<option value="">Seleccione un taxi</option>
@ -164,9 +156,13 @@ try {
</div>
</div>
</div>
<div class="form-floating mb-3">
<input class="form-control" id="inputFecha" type="datetime-local" name="fecha_registro" required />
<label for="inputFecha">Fecha y Hora</label>
</div>
<div class="mt-4 mb-0">
<div class="d-grid">
<button type="submit" name="add_localizacion" class="btn btn-primary btn-block">Actualizar Localización</button>
<button type="submit" name="add_localizacion_historica" class="btn btn-primary btn-block">Añadir a Historial</button>
</div>
</div>
</form>
@ -241,18 +237,31 @@ try {
const lat = parseFloat(taxi.latitud);
const lon = parseFloat(taxi.longitud);
const matricula = taxi.matricula;
const taxiId = taxi.id; // Asegúrate de que la API devuelve el ID del taxi
if (!isNaN(lat) && !isNaN(lon)) {
const popupContent = `<b>Taxi:</b> ${matricula}<br><b>Modelo:</b> ${taxi.modelo || 'N/A'}<br><b>Última vez:</b> ${taxi.ultima_actualizacion}`;
const latLng = [lat, lon];
let marker;
if (markers[matricula]) {
markers[matricula].setLatLng(latLng).setPopupContent(popupContent);
marker = markers[matricula].setLatLng(latLng).setPopupContent(popupContent);
} else {
markers[matricula] = L.marker(latLng, { icon: taxiIcon }).addTo(map)
marker = L.marker(latLng, { icon: taxiIcon }).addTo(map)
.bindPopup(popupContent);
markers[matricula] = marker;
}
// Extender los límites para el auto-zoom
marker.off('click').on('click', () => {
document.getElementById('selectTaxi').value = taxiId;
document.getElementById('inputLatitud').value = lat.toFixed(8);
document.getElementById('inputLongitud').value = lon.toFixed(8);
document.getElementById('inputFecha').value = new Date().toISOString().slice(0, 16);
// Scroll to the form for better UX
document.getElementById('selectTaxi').focus();
});
bounds.extend(latLng);
}
});
@ -271,6 +280,15 @@ try {
// Carga inicial
updateMap();
// Set current date and time for the historical form
document.getElementById('inputFecha').value = new Date().toISOString().slice(0, 16);
// Get coordinates on map click
map.on('click', function(e) {
document.getElementById('inputLatitud').value = e.latlng.lat.toFixed(8);
document.getElementById('inputLongitud').value = e.latlng.lng.toFixed(8);
});
// Lógica para el historial de rutas
let routePolyline = null;
document.getElementById('history-form').addEventListener('submit', function(e) {