@teddy-dev/frontend 1.0.1
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.
- package/algolia/algolia-loader.js +56 -0
- package/algolia/algolia-search.js +222 -0
- package/auth/teddy-auth-login.js +29 -0
- package/auth/teddy-auth-profile.js +58 -0
- package/auth/teddy-auth-register.js +52 -0
- package/auth/teddy-auth-reset.js +39 -0
- package/auth/teddy-auth.js +92 -0
- package/bantoa/bantoa-product.js +64 -0
- package/bantoa/bantoa-search.js +46 -0
- package/bantoa/bantoa-stylemix.js +43 -0
- package/bantoa/bantoa.js +21 -0
- package/cart/teddy-cart-controller.js +163 -0
- package/cart/teddy-cart-customer.js +86 -0
- package/cart/teddy-cart-discounts.js +55 -0
- package/cart/teddy-cart-promo-apply.js +24 -0
- package/cart/teddy-cart-promo-error.js +38 -0
- package/cart/teddy-cart-promo-loading.js +20 -0
- package/cart/teddy-cart-promo.js +96 -0
- package/components/mc-btn.js +38 -0
- package/components/mc-card-render.js +33 -0
- package/components/mc-cart-counter.js +14 -0
- package/components/mc-cart-error.js +35 -0
- package/components/mc-cart-quantity.js +43 -0
- package/components/mc-cart-remove.js +32 -0
- package/components/mc-copy.js +33 -0
- package/components/mc-element.js +84 -0
- package/components/mc-form-errors.js +35 -0
- package/components/mc-form-success.js +31 -0
- package/components/mc-form.js +223 -0
- package/components/mc-input-area.js +13 -0
- package/components/mc-input-checkbox-group.js +52 -0
- package/components/mc-input-checkbox.js +12 -0
- package/components/mc-input-password.js +39 -0
- package/components/mc-input-places.js +43 -0
- package/components/mc-input-quantity.js +43 -0
- package/components/mc-input-select.js +14 -0
- package/components/mc-input-text.js +12 -0
- package/components/mc-input.js +137 -0
- package/components/mc-loader.js +21 -0
- package/components/mc-modal.js +69 -0
- package/components/mc-password-eye.js +24 -0
- package/components/mc-password-tips.js +60 -0
- package/components/mc-qrcode.js +41 -0
- package/components/mc-range.js +108 -0
- package/components/mc-read-more.js +56 -0
- package/components/mc-recommended.js +50 -0
- package/components/mc-referrer.js +20 -0
- package/components/mc-splash-controller.js +32 -0
- package/components/mc-splash-link.js +65 -0
- package/components/mc-stoq.js +30 -0
- package/components/mc-swiper.js +333 -0
- package/components/mc-video.js +61 -0
- package/css/bootstrap-lg.css +2762 -0
- package/css/bootstrap-lg.min.css +1 -0
- package/css/bootstrap-md.css +2762 -0
- package/css/bootstrap-md.min.css +1 -0
- package/css/bootstrap-sm.css +2762 -0
- package/css/bootstrap-sm.min.css +1 -0
- package/css/bootstrap-xl.css +2790 -0
- package/css/bootstrap-xl.min.css +1 -0
- package/css/bootstrap-xxl.css +2762 -0
- package/css/bootstrap-xxl.min.css +1 -0
- package/css/bootstrap.css +9824 -0
- package/css/bootstrap.min.css +5 -0
- package/css/mc-form-errors.css +3 -0
- package/css/mc-loader.css +6 -0
- package/css/mc-password-eye.css +6 -0
- package/css/mc-password-tips.css +6 -0
- package/css/mc-read-more.css +14 -0
- package/css/mc-video.css +4 -0
- package/css/mc-wishlist-hero-btn.css +7 -0
- package/loader.js +110 -0
- package/loyalty/teddy-loyalty-create.js +40 -0
- package/loyalty/teddy-loyalty-redeem.js +38 -0
- package/loyalty/teddy-loyalty.js +214 -0
- package/package.json +20 -0
- package/res/mc-events.js +43 -0
- package/res/mc-shopify.js +439 -0
- package/res/mc-utils.js +119 -0
- package/res/mc-vue.js +9350 -0
- package/returns/teddy-return-iban.js +115 -0
- package/returns/teddy-return-list.js +165 -0
- package/returns/teddy-return-request.js +353 -0
- package/scripts/publish-store.js +62 -0
- package/test/auth-login-error.json +4 -0
- package/test/auth-login-success.json +13 -0
- package/test/auth-password-change-error.json +4 -0
- package/test/auth-password-change-success.json +3 -0
- package/test/auth-register-error.json +4 -0
- package/test/auth-register-success.json +12 -0
- package/test/auth-reset-error.json +4 -0
- package/test/auth-reset-success.json +3 -0
- package/test/loyalty-error.json +4 -0
- package/test/loyalty-noinfo.json +18 -0
- package/test/loyalty-redeem-error.json +4 -0
- package/test/loyalty-redeem-success.json +11 -0
- package/test/loyalty-success.json +143 -0
- package/test/returns-create-success.json +1 -0
- package/test/returns-get-success.json +35 -0
- package/test/returns-get-tracking.json +30 -0
- package/test/returns-list-empty.json +4 -0
- package/test/returns-list-success.json +59 -0
- package/test/returns-search-manual.json +67 -0
- package/test/returns-search-success.json +76 -0
- package/test/wishlist-error.json +4 -0
- package/test/wishlist-success.json +3 -0
- package/wishlist/teddy-wishlist-btn.js +55 -0
- package/wishlist/teddy-wishlist-clear.js +18 -0
- package/wishlist/teddy-wishlist-counter.js +35 -0
- package/wishlist/teddy-wishlist-item.js +46 -0
- package/wishlist/teddy-wishlist-page.js +59 -0
- package/wishlist/teddy-wishlist.js +131 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const {createApp} = await import('../res/mc-vue.js');
|
|
2
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
3
|
+
await loadComponent('./auth/teddy-auth.js', false);
|
|
4
|
+
|
|
5
|
+
class TeddyReturnIban extends HTMLElement {
|
|
6
|
+
|
|
7
|
+
connectedCallback() {
|
|
8
|
+
if(!this.dataset.brand || !this.dataset.market) {
|
|
9
|
+
console.error('TeddyReturnIban: missing brand or market data attributes');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
this.create();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
create = () => {
|
|
16
|
+
const cmp = this;
|
|
17
|
+
|
|
18
|
+
const app = createApp({
|
|
19
|
+
delimiters: ['${', '}'], // setta i delimitatori di vue, altrimenti se usiamo gli standard va in conflitto con liquid
|
|
20
|
+
data: () => {
|
|
21
|
+
return {
|
|
22
|
+
loading: true,
|
|
23
|
+
confirm: false,
|
|
24
|
+
code: null,
|
|
25
|
+
owner: null,
|
|
26
|
+
iban: null,
|
|
27
|
+
success: null
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
methods: {
|
|
31
|
+
|
|
32
|
+
sendData: function() {
|
|
33
|
+
this.loading = true;
|
|
34
|
+
const body = {
|
|
35
|
+
returnCode: this.code,
|
|
36
|
+
returnHoldername: this.owner,
|
|
37
|
+
returnIBAN: this.iban,
|
|
38
|
+
brand: cmp.dataset.brand,
|
|
39
|
+
market: cmp.dataset.market,
|
|
40
|
+
callingSystem: 6,
|
|
41
|
+
sessionId: TeddyAuth.getSessionId(),
|
|
42
|
+
};
|
|
43
|
+
const data = {
|
|
44
|
+
method: theme.apis.returns.dev ? 'GET' : 'post',
|
|
45
|
+
url: theme.apis.returns.iban
|
|
46
|
+
};
|
|
47
|
+
if(!theme.apis.returns.dev) {
|
|
48
|
+
data.data = body;
|
|
49
|
+
data.headers = {
|
|
50
|
+
"Ocp-Apim-Subscription-Key":"0936a98c9baa4aa1a2787657e151b44a"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
console.log('Iban with data: ', data);
|
|
54
|
+
axios(data).then(response => {
|
|
55
|
+
this.setSuccess(response.data);
|
|
56
|
+
}).catch(error => {
|
|
57
|
+
this.setError(error);
|
|
58
|
+
}).finally(() => {
|
|
59
|
+
this.loading = false;
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
setSuccess: function(resp) {
|
|
64
|
+
if(!resp.success || !resp.return_id) {
|
|
65
|
+
this.setError(resp);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.success = true;
|
|
69
|
+
this.error = null;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
setError: function(e) {
|
|
73
|
+
this.success = false;
|
|
74
|
+
this.error = true;
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
next: function() {
|
|
78
|
+
this.confirm = true;
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
prev: function() {
|
|
82
|
+
this.confirm = false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
},
|
|
86
|
+
computed: {
|
|
87
|
+
isValid() {
|
|
88
|
+
return this.code != null && this.code.length == 20 && this.owner != null && this.owner.length > 0 && this.iban != null && this.iban.length == 27;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
mounted: function() {
|
|
92
|
+
this.loading = false;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
app.config.globalProperties.$filters = {
|
|
96
|
+
money(value) {
|
|
97
|
+
return McUtils.money(value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
app.config.compilerOptions.isCustomElement = tag => tag.includes('-'); // per evitare che vue vada in conflitto con liquid
|
|
101
|
+
app.mount(this);
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
getOrderId() {
|
|
106
|
+
// se l'utente arriva da un link diretto
|
|
107
|
+
const params = new URLSearchParams(window.location.search);
|
|
108
|
+
return params.get('order')?.replace('#', '') || null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
if (!window.customElements.get('teddy-return-iban')) {
|
|
113
|
+
window.customElements.define('teddy-return-iban', TeddyReturnIban);
|
|
114
|
+
}
|
|
115
|
+
window.TeddyReturnIban = TeddyReturnIban;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const {createApp} = await import('../res/mc-vue.js');
|
|
2
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
3
|
+
|
|
4
|
+
class TeddyReturnList extends HTMLElement {
|
|
5
|
+
|
|
6
|
+
connectedCallback() {
|
|
7
|
+
const cmp = this;
|
|
8
|
+
|
|
9
|
+
const app = createApp({
|
|
10
|
+
delimiters: ['${', '}'], // setta i delimitatori di vue, altrimenti se usiamo gli standard va in conflitto con liquid
|
|
11
|
+
data: () => {
|
|
12
|
+
return {
|
|
13
|
+
returns: [],
|
|
14
|
+
selected: null,
|
|
15
|
+
loaded: false,
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
methods: {
|
|
19
|
+
checkReturns: function () {
|
|
20
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
21
|
+
const returnId = urlParams.get('return');
|
|
22
|
+
if(returnId)
|
|
23
|
+
this.getReturn(returnId);
|
|
24
|
+
else
|
|
25
|
+
this.getReturns();
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
getReturns: function () {
|
|
29
|
+
this.loaded = false;
|
|
30
|
+
const data = {
|
|
31
|
+
method: 'GET',
|
|
32
|
+
url: theme.apis.returns.list,
|
|
33
|
+
};
|
|
34
|
+
axios(data).then(response => {
|
|
35
|
+
const rd = response.data || {};
|
|
36
|
+
rd.success ? this.returnsFound(rd) : this.returnsNotFound(rd);
|
|
37
|
+
}).catch(error => {
|
|
38
|
+
this.returnsNotFound(error);
|
|
39
|
+
}).finally(() => {
|
|
40
|
+
this.loaded = true;
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
returnsFound: function (response) {
|
|
45
|
+
console.log('Returns found:', response);
|
|
46
|
+
this.returns = response.returns || [];
|
|
47
|
+
this.returns.forEach(element => {
|
|
48
|
+
this.completeReturnItem(element);
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
returnsNotFound: function (error) {
|
|
53
|
+
this.returns = [];
|
|
54
|
+
console.error('Error fetching returns:', error);
|
|
55
|
+
Utils.showError('Non sono stati trovati resi per questo ordine.');
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
completeReturnItem: function (returnItem) {
|
|
59
|
+
const data = {
|
|
60
|
+
method: theme.apis.returns.dev ? 'GET' : 'POST',
|
|
61
|
+
url: `${theme.apis.returns.get.replace('{return_id}', returnItem.return_id)}`,
|
|
62
|
+
};
|
|
63
|
+
axios(data).then(response => {
|
|
64
|
+
const rd = response.data || {};
|
|
65
|
+
this.returns = this.returns.map(r => {
|
|
66
|
+
return r.return_id == returnItem.return_id ? { ...r, ...rd.return } : r;
|
|
67
|
+
});
|
|
68
|
+
console.log('Return item found:', this.returns);
|
|
69
|
+
}).catch(error => {
|
|
70
|
+
console.error('Error fetching return item:', error);
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
getReturn: function (returnId) {
|
|
75
|
+
if(!returnId) { console.error('Return ID is required'); return; }
|
|
76
|
+
this.returns = [];
|
|
77
|
+
this.selected = null;
|
|
78
|
+
this.loaded = false;
|
|
79
|
+
const data = {
|
|
80
|
+
method: theme.apis.returns.dev ? 'GET' : 'POST',
|
|
81
|
+
url: `${theme.apis.returns.get.replace('{return_id}', returnId)}`,
|
|
82
|
+
};
|
|
83
|
+
axios(data).then(response => {
|
|
84
|
+
const rd = response.data || {};
|
|
85
|
+
rd.success ? this.returnFound(rd) : this.returnNotFound(rd);
|
|
86
|
+
}).catch(error => {
|
|
87
|
+
this.returnNotFound(error);
|
|
88
|
+
}).finally(() => {
|
|
89
|
+
this.loaded = true;
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
returnFound: function (response) {
|
|
94
|
+
this.selected = response.return || null;
|
|
95
|
+
console.log('Return found:', this.selected);
|
|
96
|
+
if (!this.selected) {
|
|
97
|
+
console.error('Return not found');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
returnNotFound: function (error) {
|
|
103
|
+
this.selected = null;
|
|
104
|
+
console.error('Error fetching return:', error);
|
|
105
|
+
Utils.showError('Errore durante il recupero del reso.');
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
back: function () {
|
|
109
|
+
this.selected = null;
|
|
110
|
+
const url = new URL(window.location.href);
|
|
111
|
+
url.searchParams.delete('return');
|
|
112
|
+
window.history.pushState({}, '', url.toString());
|
|
113
|
+
this.getReturns();
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
watch: {
|
|
117
|
+
selected: function (newSelected, oldSelected) {
|
|
118
|
+
const url = new URL(window.location.href);
|
|
119
|
+
if (newSelected) {
|
|
120
|
+
url.searchParams.set('return', newSelected.return_id);
|
|
121
|
+
} else {
|
|
122
|
+
url.searchParams.delete('return');
|
|
123
|
+
}
|
|
124
|
+
window.history.pushState({}, '', url.toString());
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
computed: {
|
|
128
|
+
progress() {
|
|
129
|
+
if(!this.selected) return 0;
|
|
130
|
+
|
|
131
|
+
if (this.selected.return_status === 'OPEN') return 52;
|
|
132
|
+
if (this.selected.return_status === 'CLOSED') return 100;
|
|
133
|
+
else return 3;
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
mounted() {
|
|
137
|
+
this.checkReturns();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
app.config.globalProperties.$filters = {
|
|
141
|
+
money(value) {
|
|
142
|
+
return McUtils.money(value);
|
|
143
|
+
},
|
|
144
|
+
date(value) {
|
|
145
|
+
return new Date(value).toLocaleDateString('it-IT', {
|
|
146
|
+
year: 'numeric',
|
|
147
|
+
month: '2-digit',
|
|
148
|
+
day: '2-digit'
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
app.config.compilerOptions.isCustomElement = tag => tag.includes('-'); // per evitare che vue vada in conflitto con liquid
|
|
153
|
+
app.mount(this);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
getOrderId() {
|
|
157
|
+
// se l'utente arriva da un link diretto
|
|
158
|
+
const params = new URLSearchParams(window.location.search);
|
|
159
|
+
return params.get('order');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (!window.customElements.get('teddy-return-list')) {
|
|
163
|
+
window.customElements.define('teddy-return-list', TeddyReturnList);
|
|
164
|
+
}
|
|
165
|
+
window.TeddyReturnList = TeddyReturnList
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
const {createApp} = await import('../res/mc-vue.js');
|
|
2
|
+
await loadComponent('./res/mc-utils.js', false);
|
|
3
|
+
|
|
4
|
+
class TeddyReturnRequest extends HTMLElement {
|
|
5
|
+
|
|
6
|
+
connectedCallback() {
|
|
7
|
+
const cmp = this;
|
|
8
|
+
|
|
9
|
+
const app = createApp({
|
|
10
|
+
delimiters: ['${', '}'], // setta i delimitatori di vue, altrimenti se usiamo gli standard va in conflitto con liquid
|
|
11
|
+
data: () => {
|
|
12
|
+
return {
|
|
13
|
+
loading: true, // se mostrare il caricamento o meno
|
|
14
|
+
returnWhere: null, // reso online o in negozio ('online' o 'store')
|
|
15
|
+
order: null, // l'ordine ottenuto dalla chiamata
|
|
16
|
+
orderId: null, // l'id dell'ordine che il cliente cerca o seleziona dalla tendina
|
|
17
|
+
email: cmp.dataset.email?.length > 0 ? cmp.dataset.email : null, // la mail per cercare l'ordine
|
|
18
|
+
zip: null, // il cap per cercare l'ordine
|
|
19
|
+
returnAddress: null, // l'indirizzo di reso
|
|
20
|
+
btOwner: null, // il nome del proprietario per il bonifico
|
|
21
|
+
btIban: null, // l'iban per il bonifico
|
|
22
|
+
returnId: null, // l'id del reso
|
|
23
|
+
findBy: 'email', // il metodo di ricerca dell'ordine (email o zip)
|
|
24
|
+
step: cmp.dataset.where != undefined ? 'where': 'find', // il passo corrente (where, store, find, items, address, summary, success, error)
|
|
25
|
+
error: null, // l'errore da mostrare
|
|
26
|
+
addressType: 'order', // tab dell'indirizzo selezionato (order, new, pudo)
|
|
27
|
+
steps: [
|
|
28
|
+
'where', 'store', 'find', 'items', 'address', 'summary', 'success', 'error'
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
methods: {
|
|
33
|
+
checkOrderUrl: function() {
|
|
34
|
+
const params = new URLSearchParams(window.location.search);
|
|
35
|
+
if(!params.has('order')) {
|
|
36
|
+
this.loading = false;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.orderId = params.get('order');
|
|
40
|
+
this.searchOrder();
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
setWhere: function(where) {
|
|
44
|
+
if(where != null && where != 'online' && where != 'store') {
|
|
45
|
+
console.error('Invalid returnWhere value: ' + where);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.returnWhere = where;
|
|
49
|
+
this.step = this.returnWhere ? this.returnWhere == 'online' ? 'find' : 'store' : 'where';
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
searchOrder: function() {
|
|
53
|
+
this.loading = true;
|
|
54
|
+
const data = {
|
|
55
|
+
method: theme.apis.returns.dev ? 'GET' : 'POST',
|
|
56
|
+
url: theme.apis.returns.search,
|
|
57
|
+
};
|
|
58
|
+
if(!theme.apis.returns.dev) {
|
|
59
|
+
data.data = {
|
|
60
|
+
order_name: this.orderId,
|
|
61
|
+
email: this.email,
|
|
62
|
+
zip: this.zip
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
console.log('Searching order with data: ', data);
|
|
66
|
+
axios(data).then(response => {
|
|
67
|
+
this.orderFound(response.data);
|
|
68
|
+
}).catch(error => {
|
|
69
|
+
this.orderNotFound(error);
|
|
70
|
+
}).finally(() => {
|
|
71
|
+
this.loading = false;
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
createReturn: function() {
|
|
76
|
+
this.loading = true;
|
|
77
|
+
const body = {
|
|
78
|
+
order_id: this.order.order_id, // id dell'ordine
|
|
79
|
+
/*address: this.returnAddress,
|
|
80
|
+
payment_method: {
|
|
81
|
+
same: !this.order.manual,
|
|
82
|
+
iban: this.btIban || null, // iban del conto corrente, se il metodo era uno manuale
|
|
83
|
+
owner: this.btOwner || null, // intestatario del conto corrente, se il metodo era uno manuale
|
|
84
|
+
},*/
|
|
85
|
+
lines: this.order.lines.filter(l => l.selected).map(l => {
|
|
86
|
+
return {
|
|
87
|
+
id: l.id, // id della linea che mi avevi passato in precedenza
|
|
88
|
+
quantity: l.quantity, // quantità della linea che mi avevi passato in precedenza
|
|
89
|
+
reason_id: l.reason,
|
|
90
|
+
reason_note: l.description || (l.reason == 'OTHER' ? 'Non è stato consegnato nei tempi previsti' : null), // motivo del reso, se presente
|
|
91
|
+
};
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
const data = {
|
|
95
|
+
method: theme.apis.returns.dev ? 'GET' : 'post',
|
|
96
|
+
url: theme.apis.returns.create
|
|
97
|
+
};
|
|
98
|
+
if(!theme.apis.returns.dev) {
|
|
99
|
+
data.data = body;
|
|
100
|
+
}
|
|
101
|
+
console.log('Creating return with data: ', data);
|
|
102
|
+
axios(data).then(response => {
|
|
103
|
+
this.returnSuccess(response.data);
|
|
104
|
+
}).catch(error => {
|
|
105
|
+
this.returnError(error);
|
|
106
|
+
}).finally(() => {
|
|
107
|
+
this.loading = false;
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
returnSuccess: function(resp) {
|
|
112
|
+
if(!resp.success || !resp.return_id) {
|
|
113
|
+
this.returnError(resp);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.returnId = resp.return_id;
|
|
118
|
+
this.step = 'success';
|
|
119
|
+
this.error = null;
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
returnError: function(e) {
|
|
123
|
+
McUtils.log(e);
|
|
124
|
+
this.step = 'error';
|
|
125
|
+
this.returnId = null;
|
|
126
|
+
this.error = e.error || e.message || 'Error creating return';
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
orderFound: function(resp) {
|
|
130
|
+
console.log('Order found: ', resp);
|
|
131
|
+
if(!resp.success || !resp.order) {
|
|
132
|
+
this.orderNotFound(resp);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.order = resp.order;
|
|
137
|
+
this.order.lines = this.order.lines.map(i => {
|
|
138
|
+
i.max = i.quantity; // setto il max della linea al valore della quantità
|
|
139
|
+
return i;
|
|
140
|
+
});
|
|
141
|
+
this.setAddressType(this.order.address ? 'order' : 'new'); // se l'ordine ha un indirizzo, lo uso come predefinito
|
|
142
|
+
this.error = null;
|
|
143
|
+
this.step = 'items';
|
|
144
|
+
McUtils.log(this.order);
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
orderNotFound: function(e) {
|
|
148
|
+
this.order = null;
|
|
149
|
+
this.step = 'find';
|
|
150
|
+
this.error = e.error || e.message || 'Order not found';
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
toFind: function() {
|
|
154
|
+
this.step = 'find';
|
|
155
|
+
this.order = null;
|
|
156
|
+
this.orderId = null;
|
|
157
|
+
this.email = null;
|
|
158
|
+
this.zip = null;
|
|
159
|
+
this.error = null;
|
|
160
|
+
this.returnAddress = null;
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
toItems: function() {
|
|
164
|
+
this.step = 'items';
|
|
165
|
+
this.returnAddress = null;
|
|
166
|
+
this.addressType = 'order';
|
|
167
|
+
this.error = null;
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
toAddress: function() {
|
|
171
|
+
this.step = 'address';
|
|
172
|
+
this.returnAddress = this.order.address || {};
|
|
173
|
+
this.error = null;
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
toSummary: function() {
|
|
177
|
+
this.step = 'summary';
|
|
178
|
+
this.error = null;
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
setAddressType: function(type) {
|
|
182
|
+
if(type != null && type != 'order' && type != 'new' && type != 'pudo') {
|
|
183
|
+
console.error('Invalid addressType value: ' + type);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
this.addressType = type;
|
|
187
|
+
this.returnAddress = type == 'order' ? this.order.address : {};
|
|
188
|
+
console.log('Address type set to: ', this.returnAddress);
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
restart: function() {
|
|
192
|
+
this.step = 'where';
|
|
193
|
+
this.returnId = null;
|
|
194
|
+
this.order = null;
|
|
195
|
+
this.orderId = null;
|
|
196
|
+
this.email = null;
|
|
197
|
+
this.zip = null;
|
|
198
|
+
this.error = null;
|
|
199
|
+
this.returnAddress = null;
|
|
200
|
+
this.btOwner = null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
},
|
|
204
|
+
computed: {
|
|
205
|
+
loadingStatus: {
|
|
206
|
+
get() {
|
|
207
|
+
if(!this.loading)
|
|
208
|
+
return;
|
|
209
|
+
if(this.order != null) {
|
|
210
|
+
return 'create';
|
|
211
|
+
}
|
|
212
|
+
if(this.orderId != null) {
|
|
213
|
+
return 'search';
|
|
214
|
+
}
|
|
215
|
+
return 'initial';
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
isFindValid: {
|
|
220
|
+
get() {
|
|
221
|
+
if(this.step != 'find')
|
|
222
|
+
return true;
|
|
223
|
+
|
|
224
|
+
if(cmp.dataset.customer)
|
|
225
|
+
return this.orderId != null && this.orderId.length > 0;
|
|
226
|
+
|
|
227
|
+
return (this.email != null && this.email.length > 0 || this.zip != null && this.zip.length > 0) && this.orderId != null && this.orderId.length > 0;
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
isItemsValid: {
|
|
232
|
+
get() {
|
|
233
|
+
if(this.step != 'items')
|
|
234
|
+
return true;
|
|
235
|
+
|
|
236
|
+
if(this.order == null || this.order.lines == null)
|
|
237
|
+
return false;
|
|
238
|
+
|
|
239
|
+
const selectedItems = this.order.lines.filter(i => i.selected);
|
|
240
|
+
console.log('Selected items: ', selectedItems);
|
|
241
|
+
if (selectedItems.length === 0) return false;
|
|
242
|
+
if (selectedItems.some(i => !i.reason || i.reason.length === 0)) return false;
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
isAddressValid: {
|
|
248
|
+
get() {
|
|
249
|
+
if(this.step != 'address' || this.addressType != 'new')
|
|
250
|
+
return true;
|
|
251
|
+
|
|
252
|
+
if(this.returnAddress == null)
|
|
253
|
+
return false;
|
|
254
|
+
|
|
255
|
+
const a = this.returnAddress;
|
|
256
|
+
|
|
257
|
+
return (a.first_name != null && a.first_name.length > 0 || a.last_name != null && a.last_name.length > 0) && (a.address1 != null && a.address1.length > 0) && (a.city != null && a.city.length > 0) && (a.zip != null && a.zip.length > 0) && (a.country != null && a.country.length > 0);
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
isSummaryValid: {
|
|
262
|
+
get() {
|
|
263
|
+
if(this.step != 'summary')
|
|
264
|
+
return true;
|
|
265
|
+
|
|
266
|
+
return this.order.manual ? this.btOwner?.length > 0 && this.btIban?.length > 0 : true;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
isWhereValid: {
|
|
271
|
+
get() {
|
|
272
|
+
if(this.step != 'where')
|
|
273
|
+
return true;
|
|
274
|
+
|
|
275
|
+
return this.returnWhere == 'online' || this.returnWhere == 'store';
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
returnItems: {
|
|
280
|
+
get() {
|
|
281
|
+
if(this.order == null || this.order.lines == null)
|
|
282
|
+
return [];
|
|
283
|
+
|
|
284
|
+
return this.order.lines.filter(i => i.selected);
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
returnTotal: {
|
|
289
|
+
get() {
|
|
290
|
+
if(this.order == null || this.order.lines == null)
|
|
291
|
+
return 0;
|
|
292
|
+
|
|
293
|
+
// Usa final_price (prezzo scontato) se disponibile, altrimenti price (prezzo originale)
|
|
294
|
+
return this.order.lines.filter(i => i.selected).reduce((acc, i) => {
|
|
295
|
+
const itemPrice = i.final_price !== undefined ? i.final_price : i.price;
|
|
296
|
+
return acc + itemPrice/i.max*i.quantity;
|
|
297
|
+
}, 0);
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
address: {
|
|
302
|
+
get() {
|
|
303
|
+
if(this.returnAddress == null)
|
|
304
|
+
return '';
|
|
305
|
+
|
|
306
|
+
const first_name = this.returnAddress.first_name || '';
|
|
307
|
+
const last_name = this.returnAddress.last_name || '';
|
|
308
|
+
const company = this.returnAddress.company || '';
|
|
309
|
+
const address1 = this.returnAddress.address1 || '';
|
|
310
|
+
const a = this.returnAddress;
|
|
311
|
+
|
|
312
|
+
const address2 = a.address2 || '';
|
|
313
|
+
const city = a.city || '';
|
|
314
|
+
const province = a.province ? `(${a.province})` : '';
|
|
315
|
+
const zip = a.zip || '';
|
|
316
|
+
const country = a.country || '';
|
|
317
|
+
const phone = a.phone || '';
|
|
318
|
+
|
|
319
|
+
const line1 = first_name.length || last_name.length ? `${first_name} ${last_name}<br>` : '';
|
|
320
|
+
const line2 = company.length ? `${company}<br>` : '';
|
|
321
|
+
const line3 = address1.length ? `${address1}<br>` : '';
|
|
322
|
+
const line4 = address2.length ? `${address2}<br>` : '';
|
|
323
|
+
const line5 = city.length || province.length || zip.length ? `${city} ${province} ${zip}<br>` : '';
|
|
324
|
+
const line6 = country.length ? `${country}<br>` : '';
|
|
325
|
+
const line7 = phone.length ? phone : '';
|
|
326
|
+
return `${line1}${line2}${line3}${line4}${line5}${line6}${line7}`;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
mounted() {
|
|
331
|
+
this.checkOrderUrl();
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
app.config.globalProperties.$filters = {
|
|
335
|
+
money(value) {
|
|
336
|
+
return McUtils.money(value);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
app.config.compilerOptions.isCustomElement = tag => tag.includes('-'); // per evitare che vue vada in conflitto con liquid
|
|
340
|
+
app.mount(this);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
getOrderId() {
|
|
344
|
+
// se l'utente arriva da un link diretto
|
|
345
|
+
const params = new URLSearchParams(window.location.search);
|
|
346
|
+
return params.get('order')?.replace('#', '') || null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
}
|
|
350
|
+
if (!window.customElements.get('teddy-return-request')) {
|
|
351
|
+
window.customElements.define('teddy-return-request', TeddyReturnRequest);
|
|
352
|
+
}
|
|
353
|
+
window.TeddyReturnRequest = TeddyReturnRequest;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {execSync} = require('child_process');
|
|
5
|
+
const readline = require('readline');
|
|
6
|
+
|
|
7
|
+
const rl = readline.createInterface({
|
|
8
|
+
input: process.stdin,
|
|
9
|
+
output: process.stdout,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const ask = (question, defaultValue) => new Promise((resolve) => {
|
|
13
|
+
const suffix = defaultValue ? ` (${defaultValue})` : '';
|
|
14
|
+
rl.question(`${question}${suffix}: `, (answer) => {
|
|
15
|
+
resolve(answer.trim() || defaultValue || '');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const sanitizeTagPart = (value) => value
|
|
20
|
+
.toLowerCase()
|
|
21
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
22
|
+
.replace(/-+/g, '-')
|
|
23
|
+
.replace(/^-|-$/g, '');
|
|
24
|
+
|
|
25
|
+
(async () => {
|
|
26
|
+
try {
|
|
27
|
+
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
28
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
29
|
+
const currentVersion = pkg.version;
|
|
30
|
+
|
|
31
|
+
console.log(`Current version: ${currentVersion}`);
|
|
32
|
+
|
|
33
|
+
const storeRaw = await ask('Store name (used for npm dist-tag)', '');
|
|
34
|
+
const store = sanitizeTagPart(storeRaw);
|
|
35
|
+
if (!store) {
|
|
36
|
+
console.error('Store name is required.');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const bump = await ask('Version bump (patch/minor/major/prerelease)', 'patch');
|
|
41
|
+
const npmVersionArgs = ['npm', 'version', bump];
|
|
42
|
+
if (bump === 'prerelease') {
|
|
43
|
+
const preid = await ask('Prerelease identifier (preid)', 'beta');
|
|
44
|
+
npmVersionArgs.push(`--preid=${preid}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log(`Running: ${npmVersionArgs.join(' ')}`);
|
|
48
|
+
const newVersionRaw = execSync(npmVersionArgs.join(' '), {encoding: 'utf8'}).trim();
|
|
49
|
+
const newVersion = newVersionRaw.replace(/^v/, '');
|
|
50
|
+
|
|
51
|
+
const tag = `${store}-${newVersion}`;
|
|
52
|
+
console.log(`Publishing with dist-tag "${tag}"...`);
|
|
53
|
+
execSync(`npm publish --access public --tag ${tag}`, {stdio: 'inherit'});
|
|
54
|
+
|
|
55
|
+
console.log(`Done. Published ${pkg.name}@${newVersion} with tag "${tag}".`);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error(err.message);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
} finally {
|
|
60
|
+
rl.close();
|
|
61
|
+
}
|
|
62
|
+
})();
|