292 lines
14 KiB
HTML
292 lines
14 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Reservation Details - Edu-Space Admin{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid pt-5 mt-4">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h1 class="h3">
|
|
<i class="bi bi-calendar-check text-info"></i> Reservation Details
|
|
</h1>
|
|
<div class="d-flex gap-2">
|
|
{% if user.can_edit_reservation(reservation) %}
|
|
<a href="/schedule/edit_reservation?id={{ reservation.id }}" class="btn btn-warning">
|
|
<i class="bi bi-pencil-square me-1"></i>Modificar Reserva
|
|
</a>
|
|
{% endif %}
|
|
<a href="/schedule/list_reservations" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-left me-1"></i>Back to List
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Main Reservation Info -->
|
|
<div class="col-lg-8 mb-4">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header border-0 py-3">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-info-circle text-primary"></i> Reservation Information
|
|
</h5>
|
|
<span class="badge bg-{% if reservation.status.value == 'CONFIRMED' %}success{% elif reservation.status.value == 'PENDING' %}warning{% else %}secondary{% endif %}">
|
|
{{ reservation.status.value }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="text-muted small">Reservation ID</label>
|
|
<p class="mb-0"><strong>#{{ reservation.id }}</strong></p>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="text-muted small">Created by</label>
|
|
<p class="mb-0">
|
|
<i class="bi bi-person"></i>
|
|
{% if reservation.user %}
|
|
{{ reservation.user.first_name }} {{ reservation.user.last_name }}
|
|
{% else %}
|
|
Unknown
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="text-muted small">Date & Time</label>
|
|
<p class="mb-0">
|
|
<i class="bi bi-clock"></i>
|
|
{{ format_date(reservation.start_time, format='long')|capitalize }}<br>
|
|
{{ reservation.start_time }} - {{ reservation.end_time }}
|
|
</p>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="text-muted small">Duration</label>
|
|
<p class="mb-0">
|
|
<i class="bi bi-hourglass"></i>
|
|
{% set duration = reservation.duration or 120 %}
|
|
{{ (duration / 60) | round(1) }} hours
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if reservation.purpose %}
|
|
<div class="mb-3">
|
|
<label class="text-muted small">Purpose</label>
|
|
<p class="mb-0">{{ reservation.purpose }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if reservation.notes %}
|
|
<div class="mb-3">
|
|
<label class="text-muted small">Notes</label>
|
|
<p class="mb-0">{{ reservation.notes }}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Classroom Details -->
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header border-0 py-3 bg-body-tertiary">
|
|
<h5 class="mb-0 h6 fw-bold">
|
|
<i class="bi bi-geo-alt text-primary me-2"></i>Ubicación y Espacio Asignado
|
|
</h5>
|
|
</div>
|
|
<div class="card-body p-4">
|
|
{% if reservation.classroom %}
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-4">
|
|
<div class="p-3 rounded bg-body-tertiary border">
|
|
<small class="text-muted d-block mb-1">🏢 Edificio / Sede</small>
|
|
<h6 class="mb-0 fw-bold text-primary">{{ reservation.classroom.building_name }}</h6>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="p-3 rounded bg-body-tertiary border">
|
|
<small class="text-muted d-block mb-1">🪜 Piso / Nivel</small>
|
|
<h6 class="mb-0 fw-bold text-secondary">
|
|
{% if reservation.classroom.is_virtual %}
|
|
<span class="badge bg-primary-subtle text-primary border">Campus Virtual</span>
|
|
{% else %}
|
|
{{ reservation.classroom.floor_display }}
|
|
{% endif %}
|
|
</h6>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="p-3 rounded bg-body-tertiary border">
|
|
<small class="text-muted d-block mb-1">🚪 Aula</small>
|
|
<h6 class="mb-0 fw-bold text-success">{{ reservation.classroom.code }}</h6>
|
|
<small class="text-muted">Capacidad: <strong>{{ reservation.classroom.capacity_display }}</strong></small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if reservation.classroom.description %}
|
|
<div class="mt-2">
|
|
<label class="text-muted small">Descripción del Aula</label>
|
|
<p class="mb-0 small">{{ reservation.classroom.description }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Banner de Aula Virtual (Zoom, Meet, Teams) -->
|
|
{% if reservation.effective_virtual_link or (reservation.classroom and reservation.classroom.is_virtual) %}
|
|
<div class="mt-3 p-3 rounded bg-primary bg-opacity-10 border border-primary border-opacity-25 d-flex flex-column flex-sm-row justify-content-between align-items-sm-center gap-3">
|
|
<div>
|
|
<div class="fw-bold text-primary mb-1">
|
|
<i class="bi bi-camera-video me-1"></i>Aula Virtual / Videoconferencia
|
|
</div>
|
|
{% if reservation.effective_virtual_link %}
|
|
<small class="text-secondary text-break font-monospace d-block">{{ reservation.effective_virtual_link }}</small>
|
|
{% else %}
|
|
<small class="text-muted fst-italic">Modalidad remota sin enlace específico registrado</small>
|
|
{% endif %}
|
|
</div>
|
|
{% if reservation.effective_virtual_link %}
|
|
<a href="{{ reservation.effective_virtual_link }}" target="_blank" class="btn btn-success btn-sm px-3 text-nowrap">
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>Unirse a Clase (Zoom / Meet)
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<p class="text-muted mb-0">Classroom information not available</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Subject & Commission -->
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header border-0 py-3">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-book text-warning"></i> Subject & Commission
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if reservation.commission %}
|
|
<div class="mb-3">
|
|
<label class="text-muted small">Commission Code</label>
|
|
<p class="mb-0"><strong>{{ reservation.commission.get_full_code() }}</strong></p>
|
|
</div>
|
|
{% if reservation.commission.subject %}
|
|
<div class="mb-3">
|
|
<label class="text-muted small">Subject</label>
|
|
<p class="mb-0">{{ reservation.commission.subject.name }}</p>
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<p class="text-muted mb-0">No commission assigned</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attendees -->
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header border-0 py-3">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-people text-success"></i> Attendance
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="text-center">
|
|
<h3 class="mb-1">{{ reservation.expected_attendees }}</h3>
|
|
<p class="text-muted small">Expected Attendees</p>
|
|
{% if reservation.classroom %}
|
|
{% if reservation.classroom.capacity and reservation.classroom.capacity > 0 %}
|
|
<div class="progress mt-3" style="height: 8px;">
|
|
{% set percentage = (reservation.expected_attendees / reservation.classroom.capacity * 100) %}
|
|
<div class="progress-bar bg-{% if percentage > 90 %}danger{% elif percentage > 75 %}warning{% else %}success{% endif %}"
|
|
role="progressbar"
|
|
{{ ('style="width: ' ~ ([percentage|round(1), 100]|min|string) ~ '%;"') | safe }}></div>
|
|
</div>
|
|
<small class="text-muted">
|
|
{{ reservation.expected_attendees }} / {{ reservation.classroom.capacity }} capacidad
|
|
</small>
|
|
{% else %}
|
|
<div class="mt-2">
|
|
<span class="badge bg-primary-subtle text-primary border">
|
|
{% if reservation.classroom.is_virtual %}🌐 Campus Virtual (Sin límite físico){% else %}Capacidad no definida{% endif %}
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header border-0 py-3">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-gear text-secondary"></i> Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
{% if user.can_edit_reservation(reservation) %}
|
|
<a href="/schedule/edit_reservation?id={{ reservation.id }}" class="btn btn-warning">
|
|
<i class="bi bi-pencil-square me-1"></i>Modificar Reserva
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if reservation.status.value == 'PENDING' or reservation.status == 'PENDING' %}
|
|
<form method="POST" action="/schedule/confirm_reservation?id={{ reservation.id }}">
|
|
<input type="hidden" name="id" value="{{ reservation.id }}">
|
|
<button type="submit" class="btn btn-success" onclick="return confirm('¿Confirmar esta reserva?')">
|
|
<i class="bi bi-check-circle me-1"></i>Confirmar Reserva
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
|
|
{% if reservation.can_be_cancelled() %}
|
|
<form method="POST" action="/schedule/cancel_reservation?id={{ reservation.id }}">
|
|
<input type="hidden" name="id" value="{{ reservation.id }}">
|
|
<button type="submit" class="btn btn-danger" onclick="return confirm('¿Cancelar esta reserva?')">
|
|
<i class="bi bi-x-circle me-1"></i>Cancelar Reserva
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
|
|
<a href="/schedule/list_reservations" class="btn btn-outline-secondary">
|
|
<i class="bi bi-list"></i> View All Reservations
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Timestamps -->
|
|
<div class="row mt-4">
|
|
<div class="col-12">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="row text-muted small">
|
|
<div class="col-md-4">
|
|
<i class="bi bi-clock-history"></i>
|
|
Created: {{ reservation.created_at }}
|
|
</div>
|
|
{% if reservation.updated_at %}
|
|
<div class="col-md-4">
|
|
<i class="bi bi-arrow-repeat"></i>
|
|
Updated: {{ reservation.updated_at }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="col-md-4">
|
|
<i class="bi bi-info-square"></i>
|
|
Reservation ID: #{{ reservation.id }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %} |