@riosst100/pwa-marketplace 3.3.4 → 3.3.5
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/i18n/id_ID.json +8 -1
- package/package.json +1 -1
- package/src/components/LoadingRequest/loadingRequest.js +3 -1
- package/src/components/LoadingRequest/loadingRequest.module.css +4 -2
- package/src/components/OrderDetail/components/trackOrder.js +151 -0
- package/src/components/OrderDetail/orderDetail.js +15 -0
- package/src/overwrites/peregrine/lib/talons/SignIn/useSignIn.js +1 -0
- package/src/overwrites/peregrine/lib/talons/TrackOrder/trackOrder.gql.js +24 -0
- package/src/talons/SocialLogin/useSocialLogin.js +1 -0
- package/src/talons/TrackOrder/useTrackOrder.js +53 -0
package/i18n/id_ID.json
CHANGED
|
@@ -546,5 +546,12 @@
|
|
|
546
546
|
"messages.loginRequired": "Silakan masuk ke akun Anda untuk mengirim pesan ke seller.",
|
|
547
547
|
"messages.messageSent": "Pesan berhasil dikirim.",
|
|
548
548
|
"messages.replySent": "Balasan berhasil dikirim.",
|
|
549
|
-
"messages.messageDeleted": "Pesan berhasil dihapus."
|
|
549
|
+
"messages.messageDeleted": "Pesan berhasil dihapus.",
|
|
550
|
+
"order.track.inTransit": "Sedang Dikirim",
|
|
551
|
+
"order.track.delivered": "Pesanan Tiba",
|
|
552
|
+
"order.track.courier": "Kurir",
|
|
553
|
+
"order.track.waybill": "Resi",
|
|
554
|
+
"order.track.status": "Status",
|
|
555
|
+
"order.track.step1": "Langkah 1 dari 2",
|
|
556
|
+
"order.track.step2": "Langkah 2 dari 2"
|
|
550
557
|
}
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ const LoadingRequest = props => {
|
|
|
18
18
|
const {
|
|
19
19
|
isLoading
|
|
20
20
|
} = props;
|
|
21
|
+
// const isLoading = true;
|
|
21
22
|
|
|
22
23
|
const modal = isLoading ? (
|
|
23
24
|
<div className={modalClasses.overlay} role="dialog" aria-modal="true" aria-label="Modal">
|
|
@@ -27,7 +28,8 @@ const LoadingRequest = props => {
|
|
|
27
28
|
<img src={process.env.MAGENTO_BACKEND_URL + "/media/images/spinner2.gif"} style={{"width":"15%"}} />
|
|
28
29
|
<div style={{
|
|
29
30
|
"marginTop": "10px",
|
|
30
|
-
"color": "white"
|
|
31
|
+
"color": "white",
|
|
32
|
+
"fontSize": "14px"
|
|
31
33
|
}}>Please wait...</div>
|
|
32
34
|
</div>
|
|
33
35
|
</div>
|
|
@@ -75,8 +75,9 @@
|
|
|
75
75
|
.backdrop{
|
|
76
76
|
position:absolute;
|
|
77
77
|
inset:0;
|
|
78
|
-
background: rgba(0, 0, 0, 0.64);
|
|
79
|
-
|
|
78
|
+
/* background: rgba(0, 0, 0, 0.64); */
|
|
79
|
+
background: rgb(0 0 0 / 50%);
|
|
80
|
+
/* backdrop-filter: blur(1px); */
|
|
80
81
|
}
|
|
81
82
|
.dialog{
|
|
82
83
|
position:relative;
|
|
@@ -119,6 +120,7 @@
|
|
|
119
120
|
text-align: center;
|
|
120
121
|
flex-wrap: wrap;
|
|
121
122
|
align-content: center;
|
|
123
|
+
align-items: center;
|
|
122
124
|
}
|
|
123
125
|
.triggerBtn{
|
|
124
126
|
background:#f76b1c;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { TickCircle } from 'iconsax-react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
import useTrackOrder from '@riosst100/pwa-marketplace/src/talons/TrackOrder/useTrackOrder';
|
|
6
|
+
|
|
7
|
+
const TrackOrder = ({ order }) => {
|
|
8
|
+
const incrementId = useMemo(() => {
|
|
9
|
+
const num = order?.number;
|
|
10
|
+
return typeof num === 'number' ? String(num) : (num || '');
|
|
11
|
+
}, [order]);
|
|
12
|
+
|
|
13
|
+
const { trackOrder, isLoadingWithoutData, isBackgroundLoading, errorMessage } = useTrackOrder({ incrementId });
|
|
14
|
+
|
|
15
|
+
const { formatMessage, locale } = useIntl();
|
|
16
|
+
|
|
17
|
+
const status = (order?.status || '').toLowerCase();
|
|
18
|
+
const delivered = status === 'complete';
|
|
19
|
+
const canceled = status === 'canceled' || status === 'cancel' || status === 'cancelled';
|
|
20
|
+
const inTransit = !canceled && status !== '' && !delivered;
|
|
21
|
+
|
|
22
|
+
const summary = trackOrder?.summary;
|
|
23
|
+
const manifests = Array.isArray(trackOrder?.manifest)
|
|
24
|
+
? trackOrder.manifest
|
|
25
|
+
: (trackOrder?.manifest ? [trackOrder.manifest] : []);
|
|
26
|
+
|
|
27
|
+
const activeManifestIndex = useMemo(() => {
|
|
28
|
+
if (!manifests.length) return -1;
|
|
29
|
+
let bestIdx = 0;
|
|
30
|
+
let bestTime = -Infinity;
|
|
31
|
+
manifests.forEach((m, idx) => {
|
|
32
|
+
const d = m?.manifest_date;
|
|
33
|
+
const t = m?.manifest_time;
|
|
34
|
+
const dt = d && t ? new Date(`${d}T${t}`) : undefined;
|
|
35
|
+
const time = dt && !isNaN(dt) ? dt.getTime() : NaN;
|
|
36
|
+
if (!isNaN(time) && time > bestTime) {
|
|
37
|
+
bestTime = time;
|
|
38
|
+
bestIdx = idx;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return isFinite(bestTime) ? bestIdx : 0;
|
|
42
|
+
}, [manifests]);
|
|
43
|
+
|
|
44
|
+
const formatManifestDate = m => {
|
|
45
|
+
const d = m?.manifest_date;
|
|
46
|
+
const t = m?.manifest_time;
|
|
47
|
+
if (d && t) {
|
|
48
|
+
const dt = new Date(`${d}T${t}`);
|
|
49
|
+
if (!isNaN(dt)) {
|
|
50
|
+
try {
|
|
51
|
+
return new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeStyle: 'short' }).format(dt);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return dt.toLocaleString();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return [t || '', d || ''].filter(Boolean).join(' ') || '-';
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const [copied, setCopied] = useState(false);
|
|
61
|
+
const handleCopyWaybill = () => {
|
|
62
|
+
const text = summary?.waybill_number;
|
|
63
|
+
if (!text) return;
|
|
64
|
+
if (navigator?.clipboard?.writeText) {
|
|
65
|
+
navigator.clipboard.writeText(text)
|
|
66
|
+
.then(() => {
|
|
67
|
+
setCopied(true);
|
|
68
|
+
setTimeout(() => setCopied(false), 1500);
|
|
69
|
+
})
|
|
70
|
+
.catch(() => {});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const loading = isLoadingWithoutData || isBackgroundLoading;
|
|
75
|
+
return (
|
|
76
|
+
<div className="block-content rounded-md border border-gray-100 px-4 py-6 relative" aria-busy={loading}>
|
|
77
|
+
<div className="relative h-12 mb-6">
|
|
78
|
+
<div className="absolute left-0 right-0 top-[10px] flex">
|
|
79
|
+
<div className={`h-[2px] w-1/2 rounded-l-full ${inTransit || delivered ? 'bg-blue-600' : 'bg-gray-100'}`}></div>
|
|
80
|
+
<div className={`h-[2px] w-1/2 rounded-r-full ${delivered ? 'bg-blue-600' : 'bg-gray-100'}`}></div>
|
|
81
|
+
</div>
|
|
82
|
+
<div className="absolute left-0 right-0 top-[10px] flex justify-between">
|
|
83
|
+
<div className="flex flex-col items-center">
|
|
84
|
+
<span className={`w-3 h-3 rounded-full -translate-y-1/2 ring-2 ring-white shadow ${inTransit || delivered ? 'bg-blue-700' : 'bg-gray-100'} ${inTransit ? 'animate-pulse' : ''}`}></span>
|
|
85
|
+
<span className={`mt-2 text-sm ${inTransit || delivered ? 'text-blue-700 font-medium' : 'text-gray-200'}`}>{formatMessage({ id: 'order.track.inTransit', defaultMessage: 'In Transit' })}</span>
|
|
86
|
+
</div>
|
|
87
|
+
<div className="flex flex-col items-center">
|
|
88
|
+
<span className={`w-5 h-5 rounded-full -translate-y-1/2 flex items-center justify-center ring-2 ring-white shadow transition-transform duration-300 ${delivered ? 'bg-green-500 scale-110' : (delivered || inTransit ? 'bg-blue-700' : 'bg-gray-100')}`}>
|
|
89
|
+
{delivered && <TickCircle size={14} color="#ffffff" variant="Bold" />}
|
|
90
|
+
</span>
|
|
91
|
+
<span className={`mt-2 text-sm ${delivered ? 'text-green-600 font-medium' : 'text-gray-200'}`}>{formatMessage({ id: 'order.track.delivered', defaultMessage: 'Delivered' })}</span>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div className="flex flex-col gap-2 mb-6">
|
|
97
|
+
{summary && (
|
|
98
|
+
<div className="flex flex-col gap-2">
|
|
99
|
+
<div className="px-2 py-1 rounded bg-gray-100 text-gray-900 text-xs w-[250px]">
|
|
100
|
+
<strong>{formatMessage({ id: 'order.track.courier', defaultMessage: 'Courier' })}:</strong> {summary.courier_name || '-'}
|
|
101
|
+
</div>
|
|
102
|
+
<div className="px-2 py-1 rounded bg-gray-100 text-gray-900 text-xs w-[250px] flex items-center justify-between">
|
|
103
|
+
<div className="truncate" title={summary.waybill_number || ''}>
|
|
104
|
+
<strong>{formatMessage({ id: 'order.track.waybill', defaultMessage: 'Waybill' })}:</strong> {summary.waybill_number || '-'}
|
|
105
|
+
</div>
|
|
106
|
+
{summary.waybill_number && (
|
|
107
|
+
<button type="button" onClick={handleCopyWaybill} className="ml-2 px-2 py-1 rounded bg-blue-600 text-white text-xs hover:bg-blue-700">
|
|
108
|
+
{copied ? formatMessage({ id: 'common.copied', defaultMessage: 'Copied!' }) : formatMessage({ id: 'common.copy', defaultMessage: 'Copy' })}
|
|
109
|
+
</button>
|
|
110
|
+
)}
|
|
111
|
+
</div>
|
|
112
|
+
<div className={`px-2 py-1 rounded text-xs w-[250px] ${summary.status?.toLowerCase() === 'delivered' ? 'bg-green-100 text-green-700' : 'bg-blue-100 text-blue-700'}`}>
|
|
113
|
+
<strong>{formatMessage({ id: 'order.track.status', defaultMessage: 'Status' })}:</strong> {summary.status || '-'}
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
)}
|
|
117
|
+
{errorMessage && (
|
|
118
|
+
<div className="text-red-600 text-sm">{errorMessage}</div>
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
{manifests.length > 0 && (
|
|
123
|
+
<div className="relative flex flex-col gap-4">
|
|
124
|
+
<div className="pointer-events-none absolute left-[4px] top-0 bottom-0 border-l border-gray-100"></div>
|
|
125
|
+
{manifests.map((m, idx) => (
|
|
126
|
+
<div key={idx} className="flex items-start gap-3">
|
|
127
|
+
<div className={`mt-1 w-2 h-2 rounded-full z-10 ${idx === activeManifestIndex ? 'bg-blue-700' : 'bg-gray-100'}`}></div>
|
|
128
|
+
<div className="flex-1">
|
|
129
|
+
<div className="text-sm text-gray-800">{m?.manifest_description || '-'}</div>
|
|
130
|
+
{m?.city_name && (
|
|
131
|
+
<div className="text-xs text-gray-500">{m.city_name}</div>
|
|
132
|
+
)}
|
|
133
|
+
<div className="text-xs text-gray-500">{formatManifestDate(m)}</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
))}
|
|
137
|
+
</div>
|
|
138
|
+
)}
|
|
139
|
+
{loading && (
|
|
140
|
+
<div className="absolute inset-0 z-20 bg-white/60 backdrop-blur-[1px] flex items-center justify-center">
|
|
141
|
+
<div className="flex items-center gap-2">
|
|
142
|
+
<span className="w-5 h-5 rounded-full border-2 border-gray-200 border-t-blue-600 animate-spin"></span>
|
|
143
|
+
<span className="text-sm text-gray-700">{formatMessage({ id: 'order.track.loading', defaultMessage: 'Loading tracking order…' })}</span>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
)}
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default TrackOrder;
|
|
@@ -5,6 +5,7 @@ import Button from '@magento/venia-ui/lib/components/Button';
|
|
|
5
5
|
import cn from 'classnames';
|
|
6
6
|
import { Printer, ConvertCard } from 'iconsax-react';
|
|
7
7
|
import ItemsOrdered from './components/itemsOrdered';
|
|
8
|
+
import TrackOrder from './components/trackOrder';
|
|
8
9
|
import RMAList from './components/rmaList';
|
|
9
10
|
import useRmaPage from '@riosst100/pwa-marketplace/src/talons/RMAPage/useRmaPage';
|
|
10
11
|
import { useLocation, useParams, useHistory } from 'react-router-dom';
|
|
@@ -93,6 +94,7 @@ const OrderDetail = (props) => {
|
|
|
93
94
|
? new Date(order.order_date.replace(' ', 'T')).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })
|
|
94
95
|
: '-';
|
|
95
96
|
const status = order?.status || '-';
|
|
97
|
+
const isClosed = (order?.status || '').toLowerCase() === 'closed';
|
|
96
98
|
const shippingMethod = order?.shipping_method || '-';
|
|
97
99
|
const trackingNumber = order?.shipments?.[0]?.tracking?.[0]?.number || '-';
|
|
98
100
|
const shippingAddress = order?.shipping_address;
|
|
@@ -236,6 +238,19 @@ const OrderDetail = (props) => {
|
|
|
236
238
|
</div>
|
|
237
239
|
</div>
|
|
238
240
|
</div>
|
|
241
|
+
{!isClosed && (
|
|
242
|
+
<div className="block block-order-details-view">
|
|
243
|
+
<div aria-live="polite" className="text-lg font-medium text-left mb-4 block-title">
|
|
244
|
+
{
|
|
245
|
+
formatMessage({
|
|
246
|
+
id: 'order.trackOrder',
|
|
247
|
+
defaultMessage: 'Track Order'
|
|
248
|
+
})
|
|
249
|
+
}
|
|
250
|
+
</div>
|
|
251
|
+
<TrackOrder order={order} />
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
239
254
|
<div className="block block-order-details-view">
|
|
240
255
|
<div aria-live="polite" className="text-lg font-medium text-left mb-4 block-title">
|
|
241
256
|
{
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const GET_TRACK_ORDER = gql`
|
|
4
|
+
query GetTrackOrder($increment_id: String!) {
|
|
5
|
+
trackOrder(increment_id: $increment_id) {
|
|
6
|
+
delivered
|
|
7
|
+
summary {
|
|
8
|
+
courier_name
|
|
9
|
+
waybill_number
|
|
10
|
+
status
|
|
11
|
+
}
|
|
12
|
+
manifest {
|
|
13
|
+
manifest_description
|
|
14
|
+
manifest_date
|
|
15
|
+
city_name
|
|
16
|
+
manifest_time
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
getTrackOrderQuery: GET_TRACK_ORDER
|
|
24
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'react';
|
|
2
|
+
import { useQuery } from '@apollo/client';
|
|
3
|
+
|
|
4
|
+
import { useAppContext } from '@magento/peregrine/lib/context/app';
|
|
5
|
+
import { deriveErrorMessage } from '@magento/peregrine/lib/util/deriveErrorMessage';
|
|
6
|
+
|
|
7
|
+
import operations from '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/TrackOrder/trackOrder.gql';
|
|
8
|
+
|
|
9
|
+
export const useTrackOrder = (props = {}) => {
|
|
10
|
+
const { incrementId } = props;
|
|
11
|
+
const { getTrackOrderQuery } = operations;
|
|
12
|
+
|
|
13
|
+
const [
|
|
14
|
+
,
|
|
15
|
+
{
|
|
16
|
+
actions: { setPageLoading }
|
|
17
|
+
}
|
|
18
|
+
] = useAppContext();
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
data,
|
|
22
|
+
error,
|
|
23
|
+
loading,
|
|
24
|
+
refetch
|
|
25
|
+
} = useQuery(getTrackOrderQuery, {
|
|
26
|
+
fetchPolicy: 'cache-and-network',
|
|
27
|
+
variables: { increment_id: incrementId },
|
|
28
|
+
skip: !incrementId
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const isLoadingWithoutData = !data && loading;
|
|
32
|
+
const isBackgroundLoading = !!data && loading;
|
|
33
|
+
|
|
34
|
+
// Update the page indicator if the GraphQL query is in flight.
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
setPageLoading(isBackgroundLoading);
|
|
37
|
+
}, [isBackgroundLoading, setPageLoading]);
|
|
38
|
+
|
|
39
|
+
const derivedErrorMessage = useMemo(
|
|
40
|
+
() => deriveErrorMessage([error]),
|
|
41
|
+
[error]
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
errorMessage: derivedErrorMessage,
|
|
46
|
+
isLoadingWithoutData,
|
|
47
|
+
isBackgroundLoading,
|
|
48
|
+
trackOrder: data ? data.trackOrder : undefined,
|
|
49
|
+
refetchTrackOrder: refetch
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default useTrackOrder;
|