RomanL 8 лет назад
Родитель
Сommit
5415689e4c

+ 8 - 6
modules/base/general/js/showcase.js

@@ -3,10 +3,12 @@ $(document).ready(function () {
 });
 
 function bx_showcase_view_init() {
-    $('.bx-base-unit-showcase-wrapper').flickity({
-        cellSelector: '.bx-base-unit-showcase',
-        cellAlign: 'left',
-        pageDots: false,
-        imagesLoaded: true
-    });
+	if($('.bx-base-unit-showcase-wrapper').closest('.bx-popup-wrapper').length == 0){
+		$('.bx-base-unit-showcase-wrapper').flickity({
+			cellSelector: '.bx-base-unit-showcase',
+			cellAlign: 'left',
+			pageDots: false,
+			imagesLoaded: true
+		});
+	}
 }

+ 28 - 0
modules/boonex/attendant/classes/BxAttendantAlertsResponse.php

@@ -0,0 +1,28 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAttendantAlertsResponse extends BxDolAlertsResponse
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    
+    public function response($oAlert)
+    {
+        if ($oAlert->sUnit == 'profile' && $oAlert->sAction == 'add'){
+            $oModule = BxDolModule::getInstance('bx_attendant');
+            $oModule->initPopupWithRecommendedOnProfileAdd($oAlert->iObject);
+        }
+    }
+}
+
+/** @} */

+ 41 - 0
modules/boonex/attendant/classes/BxAttendantConfig.php

@@ -0,0 +1,41 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleConfig');
+
+class BxAttendantConfig extends BxBaseModGeneralConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+        $this->CNF = array (
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'events',
+            
+             // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_METHOD' => 'method',
+            'FIELD_ACTION' => 'action',
+            'FIELD_ADDED' => 'added',
+            'FIELD_PROCESSED' => 'processed',
+            'FIELD_OBJECT_ID' => 'object_id'
+        );
+        $this->_aJsClasses = array(
+           'main' => 'BxAttendantPopupWithRecommendedOnProfileAdd'
+        );
+        $this->_aJsObjects = array(
+            'main' => 'oBxAttendantPopupWithRecommendedOnProfileAdd'
+        );
+    }
+    
+}
+
+/** @} */

+ 87 - 0
modules/boonex/attendant/classes/BxAttendantDb.php

@@ -0,0 +1,87 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleDb');
+
+class BxAttendantDb extends BxBaseModGeneralDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+
+        $this->_oConfig = $oConfig;
+        $CNF = $oConfig->CNF;
+        $this->_sTableEntries = $CNF['TABLE_ENTRIES'];
+    }
+    
+    public function getEvents($aParams, $bReturnCount = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+        $sSelectClause = $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        $sSelectClause = "`{$this->_sTableEntries}`.*";
+
+        switch($aParams['type']) {
+            case 'active_by_action_and_object_id':
+                $aMethod['name'] = 'getAll';
+                $aMethod['params'][1] = array(
+                    'action' => $aParams['action'],
+                    'object_id' => $aParams['object_id']
+                );
+                $sWhereClause = "AND `{$this->_sTableEntries}`.`" . $CNF['FIELD_ACTION'] . "` =:action  AND `{$this->_sTableEntries}`.`" . $CNF['FIELD_OBJECT_ID'] . "` =:object_id AND `" . $CNF['FIELD_PROCESSED'] . "` IS NULL";
+                break;
+            case 'all':
+                $aMethod['name'] = 'getAll';
+                $aMethod['params'][1] = array(
+                    'request_id' => $aParams['value']
+                );
+                break;
+        }
+
+        $sSql = "SELECT {select} FROM `{$this->_sTableEntries}` " . $sJoinClause . " WHERE 1 " . $sWhereClause . " {order} {limit}";
+        
+        $aMethod['params'][0] = str_replace(array('{select}', '{order}', '{limit}'), array($sSelectClause, $sOrderClause, $sLimitClause), $sSql);
+        $aEntries = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+        
+        if(!$bReturnCount)
+            return $aEntries;
+
+        $aMethod['name'] = 'getOne';
+        $aMethod['params'][0] = str_replace(array('{select}', '{order}', '{limit}'), array("COUNT(*)", "", ""), $sSql);
+
+        return array($aEntries, (int)call_user_func_array(array($this, $aMethod['name']), $aMethod['params']));
+    }
+    
+    public function addEvent($sMethod, $sAction, $iObjectId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'method' => $sMethod,
+            'action' => $sAction,
+            'added' => time(),
+            'object_id' => $iObjectId
+        );
+        $this->query("INSERT INTO `" . $CNF['TABLE_ENTRIES'] . "` (`" . $CNF['FIELD_METHOD'] . "`, `" . $CNF['FIELD_ACTION'] . "`, `" . $CNF['FIELD_ADDED'] . "`, `" . $CNF['FIELD_OBJECT_ID'] . "`) values (:method, :action, :added, :object_id)", $aBindings);
+    }
+    
+    public function setEventProcessed($id)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'processed' => time()
+        );
+        $this->query("UPDATE `" . $CNF['TABLE_ENTRIES'] . "` SET   `" . $CNF['FIELD_PROCESSED'] . "` = :processed", $aBindings);
+    }
+}
+
+/** @} */

