@popsure/dirty-swan 0.26.10 → 0.26.11

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 (230) hide show
  1. package/package.json +2 -1
  2. package/src/App.tsx +50 -0
  3. package/src/bin/index.ts +71 -0
  4. package/src/bin/tsconfig.json +13 -0
  5. package/src/bin/util/index.test.ts +85 -0
  6. package/src/bin/util/index.ts +132 -0
  7. package/src/bin/util/test/data.json +13 -0
  8. package/src/colors.scss +1 -0
  9. package/src/font-weight.scss +1 -0
  10. package/src/grid.scss +1 -0
  11. package/src/index.tsx +37 -0
  12. package/src/intro.stories.mdx +41 -0
  13. package/src/lib/components/autocompleteAddress/demo.tsx +38 -0
  14. package/src/lib/components/autocompleteAddress/index.stories.mdx +44 -0
  15. package/src/lib/components/autocompleteAddress/index.tsx +316 -0
  16. package/src/lib/components/autocompleteAddress/mapStyle.ts +187 -0
  17. package/src/lib/components/autocompleteAddress/style.module.scss +82 -0
  18. package/src/lib/components/autocompleteAddress/util/index.test.ts +51 -0
  19. package/src/lib/components/autocompleteAddress/util/index.ts +55 -0
  20. package/src/lib/components/button/icons/index.ts +14 -0
  21. package/src/lib/components/button/icons/send-purple.svg +4 -0
  22. package/src/lib/components/button/icons/send-white.svg +4 -0
  23. package/src/lib/components/button/index.stories.mdx +121 -0
  24. package/src/lib/components/button/index.tsx +64 -0
  25. package/src/lib/components/button/styles.module.scss +5 -0
  26. package/src/lib/components/cards/a.stories.mdx +44 -0
  27. package/src/lib/components/cards/cardButton/index.stories.mdx +47 -0
  28. package/src/lib/components/cards/cardButton/index.tsx +61 -0
  29. package/src/lib/components/cards/cardButton/style.module.scss +33 -0
  30. package/src/lib/components/cards/cardWithLeftIcon/index.stories.mdx +103 -0
  31. package/src/lib/components/cards/cardWithLeftIcon/index.tsx +87 -0
  32. package/src/lib/components/cards/cardWithLeftIcon/style.module.scss +23 -0
  33. package/src/lib/components/cards/cardWithTopIcon/index.stories.mdx +105 -0
  34. package/src/lib/components/cards/cardWithTopIcon/index.tsx +60 -0
  35. package/src/lib/components/cards/cardWithTopIcon/style.module.scss +10 -0
  36. package/src/lib/components/cards/cardWithTopLeftIcon/index.stories.mdx +101 -0
  37. package/src/lib/components/cards/cardWithTopLeftIcon/index.tsx +72 -0
  38. package/src/lib/components/cards/cardWithTopLeftIcon/style.module.scss +21 -0
  39. package/src/lib/components/cards/icons/arrow-right.svg +4 -0
  40. package/src/lib/components/cards/icons/chevron-right.svg +3 -0
  41. package/src/lib/components/cards/icons/feather-logo.svg +10 -0
  42. package/src/lib/components/cards/icons/index.ts +36 -0
  43. package/src/lib/components/cards/icons/info.svg +12 -0
  44. package/src/lib/components/cards/index.test.ts +37 -0
  45. package/src/lib/components/cards/index.tsx +57 -0
  46. package/src/lib/components/cards/infoCard/index.stories.mdx +61 -0
  47. package/src/lib/components/cards/infoCard/index.tsx +47 -0
  48. package/src/lib/components/cards/infoCard/style.module.scss +53 -0
  49. package/src/lib/components/chip/icons/remove-button-highlighted.svg +4 -0
  50. package/src/lib/components/chip/icons/remove-button.svg +4 -0
  51. package/src/lib/components/chip/index.stories.mdx +101 -0
  52. package/src/lib/components/chip/index.tsx +38 -0
  53. package/src/lib/components/chip/style.module.scss +54 -0
  54. package/src/lib/components/comparisonTable/components/Chevron.tsx +19 -0
  55. package/src/lib/components/comparisonTable/components/Row/index.tsx +68 -0
  56. package/src/lib/components/comparisonTable/components/Row/style.module.scss +114 -0
  57. package/src/lib/components/comparisonTable/components/TableArrows/Arrow.tsx +19 -0
  58. package/src/lib/components/comparisonTable/components/TableArrows/index.tsx +52 -0
  59. package/src/lib/components/comparisonTable/components/TableArrows/style.module.scss +53 -0
  60. package/src/lib/components/comparisonTable/components/TableInfoButton/index.tsx +37 -0
  61. package/src/lib/components/comparisonTable/components/TableInfoButton/style.module.scss +30 -0
  62. package/src/lib/components/comparisonTable/components/TableRating/StarIcon.tsx +13 -0
  63. package/src/lib/components/comparisonTable/components/TableRating/ZapIcon.tsx +17 -0
  64. package/src/lib/components/comparisonTable/components/TableRating/index.tsx +45 -0
  65. package/src/lib/components/comparisonTable/components/TableRating/style.module.scss +13 -0
  66. package/src/lib/components/comparisonTable/components/TableRowHeader/index.tsx +35 -0
  67. package/src/lib/components/comparisonTable/components/TableRowHeader/style.module.scss +3 -0
  68. package/src/lib/components/comparisonTable/components/TableTrueFalse.tsx +40 -0
  69. package/src/lib/components/comparisonTable/hooks/useActiveTableArrows.ts +63 -0
  70. package/src/lib/components/comparisonTable/index.stories.mdx +254 -0
  71. package/src/lib/components/comparisonTable/index.tsx +211 -0
  72. package/src/lib/components/comparisonTable/style.module.scss +104 -0
  73. package/src/lib/components/dateSelector/datepicker.scss +406 -0
  74. package/src/lib/components/dateSelector/icons/calendar.svg +6 -0
  75. package/src/lib/components/dateSelector/icons/chevron-left.svg +3 -0
  76. package/src/lib/components/dateSelector/icons/chevron-right.svg +3 -0
  77. package/src/lib/components/dateSelector/index.stories.mdx +62 -0
  78. package/src/lib/components/dateSelector/index.test.ts +33 -0
  79. package/src/lib/components/dateSelector/index.tsx +247 -0
  80. package/src/lib/components/dateSelector/style.module.scss +77 -0
  81. package/src/lib/components/downloadButton/icons/check.svg +3 -0
  82. package/src/lib/components/downloadButton/icons/download.svg +5 -0
  83. package/src/lib/components/downloadButton/index.stories.mdx +59 -0
  84. package/src/lib/components/downloadButton/index.tsx +67 -0
  85. package/src/lib/components/downloadButton/style.module.scss +19 -0
  86. package/src/lib/components/downloadRing/icons/check-outside-circle.tsx +26 -0
  87. package/src/lib/components/downloadRing/icons/download-cloud.tsx +18 -0
  88. package/src/lib/components/downloadRing/icons/style.module.scss +7 -0
  89. package/src/lib/components/downloadRing/index.stories.mdx +35 -0
  90. package/src/lib/components/downloadRing/index.tsx +79 -0
  91. package/src/lib/components/downloadRing/style.module.scss +66 -0
  92. package/src/lib/components/dropzone/images/error.tsx +18 -0
  93. package/src/lib/components/dropzone/images/file.tsx +26 -0
  94. package/src/lib/components/dropzone/images/style.module.scss +7 -0
  95. package/src/lib/components/dropzone/images/upload-complete.tsx +24 -0
  96. package/src/lib/components/dropzone/images/upload.tsx +18 -0
  97. package/src/lib/components/dropzone/index.stories.mdx +44 -0
  98. package/src/lib/components/dropzone/index.tsx +152 -0
  99. package/src/lib/components/dropzone/style.module.scss +90 -0
  100. package/src/lib/components/input/a.stories.mdx +28 -0
  101. package/src/lib/components/input/autoSuggestInput/index.stories.mdx +137 -0
  102. package/src/lib/components/input/autoSuggestInput/index.tsx +81 -0
  103. package/src/lib/components/input/autoSuggestInput/style.module.scss +71 -0
  104. package/src/lib/components/input/autoSuggestMultiSelect/index.stories.mdx +115 -0
  105. package/src/lib/components/input/autoSuggestMultiSelect/index.tsx +75 -0
  106. package/src/lib/components/input/autoSuggestMultiSelect/style.module.scss +4 -0
  107. package/src/lib/components/input/currency/format/index.test.ts +49 -0
  108. package/src/lib/components/input/currency/format/index.ts +15 -0
  109. package/src/lib/components/input/currency/index.stories.mdx +25 -0
  110. package/src/lib/components/input/currency/index.test.tsx +56 -0
  111. package/src/lib/components/input/currency/index.tsx +53 -0
  112. package/src/lib/components/input/iban/formatIban/index.test.ts +11 -0
  113. package/src/lib/components/input/iban/formatIban/index.ts +22 -0
  114. package/src/lib/components/input/iban/index.stories.mdx +21 -0
  115. package/src/lib/components/input/iban/index.tsx +20 -0
  116. package/src/lib/components/input/index.stories.mdx +62 -0
  117. package/src/lib/components/input/index.tsx +51 -0
  118. package/src/lib/components/input/style.module.scss +94 -0
  119. package/src/lib/components/modal/bottomModal/img/close.svg +4 -0
  120. package/src/lib/components/modal/bottomModal/index.tsx +68 -0
  121. package/src/lib/components/modal/bottomModal/style.module.scss +104 -0
  122. package/src/lib/components/modal/bottomOrRegularModal/index.tsx +43 -0
  123. package/src/lib/components/modal/bottomOrRegularModal/style.module.scss +16 -0
  124. package/src/lib/components/modal/hooks/useOnClose.ts +51 -0
  125. package/src/lib/components/modal/index.stories.mdx +316 -0
  126. package/src/lib/components/modal/index.ts +14 -0
  127. package/src/lib/components/modal/regularModal/img/close.svg +4 -0
  128. package/src/lib/components/modal/regularModal/index.tsx +55 -0
  129. package/src/lib/components/modal/regularModal/style.module.scss +106 -0
  130. package/src/lib/components/multiDropzone/UploadFileCell/index.tsx +138 -0
  131. package/src/lib/components/multiDropzone/UploadFileCell/style.module.scss +101 -0
  132. package/src/lib/components/multiDropzone/icons/bmp-complete.svg +10 -0
  133. package/src/lib/components/multiDropzone/icons/bmp.svg +10 -0
  134. package/src/lib/components/multiDropzone/icons/doc-complete.svg +11 -0
  135. package/src/lib/components/multiDropzone/icons/doc.svg +11 -0
  136. package/src/lib/components/multiDropzone/icons/docx-complete.svg +12 -0
  137. package/src/lib/components/multiDropzone/icons/docx.svg +12 -0
  138. package/src/lib/components/multiDropzone/icons/eye.svg +4 -0
  139. package/src/lib/components/multiDropzone/icons/generic-complete.svg +4 -0
  140. package/src/lib/components/multiDropzone/icons/generic-error.svg +7 -0
  141. package/src/lib/components/multiDropzone/icons/generic.svg +4 -0
  142. package/src/lib/components/multiDropzone/icons/heic-complete.svg +11 -0
  143. package/src/lib/components/multiDropzone/icons/heic.svg +11 -0
  144. package/src/lib/components/multiDropzone/icons/index.ts +51 -0
  145. package/src/lib/components/multiDropzone/icons/jpeg-complete.svg +11 -0
  146. package/src/lib/components/multiDropzone/icons/jpeg.svg +11 -0
  147. package/src/lib/components/multiDropzone/icons/jpg-complete.svg +10 -0
  148. package/src/lib/components/multiDropzone/icons/jpg.svg +10 -0
  149. package/src/lib/components/multiDropzone/icons/pdf-complete.svg +8 -0
  150. package/src/lib/components/multiDropzone/icons/pdf.svg +8 -0
  151. package/src/lib/components/multiDropzone/icons/png-complete.svg +10 -0
  152. package/src/lib/components/multiDropzone/icons/png.svg +10 -0
  153. package/src/lib/components/multiDropzone/icons/trash.svg +6 -0
  154. package/src/lib/components/multiDropzone/icons/upload.svg +5 -0
  155. package/src/lib/components/multiDropzone/index.stories.mdx +91 -0
  156. package/src/lib/components/multiDropzone/index.tsx +99 -0
  157. package/src/lib/components/multiDropzone/style.module.scss +32 -0
  158. package/src/lib/components/segmentedControl/index.stories.mdx +47 -0
  159. package/src/lib/components/segmentedControl/index.tsx +105 -0
  160. package/src/lib/components/segmentedControl/style.module.scss +36 -0
  161. package/src/lib/components/signaturePad/img/reset.svg +4 -0
  162. package/src/lib/components/signaturePad/img/sign.svg +3 -0
  163. package/src/lib/components/signaturePad/index.stories.mdx +17 -0
  164. package/src/lib/components/signaturePad/index.tsx +96 -0
  165. package/src/lib/components/signaturePad/style.module.scss +90 -0
  166. package/src/lib/index.tsx +71 -0
  167. package/src/lib/models/autoSuggestInput/index.ts +4 -0
  168. package/src/lib/models/download.ts +1 -0
  169. package/src/lib/models/downloadRing/index.ts +6 -0
  170. package/src/lib/scss/index.scss +22 -0
  171. package/src/lib/scss/private/_reset.scss +149 -0
  172. package/src/lib/scss/private/base/_colors.scss +19 -0
  173. package/src/lib/scss/private/base/_cursors.scss +31 -0
  174. package/src/lib/scss/private/base/_display.scss +35 -0
  175. package/src/lib/scss/private/base/_grid.scss +52 -0
  176. package/src/lib/scss/private/base/_index.scss +9 -0
  177. package/src/lib/scss/private/base/_shadows.scss +2 -0
  178. package/src/lib/scss/private/base/_spacing.scss +89 -0
  179. package/src/lib/scss/private/base/_typography.scss +128 -0
  180. package/src/lib/scss/private/base/_width_and_height.scss +25 -0
  181. package/src/lib/scss/private/base/cursors.stories.mdx +18 -0
  182. package/src/lib/scss/private/base/demo.tsx +119 -0
  183. package/src/lib/scss/private/base/display.stories.mdx +19 -0
  184. package/src/lib/scss/private/base/flex/_flex.scss +63 -0
  185. package/src/lib/scss/private/base/flex/flex.stories.mdx +139 -0
  186. package/src/lib/scss/private/base/flex/style.module.scss +24 -0
  187. package/src/lib/scss/private/base/spacing.stories.mdx +173 -0
  188. package/src/lib/scss/private/base/style.module.scss +42 -0
  189. package/src/lib/scss/private/base/typography.stories.mdx +71 -0
  190. package/src/lib/scss/private/base/width_and_height.stories.mdx +172 -0
  191. package/src/lib/scss/private/components/_badge.scss +41 -0
  192. package/src/lib/scss/private/components/_buttons.scss +193 -0
  193. package/src/lib/scss/private/components/_cards.scss +32 -0
  194. package/src/lib/scss/private/components/_index.scss +6 -0
  195. package/src/lib/scss/private/components/_input.scss +241 -0
  196. package/src/lib/scss/private/components/_notices.scss +39 -0
  197. package/src/lib/scss/private/components/_spinner.scss +60 -0
  198. package/src/lib/scss/private/components/assets/checkmark.svg +3 -0
  199. package/src/lib/scss/private/components/assets/icon-form-dropdown.svg +3 -0
  200. package/src/lib/scss/private/components/badge.stories.mdx +37 -0
  201. package/src/lib/scss/private/components/button.stories.mdx +107 -0
  202. package/src/lib/scss/private/components/cards.stories.mdx +35 -0
  203. package/src/lib/scss/private/components/checkbox.stories.mdx +47 -0
  204. package/src/lib/scss/private/components/input.stories.mdx +33 -0
  205. package/src/lib/scss/private/components/notices.stories.mdx +37 -0
  206. package/src/lib/scss/private/components/radio.stories.mdx +47 -0
  207. package/src/lib/scss/private/components/select.stories.mdx +17 -0
  208. package/src/lib/scss/private/components/spinner.stories.mdx +25 -0
  209. package/src/lib/scss/public/colors/_index.scss +2 -0
  210. package/src/lib/scss/public/colors/default.scss +125 -0
  211. package/src/lib/scss/public/colors/overrides.scss +0 -0
  212. package/src/lib/scss/public/colors.stories.mdx +27 -0
  213. package/src/lib/scss/public/demo.tsx +285 -0
  214. package/src/lib/scss/public/font/_index.scss +2 -0
  215. package/src/lib/scss/public/font/default.scss +3 -0
  216. package/src/lib/scss/public/font/overrides.scss +0 -0
  217. package/src/lib/scss/public/font-weight.scss +9 -0
  218. package/src/lib/scss/public/font-weight.stories.mdx +32 -0
  219. package/src/lib/scss/public/grid.scss +21 -0
  220. package/src/lib/scss/public/grid.stories.mdx +41 -0
  221. package/src/lib/scss/third-party/_google_places.scss +62 -0
  222. package/src/lib/scss/third-party/_index.scss +1 -0
  223. package/src/lib/scss/utils/_index.scss +3 -0
  224. package/src/lib/util/calendarDate/index.test.ts +32 -0
  225. package/src/lib/util/calendarDate/index.ts +30 -0
  226. package/src/lib/util/zeroFill.test.ts +15 -0
  227. package/src/lib/util/zeroFill.ts +7 -0
  228. package/src/react-app-env.d.ts +1 -0
  229. package/src/setupTests.js +8 -0
  230. package/src/theme.stories.mdx +54 -0
