@salla.sa/twilight-components 1.0.20 → 1.0.21

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.
@@ -18,8 +18,8 @@ const SallaRating = class {
18
18
  * Set to true to display shipping rating step
19
19
  */
20
20
  this.isShippingRating = false;
21
- this.ratingChain = Promise.resolve();
22
21
  this.stepsCount = 0;
22
+ this.currentIndex = 0;
23
23
  Helper.setHost(this.host);
24
24
  salla.event.on('rating::show', () => this.show());
25
25
  }
@@ -37,69 +37,34 @@ const SallaRating = class {
37
37
  }
38
38
  initiateRating() {
39
39
  this.handleWizard();
40
- this.handleSubmitRating();
41
40
  this.starsRating();
42
41
  this.highlightSelectedStars();
43
42
  }
44
43
  // handle wizard
45
44
  handleWizard() {
46
- 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');
47
- this.setModalHeight(steps[0]);
48
- this.showActiveStep(steps, dots, index, nextBtnText);
49
- Helper.onClick("#prev-btn", () => {
50
- index > 0 && index--;
51
- this.showActiveStep(steps, dots, index, nextBtnText);
52
- index == 0 && Helper.toggle('#prev-btn', 's-rating-unvisiable', 'block', () => true);
53
- });
54
- Helper.onClick("#next-btn", () => {
55
- this.ratingValidation();
56
- if (index == this.stepsCount - 1) {
57
- salla.event.dispatch("submit::order-rating");
58
- }
59
- else {
60
- index < this.stepsCount - 1 && index++;
61
- this.showActiveStep(steps, dots, index, nextBtnText);
62
- Helper.toggle('#prev-btn', 'block', 's-rating-unvisiable', () => true);
63
- }
45
+ this.steps = this.host.querySelectorAll(".s-rating-step");
46
+ this.dots = this.host.querySelectorAll(".s-rating-step-dot");
47
+ this.showActiveStep();
48
+ Helper.onClick("#prev-btn", event => {
49
+ Helper.toggleElement(event.target, 's-rating-unvisiable', 'block', () => this.currentIndex == 0);
50
+ this.currentIndex > 0 && this.currentIndex--;
51
+ this.showActiveStep();
64
52
  });
65
53
  }
66
- showActiveStep(steps, dots, index, nextBtnText) {
54
+ showActiveStep(current = null) {
67
55
  var _a;
68
- // Active step
69
- Helper.toggle('.s-rating-step', 's-rating-hidden', 's-rating-active', () => true);
70
- Helper.toggleElement(steps[index], 's-rating-unactive', 's-rating-hidden', () => true);
71
- setTimeout(() => Helper.toggleElement(steps[index], 's-rating-active', 's-rating-unactive', () => true), 200);
72
- // Hanle dots
73
- Helper.toggle('.s-rating-step-dot', 's-rating-bg-gray', 's-rating-bg-primary', () => true);
74
- this.stepsCount > 1 && Helper.toggleElement(dots[index], 's-rating-bg-primary', 's-rating-bg-gray', () => true);
56
+ this.currentTab = current || this.steps[this.currentIndex];
57
+ Helper.toggle('.s-rating-step', 's-rating-active', 's-rating-hidden', tab => tab == this.currentTab)
58
+ .toggle('.s-rating-step-dot', 's-rating-bg-gray', 's-rating-bg-primary', dot => dot != this.dots[this.currentIndex]);
59
+ // the animation
60
+ Helper.toggleElement(this.currentTab, 's-rating-unactive', 's-rating-hidden', () => true);
61
+ setTimeout(() => Helper.toggleElement(this.currentTab, 's-rating-active', 's-rating-unactive', () => true), 300);
75
62
  // Btn text
76
- nextBtnText.innerHTML = ((_a = steps[index + 1]) === null || _a === void 0 ? void 0 : _a.dataset.stepName) || salla.lang.get('pages.rating.send_ratings');
77
- this.setModalHeight(steps[index]);
78
- }
79
- setModalHeight(current) {
80
- const wrapper = this.host.querySelector('.s-rating-wrapper');
81
- setTimeout(() => wrapper === null || wrapper === void 0 ? void 0 : wrapper.setAttribute('style', 'height:' + (current === null || current === void 0 ? void 0 : current.scrollHeight) + 'px'));
82
- }
83
- // Listen to submit::order-rating event used in handleWizard()
84
- handleSubmitRating() {
85
- salla.event.on('submit::order-rating', () => this.sendRating().then(() => {
86
- // Handle timer
87
- let thankYouView = this.host.querySelector('.s-rating-thanks'), seconds = 10;
88
- let timeToClose = setInterval(() => {
89
- seconds--;
90
- this.host.querySelector('.s-rating-thanks-time').innerHTML = `00:0${seconds}`;
91
- if (seconds == 0) {
92
- this.hide();
93
- clearInterval(timeToClose);
94
- }
95
- }, 1000);
96
- // Hide steps and show thanks msg
97
- Helper.toggle('.s-rating-step', 's-rating-hidden', 's-rating-active', () => true);
98
- this.host.querySelector('.s-rating-footer').classList.add('s-rating-unvisiable');
99
- Helper.toggleElement(thankYouView, 's-rating-unactive', 's-rating-hidden', () => true);
100
- setTimeout(() => Helper.toggleElement(thankYouView, 's-rating-active', 's-rating-unactive', () => true), 200);
101
- this.setModalHeight(thankYouView);
102
- }));
63
+ let nextType = (_a = this.steps[this.currentIndex + 1]) === null || _a === void 0 ? void 0 : _a.dataset.type;
64
+ this.nextBtn.querySelector('.s-button-text').innerHTML = nextType
65
+ ? salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.' + nextType)
66
+ : salla.lang.get('pages.rating.send_ratings');
67
+ setTimeout(() => { var _a; return this.body.setAttribute('style', 'height:' + ((_a = this.currentTab) === null || _a === void 0 ? void 0 : _a.scrollHeight) + 'px'); });
103
68
  }
104
69
  // handle star rating
105
70
  starsRating() {
@@ -109,11 +74,11 @@ const SallaRating = class {
109
74
  // Prevent form from submitting
110
75
  event.preventDefault();
111
76
  // Get the selected star - activeElement is not supported in safari
112
- var activeStars = event.target.querySelectorAll('.s-rating-btn-star.hovered');
113
- var selected = activeStars[activeStars.length - 1];
77
+ let activeStars = event.target.querySelectorAll('.s-rating-btn-star.hovered');
78
+ let selected = activeStars[activeStars.length - 1];
114
79
  if (!selected)
115
80
  return;
116
- var selectedIndex = parseInt(selected.dataset.star, 10);
81
+ let selectedIndex = parseInt(selected.dataset.star, 10);
117
82
  event.target.querySelector('.rating_hidden_input').value = selectedIndex;
118
83
  // Get all stars in this form (only search in the form, not the whole document)
119
84
  // Loop through each star, and add or remove the `.selected` class to toggle highlighting
@@ -155,85 +120,92 @@ const SallaRating = class {
155
120
  }
156
121
  }
157
122
  });
158
- starElement.addEventListener('mouseout', () => {
159
- starElement.classList.contains(...hover) ? starElement.classList.remove(...hover) : null;
160
- });
123
+ starElement.addEventListener('mouseout', () => starElement.classList.remove(...hover));
161
124
  });
