diff --git a/front/.eslintrc.cjs b/front/.eslintrc.cjs
index ec601b2..d46b749 100644
--- a/front/.eslintrc.cjs
+++ b/front/.eslintrc.cjs
@@ -11,5 +11,6 @@ module.exports = {
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': 'warn',
+ 'react/prop-types': 'off'
},
}
diff --git a/front/src/App.jsx b/front/src/App.jsx
index aaf598f..6329f68 100644
--- a/front/src/App.jsx
+++ b/front/src/App.jsx
@@ -2,7 +2,7 @@ import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'
import { HomePage, AddPage, LoginPage, UserPage } from './pages'
-import WithToken from './components/WithToken'
+import { WithToken } from './components'
import 'leaflet/dist/leaflet.css'
diff --git a/front/src/assets/metro.js b/front/src/assets/metro.js
index 8b8172c..f577ae3 100644
--- a/front/src/assets/metro.js
+++ b/front/src/assets/metro.js
@@ -1,5 +1,5 @@
-const metros = {
- red: [
+const stations = {
+ red: new Set([
"Девяткино",
"Гражданский проспект",
"Академическая",
@@ -19,8 +19,8 @@ const metros = {
"Автово",
"Ленинский проспект",
"Проспект Ветеранов"
- ],
- blue: [
+ ]),
+ blue: new Set([
"Парнас",
"Проспект Просвещения",
"Озерки",
@@ -39,8 +39,8 @@ const metros = {
"Московская",
"Звёздная",
"Купчино"
- ],
- green: [
+ ]),
+ green: new Set([
"Приморская",
"Беговая",
"Василеостровская",
@@ -52,11 +52,9 @@ const metros = {
"Пролетарская",
"Обухово",
"Рыбацкое"
- ],
- orange: [
+ ]),
+ orange: new Set([
"Спасская",
- "Горный институт",
- "Театральная",
"Достоевская",
"Лиговский проспект",
"Площадь Александра Невского",
@@ -64,8 +62,8 @@ const metros = {
"Ладожская",
"Проспект Большевиков",
"Улица Дыбенко"
- ],
- violet: [
+ ]),
+ violet: new Set([
"Комендантский проспект",
"Старая Деревня",
"Крестовский остров",
@@ -81,15 +79,23 @@ const metros = {
"Проспект славы",
"Дунайскай",
"Шушары"
- ],
- gold: [
- "Юго западная",
- "Каретная",
- "Путиловская",
- "Броневая",
- "Заставская",
- "Боровая"
- ]
+ ]),
}
-export { metros }
+const colors = {
+ red: "#D6083B",
+ blue: "#0078C9",
+ green: "#009A49",
+ orange: "#EA7125",
+ violet: "#702785",
+}
+
+const lines = {
+ red: "Красная",
+ blue: "Синяя",
+ green: "Зелёная",
+ orange: "Оранжевая",
+ violet: "Фиолетовая",
+}
+
+export { stations, colors, lines }
diff --git a/front/src/components/AnnouncementDetails.jsx b/front/src/components/AnnouncementDetails.jsx
index 7685e35..0439fa0 100644
--- a/front/src/components/AnnouncementDetails.jsx
+++ b/front/src/components/AnnouncementDetails.jsx
@@ -1,18 +1,19 @@
import { Modal, Button } from 'react-bootstrap'
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
+import LineDot from './LineDot'
import { categoryNames } from '../assets/category'
import { useBook } from '../hooks/api'
function AnnouncementDetails({ close, announcement: { id, name, category, bestBy, description, lat, lng, address, metro } }) {
- const {handleBook, status: bookStatus} = useBook(id)
+ const { handleBook, status: bookStatus } = useBook(id)
return (
-
+
Подробнее
@@ -35,14 +36,18 @@ function AnnouncementDetails({ close, announcement: { id, name, category, bestBy
/>
- {address + "\n" + metro}
+
+ {address}
+
+ {metro}
+
diff --git a/front/src/components/ClickHandler.jsx b/front/src/components/ClickHandler.jsx
new file mode 100644
index 0000000..1404c20
--- /dev/null
+++ b/front/src/components/ClickHandler.jsx
@@ -0,0 +1,12 @@
+import { useMapEvent } from "react-leaflet"
+
+function ClickHandler({ setPosition }) {
+ const map = useMapEvent('click', (e) => {
+ setPosition(e.latlng)
+ map.setView(e.latlng)
+ })
+
+ return null
+}
+
+export default ClickHandler
\ No newline at end of file
diff --git a/front/src/components/Filters.jsx b/front/src/components/Filters.jsx
index 9b63bd0..a8e156c 100644
--- a/front/src/components/Filters.jsx
+++ b/front/src/components/Filters.jsx
@@ -1,7 +1,7 @@
import { Button, Form, Modal } from "react-bootstrap"
import { categoryNames } from "../assets/category"
-import { metros } from '../assets/metro'
+import { stations, lines } from '../assets/metro'
function Filters({ filter, setFilter, filterShown, setFilterShown }) {
@@ -55,11 +55,13 @@ function Filters({ filter, setFilter, filterShown, setFilterShown }) {
- {Object.entries(metros).map(
- ([branch, stations]) =>
- stations.map(metro =>
-
- )
+ {Object.entries(stations).map(
+ ([line, stations]) =>
+
)}
diff --git a/front/src/components/LineDot.jsx b/front/src/components/LineDot.jsx
new file mode 100644
index 0000000..c9ee77c
--- /dev/null
+++ b/front/src/components/LineDot.jsx
@@ -0,0 +1,12 @@
+import { colors, lines } from '../assets/metro'
+import { lineByName } from '../utils/metro'
+
+function LineDot({ station }) {
+ const line = lineByName(station)
+ const lineTitle = lines[line]
+ const color = colors[line]
+
+ return ⬤
+}
+
+export default LineDot
diff --git a/front/src/components/index.js b/front/src/components/index.js
new file mode 100644
index 0000000..eeffa7d
--- /dev/null
+++ b/front/src/components/index.js
@@ -0,0 +1,19 @@
+import AnnouncementDetails from "./AnnouncementDetails"
+import BottomNavBar from "./BottomNavBar"
+import Filters from "./Filters"
+import LineDot from "./LineDot"
+import LocationMarker from './LocationMarker'
+import TrashboxMarkers from './TrashboxMarkers'
+import WithToken from './WithToken'
+import ClickHandler from './ClickHandler'
+
+export {
+ AnnouncementDetails,
+ BottomNavBar,
+ Filters,
+ LineDot,
+ LocationMarker,
+ TrashboxMarkers,
+ WithToken,
+ ClickHandler,
+}
diff --git a/front/src/hooks/index.js b/front/src/hooks/index.js
new file mode 100644
index 0000000..7f558fd
--- /dev/null
+++ b/front/src/hooks/index.js
@@ -0,0 +1,5 @@
+import useStoryDimensions from "./useStoryDimensions"
+
+export {
+ useStoryDimensions,
+}
diff --git a/front/src/pages/AddPage.jsx b/front/src/pages/AddPage.jsx
index 90528ee..dd14b99 100644
--- a/front/src/pages/AddPage.jsx
+++ b/front/src/pages/AddPage.jsx
@@ -1,13 +1,13 @@
import { useEffect, useState } from "react"
import { Form, Button, Card } from "react-bootstrap"
import { MapContainer, TileLayer } from 'react-leaflet'
+import { latLng } from "leaflet"
+
+import { ClickHandler, LocationMarker, TrashboxMarkers } from "../components"
+import { useAddAnnouncement, useTrashboxes } from "../hooks/api"
import { categoryNames } from "../assets/category"
-import { latLng } from "leaflet"
-import { metros } from "../assets/metro"
-import LocationMarker from "../components/LocationMarker"
-import TrashboxMarkers from "../components/TrashboxMarkers"
-import { useAddAnnouncement, useTrashboxes } from "../hooks/api"
+import { stations, lines } from "../assets/metro"
function AddPage() {
const [addressPosition, setAddressPosition] = useState(latLng(59.972, 30.3227))
@@ -46,7 +46,7 @@ function AddPage() {
})()
}, [addressPosition])
- const {doAdd, status} = useAddAnnouncement()
+ const { doAdd, status } = useAddAnnouncement()
const handleSubmit = (event) => {
event.preventDefault()
@@ -107,6 +107,9 @@ function AddPage() {
position={addressPosition}
setPosition={setAddressPosition}
/>
+
Адрес: {address}
@@ -134,11 +137,13 @@ function AddPage() {
- {Object.entries(metros).map(
- ([branch, stations]) =>
- stations.map(metro =>
-
- )
+ {Object.entries(stations).map(
+ ([line, stations]) =>
+
)}
diff --git a/front/src/pages/HomePage.jsx b/front/src/pages/HomePage.jsx
index 63cfe93..0602629 100644
--- a/front/src/pages/HomePage.jsx
+++ b/front/src/pages/HomePage.jsx
@@ -1,11 +1,8 @@
import { useEffect, useState } from 'react'
import Stories from 'react-insta-stories'
-import BottomNavBar from '../components/BottomNavBar'
-import useStoryDimensions from '../hooks/useStoryDimensions'
-import AnnouncementDetails from '../components/AnnouncementDetails'
-import Filters from '../components/Filters'
-
+import { BottomNavBar, AnnouncementDetails, Filters } from '../components'
+import { useStoryDimensions } from '../hooks'
import { useHomeAnnouncementList } from '../hooks/api'
import puffSpinner from '../assets/puff.svg'
@@ -29,21 +26,21 @@ function fallbackGenerateStories(announcementsFetch) {
return fallbackStory()
if (announcementsFetch.error)
- return fallbackStory(announcementsFetch.error)
+ return fallbackStory(announcementsFetch.error, true)
- if (stories.length == 0)
+ if (stories.length === 0)
return fallbackStory("Здесь пока пусто")
return stories
}
-const fallbackStory = (text) => [{
+const fallbackStory = (text, isError = false) => [{
content: ({ action }) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => { action('pause') }, [action])
return (
-
+
{text ||

}
)
@@ -66,22 +63,14 @@ function HomePage() {
return (<>
- {announcementsFetch.error ?
- (
-
-
{announcementsFetch.error}
-
- ) : (
-
- )
- }
+
>)
diff --git a/front/src/pages/LoginPage.jsx b/front/src/pages/LoginPage.jsx
index 3243ce8..cccf7a8 100644
--- a/front/src/pages/LoginPage.jsx
+++ b/front/src/pages/LoginPage.jsx
@@ -1,5 +1,6 @@
import { Form, Button, Card, Tabs, Tab } from "react-bootstrap"
import { useNavigate } from "react-router-dom";
+
import { useAuth } from "../hooks/api";
import { setToken } from "../utils/auth";
diff --git a/front/src/utils/metro.js b/front/src/utils/metro.js
new file mode 100644
index 0000000..dce5a72
--- /dev/null
+++ b/front/src/utils/metro.js
@@ -0,0 +1,7 @@
+import { stations } from "../assets/metro"
+
+function lineByName(name) {
+ return Object.keys(stations).find(line => stations[line].has(name))
+}
+
+export { lineByName }