colour settings start
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
56
migrations/versions/ca9026520dad_add_colorsettings_table.py
Normal file
56
migrations/versions/ca9026520dad_add_colorsettings_table.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Add ColorSettings table
|
||||
|
||||
Revision ID: ca9026520dad
|
||||
Revises: 76da0573e84b
|
||||
Create Date: 2025-05-25 21:08:37.158900
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'ca9026520dad'
|
||||
down_revision = '76da0573e84b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('color_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')
|
||||
)
|
||||
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
||||
batch_op.alter_column('deleted',
|
||||
existing_type=sa.BOOLEAN(),
|
||||
nullable=True,
|
||||
existing_server_default=sa.text('false'))
|
||||
|
||||
with op.batch_alter_table('trashed_file', schema=None) as batch_op:
|
||||
batch_op.alter_column('deleted_at',
|
||||
existing_type=postgresql.TIMESTAMP(),
|
||||
nullable=True)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('trashed_file', schema=None) as batch_op:
|
||||
batch_op.alter_column('deleted_at',
|
||||
existing_type=postgresql.TIMESTAMP(),
|
||||
nullable=False)
|
||||
|
||||
with op.batch_alter_table('room_file', schema=None) as batch_op:
|
||||
batch_op.alter_column('deleted',
|
||||
existing_type=sa.BOOLEAN(),
|
||||
nullable=False,
|
||||
existing_server_default=sa.text('false'))
|
||||
|
||||
op.drop_table('color_settings')
|
||||
# ### end Alembic commands ###
|
||||
Binary file not shown.
@@ -322,3 +322,8 @@ def init_routes(main_bp):
|
||||
@login_required
|
||||
def trash():
|
||||
return render_template('trash/trash.html')
|
||||
|
||||
@main_bp.route('/settings')
|
||||
@login_required
|
||||
def settings():
|
||||
return render_template('settings/settings.html')
|
||||
@@ -1,12 +1,8 @@
|
||||
:root {
|
||||
--primary-color: #16767b;
|
||||
--secondary-color: #741b5f;
|
||||
--primary-light: #1a8a90;
|
||||
--secondary-light: #8a2170;
|
||||
}
|
||||
/* Import color variables */
|
||||
@import 'colors.css';
|
||||
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
.auth-container {
|
||||
@@ -17,12 +13,12 @@ body {
|
||||
.auth-card {
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 4px 6px var(--shadow-color);
|
||||
}
|
||||
|
||||
.auth-header {
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
|
||||
color: white;
|
||||
color: var(--white);
|
||||
padding: 20px;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
@@ -39,7 +35,7 @@ body {
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 0.2rem rgba(22, 118, 123, 0.25);
|
||||
box-shadow: 0 0 0 0.2rem var(--shadow-color-light);
|
||||
}
|
||||
|
||||
.alert {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
:root {
|
||||
--primary-color: #16767b;
|
||||
--secondary-color: #741b5f;
|
||||
--primary-light: #1a8a90;
|
||||
--secondary-light: #8a2170;
|
||||
}
|
||||
/* Import color variables */
|
||||
@import 'colors.css';
|
||||
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
@@ -17,9 +13,9 @@ body {
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: white;
|
||||
background-color: var(--white);
|
||||
min-height: calc(100vh - 56px);
|
||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 2px 0 5px var(--shadow-color);
|
||||
position: sticky;
|
||||
top: 56px; /* Height of the navbar */
|
||||
height: calc(100vh - 56px);
|
||||
@@ -27,19 +23,19 @@ body {
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
color: #333;
|
||||
color: var(--text-dark);
|
||||
padding: 0.8rem 1rem;
|
||||
border-radius: 0.25rem;
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover {
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.sidebar .nav-link i {
|
||||
@@ -53,7 +49,7 @@ body {
|
||||
.card {
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 4px var(--shadow-color);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
|
||||
51
static/css/colors.css
Normal file
51
static/css/colors.css
Normal file
@@ -0,0 +1,51 @@
|
||||
:root {
|
||||
/* Primary Colors */
|
||||
--primary-color: #16767b;
|
||||
--primary-light: #1a8a90;
|
||||
|
||||
/* Secondary Colors */
|
||||
--secondary-color: #741b5f;
|
||||
--secondary-light: #8a2170;
|
||||
|
||||
/* Background Colors */
|
||||
--bg-color: #f8f9fa;
|
||||
--white: #ffffff;
|
||||
--primary-bg-light: #e6f3f4;
|
||||
|
||||
/* Text Colors */
|
||||
--text-dark: #333333;
|
||||
--text-muted: #6c757d;
|
||||
|
||||
/* Status Colors */
|
||||
--warning-color: #ffd700;
|
||||
--danger-color: #dc3545;
|
||||
|
||||
/* Shadow Colors */
|
||||
--shadow-color: rgba(0, 0, 0, 0.1);
|
||||
--shadow-color-light: rgba(0, 0, 0, 0.25);
|
||||
|
||||
/* Border Colors */
|
||||
--border-color: #dee2e6;
|
||||
--border-light: #e9ecef;
|
||||
|
||||
/* Opacity Colors */
|
||||
--primary-opacity-8: rgba(22, 118, 123, 0.08);
|
||||
--primary-opacity-12: rgba(22, 118, 123, 0.12);
|
||||
--primary-opacity-15: rgba(22, 118, 123, 0.15);
|
||||
--primary-opacity-20: rgba(22, 118, 123, 0.2);
|
||||
--warning-opacity-15: rgba(255, 215, 0, 0.15);
|
||||
--danger-opacity-15: rgba(220, 53, 69, 0.15);
|
||||
|
||||
/* Chart Colors */
|
||||
--chart-primary: #16767b;
|
||||
--chart-secondary: #741b5f;
|
||||
--chart-warning: #ffd700;
|
||||
--chart-primary-light: #2c9da9;
|
||||
--chart-primary-lighter: #43c4d3;
|
||||
--chart-primary-lightest: #5ad9e8;
|
||||
--chart-primary-pale: #71eefd;
|
||||
--chart-secondary-light: #8a2b73;
|
||||
--chart-secondary-lighter: #a03b87;
|
||||
--chart-secondary-lightest: #b64b9b;
|
||||
--chart-secondary-pale: #cc5baf;
|
||||
}
|
||||
@@ -1,11 +1,5 @@
|
||||
:root {
|
||||
--primary-color: #16767b;
|
||||
--secondary-color: #741b5f;
|
||||
--primary-light: #1a8a90;
|
||||
--secondary-light: #8a2170;
|
||||
--warning-color: #ffd700;
|
||||
--danger-color: #dc3545;
|
||||
}
|
||||
/* Import color variables */
|
||||
@import 'colors.css';
|
||||
|
||||
/* Masonry Layout */
|
||||
.masonry {
|
||||
@@ -31,7 +25,7 @@
|
||||
.card {
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 4px var(--shadow-color);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
@@ -77,24 +71,24 @@
|
||||
|
||||
/* Badge Styles */
|
||||
.badge-starred {
|
||||
background-color: rgba(255, 215, 0, 0.15) !important;
|
||||
background-color: var(--warning-opacity-15) !important;
|
||||
color: var(--warning-color) !important;
|
||||
}
|
||||
|
||||
.badge-trash {
|
||||
background-color: rgba(220, 53, 69, 0.15) !important;
|
||||
background-color: var(--danger-opacity-15) !important;
|
||||
color: var(--danger-color) !important;
|
||||
}
|
||||
|
||||
/* Contact Link Styles */
|
||||
.contact-link {
|
||||
background-color: rgba(22, 118, 123, 0.08);
|
||||
background-color: var(--primary-opacity-8);
|
||||
color: var(--primary-color);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.contact-link:hover {
|
||||
background-color: rgba(22, 118, 123, 0.12);
|
||||
background-color: var(--primary-opacity-12);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
@@ -106,8 +100,8 @@
|
||||
|
||||
/* Alert Styles */
|
||||
.alert-info {
|
||||
background-color: rgba(22, 118, 123, 0.08);
|
||||
border-color: rgba(22, 118, 123, 0.2);
|
||||
background-color: var(--primary-opacity-8);
|
||||
border-color: var(--primary-opacity-20);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
@@ -118,7 +112,7 @@
|
||||
}
|
||||
|
||||
.list-group-item:not(:last-child) {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-bottom: 1px solid var(--shadow-color);
|
||||
}
|
||||
|
||||
/* Download Button */
|
||||
@@ -126,14 +120,14 @@
|
||||
background-color: var(--primary-color);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 2px rgba(22, 118, 123, 0.08);
|
||||
color: white;
|
||||
box-shadow: 0 1px 2px var(--primary-opacity-8);
|
||||
color: var(--white);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-download:hover {
|
||||
background-color: var(--primary-light);
|
||||
color: white;
|
||||
color: var(--white);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 4px rgba(22, 118, 123, 0.12);
|
||||
box-shadow: 0 2px 4px var(--primary-opacity-12);
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
/* Import color variables */
|
||||
@import 'colors.css';
|
||||
|
||||
.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;
|
||||
}
|
||||
@@ -27,6 +27,13 @@
|
||||
<i class="fas fa-bell text-xl" style="width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center;"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% if current_user.is_admin %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link flex items-center justify-center" href="{{ url_for('main.settings') }}">
|
||||
<i class="fas fa-cog text-xl" style="width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center;"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle flex items-center gap-2" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown">
|
||||
<img src="{{ url_for('profile_pic', filename=current_user.profile_picture) if current_user.profile_picture else url_for('static', filename='default-avatar.png') }}"
|
||||
@@ -37,7 +44,9 @@
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="{{ url_for('main.profile') }}"><i class="fas fa-user"></i> Profile</a></li>
|
||||
<li><a class="dropdown-item" href="#"><i class="fas fa-cog"></i> Settings</a></li>
|
||||
{% if current_user.is_admin %}
|
||||
<li><a class="dropdown-item" href="{{ url_for('main.settings') }}"><i class="fas fa-cog"></i> Settings</a></li>
|
||||
{% endif %}
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="{{ url_for('auth.logout') }}"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -62,6 +62,26 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Helper function to get computed CSS variable value
|
||||
function getCssVar(varName) {
|
||||
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
|
||||
}
|
||||
|
||||
// Get all chart colors
|
||||
const chartColors = {
|
||||
primary: getCssVar('--chart-primary'),
|
||||
secondary: getCssVar('--chart-secondary'),
|
||||
warning: getCssVar('--chart-warning'),
|
||||
primaryLight: getCssVar('--chart-primary-light'),
|
||||
primaryLighter: getCssVar('--chart-primary-lighter'),
|
||||
primaryLightest: getCssVar('--chart-primary-lightest'),
|
||||
primaryPale: getCssVar('--chart-primary-pale'),
|
||||
secondaryLight: getCssVar('--chart-secondary-light'),
|
||||
secondaryLighter: getCssVar('--chart-secondary-lighter'),
|
||||
secondaryLightest: getCssVar('--chart-secondary-lightest'),
|
||||
secondaryPale: getCssVar('--chart-secondary-pale')
|
||||
};
|
||||
|
||||
// Contact Status Chart
|
||||
const statusCtx = document.getElementById('statusChart');
|
||||
if (statusCtx) {
|
||||
@@ -71,7 +91,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
labels: ['Active', 'Inactive'],
|
||||
datasets: [{
|
||||
data: [{{ active_count }}, {{ inactive_count }}],
|
||||
backgroundColor: ['#16767b', '#741b5f'],
|
||||
backgroundColor: [chartColors.primary, chartColors.secondary],
|
||||
borderWidth: 0,
|
||||
hoverOffset: 4
|
||||
}]
|
||||
@@ -98,7 +118,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
labels: ['Starred', 'Unstarred'],
|
||||
datasets: [{
|
||||
data: [{{ starred_count }}, {{ file_count - starred_count }}],
|
||||
backgroundColor: ['#ffd700', '#16767b'],
|
||||
backgroundColor: [chartColors.warning, chartColors.primary],
|
||||
borderWidth: 0,
|
||||
hoverOffset: 4
|
||||
}]
|
||||
@@ -124,8 +144,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
datasets: [{
|
||||
data: [{% for type in storage_by_type %}{{ type.total_size }}{% if not loop.last %}, {% endif %}{% endfor %}],
|
||||
backgroundColor: [
|
||||
'#16767b', '#2c9da9', '#43c4d3', '#5ad9e8', '#71eefd',
|
||||
'#741b5f', '#8a2b73', '#a03b87', '#b64b9b', '#cc5baf'
|
||||
chartColors.primary,
|
||||
chartColors.primaryLight,
|
||||
chartColors.primaryLighter,
|
||||
chartColors.primaryLightest,
|
||||
chartColors.primaryPale,
|
||||
chartColors.secondary,
|
||||
chartColors.secondaryLight,
|
||||
chartColors.secondaryLighter,
|
||||
chartColors.secondaryLightest,
|
||||
chartColors.secondaryPale
|
||||
],
|
||||
borderWidth: 0,
|
||||
hoverOffset: 4
|
||||
@@ -156,8 +184,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
datasets: [{
|
||||
data: [{% for type in trash_by_type %}{{ type.count }}{% if not loop.last %}, {% endif %}{% endfor %}],
|
||||
backgroundColor: [
|
||||
'#16767b', '#2c9da9', '#43c4d3', '#5ad9e8', '#71eefd',
|
||||
'#741b5f', '#8a2b73', '#a03b87', '#b64b9b', '#cc5baf'
|
||||
chartColors.primary,
|
||||
chartColors.primaryLight,
|
||||
chartColors.primaryLighter,
|
||||
chartColors.primaryLightest,
|
||||
chartColors.primaryPale,
|
||||
chartColors.secondary,
|
||||
chartColors.secondaryLight,
|
||||
chartColors.secondaryLighter,
|
||||
chartColors.secondaryLightest,
|
||||
chartColors.secondaryPale
|
||||
],
|
||||
borderWidth: 0,
|
||||
hoverOffset: 4
|
||||
|
||||
18
templates/settings/settings.html
Normal file
18
templates/settings/settings.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends "common/base.html" %}
|
||||
{% from "components/header.html" import header %}
|
||||
|
||||
{% block title %}Settings - DocuPulse{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ header(
|
||||
title="Settings",
|
||||
description="Manage your docupulse settings",
|
||||
button_text="",
|
||||
button_url="",
|
||||
icon="fa-cog"
|
||||
) }}
|
||||
|
||||
<div class="container-fluid">
|
||||
<!-- Settings content will go here -->
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user