strapi-plugin-map-box 0.0.1 → 0.0.3

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.
@@ -1,4 +1,4 @@
1
- import { useRef, useEffect, useState } from "react";
1
+ import { useRef, useEffect, useState, useCallback } from "react";
2
2
  import { PinMap } from "@strapi/icons";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { Field, JSONInput } from "@strapi/design-system";
@@ -34,58 +34,213 @@ const ControlsContainer = styled.div`
34
34
  position: absolute;
35
35
  top: 1rem;
36
36
  left: 1rem;
37
- z-index: 1;
38
- width: 300px;
37
+ z-index: 10;
38
+ width: 350px;
39
39
  `;
40
- const ControlsWrapper = styled.div`
40
+ const SearchWrapper = styled.div`
41
+ position: relative;
42
+ `;
43
+ const SearchInputContainer = styled.div`
41
44
  display: flex;
42
- gap: 0.5rem;
45
+ align-items: center;
46
+ background: white;
47
+ border: 1px solid #dcdce4;
48
+ border-radius: 4px;
49
+ overflow: hidden;
50
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
51
+
52
+ &:focus-within {
53
+ border-color: #4945ff;
54
+ box-shadow: 0 0 0 2px rgba(73, 69, 255, 0.2);
55
+ }
56
+ `;
57
+ const SearchIcon = styled.div`
58
+ padding: 0 12px;
59
+ color: #8e8e93;
60
+ display: flex;
61
+ align-items: center;
43
62
  `;
44
63
  const SearchInput = styled.input`
45
64
  flex: 1;
46
- padding: 0.5rem;
47
- border: 1px solid #dcdce4;
48
- border-radius: 4px;
65
+ padding: 10px 0;
66
+ border: none;
49
67
  font-size: 14px;
68
+ outline: none;
69
+ background: transparent;
70
+
71
+ &::placeholder {
72
+ color: #8e8e93;
73
+ }
50
74
  `;
51
- const SearchButton = styled.button`
52
- padding: 0.5rem 1rem;
53
- background-color: #4945ff;
54
- color: white;
75
+ const ClearButton = styled.button`
76
+ padding: 8px 12px;
77
+ background: none;
55
78
  border: none;
79
+ cursor: pointer;
80
+ color: #8e8e93;
81
+ display: flex;
82
+ align-items: center;
83
+
84
+ &:hover {
85
+ color: #666;
86
+ }
87
+ `;
88
+ const LoadingSpinner = styled.div`
89
+ padding: 8px 12px;
90
+ color: #4945ff;
91
+
92
+ @keyframes spin {
93
+ to {
94
+ transform: rotate(360deg);
95
+ }
96
+ }
97
+
98
+ svg {
99
+ animation: spin 1s linear infinite;
100
+ }
101
+ `;
102
+ const ResultsDropdown = styled.div`
103
+ position: absolute;
104
+ top: calc(100% + 4px);
105
+ left: 0;
106
+ right: 0;
107
+ background: white;
108
+ border: 1px solid #dcdce4;
56
109
  border-radius: 4px;
110
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
111
+ max-height: 300px;
112
+ overflow-y: auto;
113
+ `;
114
+ const ResultItem = styled.button`
115
+ width: 100%;
116
+ padding: 12px;
117
+ display: flex;
118
+ align-items: flex-start;
119
+ gap: 12px;
120
+ background: none;
121
+ border: none;
122
+ border-bottom: 1px solid #f0f0f0;
57
123
  cursor: pointer;
58
- font-size: 14px;
124
+ text-align: left;
125
+ transition: background-color 0.15s;
126
+
127
+ &:last-child {
128
+ border-bottom: none;
129
+ }
59
130
 
60
131
  &:hover {
61
- background-color: #3832e0;
132
+ background-color: #f6f6f9;
62
133
  }
63
134
  `;
