Added theme classic

This commit is contained in:
Antonio de la Rosa 2025-01-20 01:18:55 +01:00
parent 573b0c4917
commit 30b41aa46b
12 changed files with 1802 additions and 108 deletions

View file

@ -1,4 +1,5 @@
from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from settings import config
@ -47,9 +48,14 @@ for name_module, module_app in config.apps.items():
app.mount("/mediafrom/"+app_basedir, StaticFiles(directory=media_path), name="static_"+app_basedir)
fast_app=getattr(controller_mod, app_module)
if not hasattr(controller_mod, 'wsgi_module'):
fast_app=getattr(controller_mod, app_module)
app.mount(path_module, fast_app)
else:
wsgi_app=getattr(controller_mod, app_module)
app.mount(path_module, WSGIMiddleware(wsgi_app))
# http://localhost:8000/mediafrom/admin/css/font-awesome.min.css

View file

@ -23,7 +23,7 @@
% endif
% if not simplelist.table_div:
<table class="table" id="${simplelist.model.name}_table">
<table class="table_list" id="${simplelist.model.name}_table">
<thead>
<tr class="title_list">
% for field in simplelist.fields_showed:

View file

@ -40,7 +40,7 @@ def home_admin(request: Request, paramecio_session: Annotated[str | None, Cookie
i18n=I18n('admin', I18n.session_lang(request.session))
return t.load_template('layout.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='home_admin')
return t.load_template('layout.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='home_admin', session=request.session)
@admin_app.get('/login', response_class=HTMLResponse)
@ -211,6 +211,15 @@ def logout_admin(request: Request) -> RedirectResponse:
return response
@admin_app.get('/change_lang')
def change_lang():
return RedirectResponse(app.url_path_for('home_admin'))
@admin_app.get('/change_theme')
def change_theme():
return RedirectResponse(app.url_path_for('home_admin'))
def check_login_tries(request, db):
@ -251,3 +260,4 @@ def check_login_tries(request, db):
logintries.query('insert into logintries (`ip`, `num_tries`, `last_login`) VALUES (%s, %s, %s)', [ip, 1, date_now])
return you_cannot_login

View file

@ -23,6 +23,8 @@ tpl_path=os.path.dirname(__file__).replace('/admin', '')+'/templates/admin'
if t.env.directories[1]!=tpl_path:
t.env.directories.insert(1, tpl_path)
modules_admin.append(['menu_users', 'people-circle', True])
modules_admin.append(['fastadmin_users', 'people-circle'])
modules_admin_icons.append('<symbol id="people-circle" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></symbol>')
@ -42,5 +44,5 @@ def fastadmin_users(request: Request):
slist.fields_showed=['username', 'email', 'double_auth', 'last_login']
return t.load_template('users.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='fastadmin_users', slist=slist)
return t.load_template('users.phtml', title=i18n.tlang('Admin'), tlang=i18n.tlang, url_for=app.url_path_for, module_selected='fastadmin_users', slist=slist, session=request.session)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,49 @@
/*! responsive-nav.js 1.0.39 by @viljamis */
.nav-collapse ul {
margin: 0;
padding: 0;
width: 100%;
display: block;
list-style: none;
}
.nav-collapse li {
width: 100%;
display: block;
}
.js .nav-collapse {
clip: rect(0 0 0 0);
max-height: 0;
position: absolute;
display: block;
overflow: hidden;
zoom: 1;
}
.nav-collapse.opened {
max-height: 9999px;
}
.nav-toggle {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
@media screen and (min-width: 40em) {
.js .nav-collapse {
position: relative;
}
.js .nav-collapse.closed {
max-height: none;
}
.nav-toggle {
display: none;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5,119 +5,176 @@ from parameciofast.libraries.i18n import I18n
i18n=I18n('fastadmin')
dark_checked=""
dark_css=""
if session.get('theme', '0')=='1':
dark_checked='checked'
dark_css='dark'
%>
<!doctype html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>${title}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="${make_media_url('css/layout.css', 'fastadmin')}" type="text/css" media="all" />
<%block name="css">
<link href="${make_media_url('css/admin.css', 'admin')}" rel="stylesheet" />
<link href="${make_media_url('css/responsive-nav.css', 'admin')}" rel="stylesheet" />
<link href="${make_media_url('css/tooltipster.bundle.min.css', 'admin')}" rel="stylesheet" />
<!--<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> -->
<%block name="extra_css">
</%block>
<%block name="header_js">
<script language="Javascript" src="${make_media_url('js/jquery-3.7.1.min.js', 'fastadmin')}"></script>
<script language="Javascript" src="${make_media_url('js/responsive-nav.min.js', 'fastadmin')}"></script>
<script language="Javascript" src="${make_media_url('js/tooltipster.bundle.min.js', 'fastadmin')}"></script>
<%block name="extra_js">
</%block>
<%block name="extra_header">
</%block>
</head>
<body data-bs-theme="dark">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"/>
</symbol>
%for module_icon in modules_admin_icons:
${module_icon|n}
<body class="${dark_css}">
<div id="layer_loading"><div id="container_loading"><div class="lds-dual-ring"></div></div></div>
<div id="languages_general">
</div>
<div id="logout">
<%block name="logout"><a href="${url_for('logout_admin')}"><i class="fa fa-power-off" aria-hidden="true"></i> Logout</a></%block>
</div>
<div id="center_body">
<div id="header">
<a href="#nav" id="toggle"><i class="fa fa-bars" aria-hidden="true"></i><span>Menu</span></a>
<%block name="title_admin"><span id="title_phango">Admin</span> <span id="title_framework">site!</span>
</%block>
<%block name="languages">
<div id="languages_general">
<%def name="select_lang(i18n, lang_selected)">${'choose_flag' if i18n==lang_selected else 'no_choose_flag'}</%def>
</%block>
% if lang_selected!=None:
% for i18n_lang in i18n.dict_i18n:
<a class="${select_lang(i18n_lang, lang_selected)}" href=""><img src="${make_media_url('images/languages/'+i18n_lang+'.png', 'admin')}" alt="${i18n_lang}"/></a>
% endfor
</svg>
<div class="loader-div" id="loader-div" style="display:none;">
<span class="loader">
<span></span>
<span></span>
</span>
</div>
<main>
<div class="container-fluid">
<div id="header_dashboard" class="row pt-3 pb-3">
<div class="col-sm-6 m-0 d-flex align-content-center flex-wrap align-self-center">
<h2 class="text-left ms-4 mt-0 mt-0 p-0" id="form_title">${tlang('Dashboard')}</h2>
% endif
</div>
</div>
<div class="row">
<div class="col-sm-2 p-3 m-0 text-white bg-dark" style="height:91vh;">
<!--<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"></use></svg>
<span class="fs-4">Sidebar</span>
</a>-->
<hr>
<!--<ul class="nav nav-pills flex-column mb-auto">
<li>
<a href="#" class="nav-link active text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#speedometer2"></use></svg>
${tlang('Dashboard')}
</a>
</li>
</ul>-->
<div class="content_admin">
<nav id="menu" class="nav-collapse">
<ul>
<li class="menu_title"><%block name="applications"><i class="fa fa-gear" aria-hidden="true"></i>${tlang('Applications')}</li></%block>
% for module in modules_admin:
<ul class="nav nav-pills flex-column mb-auto">
<li>
<a href="${url_for(module[0])}" class="nav-link text-white menu_item ${'active' if module[0]==module_selected else ''}" id="menu_${module[0]}">
% if len(module)>2:
<div class="father_admin">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${module[1]}"></use></svg>
${i18n.clang('fastadmin', module[0], module[0])}
</div>
% else:
<!--<a href="${url_for(module[0])}" class="nav-link text-white menu_item ${'active' if module[0]==module_selected else ''}" id="menu_${module[0]}">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${module[1]}"></use></svg>
${i18n.clang('fastadmin', module[0], module[0])}
</a>-->
<a href="${url_for(module[0])}" class="${'selected_menu' if module[0]==module_name else ''}">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${module[1]}"></use></svg>
${i18n.clang('fastadmin', module[0], module[0])}
</a>
% endif
</li>
</ul>
% endfor
<hr>
</ul>
</nav>
<div class="contents">
<h1>${title}</h1>
<div class="switch-btn">
<div class="switch-text">
${_('Dark theme')}
</div>
<div class="switch-slider">
<label class="switch">
<input type="checkbox" name="theme" value="1" id="theme" ${dark_checked}/>
<span class="slider round"></span>
</label>
</div>
</div>
<div class="content">
</div>
<div class="col-sm m-2 pt-3" style="">
<%block name="content">
<div class="card">
<div class="card-header bg-primary bg-gradient">
${tlang('Welcome to admin')}
</div>
<div class="card-body">
<p>${tlang('This is the admin section of your site.')}</p>
</div>
</div>
</%block>
</div>
</div>
</main>
</div>
<footer class="footer m-0 p-0">
</footer>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<div id="loading_ajax">
</div>
<script>
document.documentElement.setAttribute('data-bs-theme','dark');
var navigation = responsiveNav(".nav-collapse", {customToggle: "#toggle"});
setTimeout(function () {
$('.tooltip').tooltipster({
animation: 'fade',
delay: 100,
trigger: 'click'
});
$('#loader-div').fadeOut(2000);
const slider = document.querySelector('input[name="theme"]');
slider.addEventListener("change", function () {
}, 1000);
//Block button while send to ajax.
$('.menu_item').hover( function (e) {
$(this).prop("disabled",true);
if($(this).hasClass('active')) {
var dark='';
$(this).removeClass('active');
if (this.checked) {
document.body.classList.add("dark");
dark='1';
} else {
document.body.classList.remove("dark");
$(this).addClass('active');
dark='0';
}
$.ajax({
url: "${url_for('change_theme')}?theme="+dark,
type: 'GET',
data: {},
success: function (data) {
if(!data.error) {
console.log('Changed to dark in all pages');
}
else {
console.log('Cannot set dark theme in all pages!');
}
$(slider).prop("disabled",false);
},
error: function (data) {
alert('Error: '+data.status+' '+data.statusText);
$(slider).prop("disabled", false);
},
dataType: 'json'
});
});
$(document).ready(function () {
$('#layer_loading').hide();
});
</script>
<%block name="js">
<%block name="jscript_block">
</%block>
</body>
</html>

View file

@ -0,0 +1,123 @@
<%
from parameciofast.modules.fastadmin.libraries.config import modules_admin, modules_admin_icons
from parameciofast.libraries.i18n import I18n
i18n=I18n('fastadmin')
%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${title}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="${make_media_url('css/layout.css', 'fastadmin')}" type="text/css" media="all" />
<%block name="css">
</%block>
<%block name="header_js">
</%block>
</head>
<body data-bs-theme="dark">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="home" viewBox="0 0 16 16">
<path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146zM2.5 14V7.707l5.5-5.5 5.5 5.5V14H10v-4a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v4H2.5z"/>
</symbol>
%for module_icon in modules_admin_icons:
${module_icon|n}
%endfor
</svg>
<div class="loader-div" id="loader-div" style="display:none;">
<span class="loader">
<span></span>
<span></span>
</span>
</div>
<main>
<div class="container-fluid">
<div id="header_dashboard" class="row pt-3 pb-3">
<div class="col-sm-6 m-0 d-flex align-content-center flex-wrap align-self-center">
<h2 class="text-left ms-4 mt-0 mt-0 p-0" id="form_title">${tlang('Dashboard')}</h2>
</div>
</div>
<div class="row">
<div class="col-sm-2 p-3 m-0 text-white bg-dark" style="height:91vh;">
<!--<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"></use></svg>
<span class="fs-4">Sidebar</span>
</a>-->
<hr>
<!--<ul class="nav nav-pills flex-column mb-auto">
<li>
<a href="#" class="nav-link active text-white">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#speedometer2"></use></svg>
${tlang('Dashboard')}
</a>
</li>
</ul>-->
% for module in modules_admin:
<ul class="nav nav-pills flex-column mb-auto">
<li>
<a href="${url_for(module[0])}" class="nav-link text-white menu_item ${'active' if module[0]==module_selected else ''}" id="menu_${module[0]}">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${module[1]}"></use></svg>
${i18n.clang('fastadmin', module[0], module[0])}
</a>
</li>
</ul>
% endfor
<hr>
</div>
<div class="col-sm m-2 pt-3" style="">
<%block name="content">
<div class="card">
<div class="card-header bg-primary bg-gradient">
${tlang('Welcome to admin')}
</div>
<div class="card-body">
<p>${tlang('This is the admin section of your site.')}</p>
</div>
</div>
</%block>
</div>
</div>
</main>
</div>
<footer class="footer m-0 p-0">
</footer>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script>
document.documentElement.setAttribute('data-bs-theme','dark');
setTimeout(function () {
$('#loader-div').fadeOut(2000);
}, 1000);
$('.menu_item').hover( function (e) {
if($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
</script>
<%block name="js">
</%block>
</body>
</html>