Skip to content

Commit 266429f

Browse files
authored
feat: Remove lineProfile page (#1842)
1 parent e639afe commit 266429f

24 files changed

Lines changed: 51 additions & 1474 deletions

CLAUDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ src/
101101
│ ├── dashboard/ # Analytics dashboard with charts
102102
│ ├── gaps/ # Service gap visualization
103103
│ ├── gapsPatterns/ # Gap-patterns analysis
104-
│ ├── lineProfile/ # Individual line details
105104
│ ├── operator/ # Operator performance
106105
│ ├── singleLineMap/ # Single line on the map
107106
│ ├── stationStops/ # Planned vs. actual stop times at one stop

src/api/gtfsService.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -100,31 +100,6 @@ export async function getGtfsStopHitTimesAsync(stop: BusStop, time: dayjs.Dayjs)
100100
}
101101
}
102102

103-
export async function getRouteById(routeId?: string, signal?: AbortSignal) {
104-
try {
105-
if (!routeId?.trim()) {
106-
throw new Error('Route id is required and cannot be empty')
107-
}
108-
const id = Number(routeId)
109-
if (!Number.isInteger(id) || id <= 0 || id > Number.MAX_SAFE_INTEGER) {
110-
throw new Error(`Invalid route id: ${routeId}.`)
111-
}
112-
return await GTFS_API.gtfsRoutesGetGet({ id }, { signal })
113-
} catch (error) {
114-
let errorMessage: string
115-
if (error instanceof Error) {
116-
errorMessage =
117-
error.message === 'Response returned an error code'
118-
? `Route with id ${routeId} not found`
119-
: error.message
120-
} else {
121-
errorMessage = 'An unexpected error occurred while fetching route data'
122-
}
123-
console.error(`Failed to get route ${routeId}:`, errorMessage)
124-
throw new Error(errorMessage)
125-
}
126-
}
127-
128103
export async function getAllRoutesList(operatorId: string, date: CivilDate, signal?: AbortSignal) {
129104
return await GTFS_API.gtfsRoutesListGet(
130105
{

src/layout/header/shareUrl.test.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -208,32 +208,3 @@ describe('buildShareUrl — per-page param contracts', () => {
208208
})
209209
}
210210
})
211-
212-
// ---------------------------------------------------------------------------
213-
// buildShareUrl — dynamic profile path
214-
// ---------------------------------------------------------------------------
215-
216-
// /profile/:id is not in PAGE_SHARE_PARAMS. The route ID is already in the
217-
// path, so GlobalSearchContext params must not leak into the URL — only explicit
218-
// page params (e.g. rideTime) registered via PageShareParamsContext appear.
219-
220-
describe('buildShareUrl — dynamic profile path', () => {
221-
it('no GlobalSearchContext params leak into the URL', () => {
222-
const p = paramsOf(build('/profile/12345', fullSearch))
223-
expect(p.operatorId).toBeUndefined()
224-
expect(p.lineNumber).toBeUndefined()
225-
expect(p.date).toBeUndefined()
226-
expect(p.routeKey).toBeUndefined()
227-
expect(p.rideTime).toBeUndefined()
228-
})
229-
230-
it('page params (rideTime) are included', () => {
231-
const p = paramsOf(build('/profile/12345', fullSearch, { rideTime: '08:30:00' }))
232-
expect(p.rideTime).toBe('08:30:00')
233-
})
234-
235-
it('profile id is preserved in the pathname', () => {
236-
const url = new URL(build('/profile/12345', fullSearch, { rideTime: '08:30:00' }))
237-
expect(url.pathname).toBe('/profile/12345')
238-
})
239-
})