135
+ const ResultIcon = styled.div`
136
+ width: 32px;
137
+ height: 32px;
138
+ border-radius: 6px;
139
+ background-color: rgba(73, 69, 255, 0.1);
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ flex-shrink: 0;
144
+ color: #4945ff;
145
+ `;
146
+ const ResultTextContainer = styled.div`
147
+ flex: 1;
148
+ min-width: 0;
149
+ `;
150
+ const ResultTitle = styled.div`
151
+ font-size: 14px;
152
+ font-weight: 500;
153
+ color: #32324d;
154
+ white-space: nowrap;
155
+ overflow: hidden;
156
+ text-overflow: ellipsis;
157
+ `;
158
+ const ResultSubtitle = styled.div`
159
+ font-size: 12px;
160
+ color: #8e8e93;
161
+ white-space: nowrap;
162
+ overflow: hidden;
163
+ text-overflow: ellipsis;
164
+ margin-top: 2px;
165
+ `;
166
+ const NoResults = styled.div`
167
+ padding: 16px;
168
+ text-align: center;
169
+ color: #8e8e93;
170
+ font-size: 14px;
171
+ `;
172
+ const getPlaceIcon = (placeType) => {
173
+ if (placeType.includes("poi")) {
174
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" }) });
175
+ }
176
+ if (placeType.includes("address")) {
177
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" }) });
178
+ }
179
+ if (placeType.includes("place") || placeType.includes("locality")) {
180
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z" }) });
181
+ }
182
+ if (placeType.includes("region") || placeType.includes("country")) {
183
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" }) });
184
+ }
185
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" }) });
186
+ };
64
187
  const MapSearch = ({
65
- onSearch,
66
188
  searchQuery,
67
189
  setSearchQuery,
68
- handleKeyDown
190
+ searchResults,
191
+ isSearching,
192
+ onSelectResult,
193
+ onClear,
194
+ showResults,
195
+ setShowResults
69
196
  }) => {
70
- return /* @__PURE__ */ jsx(ControlsContainer, { children: /* @__PURE__ */ jsxs(ControlsWrapper, { children: [
71
- /* @__PURE__ */ jsx(
72
- SearchInput,
73
- {
74
- type: "text",
75
- value: searchQuery,
76
- onChange: (e) => setSearchQuery(e.target.value),
77
- onKeyDown: handleKeyDown,
78
- placeholder: "Search for a location..."
79
- }
80
- ),
81
- /* @__PURE__ */ jsx(
82
- SearchButton,
83
- {
84
- type: "button",
85
- onClick: onSearch,
86
- children: "Search"
87
- }
88
- )
197
+ const handleInputChange = (e) => {
198
+ setSearchQuery(e.target.value);
199
+ setShowResults(true);
200
+ };
201
+ const handleResultClick = (result) => {
202
+ onSelectResult(result);
203
+ setShowResults(false);
204
+ };
205
+ const handleClear = () => {
206
+ onClear();
207
+ setShowResults(false);
208
+ };
209
+ return /* @__PURE__ */ jsx(ControlsContainer, { children: /* @__PURE__ */ jsxs(SearchWrapper, { children: [
210
+ /* @__PURE__ */ jsxs(SearchInputContainer, { children: [
211
+ /* @__PURE__ */ jsx(SearchIcon, { children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }) }) }),
212
+ /* @__PURE__ */ jsx(
213
+ SearchInput,
214
+ {
215
+ type: "text",
216
+ value: searchQuery,
217
+ onChange: handleInputChange,
218
+ onFocus: () => setShowResults(true),
219
+ placeholder: "Search for a location..."
220
+ }
221
+ ),
222
+ isSearching && /* @__PURE__ */ jsx(LoadingSpinner, { children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z" }) }) }),
223
+ searchQuery && !isSearching && /* @__PURE__ */ jsx(ClearButton, { onClick: handleClear, type: "button", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) })
224
+ ] }),
225
+ showResults && searchQuery.length > 2 && /* @__PURE__ */ jsx(ResultsDropdown, { children: searchResults.length > 0 ? searchResults.map((result) => {
226
+ const [title, ...rest] = result.place_name.split(",");
227
+ const subtitle = rest.join(",").trim();
228
+ return /* @__PURE__ */ jsxs(
229
+ ResultItem,
230
+ {
231
+ onClick: () => handleResultClick(result),
232
+ type: "button",
233
+ children: [
234
+ /* @__PURE__ */ jsx(ResultIcon, { children: getPlaceIcon(result.place_type) }),
235
+ /* @__PURE__ */ jsxs(ResultTextContainer, { children: [
236
+ /* @__PURE__ */ jsx(ResultTitle, { children: title }),
237
+ subtitle && /* @__PURE__ */ jsx(ResultSubtitle, { children: subtitle })
238
+ ] })
239
+ ]
240
+ },
241
+ result.id
242
+ );
243
+ }) : !isSearching ? /* @__PURE__ */ jsx(NoResults, { children: "No results found" }) : null })
89
244
  ] }) });
90
245
  };
91
246
  const DEFAULT_VIEW_STATE = {
@@ -110,7 +265,7 @@ const useMapBoxSettings = () => {
110
265
  const fetchSettings = async () => {
111
266
  try {
112
267
  setIsLoading(true);
113
- const { data } = await get("/strapi-plugin-map-box/get-settings");
268
+ const { data } = await get("/map-box/get-settings");
114
269
  console.log("data from getSettings", data);
115
270
  setConfig(data);
116
271
  setError(null);
@@ -219,54 +374,93 @@ function MapBoxField({ name, onChange, value, intlLabel, required }) {
219
374
  const { viewState, markerPosition, setViewState, setMarkerPosition } = useMapLocationHook(value);
220
375
  const { accessToken, debugMode } = config || {};
221
376
  const [searchQuery, setSearchQuery] = useState("");
222
- const [searchResults, setSearchResults] = useState(null);
377
+ const [searchResults, setSearchResults] = useState([]);
378
+ const [isSearching, setIsSearching] = useState(false);
379
+ const [showResults, setShowResults] = useState(false);
223
380
  const [searchError, setSearchError] = useState(null);
224
- const updateMarkerPosition = (lng, lat, address) => {
225
- setMarkerPosition({ longitude: lng, latitude: lat });
226
- const newValue = {
227
- longitude: lng,
228
- latitude: lat,
229
- address: address || "Selected location",
230
- zoom: viewState.zoom,
231
- pitch: viewState.pitch,
232
- bearing: viewState.bearing
233
- };
234
- onChange({ target: { name, value: newValue, type: "json" } });
235
- };
236
- const handleSearch = async () => {
237
- if (!searchQuery.trim()) return;
238
- try {
239
- setSearchError(null);
240
- const encodedQuery = encodeURIComponent(searchQuery.trim());
241
- const url = `/strapi-plugin-map-box/location-search/${encodedQuery}`;
242
- const { data } = await get(url);
243
- setSearchResults(data);
244
- if (data.features && data.features[0]) {
245
- const [longitude, latitude] = data.features[0].center;
246
- setViewState((prev) => ({
247
- ...prev,
248
- longitude,
249
- latitude,
250
- zoom: 14,
251
- transitionDuration: 1e3
252
- }));
253
- updateMarkerPosition(longitude, latitude, data.features[0].place_name);
254
- } else if (data.error) {
255
- setSearchError(data.error);
256
- } else {
257
- setSearchError("No results found");
258
- }
259
- } catch (error2) {
260
- console.error("Error searching location:", error2);
261
- setSearchError(error2 instanceof Error ? error2.message : "An error occurred");
381
+ const searchTimeoutRef = useRef(null);
382
+ const updateMarkerPosition = useCallback(
383
+ (lng, lat, address) => {
384
+ setMarkerPosition({ longitude: lng, latitude: lat });
385
+ const newValue = {
386
+ longitude: lng,
387
+ latitude: lat,
388
+ address: address || "Selected location",
389
+ zoom: viewState.zoom,
390
+ pitch: viewState.pitch,
391
+ bearing: viewState.bearing
392
+ };
393
+ onChange({ target: { name, value: newValue, type: "json" } });
394
+ },
395
+ [name, onChange, setMarkerPosition, viewState.zoom, viewState.pitch, viewState.bearing]
396
+ );
397
+ useEffect(() => {
398
+ if (searchTimeoutRef.current) {
399
+ clearTimeout(searchTimeoutRef.current);
262
400
  }
263
- };
264
- const handleKeyDown = (e) => {
265
- if (e.key === "Enter") {
266
- e.preventDefault();
267
- handleSearch();
401
+ if (searchQuery.trim().length <= 2) {
402
+ setSearchResults([]);
403
+ setIsSearching(false);
404
+ return;
268
405
  }
269
- };
406
+ setIsSearching(true);
407
+ searchTimeoutRef.current = setTimeout(async () => {
408
+ try {
409
+ setSearchError(null);
410
+ const encodedQuery = encodeURIComponent(searchQuery.trim());
411
+ const url = `/map-box/location-search/${encodedQuery}`;
412
+ const { data } = await get(url);
413
+ if (data.features) {
414
+ setSearchResults(
415
+ data.features.slice(0, 5).map((feature) => ({
416
+ id: feature.id,
417
+ place_name: feature.place_name,
418
+ center: feature.center,
419
+ place_type: feature.place_type
420
+ }))
421
+ );
422
+ } else if (data.error) {
423
+ setSearchError(data.error);
424
+ setSearchResults([]);
425
+ } else {
426
+ setSearchResults([]);
427
+ }
428
+ } catch (error2) {
429
+ console.error("Error searching location:", error2);
430
+ setSearchError(error2 instanceof Error ? error2.message : "An error occurred");
431
+ setSearchResults([]);
432
+ } finally {
433
+ setIsSearching(false);
434
+ }
435
+ }, 300);
436
+ return () => {
437
+ if (searchTimeoutRef.current) {
438
+ clearTimeout(searchTimeoutRef.current);
439
+ }
440
+ };
441
+ }, [searchQuery, get]);
442
+ const handleSelectResult = useCallback(
443
+ (result) => {
444
+ const [longitude, latitude] = result.center;
445
+ setViewState((prev) => ({
446
+ ...prev,
447
+ longitude,
448
+ latitude,
449
+ zoom: 14,
450
+ transitionDuration: 1e3
451
+ }));
452
+ updateMarkerPosition(longitude, latitude, result.place_name);
453
+ setSearchQuery(result.place_name.split(",")[0]);
454
+ setSearchResults([]);
455
+ setShowResults(false);
456
+ },
457
+ [setViewState, updateMarkerPosition]
458
+ );
459
+ const handleClearSearch = useCallback(() => {
460
+ setSearchQuery("");
461
+ setSearchResults([]);
462
+ setShowResults(false);
463
+ }, []);
270
464
  const handleMapClick = (event) => {
271
465
  const { lngLat } = event;
272
466
  updateMarkerPosition(lngLat.lng, lngLat.lat);
@@ -274,6 +468,18 @@ function MapBoxField({ name, onChange, value, intlLabel, required }) {
274
468
  const handleMapMove = (evt) => {
275
469
  setViewState(evt.viewState);
276
470
  };
471
+ const handleMapMoveEnd = (evt) => {
472
+ const { longitude, latitude, zoom, pitch, bearing } = evt.viewState;
473
+ const newValue = {
474
+ longitude: markerPosition.longitude,
475
+ latitude: markerPosition.latitude,
476
+ address: value?.address || "Selected location",
477
+ zoom,
478
+ pitch,
479
+ bearing
480
+ };
481
+ onChange({ target: { name, value: newValue, type: "json" } });
482
+ };
277
483
  const handleMarkerDragEnd = (event) => {
278
484
  const { lngLat } = event;
279
485
  updateMarkerPosition(lngLat.lng, lngLat.lat);
@@ -320,10 +526,14 @@ function MapBoxField({ name, onChange, value, intlLabel, required }) {
320
526
  /* @__PURE__ */ jsx(
321
527
  MapSearch,
322
528
  {
323
- onSearch: handleSearch,
324
529
  searchQuery,
325
530
  setSearchQuery,
326
- handleKeyDown
531
+ searchResults,
532
+ isSearching,
533
+ onSelectResult: handleSelectResult,
534
+ onClear: handleClearSearch,
535
+ showResults,
536
+ setShowResults
327
537
  }
328
538
  ),
329
539
  /* @__PURE__ */ jsxs(
@@ -331,6 +541,7 @@ function MapBoxField({ name, onChange, value, intlLabel, required }) {
331
541
  {
332
542
  ...viewState,
333
543
  onMove: handleMapMove,
544
+ onMoveEnd: handleMapMoveEnd,
334
545
  onClick: handleMapClick,
335
546
  mapStyle: "mapbox://styles/mapbox/streets-v12",
336
547
  mapboxAccessToken: accessToken,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/components/custom-field/MapBoxField/MapSearch.tsx","../../admin/src/components/custom-field/MapBoxField/types.ts","../../admin/src/components/custom-field/MapBoxField/hooks.ts","../../admin/src/components/custom-field/MapBoxField/DebugInfo.tsx","../../admin/src/components/custom-field/MapBoxField/index.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'map-box';\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import React from 'react';\nimport styled from 'styled-components';\n\nconst ControlsContainer = styled.div`\n position: absolute;\n top: 1rem;\n left: 1rem;\n z-index: 1;\n width: 300px;\n`;\n\nconst ControlsWrapper = styled.div`\n display: flex;\n gap: 0.5rem;\n`;\n\nconst SearchInput = styled.input`\n flex: 1;\n padding: 0.5rem;\n border: 1px solid #dcdce4;\n border-radius: 4px;\n font-size: 14px;\n`;\n\nconst SearchButton = styled.button`\n padding: 0.5rem 1rem;\n background-color: #4945ff;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n\n &:hover {\n background-color: #3832e0;\n }\n`;\n\ninterface MapSearchProps {\n onSearch: () => void;\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n handleKeyDown: (e: React.KeyboardEvent) => void;\n}\n\nexport const MapSearch: React.FC<MapSearchProps> = ({\n onSearch,\n searchQuery,\n setSearchQuery,\n handleKeyDown\n}) => {\n return (\n <ControlsContainer>\n <ControlsWrapper>\n <SearchInput\n type=\"text\"\n value={searchQuery}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchQuery(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Search for a location...\"\n />\n <SearchButton\n type=\"button\"\n onClick={onSearch}\n >\n Search\n </SearchButton>\n </ControlsWrapper>\n </ControlsContainer>\n );\n};","export type MapBoxValue = {\n longitude: number;\n latitude: number;\n zoom: number;\n pitch: number;\n bearing: number;\n address: string;\n}\n\n\nexport interface ViewState {\n longitude: number;\n latitude: number;\n zoom: number;\n pitch: number;\n bearing: number;\n padding?: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n };\n}\n\nexport const DEFAULT_VIEW_STATE: ViewState = {\n longitude: -122.4194,\n latitude: 37.7749,\n zoom: 13,\n pitch: 0,\n bearing: 0,\n padding: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n }\n};","import { type MapBoxValue, type ViewState, DEFAULT_VIEW_STATE } from './types';\n\nimport { useEffect, useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\ntype config = {\n accessToken: string;\n debugMode: boolean;\n};\n\nexport const useMapBoxSettings = () => {\n const { get } = useFetchClient();\n const [config, setConfig] = useState<config | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchSettings = async () => {\n try {\n setIsLoading(true);\n const { data } = await get('/strapi-plugin-map-box/get-settings');\n console.log('data from getSettings', data);\n setConfig(data);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch MapBox settings');\n } finally {\n setIsLoading(false);\n }\n };\n fetchSettings();\n }, []);\n\n return { config, isLoading, error };\n};\n\nexport const useMapLocationHook = (initialValue?: MapBoxValue) => {\n const [viewState, setViewState] = useState<ViewState>(DEFAULT_VIEW_STATE);\n const [markerPosition, setMarkerPosition] = useState({\n longitude: DEFAULT_VIEW_STATE.longitude,\n latitude: DEFAULT_VIEW_STATE.latitude,\n });\n\n useEffect(() => {\n if (initialValue) {\n console.log('Initializing from previous value:', initialValue);\n const previousValue = initialValue as MapBoxValue;\n\n setViewState((prev) => ({\n ...prev,\n longitude: previousValue.longitude,\n latitude: previousValue.latitude,\n zoom: previousValue.zoom,\n pitch: previousValue.pitch,\n bearing: previousValue.bearing,\n }));\n\n setMarkerPosition({\n longitude: previousValue.longitude,\n latitude: previousValue.latitude,\n });\n }\n }, []);\n\n return { viewState, setViewState, markerPosition, setMarkerPosition };\n};\n\nexport const useLocationService = () => {\n const { get } = useFetchClient();\n const [searchError, setSearchError] = useState<string | null>(null);\n const [searchResults, setSearchResults] = useState<any>(null);\n\n const searchLocation = async (query: string) => {\n try {\n setSearchError(null);\n const encodedQuery = encodeURIComponent(query.trim());\n const { data } = await get(`/strapi-plugin-map-box/location-search/${encodedQuery}`);\n setSearchResults(data);\n return data;\n } catch (error) {\n setSearchError(error instanceof Error ? error.message : 'An error occurred');\n return null;\n }\n };\n\n return { searchLocation, searchError, searchResults };\n};\n","import styled from 'styled-components';\nimport { ViewState } from './types';\n\n\ninterface DebugInfoProps {\n searchResults: any;\n searchError: string | null;\n viewState: ViewState;\n markerPosition: { longitude: number; latitude: number };\n searchQuery: string;\n value?: any;\n}\n\nexport function DebugInfo({ \n searchResults, \n searchError, \n viewState,\n markerPosition,\n searchQuery,\n value \n}: DebugInfoProps) {\n return (\n <DebugContainer>\n <h4>Debug Information:</h4>\n \n <DebugSection>\n <strong>Search Results:</strong>\n <DebugPre>\n {searchResults ? JSON.stringify(searchResults, null, 2) : 'No search results yet'}\n </DebugPre>\n </DebugSection>\n\n {searchError && (\n <ErrorMessage>\n <strong>Error:</strong> {searchError}\n </ErrorMessage>\n )}\n\n <DebugSection>\n <strong>Current View State:</strong>\n <DebugPre>\n {JSON.stringify(viewState, null, 2)}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Marker Position:</strong>\n <DebugPre>\n {JSON.stringify(markerPosition, null, 2)}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Search Query:</strong>\n <DebugPre>\n {searchQuery || 'No search query'}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Current Value:</strong>\n <DebugPre>\n {value ? JSON.stringify(value, null, 2) : 'No value set'}\n </DebugPre>\n </DebugSection>\n </DebugContainer>\n );\n}\n\nconst DebugContainer = styled.div`\n margin-top: 20px;\n padding: 1rem;\n background-color: #f5f5f5;\n border-radius: 4px;\n`;\n\nconst DebugSection = styled.div`\n margin-bottom: 10px;\n`;\n\nconst DebugPre = styled.pre`\n background: #ffffff;\n padding: 10px;\n border-radius: 4px;\n max-height: 200px;\n overflow: auto;\n margin: 5px 0;\n border: 1px solid #dcdce4;\n`;\n\nconst ErrorMessage = styled.div`\n color: #d02b20;\n margin-bottom: 10px;\n padding: 10px;\n background-color: #fff5f5;\n border: 1px solid #ffd7d5;\n border-radius: 4px;\n`;","import { MapBoxValue } from './types';\nimport { Field, JSONInput } from '@strapi/design-system';\n\nimport Map, {\n FullscreenControl,\n GeolocateControl,\n Marker,\n NavigationControl,\n} from 'react-map-gl/mapbox';\n\nimport 'mapbox-gl/dist/mapbox-gl.css';\nimport { useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\nimport { MapSearch } from './MapSearch';\n\nimport { useMapBoxSettings, useMapLocationHook } from './hooks';\nimport { DebugInfo } from './DebugInfo';\n\ninterface MapBoxFieldProps {\n name: string;\n onChange: (event: { target: { name: string; value: object; type: string } }) => void;\n value?: MapBoxValue;\n intlLabel?: {\n defaultMessage: string;\n };\n required?: boolean;\n}\n\n// #endregion\n\nexport function MapBoxField({ name, onChange, value, intlLabel, required }: MapBoxFieldProps) {\n const { get } = useFetchClient();\n const { config, isLoading, error } = useMapBoxSettings();\n const { viewState, markerPosition, setViewState, setMarkerPosition } = useMapLocationHook(value);\n\n const { accessToken, debugMode } = config || {};\n\n const [searchQuery, setSearchQuery] = useState('');\n const [searchResults, setSearchResults] = useState<any>(null);\n const [searchError, setSearchError] = useState<string | null>(null);\n\n const updateMarkerPosition = (lng: number, lat: number, address?: string) => {\n setMarkerPosition({ longitude: lng, latitude: lat });\n\n // Update the JSON value with all necessary data\n const newValue = {\n longitude: lng,\n latitude: lat,\n address: address || 'Selected location',\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n };\n\n onChange({ target: { name, value: newValue, type: 'json' } });\n };\n\n const handleSearch = async () => {\n if (!searchQuery.trim()) return;\n\n try {\n setSearchError(null);\n const encodedQuery = encodeURIComponent(searchQuery.trim());\n const url = `/strapi-plugin-map-box/location-search/${encodedQuery}`;\n const { data } = await get(url);\n\n setSearchResults(data);\n\n if (data.features && data.features[0]) {\n const [longitude, latitude] = data.features[0].center;\n // Update both the view and marker position\n setViewState((prev) => ({\n ...prev,\n longitude,\n latitude,\n zoom: 14,\n transitionDuration: 1000,\n }));\n updateMarkerPosition(longitude, latitude, data.features[0].place_name);\n } else if (data.error) {\n setSearchError(data.error);\n } else {\n setSearchError('No results found');\n }\n } catch (error) {\n console.error('Error searching location:', error);\n setSearchError(error instanceof Error ? error.message : 'An error occurred');\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSearch();\n }\n };\n\n const handleMapClick = (event: any) => {\n const { lngLat } = event;\n updateMarkerPosition(lngLat.lng, lngLat.lat);\n };\n\n const handleMapMove = (evt: any) => {\n setViewState(evt.viewState);\n };\n\n const handleMarkerDragEnd = (event: any) => {\n const { lngLat } = event;\n updateMarkerPosition(lngLat.lng, lngLat.lat);\n };\n\n const handlePositionChange = (input: string) => {\n try {\n const value = JSON.parse(input);\n setViewState((prev) => ({\n ...prev,\n longitude: value.longitude,\n latitude: value.latitude,\n zoom: value.zoom || prev.zoom,\n pitch: value.pitch || prev.pitch,\n bearing: value.bearing || prev.bearing,\n }));\n setMarkerPosition({\n longitude: value.longitude,\n latitude: value.latitude,\n });\n onChange({ target: { name, value, type: 'json' } });\n } catch {\n // Handle invalid JSON\n }\n };\n\n // Construct the final JSON value to be saved\n const finalValue: MapBoxValue = {\n longitude: markerPosition.longitude,\n latitude: markerPosition.latitude,\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n address: (value as MapBoxValue)?.address || 'Selected location',\n };\n\n const strValue = JSON.stringify(value || finalValue, null, 2);\n\n if (!accessToken || isLoading) {\n return <div>Loading...</div>;\n }\n\n if (error) {\n return <div>Error: {error}</div>;\n }\n\n return (\n <div>\n <div style={{ position: 'relative', height: '500px', width: '100%' }}>\n <MapSearch\n onSearch={handleSearch}\n searchQuery={searchQuery}\n setSearchQuery={setSearchQuery}\n handleKeyDown={handleKeyDown}\n />\n <Map\n {...viewState}\n onMove={handleMapMove}\n onClick={handleMapClick}\n mapStyle=\"mapbox://styles/mapbox/streets-v12\"\n // mapStyle=\"mapbox://styles/mapbox/light-v11\"\n mapboxAccessToken={accessToken}\n attributionControl={false}\n style={{ height: '100%', width: '100%' }}\n >\n <FullscreenControl />\n <NavigationControl />\n <GeolocateControl />\n <Marker\n longitude={markerPosition.longitude}\n latitude={markerPosition.latitude}\n color=\"#4945ff\"\n draggable\n onDragEnd={handleMarkerDragEnd}\n />\n </Map>\n </div>\n {debugMode && (\n <Field.Root name={name} required={required}>\n <Field.Label>{intlLabel?.defaultMessage ?? 'Location'}</Field.Label>\n <JSONInput value={strValue} onChange={handlePositionChange}></JSONInput>\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n )}\n\n {debugMode && (\n <DebugInfo\n viewState={viewState}\n searchResults={searchResults}\n searchError={searchError}\n markerPosition={markerPosition}\n searchQuery={searchQuery}\n value={value}\n />\n )}\n </div>\n );\n}\n","import { getTranslation } from './utils/getTranslation';\nimport { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport { PinMap } from '@strapi/icons';\nimport { MapBoxField } from './components/custom-field/MapBoxField/index';\n\nexport default {\n register(app: any) {\n \n app.customFields.register({\n name: 'map-box',\n type: 'json',\n icon: PinMap,\n intlLabel: {\n id: 'custom.fields.map-box.label',\n defaultMessage: 'Map Box',\n },\n intlDescription: {\n id: 'custom.fields.map-box.description',\n defaultMessage: 'Enter geographic coordinates',\n },\n components: {\n Input: () => ({ default: MapBoxField as React.ComponentType }) as any,\n },\n });\n\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads({ locales }: { locales: string[] }) {\n return Promise.all(\n locales.map(async (locale) => {\n try {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return { data, locale };\n } catch {\n return { data: {}, locale };\n }\n })\n );\n },\n};\n"],"names":["error","value"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/components/Initializer.tsx","../../admin/src/components/custom-field/MapBoxField/MapSearch.tsx","../../admin/src/components/custom-field/MapBoxField/types.ts","../../admin/src/components/custom-field/MapBoxField/hooks.ts","../../admin/src/components/custom-field/MapBoxField/DebugInfo.tsx","../../admin/src/components/custom-field/MapBoxField/index.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'map-box';\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import React from 'react';\nimport styled from 'styled-components';\n\nconst ControlsContainer = styled.div`\n position: absolute;\n top: 1rem;\n left: 1rem;\n z-index: 10;\n width: 350px;\n`;\n\nconst SearchWrapper = styled.div`\n position: relative;\n`;\n\nconst SearchInputContainer = styled.div`\n display: flex;\n align-items: center;\n background: white;\n border: 1px solid #dcdce4;\n border-radius: 4px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n\n &:focus-within {\n border-color: #4945ff;\n box-shadow: 0 0 0 2px rgba(73, 69, 255, 0.2);\n }\n`;\n\nconst SearchIcon = styled.div`\n padding: 0 12px;\n color: #8e8e93;\n display: flex;\n align-items: center;\n`;\n\nconst SearchInput = styled.input`\n flex: 1;\n padding: 10px 0;\n border: none;\n font-size: 14px;\n outline: none;\n background: transparent;\n\n &::placeholder {\n color: #8e8e93;\n }\n`;\n\nconst ClearButton = styled.button`\n padding: 8px 12px;\n background: none;\n border: none;\n cursor: pointer;\n color: #8e8e93;\n display: flex;\n align-items: center;\n\n &:hover {\n color: #666;\n }\n`;\n\nconst LoadingSpinner = styled.div`\n padding: 8px 12px;\n color: #4945ff;\n\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n svg {\n animation: spin 1s linear infinite;\n }\n`;\n\nconst ResultsDropdown = styled.div`\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: white;\n border: 1px solid #dcdce4;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-height: 300px;\n overflow-y: auto;\n`;\n\nconst ResultItem = styled.button`\n width: 100%;\n padding: 12px;\n display: flex;\n align-items: flex-start;\n gap: 12px;\n background: none;\n border: none;\n border-bottom: 1px solid #f0f0f0;\n cursor: pointer;\n text-align: left;\n transition: background-color 0.15s;\n\n &:last-child {\n border-bottom: none;\n }\n\n &:hover {\n background-color: #f6f6f9;\n }\n`;\n\nconst ResultIcon = styled.div`\n width: 32px;\n height: 32px;\n border-radius: 6px;\n background-color: rgba(73, 69, 255, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: #4945ff;\n`;\n\nconst ResultTextContainer = styled.div`\n flex: 1;\n min-width: 0;\n`;\n\nconst ResultTitle = styled.div`\n font-size: 14px;\n font-weight: 500;\n color: #32324d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nconst ResultSubtitle = styled.div`\n font-size: 12px;\n color: #8e8e93;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n`;\n\nconst NoResults = styled.div`\n padding: 16px;\n text-align: center;\n color: #8e8e93;\n font-size: 14px;\n`;\n\nexport interface SearchResult {\n id: string;\n place_name: string;\n center: [number, number];\n place_type: string[];\n}\n\ninterface MapSearchProps {\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n searchResults: SearchResult[];\n isSearching: boolean;\n onSelectResult: (result: SearchResult) => void;\n onClear: () => void;\n showResults: boolean;\n setShowResults: (show: boolean) => void;\n}\n\nconst getPlaceIcon = (placeType: string[]) => {\n if (placeType.includes('poi')) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\" />\n </svg>\n );\n }\n if (placeType.includes('address')) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\" />\n </svg>\n );\n }\n if (placeType.includes('place') || placeType.includes('locality')) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z\" />\n </svg>\n );\n }\n if (placeType.includes('region') || placeType.includes('country')) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z\" />\n </svg>\n );\n }\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\" />\n </svg>\n );\n};\n\nexport const MapSearch: React.FC<MapSearchProps> = ({\n searchQuery,\n setSearchQuery,\n searchResults,\n isSearching,\n onSelectResult,\n onClear,\n showResults,\n setShowResults,\n}) => {\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(e.target.value);\n setShowResults(true);\n };\n\n const handleResultClick = (result: SearchResult) => {\n onSelectResult(result);\n setShowResults(false);\n };\n\n const handleClear = () => {\n onClear();\n setShowResults(false);\n };\n\n return (\n <ControlsContainer>\n <SearchWrapper>\n <SearchInputContainer>\n <SearchIcon>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />\n </svg>\n </SearchIcon>\n <SearchInput\n type=\"text\"\n value={searchQuery}\n onChange={handleInputChange}\n onFocus={() => setShowResults(true)}\n placeholder=\"Search for a location...\"\n />\n {isSearching && (\n <LoadingSpinner>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z\" />\n </svg>\n </LoadingSpinner>\n )}\n {searchQuery && !isSearching && (\n <ClearButton onClick={handleClear} type=\"button\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </ClearButton>\n )}\n </SearchInputContainer>\n\n {showResults && searchQuery.length > 2 && (\n <ResultsDropdown>\n {searchResults.length > 0 ? (\n searchResults.map((result) => {\n const [title, ...rest] = result.place_name.split(',');\n const subtitle = rest.join(',').trim();\n return (\n <ResultItem\n key={result.id}\n onClick={() => handleResultClick(result)}\n type=\"button\"\n >\n <ResultIcon>{getPlaceIcon(result.place_type)}</ResultIcon>\n <ResultTextContainer>\n <ResultTitle>{title}</ResultTitle>\n {subtitle && <ResultSubtitle>{subtitle}</ResultSubtitle>}\n </ResultTextContainer>\n </ResultItem>\n );\n })\n ) : !isSearching ? (\n <NoResults>No results found</NoResults>\n ) : null}\n </ResultsDropdown>\n )}\n </SearchWrapper>\n </ControlsContainer>\n );\n};\n","export type MapBoxValue = {\n longitude: number;\n latitude: number;\n zoom: number;\n pitch: number;\n bearing: number;\n address: string;\n}\n\n\nexport interface ViewState {\n longitude: number;\n latitude: number;\n zoom: number;\n pitch: number;\n bearing: number;\n padding?: {\n top: number;\n bottom: number;\n left: number;\n right: number;\n };\n}\n\nexport const DEFAULT_VIEW_STATE: ViewState = {\n longitude: -122.4194,\n latitude: 37.7749,\n zoom: 13,\n pitch: 0,\n bearing: 0,\n padding: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n }\n};","import { type MapBoxValue, type ViewState, DEFAULT_VIEW_STATE } from './types';\n\nimport { useEffect, useState } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\n\ntype config = {\n accessToken: string;\n debugMode: boolean;\n};\n\nexport const useMapBoxSettings = () => {\n const { get } = useFetchClient();\n const [config, setConfig] = useState<config | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchSettings = async () => {\n try {\n setIsLoading(true);\n const { data } = await get('/map-box/get-settings');\n console.log('data from getSettings', data);\n setConfig(data);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch MapBox settings');\n } finally {\n setIsLoading(false);\n }\n };\n fetchSettings();\n }, []);\n\n return { config, isLoading, error };\n};\n\nexport const useMapLocationHook = (initialValue?: MapBoxValue) => {\n const [viewState, setViewState] = useState<ViewState>(DEFAULT_VIEW_STATE);\n const [markerPosition, setMarkerPosition] = useState({\n longitude: DEFAULT_VIEW_STATE.longitude,\n latitude: DEFAULT_VIEW_STATE.latitude,\n });\n\n useEffect(() => {\n if (initialValue) {\n console.log('Initializing from previous value:', initialValue);\n const previousValue = initialValue;\n\n setViewState((prev) => ({\n ...prev,\n longitude: previousValue.longitude,\n latitude: previousValue.latitude,\n zoom: previousValue.zoom,\n pitch: previousValue.pitch,\n bearing: previousValue.bearing,\n }));\n\n setMarkerPosition({\n longitude: previousValue.longitude,\n latitude: previousValue.latitude,\n });\n }\n }, []);\n\n return { viewState, setViewState, markerPosition, setMarkerPosition };\n};\n\nexport const useLocationService = () => {\n const { get } = useFetchClient();\n const [searchError, setSearchError] = useState<string | null>(null);\n const [searchResults, setSearchResults] = useState<any>(null);\n\n const searchLocation = async (query: string) => {\n try {\n setSearchError(null);\n const encodedQuery = encodeURIComponent(query.trim());\n const { data } = await get(`/strapi-plugin-map-box/location-search/${encodedQuery}`);\n setSearchResults(data);\n return data;\n } catch (error) {\n setSearchError(error instanceof Error ? error.message : 'An error occurred');\n return null;\n }\n };\n\n return { searchLocation, searchError, searchResults };\n};\n","import styled from 'styled-components';\nimport { ViewState } from './types';\n\n\ninterface DebugInfoProps {\n searchResults: any;\n searchError: string | null;\n viewState: ViewState;\n markerPosition: { longitude: number; latitude: number };\n searchQuery: string;\n value?: any;\n}\n\nexport function DebugInfo({ \n searchResults, \n searchError, \n viewState,\n markerPosition,\n searchQuery,\n value \n}: DebugInfoProps) {\n return (\n <DebugContainer>\n <h4>Debug Information:</h4>\n \n <DebugSection>\n <strong>Search Results:</strong>\n <DebugPre>\n {searchResults ? JSON.stringify(searchResults, null, 2) : 'No search results yet'}\n </DebugPre>\n </DebugSection>\n\n {searchError && (\n <ErrorMessage>\n <strong>Error:</strong> {searchError}\n </ErrorMessage>\n )}\n\n <DebugSection>\n <strong>Current View State:</strong>\n <DebugPre>\n {JSON.stringify(viewState, null, 2)}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Marker Position:</strong>\n <DebugPre>\n {JSON.stringify(markerPosition, null, 2)}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Search Query:</strong>\n <DebugPre>\n {searchQuery || 'No search query'}\n </DebugPre>\n </DebugSection>\n\n <DebugSection>\n <strong>Current Value:</strong>\n <DebugPre>\n {value ? JSON.stringify(value, null, 2) : 'No value set'}\n </DebugPre>\n </DebugSection>\n </DebugContainer>\n );\n}\n\nconst DebugContainer = styled.div`\n margin-top: 20px;\n padding: 1rem;\n background-color: #f5f5f5;\n border-radius: 4px;\n`;\n\nconst DebugSection = styled.div`\n margin-bottom: 10px;\n`;\n\nconst DebugPre = styled.pre`\n background: #ffffff;\n padding: 10px;\n border-radius: 4px;\n max-height: 200px;\n overflow: auto;\n margin: 5px 0;\n border: 1px solid #dcdce4;\n`;\n\nconst ErrorMessage = styled.div`\n color: #d02b20;\n margin-bottom: 10px;\n padding: 10px;\n background-color: #fff5f5;\n border: 1px solid #ffd7d5;\n border-radius: 4px;\n`;","import { MapBoxValue } from './types';\nimport { Field, JSONInput } from '@strapi/design-system';\n\nimport Map, {\n FullscreenControl,\n GeolocateControl,\n Marker,\n NavigationControl,\n} from 'react-map-gl/mapbox';\n\nimport 'mapbox-gl/dist/mapbox-gl.css';\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { useFetchClient } from '@strapi/strapi/admin';\nimport { MapSearch, SearchResult } from './MapSearch';\n\nimport { useMapBoxSettings, useMapLocationHook } from './hooks';\nimport { DebugInfo } from './DebugInfo';\n\ninterface MapBoxFieldProps {\n name: string;\n onChange: (event: { target: { name: string; value: object; type: string } }) => void;\n value?: MapBoxValue;\n intlLabel?: {\n defaultMessage: string;\n };\n required?: boolean;\n}\n\nexport function MapBoxField({ name, onChange, value, intlLabel, required }: MapBoxFieldProps) {\n const { get } = useFetchClient();\n const { config, isLoading, error } = useMapBoxSettings();\n const { viewState, markerPosition, setViewState, setMarkerPosition } = useMapLocationHook(value);\n\n const { accessToken, debugMode } = config || {};\n\n const [searchQuery, setSearchQuery] = useState('');\n const [searchResults, setSearchResults] = useState<SearchResult[]>([]);\n const [isSearching, setIsSearching] = useState(false);\n const [showResults, setShowResults] = useState(false);\n const [searchError, setSearchError] = useState<string | null>(null);\n const searchTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const updateMarkerPosition = useCallback(\n (lng: number, lat: number, address?: string) => {\n setMarkerPosition({ longitude: lng, latitude: lat });\n\n const newValue = {\n longitude: lng,\n latitude: lat,\n address: address || 'Selected location',\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n };\n\n onChange({ target: { name, value: newValue, type: 'json' } });\n },\n [name, onChange, setMarkerPosition, viewState.zoom, viewState.pitch, viewState.bearing]\n );\n\n // Debounced search as user types\n useEffect(() => {\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n\n if (searchQuery.trim().length <= 2) {\n setSearchResults([]);\n setIsSearching(false);\n return;\n }\n\n setIsSearching(true);\n\n searchTimeoutRef.current = setTimeout(async () => {\n try {\n setSearchError(null);\n const encodedQuery = encodeURIComponent(searchQuery.trim());\n const url = `/map-box/location-search/${encodedQuery}`;\n const { data } = await get(url);\n\n if (data.features) {\n setSearchResults(\n data.features.slice(0, 5).map((feature: any) => ({\n id: feature.id,\n place_name: feature.place_name,\n center: feature.center,\n place_type: feature.place_type,\n }))\n );\n } else if (data.error) {\n setSearchError(data.error);\n setSearchResults([]);\n } else {\n setSearchResults([]);\n }\n } catch (error) {\n console.error('Error searching location:', error);\n setSearchError(error instanceof Error ? error.message : 'An error occurred');\n setSearchResults([]);\n } finally {\n setIsSearching(false);\n }\n }, 300);\n\n return () => {\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n };\n }, [searchQuery, get]);\n\n const handleSelectResult = useCallback(\n (result: SearchResult) => {\n const [longitude, latitude] = result.center;\n\n setViewState((prev) => ({\n ...prev,\n longitude,\n latitude,\n zoom: 14,\n transitionDuration: 1000,\n }));\n\n updateMarkerPosition(longitude, latitude, result.place_name);\n setSearchQuery(result.place_name.split(',')[0]);\n setSearchResults([]);\n setShowResults(false);\n },\n [setViewState, updateMarkerPosition]\n );\n\n const handleClearSearch = useCallback(() => {\n setSearchQuery('');\n setSearchResults([]);\n setShowResults(false);\n }, []);\n\n const handleMapClick = (event: any) => {\n const { lngLat } = event;\n updateMarkerPosition(lngLat.lng, lngLat.lat);\n };\n\n const handleMapMove = (evt: any) => {\n setViewState(evt.viewState);\n };\n\n const handleMapMoveEnd = (evt: any) => {\n const { longitude, latitude, zoom, pitch, bearing } = evt.viewState;\n\n // Save the current view state including zoom level\n const newValue = {\n longitude: markerPosition.longitude,\n latitude: markerPosition.latitude,\n address: (value as MapBoxValue)?.address || 'Selected location',\n zoom,\n pitch,\n bearing,\n };\n\n onChange({ target: { name, value: newValue, type: 'json' } });\n };\n\n const handleMarkerDragEnd = (event: any) => {\n const { lngLat } = event;\n updateMarkerPosition(lngLat.lng, lngLat.lat);\n };\n\n const handlePositionChange = (input: string) => {\n try {\n const value = JSON.parse(input);\n setViewState((prev) => ({\n ...prev,\n longitude: value.longitude,\n latitude: value.latitude,\n zoom: value.zoom || prev.zoom,\n pitch: value.pitch || prev.pitch,\n bearing: value.bearing || prev.bearing,\n }));\n setMarkerPosition({\n longitude: value.longitude,\n latitude: value.latitude,\n });\n onChange({ target: { name, value, type: 'json' } });\n } catch {\n // Handle invalid JSON\n }\n };\n\n // Construct the final JSON value to be saved\n const finalValue: MapBoxValue = {\n longitude: markerPosition.longitude,\n latitude: markerPosition.latitude,\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n address: (value as MapBoxValue)?.address || 'Selected location',\n };\n\n const strValue = JSON.stringify(value || finalValue, null, 2);\n\n if (!accessToken || isLoading) {\n return <div>Loading...</div>;\n }\n\n if (error) {\n return <div>Error: {error}</div>;\n }\n\n return (\n <div>\n <div style={{ position: 'relative', height: '500px', width: '100%' }}>\n <MapSearch\n searchQuery={searchQuery}\n setSearchQuery={setSearchQuery}\n searchResults={searchResults}\n isSearching={isSearching}\n onSelectResult={handleSelectResult}\n onClear={handleClearSearch}\n showResults={showResults}\n setShowResults={setShowResults}\n />\n <Map\n {...viewState}\n onMove={handleMapMove}\n onMoveEnd={handleMapMoveEnd}\n onClick={handleMapClick}\n mapStyle=\"mapbox://styles/mapbox/streets-v12\"\n mapboxAccessToken={accessToken}\n attributionControl={false}\n style={{ height: '100%', width: '100%' }}\n >\n <FullscreenControl />\n <NavigationControl />\n <GeolocateControl />\n <Marker\n longitude={markerPosition.longitude}\n latitude={markerPosition.latitude}\n color=\"#4945ff\"\n draggable\n onDragEnd={handleMarkerDragEnd}\n />\n </Map>\n </div>\n {debugMode && (\n <Field.Root name={name} required={required}>\n <Field.Label>{intlLabel?.defaultMessage ?? 'Location'}</Field.Label>\n <JSONInput value={strValue} onChange={handlePositionChange}></JSONInput>\n <Field.Error />\n <Field.Hint />\n </Field.Root>\n )}\n\n {debugMode && (\n <DebugInfo\n viewState={viewState}\n searchResults={searchResults}\n searchError={searchError}\n markerPosition={markerPosition}\n searchQuery={searchQuery}\n value={value}\n />\n )}\n </div>\n );\n}\n","import { getTranslation } from './utils/getTranslation';\nimport { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\nimport { PinMap } from '@strapi/icons';\nimport { MapBoxField } from './components/custom-field/MapBoxField/index';\n\nexport default {\n register(app: any) {\n \n app.customFields.register({\n name: 'map-box',\n type: 'json',\n icon: PinMap,\n intlLabel: {\n id: 'custom.fields.map-box.label',\n defaultMessage: 'Map Box',\n },\n intlDescription: {\n id: 'custom.fields.map-box.description',\n defaultMessage: 'Enter geographic coordinates',\n },\n components: {\n Input: () => ({ default: MapBoxField as React.ComponentType }) as any,\n },\n });\n\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads({ locales }: { locales: string[] }) {\n return Promise.all(\n locales.map(async (locale) => {\n try {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return { data, locale };\n } catch {\n return { data: {}, locale };\n }\n })\n );\n },\n};\n"],"names":["error","value"],"mappings":"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"}
@@ -1,9 +1,19 @@
1
1
  import React from 'react';
2
+ export interface SearchResult {
3
+ id: string;
4
+ place_name: string;
5
+ center: [number, number];
6
+ place_type: string[];
7
+ }
2
8
  interface MapSearchProps {
3
- onSearch: () => void;
4
9
  searchQuery: string;
5
10
  setSearchQuery: (query: string) => void;
6
- handleKeyDown: (e: React.KeyboardEvent) => void;
11
+ searchResults: SearchResult[];
12
+ isSearching: boolean;
13
+ onSelectResult: (result: SearchResult) => void;
14
+ onClear: () => void;
15
+ showResults: boolean;
16
+ setShowResults: (show: boolean) => void;
7
17
  }
8
18
  export declare const MapSearch: React.FC<MapSearchProps>;
9
19
  export {};