Magento2 | PWA | GraphQL

Display mini login besides mini cart in Magento2


In this post we wiil check how to display mini login besides mini cart in Magento2.

Let's start by creating custom module.

You can find complete module on Github at Magelearn_Minilogin




Create folder inside app/code/Magelearn/Minilogin

Add registration.php file in it:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Magelearn_Minilogin',
    __DIR__
);

Add composer.json file in it:

{
    "name": "magelearn/module-minilogin",
    "description": "Display mini login besides mini cart",
    "type": "magento2-module",
    "license": "proprietary",
    "version": "1.0.0",
    "authors": [
        {
            "name": "Vijay Rami",
            "email": "vijaymrami@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\Minilogin\\": ""
        }
    }
}

Add etc/module.xml file in it:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Magelearn_Minilogin" schema_version="0.0.1"  setup_version="0.0.1">
        <sequence/>
    </module>
</config>

Now to display login button beside minicart, first we will add layout file.

Add app/code/Magelearn/Minilogin/view/frontend/layout/default.xml file.

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <!--<move element="authentication-popup" destination="login-icon"/>-->
        <referenceContainer name="header-wrapper">
            <block class="Magelearn\Minilogin\Block\Customer\Account\Form" name="login-icon" template="Magelearn_Minilogin::account/link/mini-login.phtml" after="minicart">
                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="types" xsi:type="array"/>
                        <item name="components" xsi:type="array">
                            <item name="mini_login_content" xsi:type="array">
                                <item name="component" xsi:type="string">Magelearn_Minilogin/js/view/minilogin</item>
                                <item name="config" xsi:type="array">
                                    <item name="template" xsi:type="string">Magento_Customer/authentication-popup</item>
                                </item>
                                <item name="children" xsi:type="array">
                                    <item name="messages" xsi:type="array">
                                        <item name="component" xsi:type="string">Magento_Ui/js/view/messages</item>
                                        <item name="displayArea" xsi:type="string">messages</item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
                <container name="customer.login.container" label="Customer Login Container" htmlTag="div" htmlClass="login-container">
                    <block class="Magento\Customer\Block\Form\Login" name="customer_form_login" template="form/login.phtml">
                		<container name="form.additional.info" as="form_additional_info"/>
                    </block>
            		<block class="Magento\Customer\Block\Form\Login\Info" name="customer.new" template="newcustomer.phtml"/>
                </container>
                <block class="Magento\Cookie\Block\RequireCookie" name="require-cookie" template="Magento_Cookie::require_cookie.phtml">
                    <arguments>
                        <argument name="triggers" xsi:type="array">
                            <item name="loginButton" xsi:type="string">.action.login</item>
                        </argument>
                    </arguments>
                </block>
            </block>
        </referenceContainer>
    </body>
</page>

Now as per defined in layout file, we will add our block class file at app/code/Magelearn/Minilogin/Block/Customer/Account/Form.php file.

<?php
namespace Magelearn\Minilogin\Block\Customer\Account;

use Magento\Framework\View\Element\Template;

class Form extends Template
{

    /**
     * Customer session
     *
     * @var \Magento\Framework\App\Http\Context
     */
    protected $httpContext;

    /**
     * @var \Magento\Customer\Model\Url
     */
    protected $_customerUrl;


    /**
     * @param Template\Context $context
     * @param \Magento\Customer\Model\Url $customerUrl
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Customer\Model\Url $customerUrl,
        \Magento\Customer\CustomerData\JsLayoutDataProviderPoolInterface $jsLayoutDataProvider,
        array $data = [])
    {
        $this->httpContext = $httpContext;
        if (isset($data['jsLayout'])) {
            $this->jsLayout = array_merge_recursive($jsLayoutDataProvider->getData(), $data['jsLayout']);
            unset($data['jsLayout']);
        } else {
            $this->jsLayout = $jsLayoutDataProvider->getData();
        }

        parent::__construct($context,$data);
        $this->_customerUrl = $customerUrl;
    }
    /**
     * @return string
     */
    public function getHref()
    {
        return $this->isLoggedIn()
            ? $this->_customerUrl->getLogoutUrl()
            : $this->_customerUrl->getLoginUrl();
    }
	/**
     * @return string
     */
    public function getLoginText()
    {
        return $this->isLoggedIn()
            ? __('Log out')
            : __('Login');
    }

    public function getForgotPasswordActionUrl(){

        return $this->getUrl('customer/account/forgotpasswordpost');
    }

    /**
     * Returns popup config
     *
     * @return array
     */
    public function getConfig()
    {
        return [
            'customerRegisterUrl' => $this->getCustomerRegisterUrlUrl(),
            'customerForgotPasswordUrl' => $this->getCustomerForgotPasswordUrl(),
            'baseUrl' => $this->getBaseUrl()
        ];
    }

