@navigoo/map-components 1.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.
Files changed (38) hide show
  1. package/README.md +0 -0
  2. package/dist/components/Dashboard.d.ts +14 -0
  3. package/dist/components/Dashboard.js +52 -0
  4. package/dist/components/DetourRouteSearch.d.ts +10 -0
  5. package/dist/components/DetourRouteSearch.js +119 -0
  6. package/dist/components/MapView.d.ts +14 -0
  7. package/dist/components/MapView.js +179 -0
  8. package/dist/components/RouteSearch.d.ts +10 -0
  9. package/dist/components/RouteSearch.js +95 -0
  10. package/dist/components/SearchBar.d.ts +10 -0
  11. package/dist/components/SearchBar.js +48 -0
  12. package/dist/components/TransportOptions.d.ts +3 -0
  13. package/dist/components/TransportOptions.js +24 -0
  14. package/dist/components/TripType.d.ts +3 -0
  15. package/dist/components/TripType.js +20 -0
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.js +39 -0
  18. package/dist/lib/api.d.ts +21 -0
  19. package/dist/lib/api.js +58 -0
  20. package/dist/lib/geolocalisation.d.ts +9 -0
  21. package/dist/lib/geolocalisation.js +30 -0
  22. package/dist/lib/type.d.ts +32 -0
  23. package/dist/lib/type.js +2 -0
  24. package/package.json +31 -0
  25. package/src/components/Dashboard.tsx +183 -0
  26. package/src/components/DetourRouteSearch.tsx +217 -0
  27. package/src/components/MapView.tsx +201 -0
  28. package/src/components/RouteSearch.tsx +163 -0
  29. package/src/components/SearchBar.tsx +87 -0
  30. package/src/components/TransportOptions.tsx +53 -0
  31. package/src/components/TripType.tsx +47 -0
  32. package/src/components/styles.modules.css +207 -0
  33. package/src/components/wellknown.d.ts +1 -0
  34. package/src/css-module.d.ts +4 -0
  35. package/src/index.ts +10 -0
  36. package/src/lib/api.ts +74 -0
  37. package/src/lib/geolocalisation.ts +41 -0
  38. package/src/lib/type.ts +37 -0
