ordering-ui-admin-external 1.8.5 → 1.9.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 (109) hide show
  1. package/_bundles/{ordering-ui-admin.66a745752c35fb204c80.js → ordering-ui-admin.46b3298439d9527907e3.js} +2 -2
  2. package/_bundles/{ordering-ui-admin.66a745752c35fb204c80.js.LICENSE.txt → ordering-ui-admin.46b3298439d9527907e3.js.LICENSE.txt} +0 -0
  3. package/_modules/components/MyProducts/OrderingWebsite/index.js +50 -8
  4. package/_modules/components/Settings/Deliverect/index.js +103 -0
  5. package/_modules/components/Settings/Deliverect/styles.js +115 -0
  6. package/_modules/components/Settings/IntegrationListing/index.js +41 -2
  7. package/_modules/components/Settings/IntegrationListing/styles.js +7 -4
  8. package/_modules/components/Settings/ItsaCheckmate/index.js +112 -0
  9. package/_modules/components/Settings/ItsaCheckmate/styles.js +118 -0
  10. package/_modules/components/Settings/PickerExpress/index.js +178 -0
  11. package/_modules/components/Settings/PickerExpress/styles.js +111 -0
  12. package/_modules/components/Stores/BusinessAdd/BusinessDetails/index.js +95 -0
  13. package/_modules/components/Stores/BusinessAdd/BusinessDetails/styles.js +43 -0
  14. package/_modules/components/Stores/BusinessAdd/DeliveryZone/index.js +233 -0
  15. package/_modules/components/Stores/BusinessAdd/DeliveryZone/styles.js +40 -0
  16. package/_modules/components/Stores/BusinessAdd/Images/index.js +181 -0
  17. package/_modules/components/Stores/BusinessAdd/Images/styles.js +42 -0
  18. package/_modules/components/Stores/BusinessAdd/OrderTypePriceLevel/index.js +53 -0
  19. package/_modules/components/Stores/BusinessAdd/OrderTypePriceLevel/styles.js +31 -0
  20. package/_modules/components/Stores/BusinessAdd/OtherDetails/index.js +43 -0
  21. package/_modules/components/Stores/BusinessAdd/OtherDetails/styles.js +25 -0
  22. package/_modules/components/Stores/BusinessAdd/PaymentMethods/index.js +48 -0
  23. package/_modules/components/Stores/BusinessAdd/PaymentMethods/styles.js +31 -0
  24. package/_modules/components/Stores/BusinessAdd/Photos/index.js +174 -0
  25. package/_modules/components/Stores/BusinessAdd/Photos/styles.js +46 -0
  26. package/_modules/components/Stores/BusinessAdd/ReceiveOrders/index.js +48 -0
  27. package/_modules/components/Stores/BusinessAdd/ReceiveOrders/styles.js +24 -0
  28. package/_modules/components/Stores/BusinessAdd/Schedule/index.js +31 -0
  29. package/_modules/components/Stores/BusinessAdd/Schedule/styles.js +14 -0
  30. package/_modules/components/Stores/BusinessAdd/index.js +170 -0
  31. package/_modules/components/Stores/BusinessAdd/styles.js +29 -0
  32. package/_modules/components/Stores/BusinessDeliveryDetails/styles.js +1 -1
  33. package/_modules/components/Stores/BusinessDeliveryPickupMore/index.js +4 -0
  34. package/_modules/components/Stores/BusinessDeliveryZoneInformation/index.js +1 -1
  35. package/_modules/components/Stores/BusinessPickupDetails/styles.js +1 -1
  36. package/_modules/components/Stores/BusinessProductAddForm/index.js +4 -4
  37. package/_modules/components/Stores/BusinessProductsCategoyInfo/index.js +1 -6
  38. package/_modules/components/Stores/BusinessProductsListing/index.js +38 -14
  39. package/_modules/components/Stores/BusinessesList/index.js +3 -2
  40. package/_modules/components/Stores/BusinessesListing/index.js +51 -26
  41. package/_modules/components/Stores/BusinessesListing/styles.js +22 -15
  42. package/_modules/components/Stores/BusinessesListingHeader/index.js +6 -5
  43. package/_modules/components/Stores/ProductStartGuide/index.js +69 -0
  44. package/_modules/components/Stores/ProductStartGuide/styles.js +28 -0
  45. package/_modules/components/Stores/ProductStep/index.js +92 -0
  46. package/_modules/components/Stores/ProductStep/styles.js +18 -0
  47. package/_modules/components/Stores/RestaurantSelectGuide/index.js +104 -0
  48. package/_modules/components/Stores/RestaurantSelectGuide/styles.js +44 -0
  49. package/_modules/components/Stores/index.js +7 -0
  50. package/_modules/index.js +6 -0
  51. package/index-template.js +64 -2
  52. package/package.json +2 -2
  53. package/src/components/MyProducts/OrderingWebsite/index.js +45 -3
  54. package/src/components/Settings/Deliverect/index.js +149 -0
  55. package/src/components/Settings/Deliverect/styles.js +344 -0
  56. package/src/components/Settings/IntegrationListing/index.js +46 -12
  57. package/src/components/Settings/IntegrationListing/styles.js +7 -1
  58. package/src/components/Settings/ItsaCheckmate/index.js +170 -0
  59. package/src/components/Settings/ItsaCheckmate/styles.js +366 -0
  60. package/src/components/Settings/PickerExpress/index.js +222 -0
  61. package/src/components/Settings/PickerExpress/styles.js +330 -0
  62. package/src/components/Stores/BusinessAdd/BusinessDetails/index.js +106 -0
  63. package/src/components/Stores/BusinessAdd/BusinessDetails/styles.js +107 -0
  64. package/src/components/Stores/BusinessAdd/DeliveryZone/index.js +250 -0
  65. package/src/components/Stores/BusinessAdd/DeliveryZone/styles.js +101 -0
  66. package/src/components/Stores/BusinessAdd/Images/index.js +168 -0
  67. package/src/components/Stores/BusinessAdd/Images/styles.js +94 -0
  68. package/src/components/Stores/BusinessAdd/OrderTypePriceLevel/index.js +43 -0
  69. package/src/components/Stores/BusinessAdd/OrderTypePriceLevel/styles.js +70 -0
  70. package/src/components/Stores/BusinessAdd/OtherDetails/index.js +51 -0
  71. package/src/components/Stores/BusinessAdd/OtherDetails/styles.js +49 -0
  72. package/src/components/Stores/BusinessAdd/PaymentMethods/index.js +39 -0
  73. package/src/components/Stores/BusinessAdd/PaymentMethods/styles.js +46 -0
  74. package/src/components/Stores/BusinessAdd/Photos/index.js +156 -0
  75. package/src/components/Stores/BusinessAdd/Photos/styles.js +108 -0
  76. package/src/components/Stores/BusinessAdd/ReceiveOrders/index.js +46 -0
  77. package/src/components/Stores/BusinessAdd/ReceiveOrders/styles.js +69 -0
  78. package/src/components/Stores/BusinessAdd/Schedule/index.js +23 -0
  79. package/src/components/Stores/BusinessAdd/Schedule/styles.js +14 -0
  80. package/src/components/Stores/BusinessAdd/index.js +184 -0
  81. package/src/components/Stores/BusinessAdd/styles.js +85 -0
  82. package/src/components/Stores/BusinessDeliveryDetails/styles.js +1 -0
  83. package/src/components/Stores/BusinessDeliveryPickupMore/index.js +9 -1
  84. package/src/components/Stores/BusinessDeliveryZoneInformation/index.js +8 -10
  85. package/src/components/Stores/BusinessPickupDetails/styles.js +1 -0
  86. package/src/components/Stores/BusinessProductAddForm/index.js +1 -1
  87. package/src/components/Stores/BusinessProductsCategoyInfo/index.js +4 -7
  88. package/src/components/Stores/BusinessProductsListing/index.js +20 -0
  89. package/src/components/Stores/BusinessesList/index.js +3 -2
  90. package/src/components/Stores/BusinessesListing/index.js +101 -67
  91. package/src/components/Stores/BusinessesListing/styles.js +36 -0
  92. package/src/components/Stores/BusinessesListingHeader/index.js +58 -51
  93. package/src/components/Stores/ProductStartGuide/index.js +60 -0
  94. package/src/components/Stores/ProductStartGuide/styles.js +62 -0
  95. package/src/components/Stores/ProductStep/index.js +84 -0
  96. package/src/components/Stores/ProductStep/styles.js +29 -0
  97. package/src/components/Stores/RestaurantSelectGuide/index.js +119 -0
  98. package/src/components/Stores/RestaurantSelectGuide/styles.js +150 -0
  99. package/src/components/Stores/index.js +2 -0
  100. package/src/index.js +2 -0
  101. package/template/app.js +4 -0
  102. package/template/assets/images/dummies/no-businesses.png +0 -0
  103. package/template/assets/images/import-menu.png +0 -0
  104. package/template/assets/images/imported-menu.png +0 -0
  105. package/template/assets/images/picker-express.png +0 -0
  106. package/template/components/ListenPageChanges/index.js +1 -0
  107. package/template/config.json +1 -1
  108. package/template/helmetdata.json +7 -0
  109. package/template/pages/BusinessAdd/index.js +11 -0