    /**
     * Return base url.
     *
     * @return string
     */
    public function getBaseUrl()
    {
        return $this->_storeManager->getStore()->getBaseUrl();
    }

    /**
     * Get customer register url
     *
     * @return string
     */
    public function getCustomerRegisterUrlUrl()
    {
        return $this->getUrl('customer/account/create');
    }

    /**
     * Get customer forgot password url
     *
     * @return string
     */
    public function getCustomerForgotPasswordUrl()
    {
        return $this->getUrl('customer/account/forgotpassword');
    }

    /**
     * Is logged in
     *
     * @return bool
     */
    public function isLoggedIn()
    {
        return $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
    }
}

Now as per defined in layout file, we will add our JS component and phtml files.

Add app/code/Magelearn/Minilogin/view/frontend/templates/account/link/mini-login.phtml file.

<div data-block="mini_login" class="minicart-wrapper">
    <a class="action showlogin" href="<?php /* @escapeNotVerified */
    echo $this->getHref(); ?>"
       data-bind="scope: 'mini_login_content'">
        <span class="text"><?php /* @escapeNotVerified */
            echo $this->getLoginText(); ?></span>
    </a>
	<!-- for making "closeOnMouseLeave": true, Add
		"triggerEvent": "hover"
		"closeOnMouseLeave": true
		and remove "timeout": "2000"
	-->
    <div class="block block-minicart empty"
         data-role="dropdownDialog"
         data-mage-init='{"dropdownDialog":{
                "appendTo":"[data-block=mini_login]",
                "triggerTarget":".showlogin",
                "timeout": "2000",
                "closeOnMouseLeave": false,
                "closeOnEscape": true,
                "triggerClass":"active",
                "parentClass":"active",
                "triggerEvent" : "mouseenter",
                "buttons":[]}}'>
        <div id="mini-login-content-wrapper" data-bind="scope: 'mini_login_content'">
            <h3 class="title">
            	<?php echo ($block->isLoggedIn()) ? '<span data-bind="html: getCustomerName()"></span>' : 'Login'; ?>
            </h3>
            <?php if ($block->isLoggedIn()): ?>
            	<p data-bind="text: customsection().customdata"></p>
            	<ul class="account-links">
	            	<li><a href="<?php echo $this->getUrl('wishlist') ?>">Wishlist</a></li>
	            	<li><a href="<?php echo $this->getUrl('customer/account') ?>">My Account</a></li>
	            	<li><a href="<?php echo $this->getUrl('customer/account/logout') ?>">Logout</a></li>
            	</ul>
            <?php endif; ?>
            <?php if (!$block->isLoggedIn()): ?>
            <div class="block block-customer-login"
                 data-bind="attr: {'data-label': $t('or')}">
                <div class="block-title">
                    <strong id="block-customer-login-heading"
                            role="heading"
                            aria-level="2"
                            data-bind="i18n: 'Checkout out using your account'"></strong>
                </div>
                <!-- ko foreach: getRegion('messages') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!--/ko-->
                <!-- ko foreach: getRegion('before') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
                <div class="block-content" aria-labelledby="block-customer-login-heading">
                    <form class="form form-login"
                          method="post"
                          data-bind="submit:login, blockLoader: isLoading"
                          id="login-form">
                        <div class="fieldset login" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
                            <div class="field email required">
                                <label class="label" for="email"><span data-bind="i18n: 'Email Address'"></span></label>

                                <div class="control">
                                    <input name="username"
                                           id="email"
                                           type="email"
                                           class="input-text"
                                           data-bind="attr: {autocomplete: autocomplete}"
                                           data-validate="{required:true, 'validate-email':true}">
                                </div>
                            </div>
                            <div class="field password required">
                                <label for="pass" class="label"><span data-bind="i18n: 'Password'"></span></label>

                                <div class="control">
                                    <input name="password"
                                           type="password"
                                           class="input-text"
                                           id="pass"
                                           data-bind="attr: {autocomplete: autocomplete}"
                                           data-validate="{required:true, 'validate-password':true}">
                                </div>
                            </div>
                            <!-- ko foreach: getRegion('additional-login-form-fields') -->
                            <!-- ko template: getTemplate() --><!-- /ko -->
                            <!-- /ko -->
                        </div>
                        <div class="actions-toolbar">
                            <input name="context" type="hidden" value="checkout"/>

                            <div class="forgot-password-form">
                                <a class="action" data-bind="attr: {href: forgotPasswordUrl}, click: callForgotPwdForm">
                                    <span data-bind="i18n: 'Forgot Your Password?'"></span>
                                </a>
                            </div>

                            <div class="buttons">
                                <div class="primary">
                                    <button type="submit" class="action action-login secondary" name="send" id="send2">
                                        <span data-bind="i18n: 'Sign In'"></span>
                                    </button>
                                </div>
                                <div class="secondary">
                                    <a class="action" data-bind="attr: {href: registerUrl}">
                                        <span data-bind="i18n: 'Register'"></span>
                                    </a>
                                </div>
                            </div>
                        </div>
                    </form>

                    <form class="form form-forgotpwd no-display"
                          method="post"
                          data-bind="submit:forgotpwd"
                          id="forgotpwd-form" action="<?php echo $block->getForgotPasswordActionUrl() ?>">
                        <div class="fieldset forgotpwd" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">

                            <div class="field note"><?php /* @escapeNotVerified */ echo __('Enter your email and we\'ll email you instructions on how to reset your password.'); ?></div>
                            <div class="field email required">
                                <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label>
                                <div class="control">
                                    <input type="email" name="email" alt="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtml($block->getEmailValue()) ?>" data-validate="{required:true, 'validate-email':true}">
                                </div>
                            </div>
                        </div>
                        <div class="actions-toolbar">
                            <div class="buttons">
                                <div>
                                    <button type="submit" class="action" name="send" id="send3">
                                        <span data-bind="i18n: 'Send'"></span>
                                    </button>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
            <?php endif; ?>
        </div>
    </div>
    <script type="text/x-magento-init">
    {
        "[data-block='mini_login']": {
            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout(); ?>
        },
        "*": {
            "Magento_Ui/js/block-loader": "<?php /* @escapeNotVerified */echo $block->getViewFileUrl('images/loader-1.gif'); ?>"
        }
    }
    </script>
