@bjsdistribution/dms-client-return 0.1.21-prod → 0.1.22-dev

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 (49) hide show
  1. package/dist/common/custom-input/CustomInput.d.ts +5 -0
  2. package/dist/components/order-view/order-actions/actions/send-sms/SendSmsModal.d.ts +1 -0
  3. package/dist/components/order-view/order-actions/actions/what3words/What3WordsModal.tsx.d.ts +3 -0
  4. package/dist/components/order-view/store.d.ts +1 -1
  5. package/dist/components/order-view/types.d.ts +5 -4
  6. package/dist/components/order-view/utils.d.ts +2 -1
  7. package/dist/components/store.d.ts +2 -1
  8. package/dist/dms-client-return.cjs.development.js +1278 -903
  9. package/dist/dms-client-return.cjs.development.js.map +1 -1
  10. package/dist/dms-client-return.cjs.production.min.js +1 -1
  11. package/dist/dms-client-return.cjs.production.min.js.map +1 -1
  12. package/dist/dms-client-return.esm.js +1280 -905
  13. package/dist/dms-client-return.esm.js.map +1 -1
  14. package/package.json +1 -1
  15. package/src/common/custom-input/CustomInput.tsx +24 -0
  16. package/src/components/client-portal/DateFilterStore.ts +57 -9
  17. package/src/components/client-portal/OutstandingTable.tsx +1 -1
  18. package/src/components/client-portal/ReturnStatus.tsx +84 -44
  19. package/src/components/client-portal/return-confirm/ConfirmedMain.tsx +5 -6
  20. package/src/components/client-portal/return-confirm/ReturnConfirmedTable.tsx +21 -2
  21. package/src/components/order-daily-overview/header/route-header/ClientRouterHeader.tsx +45 -23
  22. package/src/components/order-daily-overview/header-filters/HeaderFilter.tsx +3 -2
  23. package/src/components/order-daily-overview/header-filters/SelectionFilter.tsx +5 -3
  24. package/src/components/order-daily-overview/index.tsx +12 -5
  25. package/src/components/order-daily-overview/return-order-table/return-orders-filters/ReturnFilter.tsx +53 -4
  26. package/src/components/order-view/details-filters/left-side-filters/dropdowns/DropDowns.tsx +48 -12
  27. package/src/components/order-view/general-information/dropdowns/Print.tsx +13 -17
  28. package/src/components/order-view/modalsPopup/ModalManager.tsx +9 -1
  29. package/src/components/order-view/notes/logs/index.tsx +3 -1
  30. package/src/components/order-view/order-actions/actions/add-resources/DocFileUpload.tsx +4 -4
  31. package/src/components/order-view/order-actions/actions/charge-log/index.tsx +26 -1
  32. package/src/components/order-view/order-actions/actions/confirm-order/customer-info/DeliveryDate.tsx +1 -3
  33. package/src/components/order-view/order-actions/actions/create-task-reminder/CreateReminderModal.tsx +7 -4
  34. package/src/components/order-view/order-actions/actions/force-debrief/ForceDebriefModal.tsx +21 -20
  35. package/src/components/order-view/order-actions/actions/send-sms/SendSmsModal.tsx +104 -51
  36. package/src/components/order-view/order-actions/actions/what3words/What3WordsModal.tsx.tsx +306 -0
  37. package/src/components/order-view/order-actions/index.tsx +34 -13
  38. package/src/components/order-view/order-details/expanded-content/customer-section/contact-info/ContactHome.tsx +6 -3
  39. package/src/components/order-view/order-details/expanded-content/customer-section/contact-info/ContactMobile.tsx +6 -3
  40. package/src/components/order-view/order-details/expanded-content/customer-section/contact-info/ContactWork.tsx +9 -3
  41. package/src/components/order-view/order-details/expanded-content/customer-section/location-info/Latitude.tsx +5 -7
  42. package/src/components/order-view/order-details/expanded-content/customer-section/location-info/Longitude.tsx +1 -1
  43. package/src/components/order-view/order-details/expanded-content/customer-section/location-info/What3words.tsx +45 -13
  44. package/src/components/order-view/order-details/expanded-content/footer/index.tsx +63 -27
  45. package/src/components/order-view/order-details/expanded-content/orders-section/DeliveryDate.tsx +1 -1
  46. package/src/components/order-view/products-info/index.tsx +1 -0
  47. package/src/components/order-view/types.ts +6 -4
  48. package/src/components/store.ts +8 -1
  49. package/src/index.tsx +6 -4