162
125
  });
163
126
  }
164
- // send feedback rating and validation
165
- sendRating() {
166
- Helper.all('.s-rating-step', ratingStep => {
167
- let type = ratingStep.dataset.type;
168
- let formsData = [];
169
- ratingStep.querySelectorAll('.rating-outer-form')
170
- .forEach((form) => {
171
- let formData = {};
172
- form.querySelectorAll('[name]')
173
- .forEach(function (input) {
174
- let inputData = salla.helpers.inputData(input.name, input.value, formData);
175
- formData[inputData.name] = inputData.value;
176
- });
177
- formsData = [];
178
- formsData.push(formData);
179
- this.sendFeedback(type, formsData);
180
- });
127
+ sendFeedback(current = null, type = null) {
128
+ if (!current && this.currentTab.dataset.type === 'products') {
129
+ let forms = Array.from(this.currentTab.querySelectorAll('.rating-outer-form'));
130
+ let promise = this.sendFeedback(forms[0], 'product');
131
+ forms.slice(1).forEach(form => promise.then(() => this.sendFeedback(form, 'product')));
132
+ return promise;
133
+ }
134
+ type = type || this.currentTab.dataset.type;
135
+ current = current || this.currentTab;
136
+ let data = {};
137
+ current.querySelectorAll('[name]').forEach(input => {
138
+ //decode names like `<input name="jamal[inner]" value="hi">` to be name(jamal), value: {inner:"hi"}
139
+ let inputData = salla.helpers.inputData(input.name, input.value, data);
140
+ data[inputData.name] = inputData.value;
181
141
  });
182
- return this.ratingChain;
183
- }
184
- sendFeedback(type, formsData) {
185
- if (!formsData || formsData.length == 0) {
142
+ if (Object.keys(data).length == 0) {
143
+ return;
144
+ }
145
+ data['order_id'] = this.order.id;
146
+ data['type'] = this.currentTab.dataset.type;
147
+ return salla.feedback.api[type](data);
148
+ }
149
+ submit() {
150
+ this.validate();
151
+ if (this.currentIndex == this.stepsCount - 1) {
152
+ this.showThankYou();
186
153
  return;
187
154
  }
188
- this.nextBtn.load();
189
155
  salla.config.canLeave = false;
190
- this.ratingChain = salla.feedback.api[type](formsData[0])
191
- .then(function () {
192
- salla.config.canLeave = true;
193
- }).catch(() => salla.config.canLeave = true);
194
- }
195
- ratingValidation() {
196
- let errorMsg = '';
197
- document.querySelectorAll('.s-rating-step.s-rating-active')
198
- .forEach((ratingSection) => {
199
- ratingSection.querySelectorAll('.rating-outer-form')
200
- .forEach((rating) => {
201
- let ratingInput = rating.querySelector('.rating_hidden_input');
202
- let commentInput = rating.querySelector('.s-rating-comment');
203
- let validationMessage = rating.querySelector('.s-rating-validation-msg');
204
- if (ratingInput.value && commentInput.value && commentInput.value.length > 3) {
205
- commentInput.classList.remove('s-rating-has-error');
206
- validationMessage.innerHTML = '';
207
- return;
208
- }
209
- else if (commentInput.value && commentInput.value.length > 3) {
210
- commentInput.classList.remove('s-rating-has-error');
211
- }
212
- else {
213
- commentInput.classList.add('s-rating-has-error');
214
- }
215
- errorMsg = ratingInput.value
216
- ? (salla.lang.get('common.errors.not_less_than_chars', { chars: 4 }) + ' ' + commentInput.getAttribute('placeholder'))
217
- : (rating.dataset.starsError || salla.lang.get('pages.rating.rate_store_stars'));
218
- validationMessage.innerHTML = errorMsg;
219
- });
220
- });
221
- //Fire error to prevent going to next step
222
- if (errorMsg) {
223
- throw new Error(errorMsg);
156
+ this.nextBtn.load()
157
+ .then(() => this.sendFeedback())
158
+ .then(() => this.currentIndex < this.stepsCount - 1 && this.currentIndex++)
159
+ .then(() => this.showActiveStep())
160
+ .then(() => Helper.toggle('#prev-btn', 'block', 's-rating-unvisiable', () => true))
161
+ .finally(() => this.nextBtn.stop() && (salla.config.canLeave = true));
162
+ }
163
+ validate(rating = null, type = null) {
164
+ if (!rating && this.currentTab.dataset.type == 'products') {
165
+ return this.currentTab.querySelectorAll('.rating-outer-form').forEach(rating => this.validate(rating, 'product'));
166
+ }
167
+ rating = rating || this.currentTab;
168
+ let stars = rating.querySelector('.rating_hidden_input').value;
169
+ let comment = rating.querySelector('.s-rating-comment');
170
+ let validationMessage = rating.querySelector('.s-rating-validation-msg');
171
+ if (stars && comment.value && comment.value.length > 3) {
172
+ comment.classList.remove('s-rating-has-error');
173
+ validationMessage.innerHTML = '';
174
+ return;
224
175
  }
176
+ type = type || rating['dataset'].type;
177
+ Helper.toggleElement(comment, 'save', 's-rating-has-error', el => el.value.length > 3);
178
+ throw validationMessage.innerHTML = stars
179
+ ? (salla.lang.get('common.errors.not_less_than_chars', { chars: 4 }) + ' ' + comment.getAttribute('placeholder'))
180
+ : salla.lang.get(`pages.rating.rate_${type}_stars`).replace(' (:item)', '');
181
+ }
182
+ showThankYou() {
183
+ let seconds = 10;
184
+ let timeToClose = setInterval(() => {
185
+ this.thanksTime.innerHTML = '00:0' + (seconds--);
186
+ seconds < 0 && this.hide() && clearInterval(timeToClose);
187
+ }, 1000);
188
+ this.host.querySelector('.s-rating-footer').classList.add('s-rating-unvisiable');
189
+ this.showActiveStep(this.thanksTab);
225
190
  }
226
191
  renderStoreRating() {
227
- return (h("section", { class: "s-rating-step", "data-type": "store", "data-step-name": salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.store') }, h("div", { class: "rating-outer-form s-rating-step-wrap", "data-stars-error": salla.lang.get('pages.rating.rate_store_stars') }, h("input", { type: "hidden", name: "order_id", value: this.order.id }), h("input", { type: "hidden", name: "type", value: "store" }), h("div", { class: "s-rating-rounded-icon" }, h("img", { src: salla.get('store.logo'), alt: "store name", class: "s-rating-store-logo" })), h("h2", { class: "s-rating-title" }, salla.lang.get('pages.rating.rate_the_store')), h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), h("textarea", { id: "storeReview", name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_store_rate') }), h("small", { class: "s-rating-validation-msg" }))));
192
+ return this.order.testimonials_enabled ?
193
+ h("div", { class: "rating-outer-form s-rating-step-wrap s-rating-step", "data-type": "store" }, h("div", { class: "s-rating-rounded-icon" }, h("img", { src: salla.get('store.logo'), alt: "store name", class: "s-rating-store-logo" })), h("h2", { class: "s-rating-title" }, salla.lang.get('pages.rating.rate_the_store')), h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), h("textarea", { id: "storeReview", name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_store_rate') }), h("small", { class: "s-rating-validation-msg" }))
194
+ : '';
228
195
  }
229
196
  renderShippingRating() {
230
- return (h("section", { class: "s-rating-step", "data-type": "shipping", "data-step-name": salla.lang.get('pages.rating.rate') + ' ' + salla.lang.get('pages.rating.shipping') }, h("div", { class: "rating-outer-form s-rating-step-wrap", "data-stars-error": salla.lang.get('pages.rating.rate_shipping_stars') }, h("input", { type: "hidden", name: "order_id", value: this.order.id }), h("input", { type: "hidden", name: "shipping_company_id", value: this.order.shipping.company.id }), h("input", { type: "hidden", name: "type", value: "shipping" }), h("div", { class: "s-rating-rounded-icon" }, h("img", { src: this.order.shipping.company.logo, alt: "company name", class: "s-rating-shipping-logo" })), h("h2", { class: "s-rating-title" }, " ", salla.lang.get('pages.rating.rate_shipping') + ' ' + this.order.shipping.company.name), h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), h("textarea", { id: "shippingReview", name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_shipping_rate') }), h("small", { class: "s-rating-validation-msg" }))));
197
+ return this.order.shipping_enabled
198
+ ?
199
+ h("div", { class: "rating-outer-form s-rating-step-wrap s-rating-step", "data-type": "shipping" }, h("input", { type: "hidden", name: "shipping_company_id", value: this.order.shipping.company.id }), h("div", { class: "s-rating-rounded-icon" }, h("img", { src: this.order.shipping.company.logo, alt: "company name", class: "s-rating-shipping-logo" })), h("h2", { class: "s-rating-title" }, " ", salla.lang.get('pages.rating.rate_shipping') + ' ' + this.order.shipping.company.name), h("div", { class: "s-rating-stars-company" }, " ", this.getStarsRating('large')), h("textarea", { name: "comment", class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_shipping_rate') }), h("small", { class: "s-rating-validation-msg" }))
200
+ : '';
231
201
  }
232
202
  renderProductsRating() {
233
- return (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) => h("div", { class: "rating-outer-form s-rating-product", "data-stars-error": salla.lang.get('pages.rating.rate_product_stars') }, h("img", { src: item.product.thumbnail, alt: item.product.name, class: "s-rating-product-img" }), h("div", { class: "s-rating-product-details" }, h("h3", { class: "s-rating-product-title" }, " ", item.product.name), h("div", { class: "s-rating-stars-product" }, " ", this.getStarsRating('small')), h("input", { type: "hidden", name: "order_id", value: this.order.id }), h("input", { type: "hidden", name: `products[${index}][product_id]`, value: item.product.id }), h("input", { type: "hidden", name: "type", value: "products" }), h("textarea", { "data-product-id": item.product.id, name: `products[${index}][comment]`, id: `productReview_${item.product.id}`, class: "s-rating-comment", placeholder: salla.lang.get('pages.rating.write_product_rate') }), h("small", { class: "s-rating-validation-msg" }))))));
203
+ return this.order.products_enabled
204
+ ? h("section", { class: "s-rating-step", "data-type": "products" }, this.order.products.map((item, index) => h("div", { class: "rating-outer-form s-rating-product", "data-stars-error": salla.lang.get('pages.rating.rate_product_stars') }, h("img", { src: item.product.thumbnail, alt: item.product.name, class: "s-rating-product-img" }), h("div", { class: "s-rating-product-details" }, h("h3", { class: "s-rating-product-title" }, " ", item.product.name), h("div", { class: "s-rating-stars-product" }, " ", this.getStarsRating('small')), h("input", { type: "hidden", name: `products[${index}][id]`, value: item.product.id }), h("textarea", { placeholder: salla.lang.get('pages.rating.write_product_rate'), name: `products[${index}][comment]`, class: "s-rating-comment" }), h("small", { class: "s-rating-validation-msg" })))))
205
+ : '';
234
206
  }
235
207
  renderThanksView() {
236
- return (h("div", { class: "s-rating-thanks s-rating-hidden" }, h("span", { class: "s-rating-thanks-icon sicon-check-circle2" }), h("h3", { class: "s-rating-thanks-title" }, salla.lang.get('pages.rating.thanks')), h("div", { class: "s-rating-thanks-msg", innerHTML: this.thanksMsg }), 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"), h("time", { class: "s-rating-thanks-time" })));
208
+ return (h("div", { class: "s-rating-thanks s-rating-hidden", ref: el => this.thanksTab = el }, h("span", { class: "s-rating-thanks-icon sicon-check-circle2" }), h("h3", { class: "s-rating-thanks-title" }, salla.lang.get('pages.rating.thanks')), h("div", { class: "s-rating-thanks-msg", innerHTML: this.thanksMsg }), 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"), h("time", { class: "s-rating-thanks-time", ref: el => this.thanksTime = el })));
237
209
  }
238
210
  getStarsRating(size) {
239
211
  return (h("form", { class: "s-rating-stars-element" }, h("input", { type: "hidden", class: "rating_hidden_input", name: "rating", value: "" }), [1, 2, 3, 4, 5].map(star => h("button", { type: "submit", class: `s-rating-btn-star s-rating-btn-star-` + size, "data-star": star }, h("i", { class: "sicon-star2" })))));
@@ -241,9 +213,8 @@ const SallaRating = class {
241
213
  // render
242
214
  render() {
243
215
  return (h(Host, null, h("salla-modal", { isLoading: true, width: "md", ref: modal => this.modal = modal }, this.order
244
- ? [h("div", { class: "s-rating-wrapper " }, this.order.testimonials_enabled && this.renderStoreRating(), this.order.products_enabled && this.renderProductsRating(), this.order.shipping_enabled && this.renderShippingRating(), this.renderThanksView()),
245
- h("div", { class: "s-rating-footer" }, h("button", { id: "prev-btn", class: "s-rating-btn s-rating-unvisiable" }, salla.lang.get('common.elements.back')), this.stepsCount > 1 ?
246
- h("ul", { class: "s-rating-dots" }, [0, 1, 2].slice(0, this.stepsCount).map(index => h("li", { class: `${index == 0 ? 's-rating-bg-primary' : 's-rating-bg-gray'} s-rating-step-dot` }))) : '', h("salla-button", { id: "next-btn", ref: nextBtn => this.nextBtn = nextBtn }, "\u0627\u0644\u062A\u0627\u0644\u064A")),]
216
+ ? [h("div", { class: "s-rating-wrapper", ref: el => this.body = el }, this.renderStoreRating(), this.renderProductsRating(), this.renderShippingRating(), this.renderThanksView()),
217
+ h("div", { class: "s-rating-footer" }, h("button", { id: "prev-btn", class: "s-rating-btn s-rating-unvisiable" }, salla.lang.get('common.elements.back')), this.stepsCount > 1 ? h("ul", { class: "s-rating-dots" }, [0, 1, 2].slice(0, this.stepsCount).map(() => h("li", { class: 's-rating-bg-gray s-rating-step-dot' }))) : '', h("salla-button", { ref: el => this.nextBtn = el, onClick: () => this.submit() }, salla.lang.get('common.elements.next'))),]
247
218
  : '')));
248
219
  }
249
220
  componentDidRender() {
@@ -19,23 +19,28 @@ export declare class SallaRating {
19
19
  * Set to true to display shipping rating step
20
20
  */
21
21
  isShippingRating: boolean;
22
- private ratingChain;
23
22
  private stepsCount;
24
23
  private nextBtn;
25
24
  private modal;
25
+ private currentIndex;
26
+ private currentTab;
27
+ private thanksTab;
28
+ private body;
29
+ private thanksTime;
30
+ private steps;
31
+ private dots;
26
32
  host: HTMLElement;
27
33
  show(): Promise<NodeJS.Timeout>;
28
34
  hide(): Promise<HTMLElement>;
29
35
  protected initiateRating(): void;
30
36
  private handleWizard;
31
37
  private showActiveStep;
32
- private setModalHeight;
33
- private handleSubmitRating;
34
38
  private starsRating;
35
39
  private highlightSelectedStars;
36
- private sendRating;
37
40
  private sendFeedback;
38
- private ratingValidation;
41
+ private submit;
42
+ private validate;
43
+ private showThankYou;
39
44
  private renderStoreRating;
40
45
  private renderShippingRating;
41
46
  private renderProductsRating;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salla.sa/twilight-components",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "license": "MIT",
5
5
  "keywords": [
6
6
  "twilight",