Skip to content

Commit e4de791

Browse files
committed
fixes
1 parent 70e674e commit e4de791

4 files changed

Lines changed: 62 additions & 61 deletions

File tree

src/App.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useCallback, useMemo } from "react"
1+
import { useState, useCallback, useMemo, useEffect } from "react"
22
import { MapContainer } from "./components/Map/MapContainer"
33
import { useMapData } from "./hooks/useMapData"
44
import type { MapState } from "./types"
@@ -18,8 +18,8 @@ function App() {
1818
const totalFreeSpots = useMemo(
1919
() =>
2020
zones.reduce((acc, zone) => {
21-
const occupied = zone.occupied as number | undefined
22-
const capacity = zone.capacity as number
21+
const occupied = zone.occupied
22+
const capacity = zone.capacity
2323
if (occupied !== undefined) {
2424
return acc + (capacity - occupied)
2525
}
@@ -31,14 +31,14 @@ function App() {
3131
const totalCapacity = useMemo(
3232
() =>
3333
zones.reduce((acc, zone) => {
34-
const capacity = zone.capacity as number
34+
const capacity = zone.capacity
3535
return acc + capacity
3636
}, 0),
3737
[zones]
3838
)
3939

4040
const handleZoneClick = useCallback((zone: Zone) => {
41-
const points = zone.points as { latitude: number; longitude: number }[]
41+
const points = zone.points
4242
if (points && points.length > 0) {
4343
const centerLat =
4444
points.reduce((sum, p) => sum + p.latitude, 0) / points.length
@@ -56,6 +56,14 @@ function App() {
5656
setMapState(newState)
5757
}, [])
5858

59+
useEffect(() => {
60+
const interval = setInterval(() => {
61+
refetch()
62+
}, 10000)
63+
64+
return () => clearInterval(interval)
65+
}, [refetch])
66+
5967
return (
6068
<div className="min-h-screen bg-gray-50">
6169
<header className="bg-white shadow-sm border-b">
@@ -66,13 +74,6 @@ function App() {
6674
Парковки СПб
6775
</h1>
6876
</div>
69-
70-
<button
71-
onClick={refetch}
72-
className="px-1 sm:px-2 py-1 text-xs sm:text-sm bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
73-
>
74-
Обновить
75-
</button>
7677
</div>
7778
</div>
7879
</header>

src/components/Map/MapContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const MapContainer: React.FC<MapContainerProps> = ({
6161
<LeafletMapContainer
6262
center={center}
6363
zoom={zoom}
64-
maxZoom={30}
64+
maxZoom={18}
6565
style={{ height: "100%", width: "100%" }}
6666
attributionControl={false}
6767
>

src/components/Map/MapPoints.tsx

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -66,80 +66,70 @@ interface MapPointsProps {
6666
onZoneClick?: (zone: Zone) => void
6767
}
6868

69-
const getZonePolygonColor = (
70-
zoneType?: string,
71-
occupied?: number,
72-
capacity?: number
73-
) => {
74-
if (zoneType === "parallel") {
75-
return "#3B82F6"
69+
const getZonePolygonColor = (freeSpots: number | undefined): string => {
70+
if (freeSpots === undefined || freeSpots === 0) {
71+
return "#EF4444"
7672
}
77-
78-
if (occupied !== undefined && capacity !== undefined) {
79-
const occupancyRate = capacity > 0 ? occupied / capacity : 0
80-
if (occupancyRate >= 0.9) return "#EF4444"
81-
if (occupancyRate >= 0.7) return "#F59E0B"
82-
return "#10B981"
73+
if (freeSpots === 1) {
74+
return "#F59E0B"
8375
}
84-
8576
return "#10B981"
8677
}
8778

8879
export const MapPoints: React.FC<MapPointsProps> = ({ zones, onZoneClick }) => {
8980
return (
9081
<>
9182
{zones.map((zone) => {
92-
const zoneId = zone.zone_id as number
93-
const points = zone.points as Point[]
94-
const zoneType = zone.zone_type as string
95-
const occupied = zone.occupied as number | undefined
96-
const capacity = zone.capacity as number
97-
const pay = zone.pay as number
98-
const confidence = zone.confidence as number | undefined
99-
const cameraId = zone.camera_id as number | undefined
100-
101-
const fillColor = getZonePolygonColor(zoneType, occupied, capacity)
10283
const freeSpots =
103-
occupied !== undefined ? capacity - occupied : undefined
84+
zone.occupied !== undefined
85+
? zone.capacity - zone.occupied
86+
: undefined
87+
const fillColor = getZonePolygonColor(freeSpots)
10488

10589
const centerLat =
106-
points.reduce((sum, p) => sum + p.latitude, 0) / points.length
90+
zone.points.reduce((sum, p) => sum + p.latitude, 0) /
91+
zone.points.length
10792
const centerLng =
108-
points.reduce((sum, p) => sum + p.longitude, 0) / points.length
93+
zone.points.reduce((sum, p) => sum + p.longitude, 0) /
94+
zone.points.length
10995

11096
const popupContent = (
11197
<div className="map-popup min-w-[200px]">
112-
<h3 className="font-semibold text-gray-800 mb-2">Зона {zoneId}</h3>
98+
<h3 className="font-semibold text-gray-800 mb-2">
99+
Зона {zone.zone_id}
100+
</h3>
113101

114-
{zoneType && (
102+
{zone.zone_type && (
115103
<div className="mb-2">
116104
<span
117105
className={`inline-block px-2 py-1 text-xs font-medium rounded-full ${
118-
zoneType === "parallel"
106+
zone.zone_type === "parallel"
119107
? "bg-blue-100 text-blue-800"
120108
: "bg-green-100 text-green-800"
121109
}`}
122110
>
123-
{zoneType === "parallel" ? "Параллельная" : "Стандартная"}
111+
{zone.zone_type === "parallel"
112+
? "Параллельная"
113+
: "Стандартная"}
124114
</span>
125115
</div>
126116
)}
127117

128-
{capacity !== undefined && (
118+
{zone.capacity !== undefined && (
129119
<div className="mb-1">
130120
<span className="text-sm font-medium text-gray-700">
131121
Вместимость:
132122
</span>{" "}
133-
<span className="text-sm text-gray-900">{capacity}</span>
123+
<span className="text-sm text-gray-900">{zone.capacity}</span>
134124
</div>
135125
)}
136126

137-
{occupied !== undefined && (
127+
{zone.occupied !== undefined && (
138128
<div className="mb-1">
139129
<span className="text-sm font-medium text-gray-700">
140130
Занято:
141131
</span>{" "}
142-
<span className="text-sm text-gray-900">{occupied}</span>
132+
<span className="text-sm text-gray-900">{zone.occupied}</span>
143133
</div>
144134
)}
145135

@@ -154,43 +144,44 @@ export const MapPoints: React.FC<MapPointsProps> = ({ zones, onZoneClick }) => {
154144
</div>
155145
)}
156146

157-
{pay !== undefined && (
147+
{zone.pay !== undefined && (
158148
<div className="mb-1">
159149
<span className="text-sm font-medium text-gray-700">
160150
Оплата:
161151
</span>{" "}
162152
<span className="text-sm text-gray-900">
163-
{pay != null && (pay === 0 ? "Бесплатно" : `${pay} руб`)}
153+
{zone.pay != null &&
154+
(zone.pay === 0 ? "Бесплатно" : `${zone.pay} руб`)}
164155
</span>
165156
</div>
166157
)}
167158

168-
{confidence !== undefined && (
159+
{zone.confidence !== undefined && (
169160
<div className="mb-1">
170161
<span className="text-sm font-medium text-gray-700">
171162
Уверенность:
172163
</span>{" "}
173164
<span className="text-sm text-gray-900">
174-
{(Number(confidence) * 100).toFixed(1)}%
165+
{(Number(zone.confidence) * 100).toFixed(1)}%
175166
</span>
176167
</div>
177168
)}
178169

179-
{cameraId !== undefined && (
170+
{zone.camera_id !== undefined && (
180171
<div className="mt-2 pt-2 border-t border-gray-200">
181172
<span className="text-xs text-gray-500">
182-
Камера ID: {String(cameraId)}
173+
Камера ID: {String(zone.camera_id)}
183174
</span>
184175
</div>
185176
)}
186177
</div>
187178
)
188179

189-
if (zoneType === "parallel" && points && points.length === 4) {
190-
const centerLine = calculateCenterLine(points)
180+
if (zone.zone_type === "parallel" && zone.points.length === 4) {
181+
const centerLine = calculateCenterLine(zone.points)
191182

192183
return (
193-
<React.Fragment key={zoneId}>
184+
<React.Fragment key={zone.zone_id}>
194185
{centerLine.length === 2 && (
195186
<Polyline
196187
positions={centerLine}
@@ -222,12 +213,14 @@ export const MapPoints: React.FC<MapPointsProps> = ({ zones, onZoneClick }) => {
222213
}
223214

224215
const polygonPoints =
225-
points && points.length === 4
226-
? points.map((p) => [p.latitude, p.longitude] as [number, number])
216+
zone.points.length === 4
217+
? zone.points.map(
218+
(p) => [p.latitude, p.longitude] as [number, number]
219+
)
227220
: null
228221

229222
return (
230-
<React.Fragment key={zoneId}>
223+
<React.Fragment key={zone.zone_id}>
231224
{polygonPoints && (
232225
<Polygon
233226
positions={polygonPoints}

src/types/api.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,14 @@ export interface CreateZone {
2626
}
2727

2828
export interface Zone {
29-
[key: string]: unknown
29+
zone_id: number
30+
points: Point[]
31+
zone_type: string
32+
capacity: number
33+
pay: number
34+
occupied?: number
35+
confidence?: number
36+
camera_id?: number
3037
}
3138

3239
export interface GetZonesParams {

0 commit comments

Comments
 (0)