@@ -0,0 +1,306 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import {
3
+ useCurrentAction,
4
+ useCustomerInfo,
5
+ useOrderDetails,
6
+ usePrevOrderDetails,
7
+ } from '../../../store';
8
+ import OrderActionModal from '../../../../../common/modals/order-action-modal/OrderActionModal';
9
+ import { notification } from 'antd';
10
+ import { Label, useAxios } from '@bjsdistribution/dms-component-library';
11
+ import styled from 'styled-components';
12
+ import GenericInput from '../../../../../common/custom-input/CustomInput';
13
+ import { compareOrderDetailsStates } from '../../../utils';
14
+ import { ApiResponse } from '../../../types';
15
+ import { useClientPortal } from '../../../../store';
16
+
17
+ function What3WordsModal(props: any) {
18
+ const w3wRegex = /^\/{0,}[^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}[・.。][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}[・.。][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}$/;
19
+ const [, setCurrentAction] = useCurrentAction();
20
+ const [orderDetails, setOrderDetails] = useOrderDetails();
21
+ const [prevOrderDetails, setPrevOrderDetails] = usePrevOrderDetails();
22
+ const [customerInfo] = useCustomerInfo();
23
+ const [w3wError, setW3wError] = useState('');
24
+ const [isClientPortal] = useClientPortal();
25
+ const orderRecipient = orderDetails?.order_recipient || {};
26
+ const [currentWhat3Words, setWhat3Words] = useState();
27
+ const [localW3W, setLocalW3W] = useState('');
28
+ const [localLat, setLocalLat] = useState(orderRecipient?.latitude || '');
29
+ const [localLong, setLocalLong] = useState(orderRecipient?.longitude || '');
30
+
31
+ const closeModal = () => setCurrentAction(undefined);
32
+
33
+ const cleanW3WAddress = (w3wStr: string) => {
34
+ return w3wStr.replace(/^\/+/, '');
35
+ };
36
+
37
+ const validateInput = (value: string) => {
38
+ if (value.trim()) {
39
+ const isValid = w3wRegex.test(value);
40
+ setW3wError(
41
+ isValid ? '' : 'Please enter a valid input (format: word.word.word)'
42
+ );
43
+ } else {
44
+ setW3wError('Input cannot be empty or only spaces');
45
+ }
46
+ };
47
+
48
+ const onChangeW3W = (e: React.ChangeEvent<HTMLInputElement>) => {
49
+ const rawVal = e.target.value;
50
+ const val = cleanW3WAddress(rawVal);
51
+ validateInput(rawVal); // still validate raw input for dots, etc.
52
+ setLocalW3W(val);
53
+ };
54
+
55
+ const onChangeLatitude = (e: React.ChangeEvent<HTMLInputElement>) => {
56
+ setLocalLat(e.target.value);
57
+ };
58
+
59
+ const onChangeLongitude = (e: React.ChangeEvent<HTMLInputElement>) => {
60
+ setLocalLong(e.target.value);
61
+ };
62
+
63
+ const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
64
+ if (['e', 'E', '+', '-'].includes(e.key)) {
65
+ e.preventDefault();
66
+ }
67
+ };
68
+
69
+ const { fetchData: callUpdateOrderAPI } = useAxios<{
70
+ data: ApiResponse[];
71
+ }>({
72
+ endpoint: `/orders/update/`,
73
+ method: 'PUT',
74
+ });
75
+
76
+ const { fetchData: getWhat3Words } = useAxios<{
77
+ data: ApiResponse[];
78
+ }>({
79
+ endpoint: `/v1/orders/coordinates_to_w3w/?`,
80
+ method: 'GET',
81
+ });
82
+
83
+ useEffect(() => {
84
+ if (
85
+ orderDetails?.order_recipient?.latitude &&
86
+ orderDetails?.order_recipient?.longitude
87
+ ) {
88
+ getWhat3Words({
89
+ endPointQuery: `latitude=${orderDetails?.order_recipient?.latitude}&longitude=${orderDetails?.order_recipient?.longitude}`,
90
+ }).then((response: any) => {
91
+ console.log(response?.data);
92
+ setWhat3Words(response?.data?.words);
93
+ });
94
+ }
95
+ }, [
96
+ orderDetails?.order_recipient?.latitude,
97
+ orderDetails?.order_recipient?.longitude,
98
+ ]);
99
+
100
+ const onSave = async () => {
101
+ const updatedOrderDetails = {
102
+ ...orderDetails,
103
+ order_recipient: {
104
+ ...(orderDetails?.order_recipient || {}),
105
+ what_3words_address: localW3W,
106
+ latitude: localLat,
107
+ longitude: localLong,
108
+ },
109
+ };
110
+
111
+ const payload = compareOrderDetailsStates(
112
+ prevOrderDetails,
113
+ updatedOrderDetails
114
+ );
115
+
116
+ let response = (await callUpdateOrderAPI({
117
+ payload: [payload],
118
+ })) as {
119
+ code: number | null;
120
+ error?: string | null | undefined;
121
+ [key: string]: any;
122
+ };
123
+
124
+ if (response.code === 200 && response?.data?.length > 0) {
125
+ notification.success({
126
+ message: 'Success',
127
+ description: `${response?.message}`,
128
+ });
129
+
130
+ await props?.callOrdersApi();
131
+ setOrderDetails(response?.data[0]);
132
+ setPrevOrderDetails(response?.data[0]);
133
+ closeModal();
134
+ } else {
135
+ notification.error({
136
+ message: 'Update Failed',
137
+ description: response?.error || 'Unknown error',
138
+ });
139
+
140
+ setOrderDetails(prevOrderDetails);
141
+ }
142
+ };
143
+
144
+ const infoText = `${customerInfo?.recipient_name}, ${customerInfo?.postcode}`;
145
+
146
+ const isDifferent = () => {
147
+ const original = orderRecipient || {};
148
+ return (
149
+ localW3W !== (original.what_3words_address || '') ||
150
+ localLat !== (original.latitude || '') ||
151
+ localLong !== (original.longitude || '')
152
+ );
153
+ };
154
+
155
+ useEffect(() => {
156
+ setLocalLat(orderRecipient?.latitude || '');
157
+ setLocalLong(orderRecipient?.longitude || '');
158
+ }, [orderRecipient]);
159
+
160
+ return (
161
+ <OrderActionModal
162
+ headerTitle="WHAT3WORDS"
163
+ onCloseHeader={closeModal}
164
+ onSubmit={onSave}
165
+ showAdditionalInfo
166
+ infoText={infoText}
167
+ isSubmitDisabled={isClientPortal ? true : !isDifferent() || !!w3wError}
168
+ submitBtnTitle="Save Details"
169
+ >
170
+ <Section>
171
+ <FieldRow>
172
+ <WordsSection>
173
+ <Label label="Words" />
174
+ <WordInputWrapper>
175
+ <CustomInput
176
+ name="w3w"
177
+ type="text"
178
+ placeholder="Format: word.word.word"
179
+ value={localW3W}
180
+ onChange={onChangeW3W}
181
+ disabled={isClientPortal}
182
+ />
183
+
184
+ {w3wError && <ErrorText>{w3wError}</ErrorText>}
185
+ </WordInputWrapper>
186
+
187
+ <CurrentText>
188
+ <strong>Current:</strong>{' '}
189
+ <a
190
+ href={`https://what3words.com/${currentWhat3Words}`}
191
+ target="_blank"
192
+ rel="noopener noreferrer"
193
+ >
194
+ {currentWhat3Words}
195
+ </a>
196
+ </CurrentText>
197
+ </WordsSection>
198
+ </FieldRow>
199
+ </Section>
200
+
201
+ <Section>
202
+ <CoordRow>
203
+ <Coordinate>
204
+ <Label label="Latitude" htmlFor="lat" />
205
+ <CustomInput
206
+ name="lat"
207
+ type="number"
208
+ placeholder="Lat"
209
+ value={localLat}
210
+ onChange={onChangeLatitude}
211
+ onKeyDown={handleKeyDown}
212
+ />
213
+ </Coordinate>
214
+ <Coordinate>
215
+ <Label label="Longitude" htmlFor="long" />
216
+
217
+ <CustomInput
218
+ name="long"
219
+ type="number"
220
+ placeholder="Long"
221
+ value={localLong}
222
+ onChange={onChangeLongitude}
223
+ onKeyDown={handleKeyDown}
224
+ />
225
+ </Coordinate>
226
+ </CoordRow>
227
+ </Section>
228
+ </OrderActionModal>
229
+ );
230
+ }
231
+
232
+ const WordsSection = styled.div`
233
+ display: flex;
234
+ flex-direction: row;
235
+ gap: 15px;
236
+ align-items: center;
237
+ `;
238
+
239
+ const WordInputWrapper = styled.div`
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: 4px;
243
+ width: 100%;
244
+ `;
245
+
246
+ const CurrentText = styled.div`
247
+ font-size: 13px;
248
+ color: #444;
249
+ white-space: nowrap;
250
+
251
+ a {
252
+ color: #1677ff;
253
+ text-decoration: none;
254
+ }
255
+
256
+ a:hover {
257
+ text-decoration: underline;
258
+ }
259
+ `;
260
+
261
+ const ErrorText = styled.span`
262
+ color: red;
263
+ font-size: 0.85rem;
264
+ margin-top: 4px;
265
+ `;
266
+
267
+ const Section = styled.div`
268
+ padding: 15px;
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 16px;
272
+ `;
273
+
274
+ const FieldRow = styled.div`
275
+ display: flex;
276
+ align-items: center;
277
+ gap: 10px;
278
+ flex-wrap: wrap;
279
+ `;
280
+
281
+ const CoordRow = styled.div`
282
+ display: flex;
283
+ justify-content: space-between;
284
+ gap: 14px;
285
+ `;
286
+
287
+ const Coordinate = styled.div`
288
+ flex: 1;
289
+ display: flex;
290
+ flex-direction: column;
291
+ gap: 5px;
292
+ `;
293
+
294
+ const CustomInput = styled(GenericInput)`
295
+ width: 100%;
296
+ &::-webkit-outer-spin-button,
297
+ &::-webkit-inner-spin-button {
298
+ -webkit-appearance: none;
299
+ margin: 0;
300
+ }
301
+ &:focus-visible {
302
+ outline: none;
303
+ }
304
+ `;
305
+
306
+ export default What3WordsModal;
@@ -34,6 +34,8 @@ import ChargeLog from './actions/charge-log';
34
34
  import ReminderModal from './actions/create-task-reminder';