+ 115 - 0
modules/boonex/attendant/classes/BxAttendantModule.php

@@ -0,0 +1,115 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+define('BX_ATTENDANT_ON_PROFILE_CREATION_METHOD', 'browse_recommended');
+
+class BxAttendantModule extends BxDolModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    /**
+     * Service methods
+     */
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-on-profile get_profile_modules
+     * 
+     * @code bx_srv('bx_attendant', 'get_profile_modules', [...]); @endcode
+     * 
+     * Get list of avaliable modules for on_profile_creation event
+     * 
+     * @return an array with avaliable modules. 
+     * 
+     * @see BxAttendantModule::serviceGetProfileModules
+     */
+    /** 
+     * @ref bx_attendant-get_profile_modules "get_profile_modules"
+     */
+    public function serviceGetProfileModules()
+    {
+        $aResult = array();
+        $BxDolModuleQuery = BxDolModuleQuery::getInstance();
+        $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
+        foreach($aModules as $aModule){
+            if(BxDolRequest::serviceExists($aModule['name'], BX_ATTENDANT_ON_PROFILE_CREATION_METHOD)){
+                $aResult[$aModule['name']] = $aModule['title'];
+            }
+        }
+        return $aResult;
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_attendant Attendant
+     * @subsection bx_attendant-other Other
+     * @subsubsection bx_attendant-get_profile_modules handle_action_view
+     * 
+     * @code bx_srv('bx_attendant', 'handle_action_view', [...]); @endcode
+     * 
+     * Get Include for injection
+     * 
+     * @return an include code
+     * 
+     * @see BxAttendantModule::HandleActionView
+     */
+    /** 
+     * @ref bx_attendant-handle_action_view "handle_action_view"
+     */
+    public function serviceHandleActionView()
+    {
+        if (!isLogged())
+            return;
+        $sRv = '';
+        $aEvents = $this->_oDb->getEvents(array('type' => 'active_by_action_and_object_id', 'action' => 'view', 'object_id' => bx_get_logged_profile_id()));
+        foreach($aEvents as $aEvent){
+            $sRv .= call_user_func_array(array($this, $aEvent['method']), array($aEvent['object_id']));
+            //$this->_oDb->setEventProcessed($aEvent['id']);
+        }
+        return $sRv;
+    }
+    
+    public function serviceHandleActionNonView()
+    {
+       //for some other actions fex cron - not implemented
+    }
+    
+    public function addEvent($sMethod, $sAction, $iObjectId)
+    {
+        $this->_oDb->addEvent($sMethod, $sAction, $iObjectId);
+    }
+    
+    public function initPopupWithRecommendedOnProfileAdd($iProfileId)
+    {
+        $this->addEvent('processPopupWithRecommendedOnProfileAdd', 'view', $iProfileId);
+    }
+    
+    public function processPopupWithRecommendedOnProfileAdd($iProfileId)
+    {
+        $sRv = '';
+        $aModules = explode(',', getParam('bx_attendant_on_profile_creation_modules'));
+        $aModulteData = array();
+        foreach($aModules as $sModuleName){
+            if(BxDolRequest::serviceExists($sModuleName, BX_ATTENDANT_ON_PROFILE_CREATION_METHOD)){
+                $aTmp = BxDolService::call($sModuleName, BX_ATTENDANT_ON_PROFILE_CREATION_METHOD, array('unit_view' => 'showcase', 'empty_message' => false, "ajax_paginate" => false));
+                array_push($aModulteData, $aTmp['content']);
+            }
+        }
+        $sRv = $this->_oTemplate->popupWithRecommendedOnProfileAdd($aModulteData);
+        return $sRv;
+    }
+}
+
+/** @} */