@@ -0,0 +1,207 @@
1
+ .header {
2
+ background-color: #fff;
3
+ padding: 10px 20px;
4
+ border-bottom: 1px solid #ddd;
5
+ }
6
+ .headerTitle {
7
+ font-size: 24px;
8
+ font-weight: bold;
9
+ }
10
+ .titleAccent {
11
+ color: #007bff;
12
+ }
13
+ .mainContainer {
14
+ display: flex;
15
+ }
16
+ .sidebar {
17
+ width: 60px;
18
+ background-color: #f4f4f4;
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ padding-top: 20px;
23
+ }
24
+ .sidebarButton {
25
+ background: none;
26
+ border: none;
27
+ padding: 10px;
28
+ cursor: pointer;
29
+ margin-bottom: 20px;
30
+ }
31
+ .sidebarButton.active {
32
+ background-color: #007bff;
33
+ border-radius: 5px;
34
+ }
35
+ .contentPanel {
36
+ flex: 1;
37
+ padding: 20px;
38
+ transition: all 0.3s;
39
+ }
40
+ .contentPanel.open {
41
+ transform: translateX(0);
42
+ }
43
+ .sectionContainer {
44
+ background-color: #fff;
45
+ padding: 20px;
46
+ border-radius: 8px;
47
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
48
+ }
49
+ .sectionTitle {
50
+ font-size: 20px;
51
+ margin-bottom: 20px;
52
+ }
53
+ .toggleContainer {
54
+ display: flex;
55
+ align-items: center;
56
+ margin-bottom: 20px;
57
+ }
58
+ .switch {
59
+ position: relative;
60
+ display: inline-block;
61
+ width: 40px;
62
+ height: 20px;
63
+ }
64
+ .switch input {
65
+ opacity: 0;
66
+ width: 0;
67
+ height: 0;
68
+ }
69
+ .slider {
70
+ position: absolute;
71
+ cursor: pointer;
72
+ top: 0;
73
+ left: 0;
74
+ right: 0;
75
+ bottom: 0;
76
+ background-color: #ccc;
77
+ border-radius: 20px;
78
+ transition: 0.4s;
79
+ }
80
+ .slider:before {
81
+ position: absolute;
82
+ content: '';
83
+ height: 16px;
84
+ width: 16px;
85
+ left: 2px;
86
+ bottom: 2px;
87
+ background-color: white;
88
+ border-radius: 50%;
89
+ transition: 0.4s;
90
+ }
91
+ .switch input:checked + .slider {
92
+ background-color: #007bff;
93
+ }
94
+ .switch input:checked + .slider:before {
95
+ transform: translateX(20px);
96
+ }
97
+ .toggleLabel {
98
+ margin-left: 10px;
99
+ }
100
+ .locationButton {
101
+ display: flex;
102
+ align-items: center;
103
+ padding: 10px 20px;
104
+ background-color: #007bff;
105
+ color: white;
106
+ border: none;
107
+ border-radius: 4px;
108
+ cursor: pointer;
109
+ }
110
+ .locationButton:disabled {
111
+ background-color: #ccc;
112
+ cursor: not-allowed;
113
+ }
114
+ .error {
115
+ color: red;
116
+ margin: 10px 0;
117
+ }
118
+ .searchSection {
119
+ padding: 20px;
120
+ }
121
+ .searchGroup {
122
+ margin-bottom: 15px;
123
+ }
124
+ .label {
125
+ display: block;
126
+ font-weight: bold;
127
+ margin-bottom: 5px;
128
+ }
129
+ .searchInput {
130
+ width: 100%;
131
+ padding: 8px;
132
+ border: 1px solid #ccc;
133
+ border-radius: 4px;
134
+ }
135
+ .searchResults {
136
+ list-style: none;
137
+ padding: 0;
138
+ margin: 5px 0;
139
+ border: 1px solid #ccc;
140
+ max-height: 200px;
141
+ overflow-y: auto;
142
+ }
143
+ .routeSearchSection {
144
+ padding: 20px;
145
+ }
146
+ .route-search {
147
+ margin-bottom: 20px;
148
+ }
149
+ .searchResultItem {
150
+ padding: 8px;
151
+ cursor: pointer;
152
+ }
153
+ .searchResultItem:hover {
154
+ background-color: #f0f0f0;
155
+ }
156
+ .searchButton {
157
+ padding: 10px 20px;
158
+ background-color: #007bff;
159
+ color: white;
160
+ border: none;
161
+ border-radius: 4px;
162
+ cursor: pointer;
163
+ }
164
+ .searchButton.disabled {
165
+ background-color: #ccc;
166
+ cursor: not-allowed;
167
+ }
168
+ .optionsSection {
169
+ margin-top: 20px;
170
+ }
171
+ .optionsHeader {
172
+ display: flex;
173
+ justify-content: space-between;
174
+ align-items: center;
175
+ }
176
+ .optionsTitle {
177
+ font-size: 16px;
178
+ font-weight: bold;
179
+ }
180
+ .toggleButton {
181
+ background: none;
182
+ border: none;
183
+ color: #007bff;
184
+ cursor: pointer;
185
+ }
186
+ .transportOptions {
187
+ display: flex;
188
+ gap: 10px;
189
+ margin-top: 10px;
190
+ }
191
+ .transportOption {
192
+ display: flex;
193
+ align-items: center;
194
+ padding: 8px 16px;
195
+ border: 1px solid #ccc;
196
+ border-radius: 4px;
197
+ cursor: pointer;
198
+ }
199
+ .transportOption.selected {
200
+ border-color: #007bff;
201
+ }
202
+ .transportIcon {
203
+ margin-right: 8px;
204
+ }
205
+ .transportName {
206
+ font-size: 14px;
207
+ }
@@ -0,0 +1 @@
1
+ declare module 'wellknown';
@@ -0,0 +1,4 @@
1
+ declare module '*.module.css' {
2
+ const classes: { [key: string]: string };
3
+ export default classes;
4
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { default as SearchBar } from './components/SearchBar';
2
+ export { default as RouteSearch } from './components/RouteSearch';
3
+ export { default as DetourRouteSearch } from './components/DetourRouteSearch';
4
+ export { default as MapView } from './components/MapView';
5
+ export { default as Dashboard } from './components/Dashboard';
6
+ export { default as TransportOptions } from './components/TransportOptions';
7
+ export { default as TripType } from './components/TripType';
8
+ export { ApiClient } from './lib/api';
9
+ export { getCurrentPosition } from './lib/geolocalisation';
10
+ export * from './lib/type';
package/src/lib/api.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { Place, Route, GeolocationResult } from './type';
2
+
3
+ export class ApiClient {
4
+ private baseUrl: string;
5
+
6
+ constructor(baseUrl: string) {
7
+ this.baseUrl = baseUrl;
8
+ }
9
+
10
+ async searchPlaces(name: string): Promise<Place[]> {
11
+ const response = await fetch(`${this.baseUrl}/api/places?name=${encodeURIComponent(name)}`);
12
+ const data = await response.json();
13
+ if (response.ok && data.success) {
14
+ return data.data.filter((place: Place) => place.coordinates !== null);
15
+ }
16
+ throw new Error(data.error || 'Failed to search places');
17
+ }
18
+
19
+ async findClosestPlace(lat: number, lng: number): Promise<Place | null> {
20
+ const response = await fetch(`${this.baseUrl}/api/places/closest?lat=${lat}&lng=${lng}`);
21
+ const data = await response.json();
22
+ if (response.ok && data.success) {
23
+ return data.data;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ async calculateRoute(
29
+ points: { lat: number; lng: number }[],
30
+ mode: 'driving' | 'walking' | 'cycling',
31
+ startPlaceName: string,
32
+ endPlaceName: string
33
+ ): Promise<Route[]> {
34
+ const response = await fetch(`${this.baseUrl}/api/routes`, {
35
+ method: 'POST',
36
+ headers: { 'Content-Type': 'application/json' },
37
+ body: JSON.stringify({ points, mode, startPlaceName, endPlaceName }),
38
+ });
39
+ const data = await response.json();
40
+ if (response.ok && data.routes) {
41
+ return data.routes;
42
+ }
43
+ throw new Error(data.error || 'Failed to calculate route');
44
+ }
45
+
46
+ async calculateRouteWithDetour(
47
+ start: { lat: number; lng: number },
48
+ detour: { lat: number; lng: number },
49
+ end: { lat: number; lng: number },
50
+ mode: string,
51
+ startPlaceName: string,
52
+ detourPlaceName: string,
53
+ endPlaceName: string
54
+ ): Promise<Route[]> {
55
+ const response = await fetch(`${this.baseUrl}/api/routes/with-detour`, {
56
+ method: 'POST',
57
+ headers: { 'Content-Type': 'application/json' },
58
+ body: JSON.stringify({
59
+ start,
60
+ detour,
61
+ end,
62
+ transportMode: mode,
63
+ startPlaceName,
64
+ detourPlaceName,
65
+ endPlaceName,
66
+ }),
67
+ });
68
+ const data = await response.json();
69
+ if (response.ok && data.routes) {
70
+ return data.routes;
71
+ }
72
+ throw new Error(data.error || 'Failed to calculate route with detour');
73
+ }
74
+ }
@@ -0,0 +1,41 @@
1
+ export interface GeolocationResult {
2
+ latitude: number;
3
+ longitude: number;
4
+ }
5
+
6
+ export interface GeolocationError {
7
+ code: number;
8
+ message: string;
9
+ }
10
+
11
+ export const getCurrentPosition = (): Promise<GeolocationResult> => {
12
+ return new Promise((resolve, reject) => {
13
+ if (!navigator.geolocation) {
14
+ reject({
15
+ code: -1,
16
+ message: 'Geolocation is not supported by this browser.',
17
+ });
18
+ return;
19
+ }
20
+
21
+ navigator.geolocation.getCurrentPosition(
22
+ (position) => {
23
+ resolve({
24
+ latitude: position.coords.latitude,
25
+ longitude: position.coords.longitude,
26
+ });
27
+ },
28
+ (error) => {
29
+ reject({
30
+ code: error.code,
31
+ message: error.message,
32
+ });
33
+ },
34
+ {
35
+ enableHighAccuracy: true,
36
+ timeout: 10000,
37
+ maximumAge: 0,
38
+ }
39
+ );
40
+ });
41
+ };
@@ -0,0 +1,37 @@
1
+ export interface Coordinates {
2
+ lat: number;
3
+ lng: number;
4
+ }
5
+
6
+ export interface Place {
7
+ id: string | number;
8
+ name: string;
9
+ coordinates: Coordinates | null;
10
+ }
11
+
12
+ export interface RouteStep {
13
+ geometry: string;
14
+ source: string;
15
+ target: string;
16
+ distance: number;
17
+ duration: number;
18
+ }
19
+
20
+ export interface Route {
21
+ distance: number;
22
+ duration: number;
23
+ steps: RouteStep[];
24
+ startPlaceName?: string;
25
+ endPlaceName?: string;
26
+ geometry: string;
27
+ }
28
+
29
+ export interface GeolocationResult {
30
+ latitude: number;
31
+ longitude: number;
32
+ }
33
+
34
+ export interface GeolocationError {
35
+ code: number;
36
+ message: string;
37
+ }