diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index 3c7a3b2..ba276ec 100644 Binary files a/__pycache__/models.cpython-313.pyc and b/__pycache__/models.cpython-313.pyc differ diff --git a/migrations/versions/9faab7ef6036_add_site_settings_table.py b/migrations/versions/9faab7ef6036_add_site_settings_table.py new file mode 100644 index 0000000..3e18a7c --- /dev/null +++ b/migrations/versions/9faab7ef6036_add_site_settings_table.py @@ -0,0 +1,42 @@ +"""Add site_settings table + +Revision ID: 9faab7ef6036 +Revises: ca9026520dad +Create Date: 2025-05-25 21:16:39.683736 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '9faab7ef6036' +down_revision = 'ca9026520dad' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('site_settings', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('primary_color', sa.String(length=7), nullable=True), + sa.Column('secondary_color', sa.String(length=7), nullable=True), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.drop_table('color_settings') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('color_settings', + sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column('primary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True), + sa.Column('secondary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True), + sa.Column('updated_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint('id', name=op.f('color_settings_pkey')) + ) + op.drop_table('site_settings') + # ### end Alembic commands ### diff --git a/migrations/versions/__pycache__/9faab7ef6036_add_site_settings_table.cpython-313.pyc b/migrations/versions/__pycache__/9faab7ef6036_add_site_settings_table.cpython-313.pyc new file mode 100644 index 0000000..c51223a Binary files /dev/null and b/migrations/versions/__pycache__/9faab7ef6036_add_site_settings_table.cpython-313.pyc differ diff --git a/models.py b/models.py index 218ae2b..99d45d1 100644 --- a/models.py +++ b/models.py @@ -124,4 +124,19 @@ class TrashedFile(db.Model): deleter = db.relationship('User', foreign_keys=[deleted_by], backref='deleted_trashed_files') # Changed from deleted_files to deleted_trashed_files def __repr__(self): - return f'' \ No newline at end of file + return f'' + +class SiteSettings(db.Model): + id = db.Column(db.Integer, primary_key=True) + primary_color = db.Column(db.String(7), default='#16767b') # Default from colors.css + secondary_color = db.Column(db.String(7), default='#741b5f') # Default from colors.css + updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + + @classmethod + def get_settings(cls): + settings = cls.query.first() + if not settings: + settings = cls() + db.session.add(settings) + db.session.commit() + return settings \ No newline at end of file diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index 56299ee..0b8cc23 100644 Binary files a/routes/__pycache__/main.cpython-313.pyc and b/routes/__pycache__/main.cpython-313.pyc differ diff --git a/routes/main.py b/routes/main.py index 48ddd45..d7773bb 100644 --- a/routes/main.py +++ b/routes/main.py @@ -1,6 +1,6 @@ -from flask import render_template, Blueprint, redirect, url_for, request, flash +from flask import render_template, Blueprint, redirect, url_for, request, flash, Response from flask_login import current_user, login_required -from models import User, db, Room, RoomFile, RoomMemberPermission +from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings import os from werkzeug.utils import secure_filename from sqlalchemy import func, case, literal_column, text @@ -326,4 +326,128 @@ def init_routes(main_bp): @main_bp.route('/settings') @login_required def settings(): - return render_template('settings/settings.html') \ No newline at end of file + if not current_user.is_admin: + flash('Only administrators can access settings.', 'error') + return redirect(url_for('main.dashboard')) + + site_settings = SiteSettings.get_settings() + return render_template('settings/settings.html', + primary_color=site_settings.primary_color, + secondary_color=site_settings.secondary_color) + + @main_bp.route('/settings/colors', methods=['POST']) + @login_required + def update_colors(): + if not current_user.is_admin: + flash('Only administrators can update settings.', 'error') + return redirect(url_for('main.dashboard')) + + primary_color = request.form.get('primary_color') + secondary_color = request.form.get('secondary_color') + + if not primary_color or not secondary_color: + flash('Both primary and secondary colors are required.', 'error') + return redirect(url_for('main.settings')) + + site_settings = SiteSettings.get_settings() + site_settings.primary_color = primary_color + site_settings.secondary_color = secondary_color + + try: + db.session.commit() + flash('Color settings updated successfully!', 'success') + except Exception as e: + db.session.rollback() + flash('An error occurred while updating color settings.', 'error') + + return redirect(url_for('main.settings')) + + @main_bp.route('/settings/colors/reset', methods=['POST']) + @login_required + def reset_colors(): + if not current_user.is_admin: + flash('Only administrators can update settings.', 'error') + return redirect(url_for('main.dashboard')) + + site_settings = SiteSettings.get_settings() + site_settings.primary_color = '#16767b' # Default from colors.css + site_settings.secondary_color = '#741b5f' # Default from colors.css + + try: + db.session.commit() + flash('Colors reset to defaults successfully!', 'success') + except Exception as e: + db.session.rollback() + flash('An error occurred while resetting colors.', 'error') + + return redirect(url_for('main.settings')) + + @main_bp.route('/dynamic-colors.css') + def dynamic_colors(): + site_settings = SiteSettings.get_settings() + + # Calculate derived colors + def hex_to_rgb(hex_color): + hex_color = hex_color.lstrip('#') + return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) + + def rgb_to_hex(rgb): + return '#{:02x}{:02x}{:02x}'.format(rgb[0], rgb[1], rgb[2]) + + def lighten_color(hex_color, amount): + rgb = hex_to_rgb(hex_color) + return rgb_to_hex(tuple(min(255, int(c + (255 - c) * amount)) for c in rgb)) + + # Calculate all color variants + primary_light = lighten_color(site_settings.primary_color, 0.15) + primary_bg_light = lighten_color(site_settings.primary_color, 0.9) + primary_opacity_15 = site_settings.primary_color + '26' + + secondary_light = lighten_color(site_settings.secondary_color, 0.15) + secondary_bg_light = lighten_color(site_settings.secondary_color, 0.9) + secondary_opacity_15 = site_settings.secondary_color + '26' + + # Calculate chart colors + primary_chart_light = lighten_color(site_settings.primary_color, 0.2) + primary_chart_lighter = lighten_color(site_settings.primary_color, 0.4) + primary_chart_lightest = lighten_color(site_settings.primary_color, 0.6) + primary_chart_pale = lighten_color(site_settings.primary_color, 0.8) + + secondary_chart_light = lighten_color(site_settings.secondary_color, 0.2) + secondary_chart_lighter = lighten_color(site_settings.secondary_color, 0.4) + secondary_chart_lightest = lighten_color(site_settings.secondary_color, 0.6) + secondary_chart_pale = lighten_color(site_settings.secondary_color, 0.8) + + css = f""" + :root {{ + /* Primary Colors */ + --primary-color: {site_settings.primary_color}; + --primary-light: {primary_light}; + --primary-bg-light: {primary_bg_light}; + --primary-opacity-15: {primary_opacity_15}; + + /* Secondary Colors */ + --secondary-color: {site_settings.secondary_color}; + --secondary-light: {secondary_light}; + --secondary-bg-light: {secondary_bg_light}; + --secondary-opacity-15: {secondary_opacity_15}; + + /* Chart Colors */ + --chart-primary: {site_settings.primary_color}; + --chart-secondary: {site_settings.secondary_color}; + --chart-warning: #ffd700; + + /* Primary Chart Colors */ + --chart-primary-light: {primary_chart_light}; + --chart-primary-lighter: {primary_chart_lighter}; + --chart-primary-lightest: {primary_chart_lightest}; + --chart-primary-pale: {primary_chart_pale}; + + /* Secondary Chart Colors */ + --chart-secondary-light: {secondary_chart_light}; + --chart-secondary-lighter: {secondary_chart_lighter}; + --chart-secondary-lightest: {secondary_chart_lightest}; + --chart-secondary-pale: {secondary_chart_pale}; + }} + """ + return Response(css, mimetype='text/css') \ No newline at end of file diff --git a/static/css/room_members.css b/static/css/room_members.css index 83add9d..2e68e76 100644 --- a/static/css/room_members.css +++ b/static/css/room_members.css @@ -39,9 +39,9 @@ height: 32px; border-radius: 5px; padding: 0 18px; - background-color: rgba(22,118,123,0.08); - color: #16767b; - border: 1px solid #16767b22; + background-color: var(--primary-opacity-8); + color: var(--primary-color); + border: 1px solid var(--primary-opacity-15); } .btn-save-member { diff --git a/static/css/starred.css b/static/css/starred.css index 16af55d..9f4ebcc 100644 --- a/static/css/starred.css +++ b/static/css/starred.css @@ -1,11 +1,11 @@ .btn-group .btn.active { - background-color: #e6f3f4 !important; - border-color: #16767b !important; - color: #16767b !important; + background-color: var(--primary-bg-light) !important; + border-color: var(--primary-color) !important; + color: var(--primary-color) !important; } .btn-group .btn:not(.active) { - background-color: #fff !important; - border-color: #e9ecef !important; - color: #6c757d !important; + background-color: var(--white) !important; + border-color: var(--border-light) !important; + color: var(--text-muted) !important; } \ No newline at end of file diff --git a/static/js/file-grid.js b/static/js/file-grid.js index b94116c..b54fd58 100644 --- a/static/js/file-grid.js +++ b/static/js/file-grid.js @@ -126,8 +126,8 @@ function renderFiles(files) { `; files.forEach((file, idx) => { let icon = file.type === 'folder' - ? `` - : ``; + ? `` + : ``; let size = file.size !== '-' ? (file.size > 0 ? (file.size < 1024*1024 ? (file.size/1024).toFixed(1)+' KB' : (file.size/1024/1024).toFixed(2)+' MB') : '0 KB') : '-'; let actionsArr = []; let dblClickAction = ''; @@ -138,16 +138,16 @@ function renderFiles(files) { } if (isTrashPage) { - actionsArr.push(``); - actionsArr.push(``); + actionsArr.push(``); + actionsArr.push(``); } else { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); const actions = actionsArr.join(''); table += ` ${icon} - + ${file.name} ${formatDate(file.modified)} ${file.type} @@ -161,8 +161,8 @@ function renderFiles(files) { } else { files.forEach((file, idx) => { let icon = file.type === 'folder' - ? `` - : ``; + ? `` + : ``; let size = file.size !== '-' ? (file.size > 0 ? (file.size < 1024*1024 ? (file.size/1024).toFixed(1)+' KB' : (file.size/1024/1024).toFixed(2)+' MB') : '0 KB') : '-'; let actionsArr = []; let dblClickAction = ''; @@ -173,12 +173,12 @@ function renderFiles(files) { } if (isTrashPage) { - actionsArr.push(``); - actionsArr.push(``); + actionsArr.push(``); + actionsArr.push(``); } else { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); const actions = actionsArr.join(''); grid.innerHTML += `
@@ -189,7 +189,7 @@ function renderFiles(files) {
${formatDate(file.modified)}
${size}
${isTrashPage ? `
Auto Delete: ${file.auto_delete ? formatDate(file.auto_delete) : 'Never'}
` : ''} -
+
@@ -428,8 +428,8 @@ function emptyTrash() { function showDetailsModal(idx) { const item = currentFiles[idx]; const icon = item.type === 'folder' - ? `` - : ``; + ? `` + : ``; const uploaderPic = item.uploader_profile_pic ? `/uploads/profile_pics/${item.uploader_profile_pic}` : '/static/default-avatar.png'; @@ -446,12 +446,12 @@ function showDetailsModal(idx) { ${item.uploaded_by || '-'}
${formatDate(item.modified)}
-
-
Room:
-
Path: ${(item.path ? item.path + '/' : '') + item.name}
-
Size: ${item.size === '-' ? '-' : (item.size > 0 ? (item.size < 1024*1024 ? (item.size/1024).toFixed(1)+' KB' : (item.size/1024/1024).toFixed(2)+' MB') : '0 KB')}
-
Uploaded at: ${item.uploaded_at ? new Date(item.uploaded_at).toLocaleString() : '-'}
- ${isTrashPage ? `
Auto Delete: ${item.auto_delete ? formatDate(item.auto_delete) : 'Never'}
` : ''} +
+
Room:
+
Path: ${(item.path ? item.path + '/' : '') + item.name}
+
Size: ${item.size === '-' ? '-' : (item.size > 0 ? (item.size < 1024*1024 ? (item.size/1024).toFixed(1)+' KB' : (item.size/1024/1024).toFixed(2)+' MB') : '0 KB')}
+
Uploaded at: ${item.uploaded_at ? new Date(item.uploaded_at).toLocaleString() : '-'}
+ ${isTrashPage ? `
Auto Delete: ${item.auto_delete ? formatDate(item.auto_delete) : 'Never'}
` : ''} `; document.getElementById('detailsModalBody').innerHTML = detailsHtml; var modal = new bootstrap.Modal(document.getElementById('detailsModal')); diff --git a/templates/common/base.html b/templates/common/base.html index 9b8281e..c0f00bd 100644 --- a/templates/common/base.html +++ b/templates/common/base.html @@ -10,6 +10,8 @@ + + {% block extra_css %}{% endblock %} diff --git a/templates/components/header.html b/templates/components/header.html index f17118e..884cf01 100644 --- a/templates/components/header.html +++ b/templates/components/header.html @@ -4,7 +4,7 @@

- + {{ title }}

{% if description %} @@ -16,7 +16,7 @@ {% if button_url == "#" %}
@@ -132,14 +132,14 @@
+ style="background-color: var(--primary-opacity-8); color: var(--primary-color);"> {{ user.email }} {% if user.phone %} + style="background-color: var(--primary-opacity-8); color: var(--primary-color);"> {{ user.phone }} @@ -182,7 +182,7 @@
+ style="background-color: var(--primary-opacity-8); color: var(--primary-color);"> Edit diff --git a/templates/dashboard/dashboard.html b/templates/dashboard/dashboard.html index f965cc0..c351d95 100644 --- a/templates/dashboard/dashboard.html +++ b/templates/dashboard/dashboard.html @@ -5,6 +5,7 @@ {% block extra_css %} + {% endblock %} {% block content %} diff --git a/templates/rooms/room.html b/templates/rooms/room.html index c31dfcc..1c97700 100644 --- a/templates/rooms/room.html +++ b/templates/rooms/room.html @@ -31,28 +31,28 @@
{% if current_user.is_admin %} - + Manage Members {% endif %} {% if current_user.is_admin or can_upload %} -
-
{% endif %} {% if current_user.is_admin or can_download %} - {% endif %} {% if current_user.is_admin or can_delete %} - {% endif %} @@ -60,8 +60,8 @@
@@ -191,8 +191,8 @@
@@ -217,7 +217,7 @@ @@ -270,22 +270,22 @@ #fileGrid.list-view table { width: 100%; border-collapse: collapse; - background: #fff; + background: var(--white); } #fileGrid.list-view th, #fileGrid.list-view td { padding: 0.5rem 1rem; - border-bottom: 1px solid #e9ecef; + border-bottom: 1px solid var(--border-light); text-align: left; font-size: 0.95rem; vertical-align: middle; } #fileGrid.list-view th { - background: #f8f9fa; - color: #6c757d; + background: var(--bg-color); + color: var(--text-muted); font-weight: 500; } #fileGrid.list-view tr:hover td { - background-color: rgba(22, 118, 123, 0.08); + background-color: var(--primary-opacity-8); transition: background 0.15s; } #fileGrid.list-view .file-icon { @@ -308,31 +308,31 @@ display: grid; grid-template-columns: 40px 2fr 1fr 1fr 1fr; padding: 0.5rem 1rem; - background-color: #f8f9fa; - border-bottom: 1px solid #e9ecef; - color: #6c757d; + background-color: var(--bg-color); + border-bottom: 1px solid var(--border-light); + color: var(--text-muted); font-size: 0.875rem; font-weight: 500; margin-bottom: 0.5rem; } .btn-group.btn-group-sm .btn { - background-color: #fff; - border-color: #e9ecef; - color: #6c757d; + background-color: var(--white); + border-color: var(--border-light); + color: var(--text-muted); transition: background-color 0.15s, color 0.15s; } .btn-group.btn-group-sm .btn.active, .btn-group.btn-group-sm .btn:active { - background-color: #e6f3f4 !important; - color: #16767b !important; - border-color: #16767b !important; + background-color: var(--primary-bg-light) !important; + color: var(--primary-color) !important; + border-color: var(--primary-color) !important; box-shadow: none; } .btn-group.btn-group-sm .btn:focus { - box-shadow: 0 0 0 0.1rem #16767b33; + box-shadow: 0 0 0 0.1rem var(--primary-opacity-20); } .btn-group.btn-group-sm .btn:hover:not(.active) { - background-color: #f8f9fa; - color: #16767b; + background-color: var(--bg-color); + color: var(--primary-color); } #fileGrid.table-mode { padding: 0; @@ -340,22 +340,22 @@ #fileGrid.table-mode table { width: 100%; border-collapse: collapse; - background: #fff; + background: var(--white); } #fileGrid.table-mode th, #fileGrid.table-mode td { padding: 0.5rem 1rem; - border-bottom: 1px solid #e9ecef; + border-bottom: 1px solid var(--border-light); text-align: left; font-size: 0.95rem; vertical-align: middle; } #fileGrid.table-mode th { - background: #f8f9fa; - color: #6c757d; + background: var(--bg-color); + color: var(--text-muted); font-weight: 500; } #fileGrid.table-mode tr:hover td { - background-color: rgba(22, 118, 123, 0.08); + background-color: var(--primary-opacity-8); transition: background 0.15s; } #fileGrid.table-mode .file-icon { @@ -374,6 +374,9 @@ font-size: 0.875rem; margin-left: 0.25rem; } +#fileGrid.table-mode tr.selected { + background-color: var(--primary-bg-light) !important; +} /* Disable text selection for file grid and table rows/cards */ #fileGrid, #fileGrid * { user-select: none; @@ -490,8 +493,8 @@ function showDetailsModal(idx) { } const icon = item.type === 'folder' - ? `` - : ``; + ? `` + : ``; const uploaderPic = item.uploader_profile_pic ? `/uploads/profile_pics/${item.uploader_profile_pic}` : '/static/default-avatar.png'; @@ -513,11 +516,11 @@ function showDetailsModal(idx) { ${item.uploaded_by || '-'}
${formatDate(item.modified)}
-
-
Room:
-
Path: ${(item.path ? item.path + '/' : '') + item.name}
-
Size: ${item.size === '-' ? '-' : (item.size > 0 ? (item.size < 1024*1024 ? (item.size/1024).toFixed(1)+' KB' : (item.size/1024/1024).toFixed(2)+' MB') : '0 KB')}
-
Uploaded at: ${item.uploaded_at ? new Date(item.uploaded_at).toLocaleString() : '-'}
+
+
Room:
+
Path: ${(item.path ? item.path + '/' : '') + item.name}
+
Size: ${item.size === '-' ? '-' : (item.size > 0 ? (item.size < 1024*1024 ? (item.size/1024).toFixed(1)+' KB' : (item.size/1024/1024).toFixed(2)+' MB') : '0 KB')}
+
Uploaded at: ${item.uploaded_at ? new Date(item.uploaded_at).toLocaleString() : '-'}
`; document.getElementById('detailsModalBody').innerHTML = detailsHtml; var modal = new bootstrap.Modal(document.getElementById('detailsModal')); @@ -589,10 +592,10 @@ function renderBreadcrumb() { bc.innerHTML = ''; const parts = currentPath ? currentPath.split('/') : []; let pathSoFar = ''; - bc.innerHTML += `Root`; + bc.innerHTML += `Root`; parts.forEach((part, idx) => { pathSoFar += (pathSoFar ? '/' : '') + part; - bc.innerHTML += ` / ${part}`; + bc.innerHTML += ` / ${part}`; }); // Show/hide up button const upBtn = document.getElementById('upBtn'); @@ -723,8 +726,8 @@ function renderFiles(files) { `; filesToRender.forEach((file, idx) => { let icon = file.type === 'folder' - ? `` - : ``; + ? `` + : ``; let size = file.size !== '-' ? (file.size > 0 ? (file.size < 1024*1024 ? (file.size/1024).toFixed(1)+' KB' : (file.size/1024/1024).toFixed(2)+' MB') : '0 KB') : '-'; let actionsArr = []; const canRenameAction = (canRename === 'true'); @@ -737,28 +740,28 @@ function renderFiles(files) { } if (file.type === 'file') { if (canDownload === 'true') { - actionsArr.push(``); + actionsArr.push(``); } if (canRenameAction) { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); if (canMove === 'true') { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); if (canDelete === true || canDelete === 'true') { - actionsArr.push(``); + actionsArr.push(``); } } else { - actionsArr.push(``); + actionsArr.push(``); if (canRenameAction) { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); - actionsArr.push(``); + actionsArr.push(``); + actionsArr.push(``); if (canDelete === true || canDelete === 'true') { - actionsArr.push(``); + actionsArr.push(``); } } // Move Delete to the end if present @@ -806,28 +809,28 @@ function renderFiles(files) { } if (file.type === 'file') { if (canDownload === 'true') { - actionsArr.push(``); + actionsArr.push(``); } if (canRenameAction) { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); if (canMove === 'true') { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); + actionsArr.push(``); if (canDelete === true || canDelete === 'true') { - actionsArr.push(``); + actionsArr.push(``); } } else { - actionsArr.push(``); + actionsArr.push(``); if (canRenameAction) { - actionsArr.push(``); + actionsArr.push(``); } - actionsArr.push(``); - actionsArr.push(``); + actionsArr.push(``); + actionsArr.push(``); if (canDelete === true || canDelete === 'true') { - actionsArr.push(``); + actionsArr.push(``); } } // Move Delete to the end if present diff --git a/templates/rooms/rooms.html b/templates/rooms/rooms.html index 327736f..13f7425 100644 --- a/templates/rooms/rooms.html +++ b/templates/rooms/rooms.html @@ -25,9 +25,9 @@
diff --git a/templates/settings/settings.html b/templates/settings/settings.html index af50361..942463f 100644 --- a/templates/settings/settings.html +++ b/templates/settings/settings.html @@ -13,6 +13,316 @@ ) }}
- +
+
+
+
+
Theme Colors
+
+
+
+ + + +
+
Primary Color
+
+
+
+
+ +
+ + +
+ Used for primary buttons, links, and accents +
+
+
+
+
+
+ +
+
+
+
+ Base +
+
+
+
+ Light +
+
+
+
+ Background +
+
+
+
+ Opacity 15% +
+
+
+
+
+
+
+ + +
+
Secondary Color
+
+
+
+
+ +
+ + + +
+ Used for secondary elements and highlights +
+
+
+
+
+
+ +
+
+
+
+ Base +
+
+
+
+ Light +
+
+
+
+ Opacity 15% +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+ + + + + {% endblock %} \ No newline at end of file diff --git a/templates/trash/trash.html b/templates/trash/trash.html index 7a96f8e..b7e0b34 100644 --- a/templates/trash/trash.html +++ b/templates/trash/trash.html @@ -5,6 +5,7 @@ {% block extra_css %} + {% endblock %} {% block content %}