Remove multiple login and signup templates from expert_theme, consolidating to a more streamlined design approach.
This commit is contained in:
parent
01b9498193
commit
575bb504ee
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'Expert Theme',
|
||||
'version': '18.0.1.0.0',
|
||||
'category': 'Theme/Backend',
|
||||
'version': '1.0.0',
|
||||
'category': 'Themes',
|
||||
'summary': 'Custom backend theme with installed modules home page',
|
||||
'description': """
|
||||
Expert Theme
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
- Easy navigation to installed applications
|
||||
""",
|
||||
'author': 'Expert',
|
||||
'website': '',
|
||||
'depends': ['base', 'web'],
|
||||
'website': 'https://www.exp-sa.com',
|
||||
'depends': ['base', 'web','website'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/expert_login_template_data.xml',
|
||||
|
|
@ -25,23 +25,23 @@
|
|||
'views/expert_home_views.xml',
|
||||
'views/expert_menu_views.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'expert_theme/static/src/css/expert_theme_config.css',
|
||||
'expert_theme/static/src/css/expert_theme.css',
|
||||
'expert_theme/static/src/js/expert_theme_dynamic.js',
|
||||
'expert_theme/static/src/js/expert_theme_config.js',
|
||||
'expert_theme/static/src/js/expert_home.js',
|
||||
'expert_theme/static/src/js/expert_login_template_list.js',
|
||||
'expert_theme/static/src/xml/expert_home.xml',
|
||||
],
|
||||
'web.assets_frontend': [
|
||||
'expert_theme/static/src/css/expert_login.css',
|
||||
'expert_theme/static/src/css/login_modern.css',
|
||||
'expert_theme/static/src/css/login_minimal.css',
|
||||
'expert_theme/static/src/js/expert_login_template.js',
|
||||
],
|
||||
},
|
||||
'assets': {
|
||||
'web.assets_frontend': [
|
||||
'expert_theme/static/src/scss/login_modern.scss',
|
||||
'expert_theme/static/src/scss/expert_login.scss',
|
||||
'expert_theme/static/src/scss/login_minimal.scss',
|
||||
'expert_theme/static/src/js/expert_login_template.js',
|
||||
],
|
||||
'web.assets_backend': [
|
||||
'expert_theme/static/src/scss/expert_theme_config.scss',
|
||||
'expert_theme/static/src/scss/expert_theme.scss',
|
||||
'expert_theme/static/src/js/expert_theme_dynamic.js',
|
||||
'expert_theme/static/src/js/expert_theme_config.js',
|
||||
'expert_theme/static/src/js/expert_home.js',
|
||||
'expert_theme/static/src/js/expert_login_template_list.js',
|
||||
'expert_theme/static/src/xml/expert_home.xml',
|
||||
]
|
||||
},
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'application': False,
|
||||
|
|
|
|||
|
|
@ -55,46 +55,6 @@ class ExpertController(http.Controller):
|
|||
'error': str(e)
|
||||
})
|
||||
|
||||
@http.route('/web/login', type='http', auth='none', methods=['GET', 'POST'], csrf=False)
|
||||
def web_login(self, redirect=None, **kw):
|
||||
"""Override Odoo login to use expert login templates when configured.
|
||||
|
||||
- POST: delegate to standard Odoo login logic (authentication, redirects, etc.).
|
||||
- GET: render the active expert login template if not 'default', otherwise use standard login.
|
||||
"""
|
||||
# Import Home from its new location in Odoo 18
|
||||
from odoo.addons.web.controllers.home import Home
|
||||
|
||||
# Handle login submission via standard controller
|
||||
if request.httprequest.method == 'POST':
|
||||
home = Home()
|
||||
return home.web_login(redirect=redirect, **kw)
|
||||
|
||||
# GET: decide which template to render
|
||||
try:
|
||||
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
||||
template_name = login_template.get_template_name()
|
||||
except Exception as e:
|
||||
_logger.error("Error getting active login template: %s", e)
|
||||
template_name = 'web.login'
|
||||
|
||||
# For default template, just call the standard login
|
||||
if template_name == 'web.login':
|
||||
home = Home()
|
||||
return home.web_login(redirect=redirect, **kw)
|
||||
|
||||
# Try to render the selected expert template; fall back to default on error
|
||||
try:
|
||||
return request.render(template_name, {
|
||||
'redirect': redirect or '',
|
||||
'login': kw.get('login', ''),
|
||||
'login_template': login_template,
|
||||
})
|
||||
except Exception as e:
|
||||
_logger.error("Error rendering login template '%s': %s", template_name, e)
|
||||
home = Home()
|
||||
return home.web_login(redirect=redirect, **kw)
|
||||
|
||||
@http.route('/expert_theme/get_login_template_styles', type='http', auth='public', methods=['GET'])
|
||||
def get_login_template_styles(self):
|
||||
"""Get CSS styles for the active login template (public access for login page)"""
|
||||
|
|
@ -181,106 +141,4 @@ class ExpertController(http.Controller):
|
|||
'error': str(e)
|
||||
})
|
||||
|
||||
@http.route('/web/signup', type='http', auth='public', methods=['GET', 'POST'], website=True, csrf=False)
|
||||
def web_auth_signup(self, redirect=None, **kw):
|
||||
"""Override Odoo signup to use expert signup templates when modern template is active.
|
||||
|
||||
- POST: delegate to standard Odoo signup logic (authentication, redirects, etc.).
|
||||
- GET: render the active expert signup template if modern template is active, otherwise use standard signup.
|
||||
"""
|
||||
# Import AuthSignupHome from auth_signup module
|
||||
try:
|
||||
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
|
||||
except ImportError:
|
||||
# If auth_signup is not installed, return 404
|
||||
from werkzeug.exceptions import NotFound
|
||||
raise NotFound()
|
||||
|
||||
# Handle signup submission via standard controller
|
||||
if request.httprequest.method == 'POST':
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
||||
|
||||
# GET: decide which template to render
|
||||
try:
|
||||
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
||||
template_name = login_template.get_signup_template_name()
|
||||
except Exception as e:
|
||||
_logger.error("Error getting active signup template: %s", e)
|
||||
template_name = 'auth_signup.signup'
|
||||
|
||||
# For default template, just call the standard signup
|
||||
if template_name == 'auth_signup.signup':
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
||||
|
||||
# Try to render the selected expert template; fall back to default on error
|
||||
try:
|
||||
# Get signup context from auth_signup
|
||||
auth_signup_home = AuthSignupHome()
|
||||
qcontext = auth_signup_home.get_auth_signup_qcontext()
|
||||
qcontext.update({
|
||||
'redirect': redirect or '',
|
||||
'login': kw.get('login', ''),
|
||||
'login_template': login_template,
|
||||
})
|
||||
response = request.render(template_name, qcontext)
|
||||
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
|
||||
return response
|
||||
except Exception as e:
|
||||
_logger.error("Error rendering signup template '%s': %s", template_name, e)
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_signup(redirect=redirect, **kw)
|
||||
|
||||
@http.route('/web/reset_password', type='http', auth='public', methods=['GET', 'POST'], website=True, csrf=False)
|
||||
def web_auth_reset_password(self, redirect=None, **kw):
|
||||
"""Override Odoo reset password to use expert reset password templates when modern template is active.
|
||||
|
||||
- POST: delegate to standard Odoo reset password logic (authentication, redirects, etc.).
|
||||
- GET: render the active expert reset password template if modern template is active, otherwise use standard reset password.
|
||||
"""
|
||||
# Import AuthSignupHome from auth_signup module
|
||||
try:
|
||||
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
|
||||
except ImportError:
|
||||
# If auth_signup is not installed, return 404
|
||||
from werkzeug.exceptions import NotFound
|
||||
raise NotFound()
|
||||
|
||||
# Handle reset password submission via standard controller
|
||||
if request.httprequest.method == 'POST':
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|
||||
|
||||
# GET: decide which template to render
|
||||
try:
|
||||
login_template = request.env['expert.login.template'].sudo().get_active_template()
|
||||
template_name = login_template.get_reset_password_template_name()
|
||||
except Exception as e:
|
||||
_logger.error("Error getting active reset password template: %s", e)
|
||||
template_name = 'auth_signup.reset_password'
|
||||
|
||||
# For default template, just call the standard reset password
|
||||
if template_name == 'auth_signup.reset_password':
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|
||||
|
||||
# Try to render the selected expert template; fall back to default on error
|
||||
try:
|
||||
# Get reset password context from auth_signup
|
||||
auth_signup_home = AuthSignupHome()
|
||||
qcontext = auth_signup_home.get_auth_signup_qcontext()
|
||||
qcontext.update({
|
||||
'redirect': redirect or '',
|
||||
'login': kw.get('login', ''),
|
||||
'login_template': login_template,
|
||||
})
|
||||
response = request.render(template_name, qcontext)
|
||||
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
|
||||
return response
|
||||
except Exception as e:
|
||||
_logger.error("Error rendering reset password template '%s': %s", template_name, e)
|
||||
auth_signup_home = AuthSignupHome()
|
||||
return auth_signup_home.web_auth_reset_password(redirect=redirect, **kw)
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ class ExpertLoginTemplate(models.Model):
|
|||
_rec_name = 'name'
|
||||
_order = 'sequence, name'
|
||||
|
||||
name = fields.Char(string='Template Name', required=True, help='Name of the login page template')
|
||||
name = fields.Char(string='Template Name', required=True, translate=True, help='Name of the login page template')
|
||||
active = fields.Boolean(string='Active', default=False, help='Only one template can be active at a time. Activate this template to use it on the login page.')
|
||||
sequence = fields.Integer(string='Sequence', default=10, help='Order of display')
|
||||
|
||||
|
|
@ -37,47 +37,47 @@ class ExpertLoginTemplate(models.Model):
|
|||
corporate_template_logo = fields.Binary(string='Corporate Template Logo', help='Company logo to display on Corporate login, signup, and reset password pages')
|
||||
|
||||
# Modern Template Text Fields
|
||||
modern_login_title = fields.Char(string='Login Title', default='Welcome to Expert 👋', help='Title text for Modern template login page')
|
||||
modern_login_subtitle = fields.Char(string='Login Subtitle', default='Kindly fill in your details below to sign in to your account', help='Subtitle text for Modern template login page')
|
||||
modern_login_button_text = fields.Char(string='Login Button Text', default='Sign In', help='Button text for Modern template login page')
|
||||
modern_login_title = fields.Char(string='Login Title', default='Welcome to Expert 👋', translate=True, help='Title text for Modern template login page')
|
||||
modern_login_subtitle = fields.Char(string='Login Subtitle', default='Kindly fill in your details below to sign in to your account', translate=True, help='Subtitle text for Modern template login page')
|
||||
modern_login_button_text = fields.Char(string='Login Button Text', default='Sign In', translate=True, help='Button text for Modern template login page')
|
||||
modern_login_button_bg_color = fields.Char(string='Login Button Background', default='#007bff', help='Background color for login button')
|
||||
modern_login_button_text_color = fields.Char(string='Login Button Text Color', default='#FFFFFF', help='Text color for login button')
|
||||
modern_login_button_bg_hover = fields.Char(string='Login Button BG Hover', default='#0056b3', help='Background color for login button on hover')
|
||||
modern_login_button_text_hover = fields.Char(string='Login Button Text Hover', default='#FFFFFF', help='Text color for login button on hover')
|
||||
|
||||
modern_signup_title = fields.Char(string='Signup Title', default='Create an account', help='Title text for Modern template signup page')
|
||||
modern_signup_subtitle = fields.Char(string='Signup Subtitle', default='Join us today and get started', help='Subtitle text for Modern template signup page')
|
||||
modern_signup_button_text = fields.Char(string='Signup Button Text', default='Create an account', help='Button text for Modern template signup page')
|
||||
modern_signup_title = fields.Char(string='Signup Title', default='Create an account', translate=True, help='Title text for Modern template signup page')
|
||||
modern_signup_subtitle = fields.Char(string='Signup Subtitle', default='Join us today and get started', translate=True, help='Subtitle text for Modern template signup page')
|
||||
modern_signup_button_text = fields.Char(string='Signup Button Text', default='Create an account', translate=True, help='Button text for Modern template signup page')
|
||||
modern_signup_button_bg_color = fields.Char(string='Signup Button Background', default='#28a745', help='Background color for signup button')
|
||||
modern_signup_button_text_color = fields.Char(string='Signup Button Text Color', default='#FFFFFF', help='Text color for signup button')
|
||||
modern_signup_button_bg_hover = fields.Char(string='Signup Button BG Hover', default='#218838', help='Background color for signup button on hover')
|
||||
modern_signup_button_text_hover = fields.Char(string='Signup Button Text Hover', default='#FFFFFF', help='Text color for signup button on hover')
|
||||
|
||||
modern_reset_title = fields.Char(string='Reset Password Title', default='Reset your password', help='Title text for Modern template reset password page')
|
||||
modern_reset_subtitle = fields.Char(string='Reset Password Subtitle', default='Enter your email to receive reset instructions', help='Subtitle text for Modern template reset password page')
|
||||
modern_reset_title = fields.Char(string='Reset Password Title', default='Reset your password', translate=True, help='Title text for Modern template reset password page')
|
||||
modern_reset_subtitle = fields.Char(string='Reset Password Subtitle', default='Enter your email to receive reset instructions', translate=True, help='Subtitle text for Modern template reset password page')
|
||||
|
||||
# Minimal Template Text Fields
|
||||
minimal_login_title = fields.Char(string='Login Title', default='Welcome to Expert 👋', help='Title text for Minimal template login page')
|
||||
minimal_login_subtitle = fields.Char(string='Login Subtitle', default='Kindly fill in your details below to sign in to your account', help='Subtitle text for Minimal template login page')
|
||||
minimal_login_button_text = fields.Char(string='Login Button Text', default='Sign In', help='Button text for Minimal template login page')
|
||||
minimal_login_title = fields.Char(string='Login Title', default='Welcome to Expert 👋', translate=True, help='Title text for Minimal template login page')
|
||||
minimal_login_subtitle = fields.Char(string='Login Subtitle', default='Kindly fill in your details below to sign in to your account', translate=True, help='Subtitle text for Minimal template login page')
|
||||
minimal_login_button_text = fields.Char(string='Login Button Text', default='Sign In', translate=True, help='Button text for Minimal template login page')
|
||||
minimal_login_button_bg_color = fields.Char(string='Login Button Background', default='#E5E5E5', help='Background color for login button')
|
||||
minimal_login_button_text_color = fields.Char(string='Login Button Text Color', default='#000000', help='Text color for login button')
|
||||
minimal_login_button_bg_hover = fields.Char(string='Login Button BG Hover', default='#D0D0D0', help='Background color for login button on hover')
|
||||
minimal_login_button_text_hover = fields.Char(string='Login Button Text Hover', default='#000000', help='Text color for login button on hover')
|
||||
|
||||
minimal_signup_title = fields.Char(string='Signup Title', default='Create an account', help='Title text for Minimal template signup page')
|
||||
minimal_signup_subtitle = fields.Char(string='Signup Subtitle', default='Join us today and get started', help='Subtitle text for Minimal template signup page')
|
||||
minimal_signup_button_text = fields.Char(string='Signup Button Text', default='Create an account', help='Button text for Minimal template signup page')
|
||||
minimal_signup_title = fields.Char(string='Signup Title', default='Create an account', translate=True, help='Title text for Minimal template signup page')
|
||||
minimal_signup_subtitle = fields.Char(string='Signup Subtitle', default='Join us today and get started', translate=True, help='Subtitle text for Minimal template signup page')
|
||||
minimal_signup_button_text = fields.Char(string='Signup Button Text', default='Create an account', translate=True, help='Button text for Minimal template signup page')
|
||||
minimal_signup_button_bg_color = fields.Char(string='Signup Button Background', default='#000000', help='Background color for signup button')
|
||||
minimal_signup_button_text_color = fields.Char(string='Signup Button Text Color', default='#FFFFFF', help='Text color for signup button')
|
||||
minimal_signup_button_bg_hover = fields.Char(string='Signup Button BG Hover', default='#333333', help='Background color for signup button on hover')
|
||||
minimal_signup_button_text_hover = fields.Char(string='Signup Button Text Hover', default='#FFFFFF', help='Text color for signup button on hover')
|
||||
|
||||
minimal_reset_title = fields.Char(string='Reset Password Title', default='Reset your password', help='Title text for Minimal template reset password page')
|
||||
minimal_reset_subtitle = fields.Char(string='Reset Password Subtitle', default='Enter your email to receive reset instructions', help='Subtitle text for Minimal template reset password page')
|
||||
minimal_reset_title = fields.Char(string='Reset Password Title', default='Reset your password', translate=True, help='Title text for Minimal template reset password page')
|
||||
minimal_reset_subtitle = fields.Char(string='Reset Password Subtitle', default='Enter your email to receive reset instructions', translate=True, help='Subtitle text for Minimal template reset password page')
|
||||
|
||||
# Description
|
||||
description = fields.Text(string='Description', help='Description of this template')
|
||||
description = fields.Text(string='Description', translate=True, help='Description of this template')
|
||||
|
||||
@api.model
|
||||
def get_active_template(self):
|
||||
|
|
@ -111,13 +111,14 @@ class ExpertLoginTemplate(models.Model):
|
|||
def create(self, vals):
|
||||
"""Ensure only one template is active at a time"""
|
||||
# If no active value is set, default to False (don't auto-activate new templates)
|
||||
if 'active' not in vals:
|
||||
vals['active'] = False
|
||||
if 'active' not in vals[0]:
|
||||
vals[0]['active'] = False
|
||||
# Only deactivate others if this one is being set to active
|
||||
if vals.get('active'):
|
||||
print(vals[0])
|
||||
if vals[0].get('active'):
|
||||
# Deactivate all other templates (excluding the one being created)
|
||||
self.search([('active', '=', True)]).write({'active': False})
|
||||
return super(ExpertLoginTemplate, self).create(vals)
|
||||
return super(ExpertLoginTemplate, self).create(vals[0])
|
||||
|
||||
def write(self, vals):
|
||||
"""Ensure only one template is active at a time"""
|
||||
|
|
@ -133,6 +134,7 @@ class ExpertLoginTemplate(models.Model):
|
|||
super(ExpertLoginTemplate, other_templates).write({'active': False})
|
||||
need_reload = True
|
||||
|
||||
view = self.env.ref('custom_auth_theme.view_custom_login_inherit', raise_if_not_found=False)
|
||||
result = super(ExpertLoginTemplate, self).write(vals)
|
||||
|
||||
# Update template views if active state changed
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
|
|
@ -1,269 +0,0 @@
|
|||
/* Expert Theme - Minimal Login Template Styles */
|
||||
|
||||
.expert-login-minimal {
|
||||
background: #FFFFFF;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .container-fluid {
|
||||
height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.expert-login-minimal .row {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Left Column: Login Form */
|
||||
.expert-login-minimal .expert-login-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Logo Section */
|
||||
.expert-login-minimal .expert-login-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-logo .expert-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: #000000;
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-logo .expert-logo-icon span {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-logo .expert-logo-text {
|
||||
color: #000000;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Welcome Section */
|
||||
.expert-login-minimal .expert-login-welcome {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome h1 {
|
||||
color: #000000;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome h1 .welcome-emoji {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome p {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 16px;
|
||||
margin-bottom: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Form Section */
|
||||
.expert-login-minimal .expert-login-form {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-group {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-group label {
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="text"],
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="password"] {
|
||||
background: #FFFFFF !important;
|
||||
border: 1px solid #000000 !important;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: #000000 !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="text"]::placeholder,
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="password"]::placeholder {
|
||||
color: rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="text"]:focus,
|
||||
.expert-login-minimal .expert-login-form .form-group input[type="password"]:focus {
|
||||
background: #FFFFFF !important;
|
||||
border-color: #000000 !important;
|
||||
outline: none;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-check {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-check label {
|
||||
color: #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form .form-check label input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #000000;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form button[type="submit"] {
|
||||
width: 100%;
|
||||
background: #E5E5E5;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form button[type="submit"]:hover {
|
||||
background: #D5D5D5;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-form button[type="submit"]:active {
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
/* Login Link Section */
|
||||
.expert-login-minimal .expert-login-link {
|
||||
margin-top: 24px;
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-link p {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-link p a {
|
||||
color: #000000;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-link p a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Right Column: Image Section */
|
||||
.expert-login-minimal .expert-login-right {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-right .expert-login-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-right .expert-login-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-minimal-illustration {
|
||||
width: 600px !important;
|
||||
height: 600px !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* Alert Messages */
|
||||
.expert-login-minimal .alert {
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 20px;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.expert-login-minimal .alert-danger {
|
||||
background-color: #F8D7DA;
|
||||
border: 1px solid #F5C6CB;
|
||||
color: #721C24;
|
||||
}
|
||||
|
||||
.expert-login-minimal .alert-success {
|
||||
background-color: #D4EDDA;
|
||||
border: 1px solid #C3E6CB;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 991.98px) {
|
||||
.expert-login-minimal .expert-login-left {
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome h1 .welcome-emoji {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.expert-login-minimal .expert-login-welcome p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,234 +0,0 @@
|
|||
/* Expert Theme - Modern Login Template Styles */
|
||||
|
||||
.expert-login-modern {
|
||||
background: #19181F !important;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.expert-login-modern .container-fluid {
|
||||
height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.expert-login-modern .row {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Left Column: Login Form */
|
||||
.expert-login-modern .expert-login-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Logo Section */
|
||||
.expert-login-modern .expert-login-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-logo .expert-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-logo .expert-logo-icon span {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-logo .expert-logo-text {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Welcome Section */
|
||||
.expert-login-modern .expert-login-welcome {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome h1 {
|
||||
color: white;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome h1 .welcome-emoji {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 16px;
|
||||
margin-bottom: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Form Section */
|
||||
.expert-login-modern .expert-login-form {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-group {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-group label {
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-group input[type="text"],
|
||||
.expert-login-modern .expert-login-form .form-group input[type="password"] {
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: white !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-group input[type="text"]::placeholder,
|
||||
.expert-login-modern .expert-login-form .form-group input[type="password"]::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-group input[type="text"]:focus,
|
||||
.expert-login-modern .expert-login-form .form-group input[type="password"]:focus {
|
||||
background: rgba(255, 255, 255, 0.15) !important;
|
||||
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||
outline: none;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-check {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-check label {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form .form-check label input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #667eea;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form button[type="submit"] {
|
||||
width: 100%;
|
||||
background: #764ba2;
|
||||
border: none !important;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-form button[type="submit"]:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Login Link Section */
|
||||
.expert-login-modern .expert-login-link {
|
||||
margin-top: 24px;
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-link p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-link p a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-link p a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Right Column: Image Section */
|
||||
.expert-login-modern .expert-login-right {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-right .expert-login-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-right .expert-login-image img {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 991.98px) {
|
||||
.expert-login-modern .expert-login-left {
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome h1 .welcome-emoji {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.expert-login-modern .expert-login-welcome p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,9 +47,9 @@
|
|||
body {
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%) !important;
|
||||
background: linear-gradient(135deg, var(--expert-bg-gradient-start, #f5f7fa) 0%, var(--expert-bg-gradient-end, #c3cfe2) 100%) !important;
|
||||
min-height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
// min-height: 100vh !important;
|
||||
// margin: 0 !important;
|
||||
// padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Ensure the gradient shows on the main content area */
|
||||
|
|
@ -58,7 +58,7 @@ body {
|
|||
.o_action_manager .o_view_controller .o_content {
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%) !important;
|
||||
background: linear-gradient(135deg, var(--expert-bg-gradient-start, #f5f7fa) 0%, var(--expert-bg-gradient-end, #c3cfe2) 100%) !important;
|
||||
min-height: 100vh !important;
|
||||
// min-height: 100vh !important;
|
||||
}
|
||||
|
||||
/* Override any Odoo background colors that might interfere */
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
/* Expert Theme - Minimal Login Template Styles */
|
||||
.expert-login-minimal {
|
||||
background: #FFFFFF;
|
||||
min-height: 100vh;
|
||||
|
||||
.expert-login-left {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
min-height: 100vh;
|
||||
|
||||
.expert-login-form-container {
|
||||
max-width: 450px;
|
||||
|
||||
|
||||
.expert-login-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
width: 100%;
|
||||
|
||||
.expert-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: #000000;
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
span {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.expert-logo-text {
|
||||
color: #000000;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.expert-login-welcome {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
|
||||
h1 {
|
||||
color: #000000;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
|
||||
.welcome-emoji {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 16px;
|
||||
margin-bottom: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.expert-login-form {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
background-color: transparent !important;
|
||||
|
||||
.oe_login_form,
|
||||
.oe_signup_form,
|
||||
.oe_reset_password_form {
|
||||
max-width: 450px;
|
||||
background-color: transparent !important;
|
||||
|
||||
label {
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
&[type="text"],
|
||||
&[type="password"] {
|
||||
background: #FFFFFF !important;
|
||||
border: 1px solid #000000 !important;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: #000000 !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&[type="text"]::placeholder,
|
||||
&[type="password"]::placeholder {
|
||||
color: rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
&[type="text"]:focus,
|
||||
&[type="password"]:focus {
|
||||
background: #FFFFFF !important;
|
||||
border-color: #000000 !important;
|
||||
outline: none;
|
||||
color: #000000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-check {
|
||||
margin-bottom: 32px;
|
||||
|
||||
label {
|
||||
color: #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.btn-link {
|
||||
color: #5a5a5a;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
width: 100%;
|
||||
background: #E5E5E5;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:hover {
|
||||
background: #D5D5D5;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #CCCCCC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.expert-login-link {
|
||||
margin-top: 24px;
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
color: #000000;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.expert-login-right {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 100vh;
|
||||
|
||||
.expert-login-image {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.expert-minimal-illustration {
|
||||
width: 600px !important;
|
||||
height: 600px !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.alert {
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 20px;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background-color: #F8D7DA;
|
||||
border: 1px solid #F5C6CB;
|
||||
color: #721C24;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #D4EDDA;
|
||||
border: 1px solid #C3E6CB;
|
||||
color: #155724;
|
||||
}
|
||||
}
|
||||
|
||||
/* Left Column: Login Form */
|
||||
|
||||
/* Logo Section */
|
||||
|
||||
/* Welcome Section */
|
||||
|
||||
/* Form Section */
|
||||
|
||||
/* Login Link Section */
|
||||
|
||||
/* Right Column: Image Section */
|
||||
|
||||
/* Alert Messages */
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 991.98px) {
|
||||
.expert-login-minimal {
|
||||
.expert-login-left {
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
.expert-login-welcome {
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
|
||||
.welcome-emoji {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,177 +1,180 @@
|
|||
/* Expert Theme - Modern Login Template Styles */
|
||||
|
||||
.expert-login-modern {
|
||||
background: #19181F;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
|
||||
.container-fluid {
|
||||
height: calc(100vh - 40px);
|
||||
}
|
||||
|
||||
.row {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// Left Column: Login Form
|
||||
.expert-login-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
// Logo Section
|
||||
.expert-login-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 40px;
|
||||
min-height: 100vh;
|
||||
|
||||
.expert-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.expert-login-form-container {
|
||||
max-width: 450px;
|
||||
|
||||
span {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.expert-logo-text {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
// Welcome Section
|
||||
.expert-login-welcome {
|
||||
h1 {
|
||||
color: white;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
|
||||
.welcome-emoji {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 16px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// Form Section
|
||||
.expert-login-form {
|
||||
max-width: 450px;
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 24px;
|
||||
|
||||
label {
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(255, 255, 255, 0.15) !important;
|
||||
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||
outline: none;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-check {
|
||||
margin-bottom: 32px;
|
||||
|
||||
label {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
// Logo Section
|
||||
.expert-login-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 40px;
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #667eea;
|
||||
.expert-logo-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
span {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.expert-logo-text {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button[type="submit"] {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
// Welcome Section
|
||||
.expert-login-welcome {
|
||||
h1 {
|
||||
color: white;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.2;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
|
||||
.welcome-emoji {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 16px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Login Link Section
|
||||
.expert-login-link {
|
||||
margin-top: 24px;
|
||||
max-width: 450px;
|
||||
// Form Section
|
||||
.expert-login-form {
|
||||
|
||||
p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
.oe_login_form,
|
||||
.oe_signup_form,
|
||||
.oe_reset_password_form {
|
||||
max-width: 450px;
|
||||
background-color: transparent !important;
|
||||
|
||||
a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
.form-label,
|
||||
label {
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
.form-control {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(255, 255, 255, 0.15) !important;
|
||||
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||
outline: none;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check {
|
||||
margin-bottom: 32px;
|
||||
|
||||
label {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-right: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
accent-color: #667eea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
color: #939393;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Login Link Section
|
||||
.expert-login-link {
|
||||
margin-top: 24px;
|
||||
max-width: 450px;
|
||||
|
||||
p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -183,15 +186,27 @@
|
|||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 20px 0 0 20px;
|
||||
|
||||
min-height: 100vh;
|
||||
|
||||
.expert-login-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 25%, #667eea 75%, #764ba2 100%);
|
||||
// background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 25%, #667eea 75%, #764ba2 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
|
||||
.expert-login-image-cover {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #667eea;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.expert-spiral-decoration {
|
||||
width: 400px;
|
||||
|
|
@ -254,5 +269,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
<p>Your installed modules are listed below</p>
|
||||
</div>
|
||||
<div class="expert-modules-grid" id="expert-modules-container">
|
||||
<!-- Modules will be loaded here via JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
|
|
|||
|
|
@ -3,31 +3,33 @@
|
|||
<data>
|
||||
<!-- Create a new top-level menu for Expert Home -->
|
||||
<menuitem id="menu_expert_root"
|
||||
name="Expert Home"
|
||||
sequence="1"/>
|
||||
|
||||
<menuitem id="menu_expert_home"
|
||||
name="Dashboard"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_home"
|
||||
sequence="1"/>
|
||||
|
||||
<menuitem id="menu_expert_login_templates"
|
||||
name="Login Page Templates"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_login_template"
|
||||
sequence="2"/>
|
||||
|
||||
<menuitem id="menu_expert_theme_colors"
|
||||
name="Theme Colors"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_theme_config"
|
||||
sequence="3"/>
|
||||
|
||||
<!-- Also add Theme Colors to the main menu for easier access -->
|
||||
<menuitem id="menu_theme_colors_main"
|
||||
name="Theme Colors"
|
||||
action="action_expert_theme_config"
|
||||
sequence="100"/>
|
||||
name="Odex Theme"
|
||||
web_icon="expert_theme,static/description/icon.png"
|
||||
sequence="1000" />
|
||||
|
||||
<!-- <menuitem id="menu_expert_home"
|
||||
name="Dashboard"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_home"
|
||||
sequence="1" /> -->
|
||||
|
||||
<menuitem id="menu_expert_theme_colors"
|
||||
name="Theme Colors"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_theme_config"
|
||||
sequence="1" />
|
||||
|
||||
<menuitem id="menu_expert_login_templates"
|
||||
name="Login Page Templates"
|
||||
parent="menu_expert_root"
|
||||
action="action_expert_login_template"
|
||||
sequence="2" />
|
||||
|
||||
|
||||
<!-- Also add Theme Colors to the main menu for easier access -->
|
||||
<!-- <menuitem id="menu_theme_colors_main"
|
||||
name="Theme Colors"
|
||||
action="action_expert_theme_config"
|
||||
sequence="100" /> -->
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,785 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!--
|
||||
Multiple Login Page Templates with Different HTML Structures
|
||||
Standalone templates rendered by the /web/login override.
|
||||
Each template calls web.layout and defines its own login form.
|
||||
-->
|
||||
|
||||
<!-- Template 1: Modern Card Design -->
|
||||
<template id="login_template_modern_page" name="Modern Login Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-modern">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Login Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.modern_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.modern_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.modern_login_title">
|
||||
<t t-esc="login_template.modern_login_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Welcome to Expert <span class="welcome-emoji">👋</span>
|
||||
</t>
|
||||
</h1>
|
||||
<p>
|
||||
<t t-if="login_template and login_template.modern_login_subtitle">
|
||||
<t t-esc="login_template.modern_login_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Kindly fill in your details below to sign in to your account
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Login Form -->
|
||||
<form class="oe_login_form expert-login-form" role="form" method="post" t-att-action="request.httprequest.path">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email or Username</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email or username"
|
||||
t-att-value="login"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
placeholder="Enter your password"/>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<label>
|
||||
<input type="checkbox" name="remember"/>
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<t t-if="login_template and login_template.modern_login_button_text"><t t-esc="login_template.modern_login_button_text"/></t><t t-else="">Sign In</t>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Signup Link -->
|
||||
<div class="expert-login-link">
|
||||
<p>
|
||||
Don't have an account?
|
||||
<a t-attf-href="/web/signup?{{ keep_query() }}">Sign Up</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.modern_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.modern_template_image.decode('utf-8')"
|
||||
alt="Login Image" class="img-fluid"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/modern-template-bg.png"
|
||||
alt="Login Image" class="img-fluid"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Modern Signup Template -->
|
||||
<template id="signup_template_modern_page" name="Modern Signup Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-modern">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Signup Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.modern_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.modern_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.modern_signup_title">
|
||||
<t t-esc="login_template.modern_signup_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Create an account
|
||||
</t>
|
||||
</h1>
|
||||
<p>
|
||||
<t t-if="login_template and login_template.modern_signup_subtitle">
|
||||
<t t-esc="login_template.modern_signup_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Join us today and get started
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Signup Form -->
|
||||
<form class="oe_signup_form expert-login-form" role="form" method="post" t-if="not message">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
<input type="hidden" name="token" t-att-value="token or ''"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Your Email</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email"
|
||||
t-att-value="login"
|
||||
t-att-readonly="'readonly' if (token and not invalid_token) else None"
|
||||
autofocus="autofocus"
|
||||
autocapitalize="off"
|
||||
required="required"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group" t-if="not (token and not invalid_token)">
|
||||
<label>Your Name</label>
|
||||
<input type="text" name="name" class="form-control"
|
||||
placeholder="e.g. John Doe"
|
||||
t-att-value="name"
|
||||
required="required"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Enter your password"
|
||||
required="required"
|
||||
t-att-autofocus="'autofocus' if (token and not invalid_token) else None"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Confirm Password</label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" class="form-control"
|
||||
placeholder="Confirm your password"
|
||||
required="required"/>
|
||||
</div>
|
||||
|
||||
<p class="alert alert-danger" t-if="error" role="alert">
|
||||
<t t-esc="error"/>
|
||||
</p>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<t t-if="login_template and login_template.modern_signup_button_text">
|
||||
<t t-esc="login_template.modern_signup_button_text"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Sign Up
|
||||
</t>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Signup Link -->
|
||||
<div class="expert-login-link">
|
||||
<p>
|
||||
Already have an account?
|
||||
<a t-attf-href="/web/login?{{ keep_query() }}">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.modern_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.modern_template_image.decode('utf-8')"
|
||||
alt="Signup Image" class="img-fluid"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/modern-template-bg.png"
|
||||
alt="Signup Image" class="img-fluid"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Modern Reset Password Template -->
|
||||
<template id="reset_password_template_modern_page" name="Modern Reset Password Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-modern">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Reset Password Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.modern_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.modern_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.modern_reset_title">
|
||||
<t t-esc="login_template.modern_reset_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Reset Password <span class="welcome-emoji">🔐</span>
|
||||
</t>
|
||||
</h1>
|
||||
<p t-if="not token">
|
||||
<t t-if="login_template and login_template.modern_reset_subtitle">
|
||||
<t t-esc="login_template.modern_reset_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Enter your email address and we'll send you instructions to reset your password
|
||||
</t>
|
||||
</p>
|
||||
<p t-if="token and not invalid_token">
|
||||
Enter your new password below
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Success Message -->
|
||||
<div t-if="message" class="expert-login-form">
|
||||
<p class="alert alert-success" role="status">
|
||||
<t t-esc="message"/>
|
||||
</p>
|
||||
<a href="/web/login" class="btn btn-link" style="color: #667eea;">Back to Login</a>
|
||||
</div>
|
||||
|
||||
<!-- Reset Password Form -->
|
||||
<form class="oe_reset_password_form expert-login-form" role="form" method="post" t-if="not message">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
<input type="hidden" name="token" t-att-value="token or ''"/>
|
||||
|
||||
<!-- Token-based reset (set new password) -->
|
||||
<t t-if="token and not invalid_token">
|
||||
<div class="form-group">
|
||||
<label>New Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Enter your new password"
|
||||
required="required"
|
||||
autofocus="autofocus"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Confirm Password</label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" class="form-control"
|
||||
placeholder="Confirm your new password"
|
||||
required="required"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Email-based reset (request reset) -->
|
||||
<t t-if="not token">
|
||||
<div class="form-group">
|
||||
<label>Your Email</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email"
|
||||
t-att-value="login"
|
||||
autofocus="autofocus"
|
||||
required="required"
|
||||
autocapitalize="off"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<p class="alert alert-danger" t-if="error" role="alert">
|
||||
<t t-esc="error"/>
|
||||
</p>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<t t-if="token and not invalid_token">Reset Password</t>
|
||||
<t t-if="not token">Send Reset Instructions</t>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Reset Password Link -->
|
||||
<div class="expert-login-link" t-if="not message">
|
||||
<p>
|
||||
<a t-if="not token" t-attf-href="/web/login?{{ keep_query() }}" style="color: #667eea;">Back to Login</a>
|
||||
<a t-if="invalid_token" href="/web/login" style="color: #667eea;">Back to Login</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.modern_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.modern_template_image.decode('utf-8')"
|
||||
alt="Reset Password Image" class="img-fluid"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/modern-template-bg.png"
|
||||
alt="Reset Password Image" class="img-fluid"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Template 2: Minimal Design -->
|
||||
<template id="login_template_minimal_page" name="Minimal Login Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-minimal">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Login Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.minimal_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.minimal_login_title">
|
||||
<t t-esc="login_template.minimal_login_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Welcome to Expert <span class="welcome-emoji">👋</span>
|
||||
</t>
|
||||
</h1>
|
||||
<p>
|
||||
<t t-if="login_template and login_template.minimal_login_subtitle">
|
||||
<t t-esc="login_template.minimal_login_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Kindly fill in your details below to sign in to your account
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Login Form -->
|
||||
<form class="oe_login_form expert-login-form" role="form" method="post" t-att-action="request.httprequest.path">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Email or Username</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email or username"
|
||||
t-att-value="login"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
placeholder="Enter your password"/>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<label>
|
||||
<input type="checkbox" name="remember"/>
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<t t-if="login_template and login_template.modern_login_button_text"><t t-esc="login_template.modern_login_button_text"/></t><t t-else="">Sign In</t>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Signup Link -->
|
||||
<div class="expert-login-link">
|
||||
<p>
|
||||
Don't have an account?
|
||||
<a t-attf-href="/web/signup?{{ keep_query() }}">Sign Up</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.minimal_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_image.decode('utf-8')"
|
||||
alt="Login Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/minimal-login-img.png"
|
||||
alt="Login Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Minimal Signup Template -->
|
||||
<template id="signup_template_minimal_page" name="Minimal Signup Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-minimal">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Signup Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.minimal_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.minimal_signup_title">
|
||||
<t t-esc="login_template.minimal_signup_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Create an account
|
||||
</t>
|
||||
</h1>
|
||||
<p>
|
||||
<t t-if="login_template and login_template.minimal_signup_subtitle">
|
||||
<t t-esc="login_template.minimal_signup_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<a t-attf-href="/web/login?{{ keep_query() }}" style="color: #000; text-decoration: underline;">log in instead</a>
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Signup Form -->
|
||||
<form class="oe_signup_form expert-login-form" role="form" method="post" t-if="not message">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
<input type="hidden" name="token" t-att-value="token or ''"/>
|
||||
|
||||
<div class="form-group" t-if="not (token and not invalid_token)">
|
||||
<label>Your Name</label>
|
||||
<input type="text" name="name" class="form-control"
|
||||
placeholder="e.g. John Doe"
|
||||
t-att-value="name"
|
||||
required="required"
|
||||
t-att-autofocus="'autofocus' if login and not (token and not invalid_token) else None"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Your Email</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email"
|
||||
t-att-value="login"
|
||||
t-att-readonly="'readonly' if (token and not invalid_token) else None"
|
||||
autofocus="autofocus"
|
||||
autocapitalize="off"
|
||||
required="required"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Enter your password"
|
||||
required="required"
|
||||
t-att-autofocus="'autofocus' if (token and not invalid_token) else None"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Confirm Password</label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" class="form-control"
|
||||
placeholder="Confirm your password"
|
||||
required="required"/>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<label>
|
||||
<input type="checkbox" name="terms" required="required"/>
|
||||
By creating an account, I agree to our <a href="#" style="color: #000; text-decoration: underline;">Terms of use</a> and <a href="#" style="color: #000; text-decoration: underline;">Privacy Policy</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<p class="alert alert-danger" t-if="error" role="alert">
|
||||
<t t-esc="error"/>
|
||||
</p>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Create an account
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Login Link -->
|
||||
<div class="expert-login-link">
|
||||
<p>
|
||||
Already have an account?
|
||||
<a t-attf-href="/web/login?{{ keep_query() }}" style="color: #000; text-decoration: underline;">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.minimal_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_image.decode('utf-8')"
|
||||
alt="Signup Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/minimal-login-img.png"
|
||||
alt="Signup Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Minimal Reset Password Template -->
|
||||
<template id="reset_password_template_minimal_page" name="Minimal Reset Password Template">
|
||||
<t t-call="web.layout">
|
||||
<t t-set="head">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<t t-call-assets="web.assets_frontend" t-js="false"/>
|
||||
</t>
|
||||
<t t-set="body_classname" t-value="'bg-100'"/>
|
||||
<div class="oe_login_form expert-login-minimal">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row">
|
||||
<!-- Left Column: Reset Password Form (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 expert-login-left">
|
||||
<!-- Logo and Text -->
|
||||
<div class="expert-login-logo">
|
||||
<t t-if="login_template and login_template.minimal_template_logo">
|
||||
<img t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_logo.decode('utf-8')"
|
||||
alt="Company Logo"
|
||||
style="width: 40px; height: 40px; object-fit: contain; margin-right: 12px;"/>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="expert-logo-icon">
|
||||
<span>E</span>
|
||||
</div>
|
||||
<span class="expert-logo-text">Expert</span>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- Welcome Text -->
|
||||
<div class="expert-login-welcome">
|
||||
<h1>
|
||||
<t t-if="login_template and login_template.minimal_reset_title">
|
||||
<t t-esc="login_template.minimal_reset_title"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Reset Password <span class="welcome-emoji">🔐</span>
|
||||
</t>
|
||||
</h1>
|
||||
<p t-if="not token">
|
||||
<t t-if="login_template and login_template.minimal_reset_subtitle">
|
||||
<t t-esc="login_template.minimal_reset_subtitle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
Enter your email address and we'll send you instructions to reset your password
|
||||
</t>
|
||||
</p>
|
||||
<p t-if="token and not invalid_token">
|
||||
Enter your new password below
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Success Message -->
|
||||
<div t-if="message" class="expert-login-form">
|
||||
<p class="alert alert-success" role="status">
|
||||
<t t-esc="message"/>
|
||||
</p>
|
||||
<a href="/web/login" class="btn btn-link" style="color: #000; text-decoration: underline;">Back to Login</a>
|
||||
</div>
|
||||
|
||||
<!-- Reset Password Form -->
|
||||
<form class="oe_reset_password_form expert-login-form" role="form" method="post" t-if="not message">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
<input type="hidden" name="token" t-att-value="token or ''"/>
|
||||
|
||||
<!-- Token-based reset (set new password) -->
|
||||
<t t-if="token and not invalid_token">
|
||||
<div class="form-group">
|
||||
<label>New Password</label>
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Enter your new password"
|
||||
required="required"
|
||||
autofocus="autofocus"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Confirm Password</label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" class="form-control"
|
||||
placeholder="Confirm your new password"
|
||||
required="required"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- Email-based reset (request reset) -->
|
||||
<t t-if="not token">
|
||||
<div class="form-group">
|
||||
<label>Email</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your email"
|
||||
t-att-value="login"
|
||||
autofocus="autofocus"
|
||||
required="required"
|
||||
autocapitalize="off"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<p class="alert alert-danger" t-if="error" role="alert">
|
||||
<t t-esc="error"/>
|
||||
</p>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<t t-if="token and not invalid_token">Reset Password</t>
|
||||
<t t-if="not token">Send Reset Instructions</t>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Reset Password Link -->
|
||||
<div class="expert-login-link" t-if="not message">
|
||||
<p>
|
||||
<a t-if="not token" t-attf-href="/web/login?{{ keep_query() }}" style="color: #000; text-decoration: underline;">Back to Login</a>
|
||||
<a t-if="invalid_token" href="/web/login" style="color: #000; text-decoration: underline;">Back to Login</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Image (6 columns) -->
|
||||
<div class="col-lg-6 col-md-12 d-none d-lg-block expert-login-right">
|
||||
<div class="expert-login-image">
|
||||
<img t-if="login_template and login_template.minimal_template_image"
|
||||
t-att-src="'data:image/png;base64,%s' % login_template.minimal_template_image.decode('utf-8')"
|
||||
alt="Reset Password Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
<img t-else=""
|
||||
src="/expert_theme/static/src/img/minimal-login-img.png"
|
||||
alt="Reset Password Illustration" class="img-fluid expert-minimal-illustration"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Template 3: Corporate Design -->
|
||||
<template id="login_template_corporate_page" name="Corporate Login Template">
|
||||
<t t-call="web.layout">
|
||||
<div class="oe_login_form" style="background: #1a1a1a; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px;">
|
||||
<div style="width: 100%; max-width: 500px; background: #2d2d2d; padding: 60px 50px; border-radius: 8px; border: 1px solid #404040;">
|
||||
<div class="text-center mb-5">
|
||||
<h2 style="color: #fff; font-size: 32px; font-weight: 600; margin-bottom: 10px;">Company Portal</h2>
|
||||
<p style="color: #999; font-size: 14px; margin: 0;">Secure Login Access</p>
|
||||
</div>
|
||||
<form class="oe_login_form" role="form" method="post" t-att-action="request.httprequest.path">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="redirect" t-att-value="redirect or ''"/>
|
||||
|
||||
<div style="margin-bottom: 25px;">
|
||||
<label style="color: #ccc; font-size: 13px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; display: block;">Username</label>
|
||||
<input type="text" name="login" class="form-control"
|
||||
placeholder="Enter your username"
|
||||
t-att-value="login"
|
||||
style="background: #1a1a1a; border: 1px solid #404040; color: #fff; padding: 12px 15px; border-radius: 4px; width: 100%; box-sizing: border-box;"/>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 35px;">
|
||||
<label style="color: #ccc; font-size: 13px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; display: block;">Password</label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
placeholder="Enter your password"
|
||||
style="background: #1a1a1a; border: 1px solid #404040; color: #fff; padding: 12px 15px; border-radius: 4px; width: 100%; box-sizing: border-box;"/>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-block"
|
||||
style="width: 100%; background: #007bff; color: white; border: none; padding: 14px; font-size: 15px; font-weight: 600; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.5px;">
|
||||
Access Portal
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
||||
Loading…
Reference in New Issue