+ 44 - 0
modules/boonex/attendant/classes/BxAttendantTemplate.php

@@ -0,0 +1,44 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import ('BxDolModuleTemplate');
+
+class BxAttendantTemplate extends BxBaseModGeneralTemplate
+{
+    var $sContainerId = 'oBxAttendantPopupWithRecommendedOnProfileAdd';
+    
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+    
+    function popupWithRecommendedOnProfileAdd($aModuleData)
+    {
+        $this->addJs('main.js');
+        $this->addCss('main.css');
+        $aVars = array();
+        foreach ($aModuleData as $sModuleData)
+            array_push($aVars, array ('html' => $sModuleData));
+        $oBxBaseFunctions = BxBaseFunctions::getInstance();
+        return  $this->getJsCode('main') . $oBxBaseFunctions->transBox($this->sContainerId, $this->parseHtmlByName('popup_recommended.html', array ('bx_repeat:items' => $aVars)), true, true);
+    }
+    
+    public function getJsCode($sType, $aParams = array(), $bWrap = true)
+    {
+        $aParams = array_merge(array(
+            'sContainerId' => $this->sContainerId
+        ), $aParams);
+        
+        return parent::getJsCode($sType, $aParams, $bWrap);
+    }
+}
+
+/** @} */

+ 77 - 0
modules/boonex/attendant/install/config.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_attendant',
+    'title' => 'Attendant',
+    'note' => 'Attendant module.',
+    'version' => '9.0.1.DEV',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/attendant/',
+    'home_uri' => 'attendant',
+
+    'db_prefix' => 'bx_attendant_',
+    'class_prefix' => 'BxAttendant',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Attendant',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/attendant/install/installer.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAttendantInstaller extends BxBaseModTextInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 9 - 0
modules/boonex/attendant/install/langs/en.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_attendant"><![CDATA[Attendant]]></string>
+  <string name="_bx_attendant_adm_stg_cpt_type"><![CDATA[Attendant]]></string>
+  <string name="_bx_attendant_adm_stg_cpt_category_general"><![CDATA[General]]></string>
+  <string name="_bx_attendant_adm_stg_cpt_category_on_profile_creation"><![CDATA[Popup with recomended profiles on profile add]]></string>
+  <string name="_bx_attendant_adm_stg_on_profile_creation_modules_list"><![CDATA[Modules list]]></string>
+  
+</resources>

+ 15 - 0
modules/boonex/attendant/install/sql/disable.sql

@@ -0,0 +1,15 @@
+SET @sName = 'bx_attendant';
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` IN (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId);
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- INJECTION
+DELETE FROM `sys_injections` WHERE `name`= @sName;
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;

+ 29 - 0
modules/boonex/attendant/install/sql/enable.sql

@@ -0,0 +1,29 @@
+SET @sName = 'bx_attendant';
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT IFNULL(MAX(`order`), 0) + 1 FROM `sys_options_types` WHERE `group` = 'modules');
+
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) 
+VALUES('modules', @sName, '_bx_attendant_adm_stg_cpt_type', 'bx_attendant@modules/boonex/attendant/|std-icon.svg', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `hidden`, `order`) VALUES(@iTypeId,  'bx_attendant_general', '_bx_attendant_adm_stg_cpt_category_general', 0, 1);
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `hidden`, `order`) VALUES(@iTypeId,  'bx_attendant_on_profile_creation', '_bx_attendant_adm_stg_cpt_category_on_profile_creation', 0, 2);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_params`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_attendant_on_profile_creation_modules', '_bx_attendant_adm_stg_on_profile_creation_modules_list', '', 'list', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:19:"get_profile_modules";}', '', '', '', 1);
+
+-- INJECTION
+INSERT INTO `sys_injections`(`name`, `page_index`, `key`, `type`, `data`, `replace`, `active`) VALUES
+(@sName, 0, 'injection_footer', 'service', 'a:2:{s:6:"module";s:12:"bx_attendant";s:6:"method";s:18:"handle_action_view";}', '0', '1');
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxAttendantAlertsResponse', 'modules/boonex/attendant/classes/BxAttendantAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('profile', 'add', @iHandler);

+ 28 - 0
modules/boonex/attendant/install/sql/install.sql