src/locale/ar.json

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
"year": "سنوياً"
8080
},
8181
"all_lines_on_date": "جميع الخطوط في هذا التاريخ",
82-
"profile": "بروفايل",
8382
"map": "خريطة",
8483
"id": "معرّف تقني",
8584
"origin": "المصدر",
@@ -229,6 +228,7 @@
229228
"from": "المصدر",
230229
"destination": "الوجهة",
231230
"kmh": "كم/ساعة",
231+
"agency_name": "اسم الشركة المشغّلة",
232232
"sample_time": "وقت العيّنة",
233233
"at_time": "في الساعة",
234234
"drive_direction": "اتّجاه السير",
@@ -309,38 +309,6 @@
309309
"complaint_details_required": "لكي نتمكّن من فحص طلبك، يُرجى ذكر وسائل النقل المطلوب التنسيق بينها، وأرقام الخطوط، وأسماء المشغّلين، والرقم الكتالوجي للمحطة والأوقات ذات الصلة.",
310310
"new_complaint": "شكوى جديدة"
311311
},
312-
"lineProfile": {
313-
"title": "بروفايل الخط",
314-
"notFound": "ما قدرنا نلاقي الخط اللي بتدوّر عليه :(",
315-
"id": "معرّف تقني",
316-
"date": "التاريخ",
317-
"lineReference": "معرّف الخط",
318-
"operatorReference": "معرّف الشركة المشغّلة",
319-
"agencyName": "اسم الشركة المشغّلة",
320-
"route": {
321-
"shortName": "رقم الخط",
322-
"start": "المصدر",
323-
"end": "الوجهة",
324-
"mkt": "رمز الخط",
325-
"direction": "اتّجاه الخط",
326-
"direction_forth": "ذهاب",
327-
"direction_back": "إياب",
328-
"alternative": "بديل رقم",
329-
"type": "نوع الخط"
330-
},
331-
"ride": {
332-
"journey": "معرّف الرحلة",
333-
"id": "معرّف تقني",
334-
"duration": "مدّة الرحلة"
335-
},
336-
"stop": {
337-
"name": "اسم المحطّة",
338-
"code": "رقم المحطّة",
339-
"route": "مسار المحطّة",
340-
"of": "من أصل",
341-
"location": "إحداثيات"
342-
}
343-
},
344312
"errorPage": {
345313
"title": "عفواً، حدث خطأ ما",
346314
"text": "يُرجى المحاولة مرّة أخرى لاحقاً",

src/locale/en.json

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
"year": "Yearly"
9595
},
9696
"all_lines_on_date": "All Lines on This Date",
97-
"profile": "Profile",
9897
"map": "Map",
9998
"id": "ID",
10099
"origin": "Origin",
@@ -261,6 +260,7 @@
261260
"from": "from",
262261
"destination": "destination",
263262
"kmh": "kmh",
263+
"agency_name": "Agency Name",
264264
"sample_time": "sample time",
265265
"at_time": "at",
266266
"drive_direction": "drive direction",
@@ -341,38 +341,6 @@
341341
"complaint_details_required": "In order for us to check your request, please specify in the request which modes of transportation you wish to match, line numbers, operator names, station SKU, and relevant times.",
342342
"new_complaint": "New Complaint"
343343
},
344-
"lineProfile": {
345-
"title": "Profile for Line",
346-
"notFound": "We couldn't find the line you were looking for :(",
347-
"id": "ID",
348-
"date": "Date",
349-
"lineReference": "Line Reference",
350-
"operatorReference": "Operator Reference",
351-
"agencyName": "Agency Name",
352-
"route": {
353-
"shortName": "Route Short Name",
354-
"start": "Start",
355-
"end": "End",
356-
"mkt": "Route MKT",
357-
"direction": "Route Direction",
358-
"direction_forth": "Forward",
359-
"direction_back": "Backward",
360-
"alternative": "Route Alternative",
361-
"type": "Route Type"
362-
},
363-
"ride": {
364-
"journey": "Journey ID",
365-
"id": "Ride ID",
366-
"duration": "Ride Duration"
367-
},
368-
"stop": {
369-
"name": "Stop Name",
370-
"code": "Stop ID",
371-
"route": "Stop Route",
372-
"of": "of",
373-
"location": "Stop Location"
374-
}
375-
},
376344
"errorPage": {
377345
"title": "Oops, something went wrong",
378346
"text": "Please try again later",

src/locale/he.json

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
"year": "שנתית"
9595
},
9696
"all_lines_on_date": "כל הקווים בתאריך זה",
97-
"profile": "פרופיל",
9897
"map": "מפה",
9998
"id": "מזהה טכני",
10099
"origin": "מוצא",
@@ -261,6 +260,7 @@
261260
"from": "מוצא",
262261
"destination": "יעד",
263262
"kmh": "קמ״ש",
263+
"agency_name": "שם חברה מפעילה",
264264
"sample_time": "זמן דגימה",
265265
"at_time": "בשעה",
266266
"drive_direction": "כיוון נסיעה",
@@ -341,38 +341,6 @@
341341
"complaint_details_required": "על מנת שנוכל לבדוק בקשתך, יש לפרט במסגרת הבקשה בין אילו אמצעי תחבורה ברצונך להתאים, מספרי קווים, שמות מפעילים, מק\"ט תחנה ושעות רלוונטיות.",
342342
"new_complaint": "תלונה חדשה"
343343
},
344-
"lineProfile": {
345-
"title": "פרופיל קו",
346-
"notFound": "לא הצלחנו למצוא את הקו שחיפשת :(",
347-
"id": "מזהה טכני",
348-
"date": "תאריך",
349-
"lineReference": "מזהה קו",
350-
"operatorReference": "מזהה חברה מפעילה",
351-
"agencyName": "שם חברה מפעילה",
352-
"route": {
353-
"shortName": "מס' קו",
354-
"start": "מוצא",
355-
"end": "יעד",
356-
"mkt": "מק\"ט קו",
357-
"direction": "כיוון קו",
358-
"direction_forth": "הלוך",
359-
"direction_back": "חזור",
360-
"alternative": "חלופה מס'",
361-
"type": "סוג קו"
362-
},
363-
"ride": {
364-
"journey": "מזהה נסיעה",
365-
"id": "מזהה טכני",
366-
"duration": "זמן נסיעה"
367-
},
368-
"stop": {
369-
"name": "שם תחנה",
370-
"code": "מספר תחנה",
371-
"route": "מסלול תחנה",
372-
"of": "מתוך",
373-
"location": "נ\"צ"
374-
}
375-
},
376344
"errorPage": {
377345
"title": "אופס, משהו השתבש",
378346
"text": "אנא נסה שוב מאוחר יותר",

src/locale/ru.json

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
"year": "Ежегодно"
8080
},
8181
"all_lines_on_date": "Все линии на эту дату",
82-
"profile": "Профиль",
8382
"map": "Карта",
8483
"id": "ID",
8584
"origin": "Пункт отправления",
@@ -229,6 +228,7 @@
229228
"from": "от",
230229
"destination": "пункт назначения",
231230
"kmh": "км/ч",
231+
"agency_name": "Название агентства",
232232
"sample_time": "время выборки",
233233
"at_time": "в",
234234
"drive_direction": "направление движения",
@@ -309,38 +309,6 @@
309309
"complaint_details_required": "Чтобы мы могли рассмотреть вашу заявку, необходимо подробно описать, между какими видами транспорта вы хотите обеспечить стыковку: укажите номера маршрутов, названия перевозчиков, каталожный номер остановки и соответствующее время.",
310310
"new_complaint": "Новая жалоба"
311311
},
312-
"lineProfile": {
313-
"title": "Профиль для линии",
314-
"notFound": "Мы не смогли найти линию, которую вы искали :(",
315-
"id": "ID",
316-
"date": "Дата",
317-
"lineReference": "Ссылка на линию",
318-
"operatorReference": "Ссылка на оператора",
319-
"agencyName": "Название агентства",
320-
"route": {
321-
"shortName": "Короткое название маршрута",
322-
"start": "Начало",
323-
"end": "Конец",
324-
"mkt": "Маршрут MKT",
325-
"direction": "Направление маршрута",
326-
"direction_forth": "Вперед",
327-
"direction_back": "Назад",
328-
"alternative": "Альтернатива маршрута",
329-
"type": "Тип маршрута"
330-
},
331-
"ride": {
332-
"journey": "ID рейса",
333-
"id": "ID поездки",
334-
"duration": "Продолжительность поездки"
335-
},
336-
"stop": {
337-
"name": "Название остановки",
338-
"code": "ID остановки",
339-
"route": "Маршрут остановки",
340-
"of": "из",
341-
"location": "Местоположение остановки"
342-
}
343-
},
344312
"errorPage": {
345313
"title": "Упс, что-то пошло не так",
346314
"text": "Пожалуйста, попробуйте позже",

src/model/globalState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export type GlobalSearchState = {
2121
* Set by /gaps when the user clicks a row; consumed by /single-line-map. */
2222
rideTime: string | null
2323

24-
/** Selected stop key — shared across /station-stops, /single-line-map, /line-profile. */
24+
/** Selected stop key — shared across /station-stops, /single-line-map. */
2525
stopKey: string | null
2626
}
2727

src/pages/components/map-related/MapLayers/BusToolTip.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { GtfsRoutePydanticModel } from '@hasadna/open-bus-api-client'
22
import { Button, CircularProgress } from '@mui/material'
3-
import { ReactNode, useEffect, useState } from 'react'
3+
import { ReactNode, useContext, useEffect, useState } from 'react'
44
import { useTranslation } from 'react-i18next'
5-
import { Link } from 'react-router'
5+
import { Link, useNavigate } from 'react-router'
66
import { getRoutesByLineRef } from 'src/api/gtfsService'
77
import dayjs, { ISRAEL_TIMEZONE } from 'src/dayjs'
8+
import { GlobalSearchContext } from 'src/model/globalState'
89
import { toCivilDate, todayCivilDate } from 'src/model/time/civilDate'
910
import { routeStartEnd, vehicleIDFormat } from 'src/pages/components/utils/rotueUtils'
1011
import SkeletonLoader from 'src/shared/SkeletonLoader'
@@ -14,14 +15,23 @@ import type { Point } from '../map-types'
1415
import ComplaintModal from './ComplaintModal'
1516
import './BusToolTip.scss'
1617

17-
export type BusToolTipProps = { position: Point; icon: string; children?: ReactNode }
18+
export type BusToolTipProps = {
19+
position: Point
20+
icon: string
21+
children?: ReactNode
22+
/** Turn the line number into a link to /single-line-map. Off by default: the
23+
* line-specific maps that render this tooltip are already showing that line. */
24+
linkToLineMap?: boolean
25+
}
1826

19-
export function BusToolTip({ position, icon, children }: BusToolTipProps) {
27+
export function BusToolTip({ position, icon, children, linkToLineMap }: BusToolTipProps) {
2028
const [route, setRoute] = useState<GtfsRoutePydanticModel>()
2129
const [isLoading, setIsLoading] = useState(false)
2230
const [showJson, setShowJson] = useState(false)
2331
const { t, i18n } = useTranslation()
2432
const [modalOpen, setModalOpen] = useState(false)
33+
const { setSearch } = useContext(GlobalSearchContext)
34+
const navigate = useNavigate()
2535

2636
useEffect(() => {
2737
if (!position.point?.id) return
@@ -69,6 +79,18 @@ export function BusToolTip({ position, icon, children }: BusToolTipProps) {
6979
}
7080

7181
const [from, destination] = routeStartEnd(route?.routeLongName)
82+
const lineLabel = route?.routeShortName || 'NaN' // 'NaN' is the fallback for a missing route number
83+
84+
const showOnLineMap = (route: GtfsRoutePydanticModel) => {
85+
setSearch((current) => ({
86+
...current,
87+
date: toCivilDate(route.date) ?? current.date,
88+
operatorId: route.operatorRef.toString(),
89+
lineNumber: route.routeShortName ?? null,
90+
routeKey: `${route.routeMkt}-${route.routeDirection}-${route.routeAlternative}`,
91+
}))
92+
void navigate('/single-line-map')
93+
}
7294

7395
return (
7496
<div className="bus-tooltip" dir={i18n.dir()}>
@@ -86,8 +108,18 @@ export function BusToolTip({ position, icon, children }: BusToolTipProps) {
86108
<h1 className="title">
87109
{`${t('line')}: `}
88110
<span>
89-
{/* eslint-disable-next-line i18next/no-literal-string -- fallback for a missing route number */}
90-
<Link to={`/profile/${route.id}`}>{route?.routeShortName || 'NaN'}</Link>
111+
{linkToLineMap ? (
112+
<Link
113+
to="/single-line-map"
114+
onClick={(e) => {
115+
e.preventDefault()
116+
showOnLineMap(route)
117+
}}>
118+
{lineLabel}
119+
</Link>
120+
) : (
121+
lineLabel
122+
)}
91123
</span>
92124
</h1>
93125
<Link to={`/operator?operatorId=${position.point?.siriRouteOperatorRef}`}>
@@ -97,7 +129,7 @@ export function BusToolTip({ position, icon, children }: BusToolTipProps) {
97129
<div className="content">
98130
<ul>
99131
<li>
100-
{`${t('lineProfile.agencyName')}: `}
132+
{`${t('agency_name')}: `}
101133

102134
<span>
103135
<Link to={`/operator?operatorId=${position.point?.siriRouteOperatorRef}`}>

0 commit comments

Comments
 (0)