Conversation
AvtoBBus
left a comment
There was a problem hiding this comment.
Как бы не было печально, но поиск по карте является обязательным требованием, поэтому вам на помощь OpenLayers
| <title>Прибывалка63: Электрички</title> | ||
| </head> | ||
| <body> | ||
| <noscript>You need to enable JavaScript to run this app.</noscript> |
There was a problem hiding this comment.
Коментарии и вот эту строку можно удалить
| // If you want to start measuring performance in your app, pass a function | ||
| // to log results (for example: reportWebVitals(console.log)) | ||
| // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals | ||
| reportWebVitals(); |
| import { stationsList } from './stations'; | ||
|
|
||
| const App = () => { | ||
| const [stations] = useState(stationsList); |
There was a problem hiding this comment.
const [stations, setStations] = useState(stationsList);Если даже не будете использовать, нужно просто оставлять запятую по правильному
| const formatTime = (datetime) => { | ||
| if (!datetime) return '—'; | ||
| try { | ||
| const date = new Date(datetime); | ||
| return date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); | ||
| } catch { | ||
| return '—'; | ||
| } | ||
| }; | ||
|
|
||
| const formatDuration = (seconds) => { | ||
| if (!seconds) return null; | ||
|
|
||
| const totalMinutes = Math.floor(seconds / 60); | ||
| const hours = Math.floor(totalMinutes / 60); | ||
| const minutes = totalMinutes % 60; | ||
|
|
||
| if (hours > 0) { | ||
| return `${hours} ч ${minutes} мин`; | ||
| } | ||
| return `${minutes} мин`; | ||
| }; | ||
|
|
||
| const getTrainStatus = (departureTime, arrivalTime) => { | ||
| if (!departureTime && !arrivalTime) return { text: 'нет отправления', type: 'no-departure' }; | ||
|
|
||
| const now = currentTime; | ||
| const departure = departureTime ? new Date(departureTime) : null; |
There was a problem hiding this comment.
Вот эти 3 функции в целом вспомогательные и их лучше вынести отдельно, в идеале папка utils и там файл(-ы) с этими функциями
| useEffect(() => { | ||
| if (mode === 'between' && fromSearchQuery.length > 1) { | ||
| const filtered = stations.filter(station => | ||
| station.title.toLowerCase().includes(fromSearchQuery.toLowerCase()) | ||
| ); | ||
| setFilteredFromStations(filtered); | ||
| } else { | ||
| setFilteredFromStations([]); | ||
| } | ||
| }, [fromSearchQuery, stations, mode]); | ||
|
|
||
| useEffect(() => { | ||
| if (mode === 'between' && toSearchQuery.length > 1) { | ||
| const filtered = stations.filter(station => | ||
| station.title.toLowerCase().includes(toSearchQuery.toLowerCase()) | ||
| ); | ||
| setFilteredToStations(filtered); | ||
| } else { | ||
| setFilteredToStations([]); | ||
| } | ||
| }, [toSearchQuery, stations, mode]); |
There was a problem hiding this comment.
Не самый лучший вариант, поскольку это нагромождение кода, который может вызываться лишний раз из-за каких-то изменений
Эти три функции в useEffect они как минимум идентичны, кроме 1 переменной в двух местах, а как максимум нужны для того чтобы отлавливать изменение либо станции отправления, либо станции прибытия где в onChange вы поставили только функции, обновляющие состояния. Самое правильное это создать 1 функцию хэндлер, которая будет принимать значение mode, список станций и то в какую переменную нужно записывать.
| const handleStationSelect = (station) => { | ||
| setSelectedStation(station); | ||
| setSearchQuery(''); | ||
| setFilteredStations([]); | ||
| setApiError(''); | ||
| }; | ||
|
|
||
| const handleFromStationSelect = (station) => { | ||
| setFromStation(station); | ||
| setFromSearchQuery(''); | ||
| setFilteredFromStations([]); | ||
| setApiError(''); | ||
| setNoRoutesMessage(''); | ||
| }; | ||
|
|
||
| const handleToStationSelect = (station) => { | ||
| setToStation(station); | ||
| setToSearchQuery(''); | ||
| setFilteredToStations([]); | ||
| setApiError(''); | ||
| setNoRoutesMessage(''); | ||
| }; | ||
|
|
||
| const resetSelection = () => { | ||
| setSelectedStation(null); | ||
| setFromStation(null); | ||
| setToStation(null); | ||
| setSearchQuery(''); | ||
| setFromSearchQuery(''); | ||
| setToSearchQuery(''); | ||
| setFilteredStations([]); | ||
| setFilteredFromStations([]); | ||
| setFilteredToStations([]); | ||
| setSchedule([]); | ||
| setApiError(''); | ||
| setNoRoutesMessage(''); | ||
| }; |
There was a problem hiding this comment.
Очень что-то много повторяющихся вещей есть, лучше следовать DRY
There was a problem hiding this comment.
В идеале разнести код на несколько отдельных файлов, к примеру карточку с классом schedule-item точно можно вынести. Какие-нибудь секция с вводом значений для поиска тоже выносится.
Т.е. в вашем случае, можно просто сделать папку features (читать про FSD) и там добавляется файл SearcSection и SheduleCard к примеру, в которые инкапсулируется логика и файл App сбросит лишние килограммы веса
No description provided.