strapi-plugin-map-box 0.0.1
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.
- package/README.md +4 -0
- package/dist/_chunks/en-B4KWt_jN.js +5 -0
- package/dist/_chunks/en-B4KWt_jN.js.map +1 -0
- package/dist/_chunks/en-Byx4XI2L.mjs +5 -0
- package/dist/_chunks/en-Byx4XI2L.mjs.map +1 -0
- package/dist/admin/index.js +419 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +417 -0
- package/dist/admin/index.mjs.map +1 -0
- package/dist/admin/src/components/Initializer.d.ts +5 -0
- package/dist/admin/src/components/PluginIcon.d.ts +2 -0
- package/dist/admin/src/components/custom-field/MapBoxField/DebugInfo.d.ts +14 -0
- package/dist/admin/src/components/custom-field/MapBoxField/MapSearch.d.ts +9 -0
- package/dist/admin/src/components/custom-field/MapBoxField/hooks.d.ts +29 -0
- package/dist/admin/src/components/custom-field/MapBoxField/index.d.ts +19 -0
- package/dist/admin/src/components/custom-field/MapBoxField/styles.d.ts +6 -0
- package/dist/admin/src/components/custom-field/MapBoxField/types.d.ts +22 -0
- package/dist/admin/src/index.d.ts +10 -0
- package/dist/admin/src/pages/App.d.ts +2 -0
- package/dist/admin/src/pages/HomePage.d.ts +2 -0
- package/dist/admin/src/pluginId.d.ts +1 -0
- package/dist/admin/src/utils/getTranslation.d.ts +2 -0
- package/dist/server/index.js +116 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +117 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/server/src/bootstrap.d.ts +5 -0
- package/dist/server/src/config/index.d.ts +5 -0
- package/dist/server/src/content-types/index.d.ts +2 -0
- package/dist/server/src/controllers/controller.d.ts +8 -0
- package/dist/server/src/controllers/index.d.ts +9 -0
- package/dist/server/src/destroy.d.ts +5 -0
- package/dist/server/src/index.d.ts +54 -0
- package/dist/server/src/middlewares/index.d.ts +2 -0
- package/dist/server/src/policies/index.d.ts +2 -0
- package/dist/server/src/register.d.ts +5 -0
- package/dist/server/src/routes/admin-api.d.ts +9 -0
- package/dist/server/src/routes/content-api.d.ts +2 -0
- package/dist/server/src/routes/index.d.ts +18 -0
- package/dist/server/src/services/index.d.ts +11 -0
- package/dist/server/src/services/service.d.ts +33 -0
- package/dist/server/src/utils/index.d.ts +4 -0
- package/dist/types.d.ts +6 -0
- package/package.json +89 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en-B4KWt_jN.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en-Byx4XI2L.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const react = require("react");
|
|
3
|
+
const icons = require("@strapi/icons");
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const designSystem = require("@strapi/design-system");
|
|
6
|
+
const Map = require("react-map-gl/mapbox");
|
|
7
|
+
require("mapbox-gl/dist/mapbox-gl.css");
|
|
8
|
+
const admin = require("@strapi/strapi/admin");
|
|
9
|
+
const styled = require("styled-components");
|
|
10
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
11
|
+
const Map__default = /* @__PURE__ */ _interopDefault(Map);
|
|
12
|
+
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
13
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
14
|
+
const v = glob[path];
|
|
15
|
+
if (v) {
|
|
16
|
+
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
17
|
+
}
|
|
18
|
+
return new Promise((_, reject) => {
|
|
19
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
20
|
+
reject.bind(
|
|
21
|
+
null,
|
|
22
|
+
new Error(
|
|
23
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
const PLUGIN_ID = "map-box";
|
|
30
|
+
const Initializer = ({ setPlugin }) => {
|
|
31
|
+
const ref = react.useRef(setPlugin);
|
|
32
|
+
react.useEffect(() => {
|
|
33
|
+
ref.current(PLUGIN_ID);
|
|
34
|
+
}, []);
|
|
35
|
+
return null;
|
|
36
|
+
};
|
|
37
|
+
const ControlsContainer = styled__default.default.div`
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: 1rem;
|
|
40
|
+
left: 1rem;
|
|
41
|
+
z-index: 1;
|
|
42
|
+
width: 300px;
|
|
43
|
+
`;
|
|
44
|
+
const ControlsWrapper = styled__default.default.div`
|
|
45
|
+
display: flex;
|
|
46
|
+
gap: 0.5rem;
|
|
47
|
+
`;
|
|
48
|
+
const SearchInput = styled__default.default.input`
|
|
49
|
+
flex: 1;
|
|
50
|
+
padding: 0.5rem;
|
|
51
|
+
border: 1px solid #dcdce4;
|
|
52
|
+
border-radius: 4px;
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
`;
|
|
55
|
+
const SearchButton = styled__default.default.button`
|
|
56
|
+
padding: 0.5rem 1rem;
|
|
57
|
+
background-color: #4945ff;
|
|
58
|
+
color: white;
|
|
59
|
+
border: none;
|
|
60
|
+
border-radius: 4px;
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
font-size: 14px;
|
|
63
|
+
|
|
64
|
+
&:hover {
|
|
65
|
+
background-color: #3832e0;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
const MapSearch = ({
|
|
69
|
+
onSearch,
|
|
70
|
+
searchQuery,
|
|
71
|
+
setSearchQuery,
|
|
72
|
+
handleKeyDown
|
|
73
|
+
}) => {
|
|
74
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ControlsContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(ControlsWrapper, { children: [
|
|
75
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
76
|
+
SearchInput,
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
value: searchQuery,
|
|
80
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
81
|
+
onKeyDown: handleKeyDown,
|
|
82
|
+
placeholder: "Search for a location..."
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
+
SearchButton,
|
|
87
|
+
{
|
|
88
|
+
type: "button",
|
|
89
|
+
onClick: onSearch,
|
|
90
|
+
children: "Search"
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
] }) });
|
|
94
|
+
};
|
|
95
|
+
const DEFAULT_VIEW_STATE = {
|
|
96
|
+
longitude: -122.4194,
|
|
97
|
+
latitude: 37.7749,
|
|
98
|
+
zoom: 13,
|
|
99
|
+
pitch: 0,
|
|
100
|
+
bearing: 0,
|
|
101
|
+
padding: {
|
|
102
|
+
top: 0,
|
|
103
|
+
bottom: 0,
|
|
104
|
+
left: 0,
|
|
105
|
+
right: 0
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const useMapBoxSettings = () => {
|
|
109
|
+
const { get } = admin.useFetchClient();
|
|
110
|
+
const [config, setConfig] = react.useState(null);
|
|
111
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
112
|
+
const [error, setError] = react.useState(null);
|
|
113
|
+
react.useEffect(() => {
|
|
114
|
+
const fetchSettings = async () => {
|
|
115
|
+
try {
|
|
116
|
+
setIsLoading(true);
|
|
117
|
+
const { data } = await get("/strapi-plugin-map-box/get-settings");
|
|
118
|
+
console.log("data from getSettings", data);
|
|
119
|
+
setConfig(data);
|
|
120
|
+
setError(null);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
setError(err instanceof Error ? err.message : "Failed to fetch MapBox settings");
|
|
123
|
+
} finally {
|
|
124
|
+
setIsLoading(false);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
fetchSettings();
|
|
128
|
+
}, []);
|
|
129
|
+
return { config, isLoading, error };
|
|
130
|
+
};
|
|
131
|
+
const useMapLocationHook = (initialValue) => {
|
|
132
|
+
const [viewState, setViewState] = react.useState(DEFAULT_VIEW_STATE);
|
|
133
|
+
const [markerPosition, setMarkerPosition] = react.useState({
|
|
134
|
+
longitude: DEFAULT_VIEW_STATE.longitude,
|
|
135
|
+
latitude: DEFAULT_VIEW_STATE.latitude
|
|
136
|
+
});
|
|
137
|
+
react.useEffect(() => {
|
|
138
|
+
if (initialValue) {
|
|
139
|
+
console.log("Initializing from previous value:", initialValue);
|
|
140
|
+
const previousValue = initialValue;
|
|
141
|
+
setViewState((prev) => ({
|
|
142
|
+
...prev,
|
|
143
|
+
longitude: previousValue.longitude,
|
|
144
|
+
latitude: previousValue.latitude,
|
|
145
|
+
zoom: previousValue.zoom,
|
|
146
|
+
pitch: previousValue.pitch,
|
|
147
|
+
bearing: previousValue.bearing
|
|
148
|
+
}));
|
|
149
|
+
setMarkerPosition({
|
|
150
|
+
longitude: previousValue.longitude,
|
|
151
|
+
latitude: previousValue.latitude
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}, []);
|
|
155
|
+
return { viewState, setViewState, markerPosition, setMarkerPosition };
|
|
156
|
+
};
|
|
157
|
+
function DebugInfo({
|
|
158
|
+
searchResults,
|
|
159
|
+
searchError,
|
|
160
|
+
viewState,
|
|
161
|
+
markerPosition,
|
|
162
|
+
searchQuery,
|
|
163
|
+
value
|
|
164
|
+
}) {
|
|
165
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DebugContainer, { children: [
|
|
166
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { children: "Debug Information:" }),
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DebugSection, { children: [
|
|
168
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Search Results:" }),
|
|
169
|
+
/* @__PURE__ */ jsxRuntime.jsx(DebugPre, { children: searchResults ? JSON.stringify(searchResults, null, 2) : "No search results yet" })
|
|
170
|
+
] }),
|
|
171
|
+
searchError && /* @__PURE__ */ jsxRuntime.jsxs(ErrorMessage, { children: [
|
|
172
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Error:" }),
|
|
173
|
+
" ",
|
|
174
|
+
searchError
|
|
175
|
+
] }),
|
|
176
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DebugSection, { children: [
|
|
177
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Current View State:" }),
|
|
178
|
+
/* @__PURE__ */ jsxRuntime.jsx(DebugPre, { children: JSON.stringify(viewState, null, 2) })
|
|
179
|
+
] }),
|
|
180
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DebugSection, { children: [
|
|
181
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Marker Position:" }),
|
|
182
|
+
/* @__PURE__ */ jsxRuntime.jsx(DebugPre, { children: JSON.stringify(markerPosition, null, 2) })
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DebugSection, { children: [
|
|
185
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Search Query:" }),
|
|
186
|
+
/* @__PURE__ */ jsxRuntime.jsx(DebugPre, { children: searchQuery || "No search query" })
|
|
187
|
+
] }),
|
|
188
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DebugSection, { children: [
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Current Value:" }),
|
|
190
|
+
/* @__PURE__ */ jsxRuntime.jsx(DebugPre, { children: value ? JSON.stringify(value, null, 2) : "No value set" })
|
|
191
|
+
] })
|
|
192
|
+
] });
|
|
193
|
+
}
|
|
194
|
+
const DebugContainer = styled__default.default.div`
|
|
195
|
+
margin-top: 20px;
|
|
196
|
+
padding: 1rem;
|
|
197
|
+
background-color: #f5f5f5;
|
|
198
|
+
border-radius: 4px;
|
|
199
|
+
`;
|
|
200
|
+
const DebugSection = styled__default.default.div`
|
|
201
|
+
margin-bottom: 10px;
|
|
202
|
+
`;
|
|
203
|
+
const DebugPre = styled__default.default.pre`
|
|
204
|
+
background: #ffffff;
|
|
205
|
+
padding: 10px;
|
|
206
|
+
border-radius: 4px;
|
|
207
|
+
max-height: 200px;
|
|
208
|
+
overflow: auto;
|
|
209
|
+
margin: 5px 0;
|
|
210
|
+
border: 1px solid #dcdce4;
|
|
211
|
+
`;
|
|
212
|
+
const ErrorMessage = styled__default.default.div`
|
|
213
|
+
color: #d02b20;
|
|
214
|
+
margin-bottom: 10px;
|
|
215
|
+
padding: 10px;
|
|
216
|
+
background-color: #fff5f5;
|
|
217
|
+
border: 1px solid #ffd7d5;
|
|
218
|
+
border-radius: 4px;
|
|
219
|
+
`;
|
|
220
|
+
function MapBoxField({ name, onChange, value, intlLabel, required }) {
|
|
221
|
+
const { get } = admin.useFetchClient();
|
|
222
|
+
const { config, isLoading, error } = useMapBoxSettings();
|
|
223
|
+
const { viewState, markerPosition, setViewState, setMarkerPosition } = useMapLocationHook(value);
|
|
224
|
+
const { accessToken, debugMode } = config || {};
|
|
225
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
226
|
+
const [searchResults, setSearchResults] = react.useState(null);
|
|
227
|
+
const [searchError, setSearchError] = react.useState(null);
|
|
228
|
+
const updateMarkerPosition = (lng, lat, address) => {
|
|
229
|
+
setMarkerPosition({ longitude: lng, latitude: lat });
|
|
230
|
+
const newValue = {
|
|
231
|
+
longitude: lng,
|
|
232
|
+
latitude: lat,
|
|
233
|
+
address: address || "Selected location",
|
|
234
|
+
zoom: viewState.zoom,
|
|
235
|
+
pitch: viewState.pitch,
|
|
236
|
+
bearing: viewState.bearing
|
|
237
|
+
};
|
|
238
|
+
onChange({ target: { name, value: newValue, type: "json" } });
|
|
239
|
+
};
|
|
240
|
+
const handleSearch = async () => {
|
|
241
|
+
if (!searchQuery.trim()) return;
|
|
242
|
+
try {
|
|
243
|
+
setSearchError(null);
|
|
244
|
+
const encodedQuery = encodeURIComponent(searchQuery.trim());
|
|
245
|
+
const url = `/strapi-plugin-map-box/location-search/${encodedQuery}`;
|
|
246
|
+
const { data } = await get(url);
|
|
247
|
+
setSearchResults(data);
|
|
248
|
+
if (data.features && data.features[0]) {
|
|
249
|
+
const [longitude, latitude] = data.features[0].center;
|
|
250
|
+
setViewState((prev) => ({
|
|
251
|
+
...prev,
|
|
252
|
+
longitude,
|
|
253
|
+
latitude,
|
|
254
|
+
zoom: 14,
|
|
255
|
+
transitionDuration: 1e3
|
|
256
|
+
}));
|
|
257
|
+
updateMarkerPosition(longitude, latitude, data.features[0].place_name);
|
|
258
|
+
} else if (data.error) {
|
|
259
|
+
setSearchError(data.error);
|
|
260
|
+
} else {
|
|
261
|
+
setSearchError("No results found");
|
|
262
|
+
}
|
|
263
|
+
} catch (error2) {
|
|
264
|
+
console.error("Error searching location:", error2);
|
|
265
|
+
setSearchError(error2 instanceof Error ? error2.message : "An error occurred");
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
const handleKeyDown = (e) => {
|
|
269
|
+
if (e.key === "Enter") {
|
|
270
|
+
e.preventDefault();
|
|
271
|
+
handleSearch();
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
const handleMapClick = (event) => {
|
|
275
|
+
const { lngLat } = event;
|
|
276
|
+
updateMarkerPosition(lngLat.lng, lngLat.lat);
|
|
277
|
+
};
|
|
278
|
+
const handleMapMove = (evt) => {
|
|
279
|
+
setViewState(evt.viewState);
|
|
280
|
+
};
|
|
281
|
+
const handleMarkerDragEnd = (event) => {
|
|
282
|
+
const { lngLat } = event;
|
|
283
|
+
updateMarkerPosition(lngLat.lng, lngLat.lat);
|
|
284
|
+
};
|
|
285
|
+
const handlePositionChange = (input) => {
|
|
286
|
+
try {
|
|
287
|
+
const value2 = JSON.parse(input);
|
|
288
|
+
setViewState((prev) => ({
|
|
289
|
+
...prev,
|
|
290
|
+
longitude: value2.longitude,
|
|
291
|
+
latitude: value2.latitude,
|
|
292
|
+
zoom: value2.zoom || prev.zoom,
|
|
293
|
+
pitch: value2.pitch || prev.pitch,
|
|
294
|
+
bearing: value2.bearing || prev.bearing
|
|
295
|
+
}));
|
|
296
|
+
setMarkerPosition({
|
|
297
|
+
longitude: value2.longitude,
|
|
298
|
+
latitude: value2.latitude
|
|
299
|
+
});
|
|
300
|
+
onChange({ target: { name, value: value2, type: "json" } });
|
|
301
|
+
} catch {
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const finalValue = {
|
|
305
|
+
longitude: markerPosition.longitude,
|
|
306
|
+
latitude: markerPosition.latitude,
|
|
307
|
+
zoom: viewState.zoom,
|
|
308
|
+
pitch: viewState.pitch,
|
|
309
|
+
bearing: viewState.bearing,
|
|
310
|
+
address: value?.address || "Selected location"
|
|
311
|
+
};
|
|
312
|
+
const strValue = JSON.stringify(value || finalValue, null, 2);
|
|
313
|
+
if (!accessToken || isLoading) {
|
|
314
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." });
|
|
315
|
+
}
|
|
316
|
+
if (error) {
|
|
317
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
318
|
+
"Error: ",
|
|
319
|
+
error
|
|
320
|
+
] });
|
|
321
|
+
}
|
|
322
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
323
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", height: "500px", width: "100%" }, children: [
|
|
324
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
325
|
+
MapSearch,
|
|
326
|
+
{
|
|
327
|
+
onSearch: handleSearch,
|
|
328
|
+
searchQuery,
|
|
329
|
+
setSearchQuery,
|
|
330
|
+
handleKeyDown
|
|
331
|
+
}
|
|
332
|
+
),
|
|
333
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
334
|
+
Map__default.default,
|
|
335
|
+
{
|
|
336
|
+
...viewState,
|
|
337
|
+
onMove: handleMapMove,
|
|
338
|
+
onClick: handleMapClick,
|
|
339
|
+
mapStyle: "mapbox://styles/mapbox/streets-v12",
|
|
340
|
+
mapboxAccessToken: accessToken,
|
|
341
|
+
attributionControl: false,
|
|
342
|
+
style: { height: "100%", width: "100%" },
|
|
343
|
+
children: [
|
|
344
|
+
/* @__PURE__ */ jsxRuntime.jsx(Map.FullscreenControl, {}),
|
|
345
|
+
/* @__PURE__ */ jsxRuntime.jsx(Map.NavigationControl, {}),
|
|
346
|
+
/* @__PURE__ */ jsxRuntime.jsx(Map.GeolocateControl, {}),
|
|
347
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
348
|
+
Map.Marker,
|
|
349
|
+
{
|
|
350
|
+
longitude: markerPosition.longitude,
|
|
351
|
+
latitude: markerPosition.latitude,
|
|
352
|
+
color: "#4945ff",
|
|
353
|
+
draggable: true,
|
|
354
|
+
onDragEnd: handleMarkerDragEnd
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
] }),
|
|
361
|
+
debugMode && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name, required, children: [
|
|
362
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: intlLabel?.defaultMessage ?? "Location" }),
|
|
363
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.JSONInput, { value: strValue, onChange: handlePositionChange }),
|
|
364
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {}),
|
|
365
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
|
|
366
|
+
] }),
|
|
367
|
+
debugMode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
368
|
+
DebugInfo,
|
|
369
|
+
{
|
|
370
|
+
viewState,
|
|
371
|
+
searchResults,
|
|
372
|
+
searchError,
|
|
373
|
+
markerPosition,
|
|
374
|
+
searchQuery,
|
|
375
|
+
value
|
|
376
|
+
}
|
|
377
|
+
)
|
|
378
|
+
] });
|
|
379
|
+
}
|
|
380
|
+
const index = {
|
|
381
|
+
register(app) {
|
|
382
|
+
app.customFields.register({
|
|
383
|
+
name: "map-box",
|
|
384
|
+
type: "json",
|
|
385
|
+
icon: icons.PinMap,
|
|
386
|
+
intlLabel: {
|
|
387
|
+
id: "custom.fields.map-box.label",
|
|
388
|
+
defaultMessage: "Map Box"
|
|
389
|
+
},
|
|
390
|
+
intlDescription: {
|
|
391
|
+
id: "custom.fields.map-box.description",
|
|
392
|
+
defaultMessage: "Enter geographic coordinates"
|
|
393
|
+
},
|
|
394
|
+
components: {
|
|
395
|
+
Input: () => ({ default: MapBoxField })
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
app.registerPlugin({
|
|
399
|
+
id: PLUGIN_ID,
|
|
400
|
+
initializer: Initializer,
|
|
401
|
+
isReady: false,
|
|
402
|
+
name: PLUGIN_ID
|
|
403
|
+
});
|
|
404
|
+
},
|
|
405
|
+
async registerTrads({ locales }) {
|
|
406
|
+
return Promise.all(
|
|
407
|
+
locales.map(async (locale) => {
|
|
408
|
+
try {
|
|
409
|
+
const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("../_chunks/en-B4KWt_jN.js")) }), `./translations/${locale}.json`, 3);
|
|
410
|
+
return { data, locale };
|
|
411
|
+
} catch {
|
|
412
|
+
return { data: {}, locale };
|
|
413
|
+
}
|
|
414
|
+
})
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
module.exports = index;
|
|
419
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","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":["useRef","useEffect","styled","jsx","jsxs","useFetchClient","useState","error","value","Map","FullscreenControl","NavigationControl","GeolocateControl","Marker","Field","JSONInput","PinMap"],"mappings":"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"}
|