35
35
  import TaskModal from './actions/create-task-reminder/TaskModal';
36
36
  import ForceDebriefModal from './actions/force-debrief/ForceDebriefModal';
37
+ import { useNavigate } from 'react-router-dom';
38
+ import What3WordsModal from './actions/what3words/What3WordsModal.tsx';
37
39
 
38
40
  function OrderActions() {
39
41
  const [currentAction, setCurrentAction] = useCurrentAction();
@@ -47,6 +49,7 @@ function OrderActions() {
47
49
  const [, setLoading] = useLoading();
48
50
  const [, setTasksData] = useTasksData();
49
51
  const [, setReminderNotifyData] = useReminderNotiData();
52
+ const navigate = useNavigate();
50
53
 
51
54
  // call orders api
52
55
 
@@ -58,19 +61,35 @@ function OrderActions() {
58
61
  });
59
62
 
60
63
  useEffect(() => {
61
- setLoading(loading);
62
- if (fetchedData && fetchedData?.data) {
63
- const requiredData = fetchedData?.data;
64
- setOrderDetails(requiredData[0]);
65
- setPrevOrderDetails(requiredData[0]);
66
- setCurrentAction(undefined);
67
- }
68
- if (
69
- (fetchedData && fetchedData?.data === null) ||
70
- fetchedData?.data?.length === 0
71
- ) {
72
- setCurrentAction(undefined);
73
- }
64
+ const fetchData = async () => {
65
+ try {
66
+ setLoading(loading);
67
+
68
+ if (fetchedData && fetchedData?.data) {
69
+ const requiredData = fetchedData?.data;
70
+ setOrderDetails(requiredData[0]);
71
+ setPrevOrderDetails(requiredData[0]);
72
+ setCurrentAction(undefined);
73
+ }
74
+
75
+ if (
76
+ (fetchedData && fetchedData?.data === null) ||
77
+ fetchedData?.data?.length === 0
78
+ ) {
79
+ setCurrentAction(undefined);
80
+ }
81
+ } catch (error) {
82
+ //@ts-ignore
83
+
84
+ if (error?.response?.status === 404) {
85
+ navigate('/404');
86
+ } else {
87
+ console.error('Error fetching order data:', error);
88
+ }
89
+ }
90
+ };
91
+
92
+ fetchData();
74
93
  }, [loading]);
75
94
 
76
95
  // orders api ends
@@ -293,6 +312,8 @@ function OrderActions() {
293
312
  return <ClearBookingStatus callOrderAlertsApi={callOrderAlertsApi} />;
294
313
  case 'remove-from-route':
295
314
  return <RemoveFromRoute callOrderAlertsApi={callOrderAlertsApi} />;
315
+ case 'what3Words':
316
+ return <What3WordsModal callOrdersApi={callOrdersApi} />;
296
317
  default:
297
318
  return null;
298
319
  }
@@ -12,6 +12,7 @@ import { useClientPortal } from '../../../../../store';
12
12
 
13
13
  //import { VALIDATE_UK_IRISH_NUMBER_REGEX } from '../../../helper';
14
14
  import CallCustomer from './CallCustomer';
15
+ import { Tooltip } from 'antd';
15
16
 
16
17
  function ContactHome() {
17
18
  const [errors, setErrors] = useAtom(errorAtom);
@@ -125,9 +126,11 @@ function ContactHome() {
125
126
  const finalHref = `tel:${hrefPrefix}${numberPart}`;
126
127
 
127
128
  return (
128
- <a href={finalHref} style={{ cursor: 'pointer' }}>
129
- <CallCustomer />
130
- </a>
129
+ <Tooltip placement="top" title={<span>Zoom</span>}>
130
+ <a href={finalHref} style={{ cursor: 'pointer' }}>
131
+ <CallCustomer />
132
+ </a>
133
+ </Tooltip>
131
134
  );
132
135
  })()}