</div>

Now add app/code/Magelearn/Minilogin/view/frontend/web/js/view/minilogin.js file.

define([
    'uiComponent',
    'jquery',
    'ko',
    'mage/translate',
    'Magento_Customer/js/action/login',
    'mage/url',
    'Magento_Customer/js/customer-data'
], function (Component, $, ko, $t, loginAction, url, customerData) {
    'use strict';

    return Component.extend({
        registerUrl: window.authenticationPopup.customerRegisterUrl,
        forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,
        autocomplete: window.checkout.autocomplete,

        isLoading: ko.observable(false),

        /** Is login form enabled for current customer */
        isActive: function() {
            var customer = customerData.get('customer');
            return customer() == false;
        },

        initialize: function () {
            var self = this;
            this._super();
            //initSidebar();
            url.setBaseUrl(window.authenticationPopup.baseUrl);
            loginAction.registerLoginCallback(function() {
                self.isLoading(false);
            });
            this.customsection = customerData.get('custom_section');
        },
        /** Provide login action */
        login: function(loginForm) {
            var loginData = {},
                formDataArray = $(loginForm).serializeArray();
            formDataArray.forEach(function (entry) {
                loginData[entry.name] = entry.value;
            });

            if($(loginForm).validation()
                && $(loginForm).validation('isValid')
            ) {
                this.isLoading(true);
                loginAction(loginData, null, false);
            }
        },
        forgotpwd: function(theForm) {
            var loginData = {},
                formDataArray = $(theForm).serializeArray();
            formDataArray.forEach(function (entry) {
                loginData[entry.name] = entry.value;
            });

            if($(theForm).validation()
                && $(theForm).validation('isValid')
            ) {
                theForm.submit();
            }
        },
        callForgotPwdForm: function() {
            if($('#forgotpwd-form').hasClass('no-display')) {
                $('#forgotpwd-form').removeClass('no-display');
            }
            else {
                $('#forgotpwd-form').addClass('no-display');
            }
            return false;
        },
        /*initSidebar: initSidebar,*/
        closeSidebar: function() {
            var mini_login = $('[data-block="mini_login"]');
            mini_login.on('click', '[data-action="close"]', function(event) {
                event.stopPropagation();
                mini_login.find('[data-role="dropdownDialog"]').dropdownDialog("close");
            });
            return true;
        },
        getCustomerName: function() {
        	var customer = customerData.get('customer');
            if(customer().fullname) {
                return customer().fullname;
            } else {
            	return customer().firstname;
            }
        }
    });
});

Now we will check how to add additional customer data in customer object.

For that first we will add app/code/Magelearn/Minilogin/etc/frontend/di.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\CustomerData\SectionPoolInterface">
        <arguments>
            <argument name="sectionSourceMap" xsi:type="array">
                <item name="custom_section" xsi:type="string">Magelearn\Minilogin\CustomerData\CustomSection</item>
            </argument>
        </arguments>
    </type>
</config>

Now as per defined in di.xml file, we will add app/code/Magelearn/Minilogin/CustomerData/CustomSection.php file.

<?php
namespace Magelearn\Minilogin\CustomerData;
use Magento\Customer\CustomerData\SectionSourceInterface;
 
class CustomSection implements SectionSourceInterface
{
    public function getSectionData()
    {
        return [
            'customdata' => "Congratulations !! You are logged in."
        ];
    }
}

0 Comments On "Display mini login besides mini cart in Magento2"

Back To Top