Fix mobile UI for faculty/admin backend dashboard

The faculty/admin backend (sidebar, top nav, dashboard widgets) had
zero mobile responsiveness, unlike the login page and student portal
which already had proper breakpoints. On a phone the fixed 260px
sidebar plus its unconditional margin-left permanently ate most of
the screen, and the dashboard's KPI/chart/widget rows used fixed
CSS grid columns with no stacking.

- sidebar.xml: sidebar goes off-canvas below 768px with a hamburger
  toggle and tap-to-close backdrop, instead of always being visible
- backend_forms.scss: content margin-left and the forced
  display:flex/overflow:visible on the top menu are now scoped to
  desktop only, restoring Odoo's native d-none d-md-flex mobile hide
  that the override was defeating
- education_dashboard_templates.xml: KPI/chart/widget grids stack to
  2-col/1-col under 768px/420px instead of staying fixed at 5/3 cols

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
metatroncubeswdev 2026-10-23 23:21:58 -04:00
parent faf9e75849
commit 2ac9656203
3 changed files with 70 additions and 14 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-name="education_dashboard.DashboardMain">
<div style="background:#eef9f9; padding:20px 24px 40px 24px; font-family:-apple-system,BlinkMacSystemFont,'Inter',sans-serif;">
<div class="edu-dashboard-root" style="background:#eef9f9; padding:20px 24px 40px 24px; font-family:-apple-system,BlinkMacSystemFont,'Inter',sans-serif;">
<style>
.edu-card { background:#fff; border-radius:14px; border:1px solid #e2e8f0; box-shadow:0 2px 12px rgba(15,23,42,0.06); }
@ -17,10 +17,28 @@
.edu-ann-row { display:flex; gap:10px; padding:9px 0; border-bottom:1px solid #f1f5f9; align-items:flex-start; }
.edu-ann-row:last-child { border-bottom:none; }
.edu-pill { padding:3px 9px; border-radius:20px; font-size:0.68rem; font-weight:700; flex-shrink:0; }
/* ── Responsive overrides (!important needed to beat inline styles) ── */
@media (max-width: 1100px) {
.edu-charts-grid { grid-template-columns: 1fr 1fr !important; }
.edu-charts-grid > :last-child { grid-column: 1 / -1 !important; }
}
@media (max-width: 768px) {
.edu-dashboard-root { padding: 14px 14px 32px 14px !important; }
.edu-welcome-banner { flex-direction: column !important; align-items: flex-start !important; gap: 16px !important; padding: 20px !important; }
.edu-welcome-banner > :last-child { text-align: left !important; flex-direction: row !important; flex-wrap: wrap !important; }
.edu-kpi-grid { grid-template-columns: repeat(2, 1fr) !important; }
.edu-charts-grid { grid-template-columns: 1fr !important; }
.edu-charts-grid > :last-child { grid-column: auto !important; }
.edu-bottom-grid { grid-template-columns: 1fr !important; }
}
@media (max-width: 420px) {
.edu-kpi-grid { grid-template-columns: 1fr !important; }
}
</style>
<!-- ── WELCOME BANNER ─────────────────────────────────────── -->
<div style="background:linear-gradient(135deg,rgba(31,143,143,0.65) 0%,rgba(20,77,77,0.70) 55%,rgba(13,53,53,0.75) 100%), url('/education_dashboard/static/src/img/dashboard-bg.png'); background-size:cover; background-position:center 60%; border-radius:16px; padding:26px 32px; margin-bottom:20px; display:flex; align-items:center; justify-content:space-between; position:relative; overflow:hidden;">
<div class="edu-welcome-banner" style="background:linear-gradient(135deg,rgba(31,143,143,0.65) 0%,rgba(20,77,77,0.70) 55%,rgba(13,53,53,0.75) 100%), url('/education_dashboard/static/src/img/dashboard-bg.png'); background-size:cover; background-position:center 60%; border-radius:16px; padding:26px 32px; margin-bottom:20px; display:flex; align-items:center; justify-content:space-between; position:relative; overflow:hidden;">
<div style="position:absolute;top:-30px;right:200px;width:180px;height:180px;border-radius:50%;background:rgba(255,255,255,0.05);pointer-events:none;"></div>
<div style="position:absolute;bottom:-40px;right:60px;width:240px;height:240px;border-radius:50%;background:rgba(255,255,255,0.04);pointer-events:none;"></div>
<div style="position:relative;z-index:1;">
@ -39,7 +57,7 @@
</div>
<!-- ── KPI CARDS ──────────────────────────────────────────── -->
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-bottom:20px;">
<div class="edu-kpi-grid" style="display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-bottom:20px;">
<div class="edu-kpi" t-on-click="() => this.openStudents('')">
<div class="edu-icon" style="background:#e0f7f7;color:#1f8f8f;"><i class="fa fa-users"/></div>
<div>
@ -78,7 +96,7 @@
</div>
<!-- ── CHARTS + QUICK ACTIONS ─────────────────────────────── -->
<div style="display:grid;grid-template-columns:5fr 4fr 3fr;gap:14px;margin-bottom:20px;">
<div class="edu-charts-grid" style="display:grid;grid-template-columns:5fr 4fr 3fr;gap:14px;margin-bottom:20px;">
<!-- Enrollment Trend -->
<div class="edu-card" style="padding:20px;">
@ -156,7 +174,7 @@
</div>
<!-- ── BOTTOM ROW ─────────────────────────────────────────── -->
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:20px;">
<div class="edu-bottom-grid" style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:20px;">
<!-- Upcoming Examinations -->
<div class="edu-card" style="padding:20px;">

View File

@ -28,10 +28,14 @@ body.o_web_client {
height: 100% !important; // fill the available viewport height
}
// Only push content when our custom sidebar is present
// Only push content when our custom sidebar is present (desktop only —
// below 768px the sidebar goes off-canvas, see sidebar.xml, so content
// must stay full-width instead of leaving a permanent 260px gap)
@media (min-width: 769px) {
body.o_web_client:has(.o_sidebar_custom) .o_action_manager {
margin-left: 260px;
}
}
// Inner content containers — let them grow freely
.o_content,
@ -60,13 +64,20 @@ body.o_web_client:has(.o_sidebar_custom) .o_action_manager {
background-color: transparent !important;
}
// Ensure horizontal menus are always visible in the header
// Ensure horizontal menus are always visible in the header — desktop only.
// Odoo's own navbar.xml marks .o_menu_sections/.o_menu_brand "d-none d-md-flex"
// (hidden under 768px) and relies on that for mobile; forcing display:flex
// unconditionally here defeated that native hide and the overflow "more"
// dropdown. Below 768px the custom sidebar (see sidebar.xml) is the nav
// instead, so let the top menu fall back to Odoo's native hidden state.
@media (min-width: 769px) {
.o_menu_sections {
display: flex !important;
flex-grow: 1 !important;
align-items: center !important;
overflow: visible !important;
}
}
// Explicitly override Odoo's internal enterprise variables
.o_menu_sections .o_nav_entry, .o_menu_sections .dropdown-toggle {

View File

@ -5,10 +5,37 @@
<xpath expr="//nav" position="inside">
<t t-if="currentApp and currentApp.name === 'Education'">
<!-- Mobile hamburger toggle: hidden by default, shown only below 768px (Odoo's own "md" breakpoint) -->
<!-- Centered: Odoo's own app-switcher icon (left) and systray (right)
stay visible on mobile natively, so the center is the open slot
once the brand name / section menu hide below 768px. -->
<div id="eduSidebarToggle"
onclick="document.querySelector('.o_sidebar_custom').classList.add('o_sidebar_open'); document.querySelector('.o_sidebar_backdrop').classList.add('o_sidebar_open');"
style="display:none; position:fixed; top:14px; left:50%; transform:translateX(-50%); z-index:111; width:42px; height:42px; border-radius:10px; background:rgba(0,0,0,0.25); color:#fff; align-items:center; justify-content:center; cursor:pointer;">
<i class="fa fa-bars" style="font-size:1.1rem;"/>
</div>
<!-- Backdrop: closes sidebar on outside tap, mobile only -->
<div class="o_sidebar_backdrop"
onclick="document.querySelector('.o_sidebar_custom').classList.remove('o_sidebar_open'); this.classList.remove('o_sidebar_open');"
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:89;"/>
<div class="o_sidebar_custom d-flex flex-column position-fixed"
style="top: 70px; bottom: 0; left: 0; width: 260px; background: linear-gradient(135deg, #1f8f8f 0%, #144d4d 55%, #0d3d3d 100%); border-right: 1px solid rgba(255,255,255,0.1); z-index: 90; padding-top: 10px; overflow-y: auto; box-shadow: 2px 0 10px rgba(0,0,0,0.1); color: white;">
<style>
/* ── Mobile: off-canvas sidebar + visible hamburger/backdrop ── */
@media (max-width: 768px) {
#eduSidebarToggle { display: flex !important; }
.o_sidebar_custom {
transform: translateX(-100%);
transition: transform 0.25s ease;
width: 80vw !important;
max-width: 300px;
}
.o_sidebar_custom.o_sidebar_open { transform: translateX(0); }
.o_sidebar_backdrop.o_sidebar_open { display: block !important; }
}
.o_sidebar_custom .sidebar-link {
display: flex; align-items: center; padding: 8px 16px;
margin: 2px 8px; border-radius: 8px; color: rgba(255,255,255,0.9);