133
136
  </InputContainer>
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../../../store';
12
12
  import { handleKeyDown } from '../../../../utils';
13
13
  import { useClientPortal } from '../../../../../store';
14
+ import { Tooltip } from 'antd';
14
15
 
15
16
  function ContactMobile() {
16
17
  const [errors, setErrors] = useAtom(errorAtom);
@@ -129,9 +130,11 @@ function ContactMobile() {
129
130
  const finalHref = `tel:${hrefPrefix}${numberPart}`;
130
131
 
131
132
  return (
132
- <a href={finalHref} style={{ cursor: 'pointer' }}>
133
- <CallCustomer />
134
- </a>
133
+ <Tooltip placement="top" title={<span>Zoom</span>}>
134
+ <a href={finalHref} style={{ cursor: 'pointer' }}>
135
+ <CallCustomer />
136
+ </a>
137
+ </Tooltip>
135
138
  );
136
139
  })()}
137
140
  </InputContainer>
@@ -8,11 +8,14 @@ import {
8
8
  usePrevOrderDetails,
9
9
  } from '../../../../store';
10
10
  import { handleKeyDown } from '../../../../utils';
11
+ import { useClientPortal } from '../../../../../store';
12
+ import { Tooltip } from 'antd';
11
13
  import CallCustomer from './CallCustomer';
