| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <?xml version="1.0" encoding="utf-8"?>
- <odoo>
- <data noupdate="0">
- <!--
- M22 Early Sidebar State Script
- Inyecta un script en el head que aplica el estado del sidebar
- ANTES de que la página se renderice, evitando el flash visual.
- -->
- <template id="m22_sidebar_early_init" inherit_id="web.layout" priority="1">
- <xpath expr="//head" position="inside">
- <t t-if="request.session.uid and request.website.sudo().theme_id and request.website.sudo().theme_id.name == 'theme_m22tc'">
- <script>
- // Apply sidebar collapsed state immediately before render
- (function() {
- try {
- var isCollapsed = localStorage.getItem('m22_sidebar_collapsed') === 'true';
- if (isCollapsed) {
- document.documentElement.classList.add('m22-sidebar-collapsed-init');
- }
- } catch(e) {}
- })();
- </script>
- </t>
- </xpath>
- </template>
- <!--
- M22 Authenticated Layout - Layout Primario para Usuarios Logueados
- Estrategia: Crear un layout primario que herede de portal.frontend_layout
- Este layout será la base para todas las páginas que requieran sidebar
- -->
- <record id="m22_authenticated_layout_view" model="ir.ui.view">
- <field name="name">M22 Authenticated Layout</field>
- <field name="key">theme_m22tc.m22_authenticated_layout_ir</field>
- <field name="inherit_id" ref="portal.frontend_layout"/>
- <field name="priority">1000</field>
- <field name="arch" type="xml">
- <!-- Solo aplicar cuando el usuario está logueado -->
- <xpath expr="//div[@id='wrapwrap']" position="attributes">
- <attribute name="t-attf-class" add="#{request.session.uid and not request.website.is_public_user() and request.website.sudo().theme_id and request.website.sudo().theme_id.name == 'theme_m22tc' and 'o_has_m22_sidebar' or ''}" separator=" "/>
- </xpath>
- <!-- Inyectar el sidebar ANTES del main si el usuario está logueado -->
- <xpath expr="//div[@id='wrapwrap']/main" position="before">
- <t t-if="request.session.uid and not request.website.is_public_user() and request.website.sudo().theme_id and request.website.sudo().theme_id.name == 'theme_m22tc'">
- <!-- Get Sidebar Menu Items -->
- <t t-set="sidebar_menu_root" t-value="request.env.ref('theme_m22tc.menu_portal_sidebar', raise_if_not_found=False)"/>
- <t t-set="sidebar_items"
- t-value="sidebar_menu_root.child_id.filtered(lambda m: not m.website_id or m.website_id.id == request.website.id) if (sidebar_menu_root and request.website) else []"/>
- <t t-set="current_path" t-value="request.httprequest.path"/>
- <!-- SIDEBAR - Fixed Full Height -->
- <aside id="m22_sidebar" class="m22-sidebar d-flex flex-column" data-collapsed="false">
- <!-- Sidebar Header with Logo -->
- <div class="sidebar-header px-3 py-3">
- <div class="d-flex align-items-center justify-content-between w-100">
- <a href="/my/home" class="sidebar-logo d-flex align-items-center text-decoration-none">
- <img t-att-src="request.website.image_url(request.website, 'logo')"
- alt="Logo"
- class="sidebar-logo-img"
- style="max-height: 28px; width: auto; filter: brightness(0) invert(1);"/>
- </a>
- <button class="sidebar-collapse-btn" type="button" title="Colapsar menú">
- <i class="fa fa-chevron-left"></i>
- </button>
- </div>
- </div>
- <!-- Sidebar Navigation -->
- <div class="sidebar-nav flex-grow-1">
- <ul class="nav nav-pills flex-column m-0 p-0">
- <t t-foreach="sidebar_items" t-as="menu">
- <li class="nav-item">
- <t t-set="is_active" t-value="(menu.url == '/my/home' and current_path == '/my/home') or (menu.url != '/my/home' and menu.url and menu.url in current_path)"/>
- <a t-att-href="menu.url"
- t-att-class="'nav-link %s' % ('active' if is_active else '')"
- t-att-title="menu.name">
- <i t-if="menu.m22_icon_class"
- t-attf-class="fa #{menu.m22_icon_class} sidebar-icon"></i>
- <span class="sidebar-text" t-esc="menu.name"/>
- </a>
- </li>
- </t>
- </ul>
- </div>
- <!-- Sidebar Footer (User Info) -->
- <div class="sidebar-footer">
- <a href="/my/account" class="sidebar-user-info text-decoration-none" title="Mi Cuenta">
- <div class="user-avatar">
- <i class="fa fa-user"></i>
- </div>
- <div class="sidebar-text ms-3 d-flex flex-column overflow-hidden">
- <span class="fw-semibold text-white text-truncate" t-esc="request.env.user.name"/>
- <span class="small text-white-50">Mi Cuenta</span>
- </div>
- </a>
- <a href="/web/session/logout?redirect=/web/login" class="sidebar-logout" title="Cerrar Sesión">
- <i class="fa fa-sign-out"></i>
- <span class="sidebar-text ms-2">Cerrar Sesión</span>
- </a>
- </div>
- </aside>
- <!-- Sidebar Backdrop (Mobile) -->
- <div id="m22_sidebar_backdrop" class="m22-sidebar-backdrop d-lg-none"></div>
- <!-- Mobile Bottom Navigation -->
- <nav class="m22-bottom-nav d-lg-none fixed-bottom">
- <div class="d-flex justify-content-around align-items-center">
- <!-- Primary items: First 3 items -->
- <t t-set="primary_items" t-value="sidebar_items[:3] if len(sidebar_items) >= 3 else sidebar_items"/>
- <t t-foreach="primary_items" t-as="menu">
- <a t-att-href="menu.url" class="bottom-nav-item d-flex flex-column align-items-center text-decoration-none">
- <i t-if="menu.m22_icon_class" t-attf-class="fa #{menu.m22_icon_class}"></i>
- <span class="bottom-nav-label" t-esc="menu.name"/>
- </a>
- </t>
-
- <!-- Account: Always visible -->
- <a href="/my/account" class="bottom-nav-item d-flex flex-column align-items-center text-decoration-none">
- <i class="fa fa-user"></i>
- <span class="bottom-nav-label">Cuenta</span>
- </a>
-
- <!-- More Button: Opens bottom sheet - Always last -->
- <t t-if="len(sidebar_items) > 3">
- <button type="button"
- class="bottom-nav-item d-flex flex-column align-items-center text-decoration-none border-0 bg-transparent"
- id="m22_more_btn"
- aria-label="Más opciones">
- <i class="fa fa-ellipsis-h"></i>
- <span class="bottom-nav-label">Más</span>
- </button>
- </t>
- </div>
- </nav>
-
- <!-- Bottom Sheet: iOS Style with Tailwind -->
- <div id="m22_bottom_sheet"
- class="m22-bottom-sheet-container hidden"
- style="display: none; position: fixed; inset: 0; z-index: 1050; pointer-events: none;"
- role="dialog"
- aria-modal="true"
- aria-labelledby="bottom-sheet-title">
- <!-- Backdrop -->
- <div id="m22_bottom_sheet_backdrop"
- class="m22-bottom-sheet-backdrop"
- style="position: absolute; inset: 0; opacity: 0; transition: opacity 0.3s ease;"></div>
-
- <!-- Bottom Sheet Container -->
- <div id="m22_bottom_sheet_content"
- class="m22-bottom-sheet-content"
- style="position: absolute; bottom: 0; left: 0; right: 0; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); max-height: 85vh; display: flex; flex-direction: column; pointer-events: auto;">
-
- <!-- Handle Indicator -->
- <div class="flex justify-center pt-3 pb-2">
- <div class="w-12 h-1 bg-gray-300 dark:bg-gray-600 rounded-full"></div>
- </div>
-
- <!-- Header -->
- <div class="px-6 pb-4 border-b border-gray-200 dark:border-gray-700">
- <h3 id="bottom-sheet-title" class="text-lg font-semibold text-gray-900 dark:text-white">Más opciones</h3>
- </div>
-
- <!-- Content: Additional menu items -->
- <div class="flex-1 overflow-y-auto px-4 py-4">
- <div class="space-y-1">
- <t t-set="additional_items" t-value="sidebar_items[3:] if len(sidebar_items) > 3 else []"/>
- <t t-foreach="additional_items" t-as="menu">
- <a t-att-href="menu.url"
- class="m22-sheet-item flex items-center gap-3 px-4 py-3 rounded-xl text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-150 text-decoration-none">
- <i t-if="menu.m22_icon_class"
- t-attf-class="fa #{menu.m22_icon_class} text-xl text-gray-600 dark:text-gray-400 w-6 text-center"></i>
- <span class="flex-1 font-medium" t-esc="menu.name"/>
- <i class="fa fa-chevron-right text-gray-400 text-sm"></i>
- </a>
- </t>
- </div>
- </div>
-
- <!-- Close Button -->
- <div class="px-4 pb-6 pt-2 border-t border-gray-200 dark:border-gray-700">
- <button type="button"
- id="m22_bottom_sheet_close"
- class="w-full py-3 px-4 bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white rounded-xl font-medium hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-150">
- Cerrar
- </button>
- </div>
- </div>
- </div>
- </t>
- </xpath>
- <!-- Agregar clases al main para compensar el sidebar -->
- <xpath expr="//div[@id='wrapwrap']/main" position="attributes">
- <attribute name="t-attf-class" add="#{request.website.sudo().theme_id and request.website.sudo().theme_id.name == 'theme_m22tc' and not request.env.user._is_public() and 'o_main_with_sidebar' or ''}" separator=" "/>
- </xpath>
- </field>
- </record>
- </data>
- </odoo>
|