243 lines
9.8 KiB
HTML
243 lines
9.8 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}{% trans %}Dashboard - Edu-Space Admin{% endtrans %}{% endblock %}
|
|
|
|
{% block content %}
|
|
{% if current_user.is_authenticated %}
|
|
<div class="container-fluid pt-5 mt-4">
|
|
{% endif %}
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h1 class="h3 mb-0">
|
|
<i class="bi bi-speedometer2 text-primary"></i> {% trans %}Dashboard{% endtrans %}
|
|
<small class="text-muted ms-2">{% trans %}Overview{% endtrans %}</small>
|
|
</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">{% trans %}Total Classrooms{% endtrans %}</h6>
|
|
<h2 class="mb-0">{{ stats.total_classrooms }}</h2>
|
|
</div>
|
|
<div class="bg-primary bg-opacity-10 rounded-circle p-3">
|
|
<i class="bi bi-door-open text-primary fs-4"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">{% trans %}Total Subjects{% endtrans %}</h6>
|
|
<h2 class="mb-0">{{ stats.total_subjects }}</h2>
|
|
</div>
|
|
<div class="bg-success bg-opacity-10 rounded-circle p-3">
|
|
<i class="bi bi-book text-success fs-4"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">{% trans %}Today's Reservations{% endtrans %}</h6>
|
|
<h2 class="mb-0">{{ stats.today_reservations }}</h2>
|
|
</div>
|
|
<div class="bg-info bg-opacity-10 rounded-circle p-3">
|
|
<i class="bi bi-calendar-today text-info fs-4"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">{% trans %}This Week{% endtrans %}</h6>
|
|
<h2 class="mb-0">{{ stats.week_reservations }}</h2>
|
|
</div>
|
|
<div class="bg-warning bg-opacity-10 rounded-circle p-3">
|
|
<i class="bi bi-calendar-week text-warning fs-4"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Monthly Chart -->
|
|
<div class="col-md-8 mb-4">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-graph-up text-primary"></i> Monthly Reservations
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="monthlyChart" height="100"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="col-md-4 mb-4">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-lightning text-warning"></i> Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<a href="{{ url_for('classrooms.add_classroom') }}" class="btn btn-outline-primary">
|
|
<i class="bi bi-plus-circle"></i> Add Classroom
|
|
</a>
|
|
<a href="{{ url_for('schedule.commissions_view') }}" class="btn btn-outline-warning">
|
|
<i class="bi bi-people"></i> Manage Commissions
|
|
</a>
|
|
<a href="{{ url_for('schedule.add_reservation') }}" class="btn btn-outline-success">
|
|
<i class="bi bi-calendar-plus"></i> New Reservation
|
|
</a>
|
|
<a href="{{ url_for('schedule.today_schedule') }}" class="btn btn-outline-info">
|
|
<i class="bi bi-calendar-today"></i> Today's Schedule
|
|
</a>
|
|
<a href="{{ url_for('genetic_algorithm_web.genetic_optimizer') }}" class="btn btn-info text-white">
|
|
<i class="bi bi-cpu"></i> AI Room Optimizer
|
|
</a>
|
|
<a href="{{ url_for('schedule.calendar_view') }}" class="btn btn-outline-secondary">
|
|
<i class="bi bi-calendar3"></i> View Calendar
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Upcoming Reservations -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white border-0">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-clock-history text-info"></i> Upcoming Reservations (Next 7 Days)
|
|
</h5>
|
|
<a href="{{ url_for('schedule.list_reservations') }}" class="btn btn-sm btn-outline-primary">
|
|
View All
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if upcoming_reservations %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Date & Time</th>
|
|
<th>Classroom</th>
|
|
<th>Subject</th>
|
|
<th>Teacher</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for reservation in upcoming_reservations %}
|
|
<tr>
|
|
<td>{{ reservation.start_time.strftime('%Y-%m-%d %H:%M') }}</td>
|
|
<td>{{ reservation.classroom.code }}</td>
|
|
<td>{{ reservation.commission.get_full_code() }}</td>
|
|
<td>{{ reservation.commission.teacher_name }}</td>
|
|
<td>
|
|
<span class="badge bg-{{ 'success' if reservation.status.value == 'CONFIRMED' else 'warning' }}">
|
|
{{ reservation.status.value }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<a href="{{ url_for('schedule.list_reservations') }}"
|
|
class="btn btn-sm btn-outline-primary">
|
|
<i class="bi bi-eye"></i> View
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<i class="bi bi-calendar-x text-muted" style="font-size: 3rem;"></i>
|
|
<p class="text-muted mt-3">No upcoming reservations in the next 7 days</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% if current_user.is_authenticated %}
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Fetch monthly data and create chart
|
|
$.get('/api/dashboard-stats')
|
|
.done(function(data) {
|
|
const ctx = document.getElementById('monthlyChart').getContext('2d');
|
|
new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: data.monthly_data.map(item => item.month),
|
|
datasets: [{
|
|
label: 'Reservations',
|
|
data: data.monthly_data.map(item => item.reservations),
|
|
borderColor: '#667eea',
|
|
backgroundColor: 'rgba(102, 126, 234, 0.1)',
|
|
borderWidth: 2,
|
|
fill: true,
|
|
tension: 0.4
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
stepSize: 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %} |