@@ -0,0 +1,28 @@
+SET @sName = 'bx_attendant';
+
+-- TABLE: data
+CREATE TABLE `bx_attendant_events` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `method` varchar(50) NOT NULL,
+  `added` int(11) DEFAULT NULL,
+  `processed` int(11) DEFAULT NULL,
+  `action` varchar(10) NOT NULL,
+  `object_id` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  INDEX `object_id` (`object_id`),
+  INDEX `action` (`action`)
+);
+-- STUDIO: page & widget
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_attendant', '_bx_attendant', 'bx_attendant@modules/boonex/attendant/|std-icon.svg');
+
+SET @iPageId = LAST_INSERT_ID();
+
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`, `bookmark`) 
+VALUES(@iPageId, @sName, '{url_studio}module.php?name=bx_attendant', '', 'bx_attendant@modules/boonex/attendant/|std-icon.svg', '_bx_attendant', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}', 0);
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT IFNULL(MAX(`order`), 0) + 1 FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), @iParentPageOrder);

+ 11 - 0
modules/boonex/attendant/install/sql/uninstall.sql

@@ -0,0 +1,11 @@
+SET @sName = 'bx_attendant';;
+
+-- TABLES
+DROP TABLE IF EXISTS `bx_attendant_events`;
+
+-- STUDIO WIDGET
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = @sName;
+
+

+ 50 - 0
modules/boonex/attendant/js/main.js

@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Attendant Attendant
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxAttendantPopupWithRecommendedOnProfileAdd(oOptions) {
+    this._sContainerId = oOptions.sContainerId == undefined ? 'oBxAttendantPopupWithRecommendedOnProfileAdd' : oOptions.sContainerId;
+    var $this = this;
+    $(document).ready(function () {
+        $this.init();
+    });
+}
+
+BxAttendantPopupWithRecommendedOnProfileAdd.prototype.init = function () {
+    var $this = this;
+
+    $('.bx-pwropa-item-container').hide().first().show();
+    $('#' + $this._sContainerId).dolPopup({ onShow: $this.Show() });
+    $('.bx-pwropa-button').click(function () {
+        $oCurr = $('.bx-pwropa-item-container:visible').hide();
+        $oNext = $oCurr.next(); $oNext.show();
+        $this.ReInitFlickity();
+        if (!$oNext.length) {
+            $('.bx-pwropa-container').hide();
+        }
+        
+    });
+}
+
+BxAttendantPopupWithRecommendedOnProfileAdd.prototype.Show = function () {
+    var $this = this;
+    $('#' + $this._sContainerId + ' .bx-base-pofile-unit-cnt').css('height', 'auto');
+    $('#' + $this._sContainerId + ' .bx-pwropa-item-container:visible .bx-base-unit-showcase-wrapper').flickity();
+    $this.ReInitFlickity();
+}
+
+BxAttendantPopupWithRecommendedOnProfileAdd.prototype.ReInitFlickity = function () {
+    var $this = this;
+    $('#' + $this._sContainerId + ' .bx-pwropa-item-container:visible .bx-base-unit-showcase-wrapper').flickity({
+        cellSelector: '.bx-base-unit-showcase',
+        cellAlign: 'left',
+        pageDots: false,
+        imagesLoaded: true
+    });
+}

+ 18 - 0
modules/boonex/attendant/request.php

@@ -0,0 +1,18 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+* Copyright (c) UNA, Inc - https://una.io
+* MIT License - https://opensource.org/licenses/MIT
+*
+* @defgroup    Attendant Attendant
+* @ingroup     UnaModules
+*
+* @{
+*/
+
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+check_logged();
+
+BxBaseModTextRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 11 - 0
modules/boonex/attendant/template/css/main.css

@@ -0,0 +1,11 @@
+.bx-pwropa-button-container {
+    width: 100%;
+    text-align: center;
+}
+.bx-pwropa-button-container .bx-pwropa-button {
+    float:none;
+    width:100px;
+    margin:0px auto;
+}
+.bx-pwropa-item-container {
+}

Разница между файлами не показана из-за своего большого размера
+ 10 - 0
modules/boonex/attendant/template/images/icons/std-icon.svg


+ 10 - 0
modules/boonex/attendant/template/popup_recommended.html

@@ -0,0 +1,10 @@
+<div class="bx-def-page-width bx-pwropa-container bx-def-padding bx-page-block-container">
+    <div class="bx-def-margin-bottom">
+        <bx_repeat:items>
+            <div class="bx-pwropa-item-container">__html__</div>
+        </bx_repeat:items>
+    </div>
+    <div class="bx-pwropa-button-container">
+        <a class="bx-btn bx-btn-small bx-pwropa-button">Contunie</a>
+    </div>
+</div>

Некоторые файлы не были показаны из-за большого количества измененных файлов