@@ -0,0 +1,107 @@
1
+ import styled, { css } from 'styled-components'
2
+ import { darken } from 'polished'
3
+
4
+ export const BusinessDetailsContainer = styled.div`
5
+ h2 {
6
+ font-weight: 600;
7
+ font-size: 16px;
8
+ line-height: 24px;
9
+ margin: 0;
10
+ }
11
+ `
12
+
13
+ export const ContentWrapper = styled.div`
14
+ margin-top: 23px;
15
+ `
16
+
17
+ export const FormControl = styled.div`
18
+ margin-bottom: 23px;
19
+ label {
20
+ font-weight: 400;
21
+ font-size: 14px;
22
+ line-height: 24px;
23
+ margin-bottom: 12px;
24
+ }
25
+ input {
26
+ width: 100%;
27
+ height: 44px;
28
+ }
29
+ .input-autocomplete {
30
+ width: 100%;
31
+ background: ${props => props.theme.colors?.backgroundPage || '#FFF'};
32
+ border: 1px solid ${props => props.theme.colors.borderColor};
33
+ border-radius: 8px;
34
+ font-size: 14px;
35
+ padding: 10px 15px;
36
+ outline: none;
37
+ ::placeholder {
38
+ color: ${props => props.theme.colors.secundaryLight};
39
+ }
40
+
41
+ &:-ms-input-placeholder {
42
+ color: ${props => props.theme.colors.secundaryLight};
43
+ }
44
+
45
+ &::-ms-input-placeholder { /* Microsoft Edge */
46
+ color: ${props => props.theme.colors.secundaryLight};
47
+ }
48
+ &:focus {
49
+ border-color: ${() => darken(0.07, '#CCC')};
50
+ }
51
+ }
52
+
53
+ ${({ noBottom }) => noBottom && css`
54
+ margin-bottom: 0px;
55
+ `}
56
+ `
57
+
58
+ export const GoogleMapContainer = styled.div`
59
+ margin-bottom: 23px;
60
+ label {
61
+ font-weight: 400;
62
+ font-size: 14px;
63
+ line-height: 24px;
64
+ margin-bottom: 12px;
65
+ margin-bottom: 9px;
66
+ }
67
+ p {
68
+ font-weight: 400;
69
+ font-size: 14px;
70
+ line-height: 24px;
71
+ margin: 0;
72
+ color: ${props => props.theme.colors.lightGray};
73
+ }
74
+ `
75
+
76
+ export const WrapperMap = styled.div`
77
+ width: 100%;
78
+ height: 150px;
79
+ margin-top: 30px;
80
+
81
+ > div {
82
+ position: relative !important;
83
+ width: 100% !important;
84
+ height: 100% !important;
85
+ border-radius: 8px;
86
+ }
87
+
88
+ @media (min-width: 768px) {
89
+ height: 200px;
90
+ }
91
+ `
92
+
93
+ export const FormGroup = styled.div`
94
+ display: flex;
95
+ justify-content: space-between;
96
+ flex-direction: column;
97
+ > div {
98
+ width: 100%;
99
+ }
100
+
101
+ @media (min-width: 576px) {
102
+ flex-direction: row;
103
+ > div {
104
+ width: 48%;
105
+ }
106
+ }
107
+ `
@@ -0,0 +1,250 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import { useConfig, useLanguage, useUtils, BusinessZoneGoogleMaps } from 'ordering-components-admin-external'
3
+ import { Select } from '../../../../styles/Select/FirstSelect'
4
+ import { Input } from '../../../../styles'
5
+ import { Alert } from '../../../Shared'
6
+
7
+ import {
8
+ DeliveryZoneContainer,
9
+ TypeSelectWrapper,
10
+ WrapperMap,
11
+ ErrorText,
12
+ FormControl,
13
+ Row
14
+ } from './styles'
15
+
16
+ export const DeliveryZone = (props) => {
17
+ const {
18
+ formState,
19
+ zoneState,
20
+ handleChangeZoneState,
21
+ // handleUploadKmlFiles,
22
+ kmlData
23
+ } = props
24
+
25
+ const [, t] = useLanguage()
26
+ const [{ parseNumber }] = useUtils()
27
+ const [configState] = useConfig()
28
+ const [clearState, setClearState] = useState(false)
29
+ const [infoContentString, setInfoContentString] = useState('')
30
+ const [zoneType, setZoneType] = useState(2)
31
+ const [zoneData, setZoneData] = useState()
32
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
33
+ const [isShowMap, setIsShowMap] = useState(false)
34
+ // const kmlRef = useRef(null)
35
+
36
+ const typeOptions = [
37
+ { value: 1, content: t('CIRCLE', 'Circle') },
38
+ { value: 2, content: t('POLYGON', 'Polygon') },
39
+ { value: 4, content: t('EVERYWHERE', 'Everywhere') },
40
+ { value: 5, content: t('DISTANCE_BASED', 'Distance based') }
41
+ ]
42
+
43
+ const googleMapsControls = {
44
+ defaultZoom: 8,
45
+ zoomControl: true,
46
+ streetViewControl: false,
47
+ fullscreenControl: false,
48
+ mapTypeId: 'roadmap', // 'roadmap', 'satellite', 'hybrid', 'terrain'
49
+ mapTypeControl: false,
50
+ mapTypeControlOptions: {
51
+ mapTypeIds: ['roadmap', 'satellite']
52
+ },
53
+ isMarkerDraggable: false,
54
+ defaultPosition: { lat: 40.77473399999999, lng: -73.9653844 }
55
+ }
56
+
57
+ const fillStyle = {
58
+ fillColor: '#2C7BE5',
59
+ strokeColor: '#03459E',
60
+ fillOpacity: 0.2,
61
+ strokeWeight: 2,
62
+ editable: true
63
+ }
64
+
65
+ const greenFillStyle = {
66
+ fillColor: '#008000',
67
+ fillOpacity: 0.3,
68
+ strokeColor: '#008000',
69
+ strokeOpacity: 0.8,
70
+ strokeWeight: 2
71
+ }
72
+
73
+ const handleChangeType = (type) => {
74
+ handleChangeZoneState({ type: type }, true)
75
+ setClearState(true)
76
+ setZoneType(type)
77
+ }
78
+
79
+ const handleZoneData = (data) => {
80
+ setZoneData(data)
81
+ handleChangeZoneState({ data: data }, true)
82
+ }
83
+
84
+ // const onSubmit = () => {
85
+ // if (zoneState.changes?.data || zoneType === 4) {
86
+ // handleAddBusinessDeliveryZone()
87
+ // } else {
88
+ // setAlertState({
89
+ // open: true,
90
+ // content: t('REQUIRED_POLYGON_CIRCLE', 'Add a distance based or draw a polygon or circle.')
91
+ // })
92
+ // }
93
+ // }
94
+
95
+ const closeAlert = () => {
96
+ setAlertState({
97
+ open: false,
98
+ content: []
99
+ })
100
+ }
101
+
102
+ useEffect(() => {
103
+ if (clearState) {
104
+ handleZoneData(null)
105
+ }
106
+ }, [clearState])
107
+
108
+ useEffect(() => {
109
+ if (zoneType === 2 || zoneType === 4) return
110
+ let content = '<div style="width: 90px; height: 30px">' + '<span>Radius: </span>'
111
+ content += parseNumber(zoneData?.radio || zoneData?.distance)
112
+ content += `<span>${zoneType === 5 ? configState?.configs?.distance_unit?.value : 'km'}</span>` + '</div>'
113
+ setInfoContentString(content)
114
+ }, [zoneData, zoneType])
115
+
116
+ useEffect(() => {
117
+ if (zoneType === 4) setIsShowMap(false)
118
+ else setIsShowMap(true)
119
+ }, [zoneType])
120
+
121
+ return (
122
+ <>
123
+ <DeliveryZoneContainer autoComplete='off'>
124
+ <h2>{t('LETS_CREATE_YOUR_FIRST_DELIVERY_ZONE', 'Let’s create your first Delivery Zone')}</h2>
125
+ <Row>
126
+ <FormControl>
127
+ <label>{t('NAME', 'Name')}</label>
128
+ <Input
129
+ placeholder={t('NAME', 'Name')}
130
+ name='name'
131
+ value={zoneState?.name ?? ''}
132
+ onChange={(e) => handleChangeZoneState(e)}
133
+ />
134
+ </FormControl>
135
+ <FormControl>
136
+ <label>{t('TYPE', 'Type')}</label>
137
+ <TypeSelectWrapper>
138
+ <Select
139
+ defaultValue={parseInt(zoneState?.type || zoneType)}
140
+ options={typeOptions}
141
+ onChange={handleChangeType}
142
+ />
143
+ </TypeSelectWrapper>
144
+ </FormControl>
145
+ </Row>
146
+ <Row>
147
+ <FormControl>
148
+ <label>{t('MINIMUN_PURCHASED', 'Minimum purchase')}</label>
149
+ <Input
150
+ placeholder='$0.00'
151
+ name='minimum'
152
+ value={zoneState?.minimum ?? ''}
153
+ onChange={(e) => handleChangeZoneState(e)}
154
+ />
155
+ </FormControl>
156
+ <FormControl>
157
+ <label>{t('DELIVERY_FEE', 'Delivery fee')}</label>
158
+ <Input
159
+ placeholder='$0.00'
160
+ name='price'
161
+ value={zoneState?.price ?? ''}
162
+ onChange={(e) => handleChangeZoneState(e)}
163
+ />
164
+ </FormControl>
165
+ </Row>
166
+ {zoneType === 5 &&
167
+ <Row>
168
+ <FormControl>
169
+ <label>{t('DISTANCE_FROM_STORE', 'Distance from store')}</label>
170
+ <Input
171
+ placeholder={`1 - 99 ${configState?.configs?.distance_unit?.value}`}
172
+ name='distance'
173
+ maxLength={2}
174
+ value={zoneState?.data?.distance ?? ''}
175
+ onInput={(e) => {
176
+ e.target.value = e.target.value.match('^[1-9]{1,2}$')
177
+ }}
178
+ onChange={e => handleChangeZoneState(e, false, configState?.configs?.distance_unit?.value)}
179
+ />
180
+ </FormControl>
181
+ </Row>}
182
+ <FormControl>
183
+ <label>{t('BUSINESS_ADDRESS', 'Business address')}</label>
184
+ <Input
185
+ name='address'
186
+ defaultValue={formState?.changes?.address}
187
+ disabled
188
+ />
189
+ </FormControl>
190
+ {zoneType !== 4 && isShowMap && (
191
+ configState?.configs?.google_maps_api_key?.value ? (
192
+ <WrapperMap>
193
+ {zoneType !== 5 &&
194
+ <button
195
+ type='button'
196
+ onClick={() => setClearState(true)}
197
+ >
198
+ {t('CLEAR', 'Clear')}
199
+ </button>}
200
+ <BusinessZoneGoogleMaps
201
+ distance={zoneState?.data?.distance}
202
+ disabled
203
+ apiKey={configState?.configs?.google_maps_api_key?.value}
204
+ mapControls={googleMapsControls}
205
+ clearState={clearState}
206
+ setClearState={setClearState}
207
+ type={zoneType}
208
+ data={zoneState?.data || zoneData}
209
+ handleData={handleZoneData}
210
+ fillStyle={fillStyle}
211
+ infoContentString={infoContentString}
212
+ greenFillStyle={greenFillStyle}
213
+ kmlData={kmlData}
214
+ />
215
+ </WrapperMap>
216
+ ) : (
217
+ <ErrorText>{t('REQUIRED_GOOGLE_MAP_API_KEY', 'Google Maps api key is required')}</ErrorText>
218
+ )
219
+ )}
220
+ {/* {(zoneType !== 5) && (
221
+ <KmlButtonWrapper>
222
+ <Button
223
+ color='primary'
224
+ borderRadius='8px'
225
+ type='button'
226
+ onClick={() => kmlRef.current.click()}
227
+ >
228
+ <ExamineClick
229
+ onFiles={files => handleUploadKmlFiles(files)}
230
+ childRef={e => { kmlRef.current = e }}
231
+ accept='.kml,.kmz'
232
+ >
233
+ <span>{t('UPLOAD_KML', 'Upload KML')}</span>
234
+ </ExamineClick>
235
+ </Button>
236
+ </KmlButtonWrapper>
237
+ )} */}
238
+ </DeliveryZoneContainer>
239
+ <Alert
240
+ title={t('WEB_APPNAME', 'Ordering')}
241
+ content={alertState.content}
242
+ acceptText={t('ACCEPT', 'Accept')}
243
+ open={alertState.open}
244
+ onClose={() => closeAlert()}
245
+ onAccept={() => closeAlert()}
246
+ closeOnBackdrop={false}
247
+ />
248
+ </>
249
+ )
250
+ }
@@ -0,0 +1,101 @@
1
+ import styled, { css } from 'styled-components'
2
+
3
+ export const DeliveryZoneContainer = styled.div`
4
+ display: flex;
5
+ flex-direction: column;
6
+ min-height: calc(100% - 130px);
7
+
8
+ h2 {
9
+ font-weight: 600;
10
+ font-size: 16px;
11
+ line-height: 24px;
12
+ margin-bottom: 23px;
13
+ }
14
+ `
15
+
16
+ export const TypeSelectWrapper = styled.div`
17
+ .select {
18
+ background: ${props => props.theme.colors.secundary};
19
+ width: 100%;
20
+ border: none;
21
+ font-size: 14px;
22
+ color: ${props => props.theme.colors.headingColor};
23
+ > div:first-child {
24
+ padding-top: 4px;
25
+ padding-bottom: 4px;
26
+ }
27
+ }
28
+ `
29
+
30
+ export const WrapperMap = styled.div`
31
+ width: 100%;
32
+ height: 300px;
33
+ display: flex;
34
+ justify-content: center;
35
+ box-sizing: border-box;
36
+ margin: 29px 0 20px 0;
37
+ position: relative;
38
+ > div {
39
+ position: relative !important;
40
+ width: 100% !important;
41
+ height: 100% !important;
42
+ border-radius: 8px;
43
+ }
44
+
45
+ > button {
46
+ position: absolute;
47
+ font-size: 14px;
48
+ padding: 0 5px;
49
+ background: ${props => props.theme.colors?.backgroundPage || '#FFF'};
50
+ top: 10px;
51
+ z-index: 10;
52
+ border: none;
53
+ box-shadow: rgb(0 0 0 / 30%) 0px 1px 4px;
54
+ color: ${props => props.theme.colors.headingColor};
55
+ ${props => props.theme?.rtl ? css`
56
+ right: 10px;
57
+ ` : css`
58
+ left: 10px;
59
+ `}
60
+ &:hover {
61
+ background: #eee;
62
+ }
63
+ }
64
+ `
65
+
66
+ export const ErrorText = styled.div`
67
+ font-size: 14px;
68
+ color: ${props => props.theme.colors.lightGray};
69
+ text-align: center;
70
+ margin: 20px 0;
71
+ `
72
+ export const FormControl = styled.div`
73
+ display: flex;
74
+ flex-direction: column;
75
+ label {
76
+ font-size: 14px;
77
+ margin-bottom: 9px;
78
+ }
79
+ input {
80
+ width: 100%;
81
+ }
82
+ `
83
+ export const Row = styled.div`
84
+ display: flex;
85
+ justify-content: space-between;
86
+ flex-direction: column;
87
+
88
+ > div {
89
+ width: 100%;
90
+ margin-bottom: 29px;
91
+ }
92
+ @media (min-width: 576px) {
93
+ flex-direction: row;
94
+ > div {
95
+ width: 45%;
96
+ }
97
+ }
98
+ `
99
+ export const KmlButtonWrapper = styled.div`
100
+ margin: 20px 0px;
101
+ `
@@ -0,0 +1,168 @@
1
+ import React, { useRef, useState } from 'react'
2
+ import { ExamineClick, useLanguage, DragAndDrop } from 'ordering-components-admin-external'
3
+ import { bytesConverter } from '../../../../utils'
4
+ import { Alert, Modal, ImageCrop } from '../../../Shared'
5
+ import { Image as DumyPhoto } from 'react-bootstrap-icons'
6
+ import {
7
+ ImagesContainer,
8
+ ImageFormGroup,
9
+ LogoImage,
10
+ BackgroundImage,
11
+ UploadImageIconContainer,
12
+ UploadImageIcon,
13
+ ImgInfoWrapper
14
+ } from './styles'
15
+
16
+ export const Images = (props) => {
17
+ const {
18
+ formState,
19
+ handleChangeSwtich
20
+ } = props
21
+
22
+ const [, t] = useLanguage()
23
+
24
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
25
+ const [cropState, setCropState] = useState({ name: null, data: null, open: false })
26
+
27
+ const logoRef = useRef(null)
28
+ const backgroundRef = useRef(null)
29
+
30
+ const handleClickImage = (type) => {
31
+ if (type === 'logo') {
32
+ logoRef.current.click()
33
+ }
34
+
35
+ if (type === 'header') {
36
+ backgroundRef.current.click()
37
+ }
38
+ }
39
+
40
+ const handleFiles = (files, name) => {
41
+ if (files.length === 1) {
42
+ const type = files[0].type.split('/')[0]
43
+ if (type !== 'image') {
44
+ setAlertState({
45
+ open: true,
46
+ content: [t('ERROR_ONLY_IMAGES', 'Only images can be accepted')]
47
+ })
48
+ return
49
+ }
50
+
51
+ if (bytesConverter(files[0]?.size) > 2048) {
52
+ setAlertState({
53
+ open: true,
54
+ content: [t('IMAGE_MAXIMUM_SIZE', 'The maximum image size is 2 megabytes')]
55
+ })
56
+ return
57
+ }
58
+ const reader = new window.FileReader()
59
+ reader.readAsDataURL(files[0])
60
+ reader.onload = () => {
61
+ setCropState({ name: name, data: reader.result, open: true })
62
+ }
63
+ reader.onerror = error => console.log(error)
64
+ }
65
+ }
66
+
67
+ const closeAlert = () => {
68
+ setAlertState({
69
+ open: false,
70
+ content: []
71
+ })
72
+ }
73
+
74
+ const handleChangePhoto = (croppedImg) => {
75
+ handleChangeSwtich(cropState?.name, croppedImg)
76
+ setCropState({ name: null, data: null, open: false })
77
+ }
78
+
79
+ return (
80
+ <>
81
+ <ImagesContainer>
82
+ <h2>{t('IMAGES', 'Images')}</h2>
83
+ <ImageFormGroup>
84
+ <LogoImage
85
+ onClick={() => handleClickImage('logo')}
86
+ >
87
+ <ExamineClick
88
+ onFiles={files => handleFiles(files, 'logo')}
89
+ childRef={(e) => { logoRef.current = e }}
90
+ accept='image/png, image/jpeg, image/jpg'
91
+ >
92
+ <DragAndDrop
93
+ onDrop={dataTransfer => handleFiles(dataTransfer.files, 'logo')}
94
+ accept='image/png, image/jpeg, image/jpg'
95
+ disabled={formState.loading}
96
+ >
97
+ {formState?.changes?.logo && <img src={formState?.changes?.logo} alt='logo image' loading='lazy' />}
98
+ <UploadImageIconContainer bgimage={formState?.changes?.logo}>
99
+ <UploadImageIcon>
100
+ <DumyPhoto />
101
+ <span>{t('DRAG_AND_DROP', 'Drag and drop')}</span>
102
+ </UploadImageIcon>
103
+ </UploadImageIconContainer>
104
+ </DragAndDrop>
105
+ </ExamineClick>
106
+ </LogoImage>
107
+ <ImgInfoWrapper>
108
+ <h4>{t('BUSINESS_LOGO', 'Business Logo')}</h4>
109
+ <p>512 x 512 px</p>
110
+ <p>{t('FORMAT', 'Format')}: PNG, JPG</p>
111
+ </ImgInfoWrapper>
112
+ </ImageFormGroup>
113
+ <ImageFormGroup>
114
+ <BackgroundImage
115
+ onClick={() => handleClickImage('header')}
116
+ >
117
+ <ExamineClick
118
+ onFiles={files => handleFiles(files, 'header')}
119
+ childRef={(e) => { backgroundRef.current = e }}
120
+ accept='image/png, image/jpeg, image/jpg'
121
+ >
122
+ <DragAndDrop
123
+ onDrop={dataTransfer => handleFiles(dataTransfer.files, 'header')}
124
+ accept='image/png, image/jpeg, image/jpg'
125
+ disabled={formState.loading}
126
+ >
127
+ {formState?.changes?.header && <img src={formState?.changes?.header} alt='backgrond image' loading='lazy' />}
128
+ <UploadImageIconContainer bgimage={!!formState?.changes?.header}>
129
+ <UploadImageIcon>
130
+ <DumyPhoto />
131
+ <span>{t('DRAG_AND_DROP', 'Drag and drop')}</span>
132
+ </UploadImageIcon>
133
+ </UploadImageIconContainer>
134
+ </DragAndDrop>
135
+ </ExamineClick>
136
+ </BackgroundImage>
137
+ <ImgInfoWrapper>
138
+ <h4>{t('HOMEPAGE_BACKGROUND', 'Business Header')}</h4>
139
+ <p>1350 x 400 px</p>
140
+ <p>{t('FORMAT', 'Format')}: PNG, JPG</p>
141
+ </ImgInfoWrapper>
142
+ </ImageFormGroup>
143
+ </ImagesContainer>
144
+ <Alert
145
+ title={t('ORDERING', 'Ordering')}
146
+ content={alertState.content}
147
+ acceptText={t('ACCEPT', 'Accept')}
148
+ open={alertState.open}
149
+ onClose={() => closeAlert()}
150
+ onAccept={() => closeAlert()}
151
+ closeOnBackdrop={false}
152
+ />
153
+ <Modal
154
+ width='700px'
155
+ height='80vh'
156
+ padding='30px'
157
+ title={t('IMAGE_CROP', 'Image crop')}
158
+ open={cropState?.open}
159
+ onClose={() => setCropState({ ...cropState, open: false })}
160
+ >
161
+ <ImageCrop
162
+ photo={cropState?.data}
163
+ handleChangePhoto={handleChangePhoto}
164
+ />
165
+ </Modal>
166
+ </>
167
+ )
168
+ }