542 lines
24 KiB
HTML
542 lines
24 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}User Dashboard{% endblock %}
|
|
<style>
|
|
/* Variables CSS para mayor flexibilidad */
|
|
:root {
|
|
--preview-text-font-size: 0.5rem; /* Ajusta este valor según necesites */
|
|
--dashboard-title-font-size: 1.5rem; /* Tamaño de títulos */
|
|
--dashboard-paragraph-font-size: 0.9rem; /* Tamaño de párrafos */
|
|
--table-font-size: 0.85rem; /* Tamaño de tablas */
|
|
}
|
|
|
|
/* Clase personalizada para la previsualización de texto */
|
|
#preview-text.custom-text-preview {
|
|
font-size: var(--preview-text-font-size) !important;
|
|
margin: 0 !important;
|
|
padding: 0 !important;
|
|
line-height: 1.2 !important;
|
|
white-space: pre-wrap !important;
|
|
word-wrap: break-word !important;
|
|
font-family: monospace !important;
|
|
}
|
|
|
|
/* Clases para otros elementos */
|
|
.custom-title {
|
|
font-size: var(--dashboard-title-font-size);
|
|
}
|
|
|
|
.custom-paragraph {
|
|
font-size: var(--dashboard-paragraph-font-size);
|
|
}
|
|
|
|
.custom-table {
|
|
font-size: var(--table-font-size);
|
|
}
|
|
</style>
|
|
{% block content %}
|
|
<body data-username="{{ current_user.username }}">
|
|
|
|
<div id="toast-container" class="position-fixed top-0 end-0 p-2" style="z-index: 1055;"></div>
|
|
<div id="image-preview" class="position-absolute z-1000 d-none" style="max-width: 160px; max-height: 90px;">
|
|
<img id="preview-image" style="width: 100%; height: 100%; object-fit: cover;" />
|
|
</div>
|
|
<div id="video-preview" class="position-absolute z-1000 d-none" style="width: 160px; height: 90px;">
|
|
<video id="preview-video" autoplay muted loop style="width: 100%; height: 100%; object-fit: cover;"></video>
|
|
</div>
|
|
<!-- Contenedor para Previsualización de Texto -->
|
|
<div id="text-preview" class="position-absolute z-1000 d-none p-1 border rounded" style="max-width: 160px; max-height: 90px; overflow-y: auto;">
|
|
<div id="preview-text" class="mb-0 custom-text-preview"></div>
|
|
</div>
|
|
<!-- Contenedor para Previsualización de PDF -->
|
|
<div id="pdf-preview" class="position-absolute z-1000 d-none" style="width: 160px; height: 90px;">
|
|
<canvas id="preview-pdf-canvas" style="width: 100%; height: 100%; border: none;"></canvas>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="container-fluid mt-3" style="max-width: 800px;">
|
|
<h3 class="mb-3 custom-title">Welcome, {{ user.username }}</h3>
|
|
|
|
<!-- Información del Perfil -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-info text-white p-2">
|
|
<h6 class="mb-0">User Profile</h6>
|
|
</div>
|
|
<div class="card-body p-2">
|
|
<p class="mb-1 custom-paragraph"><strong>Username:</strong> {{ user.username }}</p>
|
|
<p class="mb-1 custom-paragraph"><strong>Role:</strong> {{ user.role }}</p>
|
|
<!-- Botón para editar el perfil eliminado por requisitos legales -->
|
|
{# <a href="{{ url_for('edit_profile') }}" class="btn btn-primary btn-sm">Edit Profile</a> #}
|
|
</div>
|
|
</div>
|
|
<!-- Información de Almacenamiento -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-warning text-dark p-2">
|
|
<h6 class="mb-0">Storage Information</h6>
|
|
</div>
|
|
<div class="card-body p-2">
|
|
{% if storage_limit > 0 %}
|
|
<p class="mb-1 custom-paragraph"><strong>Storage Used:</strong> {{ storage_used }} MB</p>
|
|
<p class="mb-1 custom-paragraph"><strong>Storage Available:</strong> {{ storage_available }} MB</p>
|
|
<div class="progress mb-2" style="height: 10px;">
|
|
{% set usage_percent = (storage_used / storage_limit * 100) if storage_limit > 0 else 0 %}
|
|
{% set progress_class = 'bg-success' if usage_percent < 50 else 'bg-warning' if usage_percent < 80 else 'bg-danger' %}
|
|
<div class="progress-bar {{ progress_class }}" role="progressbar" style="width: {{ usage_percent }}%;" aria-valuenow="{{ storage_used }}" aria-valuemin="0" aria-valuemax="{{ storage_limit }}">
|
|
{{ usage_percent | round(1) }}%
|
|
</div>
|
|
</div>
|
|
{% if storage_available < (0.1 * storage_limit) %}
|
|
<div class="alert alert-danger p-1" role="alert">
|
|
You're running low on storage! Consider deleting some pastes or upgrading your account.
|
|
</div>
|
|
{% elif storage_available < (0.25 * storage_limit) %}
|
|
<div class="alert alert-warning p-1" role="alert">
|
|
You're approaching your storage limit.
|
|
</div>
|
|
{% endif %}
|
|
{% else %}
|
|
<p class="mb-1 custom-paragraph"><strong>Storage Used:</strong> {{ storage_used }} MB</p>
|
|
<p class="mb-1 custom-paragraph"><strong>Storage Available:</strong> Unlimited</p>
|
|
<div class="progress" style="height: 10px;">
|
|
<div class="progress-bar bg-success" role="progressbar" style="width: 100%;" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Botón para crear nuevo paste -->
|
|
<a href="{{ url_for('create_paste_web') }}" class="btn btn-success btn-sm mb-3">Create New Paste</a>
|
|
|
|
<!-- Formulario de Búsqueda Avanzada -->
|
|
<div class="mb-3">
|
|
<h5>Advanced Search</h5>
|
|
<form method="GET" action="{{ url_for('search_pastes_web') }}">
|
|
<div class="row g-2">
|
|
<!-- Primera fila: Campos de texto -->
|
|
<div class="col-md-4">
|
|
<label for="query" class="form-label">Keyword</label>
|
|
<input type="text" id="query" name="q" class="form-control form-control-sm" placeholder="Enter keyword">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="content_type" class="form-label">Content Type</label>
|
|
<select id="content_type" name="content_type" class="form-select form-select-sm">
|
|
<option value="">Any</option>
|
|
<option value="text">Text</option>
|
|
<option value="image">Image</option>
|
|
<option value="video">Video</option>
|
|
<option value="audio">Audio</option>
|
|
<option value="other">Other</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="language" class="form-label">Language</label>
|
|
<input type="text" id="language" name="language" class="form-control form-control-sm" placeholder="Enter language">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Segunda fila: Botón -->
|
|
<div class="row mt-2">
|
|
<div class="col-md-12 d-flex justify-content-end">
|
|
<button type="submit" class="btn btn-primary btn-sm">Search</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Estadísticas -->
|
|
<h5>Your Paste Statistics:</h5>
|
|
<ul class="list-unstyled mb-3 custom-paragraph" style="font-size: var(--dashboard-paragraph-font-size);">
|
|
<li><strong>Total Pastes:</strong> {{ total_pastes }}</li>
|
|
<li><strong>Total Size:</strong> {{ total_size }} bytes</li>
|
|
</ul>
|
|
|
|
<!-- Filtro por fechas -->
|
|
<form method="GET" action="{{ url_for('user_stats', username=user.username) }}" class="row g-2 mb-3">
|
|
<div class="col-md-4">
|
|
<label for="start_date" class="form-label">Start Date:</label>
|
|
<input type="date" id="start_date" name="start_date" class="form-control form-control-sm" value="{{ start_date }}">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="end_date" class="form-label">End Date:</label>
|
|
<input type="date" id="end_date" name="end_date" class="form-control form-control-sm" value="{{ end_date }}">
|
|
</div>
|
|
<div class="col-md-4 d-flex align-items-end">
|
|
<button type="submit" class="btn btn-primary btn-sm w-100">Filter</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Metrics Cards -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-primary mb-2 custom-table">
|
|
<div class="card-header p-2">Total Pastes</div>
|
|
<div class="card-body p-2">
|
|
<h6 id="total-pastes" class="card-title mb-0">{{ total_pastes }}</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-success mb-2 custom-table">
|
|
<div class="card-header p-2">Text Pastes</div>
|
|
<div class="card-body p-2">
|
|
<h6 id="total-text-pastes" class="card-title mb-0">{{ total_text_pastes }}</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-info mb-2 custom-table">
|
|
<div class="card-header p-2">File Pastes</div>
|
|
<div class="card-body p-2">
|
|
<h6 id="total-file-pastes" class="card-title mb-0">{{ total_file_pastes }}</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-white bg-warning mb-2 custom-table">
|
|
<div class="card-header p-2">Media Pastes</div>
|
|
<div class="card-body p-2">
|
|
<h6 id="total-media-pastes" class="card-title mb-0">{{ total_media_pastes }}</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Chart de lenguajes -->
|
|
<div class="row mb-3">
|
|
<div class="col-12">
|
|
<h5 class="mb-2">Pastes by Language and Type</h5>
|
|
<canvas id="languageTypeChart" style="max-height: 200px;"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabs para My Pastes, Favorites y Shared -->
|
|
<ul class="nav nav-tabs" id="dashboardTabs" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active" id="my-pastes-tab"
|
|
data-bs-toggle="tab" data-bs-target="#my-pastes"
|
|
type="button" role="tab" aria-controls="my-pastes"
|
|
aria-selected="true">
|
|
My Pastes
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="favorites-tab"
|
|
data-bs-toggle="tab" data-bs-target="#favorites"
|
|
type="button" role="tab" aria-controls="favorites"
|
|
aria-selected="false">
|
|
Favorites
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="shared-tab"
|
|
data-bs-toggle="tab" data-bs-target="#shared"
|
|
type="button" role="tab" aria-controls="shared"
|
|
aria-selected="false">
|
|
Shared
|
|
</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="private-pastes-tab"
|
|
data-bs-toggle="tab" data-bs-target="#private-pastes"
|
|
type="button" role="tab" aria-controls="private-pastes"
|
|
aria-selected="false">
|
|
Private Pastes
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content mt-2" id="dashboardTabsContent">
|
|
<!-- My Pastes -->
|
|
<div class="tab-pane fade show active" id="my-pastes" role="tabpanel" aria-labelledby="my-pastes-tab">
|
|
<h5>Your Pastes</h5>
|
|
{% if pastes|length > 0 %}
|
|
<table class="table table-bordered table-striped table-sm custom-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Filename</th>
|
|
<th>Type</th>
|
|
<th>Size (bytes)</th>
|
|
<th>Created At</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for paste in pastes %}
|
|
<tr id="paste-{{ paste.id }}">
|
|
<td>{{ paste.id }}</td>
|
|
<td>
|
|
<a href="{{ url_for('paste_settings', paste_id=paste.id) }}">
|
|
paste_{{ paste.id }}.{{ paste.get_extension() }}
|
|
</a>
|
|
</td>
|
|
|
|
<td>{{ paste.get_type() }}</td>
|
|
<td>{{ paste.size }}</td>
|
|
<td>{{ paste.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
|
<td>
|
|
<a href="{{ url_for('get_paste', id=paste.id) }}"
|
|
class="btn btn-sm btn-secondary view-btn"
|
|
data-url="{{ url_for('serve_media', id=paste.id) }}"
|
|
data-type="{{ paste.content_type }}">
|
|
View
|
|
</a>
|
|
<button class="btn btn-sm btn-danger delete-paste"
|
|
data-id="{{ paste.id }}">Delete</button>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<p>You do not have any pastes yet.</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Nueva pestaña: Private Pastes -->
|
|
<div class="tab-pane fade" id="private-pastes" role="tabpanel" aria-labelledby="private-pastes-tab">
|
|
<h5>Your Private Pastes</h5>
|
|
{% if private_pastes.items %}
|
|
<table class="table table-bordered table-striped table-sm custom-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Filename</th>
|
|
<th>Type</th>
|
|
<th>Size (bytes)</th>
|
|
<th>Created At</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for paste in private_pastes.items %}
|
|
<tr id="paste-{{ paste.id }}">
|
|
<td>{{ paste.id }}</td>
|
|
<td>paste_{{ paste.id }}.{{ paste.get_extension() }}</td>
|
|
|
|
<td>{{ paste.get_type() }}</td>
|
|
<td>{{ paste.size }}</td>
|
|
<td>{{ paste.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
|
<td>
|
|
<a href="{{ url_for('get_paste', id=paste.id) }}"
|
|
class="btn btn-sm btn-secondary view-btn"
|
|
data-url="{{ url_for('serve_media', id=paste.id) }}"
|
|
data-type="{{ paste.content_type }}">
|
|
View
|
|
</a>
|
|
<button class="btn btn-sm btn-danger delete-paste"
|
|
data-id="{{ paste.id }}">Delete</button>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<!-- Paginación Private Pastes -->
|
|
{% if private_pastes.pages > 1 %}
|
|
<nav aria-label="Private Pastes pagination">
|
|
<ul class="pagination justify-content-center">
|
|
{% if private_pastes.has_prev %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', private_page=private_pastes.prev_num) }}" aria-label="Previous">
|
|
<span aria-hidden="true">«</span>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% for page_num in private_pastes.iter_pages(left_edge=2, right_edge=2, left_current=1, right_current=1) %}
|
|
{% if page_num %}
|
|
{% if page_num == private_pastes.page %}
|
|
<li class="page-item active"><span class="page-link">{{ page_num }}</span></li>
|
|
{% else %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', private_page=page_num) }}">
|
|
{{ page_num }}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% else %}
|
|
<li class="page-item disabled"><span class="page-link">…</span></li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if private_pastes.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', private_page=private_pastes.next_num) }}" aria-label="Next">
|
|
<span aria-hidden="true">»</span>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<p>You do not have any private pastes yet.</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
|
|
<!-- Favorites -->
|
|
<div class="tab-pane fade" id="favorites"
|
|
role="tabpanel" aria-labelledby="favorites-tab">
|
|
<h5>Your Favorites</h5>
|
|
{% if favorite_pastes %}
|
|
<table class="table table-bordered table-striped table-sm custom-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Filename</th>
|
|
<th>Type</th>
|
|
<th>Size (bytes)</th>
|
|
<th>Created At</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="favorites-body">
|
|
{% for fav in favorite_pastes %}
|
|
<tr id="favorite-{{ fav.id }}">
|
|
<td>{{ fav.id }}</td>
|
|
<td>{{ fav.filename if fav.filename else "Paste " ~ fav.id }}</td>
|
|
<td>{{ fav.get_type() }}</td>
|
|
<td>{{ fav.size }}</td>
|
|
<td>{{ fav.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
|
<td>
|
|
<a href="{{ url_for('get_paste', id=fav.id) }}"
|
|
class="btn btn-sm btn-secondary view-btn"
|
|
data-url="{{ url_for('serve_media', id=fav.id) }}"
|
|
data-type="{{ fav.content_type }}">
|
|
View
|
|
</a>
|
|
<button class="btn btn-sm btn-danger unfavorite-btn" data-id="{{ fav.id }}">
|
|
Unfavorite
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
|
|
</table>
|
|
<!-- Paginación Favorites -->
|
|
{% if favorite_pagination.pages > 1 %}
|
|
<nav aria-label="Favorites pagination">
|
|
<ul class="pagination justify-content-center">
|
|
{% if favorite_pagination.has_prev %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', favorite_page=favorite_pagination.prev_num) }}" aria-label="Previous">
|
|
<span aria-hidden="true">«</span>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% for page_num in favorite_pagination.iter_pages(left_edge=2, right_edge=2, left_current=1, right_current=1) %}
|
|
{% if page_num %}
|
|
{% if page_num == favorite_pagination.page %}
|
|
<li class="page-item active"><span class="page-link">{{ page_num }}</span></li>
|
|
{% else %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', favorite_page=page_num) }}">
|
|
{{ page_num }}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% else %}
|
|
<li class="page-item disabled"><span class="page-link">…</span></li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if favorite_pagination.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="{{ url_for('user_dashboard', favorite_page=favorite_pagination.next_num) }}" aria-label="Next">
|
|
<span aria-hidden="true">»</span>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<p>You don't have any favorites yet.</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Shared Pastes -->
|
|
<div class="tab-pane fade" id="shared"
|
|
role="tabpanel" aria-labelledby="shared-tab">
|
|
<h5>Shared Pastes</h5>
|
|
{% if shared_pastes %}
|
|
<table class="table table-bordered table-striped table-sm custom-table">
|
|
<thead class="table-dark">
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Title</th>
|
|
<th>Owner</th>
|
|
<th>Type</th>
|
|
<th>Size (bytes)</th>
|
|
<th>Created At</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for sp in shared_pastes %}
|
|
<tr id="shared-paste-{{ sp.id }}">
|
|
<td>{{ sp.id }}</td>
|
|
<td>{{ sp.title or "Untitled" }}</td>
|
|
<td>{{ sp.owner.username }}</td>
|
|
<td>{{ sp.get_type() }}</td>
|
|
<td>{{ sp.size }}</td>
|
|
<td>{{ sp.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
|
<td>
|
|
<a href="{{ url_for('get_paste', id=sp.id) }}"
|
|
class="btn btn-sm btn-secondary view-btn"
|
|
data-url="{{ url_for('serve_media', id=sp.id) }}"
|
|
data-type="{{ sp.content_type }}">
|
|
View
|
|
</a>
|
|
|
|
{% if sp.has_edit_permission(current_user) %}
|
|
<a href="{{ url_for('edit_paste_web', id=sp.id) }}"
|
|
class="btn btn-sm btn-warning">Edit</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<!-- Paginación Shared (si es necesario) -->
|
|
{% if shared_pastes|length > 10 %}
|
|
<nav aria-label="Shared Pastes pagination">
|
|
<ul class="pagination justify-content-center">
|
|
<!-- Implementa la paginación similar a las secciones anteriores si es necesario -->
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<p>You don't have any shared pastes yet.</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="mt-4">Account Settings</h5>
|
|
<ul class="list-unstyled">
|
|
<li><a href="{{ url_for('change_password_form') }}" class="btn btn-secondary btn-sm">Change Password</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
<!-- JSON Data Embed -->
|
|
<script type="application/json" id="language-data">{{ languages | tojson | safe }}</script>
|
|
<script type="application/json" id="text-counts">{{ counts_text | tojson | safe }}</script>
|
|
<script type="application/json" id="file-counts">{{ counts_file | tojson | safe }}</script>
|
|
<script type="application/json" id="media-counts">{{ counts_media | tojson | safe }}</script>
|
|
|
|
<!-- Scripts Externos -->
|
|
<script src="https://cdn.priet.us/cdn/js/chart.js"></script>
|
|
<script src="https://cdn.priet.us/cdn/js/pdf.min.js"></script>
|
|
<script src="{{ url_for('static', filename='js/user_dashboard/toasts.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/user_dashboard/charts.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/user_dashboard/previews.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/user_dashboard/actions.js') }}"></script>
|
|
|
|
{% endblock %}
|
|
{% block footer %}
|
|
{{ super() }} <!-- Esto conserva el contenido original del footer definido en base.html -->
|
|
{% endblock %}
|