mig sttl_otp_login by yahya
|
|
@ -0,0 +1,2 @@
|
||||||
|
from . import controller
|
||||||
|
from . import models
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
"name": "Email OTP Authentication",
|
||||||
|
"version": "18.0.1.0.0",
|
||||||
|
"author": "Silver Touch Technologies Limited",
|
||||||
|
'category': 'Tools',
|
||||||
|
"website": "https://www.silvertouch.com/",
|
||||||
|
"description": """
|
||||||
|
""",
|
||||||
|
"summary": """
|
||||||
|
This module allows the user authentication of the database via OTP.
|
||||||
|
""",
|
||||||
|
'depends': ['base', 'mail', 'web', 'website', 'auth_signup'],
|
||||||
|
'data': [
|
||||||
|
"security/ir.model.access.csv",
|
||||||
|
"security/security_group.xml",
|
||||||
|
"views/otp_verification.xml",
|
||||||
|
"views/login_view.xml",
|
||||||
|
"views/otp_signup.xml",
|
||||||
|
"data/cron.xml"
|
||||||
|
],
|
||||||
|
"price": 0,
|
||||||
|
"currency": "USD",
|
||||||
|
"license": "LGPL-3",
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
'images': ['static/description/banner.png']
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
from . import otp_login
|
||||||
|
from . import otp_signup
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
from odoo import http, _
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.addons.web.controllers.home import Home
|
||||||
|
from odoo.exceptions import AccessDenied
|
||||||
|
from random import choice
|
||||||
|
import string
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
from odoo.addons.web.controllers.utils import ensure_db
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class OtpLoginHome(Home):
|
||||||
|
@http.route(website=True, auth='public')
|
||||||
|
def web_login(self, redirect=None, **kw):
|
||||||
|
"""Customized web_login for OTP flow (Odoo 18 compatible)"""
|
||||||
|
ensure_db()
|
||||||
|
qcontext = request.params.copy()
|
||||||
|
|
||||||
|
|
||||||
|
if request.httprequest.method == 'GET':
|
||||||
|
otp_login = kw.get('otp_login')
|
||||||
|
otp = kw.get('otp')
|
||||||
|
|
||||||
|
if otp_login and otp:
|
||||||
|
_logger.info("Rendering OTP verification page.")
|
||||||
|
return request.render("sttl_otp_login.custom_login_template", {
|
||||||
|
'otp': True,
|
||||||
|
'otp_login': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if otp_login:
|
||||||
|
_logger.info("Rendering OTP login page.")
|
||||||
|
return request.render("sttl_otp_login.custom_login_template", {
|
||||||
|
'otp_login': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return super(OtpLoginHome, self).web_login(redirect, **kw)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
login = kw.get('login')
|
||||||
|
password = kw.get('password')
|
||||||
|
|
||||||
|
if login:
|
||||||
|
request.params['login'] = login.strip()
|
||||||
|
if password:
|
||||||
|
request.params['password'] = password.strip()
|
||||||
|
|
||||||
|
_logger.info("Processing standard login for %s", login)
|
||||||
|
return super(OtpLoginHome, self).web_login(redirect, **kw)
|
||||||
|
|
||||||
|
def generate_otp(self, digits=4):
|
||||||
|
otp = ''.join(choice(string.digits) for _ in range(digits))
|
||||||
|
_logger.info("Generated OTP: %s", otp)
|
||||||
|
return otp
|
||||||
|
|
||||||
|
@http.route('/otp/login', type='http', auth='public', website=True, csrf=False)
|
||||||
|
def web_otp_login(self, **kw):
|
||||||
|
email = (kw.get('login') or '').strip()
|
||||||
|
|
||||||
|
if not email:
|
||||||
|
return request.render("sttl_otp_login.custom_login_template", {
|
||||||
|
'error': _('Please enter your email or login first.'),
|
||||||
|
'otp_login': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
user = request.env['res.users'].sudo().search([('login', '=', email)], limit=1)
|
||||||
|
if not user:
|
||||||
|
_logger.warning(" No user found for OTP login: %s", email)
|
||||||
|
return request.render("sttl_otp_login.custom_login_template", {
|
||||||
|
'error': _('No user found with this email.'),
|
||||||
|
'otp_login': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
OTP = self.generate_otp(4)
|
||||||
|
|
||||||
|
|
||||||
|
request.env['otp.verification'].sudo().create({
|
||||||
|
'email': email,
|
||||||
|
'otp': OTP,
|
||||||
|
'state': 'unverified',
|
||||||
|
})
|
||||||
|
|
||||||
|
_logger.info(" OTP for %s is %s", email, OTP)
|
||||||
|
|
||||||
|
# عرض صفحة إدخال OTP
|
||||||
|
return request.render("sttl_otp_login.custom_login_template", {
|
||||||
|
'otp_login': True,
|
||||||
|
'otp': True,
|
||||||
|
'login': email,
|
||||||
|
'otp_no': OTP,
|
||||||
|
# 'info_message': _("A verification code was sent to your email.")
|
||||||
|
})
|
||||||
|
|
||||||
|
@http.route('/otp/verify', type='http', auth='public', website=True, csrf=False)
|
||||||
|
def web_otp_verify(self, **kw):
|
||||||
|
|
||||||
|
email = kw.get('login')
|
||||||
|
otp_input = kw.get('otp')
|
||||||
|
|
||||||
|
|
||||||
|
otp_rec = request.env['otp.verification'].sudo().search(
|
||||||
|
[('email', '=', email)], order='create_date desc', limit=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if not otp_rec or otp_rec.otp != otp_input:
|
||||||
|
return request.render('sttl_otp_login.custom_login_template', {
|
||||||
|
'error': _("Invalid OTP. Please try again."),
|
||||||
|
'otp_login': True,
|
||||||
|
'login': email,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
otp_rec.state = 'verified'
|
||||||
|
|
||||||
|
|
||||||
|
user = request.env['res.users'].sudo().search([('login', '=', email)], limit=1)
|
||||||
|
if not user:
|
||||||
|
return request.render('sttl_otp_login.custom_login_template', {
|
||||||
|
'error': _("No account found for this email."),
|
||||||
|
'otp_login': True,
|
||||||
|
'login': email,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
credential = {'login': email, 'password': user.password or ''}
|
||||||
|
auth_info = request.session.authenticate(request.db, credential)
|
||||||
|
|
||||||
|
|
||||||
|
if auth_info and auth_info.get('uid'):
|
||||||
|
with request.env.registry.cursor() as cr:
|
||||||
|
env = request.env(user=auth_info['uid'])
|
||||||
|
request.session.finalize(env)
|
||||||
|
|
||||||
|
_logger.info(" User %s logged in successfully via OTP", email)
|
||||||
|
return request.redirect('/web')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(" Failed OTP login for %s: %s", email, e)
|
||||||
|
return request.render('sttl_otp_login.custom_login_template', {
|
||||||
|
'error': _("An unexpected error occurred. Please try again."),
|
||||||
|
'otp_login': True,
|
||||||
|
'login': email,
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
from odoo import http, _
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.addons.web.controllers.home import Home
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
import logging
|
||||||
|
import string
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class OtpSignup(Home):
|
||||||
|
|
||||||
|
def generate_otp(self, digits=4):
|
||||||
|
|
||||||
|
otp = ''.join(choice(string.digits) for _ in range(digits))
|
||||||
|
_logger.info(" Generated OTP: %s", otp)
|
||||||
|
return otp
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/web/signup/otp', type='http', auth='public', website=True, sitemap=False)
|
||||||
|
def web_signup_otp(self, **kw):
|
||||||
|
qcontext = request.params.copy()
|
||||||
|
if request.httprequest.method == 'GET':
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', qcontext)
|
||||||
|
OTP = self.generate_otp(4)
|
||||||
|
email = qcontext.get("login")
|
||||||
|
|
||||||
|
password = qcontext.get("password")
|
||||||
|
confirm_password = qcontext.get("confirm_password")
|
||||||
|
|
||||||
|
|
||||||
|
if not email or not password or not confirm_password:
|
||||||
|
qcontext["error"] = _("All fields are required.")
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', qcontext)
|
||||||
|
|
||||||
|
if password != confirm_password:
|
||||||
|
qcontext["error"] = _("Passwords do not match, please retype them.")
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', qcontext)
|
||||||
|
|
||||||
|
|
||||||
|
user_exist = request.env["res.users"].sudo().search([("login", "=", email)], limit=1)
|
||||||
|
if user_exist:
|
||||||
|
qcontext["error"] = _("Another user is already registered using this email address.")
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', qcontext)
|
||||||
|
else:
|
||||||
|
email = str(qcontext.get('login'))
|
||||||
|
# name = str(qcontext.get('name'))
|
||||||
|
# vals = {
|
||||||
|
# 'otp': OTP,
|
||||||
|
# 'email': email
|
||||||
|
# }
|
||||||
|
#send to email
|
||||||
|
# email_from = request.env.company.email
|
||||||
|
# mail_body = """\
|
||||||
|
# <html>
|
||||||
|
# <body>
|
||||||
|
# <p>
|
||||||
|
# Dear <b>%s</b>,
|
||||||
|
# <br>
|
||||||
|
# <p>
|
||||||
|
# To complete the verification process for your Odoo account,
|
||||||
|
# <br>Please use the following One-Time Password (OTP): <b>%s</b>
|
||||||
|
# </p>
|
||||||
|
# Thanks & Regards.
|
||||||
|
# </p>
|
||||||
|
# </body>
|
||||||
|
# </html>
|
||||||
|
# """ % (name, OTP)
|
||||||
|
# mail = request.env['mail.mail'].sudo().create({
|
||||||
|
# 'subject': _('Verify Your Odoo Account - OTP Required'),
|
||||||
|
# 'email_from': email_from,
|
||||||
|
# 'email_to': email,
|
||||||
|
# 'body_html': mail_body,
|
||||||
|
# })
|
||||||
|
# mail.send()
|
||||||
|
# response = request.render('sttl_otp_login.custom_otp_signup', {'otp': True, 'otp_login': True,
|
||||||
|
# 'login': qcontext["login"],
|
||||||
|
# 'otp_no': OTP,
|
||||||
|
# 'name': qcontext["name"],
|
||||||
|
# 'password': qcontext["password"],
|
||||||
|
# 'confirm_password': qcontext[
|
||||||
|
# "confirm_password"]})
|
||||||
|
# res = request.env['otp.verification'].sudo().create(vals)
|
||||||
|
# return response
|
||||||
|
|
||||||
|
#send in local
|
||||||
|
|
||||||
|
request.env['otp.verification'].sudo().create({
|
||||||
|
'otp': OTP,
|
||||||
|
'email': email,
|
||||||
|
'state': 'unverified',
|
||||||
|
})
|
||||||
|
|
||||||
|
qcontext.update({
|
||||||
|
'otp': True,
|
||||||
|
'otp_login': True,
|
||||||
|
'login': email,
|
||||||
|
'otp_no': OTP,
|
||||||
|
'password': password,
|
||||||
|
'confirm_password': confirm_password,
|
||||||
|
'info_message': f"Your OTP is: {OTP}",
|
||||||
|
})
|
||||||
|
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', qcontext)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/web/signup/otp/verify', type='http', auth='public', website=True, sitemap=False)
|
||||||
|
def web_otp_signup_verify(self, **kw):
|
||||||
|
email = kw.get('login')
|
||||||
|
otp_input = kw.get('otp')
|
||||||
|
name = kw.get('name')
|
||||||
|
password = kw.get('password')
|
||||||
|
confirm_password = kw.get('confirm_password')
|
||||||
|
|
||||||
|
otp_rec = request.env['otp.verification'].sudo().search(
|
||||||
|
[('email', '=', email)], order="create_date desc", limit=1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if not otp_rec or otp_rec.otp != otp_input:
|
||||||
|
return request.render('sttl_otp_login.custom_otp_signup', {
|
||||||
|
'otp': True, 'otp_login': True,
|
||||||
|
'login': email, 'name': name,
|
||||||
|
'password': password, 'confirm_password': confirm_password,
|
||||||
|
'error': _("Invalid OTP. Please try again."),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
otp_rec.state = 'verified'
|
||||||
|
|
||||||
|
user = request.env['res.users'].sudo().create({
|
||||||
|
'name': name,
|
||||||
|
'login': email,
|
||||||
|
'password': password,
|
||||||
|
})
|
||||||
|
request.env.cr.commit()
|
||||||
|
|
||||||
|
_logger.info(" User %s created successfully.", email)
|
||||||
|
|
||||||
|
|
||||||
|
credential = {'login': email, 'password': password}
|
||||||
|
request.session.authenticate(request.db, credential)
|
||||||
|
|
||||||
|
_logger.info(" User %s logged in successfully.", email)
|
||||||
|
|
||||||
|
|
||||||
|
return request.redirect('/web')
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
<record id="ir_cron_otp_verify" model="ir.cron">
|
||||||
|
<field name="name">OTP : Delete the OTPs generated </field>
|
||||||
|
<field name="model_id" ref="model_otp_verification"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">model._cron_delete_verified_otp()</field>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">weeks</field>
|
||||||
|
<field name="active">True</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
from . import otp_verification
|
||||||
|
from . import res_users
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
from odoo import fields, models, api
|
||||||
|
|
||||||
|
|
||||||
|
class OtpVerification(models.Model):
|
||||||
|
_name = "otp.verification"
|
||||||
|
_description = 'Otp Verification'
|
||||||
|
|
||||||
|
otp = fields.Text(string="OTP")
|
||||||
|
state = fields.Selection([
|
||||||
|
('verified', 'Verified'),
|
||||||
|
('unverified', 'Unverified'),
|
||||||
|
('rejected', 'Rejected')], string="State", default="unverified")
|
||||||
|
email = fields.Char(string="email")
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _cron_delete_verified_otp(self):
|
||||||
|
otp = self.search([])
|
||||||
|
otp.unlink()
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import logging
|
||||||
|
from odoo import api, models, SUPERUSER_ID, _
|
||||||
|
from odoo.exceptions import AccessDenied
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
from odoo.addons.mail.models.fetchmail import name
|
||||||
|
|
||||||
|
_logger = logging.getLogger(name)
|
||||||
|
|
||||||
|
class ResUsers(models.Model):
|
||||||
|
_inherit = "res.users"
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _login(cls, db, credential, user_agent_env):
|
||||||
|
login = credential.get('login')
|
||||||
|
password = credential.get('password')
|
||||||
|
login_type = credential.get('type', 'password')
|
||||||
|
otp = credential.get('otp')
|
||||||
|
|
||||||
|
ip = request.httprequest.environ.get('REMOTE_ADDR') if request else 'n/a'
|
||||||
|
_logger.info(" Login attempt: %s (type=%s)", login, login_type)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with cls.pool.cursor() as cr:
|
||||||
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
|
user = env[cls._name].search(env[cls._name]._get_login_domain(login),
|
||||||
|
order=env[cls._name]._get_login_order(),
|
||||||
|
limit=1)
|
||||||
|
if not user:
|
||||||
|
raise AccessDenied(_("Invalid login"))
|
||||||
|
user = user.with_user(user)
|
||||||
|
|
||||||
|
if login_type == 'otp':
|
||||||
|
otp_record = env['otp.verification'].sudo().search([
|
||||||
|
('email', '=', user.login),
|
||||||
|
('otp', '=', otp),
|
||||||
|
('state', '=', 'unverified')
|
||||||
|
], order='create_date desc', limit=1)
|
||||||
|
|
||||||
|
if not otp_record:
|
||||||
|
raise AccessDenied(_("Invalid OTP"))
|
||||||
|
|
||||||
|
otp_record.state = 'verified'
|
||||||
|
auth_info = {'uid': user.id, 'auth_method': 'otp', 'mfa': 'skip'}
|
||||||
|
else:
|
||||||
|
|
||||||
|
user._check_credentials({'type': 'password', 'password': password}, user_agent_env)
|
||||||
|
auth_info = {'uid': user.id, 'auth_method': 'password'}
|
||||||
|
|
||||||
|
user._update_last_login()
|
||||||
|
|
||||||
|
except AccessDenied:
|
||||||
|
_logger.warning(" Login failed for %s from %s", login, ip)
|
||||||
|
raise
|
||||||
|
|
||||||
|
_logger.info(" Login success for %s from %s", login, ip)
|
||||||
|
return auth_info
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_otp_verification,sttl_custom_reports_so.access_otp_verification,model_otp_verification,,1,1,1,1
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record model="ir.module.category" id="otp_verification">
|
||||||
|
<field name="name">OTP Table</field>
|
||||||
|
<field name="description">User access levels for OTP module</field>
|
||||||
|
<field name="sequence">10</field>
|
||||||
|
</record>
|
||||||
|
<record id="otp_verification_access" model="res.groups">
|
||||||
|
<field name="name">Admin</field>
|
||||||
|
<field name="category_id" ref="otp_verification"/>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,28 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="47" height="47" viewBox="0 0 47 47">
|
||||||
|
<g id="support" transform="translate(4)">
|
||||||
|
<circle id="Ellipse_978" data-name="Ellipse 978" cx="23.5" cy="23.5" r="23.5" transform="translate(-4)" fill="#f5f9ff"/>
|
||||||
|
<g id="handshake" transform="translate(2.001 -44.999)">
|
||||||
|
<path id="Path_78185" data-name="Path 78185" d="M77.23,127.821l-6.257,1.829-1.4,5.538c.242,2.034.623,3.938,1.88,5l10.378,8.435,1.256.966c1.89,1.454,3.681-.578,2.244-2.08-.02-.022-.042-.044-.064-.066a1.855,1.855,0,0,0,1.507.446,1.327,1.327,0,0,0,.8-2.32A1.505,1.505,0,1,0,89.6,143.36a1.973,1.973,0,0,0,1.733-3.434c-.012-.014-.026-.03-.04-.044L87,133.489l-5.759-3.69Z" transform="translate(-64.821 -66.913)" fill="#ffbc85" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78186" data-name="Path 78186" d="M195.141,395.929a1.612,1.612,0,0,0-2.02-2.506l-1.379,1.312a.434.434,0,0,1-.046.042c-1.158,1.164.946,3.816,2.687,1.96Z" transform="translate(-178.283 -314.035)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78187" data-name="Path 78187" d="M157.165,353.556l-1.457,1.528-.006.008a1.6,1.6,0,0,0,.641,2.43,1.506,1.506,0,0,0,1.8-.238l1.561-.024-.136-1.33.2-.188a1.7,1.7,0,1,0-2.451-2.348Z" transform="translate(-144.732 -276.542)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78188" data-name="Path 78188" d="M117.194,313.633l-1.365,1.45-.192.206c-1.347,1.43,1.066,3.682,2.457,2.222l.24-.248c.02-.022,1.483-.174,1.643-.192l-.026-1.506.467-.49a1.668,1.668,0,1,0-2.433-2.28Z" transform="translate(-107.364 -238.714)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78189" data-name="Path 78189" d="M84.37,292.665l-.463.5c-1.425,1.548.7,4.016,2.292,2.588l1.308-.2.058-1.248a1.736,1.736,0,0,0-2.733-2.14Z" transform="translate(-77.733 -219.386)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78190" data-name="Path 78190" d="M8.593,58.664l-6.338,6.1L.452,66.5A1.487,1.487,0,0,0,.41,68.595L3.1,71.4a.413.413,0,0,0,.581.012l1.076-1.036,7.653-7.366.95-.916a.412.412,0,0,0,.012-.582l-2.689-2.8a1.48,1.48,0,0,0-2.09-.042Z" transform="translate(0 -2.1)" fill="#62a1e2" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78191" data-name="Path 78191" d="M275.8,219.46l-1.924.44.755.766,5.829,5.8.04.044a2.113,2.113,0,0,1,.591,2.188,2.005,2.005,0,0,0,.579-3.394l-.04-.044-1.749-1.738Z" transform="translate(-255.151 -152.287)" fill="#f5a96c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78192" data-name="Path 78192" d="M164.832,127.821,163.606,129l3.831,1.89,1.407-1.09Z" transform="translate(-152.422 -66.913)" fill="#f5a96c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78193" data-name="Path 78193" d="M181.692,123.83l-1.407,1.09-1.325,1.024c-3.348,2.592-.571,5.152,1.415,4.274l2.234-1.346,1.383-.316,1.924-.44,4.08,4.058,1.749,1.738c1.1-.412,2.655-1.6,4.334-4.3l-2.552-5.339-5.96-2.855-1.529,1.222c-.252.2-.176.162-.493.152a5.758,5.758,0,0,0-3.463.74Z" transform="translate(-165.271 -60.943)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78194" data-name="Path 78194" d="M184.454,210.013l-2.234,1.346a2.18,2.18,0,0,1-1.852-.064,2.2,2.2,0,0,0,2.775.954l2.234-1.346,1.383-.316,1.9-.434c-.88-.754-1.038-.864-2.825-.454Z" transform="translate(-168.039 -142.975)" fill="#fed1a3" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78195" data-name="Path 78195" d="M371.736,221.713a10.769,10.769,0,0,1-3.954,4.14,3.616,3.616,0,0,1-.347.152l1.357,1.35c1.1-.412,2.655-1.6,4.334-4.3Z" transform="translate(-342.317 -154.386)" fill="#fec58c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78196" data-name="Path 78196" d="M93.99,60.751a1.48,1.48,0,0,1,2.082.048l2.689,2.8a.413.413,0,0,1-.012.582l1.226-1.178.95-.916a.412.412,0,0,0,.012-.582l-2.689-2.8a1.48,1.48,0,0,0-2.09-.042Z" transform="translate(-87.565 -2.099)" fill="#3987d0" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78197" data-name="Path 78197" d="M83.448,305.65a1.694,1.694,0,0,0,2.761,1.4l.856-.908.509-.542a1.613,1.613,0,0,0,.072-1.994,1.5,1.5,0,0,1-.383,1l-.906.962-.457.488A1.572,1.572,0,0,1,83.448,305.65Z" transform="translate(-77.744 -230.685)" fill="#fec58c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78198" data-name="Path 78198" d="M116.154,321.3a1.7,1.7,0,0,0,2.791.86l.24-.248a.026.026,0,0,1,.006-.008l1.457-1.528c.052-.058.1-.112.154-.162l.467-.49a1.6,1.6,0,0,0-.192-2.506,1.614,1.614,0,0,1-.465,1.57l-.467.49c-.052.05-.1.1-.154.16v0l-1.457,1.528a.027.027,0,0,1-.008.006l-.238.25a1.527,1.527,0,0,1-2.134.076Z" transform="translate(-108.214 -243.36)" fill="#fec58c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78199" data-name="Path 78199" d="M158.971,363.067l1.064-1.01.315-.3.2-.188a1.637,1.637,0,0,0-.1-2.482,1.555,1.555,0,0,1-.465,1.59l-.2.188-.563.534-.818.78-.046.04a1.509,1.509,0,0,1-1.8.24,1.887,1.887,0,0,1-.367-.262,1.935,1.935,0,0,0,.934,1.152,1.506,1.506,0,0,0,1.8-.238Z" transform="translate(-145.512 -282.368)" fill="#fec58c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78200" data-name="Path 78200" d="M195.153,403.132a1.592,1.592,0,0,0,.072-2.324,1.8,1.8,0,0,1-.539,1.174l-.759.81a1.61,1.61,0,0,1-2.551.024,1.711,1.711,0,0,0,3.018,1.124Z" transform="translate(-178.294 -321.238)" fill="#fec58c" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78201" data-name="Path 78201" d="M326.327,321.446a.526.526,0,0,1-.36-.142l-2.128-1.982a.528.528,0,0,1,.72-.774l2.128,1.982a.529.529,0,0,1-.36.915Z" transform="translate(-301.546 -244.471)" fill="#f5a96c"/>
|
||||||
|
<path id="Path_78202" data-name="Path 78202" d="M296.719,353.78a.526.526,0,0,1-.36-.142l-2.13-1.984a.528.528,0,0,1,.72-.774l2.13,1.984a.529.529,0,0,1-.36.915Z" transform="translate(-273.96 -274.592)" fill="#f5a96c"/>
|
||||||
|
<path id="Path_78203" data-name="Path 78203" d="M278.211,395.523a.527.527,0,0,1-.359-.141l-1.084-1.008a.528.528,0,0,1,.719-.774l1.084,1.008a.529.529,0,0,1-.36.916Z" transform="translate(-257.691 -314.39)" fill="#f5a96c"/>
|
||||||
|
<path id="Path_78204" data-name="Path 78204" d="M315.5,60.471l7.122,6.856,1.389,1.338.511.492a.413.413,0,0,0,.581-.012l1.4-1.464,1.286-1.34a1.487,1.487,0,0,0-.042-2.094l-1.244-1.2-6.9-6.64a1.48,1.48,0,0,0-2.09.042l-2.689,2.8a.412.412,0,0,0,.012.582Z" transform="translate(-293.199)" fill="#fc4350" fill-rule="evenodd"/>
|
||||||
|
<path id="Path_78205" data-name="Path 78205" d="M435.436,151.725v0Zm-1.25,3.428-1.4,1.466a.411.411,0,0,1-.581.01l1.264,1.218.511.492a.413.413,0,0,0,.581-.012l1.4-1.464,1.286-1.34a1.487,1.487,0,0,0-.042-2.094l-1.573-1.514.134.13-.329-.318a1.487,1.487,0,0,1,.036,2.086Z" transform="translate(-402.658 -89.183)" fill="#fb2a39" fill-rule="evenodd"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,733 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html style="box-sizing: border-box;--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px;">
|
||||||
|
<head style="box-sizing: border-box;">
|
||||||
|
<meta charset="utf-8" style="box-sizing: border-box;">
|
||||||
|
<meta content="IE=edge" http-equiv="X-UA-Compatible" style="box-sizing: border-box;">
|
||||||
|
<title style="box-sizing: border-box;">odoo</title>
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport" style="box-sizing: border-box;">
|
||||||
|
</head>
|
||||||
|
<body style="box-sizing: border-box;margin: 0;font-family: 'Poppins', sans-serif;font-size: var(--bs-body-font-size);font-weight: var(--bs-body-font-weight);line-height: var(--bs-body-line-height);color: var(--bs-body-color);text-align: var(--bs-body-text-align);background-color: var(--bs-body-bg);-webkit-text-size-adjust: 100%;-webkit-tap-highlight-color: transparent;padding: 0;">
|
||||||
|
|
||||||
|
<!-- oddo bussiness start -->
|
||||||
|
<section class="bussiness space"
|
||||||
|
style="box-sizing: border-box;padding: 70px 0; position: relative; padding:5px;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 * var(--bs-gutter-y));margin-right: calc(-0.5 * var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));align-items: center;">
|
||||||
|
<div class="col-md-7"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 50%; padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="bussiness_content" style="box-sizing: border-box;">
|
||||||
|
<h1 style="box-sizing: border-box;margin-top: 0;margin-bottom: 10px;font-weight: bold;line-height: 64px;color: #1465b4;font-size: 54px;">
|
||||||
|
Email OTP Authentication</h1>
|
||||||
|
<div class="bussiness_text" style="box-sizing: border-box;max-width: 462px;width: 100%;">
|
||||||
|
<span class="s6"
|
||||||
|
style="box-sizing: border-box;font-size: 24px;line-height: 35px;font-weight: 600;margin-bottom: 15px;color: #323232;display: block;">Simplifying Authentication with OTP via Email - Experience Seamless Login and Signup</span>
|
||||||
|
</div>
|
||||||
|
<div class="bussiness_award" style="box-sizing: border-box;">
|
||||||
|
<ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0;margin-bottom: 1rem;list-style-type: none;margin: 0;padding: 0;padding-bottom: 10px;">
|
||||||
|
<li style="box-sizing: border-box;display: inline-block;padding-right: 15px;"><img
|
||||||
|
src="image/15.png"
|
||||||
|
style="box-sizing: border-box;vertical-align: middle;max-width: 100%;height: auto;">
|
||||||
|
</li>
|
||||||
|
<li style="box-sizing: border-box;display: inline-block;padding-right: 15px;"><img
|
||||||
|
src="image/16A.png"
|
||||||
|
style="box-sizing: border-box;vertical-align: middle;max-width: 100%;height: auto;">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="bussiness_btn" style="box-sizing: border-box;margin: 15px 0;">
|
||||||
|
<a class="orange_btn" href="#"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;color: #ffff;transition: 0.5s all ease-out;-webkit-transition: 0.5s all ease-out;-moz-transition: 0.5s all ease-out;display: inline-block;padding: 13px 17px;font-size: 22px;line-height: 27px;font-weight: 600;background-color: #ff6420;border-radius: 8px;border: 1px solid transparent;position: relative;margin-right: 10px;">Demo
|
||||||
|
Available</a>
|
||||||
|
<a class="trans_btn" href="#"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;color: #ff6420;transition: 0.5s all ease-out;-webkit-transition: 0.5s all ease-out;-moz-transition: 0.5s all ease-out;display: inline-block;padding: 13px 17px;font-size: 22px;line-height: 27px;font-weight: 600;background: transparent;border: 1px solid #ff6420;border-radius: 8px;">30
|
||||||
|
Days Support</a>
|
||||||
|
</div>
|
||||||
|
<div class="bussiness_suggest"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: left;flex-wrap: wrap;">
|
||||||
|
<div class="suggestion"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: center;padding: 9px 18px;border-radius: 25px;background-color: #1465b4;color: #fff;margin-right: 10px;margin-top: 25px;font-size: 16px;line-height: 22px;">
|
||||||
|
<div class="sug_icon" style="box-sizing: border-box;padding-right: 6px;">
|
||||||
|
<i class="fa fa-check-circle" style="box-sizing: border-box;"></i>
|
||||||
|
</div>
|
||||||
|
<span style="box-sizing: border-box;font-size: 16px;line-height: 25px;font-weight: 400;">Odoo Community</span>
|
||||||
|
</div>
|
||||||
|
<div class="suggestion"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: center;padding: 9px 18px;border-radius: 25px;background-color: #1465b4;color: #fff;margin-right: 10px;margin-top: 25px;font-size: 16px;line-height: 22px;">
|
||||||
|
<div class="sug_icon" style="box-sizing: border-box;padding-right: 6px;">
|
||||||
|
<i class="fa fa-check-circle" style="box-sizing: border-box;"></i>
|
||||||
|
</div>
|
||||||
|
<span style="box-sizing: border-box;font-size: 16px;line-height: 25px;font-weight: 400;">Odoo Enterprise</span>
|
||||||
|
</div>
|
||||||
|
<div class="suggestion"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: center;padding: 9px 18px;border-radius: 25px;background-color: #1465b4;color: #fff;margin-right: 10px;margin-top: 25px;font-size: 16px;line-height: 22px;">
|
||||||
|
<div class="sug_icon" style="box-sizing: border-box;padding-right: 6px;">
|
||||||
|
<i class="fa fa-check-circle" style="box-sizing: border-box;"></i>
|
||||||
|
</div>
|
||||||
|
<span style="box-sizing: border-box;font-size: 16px;line-height: 25px;font-weight: 400;">Odoo.SH</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 50%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="bussiness_right" style="box-sizing: border-box;">
|
||||||
|
<img src="otp_login_laptop.png"
|
||||||
|
style="border-radius:20px; box-sizing: border-box;vertical-align: middle;max-width: 100%;height: auto;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- oddo bussiness end -->
|
||||||
|
<!-- consultion start -->
|
||||||
|
<section class="consultion"
|
||||||
|
style="box-sizing: border-box; position: relative; margin-top: 100px; background-color: #1465b4; padding:20px;
|
||||||
|
border-radius: 15px;">
|
||||||
|
<div style="display:flex;">
|
||||||
|
<div class="cons_text" style="box-sizing: border-box;max-width: 750px;width: 100%;">
|
||||||
|
<h2 style="box-sizing: border-box;margin-top: 0;margin-bottom: 2px;font-weight: 400;line-height: 55px;color: var(--bs-heading-color);font-size: 46px;">
|
||||||
|
<strong style="box-sizing: border-box;font-weight: bolder;color: #ff6420;">CONSULT OUR EXPERTS</strong>
|
||||||
|
</h2>
|
||||||
|
<p style="color: white; box-sizing: border-box;margin-top: 0;margin-bottom: 1rem;font-size: 14px;line-height: 18px;font-weight: 600;max-width: 682px;width: 100%;">
|
||||||
|
Unlock the potential of your business with Silver Touch! Avail a complimentary 1-hour Odoo
|
||||||
|
consulting session and discover tailored solutions for your unique needs.</p>
|
||||||
|
<div class="cons_info"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: start;">
|
||||||
|
<div class="cons_btn" style="box-sizing: border-box;margin-right: 30px;">
|
||||||
|
<a class="orange_btn" href="mailto:info@silvertouch.com"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;color: #ffff;transition: 0.5s all ease-out;-webkit-transition: 0.5s all ease-out;-moz-transition: 0.5s all ease-out;display: inline-block;background-color: #ff6420;border-radius: 8px;border: 1px solid transparent;position: relative;padding: 12px 30px;font-size: 16px;line-height: 22px;font-weight: bold;">Let's
|
||||||
|
Connect</a>
|
||||||
|
</div>
|
||||||
|
<div class="cons_con_details"
|
||||||
|
style="box-sizing: border-box;display: flex;align-items: center;justify-content: center;">
|
||||||
|
<div style="position: relative; z-index: 2;">
|
||||||
|
<img src="image/support.svg" style="max-width: 100%; height: auto;">
|
||||||
|
</div>
|
||||||
|
<div style="padding: 8px 12px 8px 35px; background: #276CD6; border-radius: 0 19px 19px 0; margin-left: -25px;">
|
||||||
|
<span style="font-size: 14px; line-height: 18px; display: inline-block; margin-right: 10px;">
|
||||||
|
<i class="fa fa-envelope" style="color:white"></i>
|
||||||
|
<a href="mailto:info@silvertouch.com" style="color: #FFF; font-size: 14px; line-height: 18px;
|
||||||
|
transition: 0.5s all ease-out;">info@silvertouch.com</a>
|
||||||
|
</span>
|
||||||
|
<span style="margin-right: 0; font-size: 14px; line-height: 18px; display: inline-block;">
|
||||||
|
<i class="fa fa-phone" style="color:white"></i>
|
||||||
|
<a href="skype:+91 79-4002-2770/1/2/3/4?chat" style="color: #FFF;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px; transition: 0.5s all ease-out;">+91 79-4002-2770/1/2/3/4</a>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- <div style="margin-top:px; width:108px; height:108px; padding:20px; border-radius:100px; left:45%; ">
|
||||||
|
<img src="assets/icons/1Hour.png"/>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="one_hours"
|
||||||
|
style="margin: 7px 0;background-color: #ffff;width: 130px;height: 130px;border-radius: 100px;padding: 25px 0px 0px 10px;">
|
||||||
|
<div class="one_hrs_circle"
|
||||||
|
style="display: flex;text-align: center;">
|
||||||
|
<span style="color: #ff6420;font-size: 18px;line-height: 22px;font-weight: bold;">
|
||||||
|
01
|
||||||
|
<br>
|
||||||
|
HOUR
|
||||||
|
<br>
|
||||||
|
DISCUSSION
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- consultion end -->
|
||||||
|
<section class="oe_container" style="margin-top: 2rem !important;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<img src="assets/icons/footer.png" alt="Silver Touch Footer" width="100%"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- features start -->
|
||||||
|
<section class="features" style="box-sizing: border-box; padding: 70px 0;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 * var(--bs-gutter-y));margin-right: calc(-0.5 * var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text " style="box-sizing: border-box;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
Features</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Seamless Authentication Experience</h5>
|
||||||
|
<p class="card-text">Our Odoo module revolutionizes authentication by offering OTP login via email. Users can opt for password or OTP login at the login page, enhancing security and user convenience effortlessly.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Seamless Integration</h5>
|
||||||
|
<p class="card-text">Our module seamlessly integrates with Odoo's existing authentication system, ensuring compatibility and ease of implementation for users and administrators alike.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Time-saving Authentication
|
||||||
|
</h5>
|
||||||
|
<p class="card-text">With OTP login, users can swiftly access their accounts without the hassle of remembering complex passwords, saving time and improving user satisfaction.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Email verification</h5>
|
||||||
|
<p class="card-text">Our module also verifies email address at the time of sign up by sending otp on the given email address, which ensures only users with valid email address gets registered in database</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Enhanced User Privacy
|
||||||
|
</h5>
|
||||||
|
<p class="card-text">With OTP-based authentication, our module prioritizes user privacy by reducing the reliance on passwords. OTPs sent to their email addresses ensure secure access to accounts, minimizing the risk of unauthorized access or data breaches.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 mt-3" style="padding:0px; border:1px solid #7e827f; border-radius: 15px;">
|
||||||
|
<div class="card-deck" style="height:100%">
|
||||||
|
<div class="card-body" style="height:100%">
|
||||||
|
<h5 class="card-title" style="color: #1465b4;"><i class="fa fa-arrow-right"
|
||||||
|
style="margin-right: 10px;"/>Flexible Login Options</h5>
|
||||||
|
<p class="card-text">Our module offers flexibility in login methods, allowing users to choose between password-based or OTP-based login. This adaptability caters to diverse user preferences and enhances accessibility while maintaining robust security protocols.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top:25px">
|
||||||
|
<div class="col-5"
|
||||||
|
style="padding-left: 16%; padding-top:13px; padding-bottom:13px; color: #ff6420; display: inline-block; border-radius: 8px;font-size: 20px;line-height: 18px;font-weight:bold;">
|
||||||
|
Website : <span
|
||||||
|
style="font-size:14px; padding:8px; border-radius:15px; color:white; background-color:#1465b4">www.silvertouch.com</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-1"></div>
|
||||||
|
<div class="col-5" style="padding:0px 0px">
|
||||||
|
<div style="width:100%; padding:13px 0px; color: #ff6420; border-radius: 8px;font-size: 20px;line-height: 18px;font-weight:bold;">
|
||||||
|
For any queries : <span
|
||||||
|
style="font-size:14px; padding:8px; border-radius:15px; color:white; background-color:#1465b4">www.silvertouch.com/contact</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- features end -->
|
||||||
|
|
||||||
|
<!-- screenshots start -->
|
||||||
|
<section class="screenshots"
|
||||||
|
style="box-sizing: border-box;background-color: #e1f0ed; padding: 70px 0; border-radius:15px;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 * var(--bs-gutter-y));margin-right: calc(-0.5 * var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text" style="box-sizing: border-box;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
App Preview</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h3 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
YouTube Preview<br/>
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"></span>
|
||||||
|
</h3>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
Witness the power of our module through the comprehensive
|
||||||
|
demonstration in the linked YouTube video.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<!-- <video class="img-fluid"-->
|
||||||
|
<!-- src="email_otp_authentication.mkv" controls width="725px"/>-->
|
||||||
|
<a href="https://www.youtube.com/watch?v=hFF35idmPQY" target="new">
|
||||||
|
<img width="625px" height="350px" src="email_otp.png"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<img class="img-fluid"
|
||||||
|
src="signup.png" width="725px"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h3 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
Sign Up<br/>
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"></span>
|
||||||
|
</h3>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
Enter user's credentials and click on send otp.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h2 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
OTP
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"> </span>
|
||||||
|
</h2>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
Enter the otp received on user's entered email address.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<img class="img-fluid"
|
||||||
|
src="signup_otp.png" width="725px"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<img class="img-fluid"
|
||||||
|
src="otp_login_link.png" width="725px"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h3 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
OTP Login link<br/>
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"></span>
|
||||||
|
</h3>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
<b>Login with OTP</b> link will redirect to use otp login functionality(User can also use default odoo login functionality).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h2 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
OTP Login page
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"> </span>
|
||||||
|
</h2>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
Enter user's registered email address here.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<img class="img-fluid"
|
||||||
|
src="login.png" width="725px"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 position-relative" style="border-radius:10px">
|
||||||
|
<div class="p-md-5 p-3 position-relative">
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="d-inline-block text-center p-3 shadow-sm"
|
||||||
|
style="background-color:#fff; border-radius:10px">
|
||||||
|
<img class="img-fluid"
|
||||||
|
src="login_otp.png" width="725px"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 d-flex align-items-center">
|
||||||
|
<div class="pl-md-2 pl-0">
|
||||||
|
<h3 class="mb-3"
|
||||||
|
style="font-family:'Inter', sans-serif; font-style:normal; font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:103%; text-transform:capitalize; color:#2B5FB2">
|
||||||
|
OTP Login<br/>
|
||||||
|
<span style="color:#333333; font-size:calc(1.1rem + 1vw)"></span>
|
||||||
|
</h3>
|
||||||
|
<p style="font-family:Inter; font-style:normal; font-weight:500; font-size:16px; line-height:150%; letter-spacing:0.02em; color:#535456">
|
||||||
|
Enter the otp received on user's entered email address.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- screenshots end -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- other apps start -->
|
||||||
|
<section class="other_app space" style="box-sizing: border-box;padding: 35px 0;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 var(--bs-gutter-y));margin-right: calc(-0.5 var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text" style="box-sizing: border-box;margin-bottom: 15px;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
Other Apps By Silver Touch</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="width:25%; padding-right:calc(var(--bs-gutter-x) 0.5); padding-left:calc(var(--bs-gutter-x) 0.5); margin-top:var(--bs-gutter-y)">
|
||||||
|
<div class="app_sec" style="margin:16px 0">
|
||||||
|
<div class="app_img" style="border-radius:12px; min-height:170px; margin:0 10px">
|
||||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/sttl_email_validation">
|
||||||
|
<img src="app_images/email_validation.png"
|
||||||
|
style="vertical-align:middle; height:auto; max-width:100%; width:100%"></a>
|
||||||
|
</div>
|
||||||
|
<div class="app_text">
|
||||||
|
<span class="text"
|
||||||
|
style="text-align:center; font-size:20px; line-height:30px; font-weight:600; display:block; color:black">Email Validation</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="width:25%; padding-right:calc(var(--bs-gutter-x) 0.5); padding-left:calc(var(--bs-gutter-x) 0.5); margin-top:var(--bs-gutter-y)">
|
||||||
|
<div class="app_sec" style="margin:16px 0">
|
||||||
|
<div class="app_img" style="border-radius:12px; min-height:170px; margin:0 10px">
|
||||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/sttl_timesheet_calendar">
|
||||||
|
<img src="app_images/timesheet_calendar.png"
|
||||||
|
style="vertical-align:middle; height:auto; max-width:100%; width:100%">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="app_text">
|
||||||
|
<span class="text"
|
||||||
|
style="text-align:center; font-size:20px; line-height:30px; font-weight:600; display:block; color:black">Timesheet Calender</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="width:25%; padding-right:calc(var(--bs-gutter-x) 0.5); padding-left:calc(var(--bs-gutter-x) 0.5); margin-top:var(--bs-gutter-y)">
|
||||||
|
<div class="app_sec" style="margin:16px 0">
|
||||||
|
<div class="app_img" style="border-radius:12px; min-height:170px; margin:0 10px">
|
||||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/sttl_timesheet_forecasting">
|
||||||
|
<img src="app_images/timesheet_forecasting.png"
|
||||||
|
style="vertical-align:middle; height:auto; max-width:100%; width:100%">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="app_text">
|
||||||
|
<span class="text"
|
||||||
|
style="text-align:center; font-size:20px; line-height:30px; font-weight:600; display:block; color:black">Timesheet Forecasting </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="width:25%; padding-right:calc(var(--bs-gutter-x) 0.5); padding-left:calc(var(--bs-gutter-x) 0.5); margin-top:var(--bs-gutter-y)">
|
||||||
|
<div class="app_sec" style="margin:16px 0">
|
||||||
|
<div class="app_img" style="border-radius:12px; min-height:170px; margin:0 10px">
|
||||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/sttl_product_description/">
|
||||||
|
<img src="app_images/product_description.png"
|
||||||
|
style="vertical-align:middle; height:auto; max-width:100%; width:100%">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="app_text">
|
||||||
|
<span class="text"
|
||||||
|
style="text-align:center; font-size:20px; line-height:30px; font-weight:600; display:block; color:black">AI Product Description</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4"/>
|
||||||
|
<a href="https://apps.odoo.com/apps/modules/browse?search=silver+touch" target="_blank"
|
||||||
|
class="col-md-3 btn btn-block mb-2 deep_hover"
|
||||||
|
style="color: #ffff; margin-left:28px; transition: 0.5s all ease-out;-webkit-transition: 0.5s all ease-out;-moz-transition: 0.5s all ease-out;display: inline-block;background-color: #ff6420;border-radius: 8px;border: 1px solid transparent;position: relative;padding: 12px 20px;font-size: 19px;line-height: 18px;font-weight:bold;">All
|
||||||
|
Silver Touch Apps</a>
|
||||||
|
<div class="col-md-5"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- other apps end -->
|
||||||
|
<!-- service start -->
|
||||||
|
<section class="service" style="box-sizing: border-box;background-color: #e1f0ed;padding: 70px 0; border-radius:15px;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 * var(--bs-gutter-y));margin-right: calc(-0.5 * var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) * 0.5);padding-left: calc(var(--bs-gutter-x) * 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text" style="box-sizing: border-box;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
Our Expertise</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<img src="assets/icons/services1.png" style="width: 99.8%;"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-5"/>
|
||||||
|
<a href="mailto:info@silvertouch.com"
|
||||||
|
class="col-2 btn btn-block mb-2 deep_hover"
|
||||||
|
style="color: #ffff; transition: 0.5s all ease-out;-webkit-transition: 0.5s all ease-out;-moz-transition: 0.5s all ease-out;display: inline-block;background-color: #ff6420;border-radius: 8px;border: 1px solid transparent;position: relative;padding: 12px 20px;font-size: 19px;line-height: 18px;font-weight:bold;">
|
||||||
|
Get in Touch
|
||||||
|
</a>
|
||||||
|
<div class="col-5"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<!-- service end -->
|
||||||
|
<!-- industries start -->
|
||||||
|
<!--industries 2.0 start-->
|
||||||
|
<section class="oe_container" style="margin-top: 6rem !important; margin-right:10px; margin-left:10px">
|
||||||
|
<div class="container"
|
||||||
|
style="--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-right: auto;margin-left: auto;max-width: 1440px;margin: 0 auto;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 var(--bs-gutter-y));margin-right: calc(-0.5 var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text" style="box-sizing: border-box;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
Industries</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="background-color: #f4f4f4">
|
||||||
|
<div class="col-5" style="background-color: #f4f4f4">
|
||||||
|
<div>
|
||||||
|
<p style="color:rgb(30,30,30); margin-top:30px; font-size:25px; font-weight:bold; margin-left:30px">
|
||||||
|
Industries we grow</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p style="width:75%; margin-top:10px; font-size:17px; color:#347cc9; margin-left:30px">Tech
|
||||||
|
Solutions for Industries to improve the way they operate.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p style="width:95%; margin-top:10px; font-size:15px; margin-left:30px">Every industry has special
|
||||||
|
needs and all those special needs ask for a special solution.
|
||||||
|
At Silvertouch we offer solutions that are especially built to aid special characteristics
|
||||||
|
of that specific industry.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-7" style="background-color: #f4f4f4;">
|
||||||
|
<img src="assets/icons/industry.png" alt="Industries Icons" width="100%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--industries 2.0 end-->
|
||||||
|
<!-- industries end -->
|
||||||
|
|
||||||
|
<!-- contact details start -->
|
||||||
|
<section class="oe_container" id="presense" style="margin-top: 6rem !important;">
|
||||||
|
<div class="container"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);margin-right: auto;max-width: 1440px;">
|
||||||
|
<div class="row"
|
||||||
|
style="box-sizing: border-box;--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display: flex;flex-wrap: wrap;margin-top: calc(-1 var(--bs-gutter-y));margin-right: calc(-0.5 var(--bs-gutter-x));margin-left: calc(-0.5 * var(--bs-gutter-x));">
|
||||||
|
<div class="col-md-12"
|
||||||
|
style="box-sizing: border-box;flex-shrink: 0;width: 100%;max-width: 100%;padding-right: calc(var(--bs-gutter-x) 0.5);padding-left: calc(var(--bs-gutter-x) 0.5);margin-top: var(--bs-gutter-y);">
|
||||||
|
<div class="title_text" style="box-sizing: border-box;">
|
||||||
|
<h3 class="text-center"
|
||||||
|
style="box-sizing: border-box;margin-top: 0;margin-bottom: 0.5rem;font-weight: 700;line-height: 60px;color: #1465b4;font-size: 40px;text-align: center;">
|
||||||
|
Our Presence</h3>
|
||||||
|
<center>
|
||||||
|
<hr
|
||||||
|
style="border: 3px solid #000133 !important; background-color: #000133 !important; width: 80px !important; margin-bottom: 2rem !important;"/>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="padding:10px; font-size: 14px; border: 1px solid #cacccc; border-width: 0 1px 0 0">
|
||||||
|
<div style="padding:10px;">
|
||||||
|
<div style="display:flex;">
|
||||||
|
<img src="image/india-flag.jpg" style="border-radius: 15px; width:32px; height:34px;"/>
|
||||||
|
<p class="mx-2">
|
||||||
|
<p style="font-size: 24px; font-weight:bold;">India</p></p>
|
||||||
|
</div>
|
||||||
|
<p style="font-weight: bold;">Silver Touch Technologies Limited</p>
|
||||||
|
<p style="padding-top:10px">2nd Floor, Saffron Tower, Opp. Central Mall, Panchvati Cross Road,
|
||||||
|
Ahmedabad - 380006 Gujarat,
|
||||||
|
India</p>
|
||||||
|
<div style="padding-top:5px; "><i class="fa fa-phone" style="margin-right:10px;"></i><a
|
||||||
|
href="tel:+91 79-4002-2770/1/2/3/4"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;-webkit-transition: 0.5s all ease;-moz-transition: 0.5s all ease;transition: 0.5s all ease-out;font-size: 14px;line-height: 18px;">
|
||||||
|
+91 79-4002-2770/1/2/3/4</a></div>
|
||||||
|
<div><i class="fa fa-envelope" style="margin-right:10px;"></i><a href="mailto:info@silvertouch.com">info@silvertouch.com</a>
|
||||||
|
</div>
|
||||||
|
<div><i class="fa fa-globe" style="margin-right:10px;"></i><a href="https://www.silvertouch.com/">https://www.silvertouch.com</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="padding:10px; font-size: 14px; border: 1px solid #cacccc; border-width: 0 1px 0 0">
|
||||||
|
<div style="padding:10px;">
|
||||||
|
<div style="display:flex;">
|
||||||
|
<img src="image/united-state-flag.jpg" style="border-radius: 15px; width:32px; height:34px;"/>
|
||||||
|
<p class="mx-2">
|
||||||
|
<p style="font-size: 24px; font-weight:bold;">USA</p></p>
|
||||||
|
</div>
|
||||||
|
<p style="font-weight: bold;">Silver Touch Technologies INC</p>
|
||||||
|
<p style="padding-top:16px; ">1149 Green Street, Iselin, NJ 08830, United States of America</p>
|
||||||
|
<div style="padding-top:20px; "><i class="fa fa-phone" style="margin-right:10px;"></i><a
|
||||||
|
href="tel:+1 (201) 331-9818"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;-webkit-transition: 0.5s all ease;-moz-transition: 0.5s all ease;transition: 0.5s all ease-out;font-size: 14px;line-height: 18px;">
|
||||||
|
+1 (201) 331-9818
|
||||||
|
</a></div>
|
||||||
|
<div><i class="fa fa-envelope" style="margin-right:10px;"></i><a href="mailto:info@silvertouch.com">info@silvertouch.com</a>
|
||||||
|
</div>
|
||||||
|
<div><i class="fa fa-globe" style="margin-right:10px;"></i><a
|
||||||
|
href="https://www.silvertouchinc.com/">https://www.silvertouchinc.com</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"
|
||||||
|
style="padding:10px; font-size: 14px; border: 1px solid #cacccc; border-width: 0 1px 0 0">
|
||||||
|
<div style="padding:10px;">
|
||||||
|
<div style="display:flex;">
|
||||||
|
<img src="image/uk-flag-img.jpg" style="border-radius: 15px; width:32px; height:34px;"/>
|
||||||
|
<p class="mx-2">
|
||||||
|
<p style="font-size: 24px; font-weight:bold;">UK</p></p>
|
||||||
|
</div>
|
||||||
|
<p style="font-weight: bold;">Silver Touch Technologies UK Limited</p>
|
||||||
|
<p style="padding-top:16px; ">4th Floor, Victoria House, Victoria Road, Chelmsford, Essex,
|
||||||
|
United Kingdom - CM1 1JR</p>
|
||||||
|
<div><i class="fa fa-phone" style="margin-right:10px;"></i><a
|
||||||
|
href="tel:+44 203-872-5140"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;-webkit-transition: 0.5s all ease;-moz-transition: 0.5s all ease;transition: 0.5s all ease-out;font-size: 14px;line-height: 18px;">
|
||||||
|
+44 203-872-5140
|
||||||
|
</a></div>
|
||||||
|
<div><i class="fa fa-envelope" style="margin-right:10px;"></i><a
|
||||||
|
href="mailto:info@silvertouchtech.co.uk">info@silvertouchtech.co.uk
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div><i class="fa fa-globe" style="margin-right:10px;"></i><a
|
||||||
|
href="https://www.silvertouchtech.co.uk/">https://www.silvertouchtech.co.uk</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3" style="padding:10px; font-size: 14px;">
|
||||||
|
<div style="padding:10px;">
|
||||||
|
<div style="display:flex;">
|
||||||
|
<img src="image/canada-flag.png" style="border-radius: 15px; width:32px; height:34px;"/>
|
||||||
|
<p class="mx-2">
|
||||||
|
<p style="font-size: 24px; font-weight:bold;">Canada</p></p>
|
||||||
|
</div>
|
||||||
|
<p style="font-weight: bold;">Silver Touch Technologies CA</p>
|
||||||
|
<p style="padding-top:16px; ">55 Albert Street, Suite 100,
|
||||||
|
Markham, ON, L3P 2T4,
|
||||||
|
Canada</p>
|
||||||
|
<div style="padding-top:20px; "><i class="fa fa-phone" style="margin-right:10px;"></i><a
|
||||||
|
href="tel:+1 (647) 829-2482"
|
||||||
|
style="box-sizing: border-box;text-decoration: none;-webkit-transition: 0.5s all ease;-moz-transition: 0.5s all ease;transition: 0.5s all ease-out;font-size: 14px;line-height: 18px;">
|
||||||
|
+1 (647) 829-2482</a></div>
|
||||||
|
<div><i class="fa fa-envelope" style="margin-right:10px;"></i><a href="mailto:info@silvertouch.ca">info@silvertouch.ca
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div><i class="fa fa-globe" style="margin-right:10px;"></i><a
|
||||||
|
href="https://www.silvertouch.ca/">https://www.silvertouch.ca</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- contact details end -->
|
||||||
|
<!-- Footer Logos Start -->
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
|
@ -0,0 +1,109 @@
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<template id="custom_login_otp_checkbox_template" inherit_id="web.login">
|
||||||
|
<xpath expr="//input[@name='password']" position="after">
|
||||||
|
<div class="o_login_otp_container">
|
||||||
|
<div style="margin-top:10px; display:flex;">
|
||||||
|
<a t-attf-href="/otp/login" class="btn btn-link" role="button">
|
||||||
|
Login with OTP
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
<xpath expr="//form[1]" position="attributes">
|
||||||
|
<attribute name="t-if">not otp_login</attribute>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="custom_login_template" inherit_id="web.login">
|
||||||
|
<xpath expr="//form[1]" position="after">
|
||||||
|
|
||||||
|
|
||||||
|
<form t-if="otp_login and not otp" id="form_otp_login" class="oe_login_form" role="form"
|
||||||
|
t-attf-action="/otp/login" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||||
|
|
||||||
|
<div class="form-group field-login">
|
||||||
|
<label for="login">Email</label>
|
||||||
|
<input type="text" placeholder="Email" name="login" t-att-value="login" id="login"
|
||||||
|
required="required"
|
||||||
|
t-attf-class="form-control #{'form-control-sm' if form_small else ''}"
|
||||||
|
autofocus="autofocus" autocapitalize="off"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p t-if="login_error" class="alert alert-danger" role="alert">
|
||||||
|
The Email entered is incorrect.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div t-attf-class="clearfix oe_login_buttons text-center mb-1 {{'pt-2' if form_small else 'pt-3'}}">
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">Send OTP</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top:10px; display:flex;">
|
||||||
|
<a t-attf-href="/web/login" class="btn btn-link" role="button">
|
||||||
|
Login with Password
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form t-if="otp and otp_no" id="form_otp" class="oe_login_form" role="form"
|
||||||
|
t-attf-action="/otp/verify" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="otp">OTP</label>
|
||||||
|
<input type="text" placeholder="OTP" name="otp" id="otp"
|
||||||
|
t-attf-class="form-control #{'form-control-sm' if form_small else ''}" required="required"/>
|
||||||
|
<input t-att-value="login" id="login" type="hidden" name="login"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div t-attf-class="clearfix oe_login_buttons text-center mb-1 {{'pt-2' if form_small else 'pt-3'}}">
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">Verify OTP</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center mt-2">
|
||||||
|
<a href="/web/login" class="btn btn-link btn-sm">Back to Login</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div t-if="otp_no" class="alert alert-info mt-3 text-center">
|
||||||
|
<b>Development OTP:</b> <t t-esc="otp_no"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<form t-if="otp and not otp_no" id="form_resend_otp" class="oe_login_form" role="form"
|
||||||
|
t-attf-action="/otp/login" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||||
|
<label for="otp">OTP</label>
|
||||||
|
<input type="text" placeholder="OTP" name="otp" id="otp"
|
||||||
|
t-attf-class="form-control #{'form-control-sm' if form_small else ''}"/>
|
||||||
|
<input t-att-value="login" id="login" type="hidden" name="login"/>
|
||||||
|
<p class="alert alert-danger" role="alert">
|
||||||
|
The OTP entered is incorrect. Please use the below button to resend the OTP.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div t-attf-class="clearfix oe_login_buttons text-center mb-1 {{'pt-2' if form_small else 'pt-3'}}">
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">Resend OTP</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="custom_login_footer_links" inherit_id="web.login" name="Custom Login with Signup Link">
|
||||||
|
<xpath expr="//form" position="after">
|
||||||
|
<div t-if="not otp_login and not otp" class="text-center mt-3">
|
||||||
|
<a href="/web/signup/otp" class="btn btn-link">Don't have an account?</a>
|
||||||
|
<a t-if="reset_password_enabled"
|
||||||
|
t-attf-href="/web/reset_password?{{ keep_query() }}" class="btn btn-link">
|
||||||
|
Reset Password
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<template id="custom_otp_signup" inherit_id="auth_signup.signup">
|
||||||
|
<xpath expr="//form" position="replace">
|
||||||
|
|
||||||
|
|
||||||
|
<form t-if="not otp" t-attf-action="/web/signup/otp" method="post" class="oe_signup_form">
|
||||||
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="col-form-label">Full Name</label>
|
||||||
|
<input type="text" name="name" id="name" class="form-control" required="required"
|
||||||
|
placeholder="Enter your full name" t-att-value="name"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="login" class="col-form-label">Email</label>
|
||||||
|
<input type="email" name="login" id="login" class="form-control" required="required"
|
||||||
|
placeholder="Enter your email" t-att-value="login"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="col-form-label">Password</label>
|
||||||
|
<input type="password" name="password" id="password" class="form-control" required="required"
|
||||||
|
placeholder="Enter password" t-att-value="password"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="confirm_password" class="col-form-label">Confirm Password</label>
|
||||||
|
<input type="password" name="confirm_password" id="confirm_password" class="form-control"
|
||||||
|
required="required" placeholder="Confirm password"
|
||||||
|
t-att-value="confirm_password"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p t-if="error" class="alert alert-danger" role="alert">
|
||||||
|
<t t-esc="error"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="d-grid text-center mt-3">
|
||||||
|
<button type="submit" class="btn btn-primary w-100">Sign up with OTP</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center mt-2">
|
||||||
|
<a href="/web/login" class="btn btn-link btn-sm">Back to Login</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<form t-if="otp" t-attf-action="/web/signup/otp/verify" method="post" class="oe_signup_form">
|
||||||
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||||
|
<input type="hidden" name="login" t-att-value="login"/>
|
||||||
|
<input type="hidden" name="name" t-att-value="name"/>
|
||||||
|
<input type="hidden" name="password" t-att-value="password"/>
|
||||||
|
<input type="hidden" name="confirm_password" t-att-value="confirm_password"/>
|
||||||
|
|
||||||
|
<div class="mb-3 text-center">
|
||||||
|
<label for="otp" class="col-form-label">Enter OTP</label>
|
||||||
|
<input type="text" name="otp" id="otp" class="form-control text-center"
|
||||||
|
placeholder="Enter the OTP code" required="required"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p t-if="error" class="alert alert-danger" role="alert">
|
||||||
|
<t t-esc="error"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<div t-if="otp_no" class="alert alert-info text-center">
|
||||||
|
🔐 Your OTP code: <b><t t-esc="otp_no"/></b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-grid text-center mt-3">
|
||||||
|
<button type="submit" class="btn btn-success w-100">Verify Create Account</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center mt-2">
|
||||||
|
<a href="/web/signup/otp" class="btn btn-link btn-sm">Back to Sign up</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="otp_verification_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">otp_verification_view_form</field>
|
||||||
|
<field name="model">otp.verification</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="otp_verification_form">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="otp"/>
|
||||||
|
<field name="state"/>
|
||||||
|
<field name="email"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="otp_verification_view_tree" model="ir.ui.view">
|
||||||
|
<field name="name">otp_verification_view_tree</field>
|
||||||
|
<field name="model">otp.verification</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list string="_tree">
|
||||||
|
<field name="otp"/>
|
||||||
|
<field name="state"/>
|
||||||
|
<field name="email"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="otp_verification_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">OTP Verification</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">otp.verification</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
id="otp_verify_menu"
|
||||||
|
name="OTP VERIFICATION"
|
||||||
|
parent="base.menu_users"
|
||||||
|
action="otp_verification_action"
|
||||||
|
groups="otp_verification_access"
|
||||||
|
sequence="0"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||