12
14
 
13
15
  function ContactWork() {
14
16
  const [errors, setErrors] = useAtom(errorAtom);
15
17
  const [orderDetails, setOrderDetails] = useOrderDetails();
18
+ const [isClientPortal] = useClientPortal();
16
19
  const orderRecipient = orderDetails?.order_recipient;
17
20
  const [prevOrderDetails] = usePrevOrderDetails();
18
21
  const apiContactWork = prevOrderDetails?.order_recipient?.contact_work;
@@ -69,6 +72,7 @@ function ContactWork() {
69
72
  onChange={onChange}
70
73
  // minLength={10}
71
74
  // maxLength={10}
75
+ disabled={isClientPortal}
72
76
  />
73
77
  {apiContactWork &&
74
78
  (() => {
@@ -115,9 +119,11 @@ function ContactWork() {
115
119
  const finalHref = `tel:${hrefPrefix}${numberPart}`;
116
120
 
117
121
  return (
118
- <a href={finalHref} style={{ cursor: 'pointer' }}>
119
- <CallCustomer />
120
- </a>
122
+ <Tooltip placement="top" title={<span>Zoom</span>}>
123
+ <a href={finalHref} style={{ cursor: 'pointer' }}>
124
+ <CallCustomer />
125
+ </a>
126
+ </Tooltip>
121
127
  );
122
128
  })()}
123
129
  </InputContainer>
@@ -9,18 +9,16 @@ function Latitude() {
9
9
  const orderRecipient = orderDetails?.order_recipient;
10
10
 
11
11
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
12
- const val = parseFloat(e.target.value);
12
+ const val = e.target.value;
13
13
  const updatedOrderRecipient = {
14
14
  ...(orderRecipient === null
15
15
  ? { latitude: val }
16
16
  : { ...orderRecipient, latitude: val }),
17
17
  };
18
- setOrderDetails(prev => {
19
- return {
20
- ...prev,
21
- order_recipient: updatedOrderRecipient,
22
- };
23
- });
18
+ setOrderDetails(prev => ({
19
+ ...prev,
20
+ order_recipient: updatedOrderRecipient,
21
+ }));
24
22
  };
25
23
 
26
24
  return (
@@ -9,7 +9,7 @@ function Longitude() {
9
9
  const orderRecipient = orderDetails?.order_recipient;
10
10
 
11
11
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
12
- const val = parseFloat(e.target.value);
12
+ const val = e.target.value;
13
13
  const updatedOrderRecipient = {
14
14
  ...(orderRecipient === null
15
15
  ? { longitude: val }
@@ -2,28 +2,47 @@ import { Input, Label } from '@bjsdistribution/dms-component-library';
2
2
  import React from 'react';
3
3
  import styled from 'styled-components';
4
4
  import What3WordsIcon from '../../../../../../assets/icons/What3WordsIcon';
5
- import { errorAtom, useAtom, useOrderDetails } from '../../../../store';
5
+ import {
6
+ errorAtom,
7
+ useAtom,
8
+ useCurrentAction,
9
+ useOrderDetails,
10
+ } from '../../../../store';
11
+ import { sanitizeInput } from '../../../../utils';
12
+ import { useClientPortal } from '../../../../../store';
6
13
 
7
14
  function What3words() {
8
15
  const w3wRegex = /^\/{0,}[^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}[・.。][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}[・.。][^0-9`~!@#$%^&*()+\-_=[{\]}\\|'<,.>?/";:£§º©®\s]{1,}$/;
9
16
  const [orderDetails, setOrderDetails] = useOrderDetails();
10
17
  const [errors, setErrors] = useAtom(errorAtom);
18
+ const [isClientPortal] = useClientPortal();
11
19
  const orderRecipient = orderDetails?.order_recipient;
20
+ const [, setCurrentAction] = useCurrentAction();
21
+
22
+ const cleanW3WAddress = (w3wStr: string) => {
23
+ if (w3wStr.startsWith('///')) {
24
+ return w3wStr.slice(3);
25
+ } else if (w3wStr.startsWith('//')) {
26
+ return w3wStr.slice(2);
27
+ } else if (w3wStr.startsWith('/')) {
28
+ return w3wStr.slice(1);
29
+ }
30
+ return w3wStr;
31
+ };
12
32
 
13
33
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
14
- const val = e.target.value;
34
+ let val = sanitizeInput(e.target.value);
15
35
  validateInput(val);
16
36
  const updatedOrderRecipient = {
17
37
  ...(orderRecipient === null
18
38
  ? { what_3words_address: val }
19
- : { ...orderRecipient, what_3words_address: val }),
39
+ : { ...orderRecipient, what_3words_address: cleanW3WAddress(val) }),
20
40
  };
21
- setOrderDetails(prev => {
22
- return {
23
- ...prev,
24
- order_recipient: updatedOrderRecipient,
25
- };
26
- });
41
+
42
+ setOrderDetails(prev => ({
43
+ ...prev,
44
+ order_recipient: updatedOrderRecipient,
45
+ }));
27
46
  };
28
47
 
29
48
  const validateInput = (value: string) => {
@@ -31,19 +50,30 @@ function What3words() {
31
50
  const isValid = w3wRegex.test(value);
32
51
  setErrors(prev => ({
33
52
  ...prev,
34
- w3wError: isValid ? '' : 'Please enter a valid input (word.word.word)',
53
+ w3wError: isValid
54
+ ? ''
55
+ : 'Please enter a valid input (format: word.word.word)',
35
56
  }));
36
57
  } else {
37
58
  setErrors(prev => ({
38
59
  ...prev,
39
- w3wError: '',
60
+ w3wError: 'Input cannot be empty or only spaces',
40
61
  }));
41
62
  }
42
63
  };
43
64
 
65
+ // const handleOpenModal = () => {
66
+ // dispatch({ type: 'what3Words' });
67
+ // };
68
+
44
69
  return (
45
70
  <Container>
46
- <Label label="What3Words Address" htmlFor="w3w" />
71
+ <Label
72
+ style={{ color: '#6396e5', cursor: 'pointer' }}
73
+ label="What3Words Address"
74
+ htmlFor="w3w"
75
+ onClick={() => setCurrentAction('what3Words')}
76
+ />
47
77
  <Wrapper>
48
78
  <What3wordsPrefix>
49
79
  <What3WordsIcon />
@@ -54,12 +84,14 @@ function What3words() {
54
84
  placeholder="Format: word.word.word"
55
85
  value={orderRecipient?.what_3words_address || ''}
56
86
  onChange={onChange}
87
+ disabled={isClientPortal}
57
88
  />
58
89
  </Wrapper>
59
90
  {errors.w3wError && <ErrorText>{errors.w3wError}</ErrorText>}
60
91
  </Container>
61
92
  );
62
93
  }
94
+
63
95
  const What3wordsPrefix = styled.div`
64
96
  position: absolute;
65
97
  top: 13px;
@@ -71,7 +103,7 @@ const Wrapper = styled.div`
71
103
  `;
72
104
 
73
105
  const CustomInput = styled(Input)`
74
- border-radius: 25px;
106
+ /* border-radius: 25px; */
75
107
  &::-webkit-outer-spin-button,
76
108
  &::-webkit-inner-spin-button {
77
109
  -webkit-appearance: none;