@@ -0,0 +1,316 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import classNames from 'classnames';
3
+ import debounce from 'lodash.debounce';
4
+ import isEqual from 'lodash.isequal';
5
+ import Input from '../input';
6
+ import { Address, countryNameFromAlphaCode } from '@popsure/public-models';
7
+
8
+ import { geocoderAddressComponentToPartialAddress } from './util';
9
+
10
+ import styles from './style.module.scss';
11
+
12
+ const GERMANY_LAT_LNG = { lat: 51.54317, lng: 10.3181503 };
13
+
14
+ const GERMANY_ALPHA_CODE = 'DE';
15
+
16
+ const MAP_CONFIG_OBJ = {
17
+ zoom: 6,
18
+ center: GERMANY_LAT_LNG,
19
+ fullscreenControl: false,
20
+ mapTypeControl: false,
21
+ panControl: false,
22
+ zoomControl: false,
23
+ streetViewControl: false,
24
+ scrollwheel: false,
25
+ scaleControl: false,
26
+ rotateControl: false,
27
+ draggable: false,
28
+ };
29
+
30
+ const loadGoogleMapsApiDynamically = (callback: () => void, apiKey: string) => {
31
+ const existingScript = document.getElementById('googleMapsImportScript');
32
+
33
+ if (existingScript) {
34
+ return;
35
+ }
36
+
37
+ const googleMapImportScript = document.createElement('script');
38
+ googleMapImportScript.id = 'googleMapsImportScript';
39
+ googleMapImportScript.type = 'text/javascript';
40
+ googleMapImportScript.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`;
41
+ document.head.appendChild(googleMapImportScript);
42
+
43
+ googleMapImportScript.onload = () => {
44
+ callback();
45
+ };
46
+ };
47
+
48
+ const AutoCompleteAddress = ({
49
+ apiKey,
50
+ address: initialAddress,
51
+ onAddressChange,
52
+ }: {
53
+ apiKey: string;
54
+ address?: Partial<Address>;
55
+ onAddressChange: (address: Partial<Address>) => void;
56
+ }) => {
57
+ const [manualAddressEntry, setManualAddressEntry] = useState(false);
58
+ const [isLoading, setIsLoading] = useState(false);
59
+ const autocomplete = useRef<google.maps.places.Autocomplete | null>(null);
60
+ const autocompleteElement = useRef<HTMLInputElement | null>(null);
61
+ const map = useRef<google.maps.Map | null>(null);
62
+ const marker = useRef<google.maps.Marker | null>(null);
63
+ const [address, setAddress] = useState(initialAddress);
64
+ const [hasLoadedGoogleAPI, setHasLoadedGoogleAPI] = useState(
65
+ window.google !== undefined
66
+ );
67
+
68
+ loadGoogleMapsApiDynamically(() => {
69
+ setHasLoadedGoogleAPI(true);
70
+ }, apiKey);
71
+
72
+ const [place, setPlace] = useState<google.maps.places.PlaceResult | null>(
73
+ null
74
+ );
75
+
76
+ useEffect(() => {
77
+ if (address) {
78
+ if (autocompleteElement.current && address.street) {
79
+ autocompleteElement.current.value = address.street;
80
+ }
81
+
82
+ if (isEqual(address, initialAddress) === false) {
83
+ onAddressChange({ ...address });
84
+ }
85
+ handleEnterAddressManually();
86
+ }
87
+ }, [initialAddress, address, onAddressChange, hasLoadedGoogleAPI]);
88
+
89
+ useEffect(() => {
90
+ if (hasLoadedGoogleAPI === false) {
91
+ return;
92
+ }
93
+
94
+ const reference = document.getElementById(
95
+ 'autocomplete'
96
+ ) as HTMLInputElement;
97
+
98
+ autocomplete.current = new google.maps.places.Autocomplete(reference, {
99
+ types: ['address'],
100
+ componentRestrictions: { country: GERMANY_ALPHA_CODE },
101
+ });
102
+
103
+ autocomplete.current.addListener('place_changed', onPlaceChanged);
104
+
105
+ map.current = new google.maps.Map(
106
+ document.getElementById('map')!,
107
+ MAP_CONFIG_OBJ
108
+ );
109
+
110
+ import('./mapStyle').then(({ style }) => {
111
+ map.current?.mapTypes.set('styled_map', style);
112
+ map.current?.setMapTypeId('styled_map');
113
+ });
114
+
115
+ marker.current = new google.maps.Marker({
116
+ map: map.current,
117
+ });
118
+
119
+ setPlaceFromAddress(address);
120
+ }, [hasLoadedGoogleAPI]); // eslint-disable-line
121
+
122
+ const onPlaceChanged = (
123
+ newPlace:
124
+ | google.maps.places.PlaceResult
125
+ | undefined = autocomplete.current?.getPlace(),
126
+ updateAddress: boolean = true
127
+ ) => {
128
+ if (newPlace?.geometry?.location) {
129
+ const geocoderAddress = geocoderAddressComponentToPartialAddress(
130
+ newPlace.address_components!
131
+ );
132
+
133
+ setPlace(newPlace);
134
+ if (updateAddress) {
135
+ setAddress((oldValue) => ({
136
+ ...geocoderAddress,
137
+ additionalInformation: oldValue?.additionalInformation,
138
+ }));
139
+ }
140
+
141
+ map.current?.panTo(newPlace.geometry.location);
142
+ map.current?.setZoom(15);
143
+
144
+ marker.current?.setPosition(newPlace.geometry.location);
145
+ }
146
+ };
147
+
148
+ const setPlaceFromAddress = useCallback((address: Partial<Address> | undefined) => {
149
+ if (!map.current) {
150
+ return;
151
+ }
152
+
153
+ if (address) {
154
+ const service = new google.maps.places.PlacesService(map.current);
155
+ const query = `${address.street ?? ''} ${address.houseNumber ?? ''}, ${
156
+ address.city ?? ''
157
+ }, ${address.country ? countryNameFromAlphaCode(address.country) : ''}`;
158
+ setIsLoading(true);
159
+ service.findPlaceFromQuery(
160
+ {
161
+ fields: ['place_id'],
162
+ query,
163
+ },
164
+ (results) => {
165
+ const firstResult = results && results[0];
166
+ if (firstResult && firstResult.place_id) {
167
+ service.getDetails(
168
+ { placeId: firstResult.place_id },
169
+ (newPlace) => {
170
+ onPlaceChanged(newPlace ?? undefined, false);
171
+ }
172
+ );
173
+ }
174
+ setIsLoading(false);
175
+ }
176
+ );
177
+ }
178
+ }, []);
179
+
180
+ const debouncedSetPlace = debounce(setPlaceFromAddress, 1000)
181
+
182
+ const handleEnterAddressManually = () => {
183
+ setManualAddressEntry(true);
184
+ };
185
+
186
+ return (
187
+ <>
188
+ <div
189
+ className={classNames(`wmx8 bg-grey-500 ${styles['map-container']}`, {
190
+ [styles['map-container--hidden']]: place === null,
191
+ })}
192
+ >
193
+ <div className={styles.map} id="map" />
194
+ {isLoading && (
195
+ <div className={styles['loading-spinner']}>
196
+ <div className="ds-spinner ds-spinner__m" />
197
+ </div>
198
+ )}
199
+ </div>
200
+ <div className={`wmx8`}>
201
+ {manualAddressEntry === false ? (
202
+ <div style={{ position: 'relative' }}>
203
+ <Input
204
+ className="w100"
205
+ id="autocomplete"
206
+ data-cy="autocomplete"
207
+ type="text"
208
+ placeholder="Search for address"
209
+ ref={autocompleteElement}
210
+ />
211
+ {hasLoadedGoogleAPI === false && (
212
+ <div className={styles['loading-spinner']}>
213
+ <div className="ds-spinner ds-spinner__m" />
214
+ </div>
215
+ )}
216
+ </div>
217
+ ) : (
218
+ <>
219
+ <div className={`d-flex ${styles['input-line']}`}>
220
+ <Input
221
+ className="w100"
222
+ data-cy="autocomplete"
223
+ type="text"
224
+ placeholder="Street"
225
+ value={address?.street || ''}
226
+ onChange={(e) => {
227
+ const newAddress = {
228
+ ...address,
229
+ street: e.target.value,
230
+ country: GERMANY_ALPHA_CODE,
231
+ };
232
+ setAddress(newAddress);
233
+ debouncedSetPlace(newAddress);
234
+ }}
235
+ />
236
+ <Input
237
+ className={`wmx2 ${styles['house-number-input']}`}
238
+ data-cy="autocomplete-house-number"
239
+ placeholder="House Number"
240
+ value={address?.houseNumber || ''}
241
+ onChange={(e) => {
242
+ const newAddress = {
243
+ ...address,
244
+ houseNumber: e.target.value,
245
+ country: GERMANY_ALPHA_CODE,
246
+ };
247
+ setAddress(newAddress);
248
+ debouncedSetPlace(newAddress);
249
+ }}
250
+ />
251
+ </div>
252
+ <Input
253
+ className="mt16"
254
+ data-cy="autocomplete-additional-info"
255
+ placeholder="Additional information (C/O, appartment…)"
256
+ value={address?.additionalInformation || ''}
257
+ onChange={(e) => {
258
+ const newAddress = {
259
+ ...address,
260
+ additionalInformation: e.target.value,
261
+ country: GERMANY_ALPHA_CODE,
262
+ };
263
+ setAddress(newAddress);
264
+ }}
265
+ />
266
+ <div className={`d-flex mt16 ${styles['input-line']}`}>
267
+ <Input
268
+ className="w100"
269
+ data-cy="autocomplete-postcode"
270
+ placeholder="Postcode"
271
+ value={address?.postcode || ''}
272
+ onChange={(e) => {
273
+ const newAddress = {
274
+ ...address,
275
+ postcode: e.target.value,
276
+ country: GERMANY_ALPHA_CODE,
277
+ };
278
+ setAddress(newAddress);
279
+ debouncedSetPlace(newAddress);
280
+ }}
281
+ />
282
+ <Input
283
+ className="w100"
284
+ data-cy="autocomplete-city"
285
+ placeholder="City"
286
+ value={address?.city || ''}
287
+ onChange={(e) => {
288
+ const newAddress = {
289
+ ...address,
290
+ city: e.target.value,
291
+ country: GERMANY_ALPHA_CODE,
292
+ };
293
+ setAddress(newAddress);
294
+ debouncedSetPlace(newAddress);
295
+ }}
296
+ />
297
+ </div>
298
+ </>
299
+ )}
300
+ </div>
301
+ {manualAddressEntry === false && (
302
+ <div className="p-p mt8">
303
+ Or{' '}
304
+ <span
305
+ className="p-a fw-bold c-pointer"
306
+ onClick={handleEnterAddressManually}
307
+ >
308
+ Enter address manually
309
+ </span>
310
+ </div>
311
+ )}
312
+ </>
313
+ );
314
+ };
315
+
316
+ export default AutoCompleteAddress;
@@ -0,0 +1,187 @@
1
+ export const style = new google.maps.StyledMapType(
2
+ [
3
+ {
4
+ elementType: 'geometry',
5
+ stylers: [
6
+ {
7
+ color: '#f5f5f5',
8
+ },
9
+ ],
10
+ },
11
+ {
12
+ elementType: 'labels',
13
+ stylers: [
14
+ {
15
+ visibility: 'off',
16
+ },
17
+ ],
18
+ },
19
+ {
20
+ elementType: 'labels.icon',
21
+ stylers: [
22
+ {
23
+ visibility: 'off',
24
+ },
25
+ ],
26
+ },
27
+ {
28
+ elementType: 'labels.text.fill',
29
+ stylers: [
30
+ {
31
+ color: '#616161',
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ elementType: 'labels.text.stroke',
37
+ stylers: [
38
+ {
39
+ color: '#f5f5f5',
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ featureType: 'administrative.land_parcel',
45
+ stylers: [
46
+ {
47
+ visibility: 'off',
48
+ },
49
+ ],
50
+ },
51
+ {
52
+ featureType: 'administrative.land_parcel',
53
+ elementType: 'labels.text.fill',
54
+ stylers: [
55
+ {
56
+ color: '#bdbdbd',
57
+ },
58
+ ],
59
+ },
60
+ {
61
+ featureType: 'administrative.neighborhood',
62
+ stylers: [
63
+ {
64
+ visibility: 'off',
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ featureType: 'poi',
70
+ elementType: 'geometry',
71
+ stylers: [
72
+ {
73
+ color: '#eeeeee',
74
+ },
75
+ ],
76
+ },
77
+ {
78
+ featureType: 'poi',
79
+ elementType: 'labels.text.fill',
80
+ stylers: [
81
+ {
82
+ color: '#757575',
83
+ },
84
+ ],
85
+ },
86
+ {
87
+ featureType: 'poi.park',
88
+ elementType: 'geometry',
89
+ stylers: [
90
+ {
91
+ color: '#e5e5e5',
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ featureType: 'poi.park',
97
+ elementType: 'labels.text.fill',
98
+ stylers: [
99
+ {
100
+ color: '#9e9e9e',
101
+ },
102
+ ],
103
+ },
104
+ {
105
+ featureType: 'road',
106
+ elementType: 'geometry',
107
+ stylers: [
108
+ {
109
+ color: '#ffffff',
110
+ },
111
+ ],
112
+ },
113
+ {
114
+ featureType: 'road.arterial',
115
+ elementType: 'labels.text.fill',
116
+ stylers: [
117
+ {
118
+ color: '#757575',
119
+ },
120
+ ],
121
+ },
122
+ {
123
+ featureType: 'road.highway',
124
+ elementType: 'geometry',
125
+ stylers: [
126
+ {
127
+ color: '#dadada',
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ featureType: 'road.highway',
133
+ elementType: 'labels.text.fill',
134
+ stylers: [
135
+ {
136
+ color: '#616161',
137
+ },
138
+ ],
139
+ },
140
+ {
141
+ featureType: 'road.local',
142
+ elementType: 'labels.text.fill',
143
+ stylers: [
144
+ {
145
+ color: '#9e9e9e',
146
+ },
147
+ ],
148
+ },
149
+ {
150
+ featureType: 'transit.line',
151
+ elementType: 'geometry',
152
+ stylers: [
153
+ {
154
+ color: '#e5e5e5',
155
+ },
156
+ ],
157
+ },
158
+ {
159
+ featureType: 'transit.station',
160
+ elementType: 'geometry',
161
+ stylers: [
162
+ {
163
+ color: '#eeeeee',
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ featureType: 'water',
169
+ elementType: 'geometry',
170
+ stylers: [
171
+ {
172
+ color: '#c9c9c9',
173
+ },
174
+ ],
175
+ },
176
+ {
177
+ featureType: 'water',
178
+ elementType: 'labels.text.fill',
179
+ stylers: [
180
+ {
181
+ color: '#9e9e9e',
182
+ },
183
+ ],
184
+ },
185
+ ],
186
+ { name: 'Styled Map' }
187
+ );
@@ -0,0 +1,82 @@
1
+ @use "../../scss/public/grid" as *;
2
+ @use "../../scss/public/colors" as *;
3
+
4
+ .input-line {
5
+ margin-left: -16px;
6
+
7
+ > * {
8
+ margin-left: 16px;
9
+ }
10
+
11
+ @include p-size-mobile {
12
+ flex-direction: column;
13
+
14
+ > *:not(:first-child) {
15
+ margin-top: 16px;
16
+ }
17
+ }
18
+ }
19
+
20
+ .house-number-input {
21
+ @include p-size-mobile {
22
+ max-width: none;
23
+ }
24
+ }
25
+
26
+ .map-container {
27
+ position: relative;
28
+
29
+ height: 112px;
30
+ margin-bottom: 16px;
31
+
32
+ border-radius: 8px;
33
+
34
+ transition: 0.3s height ease-in-out, 0.3s margin-top ease-in-out;
35
+
36
+ overflow: hidden;
37
+
38
+ &--hidden {
39
+ height: 0;
40
+ margin: 0;
41
+ }
42
+ }
43
+
44
+ @keyframes appear-in {
45
+ from {
46
+ opacity: 0;
47
+ }
48
+ to {
49
+ opacity: 1;
50
+ }
51
+ }
52
+
53
+ .appear-in-animate {
54
+ animation-name: appear-in;
55
+ animation-duration: 0.3s;
56
+ animation-fill-mode: both;
57
+ }
58
+
59
+ .loading-spinner {
60
+ display: flex;
61
+
62
+ justify-content: center;
63
+ align-items: center;
64
+
65
+ position: absolute !important;
66
+ background-color: rgba($ds-primary-500, 0.25);
67
+
68
+ top: 0;
69
+ left: 0;
70
+ bottom: 0;
71
+ right: 0;
72
+ z-index: 100;
73
+
74
+ animation-name: appear-in;
75
+ animation-duration: 0.3s;
76
+ animation-fill-mode: both;
77
+ }
78
+
79
+ .map {
80
+ width: 100%;
81
+ height: 100%;
82
+ }
@@ -0,0 +1,51 @@
1
+ import { geocoderAddressComponentToPartialAddress } from '.';
2
+
3
+ describe('geocoderAddressComponentToPartialAddress text', () => {
4
+ it('Should extract street, houseNumber, postcode, city, country from GeocoderAddressComponent[]', () => {
5
+ const input = [
6
+ { long_name: '103A', short_name: '103A', types: ['street_number'] },
7
+ {
8
+ long_name: 'Kottbusser Damm',
9
+ short_name: 'Kottbusser Damm',
10
+ types: ['route'],
11
+ },
12
+ {
13
+ long_name: 'Bezirk Neukölln',
14
+ short_name: 'Bezirk Neukölln',
15
+ types: ['sublocality_level_1', 'sublocality', 'political'],
16
+ },
17
+ {
18
+ long_name: 'Berlin',
19
+ short_name: 'Berlin',
20
+ types: ['locality', 'political'],
21
+ },
22
+ {
23
+ long_name: 'Berlin',
24
+ short_name: 'Berlin',
25
+ types: ['administrative_area_level_1', 'political'],
26
+ },
27
+ {
28
+ long_name: 'Germany',
29
+ short_name: 'DE',
30
+ types: ['country', 'political'],
31
+ },
32
+ {
33
+ long_name: '10967',
34
+ short_name: '10967',
35
+ types: ['postal_code'],
36
+ },
37
+ ];
38
+
39
+ const expectedOutput = {
40
+ street: 'Kottbusser Damm',
41
+ houseNumber: '103A',
42
+ postcode: '10967',
43
+ city: 'Berlin',
44
+ country: 'DE',
45
+ };
46
+
47
+ expect(geocoderAddressComponentToPartialAddress(input)).toEqual(
48
+ expectedOutput
49
+ );
50
+ });
51
+ });
@@ -0,0 +1,55 @@
1
+ import { Address, countryNameFromAlphaCode } from '@popsure/public-models';
2
+
3
+ export const geocoderAddressComponentToPartialAddress = (
4
+ input: google.maps.GeocoderAddressComponent[]
5
+ ): Partial<Address> => {
6
+ interface MappedType {
7
+ key: keyof Address;
8
+ value: 'long_name' | 'short_name';
9
+ }
10
+
11
+ const mapping: {
12
+ route: MappedType;
13
+ street_number: MappedType;
14
+ postal_code: MappedType;
15
+ locality: MappedType;
16
+ country: MappedType;
17
+ } = {
18
+ route: {
19
+ key: 'street',
20
+ value: 'long_name',
21
+ },
22
+ street_number: {
23
+ key: 'houseNumber',
24
+ value: 'long_name',
25
+ },
26
+ postal_code: {
27
+ key: 'postcode',
28
+ value: 'long_name',
29
+ },
30
+ locality: {
31
+ key: 'city',
32
+ value: 'long_name',
33
+ },
34
+ country: {
35
+ key: 'country',
36
+ value: 'short_name',
37
+ },
38
+ };
39
+
40
+ const toReturn: Partial<Address> = {};
41
+ input.forEach((value) => {
42
+ const type = value.types[0] as keyof typeof mapping;
43
+ const mappedValue = mapping[type];
44
+ if (mappedValue) {
45
+ toReturn[mappedValue.key] = value[mappedValue.value];
46
+ }
47
+ });
48
+
49
+ return toReturn;
50
+ };
51
+
52
+ export const inlineAddress = (address: Address) =>
53
+ `${address.street} ${address.houseNumber}, ${
54
+ address.city
55
+ }, ${countryNameFromAlphaCode(address.country)}`;
@@ -0,0 +1,14 @@
1
+ import purpleSendImage from './send-purple.svg';
2
+ import whiteSendImage from './send-white.svg';
3
+
4
+ const purpleSend = {
5
+ src: purpleSendImage,
6
+ alt: 'Paper plane',
7
+ };
8
+
9
+ const whiteSend = {
10
+ src: whiteSendImage,
11
+ alt: 'Paper plane',
12
+ };
13
+
14
+ export { purpleSend, whiteSend };
@@ -0,0 +1,4 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M18.3334 1.66667L9.16675 10.8333" stroke="#8E8CEE" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
3
+ <path d="M18.3334 1.66667L12.5001 18.3333L9.16675 10.8333L1.66675 7.5L18.3334 1.66667Z" stroke="#8E8CEE" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
4
+ </svg>