Commit 571e8b08 by Иван Кубота

Set object to Store.

Refactor console logs
parents 2682f572 e15162cf
...@@ -44,7 +44,7 @@ NS.apply = function(a,b) { ...@@ -44,7 +44,7 @@ NS.apply = function(a,b) {
cls: true, className: true, 'class': true, cls: true, className: true, 'class': true,
attr: true, style: true, renderTo: true, attr: true, style: true, renderTo: true,
prop: true, bind: true, prop: true, bind: true,
on: true on: true, renderto: true
}; };
var fastDomEl = function(type, cfg) { var fastDomEl = function(type, cfg) {
cfg = cfg || {}; cfg = cfg || {};
...@@ -384,7 +384,8 @@ NS.apply = function(a,b) { ...@@ -384,7 +384,8 @@ NS.apply = function(a,b) {
D.declare = function(name, ctor) { D.declare = function(name, ctor) {
var uses; var uses;
if(name in usage){ if(name in usage){
console.log(`${name} declaration updated. Usage count: ${usage[name].instances.length}`) log('updated', `${name} (${usage[name].instances.length})`)
usage[ name ].ctor = ctor; usage[ name ].ctor = ctor;
uses = usage[ name ].instances; uses = usage[ name ].instances;
for( var i = 0, _i = uses.length; i < _i; i++ ){ for( var i = 0, _i = uses.length; i < _i; i++ ){
...@@ -395,7 +396,8 @@ NS.apply = function(a,b) { ...@@ -395,7 +396,8 @@ NS.apply = function(a,b) {
} }
} }
}else{ }else{
console.log(`${name} declared`)
log('declared', `${name}`);
uses = (usage[ name ] = {ctor: ctor, instances: []}).instances; uses = (usage[ name ] = {ctor: ctor, instances: []}).instances;
} }
return populate(name, function construct (cfg, p) { return populate(name, function construct (cfg, p) {
...@@ -403,7 +405,29 @@ NS.apply = function(a,b) { ...@@ -403,7 +405,29 @@ NS.apply = function(a,b) {
uses.push({dom: dom, cfg: cfg, p: p}); uses.push({dom: dom, cfg: cfg, p: p});
return dom; return dom;
}); });
} };
var _log = [], later = false,
realLog = function() {
later = false;
var aggregated = _log.reduce(function(s, item) {
(s[item.evt] || (s[item.evt] = [])).push(item);
return s;
}, {});
_log.length = 0;
for(var evt in aggregated){
console.log('DOM:'+evt+' → '+aggregated[evt].map(function(item) {
return item.args.join(' ');
}).join(', '));
}
};
var log = function(evt) {
_log.push({type: 'log', evt: evt, args: [].slice.call(arguments, 1)});
if(!later)
later = setTimeout(realLog, 1000);
};
})(window['NS'], typeof window !== "undefined" ? window : })(window['NS'], typeof window !== "undefined" ? window :
typeof WorkerGlobalScope !== "undefined" ? self : typeof WorkerGlobalScope !== "undefined" ? self :
typeof global !== "undefined" ? global : typeof global !== "undefined" ? global :
......
...@@ -74,10 +74,10 @@ ansispan.foregroundColors = { ...@@ -74,10 +74,10 @@ ansispan.foregroundColors = {
var script = document.createElement( 'script' ); var script = document.createElement( 'script' );
script.setAttribute( 'type', script.type = 'text/javascript' ); script.setAttribute( 'type', script.type = 'text/javascript' );
script.onload = function(a,b,c){ script.onload = function(a,b,c){
if(fileName.indexOf('Fields')>-1){ /*if(fileName.indexOf('Fields')>-1){
//debugger //debugger
console.log('akkk',a,b,c) console.log('akkk',a,b,c)
} }*/
}; };
script.onerror = function(a,b,c){ script.onerror = function(a,b,c){
...@@ -107,7 +107,6 @@ ansispan.foregroundColors = { ...@@ -107,7 +107,6 @@ ansispan.foregroundColors = {
var _define = function(name) { var _define = function(name) {
var definition = definitions[name]; var definition = definitions[name];
if(definition.notResolved === 0){ if(definition.notResolved === 0){
console.log(name,'execute')
definition.fn.apply(null, definition.deps.map(function(dep) { definition.fn.apply(null, definition.deps.map(function(dep) {
return dep === 'exports' ? definition.exports : definitions[dep].exports return dep === 'exports' ? definition.exports : definitions[dep].exports
})); }));
...@@ -133,7 +132,6 @@ ansispan.foregroundColors = { ...@@ -133,7 +132,6 @@ ansispan.foregroundColors = {
if( dep === 'exports' ) if( dep === 'exports' )
continue; continue;
var skip = false; var skip = false;
console.log(dep)
if( !( dep in definitions ) ){ if( !( dep in definitions ) ){
var matched = false; var matched = false;
for( var j = 0, _j = InstantLoaders.length; j < _j; j++ ){ for( var j = 0, _j = InstantLoaders.length; j < _j; j++ ){
......
...@@ -82,7 +82,18 @@ Store.prototype = { ...@@ -82,7 +82,18 @@ Store.prototype = {
recursiveSet(keys.slice(0, keys.length - 1), pointer, key, val, changeList); recursiveSet(keys.slice(0, keys.length - 1), pointer, key, val, changeList);
}, },
/*
key: String, val: any
key: {k: v, ...}
*/
set: function(key, val) { set: function(key, val) {
if(typeof key === 'object'){
for(let k in key){
this.set(k, key[k]);
}
return this;
}
let changeList = []; let changeList = [];
this._set( this._set(
typeof key === 'string' ? key.split('.') : key, typeof key === 'string' ? key.split('.') : key,
...@@ -95,7 +106,7 @@ Store.prototype = { ...@@ -95,7 +106,7 @@ Store.prototype = {
this.fire('change', changeListElement[0], changeListElement[1]); this.fire('change', changeListElement[0], changeListElement[1]);
this.fire(changeListElement[0], changeListElement[1]); this.fire(changeListElement[0], changeListElement[1]);
} }
return; return this;
}, },
get: function(key, returnLastStore) { get: function(key, returnLastStore) {
key = typeof key === 'string' ? key.split('.') : key; key = typeof key === 'string' ? key.split('.') : key;
......
...@@ -37,6 +37,15 @@ ...@@ -37,6 +37,15 @@
list-style: none; list-style: none;
} }
@mixin btn-reset {
display: inline-block;
vertical-align: top;
padding: 0;
border: 0;
background-color: transparent;
cursor: pointer;
}
@mixin hover { @mixin hover {
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
......
import './view/page/login/Login.jsx'; import './view/page/login/Login.jsx';
import './view/page/account/WelcomePage.jsx'; import './view/page/account/WelcomePage.jsx';
import './view/page/account/Account.jsx'; import './view/page/account/Account.jsx';
import './view/page/account/Profile.jsx';
import './view/page/tmp/Fields.jsx'; import './view/page/tmp/Fields.jsx';
import Header from './view/block/header/Header.jsx'; import Header from './view/block/header/Header.jsx';
......
...@@ -8,7 +8,6 @@ const store = new Store(latest = { ...@@ -8,7 +8,6 @@ const store = new Store(latest = {
userID: 5, userID: 5,
name: 'Диогроген Курославович', name: 'Диогроген Курославович',
phone: '79999877414', phone: '79999877414',
token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODAzMDg0NTcsImV4cCI6MTU4MDM5NDg1Nywicm9sZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfRU1QTE9ZRUUiXSwicGhvbmUiOiI3OTk5OTg3NzQxNCIsImlkIjo1fQ.yt7LqaBkHZ_YFXg4WV8LRrm6eW9RdBjFbWNlLBYJXDyFPKjeVuR9PTGwnZdztqRxnGEKc60FnZfqpf52rfTdgkZWuuy_jXQbxfUzRvuD2GHPd4Ds12ucQnbij71-Rv0d8mA4L3EzbEQzMfSwoQsjhY6PXmhHRft4mSuXm0Cx4cn7ms92gTBFGbSWA-Ru395jTcaTpWdpAyIQFCMwAyQ1zQDRwsYc4RPPVKTH2BhkGVLVWlMDh_D22kduV-zcEzxEAFvOf6HhctsYBaasByhXIHVKQUcSKjA5bz_eftW7XQWeer0gQNR3OLRP9Qo7INL8GnhVhGEuu5UL6x0JJ9FeutOhZ4xa0jOqwzmYRcTMP63LbWNoSGHgn-UY14yG_O31Ij0wDNS-VqhCoVB1IdGawWX_p3eKLuUvCX38ZLs3cAIU1vmHlF--0KNSwo3OeYj-U9R8tWPi-zkUDw29ZAM1wu38uXI4_bw_UG2g53cSdjxuIQw8sLmAp7EF-6R1q28YQecqVKm-d8VgVeVAh8ueicFeejSzgax-3GRjHR9Kudqgxescas6rm6g5iV_-73VUXrn-8rvg2vXuB3nF-7X-SWV2gKFBP9u0hTGMBeseODyjohN3bWjnfPWU0rWhwNUsPIJabzg0iICv4a5li507TCaHg025HEa2V2mayj0wkk8'
} }
}); });
...@@ -16,13 +15,12 @@ const store = new Store(latest = { ...@@ -16,13 +15,12 @@ const store = new Store(latest = {
try{ try{
var data = JSON.parse( localStorage.getItem( 'store' ) ); var data = JSON.parse( localStorage.getItem( 'store' ) );
window.addEventListener && console.log(data)
if(data.commit !== store.get('commit')){ if(data.commit !== store.get('commit')){
console.warn('STORE: warn outdated:'); console.warn('STORE:outdated, new state → localStorage');
console.warn('\t\tCurrent data: '+ store.get('commit'), store._props); console.warn('\tSTORE:currentData #'+ store.get('commit'), store._props);
console.warn('\t\tSaved data: '+ window.CommitID, data); console.warn('\tSTORE:savedData # '+ window.CommitID, data);
console.warn('\tRun Store.restore() for restore saved state'); console.warn('\tSTORE:hint → Run Store.restore() for restore saved state');
console.warn('\tRun Store.update() for load latest default state'); console.warn('\tStore:hint → Run Store.update() for load latest default state');
Store.restore = function() { Store.restore = function() {
for( var k in data ){ for( var k in data ){
...@@ -42,7 +40,7 @@ try{ ...@@ -42,7 +40,7 @@ try{
for( var k in data ){ for( var k in data ){
store.set( k, data[ k ] ); store.set( k, data[ k ] );
} }
console.log('STORE: loaded from localStorage'); console.log('STORE:loaded ← localStorage', data);
} }
}catch( e ){} }catch( e ){}
......
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<path d="M17.8552 4.45284L4.44862 17.8595c-.46863.4686-.46863 1.2284 0 1.697.46862.4686 1.22841.4686 1.69704 0L19.5523 6.14988c.4686-.46862.4686-1.22841 0-1.69704-.4687-.46862-1.2284-.46862-1.6971 0z" fill="currentColor"/>
<path d="M19.5523 17.8551L6.14566 4.44851c-.46863-.46863-1.22842-.46863-1.69704 0-.46863.46862-.46863 1.22841 0 1.69704L17.8552 19.5522c.4687.4686 1.2284.4686 1.6971 0 .4686-.4687.4686-1.2285 0-1.6971z" fill="currentColor"/>
</svg>
import './account.scss';
import User from "/svg/user.svg";
import Rating from '../ratingBlock/Rating.jsx';
const AccountBlock = D.declare('view.block.AccountBlock', () => {
return <div class="account">
<h2 class="account__headline">Личный кабинет</h2>
<div class="account__info">
<h3 class="account__name">
<User width="32" height="32"/>
<span>{'Ким Ир Сен Константин Му Константинович Константинопольский'.split(/\s/).map(word => <div
cls="title-name-word">{word}</div>)}</span>
</h3>
<p>Химки-2</p>
<p>Кассир</p>
</div>
<div class="account__rating">
<Rating/>
</div>
</div>
});
export default AccountBlock;
export {AccountBlock};
.account__headline {
margin: 0 0 14px;
font-weight: 500;
font-size: 17px;
line-height: 22px;
color: $gray-medium;
}
.account__info {
@include mainCaption;
padding-bottom: 10px;
border-bottom: 1px solid #747474;
}
.account__info p {
margin: 0;
}
.account__name {
position: relative;
margin: 0 0 8px;
font-weight: 700;
font-size: 24px;
line-height: 32px;
color: $text-main;
}
.account__name svg {
position: absolute;
top: 0;
right: 100%;
transform: translate(-18px, 0);
color: $accent-main;
}
.title-name-word {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
...@@ -6,7 +6,7 @@ import Logout from "/svg/logout.svg"; ...@@ -6,7 +6,7 @@ import Logout from "/svg/logout.svg";
import { Page } from "../../page/Page"; import { Page } from "../../page/Page";
const {IF, NOT} = Store; const {IF, NOT} = Store;
export default D.declare('view.block.Header', () => { const Header = D.declare('view.block.Header', () => {
const tempPageMenuHidden = new Store.Value.Boolean(true); const tempPageMenuHidden = new Store.Value.Boolean(true);
return <header class={D.cls( return <header class={D.cls(
"page-header", { "page-header", {
...@@ -21,7 +21,10 @@ export default D.declare('view.block.Header', () => { ...@@ -21,7 +21,10 @@ export default D.declare('view.block.Header', () => {
<div cls={D.cls({'hidden': tempPageMenuHidden})}>{ <div cls={D.cls({'hidden': tempPageMenuHidden})}>{
Object.keys(Page) Object.keys(Page)
.map( name => .map( name =>
<button class="temp-button" type={'button'} onClick={() => store.set('navigation.current', name)}> <button class="temp-button" type={'button'} onClick={() => {
store.set('navigation.current', name);
tempPageMenuHidden.toggle();
}}>
{name} {name}
</button> </button>
) )
...@@ -35,13 +38,13 @@ export default D.declare('view.block.Header', () => { ...@@ -35,13 +38,13 @@ export default D.declare('view.block.Header', () => {
<div class="page-header__user-block"> <div class="page-header__user-block">
<Button class={"button page-header__profile-link"} <Button class={"button page-header__profile-link"}
type={"button"} type={"button"}
aria-label={"Ссылка на страницу личного кабинетаа"} aria-label={"Перейти на страницу профиля"}
> >
<User width="32" height="32"/><span>Иванов Иван</span> <User width="32" height="32"/><span>Иванов Иван</span>
</Button> </Button>
<Button class={"button page-header__logout-link"} <Button class={"button page-header__logout-link"}
type={"button"} type={"button"}
aria-label={"Кнопка выхода"} aria-label={"Выйти из аккаунта"}
> >
<Logout width="18" height="18"/><span>Выйти</span> <Logout width="18" height="18"/><span>Выйти</span>
</Button> </Button>
...@@ -51,3 +54,6 @@ export default D.declare('view.block.Header', () => { ...@@ -51,3 +54,6 @@ export default D.declare('view.block.Header', () => {
</header> </header>
}); });
export default Header;
export {Header};
\ No newline at end of file
import './accountPage.scss'; import './accountPage.scss';
import User from "/svg/user.svg";
import Rating from '../../block/ratingBlock/Rating.jsx';
import Format from "../../cmp/format/Format"; import Format from "../../cmp/format/Format";
import AccountBlock from '../../block/account/Account.jsx';
const Account = D.declare('view.page.Account', () => { const Account = D.declare('view.page.Account', () => {
return <div class="account-page"> return <div class="account-page">
<h1 class="readers-only">Страница личного кабинета сотрудника</h1> <h1 class="readers-only">Страница личного кабинета сотрудника</h1>
<div class="account-page__wrapper"> <div class="account-page__wrapper">
<div class="account-page__menu"> <div class="account-page__menu">
<div className="account-page__menu-inner"> <div class="account-page__menu-inner">
<div class="account"> <AccountBlock />
<h2 class="account__headline">Личный кабинет</h2>
<div class="account__info">
<h3 class="account__name">
<User width="32" height="32" />
<span>{'Ким Ир Сен Константин Му Константинович Константинопольский'.split(/\s/).map(word=><div cls="title-name-word">{word}</div>)}</span>
</h3>
<p>Химки-2</p>
<p>Кассир</p>
</div>
<div class="account__rating">
<Rating />
</div>
</div>
</div> </div>
</div> </div>
<div class="account-page__content"> <div class="account-page__content">
......
import './profilePage.scss';
import AccountBlock from '../../block/account/Account.jsx';
import Cross from '/svg/cross.svg';
const Profile = D.declare('view.page.Profile', () => {
return <div class="profile-page">
<button class="profile-page__link-back" onclick={()=> store.set( 'navigation.current', 'Account')} type="button" aria-label="Вернуться на страницу аккаунта">
<Cross width="24" height="24"/>
</button>
<div class="profile-page__wrapper">
<AccountBlock/>
</div>
</div>
});
export default Profile;
export {Profile};
...@@ -39,48 +39,3 @@ ...@@ -39,48 +39,3 @@
max-height: calc(100vh - 120px); max-height: calc(100vh - 120px);
overflow-y: scroll; overflow-y: scroll;
} }
.account__headline {
margin: 0 0 14px;
font-weight: 500;
font-size: 17px;
line-height: 22px;
color: $gray-medium;
}
.account__info {
@include mainCaption;
padding-bottom: 10px;
border-bottom: 1px solid #747474;
}
.account__info p {
margin: 0;
}
.account__name {
position: relative;
margin: 0 0 8px;
font-weight: 700;
font-size: 24px;
line-height: 32px;
color: $text-main;
}
.account__name svg {
position: absolute;
top: 0;
right: 100%;
transform: translate(-18px, 0);
color: $accent-main;
}
.title-name-word {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.profile-page {
@include pageInner;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
background-color: $bg-accent;
z-index: 100;
overflow-y: auto;
}
.profile-page__link-back {
@include btn-reset;
@include hover;
position: absolute;
top: 10px;
right: 10px;
padding: 10px;
color: $text-main;
}
export {Account} from "./account/Account"; export {Account} from "./account/Account";
export {Profile} from "./account/Profile";
export {WelcomePage} from "./account/WelcomePage"; export {WelcomePage} from "./account/WelcomePage";
export {Login} from "./login/Login"; export {Login} from "./login/Login";
...@@ -6,4 +7,4 @@ export {Login} from "./login/Login"; ...@@ -6,4 +7,4 @@ export {Login} from "./login/Login";
//export {LoginCode} from "./login/LoginCode"; //export {LoginCode} from "./login/LoginCode";
export {Fields} from "./tmp/Fields"; export {Fields} from "./tmp/Fields";
export {TestRequests} from "./tmp/TestRequests"; export {TestRequests} from "./tmp/TestRequests";
\ No newline at end of file
...@@ -7,10 +7,12 @@ import Arr from '../../../svg/arr.svg'; ...@@ -7,10 +7,12 @@ import Arr from '../../../svg/arr.svg';
import LoginHelp from './LoginHelp.jsx'; import LoginHelp from './LoginHelp.jsx';
import LoginPhone from './LoginPhone.jsx'; import LoginPhone from './LoginPhone.jsx';
import LoginCode from './LoginCode.jsx'; import LoginCode from './LoginCode.jsx';
import { AsyncAuthAjax } from "../../../controller/Ajax";
import { API } from "../../../dict/Consts";
const {AND, OR, IF} = Store; const {AND, OR, IF} = Store;
const Login = D.declare('view.page.Login', () => { const Login = D.declare('view.page.Login', () => {
const loginStore = new Store({ const initialState = {
phone: '79999877415', phone: '79999877415',
code: '', code: '',
codeValid: false, codeValid: false,
...@@ -22,9 +24,29 @@ const Login = D.declare('view.page.Login', () => { ...@@ -22,9 +24,29 @@ const Login = D.declare('view.page.Login', () => {
incorrectPhone: false, incorrectPhone: false,
displayHelpPage: false, displayHelpPage: false,
codeError: false codeError: false
}); };
const loginStore = new Store(
Object.assign({}, initialState)
);
store.sub('account.token', async function(data){
if(!data){
let phone = store.get('account.phone') || loginStore.get('phone') || initialState.phone;
store.set( 'navigation.current', 'Login' );
loginStore.set(initialState);
loginStore.set({phone})
}else{
const result = await AsyncAuthAjax.get( API.ENDPOINTS.GET_USER( store.get( 'account.userID' ) ) );
store.set( 'account.data', result );
if( result.lastLoginAt ){
store.set( 'navigation.current', 'Account' );
}else{
store.set( 'navigation.current', 'Welcome' );
}
}
});
return <div className={"login-page"}> return <div className={"login-page"}>
<div class="login-page__big-logo"> <div class="login-page__big-logo">
......
...@@ -2,21 +2,23 @@ import Button from "/view/cmp/button/Button.jsx"; ...@@ -2,21 +2,23 @@ import Button from "/view/cmp/button/Button.jsx";
import { AsyncAjax } from "/core/Ajax.jsx"; import { AsyncAjax } from "/core/Ajax.jsx";
import { API } from "/dict/Consts.jsx"; import { API } from "/dict/Consts.jsx";
import Arr from '/svg/arr.svg'; import Arr from '/svg/arr.svg';
import { AsyncAuthAjax } from "../../../controller/Ajax";
const {AND, OR, IF} = Store; const {AND, OR, IF} = Store;
const LoginCode = D.declare('view.page.LoginCode', ({loginStore}) => { const LoginCode = D.declare('view.page.LoginCode', ({loginStore}) => {
const checkCode = function () { const checkCode = async function () {
loginStore.set('codeChecking', true); loginStore.set('codeChecking', true);
loginStore.set('codeError', false); loginStore.set('codeError', false);
try{ try{
// TODO: GET AUTH TOKEN. SOMEHOW
const result = await AsyncAjax.post( API.ENDPOINTS.CHECK_PHONE(), {
phone: loginStore.get('phone')
} );
store.set('account.token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODAzMDg0NTcsImV4cCI6MTU4MDM5NDg1Nywicm9sZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfRU1QTE9ZRUUiXSwicGhvbmUiOiI3OTk5OTg3NzQxNCIsImlkIjo1fQ.yt7LqaBkHZ_YFXg4WV8LRrm6eW9RdBjFbWNlLBYJXDyFPKjeVuR9PTGwnZdztqRxnGEKc60FnZfqpf52rfTdgkZWuuy_jXQbxfUzRvuD2GHPd4Ds12ucQnbij71-Rv0d8mA4L3EzbEQzMfSwoQsjhY6PXmhHRft4mSuXm0Cx4cn7ms92gTBFGbSWA-Ru395jTcaTpWdpAyIQFCMwAyQ1zQDRwsYc4RPPVKTH2BhkGVLVWlMDh_D22kduV-zcEzxEAFvOf6HhctsYBaasByhXIHVKQUcSKjA5bz_eftW7XQWeer0gQNR3OLRP9Qo7INL8GnhVhGEuu5UL6x0JJ9FeutOhZ4xa0jOqwzmYRcTMP63LbWNoSGHgn-UY14yG_O31Ij0wDNS-VqhCoVB1IdGawWX_p3eKLuUvCX38ZLs3cAIU1vmHlF--0KNSwo3OeYj-U9R8tWPi-zkUDw29ZAM1wu38uXI4_bw_UG2g53cSdjxuIQw8sLmAp7EF-6R1q28YQecqVKm-d8VgVeVAh8ueicFeejSzgax-3GRjHR9Kudqgxescas6rm6g5iV_-73VUXrn-8rvg2vXuB3nF-7X-SWV2gKFBP9u0hTGMBeseODyjohN3bWjnfPWU0rWhwNUsPIJabzg0iICv4a5li507TCaHg025HEa2V2mayj0wkk8')
}catch(e){ }catch(e){
}
setTimeout(function() {
loginStore.set('codeChecking', false); loginStore.set('codeChecking', false);
loginStore.set('codeError', true); loginStore.set('codeError', true);
}, 2000) }
}; };
loginStore.sub('code', function (code) { loginStore.sub('code', function (code) {
loginStore.set('codeValid', (code+'').length === 6); loginStore.set('codeValid', (code+'').length === 6);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment