@salla.sa/twilight-components 1.0.18 → 1.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/cjs/Helper-fcea994c.js +23 -0
  2. package/dist/cjs/index-4b8b3ffe.js +1696 -0
  3. package/dist/cjs/index.cjs.js +13 -0
  4. package/dist/cjs/loader.cjs.js +21 -0
  5. package/dist/cjs/salla-branches.cjs.entry.js +92 -0
  6. package/dist/cjs/salla-button_5.cjs.entry.js +1686 -0
  7. package/dist/cjs/salla-localization.cjs.entry.js +82 -0
  8. package/dist/cjs/salla-login-008cc893.js +125 -0
  9. package/dist/cjs/salla-offer.cjs.entry.js +50 -0
  10. package/dist/cjs/salla-product-availability.cjs.entry.js +75 -0
  11. package/dist/cjs/salla-rating.cjs.entry.js +300 -0
  12. package/dist/cjs/salla-search-c7aad59a.js +81 -0
  13. package/dist/cjs/salla-search.cjs.entry.js +11 -0
  14. package/dist/cjs/twilight-components.cjs.js +19 -0
  15. package/dist/collection/Helpers/Helper.js +19 -0
  16. package/dist/collection/collection-manifest.json +22 -0
  17. package/dist/collection/components/generate-summary.js +35 -0
  18. package/dist/collection/components/salla-branches/salla-branches.css +12 -0
  19. package/dist/collection/components/salla-branches/salla-branches.js +233 -0
  20. package/dist/collection/components/salla-button/salla-button.css +3 -0
  21. package/dist/collection/components/salla-button/salla-button.js +246 -0
  22. package/dist/collection/components/salla-localization/salla-localization.js +208 -0
  23. package/dist/collection/components/salla-login/salla-login.css +3 -0
  24. package/dist/collection/components/salla-login/salla-login.js +378 -0
  25. package/dist/collection/components/salla-modal/salla-modal.js +459 -0
  26. package/dist/collection/components/salla-offer/salla-offer.js +81 -0
  27. package/dist/collection/components/salla-product-availability/salla-product-availability.js +331 -0
  28. package/dist/collection/components/salla-rating/salla-rating.css +7 -0
  29. package/dist/collection/components/salla-rating/salla-rating.js +483 -0
  30. package/dist/collection/components/salla-search/salla-search.js +132 -0
  31. package/dist/collection/components/salla-tel-input/salla-tel-input.js +14 -0
  32. package/dist/collection/components/salla-verify/salla-verify.js +273 -0
  33. package/dist/collection/index.js +2 -0
  34. package/dist/collection/interfaces/colors.js +1 -0
  35. package/dist/collection/interfaces/index.js +2 -0
  36. package/dist/collection/interfaces/ratio.js +1 -0
  37. package/dist/collection/plugins/tailwind-theme/generator.js +62 -0
  38. package/dist/collection/plugins/tailwind-theme/index.js +26 -0
  39. package/dist/{twilight-components → esm}/Helper-d07ebbc7.js +0 -0
  40. package/dist/esm/index-092659c7.js +1668 -0
  41. package/dist/esm/index.js +4 -0
  42. package/dist/esm/loader.js +17 -0
  43. package/dist/esm/polyfills/core-js.js +11 -0
  44. package/dist/esm/polyfills/css-shim.js +1 -0
  45. package/dist/esm/polyfills/dom.js +79 -0
  46. package/dist/esm/polyfills/es5-html-element.js +1 -0
  47. package/dist/esm/polyfills/index.js +34 -0
  48. package/dist/esm/polyfills/system.js +6 -0
  49. package/dist/{twilight-components → esm}/salla-branches.entry.js +1 -1
  50. package/dist/esm/salla-button_5.entry.js +1678 -0
  51. package/dist/{twilight-components → esm}/salla-localization.entry.js +1 -1
  52. package/dist/{twilight-components/salla-login-b92c73dc.js → esm/salla-login-38586400.js} +2 -6
  53. package/dist/{twilight-components → esm}/salla-offer.entry.js +1 -1
  54. package/dist/{twilight-components → esm}/salla-product-availability.entry.js +1 -1
  55. package/dist/{twilight-components → esm}/salla-rating.entry.js +1 -1
  56. package/dist/{twilight-components/salla-search-69f2d9c1.js → esm/salla-search-ca856aab.js} +1 -1
  57. package/dist/esm/salla-search.entry.js +3 -0
  58. package/dist/esm/twilight-components.js +17 -0
  59. package/dist/index.cjs.js +1 -0
  60. package/dist/index.js +1 -0
  61. package/dist/twilight-components/index.esm.js +1 -4
  62. package/dist/twilight-components/p-03d0ec44.entry.js +1 -0
  63. package/dist/twilight-components/p-13a55257.entry.js +1 -0
  64. package/dist/twilight-components/p-160062c6.js +1 -0
  65. package/dist/twilight-components/p-47f17d3b.js +1 -0
  66. package/dist/twilight-components/p-5307c7b5.entry.js +1 -0
  67. package/dist/twilight-components/p-6a1f43c6.entry.js +1 -0
  68. package/dist/twilight-components/p-7088e517.entry.js +1 -0
  69. package/dist/twilight-components/p-924e3c88.js +1 -0
  70. package/dist/twilight-components/p-e8965b01.js +1 -0
  71. package/dist/twilight-components/p-ecb1b6cc.entry.js +1 -0
  72. package/dist/twilight-components/p-f11b401a.entry.js +1 -0
  73. package/dist/twilight-components/twilight-components.css +1 -3
  74. package/dist/twilight-components/twilight-components.esm.js +1 -125
  75. package/dist/types/components/salla-login/salla-login.d.ts +0 -1
  76. package/dist/types/components/salla-tel-input/salla-tel-input.d.ts +4 -0
  77. package/dist/types/components.d.ts +13 -0
  78. package/package.json +2 -1
  79. package/dist/twilight-components/app-globals-0f993ce5.js +0 -3
  80. package/dist/twilight-components/css-shim-a64b8820.js +0 -4
  81. package/dist/twilight-components/dom-d08ba8aa.js +0 -73
  82. package/dist/twilight-components/index-8966d27f.js +0 -3010
  83. package/dist/twilight-components/salla-button.entry.js +0 -75
  84. package/dist/twilight-components/salla-login-7c25f64b.js +0 -116
  85. package/dist/twilight-components/salla-login.entry.js +0 -3
  86. package/dist/twilight-components/salla-modal.entry.js +0 -113
  87. package/dist/twilight-components/salla-search.entry.js +0 -3
  88. package/dist/twilight-components/salla-verify.entry.js +0 -114
  89. package/dist/twilight-components/shadow-css-bc14d9fd.js +0 -389
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-4b8b3ffe.js');
6
+ const Helper = require('./Helper-fcea994c.js');
7
+
8
+ const SallaLocalization = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ var _a, _b;
12
+ this.language = salla.config.get('language', {});
13
+ this.currency = salla.config.get('currency', {});
14
+ this.languagesTitle = salla.lang.get('common.titles.language');
15
+ this.currenciesTitle = salla.lang.get('common.titles.currency');
16
+ this.ok = salla.lang.get('common.elements.ok');
17
+ Helper.Helper.setHost(this.host);
18
+ salla.event.on('localization::show', () => this.show());
19
+ /**
20
+ * letting developer to insert his own slot like:
21
+ * <salla-localization>
22
+ * <div slot="language">...{name}....</div>
23
+ * <div slot="currency">...{name}....</div>
24
+ * </salla-localization>
25
+ * Because scoped templates not supported in stencil );
26
+ * we made a workaround to pass language & currency attributes, then replace names in rendering
27
+ */
28
+ this.languageSlot = ((_a = Helper.Helper.getElement('[slot="language"]')) === null || _a === void 0 ? void 0 : _a.innerHTML) || '<label class="s-localization-label" for="lang-{code}"><span>{name}</span><div class="s-localization-flag flag iti__flag iti__{country_code}"></div></label>';
29
+ this.currencySlot = ((_b = Helper.Helper.getElement('[slot="currency"]')) === null || _b === void 0 ? void 0 : _b.innerHTML) || '<label class="s-localization-label" for="currency-{code}"><span>{name}</span><small class="s-localization-currency">{code}</small></label>';
30
+ this.languages = Object.values(salla.config.get('languages', {}));
31
+ this.currencies = Object.values(salla.config.get('currencies', {}));
32
+ }
33
+ async show() {
34
+ return this.modal.show();
35
+ }
36
+ async hide() {
37
+ return this.modal.hide();
38
+ }
39
+ onChangeCurrency(event) {
40
+ this.currency = salla.config.get('currencies.' + event.target.value);
41
+ }
42
+ onChangeLanguage(event) {
43
+ this.language = salla.config.get('languages.' + event.target.value);
44
+ }
45
+ async submit() {
46
+ let url;
47
+ console.log('this.currency.code::::', this.currency, this.currency.code);
48
+ this.btn.load()
49
+ .then(() => this.currency.code === salla.config.get('user.currency') || ((url = window.location.href) && salla.currency.api.change(this.currency.code)))
50
+ .then(() => this.language.code === salla.config.get('user.language') || (url = this.language.url))
51
+ .then(() => this.btn.stop())
52
+ .then(() => this.hide())
53
+ .then(() => url && (window.location.href = url));
54
+ }
55
+ render() {
56
+ return (index.h("salla-modal", { id: "salla-localization", class: "hidden", ref: modal => this.modal = modal, "modal-width": "xs" }, index.h("div", { slot: "header" }, index.h("slot", { name: "header" })), index.h("div", { class: "s-localization-inner" }, this.languages.length > 1 ?
57
+ index.h("div", { class: "s-localization-section" }, index.h("label", { class: "s-localization-title" }, this.languagesTitle), index.h("div", { class: "s-localization-section-inner" }, this.languages.length < 6 ?
58
+ this.languages.map(lang => index.h("div", { class: "s-localization-item" }, index.h("input", { class: "s-localization-input", type: "radio", checked: this.language.code == lang.code, onChange: () => this.language = lang, name: "language", id: 'lang-' + lang.code.toLowerCase(), value: lang.code }), index.h("div", { id: "language-slot", innerHTML: this.languageSlot
59
+ .replace(/\{name\}/g, lang.name)
60
+ .replace(/\{code\}/g, lang.code)
61
+ .replace(/\{country_code\}/g, lang.country_code) }))) :
62
+ index.h("select", { class: "s-branches-select", name: "currency", onChange: e => this.onChangeLanguage(e) }, this.languages.map(lang => index.h("option", { value: lang.code, selected: this.language.code == lang.code }, lang.name)))))
63
+ : '', this.currencies.length > 1 ?
64
+ index.h("div", { class: "s-localization-section" }, index.h("label", { class: "s-localization-title" }, this.currenciesTitle), index.h("div", { class: "s-localization-section-inner" }, this.currencies.length < 6 ?
65
+ this.currencies.map(currency => index.h("div", { class: "s-localization-item" }, index.h("input", { class: "s-localization-input", type: "radio", name: "currency", checked: this.currency.code == currency.code, onChange: () => this.currency = currency, id: 'currency-' + currency.code, value: currency.code }), index.h("div", { id: "currency-slot", innerHTML: this.currencySlot
66
+ .replace(/\{name\}/g, currency.name)
67
+ .replace(/\{code\}/g, currency.code)
68
+ .replace(/\{country_code\}/g, currency.country_code) }))) :
69
+ index.h("select", { class: "s-branches-select", name: "currency", onChange: e => this.onChangeCurrency(e) }, this.currencies.map(currency => index.h("option", { value: currency.code, selected: this.currency.code == currency.code }, currency.name)))))
70
+ : ''), index.h("slot", { name: "footer" }, index.h("salla-button", { wide: true, ref: btn => this.btn = btn, onClick: () => this.submit() }, this.ok))));
71
+ }
72
+ /**
73
+ * to reduce dom levels we will move slot data into the parent dom
74
+ */
75
+ componentDidRender() {
76
+ this.host.querySelectorAll('#currency-slot').forEach(el => el.replaceWith(el.firstChild));
77
+ this.host.querySelectorAll('#language-slot').forEach(el => el.replaceWith(el.firstChild));
78
+ }
79
+ get host() { return index.getElement(this); }
80
+ };
81
+
82
+ exports.salla_localization = SallaLocalization;
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ const index = require('./index-4b8b3ffe.js');
4
+ const Helper = require('./Helper-fcea994c.js');
5
+
6
+ const sallaLoginCss = "salla-verify{display:block}";
7
+
8
+ const SallaLogin = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ this.regType = 'sms';
12
+ this.isLoginByMail = true;
13
+ this.loginTypeTitle = salla.lang.get('blocks.header.select_login_way');
14
+ this.loginText = salla.lang.get('blocks.header.login');
15
+ this.smsLabel = salla.lang.get('blocks.header.sms');
16
+ this.mobileLabel = salla.lang.get('common.elements.mobile');
17
+ this.emailLabel = salla.lang.get('common.elements.email');
18
+ this.enterText = salla.lang.get('blocks.header.enter');
19
+ this.bySMSText = salla.lang.get('blocks.header.login_by_sms');
20
+ this.byEmailText = salla.lang.get('blocks.header.login_by_email');
21
+ this.backText = salla.lang.get('common.elements.back');
22
+ this.title = this.host.title || salla.lang.get('blocks.header.login');
23
+ this.host.removeAttribute('title');
24
+ salla.auth.event.onVerificationFailed(() => {
25
+ //
26
+ });
27
+ }
28
+ /**
29
+ * @param {CustomEvent|{details:{case:'new_customer'|'authenticated', redirect_url:string|null}}} event
30
+ */
31
+ onVerified(event) {
32
+ if (!event.detail.case) {
33
+ console.log('verified but without case!');
34
+ return;
35
+ }
36
+ if (event.detail.case === "new_customer") {
37
+ return this.showTab(this.tab5);
38
+ }
39
+ //TODO::It looks that is this workaround🤔
40
+ if (salla.auth.event.getTypeActionOnVerified() !== 'redirect') {
41
+ return;
42
+ }
43
+ if (event.redirect_url) {
44
+ return window.location.href = event.redirect_url;
45
+ }
46
+ window.location.reload();
47
+ }
48
+ onbackClicked() {
49
+ this.regType == 'sms' ? this.showTab(this.tab2) : this.showTab(this.tab3);
50
+ }
51
+ async show() {
52
+ this.showTab(this.isLoginByMail ? this.tab1 : this.tab2);
53
+ return this.modal.show();
54
+ }
55
+ showTab(tab) {
56
+ [this.tab1, this.tab2, this.tab3, this.tab4, this.tab5].map(el => Helper.Helper.toggleElement(el, 'visible', 'hidden', () => el == tab));
57
+ setTimeout(() => { [this.tab1, this.tab2, this.tab3, this.tab4, this.tab5].map(el => Helper.Helper.toggleElement(el, 's-login-active', 's-login-unactive', () => el == tab)); }, 200);
58
+ setTimeout(() => { this.host.querySelector('.s-login-wrapper').setAttribute('style', 'height:' + (tab === null || tab === void 0 ? void 0 : tab.scrollHeight) + 'px'); });
59
+ if ([this.tab2, this.tab3].includes(tab)) {
60
+ this.regType = tab === this.tab2 ? 'sms' : 'email';
61
+ }
62
+ let isRegistrationTab = tab == this.tab5;
63
+ this.modal.setTitle(isRegistrationTab ? salla.lang.get('common.titles.registration') : this.title);
64
+ if (!isRegistrationTab) {
65
+ Helper.Helper.toggleElement(this.regMobileBlock, 's-hidden', 's-block', () => this.regType === 'sms')
66
+ .toggleElement(this.regEmailBlock, 's-hidden', 's-block', () => this.regType === 'email');
67
+ }
68
+ return this;
69
+ }
70
+ loginByEmail() {
71
+ if (!Helper.Helper.isValidEmail(this.email.value)) {
72
+ this.email.classList.add('s-has-error');
73
+ this.email.nextElementSibling['innerText'] = '* ' + salla.lang.get('common.elements.email_is_valid');
74
+ return;
75
+ }
76
+ this.email.nextElementSibling['innerText'] = '';
77
+ this.email.classList.remove('s-has-error');
78
+ salla.auth.api.login({ type: 'email', email: this.email.value })
79
+ .then(() => this.showTab(this.tab4))
80
+ .then(() => (this.tab4.by = 'email') && (this.tab4.url = 'auth/email/verify'))
81
+ .then(() => this.tab4.show({ email: this.email.value }));
82
+ }
83
+ loginBySMS() {
84
+ if (this.mobile.value.length < 6) {
85
+ this.mobile.classList.add('s-has-error');
86
+ this.mobile.nextElementSibling['innerText'] = '* ' + salla.lang.get('mobile_app.strings.incorrect_mobile');
87
+ return;
88
+ }
89
+ this.mobile.nextElementSibling['innerText'] = '';
90
+ this.mobile.classList.remove('s-has-error');
91
+ salla.auth.api.login({ type: 'sms', mobile: this.mobile.value })
92
+ .then(() => this.showTab(this.tab4))
93
+ .then(() => (this.tab4.by = 'sms') && (this.tab4.url = 'auth/mobile/verify'))
94
+ .then(() => this.tab4.show({ mobile: this.mobile.value, country_code: 'SA' }));
95
+ }
96
+ //TODO:: if it's enter, go submit
97
+ typing({ target }) {
98
+ target.type === 'tel' && salla.helpers.digitsOnly(target);
99
+ target.classList.remove('s-has-error');
100
+ target.nextElementSibling.innerText = '';
101
+ }
102
+ newUser() {
103
+ this.tab4.getCode()
104
+ .then(code => salla.auth.api.register({
105
+ first_name: this.firstName.value,
106
+ last_name: this.lastName.value,
107
+ phone: this.regMobile.value || this.mobile.value,
108
+ email: this.regEmail.value || this.email.value,
109
+ country_code: '',
110
+ country_key: '',
111
+ code: code,
112
+ verified_by: this.regType,
113
+ }));
114
+ }
115
+ render() {
116
+ return (index.h("salla-modal", { id: "salla-login", title: this.title, ref: modal => this.modal = modal, width: "xs" }, index.h("div", { class: "s-login-wrapper" }, this.isLoginByMail ?
117
+ index.h("div", { class: "s-login-tab", ref: tab => this.tab1 = tab }, index.h("p", { class: "s-login-sub-title" }, this.loginTypeTitle), index.h("a", { href: "#", class: "s-login-main-btn", onClick: () => this.showTab(this.tab2) }, index.h("i", { class: "s-login-main-btn-icon sicon-phone" }), index.h("span", { class: "s-login-main-btn-text" }, this.smsLabel), index.h("i", { class: "main-btn-arrow sicon-keyboard_arrow_left" })), index.h("a", { href: "#", class: "s-login-main-btn", onClick: () => this.showTab(this.tab3) }, index.h("i", { class: "s-login-main-btn-icon sicon-mail" }), index.h("span", { class: "s-login-main-btn-text" }, this.emailLabel), index.h("i", { class: "main-btn-arrow sicon-keyboard_arrow_left" })))
118
+ : '', index.h("div", { class: "s-login-tab", ref: tab => this.tab2 = tab }, index.h("label", { class: "s-login-label" }, this.mobileLabel), index.h("salla-tel-input", null), index.h("input", { onChange: () => this.loginBySMS(), type: "tel", ref: el => this.mobile = el, onInput: this.typing, placeholder: "5xx xxx xxx", class: "s-login-input tel-input s-ltr" }), index.h("span", { class: "s-login-error-message" }), index.h("salla-button", { wide: true, onClick: () => this.loginBySMS() }, this.enterText), this.isLoginByMail ? index.h("a", { href: "#", onClick: () => this.showTab(this.tab3), class: "s-login-link" }, this.byEmailText) : ''), this.isLoginByMail ?
119
+ index.h("div", { class: "s-login-tab", ref: tab => this.tab3 = tab }, index.h("label", { class: "s-login-label" }, this.emailLabel), index.h("input", { onChange: () => this.loginByEmail(), type: "email", ref: el => this.email = el, onInput: this.typing, placeholder: "your@email.com", class: "s-login-input s-ltr" }), index.h("span", { class: "s-login-error-message" }), index.h("salla-button", { wide: true, onClick: () => this.loginByEmail() }, this.enterText), index.h("a", { href: "#", onClick: () => this.showTab(this.tab2), class: "s-login-link" }, this.bySMSText)) : '', index.h("salla-verify", { "without-modal": true, ref: tab => this.tab4 = tab, autoReload: false, "back-text": this.backText }), index.h("div", { ref: tab => this.tab5 = tab }, index.h("label", { class: "s-login-label" }, salla.lang.get('blocks.header.your_name')), index.h("input", { type: "text", class: "s-login-input", ref: el => this.firstName = el, placeholder: salla.lang.get('pages.profile.first_name') }), index.h("label", { class: "s-login-label" }, salla.lang.get('pages.profile.last_name')), index.h("input", { type: "text", class: "s-login-input", ref: el => this.lastName = el, placeholder: salla.lang.get('pages.profile.last_name') }), index.h("div", { ref: el => this.regMobileBlock = el }, index.h("label", { class: "s-login-label" }, this.mobileLabel), index.h("input", { type: "tel", ref: el => this.regMobile = el, onInput: this.typing, placeholder: "5xx xxx xxx", class: "s-login-input s-ltr" }), index.h("span", { class: "s-login-error-message" })), index.h("div", { ref: el => this.regEmailBlock = el }, index.h("label", { class: "s-login-label" }, this.emailLabel), index.h("input", { type: "email", ref: el => this.regEmail = el, onInput: this.typing, placeholder: "your@email.com", class: "s-login-input s-ltr" }), index.h("span", { class: "s-login-error-message" })), index.h("salla-button", { wide: true, onClick: () => this.newUser() }, salla.lang.get('blocks.header.register'))))));
120
+ }
121
+ get host() { return index.getElement(this); }
122
+ };
123
+ SallaLogin.style = sallaLoginCss;
124
+
125
+ exports.SallaLogin = SallaLogin;
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-4b8b3ffe.js');
6
+
7
+ const SallaOffer = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.offer = null;
11
+ salla.offer.event.onExisted(data => {
12
+ //TODO:: use the best, should we hide the offer by product Id or Offer id🤔
13
+ if (salla.localStore.get('remember-offer-' + data.offer.offer_id)) {
14
+ salla.log('User selected to don\'t show this offer again.');
15
+ return;
16
+ }
17
+ this.show(data.product_id);
18
+ });
19
+ }
20
+ async show(productId) {
21
+ this.modal.show()
22
+ .then(() => salla.api.offer.details(productId))
23
+ //TODO:: make sure there is only one offer
24
+ .then(response => this.offer = response.data[0])
25
+ .then(() => console.log(this.offer));
26
+ }
27
+ rememberMe(event) {
28
+ salla.localStore.set('remember-offer-' + this.offer.id, event.target.checked);
29
+ }
30
+ render() {
31
+ var _a, _b;
32
+ return index.h("salla-modal", { ref: modal => this.modal = modal, "is-loading": this.offer === null }, this.offer !== null
33
+ ? [index.h("div", { class: "s-offer-header" }, index.h("b", { class: "s-offer-title" }, this.offer.name), index.h("h3", { class: "s-offer-subtitle" }, this.offer.message)),
34
+ index.h("div", { class: "s-offer-body" }, ((_a = this.offer.get.categories) === null || _a === void 0 ? void 0 : _a.length) > 0
35
+ ? this.offer.get.categories.map(category => index.h("a", { href: category.urls.customer, class: "s-offer-badge" }, index.h("i", { class: "s-offer-badge-icon sicon-tag" }), index.h("span", { class: "s-offer-badge-text" }, category.name)))
36
+ : (_b = this.offer.get.products) === null || _b === void 0 ? void 0 : _b.map(product => index.h("div", { class: "s-offer-product" }, "- ", product.name))),
37
+ index.h("div", { class: "s-offer-footer" }, this.offer.expiry_date ?
38
+ index.h("p", { class: "s-offer-expiry" }, salla.lang.get('pages.products.offer_expires_in'), " ", this.offer.expiry_date)
39
+ : '', index.h("label", { class: "s-offer-remember-label" }, index.h("input", { type: "checkbox", onChange: e => this.rememberMe(e), class: "s-offer-remember-input" }), "\u00A0 ", salla.lang.get('common.remember_my_choice'))),
40
+ ] : '');
41
+ }
42
+ componentDidRender() {
43
+ //todo:: now from where there is hidden attributes to the doms🤔
44
+ //todo:: add animation
45
+ this.modal.querySelectorAll('[hidden]').forEach(el => el.removeAttribute('hidden'));
46
+ }
47
+ get host() { return index.getElement(this); }
48
+ };
49
+
50
+ exports.salla_offer = SallaOffer;
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-4b8b3ffe.js');
6
+ const Helper = require('./Helper-fcea994c.js');
7
+
8
+ const SallaProductAvailability = class {
9
+ constructor(hostRef) {
10
+ index.registerInstance(this, hostRef);
11
+ this.isUser = Helper.Helper.isUser();
12
+ this.buttonText = salla.lang.get('pages.products.notify_availability');
13
+ this.countryCode = salla.config.country_code || 'SA';
14
+ this.subscribeText = salla.lang.get('common.elements.submit');
15
+ this.cancelText = salla.lang.get('common.elements.cancel');
16
+ this.subTitle = salla.lang.get('pages.products.notify_availability_subtitle');
17
+ this.mobileLabel = salla.lang.get('common.elements.mobile');
18
+ this.emailLabel = salla.lang.get('common.elements.email');
19
+ this.mobilePlaceholder = salla.lang.get('common.elements.mobile_placeholder');
20
+ this.emailPlaceholder = salla.lang.get('common.elements.email_placeholder');
21
+ this.productId = salla.config.page.id;
22
+ this.subscribedMessage = salla.lang.get('pages.products.notify_availability_success');
23
+ this.isSubscribed = false;
24
+ if (this.isUser) {
25
+ return;
26
+ }
27
+ this.channelsWatcher(this.channels);
28
+ this.title_ = this.host.title || salla.lang.get('pages.products.notify_availability_title');
29
+ this.host.removeAttribute('title');
30
+ }
31
+ channelsWatcher(newValue) {
32
+ this.channels_ = newValue.split(',');
33
+ }
34
+ async submit() {
35
+ if (this.isUser) {
36
+ return salla.api.product.availabilitySubscribe(this.productId)
37
+ .then(() => this.isSubscribed = true);
38
+ }
39
+ let data = { id: this.productId, country_code: this.countryCode };
40
+ if (this.mobile.value !== '') {
41
+ data['mobile'] = this.mobile.value;
42
+ }
43
+ if (this.email.value !== '') {
44
+ data['email'] = this.email.value;
45
+ }
46
+ return this.btn.load()
47
+ .then(() => this.btn.disable())
48
+ .then(() => salla.api.product.availabilitySubscribe(data))
49
+ .then(() => this.isSubscribed = true) //no need to wait until finishing alert animation
50
+ .then(() => this.btn.stop())
51
+ .then(() => this.modal.hide())
52
+ .catch(() => this.btn.stop() && this.btn.enable());
53
+ }
54
+ render() {
55
+ return (index.h(index.Host, null, this.isSubscribed
56
+ ? index.h("div", { class: "s-product-availability-subscribed" }, this.subscribedMessage)
57
+ : index.h("slot", null, index.h("salla-button", { wide: true, onClick: () => this.isUser ? this.submit() : this.modal.show() }, this.buttonText)), this.isUser || this.isSubscribed ? '' : this.renderModal()));
58
+ }
59
+ renderModal() {
60
+ return (index.h("salla-modal", { ref: modal => this.modal = modal, title: this.title_, subTitle: this.subTitle, icon: "sicon-bell-ring", width: "md" }, index.h("div", { class: "s-product-availability-body" }, this.channels_.includes('email') ? [
61
+ index.h("label", { class: "s-product-availability-label" }, this.emailLabel),
62
+ index.h("input", { class: "s-product-availability-input", placeholder: this.emailPlaceholder, ref: el => this.email = el, type: "email" })
63
+ ] : '', this.channels_.includes('sms') ? [
64
+ index.h("label", { class: "s-product-availability-label" }, this.mobileLabel),
65
+ index.h("input", { class: "s-product-availability-input", placeholder: this.mobilePlaceholder, ref: el => this.mobile = el, type: "text" }),
66
+ index.h("input", { type: "hidden", value: this.countryCode }),
67
+ ] : ''), index.h("div", { slot: "footer", class: "s-product-availability-footer" }, index.h("salla-button", { wide: true, ref: btn => this.btn = btn, onClick: () => this.submit() }, this.subscribeText), index.h("salla-button", { wide: true, "btn-style": "outline" }, this.cancelText))));
68
+ }
69
+ get host() { return index.getElement(this); }
70
+ static get watchers() { return {
71
+ "channels": ["channelsWatcher"]
72
+ }; }
73
+ };
74
+
75
+ exports.salla_product_availability = SallaProductAvailability;
@@ -0,0 +1,300 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-4b8b3ffe.js');
6
+ const Helper = require('./Helper-fcea994c.js');
7
+
8
+ const sallaRatingCss = ":host{display:block}.unicode{unicode-bidi:plaintext}";
9
+
10
+ const SallaRating = class {
11
+ constructor(hostRef) {
12
+ index.registerInstance(this, hostRef);
13
+ this.order = {
14
+ shipping: { id: 5622 },
15
+ products: [
16
+ {
17
+ "title": "ميكروفون عالى الجودة",
18
+ "image": "https://salla-dev.s3.eu-central-1.amazonaws.com/Mvyk/pMdEEyMVpZFj4L1Hrdm2g48AuiSx0TrKULBiOnPo.jpg",
19
+ "price": "‏10,978.00 ر.س",
20
+ "qty": "‏2",
21
+ "totalBefore": "‏1120 ر.س",
22
+ "discount": "-5%",
23
+ "total": "‏1064 ر.س",
24
+ "id": "2314513454",
25
+ "getOptimusRouteKey": "7351233357"
26
+ },
27
+ {
28
+ "title": "ميكروفون عالى الجودة",
29
+ "image": "https://salla-dev.s3.eu-central-1.amazonaws.com/Mvyk/pMdEEyMVpZFj4L1Hrdm2g48AuiSx0TrKULBiOnPo.jpg",
30
+ "price": "‏10,978.00 ر.س",
31
+ "qty": "‏2",
32
+ "totalBefore": "‏1120 ر.س",
33
+ "discount": "-5%",
34
+ "total": "‏1064 ر.س",
35
+ "id": "2314513454",
36
+ "getOptimusRouteKey": "7351233357"
37
+ },
38
+ {
39
+ "title": "ساعة ذكية بنظام اندرويد",
40
+ "image": "https://salla-dev.s3.eu-central-1.amazonaws.com/Mvyk/T4kTqYNuPAZmPMLw1bx92RnjVMZyFszVXOUZQsFJ.jpg",
41
+ "price": "‏10,978.00 ر.س",
42
+ "qty": "‏2",
43
+ "totalBefore": "‏1120 ر.س",
44
+ "discount": "-5%",
45
+ "total": "‏1064 ر.س",
46
+ "id": "679822376",
47
+ "getOptimusRouteKey": "73233357"
48
+ }
49
+ ],
50
+ storeLogo: "https://salla-dev.s3.eu-central-1.amazonaws.com/Mvyk/X3NKcY7nhaFQlR7kBBHvfDpMY48cerunKrmDA1gi.png",
51
+ shippingLogo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScPt4R6KaKDldrXb-9pUljFwL3m6A72BhN6p1qZJKprwC6VbCWC_8ASZgiJAoL_l7DepM&usqp=CAU"
52
+ };
53
+ /**
54
+ * Set to true to display store rating step
55
+ */
56
+ this.isStoreRating = false;
57
+ /**
58
+ * Set to true to display products rating step
59
+ */
60
+ this.isProductsRating = false;
61
+ /**
62
+ * Set to true to display shipping rating step
63
+ */
64
+ this.isShippingRating = false;
65
+ this.ratingChain = Promise.resolve();
66
+ this.stepsCount = 0;
67
+ Helper.Helper.setHost(this.host);
68
+ }
69
+ async show() {
70
+ return this.modal.show();
71
+ }
72
+ async hide() {
73
+ return this.modal.hide();
74
+ }
75
+ componentWillLoad() {
76
+ this.stepsCount = [this.isStoreRating, this.isProductsRating, this.isShippingRating].filter(item => item).length;
77
+ // this.getData();
78
+ }
79
+ componentDidRender() {
80
+ this.show();
81
+ this.initiateRating();
82
+ }
83
+ initiateRating() {
84
+ this.handleWizard();
85
+ this.handleSubmitRating();
86
+ this.starsRating();
87
+ this.highlightSelectedStars();
88
+ }
89
+ // getdata
90
+ // private getData() {
91
+ // salla.api.order.endpointsMethods.details = 'get'
92
+ // salla.order.api.details(salla.config.page.id).then(data => console.log(''));
93
+ // }
94
+ // handle wizard
95
+ handleWizard() {
96
+ let index = 0, steps = this.host.querySelectorAll(".s-rating-step"), dots = this.host.querySelectorAll(".s-rating-step-dot"), nextBtnText = this.host.querySelector('#next-btn .s-button-text');
97
+ this.setModalHeight(steps[0]);
98
+ this.showActiveStep(steps, dots, index, nextBtnText);
99
+ Helper.Helper.onClick("#prev-btn", () => {
100
+ index > 0 && index--;
101
+ this.showActiveStep(steps, dots, index, nextBtnText);
102
+ index == 0 && Helper.Helper.toggle('#prev-btn', 's-rating-unvisiable', 'block', () => true);
103
+ });
104
+ Helper.Helper.onClick("#next-btn", () => {
105
+ this.ratingValidation();
106
+ if (index == this.stepsCount - 1) {
107
+ salla.event.dispatch("submit::order-rating");
108
+ }
109
+ else {
110
+ index < this.stepsCount - 1 && index++;
111
+ this.showActiveStep(steps, dots, index, nextBtnText);
112
+ Helper.Helper.toggle('#prev-btn', 'block', 's-rating-unvisiable', () => true);
113
+ }
114
+ });
115
+ }
116
+ showActiveStep(steps, dots, index, nextBtnText) {
117
+ var _a;
118
+ // Active step
119
+ Helper.Helper.toggle('.s-rating-step', 's-rating-hidden', 's-rating-active', () => true);
120
+ Helper.Helper.toggleElement(steps[index], 's-rating-unactive', 's-rating-hidden', () => true);
121
+ setTimeout(() => Helper.Helper.toggleElement(steps[index], 's-rating-active', 's-rating-unactive', () => true), 200);
122
+ // Hanle dots
123
+ Helper.Helper.toggle('.s-rating-step-dot', 's-rating-bg-gray', 's-rating-bg-primary', () => true);
124
+ this.stepsCount > 1 && Helper.Helper.toggleElement(dots[index], 's-rating-bg-primary', 's-rating-bg-gray', () => true);
125
+ // Btn text
126
+ nextBtnText.innerHTML = ((_a = steps[index + 1]) === null || _a === void 0 ? void 0 : _a.dataset.stepName) || salla.lang.get('pages.rating.send_ratings');
127
+ this.setModalHeight(steps[index]);
128
+ }
129
+ setModalHeight(current) {
130
+ const wrapper = this.host.querySelector('.s-rating-wrapper');
131
+ setTimeout(() => wrapper === null || wrapper === void 0 ? void 0 : wrapper.setAttribute('style', 'height:' + (current === null || current === void 0 ? void 0 : current.scrollHeight) + 'px'));
132
+ }
133
+ // Listen to submit::order-rating event used in handleWizard()
134
+ handleSubmitRating() {
135
+ salla.event.on('submit::order-rating', () => this.sendRating().then(() => {
136
+ // Handle timer
137
+ let thankYouView = this.host.querySelector('.s-rating-thanks'), seconds = 10;
138
+ let timeToClose = setInterval(() => {
139
+ seconds--;
140
+ this.host.querySelector('.s-rating-thanks-time').innerHTML = `00:0${seconds}`;
141
+ if (seconds == 0) {
142
+ this.hide();
143
+ clearInterval(timeToClose);
144
+ }
145
+ }, 1000);
146
+ // Hide steps and show thanks msg
147
+ Helper.Helper.toggle('.s-rating-step', 's-rating-hidden', 's-rating-active', () => true);
148
+ this.host.querySelector('.s-rating-footer').classList.add('s-rating-unvisiable');
149
+ Helper.Helper.toggleElement(thankYouView, 's-rating-unactive', 's-rating-hidden', () => true);
150
+ setTimeout(() => Helper.Helper.toggleElement(thankYouView, 's-rating-active', 's-rating-unactive', () => true), 200);
151
+ this.setModalHeight(thankYouView);
152
+ }));
153
+ }
154
+ // handle star rating
155
+ starsRating() {
156
+ let selectedClasses = ['selected'];
157
+ // Listen for form submissions
158
+ salla.document.event.onSubmit('.s-rating-stars-element', function (event) {
159
+ // Prevent form from submitting
160
+ event.preventDefault();
161
+ // Get the selected star - activeElement is not supported in safari
162
+ var activeStars = event.target.querySelectorAll('.s-rating-btn-star.hovered');
163
+ var selected = activeStars[activeStars.length - 1];
164
+ if (!selected)
165
+ return;
166
+ var selectedIndex = parseInt(selected.dataset.star, 10);
167
+ event.target.querySelector('.rating_hidden_input').value = selectedIndex;
168
+ // Get all stars in this form (only search in the form, not the whole document)
169
+ // Loop through each star, and add or remove the `.selected` class to toggle highlighting
170
+ event.target
171
+ .querySelectorAll('.s-rating-btn-star')
172
+ .forEach(function (star, index) {
173
+ if (index < selectedIndex) {
174
+ // Selected star or before it, Add highlighting
175
+ star.classList.add(...selectedClasses);
176
+ return;
177
+ }
178
+ // After selected star, Remove highlight
179
+ star.classList.remove(...selectedClasses);
180
+ });
181
+ // Remove aria-pressed from any previously selected star
182
+ var previousRating = event.target.querySelector('.s-rating-btn-star[aria-pressed="true"]');
183
+ if (previousRating) {
184
+ previousRating.removeAttribute('aria-pressed');
185
+ }
186
+ // Add aria-pressed role to the selected button
187
+ selected.setAttribute('aria-pressed', true);
188
+ });
189
+ }
190
+ highlightSelectedStars() {
191
+ let hover = ['hovered'];
192
+ Helper.Helper.all('.s-rating-stars-element', el => {
193
+ let starElements = el.querySelectorAll('.s-rating-btn-star');
194
+ // remove hovered state from stars ---
195
+ el.addEventListener('mouseout', () => starElements.forEach(star => star.classList.remove(...hover)));
196
+ starElements.forEach((starElement, index) => {
197
+ starElement.addEventListener('mouseover', () => {
198
+ starElement.classList.add(...hover);
199
+ if (index <= 1) {
200
+ starElement.previousElementSibling.tagName === 'BUTTON' ? starElement.previousElementSibling.classList.add(...hover) : null;
201
+ }
202
+ else {
203
+ for (let i = 0; i < index; i++) {
204
+ starElements[i].classList.add(...hover);
205
+ }
206
+ }
207
+ });
208
+ starElement.addEventListener('mouseout', () => {
209
+ starElement.classList.contains(...hover) ? starElement.classList.remove(...hover) : null;
210
+ });
211
+ });
212
+ });
213
+ }
214
+ // send feedback rating and validation
215
+ sendRating() {
216
+ Helper.Helper.all('.s-rating-step', ratingStep => {
217
+ let type = ratingStep.dataset.type;
218
+ let formsData = [];
219
+ ratingStep.querySelectorAll('.rating-outer-form')
220
+ .forEach((form) => {
221
+ let formData = {};
222
+ form.querySelectorAll('[name]')
223
+ .forEach(function (input) {
224
+ let inputData = salla.helpers.inputData(input.name, input.value, formData);
225
+ formData[inputData.name] = inputData.value;
226
+ });
227
+ formsData = [];
228
+ formsData.push(formData);
229
+ this.sendFeedback(type, formsData);
230
+ });
231
+ });
232
+ return this.ratingChain;
233
+ }
234
+ sendFeedback(type, formsData) {
235
+ if (!formsData || formsData.length == 0) {
236
+ return;
237
+ }
238
+ this.nextBtn.load();
239
+ salla.config.canLeave = false;
240
+ this.ratingChain = salla.feedback.api[type](formsData[0])
241
+ .then(function () {
242
+ salla.config.canLeave = true;
243
+ }).catch(() => salla.config.canLeave = true);
244
+ }
245
+ ratingValidation() {
246
+ let errorMsg = '';
247
+ document.querySelectorAll('.s-rating-step.s-rating-active')
248
+ .forEach((ratingSection) => {
249
+ ratingSection.querySelectorAll('.rating-outer-form')
250
+ .forEach((rating) => {
251
+ let ratingInput = rating.querySelector('.rating_hidden_input');
252
+ let commentInput = rating.querySelector('.s-rating-comment');
253
+ let validationMessage = rating.querySelector('.s-rating-validation-msg');
254
+ if (ratingInput.value && commentInput.value && commentInput.value.length > 3) {
255
+ commentInput.classList.remove('s-rating-has-error');
256
+ validationMessage.innerHTML = '';
257
+ return;
258
+ }
259
+ else if (commentInput.value && commentInput.value.length > 3) {
260
+ commentInput.classList.remove('s-rating-has-error');
261
+ }
262
+ else {
263
+ commentInput.classList.add('s-rating-has-error');
264
+ }
265
+ errorMsg = ratingInput.value
266
+ ? (salla.lang.get('common.errors.not_less_than_chars', { chars: 4 }) + ' ' + commentInput.getAttribute('placeholder'))
267
+ : (rating.dataset.starsError || salla.lang.get('pages.rating.rate_store_stars'));
268
+ validationMessage.innerHTML = errorMsg;
269
+ });
270
+ });
271
+ //Fire error to prevent going to next step
272
+ if (errorMsg) {
273
+ throw new Error(errorMsg);
274
+ }
275
+ }
276
+ // render
277
+ render() {
278
+ return (index.h(index.Host, null, index.h("salla-modal", { class: "hidden", "modal-width": "w-[800px]", ref: modal => this.modal = modal, title: salla.lang.get('pages.rating.rate_order') + ' <span class="unicode">(#' + this.orderId + ')</span>' }, index.h("div", { class: "s-rating-wrapper " }, this.isStoreRating && this.renderStoreRating(), this.isProductsRating && this.renderProductsRating(), this.isShippingRating && this.renderShippingRating(), this.renderThanksView()), index.h("div", { class: "s-rating-footer" }, index.h("button", { id: "prev-btn", class: "s-rating-btn s-rating-unvisiable" }, salla.lang.get('pages.order.rating_prev')), this.stepsCount > 1 ?
279
+ index.h("ul", { class: "s-rating-dots" }, [0, 1, 2].slice(0, this.stepsCount).map(index$1 => index.h("li", { class: `${index$1 == 0 ? 's-rating-bg-primary' : 's-rating-bg-gray'} s-rating-step-dot` }))) : '', index.h("salla-button", { id: "next-btn", ref: nextBtn => this.nextBtn = nextBtn }, "\u0627\u0644\u062A\u0627\u0644\u064A")))));
280
+ }
281
+ renderStoreRating() {
282
+ return (index.h("section", { class: "s-rating-step", "data-type": "store", "data-step-name": salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.store') }, index.h("div", { class: "rating-outer-form s-rating-step-wrap", "data-stars-error": salla.lang.get('pages.rating.rate_store_stars') }, index.h("input", { type: "hidden", name: "order_id", value: this.orderId }), index.h("input", { type: "hidden", name: "type", value: "store" }), index.h("div", { class: "s-rating-rounded-icon" }, index.h("img", { src: this.order.storeLogo, alt: "store name", class: "s-rating-store-logo" })), index.h("h2", { class: "s-rating-title" }, salla.lang.get('pages.rating.rate_the_store')), index.h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), index.h("textarea", { id: "storeReview", name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_store_rate') }), index.h("small", { class: "s-rating-validation-msg" }))));
283
+ }
284
+ renderShippingRating() {
285
+ return (index.h("section", { class: "s-rating-step", "data-type": "shipping", "data-step-name": salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.shipping') }, index.h("div", { class: "rating-outer-form s-rating-step-wrap", "data-stars-error": salla.lang.get('pages.rating.rate_shipping_stars') }, index.h("input", { type: "hidden", name: "order_id", value: this.orderId }), index.h("input", { type: "hidden", name: "shipping_company_id", value: this.order.shipping.id }), index.h("input", { type: "hidden", name: "type", value: "shipping" }), index.h("div", { class: "s-rating-rounded-icon" }, index.h("img", { src: this.order.shippingLogo, alt: "company name", class: "s-rating-shipping-logo" })), index.h("h2", { class: "s-rating-title" }, " ", salla.lang.get('pages.rating.rate_shipping'), " \u0627\u0631\u0627\u0645\u0643\u0633"), index.h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), index.h("textarea", { id: "shippingReview", name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_shipping_rate') }), index.h("small", { class: "s-rating-validation-msg" }))));
286
+ }
287
+ renderProductsRating() {
288
+ return (index.h("section", { class: "s-rating-step", "data-type": "product", "data-step-name": salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.products') }, this.order.products.map((item, index$1) => index.h("div", { class: "rating-outer-form s-rating-product", "data-stars-error": salla.lang.get('pages.order.rate_product_stars') }, index.h("img", { src: item.image, alt: item.title, class: "s-rating-product-img" }), index.h("div", { class: "s-rating-product-details" }, index.h("h3", { class: "s-rating-product-title" }, " ", item.title), index.h("div", { class: "s-rating-stars-product" }, " ", this.getStarsRating('small')), index.h("input", { type: "hidden", name: "order_id", value: this.orderId }), index.h("input", { type: "hidden", name: `products[${index$1}][product_id]`, value: item.getOptimusRouteKey }), index.h("input", { type: "hidden", name: "type", value: "products" }), index.h("textarea", { "data-product-id": item.id, name: `products[${index$1}][comment]`, id: `productReview_${item.id}`, class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_product_rate') }), index.h("small", { class: "s-rating-validation-msg" }))))));
289
+ }
290
+ renderThanksView() {
291
+ return (index.h("div", { class: "s-rating-thanks s-rating-hidden" }, index.h("span", { class: "s-rating-thanks-icon sicon-check-circle2" }), index.h("h3", { class: "s-rating-thanks-title" }, salla.lang.get('pages.rating.thanks')), index.h("div", { class: "s-rating-thanks-msg", innerHTML: this.thanksMsg }), index.h("a", { href: "#!", onClick: () => this.hide(), class: "s-rating-thanks-btn" }, "\u0639\u0648\u062F\u0629 \u0625\u0644\u064A \u062A\u0641\u0627\u0635\u064A\u0644 \u0627\u0644\u0637\u0644\u0628"), index.h("time", { class: "s-rating-thanks-time" })));
292
+ }
293
+ getStarsRating(size) {
294
+ return (index.h("form", { class: "s-rating-stars-element" }, index.h("input", { type: "hidden", class: "rating_hidden_input", name: "rating", value: "" }), [1, 2, 3, 4, 5].map((star) => index.h("button", { type: "submit", class: `s-rating-btn-star s-rating-btn-star-` + size, "data-star": star }, index.h("i", { class: "sicon-star2" })))));
295
+ }
296
+ get host() { return index.getElement(this); }
297
+ };
298
+ SallaRating.style = sallaRatingCss;
299
+
300
+ exports.salla_rating = SallaRating;