ordering-ui-admin-external 1.22.5 → 1.23.0

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 (58) hide show
  1. package/_bundles/{ordering-ui-admin.de284e3a7bc450dcb936.js → ordering-ui-admin.8c4443e7136fdcb8778b.js} +2 -2
  2. package/_modules/components/Delivery/DriversGroupDetails/index.js +5 -1
  3. package/_modules/components/Delivery/DriversGroupsListing/index.js +2 -0
  4. package/_modules/components/Delivery/DriversMarkAsBusy/index.js +5 -0
  5. package/_modules/components/Orders/OrderBill/RefundToWallet.js +238 -0
  6. package/_modules/components/Orders/OrderBill/index.js +27 -4
  7. package/_modules/components/Orders/OrderBill/styles.js +41 -3
  8. package/_modules/components/Orders/OrderDetails/index.js +12 -3
  9. package/_modules/components/Orders/OrderDetailsHeader/index.js +57 -6
  10. package/_modules/components/Orders/OrderDetailsHeader/styles.js +11 -3
  11. package/_modules/components/Orders/OrderToPrintTicket/index.js +126 -0
  12. package/_modules/components/Orders/OrderToPrintTicket/styles.js +30 -0
  13. package/_modules/components/Orders/OrdersTable/index.js +25 -5
  14. package/_modules/components/Settings/DoordashConnect/index.js +2 -2
  15. package/_modules/components/Settings/LalamoveConnect/index.js +1 -1
  16. package/_modules/components/Settings/PickerExpress/index.js +2 -2
  17. package/_modules/components/Settings/Settings/index.js +1 -1
  18. package/_modules/components/SidebarMenu/index.js +13 -6
  19. package/_modules/components/Stores/BusinessAdd/BusinessDetails/index.js +1 -1
  20. package/_modules/components/Stores/BusinessDeviceDetail/index.js +188 -0
  21. package/_modules/components/Stores/BusinessDeviceDetail/styles.js +48 -0
  22. package/_modules/components/Stores/BusinessDeviceListing/index.js +235 -0
  23. package/_modules/components/Stores/BusinessDeviceListing/styles.js +83 -0
  24. package/_modules/components/Stores/BusinessQRCodeOption/index.js +5 -17
  25. package/_modules/components/Stores/index.js +7 -0
  26. package/_modules/index.js +6 -0
  27. package/package.json +2 -2
  28. package/src/components/Delivery/DriversGroupDetails/index.js +6 -1
  29. package/src/components/Delivery/DriversGroupsListing/index.js +2 -0
  30. package/src/components/Delivery/DriversMarkAsBusy/index.js +9 -1
  31. package/src/components/Orders/DriverMapMarkerAndInfo/index.js +1 -1
  32. package/src/components/Orders/OrderBill/RefundToWallet.js +219 -0
  33. package/src/components/Orders/OrderBill/index.js +35 -3
  34. package/src/components/Orders/OrderBill/styles.js +104 -0
  35. package/src/components/Orders/OrderDetails/index.js +14 -2
  36. package/src/components/Orders/OrderDetailsHeader/index.js +55 -5
  37. package/src/components/Orders/OrderDetailsHeader/styles.js +21 -0
  38. package/src/components/Orders/OrderToPrintTicket/index.js +264 -0
  39. package/src/components/Orders/OrderToPrintTicket/styles.js +68 -0
  40. package/src/components/Orders/OrdersTable/index.js +27 -2
  41. package/src/components/Settings/DoordashConnect/index.js +2 -2
  42. package/src/components/Settings/LalamoveConnect/index.js +1 -1
  43. package/src/components/Settings/PickerExpress/index.js +2 -2
  44. package/src/components/Settings/Settings/index.js +1 -1
  45. package/src/components/SidebarMenu/index.js +12 -6
  46. package/src/components/Stores/BusinessAdd/BusinessDetails/index.js +1 -1
  47. package/src/components/Stores/BusinessDeviceDetail/index.js +183 -0
  48. package/src/components/Stores/BusinessDeviceDetail/styles.js +160 -0
  49. package/src/components/Stores/BusinessDeviceListing/index.js +272 -0
  50. package/src/components/Stores/BusinessDeviceListing/styles.js +218 -0
  51. package/src/components/Stores/BusinessQRCodeOption/index.js +3 -20
  52. package/src/components/Stores/index.js +2 -0
  53. package/src/index.js +3 -1
  54. package/template/app.js +4 -0
  55. package/template/components/ListenPageChanges/index.js +1 -0
  56. package/template/helmetdata.json +7 -0
  57. package/template/pages/BusinessDevicesList/index.js +12 -0
  58. /package/_bundles/{ordering-ui-admin.de284e3a7bc450dcb936.js.LICENSE.txt → ordering-ui-admin.8c4443e7136fdcb8778b.js.LICENSE.txt} +0 -0
