Skip to content

Commit d7aeb3f

Browse files
committed
Links menu and site description added
1 parent bcdf152 commit d7aeb3f

2 files changed

Lines changed: 82 additions & 69 deletions

File tree

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<link rel="icon" type="image/svg+xml" href="/parktrack-icon.jpg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>ParkTrack — карта свободных парковок</title>
8+
<meta name="description" content="ParkTrack — это система для мониторинга городских парковок для анализа занятости парковок в реальном времени.">
89
</head>
910
<body>
1011
<div id="root"></div>

src/App.tsx

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import type { Zone, Camera } from "./types/api"
1212
import "./App.css"
1313

1414
function App() {
15-
const [mapState, setMapState] = useState<MapState>({
16-
center: [59.9343, 30.3351],
17-
zoom: 12,
18-
})
15+
const [mapState, setMapState] = useState<MapState>({
16+
center: [60.8943, 31.3351],
17+
zoom: 7,
18+
})
1919

2020
const [freeSpotFilter, setFreeSpotFilter] =
2121
useState<FreeSpotFilterValue>("all")
@@ -140,111 +140,123 @@ function App() {
140140
return (
141141
<div className="min-h-screen bg-gray-50">
142142
<main className="mx-auto">
143+
<div
144+
className="absolute top-2 right-2 sm:top-4 sm:right-4 z-[1000] bg-white/70 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200 map-overlay">
145+
<div className="flex items-center justify-between p-1 sm:p-2 min-w-0">
146+
<div className="flex items-center space-x-2 sm:space-x-3 min-w-0 flex-1 flex-wrap gap-1">
147+
<span className="text-xs sm:text-sm text-gray-700"><a
148+
href="https://github.com/ParkTrack-Project" target="_blank" rel="noopener noreferrer">GitHub</a></span>
149+
<span className="text-xs sm:text-sm text-gray-700"><a href="https://docs.parktrack.live" target="_blank" rel="noopener noreferrer">Документация</a></span>
150+
<span className="text-xs sm:text-sm text-gray-700"><a href="https://grafana.nawinds.dev/public-dashboards/4235e9d4e1074087a41e1205bbc91042?from=now-3h&to=now&timezone=browser" target="_blank" rel="noopener noreferrer">Статус</a></span>
151+
</div>
152+
</div>
153+
</div>
143154
<div className="relative h-[calc(100vh)] w-full">
144155
<MapContainer
145-
zones={filteredZones}
146-
mapState={mapState}
147-
onMapStateChange={handleMapStateChange}
148-
onZoneClick={handleZoneClick}
149-
className="w-full h-full"
156+
zones={filteredZones}
157+
mapState={mapState}
158+
onMapStateChange={handleMapStateChange}
159+
onZoneClick={handleZoneClick}
160+
className="w-full h-full"
150161
/>
151162

152163
<button
153-
ref={toggleButtonRef}
154-
onClick={() => setFiltersVisible(!filtersVisible)}
155-
className="absolute top-20 left-2 sm:top-20 sm:left-4 z-[1001] bg-white/90 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200 p-2 hover:bg-white transition-colors"
156-
aria-label="Toggle filters"
164+
ref={toggleButtonRef}
165+
onClick={() => setFiltersVisible(!filtersVisible)}
166+
className="absolute top-20 left-2 sm:top-21 sm:left-2.5 z-[1001] bg-white/90 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200 p-2 hover:bg-white transition-colors"
167+
aria-label="Toggle filters"
157168
>
158169
{filtersVisible ? (
159-
<svg
160-
xmlns="http://www.w3.org/2000/svg"
161-
className="h-5 w-5 text-gray-700"
162-
viewBox="0 0 20 20"
163-
fill="currentColor"
164-
>
165-
<path
166-
fillRule="evenodd"
167-
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
168-
clipRule="evenodd"
169-
/>
170-
</svg>
170+
<svg
171+
xmlns="http://www.w3.org/2000/svg"
172+
className="h-5 w-5 text-gray-700"
173+
viewBox="0 0 20 20"
174+
fill="currentColor"
175+
>
176+
<path
177+
fillRule="evenodd"
178+
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
179+
clipRule="evenodd"
180+
/>
181+
</svg>
171182
) : (
172-
<svg
173-
xmlns="http://www.w3.org/2000/svg"
174-
className="h-5 w-5 text-gray-700"
175-
viewBox="0 0 20 20"
176-
fill="currentColor"
177-
>
178-
<path
179-
fillRule="evenodd"
180-
d="M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z"
181-
clipRule="evenodd"
182-
/>
183-
</svg>
183+
<svg
184+
xmlns="http://www.w3.org/2000/svg"
185+
className="h-5 w-5 text-gray-700"
186+
viewBox="0 0 20 20"
187+
fill="currentColor"
188+
>
189+
<path
190+
fillRule="evenodd"
191+
d="M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z"
192+
clipRule="evenodd"
193+
/>
194+
</svg>
184195
)}
185196
</button>
186197

187198
{filtersVisible && (
188-
<div
189-
ref={filtersRef}
190-
className="absolute top-2 left-16 right-2 sm:top-4 sm:left-16 sm:right-auto sm:max-w-md z-[1000] bg-white/90 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200"
191-
>
192-
<div className="p-3 sm:p-4">
193-
<div className="flex flex-col gap-3">
194-
<div>
195-
<h3 className="text-xs sm:text-sm font-semibold text-gray-700 mb-2">
196-
Фильтр по свободным местам
197-
</h3>
198-
<FreeSpotsFilter
199-
value={freeSpotFilter}
200-
onChange={setFreeSpotFilter}
199+
<div
200+
ref={filtersRef}
201+
className="absolute top-2 left-16 right-2 sm:top-4 sm:left-16 sm:right-auto sm:max-w-md z-[1000] bg-white/90 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200"
202+
>
203+
<div className="p-3 sm:p-4">
204+
<div className="flex flex-col gap-3">
205+
<div>
206+
<h3 className="text-xs sm:text-sm font-semibold text-gray-700 mb-2">
207+
Фильтр по свободным местам
208+
</h3>
209+
<FreeSpotsFilter
210+
value={freeSpotFilter}
211+
onChange={setFreeSpotFilter}
212+
/>
213+
</div>
214+
<CameraSelector
215+
cameras={cameras}
216+
selectedCameraId={selectedCameraId}
217+
onCameraSelect={handleCameraSelect}
201218
/>
202219
</div>
203-
<CameraSelector
204-
cameras={cameras}
205-
selectedCameraId={selectedCameraId}
206-
onCameraSelect={handleCameraSelect}
207-
/>
208220
</div>
209221
</div>
210-
</div>
211222
)}
212223

213-
<div className="absolute bottom-2 left-2 right-2 sm:bottom-4 sm:left-4 sm:right-4 z-[1000] bg-white/70 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200 map-overlay">
224+
<div
225+
className="absolute bottom-2 left-2 right-2 sm:bottom-4 sm:left-4 sm:right-4 z-[1000] bg-white/70 backdrop-blur-sm rounded-lg shadow-lg border border-gray-200 map-overlay">
214226
<div className="flex items-center justify-between p-1 sm:p-2 min-w-0">
215227
<div className="flex items-center space-x-2 sm:space-x-3 min-w-0 flex-1 flex-wrap gap-1">
216228
{total > 0 && (
217-
<span className="text-xs sm:text-sm text-gray-700">
229+
<span className="text-xs sm:text-sm text-gray-700">
218230
Зон: {filteredZones.length}/{total}
219231
</span>
220232
)}
221233
{totalCapacity > 0 && (
222-
<span className="text-xs sm:text-sm text-gray-700">
234+
<span className="text-xs sm:text-sm text-gray-700">
223235
• Вместимость: {totalCapacity}
224236
</span>
225237
)}
226238
{totalFreeSpots > 0 && (
227-
<span className="text-xs sm:text-sm font-medium text-green-600">
239+
<span className="text-xs sm:text-sm font-medium text-green-600">
228240
• Свободно: {totalFreeSpots}
229241
</span>
230242
)}
231243

232244
{loading === "loading" && (
233-
<div className="flex items-center space-x-1">
234-
<div className="animate-spin rounded-full h-2 w-2 sm:h-3 sm:w-3 border-b-2 border-blue-600"></div>
235-
<span className="text-xs sm:text-sm text-gray-600">
245+
<div className="flex items-center space-x-1">
246+
<div className="animate-spin rounded-full h-2 w-2 sm:h-3 sm:w-3 border-b-2 border-blue-600"></div>
247+
<span className="text-xs sm:text-sm text-gray-600">
236248
Загрузка...
237249
</span>
238-
</div>
250+
</div>
239251
)}
240252
</div>
241253

242254
{error && (
243-
<div className="bg-red-50 border border-red-200 rounded-md px-1 sm:px-2 py-1 flex-shrink-0">
244-
<p className="text-xs sm:text-sm text-red-800 whitespace-nowrap">
245-
{error.message}
246-
</p>
247-
</div>
255+
<div className="bg-red-50 border border-red-200 rounded-md px-1 sm:px-2 py-1 flex-shrink-0">
256+
<p className="text-xs sm:text-sm text-red-800 whitespace-nowrap">
257+
{error.message}
258+
</p>
259+
</div>
248260
)}
249261
</div>
250262
</div>

0 commit comments

Comments
 (0)