@akinon/pz-b2b 1.60.0-rc.8 → 1.60.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +1 -10
- package/README.md +5 -23
- package/package.json +1 -1
- package/src/basket-b2b/index.tsx +11 -77
- package/src/views/basket-b2b/index.ts +0 -1
- package/src/views/basket-b2b/upload-modal.tsx +0 -106
package/CHANGELOG.md
CHANGED
@@ -1,15 +1,6 @@
|
|
1
1
|
# @akinon/pz-b2b
|
2
2
|
|
3
|
-
## 1.60.0
|
4
|
-
|
5
|
-
## 1.60.0-rc.7
|
6
|
-
|
7
|
-
## 1.60.0-rc.6
|
8
|
-
|
9
|
-
### Minor Changes
|
10
|
-
|
11
|
-
- 64699d3f: ZERO-2761: Fix invalid import for plugin module
|
12
|
-
- c45b62c: ZERO-2818: Add upload and download support for b2b package
|
3
|
+
## 1.60.0
|
13
4
|
|
14
5
|
## 1.59.0
|
15
6
|
|
package/README.md
CHANGED
@@ -102,15 +102,6 @@ Add the translation inside the basket object. Apply this for every language
|
|
102
102
|
"add_to_favorites_button": "ADD TO FAVORITES",
|
103
103
|
"delete_product_button": "delete product"
|
104
104
|
},
|
105
|
-
"upload_file_modal": {
|
106
|
-
"select_file": "Select File",
|
107
|
-
"upload": "Upload",
|
108
|
-
"no_file_selected": "No file selected",
|
109
|
-
"error": {
|
110
|
-
"upload_failed": "An error occurred while uploading the file",
|
111
|
-
"no_file_selected": "Please select a file before uploading."
|
112
|
-
}
|
113
|
-
},
|
114
105
|
"empty": {
|
115
106
|
"title": "Your cart is empty, would you like to continue with your saved carts?",
|
116
107
|
"button": "SELECT CART",
|
@@ -150,15 +141,6 @@ Add the translation inside the basket object. Apply this for every language
|
|
150
141
|
"add_to_favorites_button": "FAVORİLERE EKLE",
|
151
142
|
"delete_product_button": "ürünü sil"
|
152
143
|
},
|
153
|
-
"upload_file_modal": {
|
154
|
-
"select_file": "Dosya Seç",
|
155
|
-
"upload": "Yükle",
|
156
|
-
"no_file_selected": "Dosya seçilmedi",
|
157
|
-
"error": {
|
158
|
-
"upload_failed": "Dosya yüklenirken bir hata oluştu",
|
159
|
-
"no_file_selected": "Lütfen yüklemeden önce bir dosya seçin"
|
160
|
-
}
|
161
|
-
},
|
162
144
|
"empty": {
|
163
145
|
"title": "Sepetiniz boş, kaydettiğiniz sepetlerle devam etmek ister misiniz?",
|
164
146
|
"button": "SEPETİ SEÇ",
|
@@ -207,7 +189,7 @@ rewrites: [
|
|
207
189
|
Add plugin name
|
208
190
|
|
209
191
|
```javascript
|
210
|
-
module.exports = [
|
192
|
+
module.exports = ["...", "pz-b2b"];
|
211
193
|
```
|
212
194
|
|
213
195
|
##### File Path: src/views/product/product-info.tsx
|
@@ -215,7 +197,7 @@ module.exports = ['...', 'pz-b2b'];
|
|
215
197
|
Add imports
|
216
198
|
|
217
199
|
```javascript
|
218
|
-
import { useB2b, StoreModal } from
|
200
|
+
import { useB2b, StoreModal } from "@akinon/pz-b2b";
|
219
201
|
```
|
220
202
|
|
221
203
|
Add useB2b hook
|
@@ -226,14 +208,14 @@ const {
|
|
226
208
|
setOpenSelectStoreModal,
|
227
209
|
divisions,
|
228
210
|
divisionLoading,
|
229
|
-
B2bButton
|
211
|
+
B2bButton,
|
230
212
|
} = useB2b();
|
231
213
|
```
|
232
214
|
|
233
215
|
Add open modal button
|
234
216
|
|
235
217
|
```javascript
|
236
|
-
<B2bButton buttonText={t(
|
218
|
+
<B2bButton buttonText={t("product.add_to_cart")} />
|
237
219
|
```
|
238
220
|
|
239
221
|
Add the end in the return
|
@@ -247,6 +229,6 @@ Add the end in the return
|
|
247
229
|
open={openSelectStoreModal}
|
248
230
|
setOpen={setOpenSelectStoreModal}
|
249
231
|
/>
|
250
|
-
)
|
232
|
+
)
|
251
233
|
}
|
252
234
|
```
|
package/package.json
CHANGED
package/src/basket-b2b/index.tsx
CHANGED
@@ -7,22 +7,18 @@ import {
|
|
7
7
|
Trans,
|
8
8
|
Price,
|
9
9
|
Icon,
|
10
|
-
Link
|
11
|
-
Button
|
10
|
+
Link
|
12
11
|
} from '@akinon/next/components';
|
13
12
|
import {
|
14
13
|
useGetBasketB2bQuery,
|
15
14
|
useGetDraftsQuery,
|
16
|
-
useLoadBasketMutation
|
17
|
-
useGetBasketStatusMutation,
|
18
|
-
useExportBasketMutation
|
15
|
+
useLoadBasketMutation
|
19
16
|
} from '@akinon/next/data/client/b2b';
|
20
17
|
import {
|
21
18
|
BasketItem,
|
22
19
|
RequestQuoteModal,
|
23
20
|
RemoveProductModal,
|
24
|
-
SaveCartModal
|
25
|
-
UploadModal
|
21
|
+
SaveCartModal
|
26
22
|
} from '../views/basket-b2b';
|
27
23
|
|
28
24
|
interface BasketB2bTranslationsProps {
|
@@ -70,14 +66,11 @@ interface BasketB2bProps {
|
|
70
66
|
|
71
67
|
export function BasketB2b({ translations }: BasketB2bProps) {
|
72
68
|
const { data: basket, isLoading, isSuccess } = useGetBasketB2bQuery();
|
73
|
-
const [getBasketStatus] = useGetBasketStatusMutation();
|
74
|
-
const [exportBasket] = useExportBasketMutation();
|
75
69
|
const [loadBasket] = useLoadBasketMutation();
|
76
70
|
const { data: dataDraft } = useGetDraftsQuery();
|
77
71
|
const [open, setOpen] = useState(false);
|
78
72
|
const [openRequestQuote, setRequestQuote] = useState(false);
|
79
73
|
const [openRemoveProduct, setRemoveProduct] = useState(false);
|
80
|
-
const [openUploadBasket, setUploadBasket] = useState(false);
|
81
74
|
const [productToBeDeleted, setProductToBeDeleted] = useState(null);
|
82
75
|
const [selectedDraft, setSelectedDraft] = useState(null);
|
83
76
|
|
@@ -136,42 +129,6 @@ export function BasketB2b({ translations }: BasketB2bProps) {
|
|
136
129
|
|
137
130
|
loadBasket(selectedDraft);
|
138
131
|
};
|
139
|
-
const handleDownload = async () => {
|
140
|
-
const fieldsArray = [
|
141
|
-
'product__sku',
|
142
|
-
'quantity',
|
143
|
-
'division__erp_code',
|
144
|
-
'division__name',
|
145
|
-
'price',
|
146
|
-
'variants__Renk'
|
147
|
-
];
|
148
|
-
|
149
|
-
const queryString = new URLSearchParams(
|
150
|
-
fieldsArray.map((queryName) => ['_fields', queryName])
|
151
|
-
).toString();
|
152
|
-
|
153
|
-
try {
|
154
|
-
const data = await exportBasket(queryString).unwrap();
|
155
|
-
await handleDownloadStatus(data.cache_key);
|
156
|
-
} catch (error) {
|
157
|
-
console.error('Error during download process:', error);
|
158
|
-
}
|
159
|
-
};
|
160
|
-
|
161
|
-
const handleDownloadStatus = async (cacheKey) => {
|
162
|
-
try {
|
163
|
-
const data = await getBasketStatus(cacheKey).unwrap();
|
164
|
-
if (data.status === 'completed') {
|
165
|
-
window.location.href = data.url;
|
166
|
-
} else if (data.status === 'waiting') {
|
167
|
-
setTimeout(() => handleDownloadStatus(cacheKey), 2000);
|
168
|
-
} else {
|
169
|
-
console.warn(`Unhandled status: ${data.status}`);
|
170
|
-
}
|
171
|
-
} catch (error) {
|
172
|
-
console.error('Error fetching basket data:', error);
|
173
|
-
}
|
174
|
-
};
|
175
132
|
|
176
133
|
useEffect(() => {
|
177
134
|
if (isSuccess) {
|
@@ -199,36 +156,19 @@ export function BasketB2b({ translations }: BasketB2bProps) {
|
|
199
156
|
<h2 className="text-xl lg:text-2xl font-light">
|
200
157
|
{_translations.my_cart}
|
201
158
|
</h2>
|
159
|
+
|
202
160
|
<Link href="/" className="text-xs hover:text-secondary-500">
|
203
161
|
{_translations.back_to_shopping}
|
204
162
|
</Link>
|
205
163
|
</div>
|
206
164
|
|
207
|
-
<div className="
|
208
|
-
<
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
/>
|
215
|
-
</div>
|
216
|
-
<div className="flex items-center gap-2">
|
217
|
-
<Button
|
218
|
-
className="flex flex-col items-center justify-center"
|
219
|
-
onClick={() => setUploadBasket(true)}
|
220
|
-
>
|
221
|
-
<span>XLS</span>
|
222
|
-
<Icon name="chevron-up" size={12} />
|
223
|
-
</Button>
|
224
|
-
<Button
|
225
|
-
className="flex flex-col items-center justify-center"
|
226
|
-
onClick={handleDownload}
|
227
|
-
>
|
228
|
-
<span>XLS</span>
|
229
|
-
<Icon name="chevron-down" size={12} />
|
230
|
-
</Button>
|
231
|
-
</div>
|
165
|
+
<div className="px-5 py-4 border border-b-0 border-gray-200 text-xs text-[#363636]">
|
166
|
+
<Trans
|
167
|
+
i18nKey={_translations.table.basket_qty}
|
168
|
+
components={{
|
169
|
+
Qty: <span>{basket.total_quantity}</span>
|
170
|
+
}}
|
171
|
+
/>
|
232
172
|
</div>
|
233
173
|
|
234
174
|
<div className="w-full overflow-x-auto">
|
@@ -382,12 +322,6 @@ export function BasketB2b({ translations }: BasketB2bProps) {
|
|
382
322
|
_translations.remove_product_modal.delete_product_button
|
383
323
|
}
|
384
324
|
/>
|
385
|
-
|
386
|
-
<UploadModal
|
387
|
-
setOpen={setUploadBasket}
|
388
|
-
open={openUploadBasket}
|
389
|
-
modalTitle="File Upload"
|
390
|
-
/>
|
391
325
|
</div>
|
392
326
|
</>
|
393
327
|
);
|
@@ -1,106 +0,0 @@
|
|
1
|
-
'use client';
|
2
|
-
|
3
|
-
import { useUploadFileMutation } from '@akinon/next/data/client/b2b';
|
4
|
-
import React, { useState } from 'react';
|
5
|
-
import { Button } from '@akinon/next/components';
|
6
|
-
import { useLocalization } from '@akinon/next/hooks';
|
7
|
-
|
8
|
-
export const UploadModal = ({
|
9
|
-
open,
|
10
|
-
setOpen,
|
11
|
-
modalTitle
|
12
|
-
}: {
|
13
|
-
open: boolean;
|
14
|
-
setOpen: (open: boolean) => void;
|
15
|
-
modalTitle: string;
|
16
|
-
}) => {
|
17
|
-
const { t } = useLocalization();
|
18
|
-
const [file, setFile] = useState<File | null>(null);
|
19
|
-
const [uploadFile, { isLoading }] = useUploadFileMutation();
|
20
|
-
const [error, setError] = useState<string | null>(null);
|
21
|
-
|
22
|
-
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
23
|
-
setFile(e.target.files?.[0] || null);
|
24
|
-
setError(null);
|
25
|
-
};
|
26
|
-
|
27
|
-
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
28
|
-
e.preventDefault();
|
29
|
-
|
30
|
-
if (!file) {
|
31
|
-
setError(t('basket.b2b.upload_file_modal.error.no_file_selected'));
|
32
|
-
return;
|
33
|
-
}
|
34
|
-
|
35
|
-
const formData = new FormData();
|
36
|
-
formData.append('filename', file);
|
37
|
-
|
38
|
-
try {
|
39
|
-
await uploadFile(formData).unwrap();
|
40
|
-
setOpen(false);
|
41
|
-
setFile(null);
|
42
|
-
setError(null);
|
43
|
-
} catch (uploadError) {
|
44
|
-
setError(t('basket.b2b.upload_file_modal.error.upload_failed'));
|
45
|
-
}
|
46
|
-
};
|
47
|
-
|
48
|
-
if (!open) return null;
|
49
|
-
|
50
|
-
return (
|
51
|
-
<div className="before:w-full before:h-screen before:content-[''] before:bg-black/60 before:z-40 before:fixed before:inset-0">
|
52
|
-
<div className="w-11/12 max-w-[344px] md:w-[370px] left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-50 fixed bg-white">
|
53
|
-
<header className="relative border-b border-[#d5dadb]">
|
54
|
-
<h3 className="text-left px-[30px] py-4 font-medium text-lg">
|
55
|
-
{modalTitle}
|
56
|
-
</h3>
|
57
|
-
<button
|
58
|
-
className="absolute right-[30px] top-5"
|
59
|
-
onClick={() => setOpen(false)}
|
60
|
-
>
|
61
|
-
<i className="pz-icon-close"></i>
|
62
|
-
</button>
|
63
|
-
</header>
|
64
|
-
<div className="p-[30px]">
|
65
|
-
<form onSubmit={handleSubmit}>
|
66
|
-
<div className="relative flex flex-col justify-center items-center mb-4">
|
67
|
-
<input
|
68
|
-
type="file"
|
69
|
-
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
70
|
-
onChange={handleFileChange}
|
71
|
-
className="opacity-0 w-full absolute left-0 top-0 h-full text-[0px] cursor-pointer"
|
72
|
-
/>
|
73
|
-
<Button className="pointer-events-none h-9 text-white border rounded mb-1">
|
74
|
-
{t('basket.b2b.upload_file_modal.select_file')}
|
75
|
-
</Button>
|
76
|
-
|
77
|
-
<p className="text-xs text-[#3e3e3e]">
|
78
|
-
{file
|
79
|
-
? file.name
|
80
|
-
: t('basket.b2b.upload_file_modal.no_file_selected')}
|
81
|
-
</p>
|
82
|
-
</div>
|
83
|
-
|
84
|
-
{error && (
|
85
|
-
<p className="text-xs text-center text-error mb-4">{error}</p>
|
86
|
-
)}
|
87
|
-
|
88
|
-
<Button
|
89
|
-
type="submit"
|
90
|
-
className="h-8 bg-black text-white font-medium text-sm w-full"
|
91
|
-
disabled={isLoading}
|
92
|
-
>
|
93
|
-
{isLoading ? (
|
94
|
-
<div className="w-full h-full flex justify-center items-center">
|
95
|
-
<div className="w-4 h-4 border-2 border-gray-600 border-t-transparent rounded-full animate-spin" />
|
96
|
-
</div>
|
97
|
-
) : (
|
98
|
-
t('basket.b2b.upload_file_modal.upload')
|
99
|
-
)}
|
100
|
-
</Button>
|
101
|
-
</form>
|
102
|
-
</div>
|
103
|
-
</div>
|
104
|
-
</div>
|
105
|
-
);
|
106
|
-
};
|