@@ -0,0 +1,264 @@
1
+ import React, { forwardRef } from 'react'
2
+ import { verifyDecimals } from '../../../utils'
3
+ import { useUtils, useLanguage, useConfig } from 'ordering-components-admin-external';
4
+ import { PrintContainer, PrintTextContainer, ProductComments, ProdcutCommentsContainer, Products, InfoContainer, InsideInfo2, InsideInfo, PrintProductsContainer, PrintProducts } from './styles'
5
+
6
+ export const OrderToPrintTicket = forwardRef((props, ref) => {
7
+ const {
8
+ order,
9
+ getOrderStatus
10
+ } = props
11
+
12
+ const [, t] = useLanguage()
13
+ const [{ configs }] = useConfig();
14
+ const [{ parseDate, parsePrice, parseNumber }] = useUtils()
15
+
16
+ const deliveryStatus = {
17
+ 1: t('DELIVERY', 'Delivery'),
18
+ 2: t('PICK_UP', 'Pick up'),
19
+ 3: t('EAT_IN', 'Eat In'),
20
+ 4: t('CURBSIDE', 'Curbside'),
21
+ 5: t('DRIVER_THRU', 'Driver thru'),
22
+ }
23
+
24
+ const getProductPrice = (product) => {
25
+ let subOptionPrice = 0
26
+ if (Array.isArray(product.options)) {
27
+ if (product.options?.length > 0) {
28
+ for (const option of product.options) {
29
+ for (const suboption of option.suboptions) {
30
+ subOptionPrice += suboption.quantity * suboption.price
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ const price = product.quantity * (product.price + subOptionPrice)
37
+ return parseFloat(price.toFixed(2))
38
+ }
39
+
40
+ const getFormattedSubOptionName = ({ quantity, name, position, price }) => {
41
+ if (name !== 'No') {
42
+ const pos = position && position !== 'whole' ? `(${t(position.toUpperCase(), position)})` : '';
43
+ return pos
44
+ ? `${quantity} x ${name} ${pos} + ${parsePrice(price)}`
45
+ : `${quantity} x ${name} + ${parsePrice(price)}`;
46
+ } else {
47
+ return 'No';
48
+ }
49
+ };
50
+
51
+ const getSuboptions = (suboptions) => {
52
+ const array = []
53
+ suboptions?.length > 0 &&
54
+ suboptions?.map((suboption) => {
55
+ const string = `${getFormattedSubOptionName(suboption)}`
56
+ array.push(string)
57
+ })
58
+
59
+ return array.join('')
60
+ }
61
+
62
+ const getOptions = (options, productComment = '') => {
63
+ const array = [];
64
+
65
+ options?.length &&
66
+ options?.map((option) => {
67
+ const string =
68
+ `${option.name} ${getSuboptions(option.suboptions)}`;
69
+
70
+ array.push(string)
71
+ })
72
+
73
+ if (productComment) {
74
+ array.push(`${t('COMMENT', 'Comment')}${productComment}`)
75
+ }
76
+
77
+ return array
78
+ }
79
+
80
+ const percentTip =
81
+ parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
82
+ !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
83
+ verifyDecimals(order?.summary?.driver_tip, parseNumber);
84
+
85
+ const customerName = `${order?.customer?.name ?? ''} ${order?.customer?.middle_name ?? ''} ${order?.customer?.lastname ?? ''} ${order?.customer?.second_lastname ?? ''}`?.replace(' ', ' ')?.trim() ?? ''
86
+
87
+ return (
88
+ <PrintContainer ref={ref}>
89
+ <h1>{t('ORDER_NO', 'Order No.')} {order.id}</h1>
90
+ <PrintTextContainer>
91
+ {getOrderStatus(order?.status)?.value}
92
+ <br />
93
+ {t('DELIVERY_TYPE', 'Delivery Type')}: {deliveryStatus[order?.delivery_type]}
94
+ <br />
95
+ {t('DELIVERY_DATE', 'Delivery Date')}: {order?.delivery_datetime_utc
96
+ ? parseDate(order?.delivery_datetime_utc)
97
+ : parseDate(order?.delivery_datetime, { utc: false })
98
+ }
99
+ <br />
100
+ {t('PAYMENT_METHOD')}: {order?.paymethod?.name}
101
+ </PrintTextContainer>
102
+
103
+ <h1>{t('CUSTOMER_DETAILS', 'Customer details')}</h1>
104
+ <PrintTextContainer>
105
+ {t('FULL_NAME', 'Full Name')}: {customerName}
106
+ <br/>
107
+ {t('EMAIL', 'Email')}: {order?.customer?.email}
108
+ <br />
109
+ {t('MOBILE_PHONE', 'Mobile Phone')}: {order?.customer?.cellphone}
110
+ <br />
111
+ {!!order?.customer?.phone && (
112
+ t('MOBILE_PHONE', 'Mobile Phone')`: {order?.customer?.phone}`)}
113
+ {t('FULL_ADDRESS', 'Full Addres')}: {order?.customer?.address}
114
+ {!!order?.customer?.internal_number && (
115
+ `${t('INTERNAL_NUMBER', 'Internal Number')}: ${order?.customer?.internal_number}`)}
116
+ <br />
117
+ {!!order?.customer.zipcode && (
118
+ `${t('ZIPCODE', 'Zipcode')}: ${order?.customer.zipcode}`
119
+ )}
120
+ </PrintTextContainer>
121
+
122
+ <h1>{t('BUSINESS_DETAILS', 'Business details')}</h1>
123
+ <PrintTextContainer>
124
+ {order?.business?.name}
125
+ <br />
126
+ {order?.business?.email}
127
+ <br/>
128
+ {!!order?.business?.cellphone && (
129
+ <>
130
+ {`${t('BUSINESS_PHONE', 'Business cellphone')}: ${order?.business?.cellphone}`}
131
+ <br/>
132
+ </>
133
+ )}
134
+ {!!order?.business?.phone && (
135
+ <>
136
+ {`${t('BUSINESS_PHONE', 'Business Phone')}: ${order?.business?.phone}`}
137
+ <br/>
138
+ </>
139
+ )}
140
+ {t('ADDRESS', 'Address')}: {order?.business?.address}
141
+ <br/>
142
+ {!!order?.business?.address_notes && (
143
+ <>
144
+ {`${t('SPECIAL_ADDRESS', 'Special Address')}: ${order?.business?.address_notes}`}
145
+ <br/>
146
+ </>
147
+ )}
148
+ </PrintTextContainer>
149
+ <h1>{t('ORDER_DETAILS', 'Order Details')}</h1>
150
+ <br/>
151
+ <PrintProductsContainer>
152
+ {order?.products?.length &&
153
+ order?.products?.map((product, i) =>
154
+ <PrintProducts key={i}>
155
+ <Products>
156
+ <InsideInfo>
157
+ {`${product?.quantity}x ${product?.name}`}
158
+ </InsideInfo>
159
+ <InsideInfo2>
160
+ {parsePrice(product?.total ?? getProductPrice(product))}
161
+ </InsideInfo2>
162
+ </Products>
163
+ <ProdcutCommentsContainer>
164
+ {getOptions(product?.options, product?.comment)?.map(option => (
165
+ <ProductComments>
166
+ {option}
167
+ </ProductComments>
168
+ ))}
169
+ </ProdcutCommentsContainer>
170
+ </PrintProducts>
171
+ )}
172
+ </PrintProductsContainer>
173
+ <br/>
174
+ <InfoContainer>
175
+ <InsideInfo>
176
+ {t('SUBTOTAL', 'Subtotal')}
177
+ </InsideInfo>
178
+ <InsideInfo2>
179
+ {parsePrice(
180
+ order?.tax_type === 1
181
+ ? order?.summary?.subtotal + order?.summary?.tax ?? 0
182
+ : order?.summary?.subtotal ?? 0,
183
+ )}
184
+ </InsideInfo2>
185
+ </InfoContainer>
186
+ <InfoContainer>
187
+ {order?.summary?.discount > 0
188
+ ? order?.offer_type === 1
189
+ ? <InsideInfo>
190
+ {t('DISCOUNT', 'Discount')} ({verifyDecimals(order?.offer_rate,parsePrice,)}%)
191
+ </InsideInfo>
192
+ : <InsideInfo> {t(
193
+ 'DISCOUNT',
194
+ 'Discount',
195
+ )}
196
+ </InsideInfo>
197
+ : ''
198
+ }
199
+ {order?.summary?.discount > 0
200
+ ? <InsideInfo2>- {parsePrice(
201
+ order?.summary?.discount,
202
+ )}
203
+ </InsideInfo2>
204
+ : ''
205
+ }
206
+ </InfoContainer>
207
+
208
+ {order?.tax_type !== 1 && (
209
+ <>
210
+ <InfoContainer>
211
+ <InsideInfo>
212
+ {t('TAX', 'Tax')}
213
+ {' '}
214
+ {`(${verifyDecimals(order?.summary?.tax_rate, parseNumber)}%)`}
215
+ </InsideInfo>
216
+ <InsideInfo2>
217
+ {parsePrice(order?.summary?.tax ?? 0)}
218
+ </InsideInfo2>
219
+ </InfoContainer>
220
+ </>
221
+ )}
222
+
223
+ {order?.summary?.delivery_price > 0 && (
224
+ <InfoContainer>
225
+ <InsideInfo>
226
+ {t('DELIVERY_FEE','Delivery Fee',)}
227
+ </InsideInfo>
228
+ <InsideInfo2>
229
+ {parsePrice(order?.summary?.delivery_price)}
230
+ </InsideInfo2>
231
+ </InfoContainer>
232
+ )}
233
+
234
+ <InfoContainer>
235
+ <InsideInfo>
236
+ {t('DRIVER_TIP', 'Driver tip')}
237
+ {percentTip ? `(${percentTip}%)` : ''}
238
+ </InsideInfo>
239
+ <InsideInfo2>
240
+ {parsePrice(order?.summary?.driver_tip ?? 0)}
241
+ </InsideInfo2>
242
+ </InfoContainer>
243
+
244
+ <InfoContainer>
245
+ <InsideInfo>
246
+ {t('SERVICE_FEE', 'Service Fee')}
247
+ ({verifyDecimals(order?.summary?.service_fee, parseNumber)}%)
248
+ </InsideInfo>
249
+ <InsideInfo2>
250
+ {parsePrice(order?.summary?.service_fee ?? 0)}
251
+ </InsideInfo2>
252
+ </InfoContainer>
253
+
254
+ <InfoContainer>
255
+ <InsideInfo>
256
+ {t('TOTAL', 'Total')}
257
+ </InsideInfo>
258
+ <InsideInfo2>
259
+ {parsePrice(order?.summary?.total ?? 0)}
260
+ </InsideInfo2>
261
+ </InfoContainer>
262
+ </PrintContainer>
263
+ )
264
+ });
@@ -0,0 +1,68 @@
1
+ import styled from 'styled-components'
2
+
3
+ export const PrintContainer = styled.div`
4
+ display: none;
5
+ font-family: arial !important;
6
+ color: #000 !important;
7
+ padding: 80px 50px;
8
+ max-width: 420px;
9
+
10
+ > h1 {
11
+ font-size: 20px;
12
+ font-weight: 700;
13
+ margin: 0;
14
+ }
15
+
16
+ @media print {
17
+ display: block;
18
+
19
+ @page { size: portrait; }
20
+ }
21
+ `
22
+
23
+ export const PrintTextContainer = styled.p`
24
+ font-size: 16px
25
+ `
26
+ export const PrintProductsContainer = styled.div`
27
+ display: flex;
28
+ flex-direction:column;
29
+ `
30
+
31
+ export const PrintProducts = styled.div`
32
+ display: flex;
33
+ flexDirection:row;
34
+ flex-wrap:wrap;
35
+ `
36
+
37
+ export const Products = styled.div`
38
+ display:flex;
39
+ width:100%;
40
+ `
41
+
42
+ export const ProdcutCommentsContainer = styled.div`
43
+ font-size: 16px;
44
+ width:100%;
45
+ `
46
+
47
+ export const ProductComments = styled.div`
48
+ margin-left: 10px;
49
+ `
50
+
51
+ export const InfoContainer = styled.div`
52
+ display: flex;
53
+ `
54
+
55
+ export const InsideInfo = styled.div`
56
+ display:flex;
57
+ justify-content: flex-start;
58
+ font-size: 16px;
59
+ width: 70%
60
+ font-weight: bold
61
+ `
62
+
63
+ export const InsideInfo2 = styled.div`
64
+ display:flex;
65
+ justify-content: flex-end;
66
+ font-size: 16px;
67
+ width: 30%
68
+ `
@@ -70,6 +70,7 @@ export const OrdersTable = (props) => {
70
70
  getPageOrders(pageSize, expectedPage)
71
71
  }
72
72
  const [configState] = useConfig()
73
+ const isEnabledRowInColor = configState?.configs?.row_in_color_enabled?.value === '1'
73
74
 
74
75
  const optionsDefault = [
75
76
  {
@@ -84,6 +85,10 @@ export const OrdersTable = (props) => {
84
85
  value: 'cartGroupId',
85
86
  content: t('GROUP_ORDER', 'Group Order')
86
87
  },
88
+ {
89
+ value: 'driverGroupId',
90
+ content: t('EXPORT_DRIVER_GROUP_ID', 'Driver Group Id')
91
+ },
87
92
  {
88
93
  value: 'dateTime',
89
94
  content: t('DATE_TIME', 'Date and time')
@@ -498,6 +503,15 @@ export const OrdersTable = (props) => {
498
503
  </StatusInfo>
499
504
  </td>
500
505
  )}
506
+ {allowColumns?.driverGroupId?.visable && (
507
+ <td className='statusInfo'>
508
+ <StatusInfo>
509
+ <div className='info'>
510
+ <p className='bold'><Skeleton width={100} /></p>
511
+ </div>
512
+ </StatusInfo>
513
+ </td>
514
+ )}
501
515
  {allowColumns?.status?.visable && !isSelectedOrders && (
502
516
  <td className='statusInfo'>
503
517
  <StatusInfo>
@@ -597,7 +611,7 @@ export const OrdersTable = (props) => {
597
611
  className={parseInt(orderDetailId) === order.id ? 'active' : ''}
598
612
  onClick={(e) => handleClickOrder(order, e)}
599
613
  data-tour={i === 0 ? 'tour_start' : ''}
600
- data-status={getStatusClassName(getDelayMinutes(order))}
614
+ data-status={isEnabledRowInColor && getStatusClassName(getDelayMinutes(order))}
601
615
  >
602
616
  <tr>
603
617
  {Object.keys(allowColumns).filter(col => allowColumns[col]?.visable)
@@ -679,6 +693,17 @@ export const OrdersTable = (props) => {
679
693
  </td>
680
694
  )
681
695
  }
696
+ if (column === 'driverGroupId') {
697
+ return (
698
+ <td className='orderGroupId' key={`cart_group_id${i}-${index}`}>
699
+ <StatusInfo>
700
+ {order?.driver_group_id && (
701
+ <p className='bold'>{t('No', 'No')}. {order?.driver_group_id}</p>
702
+ )}
703
+ </StatusInfo>
704
+ </td>
705
+ )
706
+ }
682
707
  if (column === 'business') {
683
708
  return (
684
709
  <td className='businessInfo' key={`businessInfo${i}-${index}`}>
@@ -815,7 +840,7 @@ export const OrdersTable = (props) => {
815
840
  )
816
841
  }
817
842
  })}
818
- <td />
843
+ <td />
819
844
  </tr>
820
845
  </OrderTbody>
821
846
  ))
@@ -151,7 +151,7 @@ const DoordashConnectUI = (props) => {
151
151
  {t('DOORDASH_CONNECT_SUPPORT', 'Are you having trouble connecting this, or are you looking to get it elsewhere besides the USA?')}
152
152
  </p>
153
153
  <p>
154
- <a onClick={() => handleGoToLink(t('DOORDASH_CONNECT_SUPPORT_LINK', 'https://www.ordering.co/ordering-support'))}>{t('CONTACT_US', 'Contact us')}</a>; <span>{t('WE_ARE_HAPPY_TO_HELP', 'we are happy to help.')}</span>
154
+ <a onClick={() => handleGoToLink(t('DOORDASH_CONNECT_SUPPORT_LINK', 'https://www.ordering.co/contact-ordering'))}>{t('CONTACT_US', 'Contact us')}</a>; <span>{t('WE_ARE_HAPPY_TO_HELP', 'we are happy to help.')}</span>
155
155
  </p>
156
156
  </Paragraph>
157
157
  <Paragraph>
@@ -164,7 +164,7 @@ const DoordashConnectUI = (props) => {
164
164
  <Button
165
165
  outline
166
166
  color='primary'
167
- onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/ordering-sales'))}
167
+ onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/en-us/contact-ordering'))}
168
168
  >
169
169
  {t('PURCHASE_INTEGRATION', 'Purchase Integration')}
170
170
  </Button>
@@ -163,7 +163,7 @@ const LalaMoveConnectUI = (props) => {
163
163
  <Button
164
164
  outline
165
165
  color='primary'
166
- onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/ordering-sales'))}
166
+ onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/en-us/contact-ordering'))}
167
167
  >
168
168
  {t('PURCHASE_INTEGRATION', 'Purchase Integration')}
169
169
  </Button>
@@ -140,7 +140,7 @@ const PickerExpressUI = (props) => {
140
140
  <p>
141
141
  {t('PICKER_EXPRESS_CONNECT_ARTICLE', 'To connect with Picker Express, you’ll have to use plugins, put in your Picker Express credentials, connect your Picker Express account, and create a driver company inside this dashboard; follow the next article step by step and get this connected in less than 5 minutes.')}
142
142
  </p>
143
- <a onClick={() => handleGoToLink(t('PICKER_EXPRESS_CONNECT_ARTICLE_LINK', 'https://support.ordering.co/hc/en-us/articles/10673894748941'))}>
143
+ <a onClick={() => handleGoToLink(t('PICKER_EXPRESS_CONNECT_ARTICLE_LINK', 'https://support.ordering.co/hc/en-us/articles/13007335725069'))}>
144
144
  {t('VIEW_ARTICLE', 'View Article')}
145
145
  </a>
146
146
  </Paragraph>
@@ -163,7 +163,7 @@ const PickerExpressUI = (props) => {
163
163
  <Button
164
164
  outline
165
165
  color='primary'
166
- onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/ordering-sales'))}
166
+ onClick={() => handleGoToLink(t('PURCHASE_INTEGRATION_LINK', 'https://www.ordering.co/en-us/contact-ordering'))}
167
167
  >
168
168
  {t('PURCHASE_INTEGRATION', 'Purchase Integration')}
169
169
  </Button>
@@ -215,7 +215,7 @@ const SettingsUI = (props) => {
215
215
  >
216
216
  <SettingItemUI
217
217
  title={t('CARD_FIELDS', 'Card fields')}
218
- description={t('CARD_FIELDS_DESC')}
218
+ description={t('CARD_FIELDS_DESC', 'Manage your card fields')}
219
219
  icon={<CreditCard />}
220
220
  active={isOpenSettingDetails === 'card'}
221
221
  />
@@ -206,6 +206,12 @@ const SidebarMenuUI = (props) => {
206
206
  title: t('BRANDS', 'Brands'),
207
207
  pageName: 'brand',
208
208
  url: '/stores/brand'
209
+ },
210
+ {
211
+ id: 4,
212
+ title: t('DEVICES', 'Devices'),
213
+ pageName: 'devices',
214
+ url: '/stores/devices'
209
215
  }
210
216
  ]
211
217
 
@@ -350,12 +356,12 @@ const SidebarMenuUI = (props) => {
350
356
  pageName: 'enterprise_promotions',
351
357
  url: '/marketing/promotions-enterprise'
352
358
  },
353
- {
354
- id: 2,
355
- title: t('CAMPAIGN', 'Campaign'),
356
- pageName: 'campaign',
357
- url: '/marketing/campaign'
358
- },
359
+ // {
360
+ // id: 2,
361
+ // title: t('CAMPAIGN', 'Campaign'),
362
+ // pageName: 'campaign',
363
+ // url: '/marketing/campaign'
364
+ // },
359
365
  {
360
366
  id: 3,
361
367
  title: t('AD_BANNERS', 'Ad banners'),
@@ -42,7 +42,7 @@ export const BusinessDetails = (props) => {
42
42
  <h2>{t('BUSINESS_DETAILS', 'Business details')}</h2>
43
43
  <ContentWrapper>
44
44
  <FormControl>
45
- <label>{t('BUSINESS_NAME', 'Business Name')}<sup>*</sup></label>
45
+ <label>{t('EXPORT_BUSINESS_NAME', 'Business Name')}<sup>*</sup></label>
46
46
  <Input
47
47
  name='name'
48
48
  placeholder={t('NAME', 'Name')}
@@ -0,0 +1,183 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import { useLanguage, BusinessDeviceDetail as BusinessDeviceDetailController } from 'ordering-components-admin-external'
3
+ import { ThreeDots, ArrowsAngleContract, ArrowsAngleExpand } from 'react-bootstrap-icons'
4
+ import { Button, IconButton, DefaultSelect, Input } from '../../../styles'
5
+ import { Select } from '../../../styles/Select/FirstSelect'
6
+ import { useTheme } from 'styled-components'
7
+ import { Alert } from '../../Shared'
8
+ import {
9
+ Container,
10
+ DetailHeder,
11
+ RightHeader,
12
+ ActionSelectorWrapper,
13
+ ActionButtonWrapper,
14
+ FormControl,
15
+ SelectWrapper,
16
+ Option,
17
+ Logo
18
+ } from './styles'
19
+ import Skeleton from 'react-loading-skeleton'
20
+
21
+ const BusinessDeviceDetailUI = (props) => {
22
+ const {
23
+ selectedDevice,
24
+ deleteDevice,
25
+ formState,
26
+ handleChangeFormState,
27
+ businessList,
28
+ updateDevice,
29
+ addDevice
30
+ } = props
31
+
32
+ const [, t] = useLanguage()
33
+ const theme = useTheme()
34
+
35
+ const [isExpand, setIsExpand] = useState(false)
36
+ const [businessOptions, setBusinessOptions] = useState(null)
37
+ const [searchValue, setSearchValue] = useState('')
38
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
39
+
40
+ const moreOptions = [
41
+ { value: 0, content: t('DELETE', 'Delete') }
42
+ ]
43
+
44
+ const expandSideBar = () => {
45
+ const element = document.getElementById('deviceDetails')
46
+ if (!element) return
47
+ if (isExpand) element.style.width = '500px'
48
+ else element.style.width = '100vw'
49
+ setIsExpand(prev => !prev)
50
+ }
51
+
52
+ const closeAlert = () => {
53
+ setAlertState({
54
+ open: false,
55
+ content: []
56
+ })
57
+ }
58
+
59
+ const handleSubmit = () => {
60
+ const errors = []
61
+ if (formState?.changes?.name !== undefined && !formState?.changes?.name) {
62
+ errors.push(t('VALIDATION_ERROR_REQUIRED', 'Name is required').replace('_attribute_', t('NAME', 'Name')))
63
+ }
64
+ if (errors.length > 0) {
65
+ setAlertState({ open: true, content: errors })
66
+ return
67
+ }
68
+ selectedDevice ? updateDevice(selectedDevice?.id) : addDevice()
69
+ }
70
+
71
+ useEffect(() => {
72
+ if (businessList?.loading) return
73
+
74
+ const options = businessList?.businesses
75
+ .filter(option => option?.name.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase()))
76
+ .map(business => ({
77
+ value: business?.id,
78
+ content: <Option><Logo src={business?.logo || theme.images?.dummies?.businessLogo} />{business?.name}</Option>
79
+ }))
80
+ setBusinessOptions(options)
81
+ }, [searchValue, businessList])
82
+
83
+ useEffect(() => {
84
+ if (formState?.result?.error) {
85
+ setAlertState({
86
+ open: true,
87
+ content: formState?.result?.result
88
+ })
89
+ }
90
+ }, [formState?.result])
91
+
92
+ return (
93
+ <Container>
94
+ <DetailHeder>
95
+ <div>
96
+ {selectedDevice?.name && <span>{selectedDevice?.name}</span>}
97
+ {!selectedDevice && (
98
+ <span>{t('ADD_NEW_DEVICE', 'Add new device')}</span>
99
+ )}
100
+ </div>
101
+ <RightHeader>
102
+ <IconButton
103
+ color='black'
104
+ onClick={expandSideBar}
105
+ >
106
+ {isExpand ? <ArrowsAngleContract /> : <ArrowsAngleExpand />}
107
+ </IconButton>
108
+ {selectedDevice && (
109
+ <ActionSelectorWrapper>
110
+ <DefaultSelect
111
+ placeholder={<ThreeDots />}
112
+ options={moreOptions}
113
+ onChange={() => deleteDevice()}
114
+ />
115
+ </ActionSelectorWrapper>
116
+ )}
117
+ </RightHeader>
118
+ </DetailHeder>
119
+ <FormControl>
120
+ <label>{t('NAME', 'Name')}</label>
121
+ <Input
122
+ value={formState?.changes?.name ?? selectedDevice?.name}
123
+ onChange={(e) => handleChangeFormState({ name: e.target.value })}
124
+ />
125
+ </FormControl>
126
+ <SelectWrapper>
127
+ <label>{t('BUSINESS', 'Business')}</label>
128
+ {businessList?.loading ? (
129
+ <Skeleton height={44} />
130
+ ) : (
131
+ <Select
132
+ options={businessOptions}
133
+ className='select'
134
+ defaultValue={formState?.changes?.business_id ?? selectedDevice?.business_id}
135
+ placeholder={t('SELECT_OPTION', 'Select an option')}
136
+ onChange={(value) => handleChangeFormState({ business_id: value })}
137
+ isShowSearchBar
138
+ searchBarIsCustomLayout
139
+ searchBarIsNotLazyLoad
140
+ searchValue={searchValue}
141
+ handleChangeSearch={(val) => setSearchValue(val)}
142
+ />
143
+ )}
144
+ </SelectWrapper>
145
+ {selectedDevice && (
146
+ <FormControl>
147
+ <label>{t('DEVICE_CODE', 'Device Code')}</label>
148
+ <Input
149
+ value={formState?.changes?.code ?? selectedDevice?.code}
150
+ onChange={(e) => handleChangeFormState({ code: e.target.value })}
151
+ disabled
152
+ />
153
+ </FormControl>
154
+ )}
155
+ <ActionButtonWrapper>
156
+ <Button
157
+ color='primary'
158
+ onClick={handleSubmit}
159
+ >
160
+ {t('SAVE', 'Save')}
161
+ </Button>
162
+ </ActionButtonWrapper>
163
+ <Alert
164
+ title={t('DEVICES', 'Devices')}
165
+ content={alertState.content}
166
+ acceptText={t('ACCEPT', 'Accept')}
167
+ open={alertState.open}
168
+ onClose={() => closeAlert()}
169
+ onAccept={() => closeAlert()}
170
+ closeOnBackdrop={false}
171
+ />
172
+ </Container>
173
+ )
174
+ }
175
+
176
+ export const BusinessDeviceDetail = (props) => {
177
+ const businessDeviceDetailProps = {
178
+ ...props,
179
+ UIComponent: BusinessDeviceDetailUI,
180
+ propsToFetch: ['id', 'name', 'logo']
181
+ }
182
+ return <BusinessDeviceDetailController {...businessDeviceDetailProps} />
183
+ }