@vidro/map-handler 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +67 -1
  2. package/dist/map-handler.js +1 -1
  3. package/map-handler.d.ts +134 -0
  4. package/package.json +10 -4
  5. package/src/types.d.ts +63 -0
  6. package/.babelrc +0 -6
  7. package/doc/animation.png +0 -0
  8. package/doc/confirmComponent.png +0 -0
  9. package/doc/giswater.png +0 -0
  10. package/doc/giswaterInfo.png +0 -0
  11. package/doc/giswaterInfoApi.png +0 -0
  12. package/doc/giswatergeojson.png +0 -0
  13. package/doc/multiTile.png +0 -0
  14. package/doc/multiTileNoGutter.png +0 -0
  15. package/doc/togglelayergiswater.png +0 -0
  16. package/doc/vidromaps-basic.png +0 -0
  17. package/examples/full/apidemo.js +0 -387
  18. package/examples/full/cachedToken.dat +0 -1
  19. package/examples/full/cachedTokenData.dat +0 -1
  20. package/examples/full/docker/Docker_compose.yml +0 -14
  21. package/examples/full/docker/Dockerfile +0 -27
  22. package/examples/full/index.php +0 -200
  23. package/examples/full/storeToken.php +0 -6
  24. package/examples/full/tester.css +0 -74
  25. package/examples/full/tester.js +0 -658
  26. package/examples/multipleIframes/index.js +0 -82
  27. package/examples/multipleIframes/index.php +0 -52
  28. package/examples/react-next/README.md +0 -282
  29. package/examples/react-next/atoms/PrintLayoutSelector.js +0 -51
  30. package/examples/react-next/atoms/PrintPaperSizeSelector.js +0 -49
  31. package/examples/react-next/atoms/PrintScaleSelector.js +0 -61
  32. package/examples/react-next/atoms/ZoomToScaleButton.js +0 -57
  33. package/examples/react-next/components/AuthComponent.js +0 -88
  34. package/examples/react-next/components/MapButtons.js +0 -108
  35. package/examples/react-next/components/MapFilters.js +0 -120
  36. package/examples/react-next/components/MapIframe.js +0 -25
  37. package/examples/react-next/components/MapInfo.js +0 -36
  38. package/examples/react-next/components/MapLayers.js +0 -60
  39. package/examples/react-next/components/MapList.js +0 -51
  40. package/examples/react-next/components/MapPrint.js +0 -50
  41. package/examples/react-next/contexts/auth.js +0 -147
  42. package/examples/react-next/contexts/maps.js +0 -185
  43. package/examples/react-next/contexts/messages.js +0 -358
  44. package/examples/react-next/contexts/print.js +0 -125
  45. package/examples/react-next/env.sample +0 -3
  46. package/examples/react-next/eslint.config.mjs +0 -14
  47. package/examples/react-next/hooks/useMapEvents.js +0 -118
  48. package/examples/react-next/jsconfig.json +0 -7
  49. package/examples/react-next/next.config.mjs +0 -6
  50. package/examples/react-next/package.json +0 -25
  51. package/examples/react-next/pages/_app.js +0 -5
  52. package/examples/react-next/pages/index.js +0 -97
  53. package/examples/react-next/postcss.config.mjs +0 -8
  54. package/examples/react-next/public/discord.svg +0 -8
  55. package/examples/react-next/public/favicon.ico +0 -0
  56. package/examples/react-next/public/file.svg +0 -1
  57. package/examples/react-next/public/logo.png +0 -0
  58. package/examples/react-next/public/next.svg +0 -1
  59. package/examples/react-next/shared/constants.js +0 -48
  60. package/examples/react-next/shared/cookies.js +0 -23
  61. package/examples/react-next/styles/globals.css +0 -24
  62. package/examples/react-next/tailwind.config.mjs +0 -17
  63. package/examples/serverLess/dist/index.23420cfa.js +0 -2973
  64. package/examples/serverLess/dist/index.23420cfa.js.map +0 -1
  65. package/examples/serverLess/dist/index.91b6cacc.js +0 -2
  66. package/examples/serverLess/dist/index.91b6cacc.js.map +0 -1
  67. package/examples/serverLess/dist/index.html +0 -1
  68. package/examples/serverLess/index.html +0 -39
  69. package/examples/serverLess/main.js +0 -113
  70. package/examples/serverLess/package.json +0 -18
  71. package/examples/serverLess/readme.md +0 -41
  72. package/examples/simple/index.html +0 -23
  73. package/examples/simple/simple.js +0 -80
  74. package/examples/taigua/index.html +0 -55
  75. package/examples/taigua/main.js +0 -490
  76. package/examples/tester.css +0 -74
  77. package/examples/vidromap/index.js +0 -20
  78. package/examples/vidromap/index.php +0 -111
  79. package/flows.md +0 -73
  80. package/helpers.md +0 -45
  81. package/src/index.js +0 -882
  82. package/src/shared/iframe-communicator.js +0 -18
  83. 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);