@vidro/map-handler 1.3.14 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -1
- package/map-handler.d.ts +134 -0
- package/package.json +10 -4
- package/src/types.d.ts +63 -0
- package/.babelrc +0 -6
- package/doc/animation.png +0 -0
- package/doc/confirmComponent.png +0 -0
- package/doc/giswater.png +0 -0
- package/doc/giswaterInfo.png +0 -0
- package/doc/giswaterInfoApi.png +0 -0
- package/doc/giswatergeojson.png +0 -0
- package/doc/multiTile.png +0 -0
- package/doc/multiTileNoGutter.png +0 -0
- package/doc/togglelayergiswater.png +0 -0
- package/doc/vidromaps-basic.png +0 -0
- package/examples/full/apidemo.js +0 -387
- package/examples/full/cachedToken.dat +0 -1
- package/examples/full/cachedTokenData.dat +0 -1
- package/examples/full/docker/Docker_compose.yml +0 -14
- package/examples/full/docker/Dockerfile +0 -27
- package/examples/full/index.php +0 -200
- package/examples/full/storeToken.php +0 -6
- package/examples/full/tester.css +0 -74
- package/examples/full/tester.js +0 -658
- package/examples/multipleIframes/index.js +0 -82
- package/examples/multipleIframes/index.php +0 -52
- package/examples/react-next/README.md +0 -282
- package/examples/react-next/atoms/PrintLayoutSelector.js +0 -51
- package/examples/react-next/atoms/PrintPaperSizeSelector.js +0 -49
- package/examples/react-next/atoms/PrintScaleSelector.js +0 -61
- package/examples/react-next/atoms/ZoomToScaleButton.js +0 -57
- package/examples/react-next/components/AuthComponent.js +0 -88
- package/examples/react-next/components/MapButtons.js +0 -108
- package/examples/react-next/components/MapFilters.js +0 -120
- package/examples/react-next/components/MapIframe.js +0 -25
- package/examples/react-next/components/MapInfo.js +0 -36
- package/examples/react-next/components/MapLayers.js +0 -60
- package/examples/react-next/components/MapList.js +0 -51
- package/examples/react-next/components/MapPrint.js +0 -50
- package/examples/react-next/contexts/auth.js +0 -147
- package/examples/react-next/contexts/maps.js +0 -185
- package/examples/react-next/contexts/messages.js +0 -358
- package/examples/react-next/contexts/print.js +0 -125
- package/examples/react-next/env.sample +0 -3
- package/examples/react-next/eslint.config.mjs +0 -14
- package/examples/react-next/hooks/useMapEvents.js +0 -118
- package/examples/react-next/jsconfig.json +0 -7
- package/examples/react-next/next.config.mjs +0 -6
- package/examples/react-next/package.json +0 -25
- package/examples/react-next/pages/_app.js +0 -5
- package/examples/react-next/pages/index.js +0 -97
- package/examples/react-next/postcss.config.mjs +0 -8
- package/examples/react-next/public/discord.svg +0 -8
- package/examples/react-next/public/favicon.ico +0 -0
- package/examples/react-next/public/file.svg +0 -1
- package/examples/react-next/public/logo.png +0 -0
- package/examples/react-next/public/next.svg +0 -1
- package/examples/react-next/shared/constants.js +0 -48
- package/examples/react-next/shared/cookies.js +0 -23
- package/examples/react-next/styles/globals.css +0 -24
- package/examples/react-next/tailwind.config.mjs +0 -17
- package/examples/serverLess/dist/index.23420cfa.js +0 -2973
- package/examples/serverLess/dist/index.23420cfa.js.map +0 -1
- package/examples/serverLess/dist/index.91b6cacc.js +0 -2
- package/examples/serverLess/dist/index.91b6cacc.js.map +0 -1
- package/examples/serverLess/dist/index.html +0 -1
- package/examples/serverLess/index.html +0 -39
- package/examples/serverLess/main.js +0 -113
- package/examples/serverLess/package.json +0 -18
- package/examples/serverLess/readme.md +0 -41
- package/examples/simple/index.html +0 -23
- package/examples/simple/simple.js +0 -80
- package/examples/taigua/index.html +0 -55
- package/examples/taigua/main.js +0 -490
- package/examples/tester.css +0 -74
- package/examples/vidromap/index.js +0 -20
- package/examples/vidromap/index.php +0 -111
- package/flows.md +0 -73
- package/helpers.md +0 -45
- package/src/index.js +0 -882
- package/src/shared/iframe-communicator.js +0 -18
- package/webpack.config.js +0 -22
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { useAuth } from "@/contexts/auth";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
|
|
4
|
-
const AuthComponent = () => {
|
|
5
|
-
const { apiUrl, setApiUrl, login, logged, logout } = useAuth();
|
|
6
|
-
const [user, setUser] = useState(
|
|
7
|
-
process.env.NEXT_PUBLIC_USER ? process.env.NEXT_PUBLIC_USER : ""
|
|
8
|
-
);
|
|
9
|
-
const [pwd, setPwd] = useState(
|
|
10
|
-
process.env.NEXT_PUBLIC_PWD ? process.env.NEXT_PUBLIC_PWD : ""
|
|
11
|
-
);
|
|
12
|
-
const [selectedMap, setSelectedMap] = useState("-1");
|
|
13
|
-
|
|
14
|
-
// Handler for API URL input changes
|
|
15
|
-
const handleApiUrlChange = (event) => {
|
|
16
|
-
setApiUrl(event.target.value);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div>
|
|
21
|
-
{logged && (
|
|
22
|
-
<div className="bg-gray-200 p-2 text-left">
|
|
23
|
-
<div className="text-xs">
|
|
24
|
-
Logged as <b>{user}</b>
|
|
25
|
-
</div>
|
|
26
|
-
<div className="text-xs">
|
|
27
|
-
API: <b>{apiUrl}</b>
|
|
28
|
-
</div>
|
|
29
|
-
<button
|
|
30
|
-
onClick={(e) => {
|
|
31
|
-
logout();
|
|
32
|
-
}}
|
|
33
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 mt-1 text-xs"
|
|
34
|
-
>
|
|
35
|
-
Logout
|
|
36
|
-
</button>
|
|
37
|
-
</div>
|
|
38
|
-
)}
|
|
39
|
-
{!logged && (
|
|
40
|
-
<div>
|
|
41
|
-
<div className="mb-4 flex gap-1">
|
|
42
|
-
<label className="w-32">API URL</label>
|
|
43
|
-
<input
|
|
44
|
-
type="text"
|
|
45
|
-
value={apiUrl}
|
|
46
|
-
onChange={handleApiUrlChange}
|
|
47
|
-
placeholder="Enter API URL..."
|
|
48
|
-
className="border border-gray-300 rounded-md p-2 w-full"
|
|
49
|
-
/>
|
|
50
|
-
</div>
|
|
51
|
-
<div className="mb-4 flex gap-1">
|
|
52
|
-
<label className="w-32">User</label>
|
|
53
|
-
<input
|
|
54
|
-
type="text"
|
|
55
|
-
value={user}
|
|
56
|
-
onChange={(e) => setUser(e.target.value)}
|
|
57
|
-
placeholder="User"
|
|
58
|
-
disabled={logged}
|
|
59
|
-
className="border border-gray-300 rounded-md p-2 w-full"
|
|
60
|
-
/>
|
|
61
|
-
</div>
|
|
62
|
-
<div className="mb-4 flex gap-1">
|
|
63
|
-
<label className="w-32">Password</label>
|
|
64
|
-
<input
|
|
65
|
-
type="password"
|
|
66
|
-
value={pwd}
|
|
67
|
-
onChange={(e) => setPwd(e.target.value)}
|
|
68
|
-
disabled={logged}
|
|
69
|
-
placeholder="User"
|
|
70
|
-
className="border border-gray-300 rounded-md p-2 w-full"
|
|
71
|
-
/>
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<button
|
|
75
|
-
onClick={(e) => {
|
|
76
|
-
login(user, pwd);
|
|
77
|
-
}}
|
|
78
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
79
|
-
>
|
|
80
|
-
Login
|
|
81
|
-
</button>
|
|
82
|
-
</div>
|
|
83
|
-
)}
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export default AuthComponent;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import ZoomToScaleButton from "@/atoms/ZoomToScaleButton";
|
|
2
|
-
import { useAuth } from "@/contexts/auth";
|
|
3
|
-
import { useMaps } from "@/contexts/maps";
|
|
4
|
-
import { useMessages } from "@/contexts/messages";
|
|
5
|
-
|
|
6
|
-
const MapButtons = () => {
|
|
7
|
-
const { logged } = useAuth();
|
|
8
|
-
const { map, mapReady, clickedCoordinates } = useMaps();
|
|
9
|
-
const {
|
|
10
|
-
ZoomIn,
|
|
11
|
-
ZoomOut,
|
|
12
|
-
zoomToExtent,
|
|
13
|
-
drawPoint,
|
|
14
|
-
Clear,
|
|
15
|
-
Highlight,
|
|
16
|
-
centerMap,
|
|
17
|
-
} = useMessages();
|
|
18
|
-
if (!logged) return null;
|
|
19
|
-
return (
|
|
20
|
-
<>
|
|
21
|
-
{!mapReady && <div>Waiting map...</div>}
|
|
22
|
-
{mapReady && (
|
|
23
|
-
<div className="flex gap-1 text-xs">
|
|
24
|
-
<button
|
|
25
|
-
onClick={(e) => {
|
|
26
|
-
console.log("Zoom +");
|
|
27
|
-
ZoomIn();
|
|
28
|
-
}}
|
|
29
|
-
disabled={!map}
|
|
30
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
31
|
-
>
|
|
32
|
-
Zoom +
|
|
33
|
-
</button>
|
|
34
|
-
<button
|
|
35
|
-
onClick={(e) => {
|
|
36
|
-
console.log("Zoom -");
|
|
37
|
-
ZoomOut();
|
|
38
|
-
}}
|
|
39
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
40
|
-
>
|
|
41
|
-
Zoom -
|
|
42
|
-
</button>
|
|
43
|
-
<button
|
|
44
|
-
onClick={(e) => {
|
|
45
|
-
console.log("Zoom to extent");
|
|
46
|
-
zoomToExtent();
|
|
47
|
-
}}
|
|
48
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
49
|
-
>
|
|
50
|
-
Zoom to extent
|
|
51
|
-
</button>
|
|
52
|
-
<button
|
|
53
|
-
onClick={(e) => {
|
|
54
|
-
console.log("Draw point");
|
|
55
|
-
drawPoint({});
|
|
56
|
-
}}
|
|
57
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
58
|
-
>
|
|
59
|
-
Add point
|
|
60
|
-
</button>
|
|
61
|
-
<button
|
|
62
|
-
onClick={(e) => {
|
|
63
|
-
console.log("Clear");
|
|
64
|
-
Clear();
|
|
65
|
-
}}
|
|
66
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
67
|
-
>
|
|
68
|
-
Clear
|
|
69
|
-
</button>
|
|
70
|
-
<button
|
|
71
|
-
onClick={(e) => {
|
|
72
|
-
console.log("Highlight clickedCoordinates", clickedCoordinates);
|
|
73
|
-
Highlight(
|
|
74
|
-
{
|
|
75
|
-
feature_type: "HIGHLIGHT",
|
|
76
|
-
geom: `POINT(${clickedCoordinates[0]} ${clickedCoordinates[1]})`,
|
|
77
|
-
},
|
|
78
|
-
2,
|
|
79
|
-
{
|
|
80
|
-
duration: 1500,
|
|
81
|
-
repeat: true,
|
|
82
|
-
},
|
|
83
|
-
0,
|
|
84
|
-
null
|
|
85
|
-
);
|
|
86
|
-
}}
|
|
87
|
-
disabled={!clickedCoordinates}
|
|
88
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
89
|
-
>
|
|
90
|
-
Highlight clicked coordinates
|
|
91
|
-
</button>
|
|
92
|
-
<button
|
|
93
|
-
onClick={(e) => {
|
|
94
|
-
console.log("Highlight clickedCoordinates", clickedCoordinates);
|
|
95
|
-
centerMap(clickedCoordinates);
|
|
96
|
-
}}
|
|
97
|
-
disabled={!clickedCoordinates}
|
|
98
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2"
|
|
99
|
-
>
|
|
100
|
-
Center map to clicked coordinates
|
|
101
|
-
</button>
|
|
102
|
-
<ZoomToScaleButton />
|
|
103
|
-
</div>
|
|
104
|
-
)}
|
|
105
|
-
</>
|
|
106
|
-
);
|
|
107
|
-
};
|
|
108
|
-
export default MapButtons;
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { useAuth } from "@/contexts/auth";
|
|
2
|
-
import { useMaps } from "@/contexts/maps";
|
|
3
|
-
import { useMessages } from "@/contexts/messages";
|
|
4
|
-
import { useEffect, useState } from "react";
|
|
5
|
-
|
|
6
|
-
const MapFilters = () => {
|
|
7
|
-
const {
|
|
8
|
-
configuredFilters,
|
|
9
|
-
mapId,
|
|
10
|
-
filters,
|
|
11
|
-
activeFilters,
|
|
12
|
-
|
|
13
|
-
activeLayer,
|
|
14
|
-
mapLayers,
|
|
15
|
-
} = useMaps();
|
|
16
|
-
const { Filters } = useMessages();
|
|
17
|
-
const { logged } = useAuth();
|
|
18
|
-
const [currentFilter, setCurrentFilter] = useState("");
|
|
19
|
-
const [filterValue, setFilterValue] = useState("");
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (!configuredFilters) return;
|
|
22
|
-
console.log("MapFilters configuredFilters", configuredFilters);
|
|
23
|
-
}, [configuredFilters]);
|
|
24
|
-
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (!activeFilters) return;
|
|
27
|
-
console.log("MapFilters activeFilters", activeFilters);
|
|
28
|
-
}, [activeFilters]);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (!filters) return;
|
|
32
|
-
console.log("MapFilters filters", filters);
|
|
33
|
-
}, [filters]);
|
|
34
|
-
|
|
35
|
-
const applyFilter = () => {
|
|
36
|
-
if (!activeLayer) {
|
|
37
|
-
console.log("No active layer");
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
console.log("Apply filter", {
|
|
41
|
-
currentFilter,
|
|
42
|
-
filterValue,
|
|
43
|
-
activeLayer,
|
|
44
|
-
});
|
|
45
|
-
//find layer info
|
|
46
|
-
const lay = mapLayers.find((l) => l.qgis_name === activeLayer);
|
|
47
|
-
console.log("Layer info", lay);
|
|
48
|
-
//format filter for mapComponent digest
|
|
49
|
-
const filter = [
|
|
50
|
-
{
|
|
51
|
-
layer_id: lay.id,
|
|
52
|
-
layer_name: lay.qgis_name,
|
|
53
|
-
filters: [
|
|
54
|
-
[
|
|
55
|
-
{
|
|
56
|
-
name: currentFilter,
|
|
57
|
-
condition: "=", //default condition - you can get condition from configuredFilters
|
|
58
|
-
value: filterValue,
|
|
59
|
-
value2: null,
|
|
60
|
-
layer_id: lay.id,
|
|
61
|
-
mapId: mapId,
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
Filters(filter);
|
|
68
|
-
console.log("Filter", filter);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
if (!logged) return null;
|
|
72
|
-
if (!mapId) return null;
|
|
73
|
-
return (
|
|
74
|
-
<>
|
|
75
|
-
<div>
|
|
76
|
-
{configuredFilters && configuredFilters.length === 0 && (
|
|
77
|
-
<div>No filters available</div>
|
|
78
|
-
)}
|
|
79
|
-
|
|
80
|
-
<div className="m-2 flex gap-2">
|
|
81
|
-
<label className="block text-sm font-medium text-gray-700 pt-2">
|
|
82
|
-
Filters
|
|
83
|
-
</label>
|
|
84
|
-
{configuredFilters && configuredFilters.length > 0 && (
|
|
85
|
-
<select
|
|
86
|
-
className="border border-gray-300 rounded-md p-2 w-60"
|
|
87
|
-
onChange={(e) => setCurrentFilter(e.target.value)}
|
|
88
|
-
value={currentFilter}
|
|
89
|
-
>
|
|
90
|
-
<option value="-1">Select filter...</option>
|
|
91
|
-
{configuredFilters.map((ele) => (
|
|
92
|
-
<option key={ele.id} value={ele.name}>
|
|
93
|
-
{ele.name}
|
|
94
|
-
</option>
|
|
95
|
-
))}
|
|
96
|
-
</select>
|
|
97
|
-
)}
|
|
98
|
-
<input
|
|
99
|
-
type="text"
|
|
100
|
-
value={filterValue}
|
|
101
|
-
onChange={(e) => setFilterValue(e.target.value)}
|
|
102
|
-
className="border border-gray-300 rounded-md p-2 w-60"
|
|
103
|
-
/>
|
|
104
|
-
<button
|
|
105
|
-
onClick={(e) => {
|
|
106
|
-
console.log("Apply filter");
|
|
107
|
-
applyFilter();
|
|
108
|
-
}}
|
|
109
|
-
disabled={filterValue === "" || currentFilter === "-1"}
|
|
110
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 mt-1 text-xs"
|
|
111
|
-
>
|
|
112
|
-
Apply filter
|
|
113
|
-
</button>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</>
|
|
117
|
-
);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export default MapFilters;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useMaps } from "@/contexts/maps";
|
|
2
|
-
import { useMessages } from "@/contexts/messages";
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
|
|
5
|
-
const MapIframe = () => {
|
|
6
|
-
const { map, sessionToken } = useMaps();
|
|
7
|
-
const { start } = useMessages();
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
if (!sessionToken) return;
|
|
11
|
-
start(sessionToken); //starts communicator
|
|
12
|
-
}, [sessionToken]);
|
|
13
|
-
|
|
14
|
-
if (!map && !sessionToken) return null;
|
|
15
|
-
return (
|
|
16
|
-
<iframe
|
|
17
|
-
id="map-frame"
|
|
18
|
-
name="map-frame"
|
|
19
|
-
src={map}
|
|
20
|
-
allow="geolocation"
|
|
21
|
-
className="h-screen w-full"
|
|
22
|
-
></iframe>
|
|
23
|
-
);
|
|
24
|
-
};
|
|
25
|
-
export default MapIframe;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { useMaps } from "@/contexts/maps";
|
|
2
|
-
import useMapEvents from "@/hooks/useMapEvents";
|
|
3
|
-
const MapInfo = () => {
|
|
4
|
-
useMapEvents();
|
|
5
|
-
const {
|
|
6
|
-
zoomLevel,
|
|
7
|
-
mapScale,
|
|
8
|
-
clickedCoordinates,
|
|
9
|
-
map,
|
|
10
|
-
displayedLayers,
|
|
11
|
-
mapResolution,
|
|
12
|
-
} = useMaps();
|
|
13
|
-
if (!map) return null;
|
|
14
|
-
return (
|
|
15
|
-
<div className="absolute bg-white/60 right-0 p-5">
|
|
16
|
-
<div className="flex flex-col gap-1 text-xs">
|
|
17
|
-
<div>Zoom level: {zoomLevel}</div>
|
|
18
|
-
<div>Map scale: {mapScale}</div>
|
|
19
|
-
<div>Map resolution: {mapResolution}</div>
|
|
20
|
-
<div>Clicked coordinates: {clickedCoordinates}</div>
|
|
21
|
-
</div>
|
|
22
|
-
<div className="bg-black/20 p-5 text-left mt-2">
|
|
23
|
-
<span>Displayed Layers:</span>
|
|
24
|
-
|
|
25
|
-
{displayedLayers && displayedLayers.length > 0 && (
|
|
26
|
-
<div className="mt-1 flex flex-col gap-1 text-xs">
|
|
27
|
-
{displayedLayers.map((layer) => (
|
|
28
|
-
<div key={`lay_${layer}`}> - {layer}</div>
|
|
29
|
-
))}
|
|
30
|
-
</div>
|
|
31
|
-
)}
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
export default MapInfo;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { useAuth } from "@/contexts/auth";
|
|
2
|
-
import { useMaps } from "@/contexts/maps";
|
|
3
|
-
import { useMessages } from "@/contexts/messages";
|
|
4
|
-
import { useEffect, useState } from "react";
|
|
5
|
-
|
|
6
|
-
const MapLayers = () => {
|
|
7
|
-
const { GetMapInfo, mapId, mapLayers, setActiveLayer } = useMaps();
|
|
8
|
-
const { ToggleLayer } = useMessages();
|
|
9
|
-
const { logged } = useAuth();
|
|
10
|
-
const [selectedLayer, setSelectedLayer] = useState("-1");
|
|
11
|
-
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
if (!mapId) return;
|
|
14
|
-
GetMapInfo(mapId);
|
|
15
|
-
}, [mapId]);
|
|
16
|
-
|
|
17
|
-
if (!logged) return null;
|
|
18
|
-
if (!mapId) return null;
|
|
19
|
-
return (
|
|
20
|
-
<>
|
|
21
|
-
<div>
|
|
22
|
-
{mapLayers && mapLayers.length === 0 && <div>No layers available</div>}
|
|
23
|
-
|
|
24
|
-
<div className="m-2 flex gap-2">
|
|
25
|
-
<label className="block text-sm font-medium text-gray-700 pt-2">
|
|
26
|
-
Layers
|
|
27
|
-
</label>
|
|
28
|
-
{mapLayers && mapLayers.length > 0 && (
|
|
29
|
-
<select
|
|
30
|
-
className="border border-gray-300 rounded-md p-2 w-60"
|
|
31
|
-
onChange={(e) => setSelectedLayer(e.target.value)}
|
|
32
|
-
value={selectedLayer}
|
|
33
|
-
>
|
|
34
|
-
<option value="-1">Select layer...</option>
|
|
35
|
-
{mapLayers.map((ele) => (
|
|
36
|
-
<option key={ele.id} value={ele.qgis_name}>
|
|
37
|
-
{ele.qgis_name} - {ele.alias}
|
|
38
|
-
</option>
|
|
39
|
-
))}
|
|
40
|
-
</select>
|
|
41
|
-
)}
|
|
42
|
-
|
|
43
|
-
<button
|
|
44
|
-
onClick={(e) => {
|
|
45
|
-
console.log("Toggle layer", selectedLayer);
|
|
46
|
-
setActiveLayer(selectedLayer);
|
|
47
|
-
ToggleLayer(selectedLayer);
|
|
48
|
-
}}
|
|
49
|
-
disabled={selectedLayer === "-1"}
|
|
50
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 mt-1 text-xs"
|
|
51
|
-
>
|
|
52
|
-
Toggle layer
|
|
53
|
-
</button>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</>
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export default MapLayers;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { useAuth } from "@/contexts/auth";
|
|
2
|
-
import { useMaps } from "@/contexts/maps";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import { getMapId as getMapIdCookie } from "@/shared/cookies";
|
|
5
|
-
const MapList = () => {
|
|
6
|
-
const { GetMap } = useMaps();
|
|
7
|
-
const { projects, logged } = useAuth();
|
|
8
|
-
const [selectedMap, setSelectedMap] = useState("-1");
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
if (!logged) return;
|
|
11
|
-
if (!getMapIdCookie()) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
setSelectedMap(getMapIdCookie());
|
|
16
|
-
}, [logged]);
|
|
17
|
-
if (!logged) return null;
|
|
18
|
-
return (
|
|
19
|
-
<div>
|
|
20
|
-
<div className="m-2 flex gap-2">
|
|
21
|
-
<label className="block text-sm font-medium text-gray-700 pt-2">
|
|
22
|
-
Maps
|
|
23
|
-
</label>
|
|
24
|
-
<select
|
|
25
|
-
className="border border-gray-300 rounded-md p-2 w-32"
|
|
26
|
-
onChange={(e) => setSelectedMap(e.target.value)}
|
|
27
|
-
value={selectedMap}
|
|
28
|
-
>
|
|
29
|
-
<option value="-1">Select a map</option>
|
|
30
|
-
{projects.map((projectId) => (
|
|
31
|
-
<option key={projectId} value={projectId}>
|
|
32
|
-
{projectId}
|
|
33
|
-
</option>
|
|
34
|
-
))}
|
|
35
|
-
</select>
|
|
36
|
-
|
|
37
|
-
<button
|
|
38
|
-
onClick={(e) => {
|
|
39
|
-
GetMap(selectedMap);
|
|
40
|
-
}}
|
|
41
|
-
disabled={selectedMap === "-1"}
|
|
42
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 mt-1 text-xs"
|
|
43
|
-
>
|
|
44
|
-
Load map
|
|
45
|
-
</button>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export default MapList;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { useMessages } from "@/contexts/messages";
|
|
2
|
-
import { usePrint } from "@/contexts/print";
|
|
3
|
-
import PrintLayoutSelector from "@/atoms/PrintLayoutSelector";
|
|
4
|
-
import PrintPaperSizeSelector from "@/atoms/PrintPaperSizeSelector";
|
|
5
|
-
import ZoomToScaleButton from "@/atoms/ZoomToScaleButton";
|
|
6
|
-
import PrintScaleSelector from "@/atoms/PrintScaleSelector";
|
|
7
|
-
import { useMaps } from "@/contexts/maps";
|
|
8
|
-
const MapPrint = ({ map }) => {
|
|
9
|
-
const { cancelPrint, print } = useMessages();
|
|
10
|
-
const { mapScale } = useMaps();
|
|
11
|
-
const { startPrint, printEnabled } = usePrint();
|
|
12
|
-
return (
|
|
13
|
-
<div className="absolute bg-white/60 left-0 py-1 px-5 m-5 text-left border border-gray-300 rounded-md">
|
|
14
|
-
<button
|
|
15
|
-
onClick={(e) => {
|
|
16
|
-
console.log("Print");
|
|
17
|
-
if (!mapScale || mapScale === "-1") {
|
|
18
|
-
alert("Choose scale first");
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
if (printEnabled) {
|
|
22
|
-
print();
|
|
23
|
-
} else {
|
|
24
|
-
startPrint();
|
|
25
|
-
}
|
|
26
|
-
}}
|
|
27
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 my-1 text-xs"
|
|
28
|
-
>
|
|
29
|
-
Print
|
|
30
|
-
</button>
|
|
31
|
-
{printEnabled && (
|
|
32
|
-
<button
|
|
33
|
-
onClick={(e) => {
|
|
34
|
-
console.log("Print");
|
|
35
|
-
cancelPrint();
|
|
36
|
-
}}
|
|
37
|
-
className="border border-gray-300 bg-black text-white rounded-md p-2 my-1 text-xs"
|
|
38
|
-
>
|
|
39
|
-
Cancel print
|
|
40
|
-
</button>
|
|
41
|
-
)}
|
|
42
|
-
<div className="text-xs text-left">
|
|
43
|
-
<PrintPaperSizeSelector />
|
|
44
|
-
<PrintLayoutSelector />
|
|
45
|
-
<PrintScaleSelector />
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
};
|
|
50
|
-
export default MapPrint;
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { createContext, useContext, useState, useEffect } from "react";
|
|
3
|
-
import { useRouter } from "next/navigation";
|
|
4
|
-
import {
|
|
5
|
-
getToken,
|
|
6
|
-
setToken as setTokenCookie,
|
|
7
|
-
removeToken as removeTokenCookie,
|
|
8
|
-
setMapList as setMapListCookie,
|
|
9
|
-
getMapList as getMapListCookie,
|
|
10
|
-
removeMapList as removeMapListCookie,
|
|
11
|
-
} from "@/shared/cookies";
|
|
12
|
-
const AuthContext = createContext({});
|
|
13
|
-
|
|
14
|
-
export const AuthProvider = ({ children }) => {
|
|
15
|
-
const [apiUrl, setApiUrl] = useState(
|
|
16
|
-
process.env.NEXT_PUBLIC_APIURL ? process.env.NEXT_PUBLIC_APIURL : ""
|
|
17
|
-
);
|
|
18
|
-
const [logged, setLogged] = useState(null);
|
|
19
|
-
const [token, setToken] = useState(null);
|
|
20
|
-
const [userId, setUserId] = useState(null);
|
|
21
|
-
const [projects, setProjects] = useState([]);
|
|
22
|
-
const router = useRouter();
|
|
23
|
-
|
|
24
|
-
const resetAuthState = () => {
|
|
25
|
-
setLogged(false);
|
|
26
|
-
setToken(null);
|
|
27
|
-
setUserId(null);
|
|
28
|
-
setProjects([]);
|
|
29
|
-
removeTokenCookie();
|
|
30
|
-
removeMapListCookie();
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
(async () => {
|
|
35
|
-
if (!getToken()) {
|
|
36
|
-
console.log("No token found");
|
|
37
|
-
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
console.log("token cookie found, authenticating...");
|
|
41
|
-
try {
|
|
42
|
-
const response = await fetch(`${apiUrl}me`, {
|
|
43
|
-
method: "GET",
|
|
44
|
-
headers: {
|
|
45
|
-
"Content-Type": "application/json",
|
|
46
|
-
Authorization: `Bearer ${getToken()}`,
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
const data = await response.json();
|
|
50
|
-
if (!response.ok) {
|
|
51
|
-
resetAuthState();
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
setToken(getToken());
|
|
55
|
-
setUserId(data.message.id);
|
|
56
|
-
setLogged(true);
|
|
57
|
-
const listMaps = getMapListCookie();
|
|
58
|
-
if (listMaps) {
|
|
59
|
-
setProjects(JSON.parse(listMaps));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
console.log("authenticated through cookie", data);
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.error("Login error:", error);
|
|
65
|
-
return { error: true, message: "An unexpected error occurred" };
|
|
66
|
-
}
|
|
67
|
-
})();
|
|
68
|
-
}, []);
|
|
69
|
-
const login = async (email, password) => {
|
|
70
|
-
try {
|
|
71
|
-
const response = await fetch(`${apiUrl}letsgo`, {
|
|
72
|
-
method: "POST",
|
|
73
|
-
headers: {
|
|
74
|
-
"Content-Type": "application/json",
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify({ user: email, pwd: password }),
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const data = await response.json();
|
|
80
|
-
console.log("login", data);
|
|
81
|
-
|
|
82
|
-
if (!response.ok) {
|
|
83
|
-
return { error: true, message: data.message || "Login failed" };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
setToken(data.message.token);
|
|
87
|
-
setUserId(data.message.id);
|
|
88
|
-
setLogged(true);
|
|
89
|
-
setProjects(data.message.maps);
|
|
90
|
-
setTokenCookie(data.message.token);
|
|
91
|
-
setMapListCookie(JSON.stringify(data.message.maps));
|
|
92
|
-
} catch (error) {
|
|
93
|
-
console.error("Login error:", error);
|
|
94
|
-
return { error: true, message: "An unexpected error occurred" };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return { error: false };
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const logout = async () => {
|
|
101
|
-
console.log("logout", token);
|
|
102
|
-
try {
|
|
103
|
-
const response = await fetch(`${apiUrl}logout`, {
|
|
104
|
-
method: "DELETE",
|
|
105
|
-
headers: {
|
|
106
|
-
"Content-Type": "application/json",
|
|
107
|
-
Authorization: `Bearer ${token}`,
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const data = await response.json();
|
|
112
|
-
console.log("logout", data);
|
|
113
|
-
|
|
114
|
-
if (!response.ok) {
|
|
115
|
-
return { error: true, message: data.message || "Logout failed" };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Reset auth state and remove token cookie
|
|
119
|
-
resetAuthState();
|
|
120
|
-
router.push("/");
|
|
121
|
-
|
|
122
|
-
return { error: false };
|
|
123
|
-
} catch (error) {
|
|
124
|
-
console.error("Logout error:", error);
|
|
125
|
-
return { error: true, message: "An unexpected error occurred" };
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
return (
|
|
130
|
-
<AuthContext.Provider
|
|
131
|
-
value={{
|
|
132
|
-
logged,
|
|
133
|
-
token,
|
|
134
|
-
login,
|
|
135
|
-
logout,
|
|
136
|
-
userId,
|
|
137
|
-
projects,
|
|
138
|
-
apiUrl,
|
|
139
|
-
setApiUrl,
|
|
140
|
-
}}
|
|
141
|
-
>
|
|
142
|
-
{children}
|
|
143
|
-
</AuthContext.Provider>
|
|
144
|
-
);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
export const useAuth = () => useContext(AuthContext);
|