Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 74 additions & 54 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import { ChevronRightIcon } from "@/components/icons/ChevronRight";
import { MenuIcon } from "@/components/icons/Menu";
import { MenuModal } from "@/components/MenuModal";
import { RouteInfoModal } from "@/components/RouteInfoModal";
import type { Line, Route, Station } from "@/types/stationapi";
import { useFetchLineById } from "@/hooks/useFetchLineById";
import { useFetchLinesByName } from "@/hooks/useFetchLinesByName";
import { useFetchRoutes } from "@/hooks/useFetchRoutes";
import { useFetchStationsByGroupId } from "@/hooks/useFetchStationsByGroupId";
import { useFetchStationsByLineId } from "@/hooks/useFetchStationsByLineId";
import { useFetchStationsByName } from "@/hooks/useFetchStationsByName";
import { useParams } from "@/hooks/useParams";
import type { Line, Route, Station } from "@/types/stationapi";
import { removeBrackets } from "@/utils/removeBracket";

type Inputs = {
Expand Down Expand Up @@ -129,11 +129,11 @@ const SelectStationListBox = ({
textValue={value}
>
<p className="font-medium opacity-90">{sta.name}</p>
<div className="flex items-center mt-1 h-4">
<div className="flex flex-wrap gap-1 mt-1">
{sta.lines.map((line) => (
<div
key={line.id}
className="w-2 h-2 rounded-full ml-1 first:ml-0"
className="w-2 h-2 rounded-full flex-shrink-0"
style={{ background: line.color }}
/>
))}
Expand Down Expand Up @@ -227,10 +227,10 @@ const LineListBox = ({
textValue={value}
>
<p className="font-medium opacity-90">{l.nameShort}</p>
<div className="flex items-center mt-1 h-4">
<div className="flex flex-wrap gap-1 mt-1">
<div
key={l.id}
className="w-2 h-2 rounded-full ml-1 first:ml-0"
className="w-2 h-2 rounded-full flex-shrink-0"
style={{ background: l.color }}
/>
</div>
Expand Down Expand Up @@ -260,8 +260,10 @@ const RoutesListBox = ({
const isHasTypeChange = useCallback(
(routeId: number) => {
const targetRoute = routes?.find((r) => r.id === routeId);
const typeIds = targetRoute?.stops.map((s) => s.trainType?.typeId);
return Array.from(new Set(typeIds)).length > 1;
const typeIds = targetRoute?.stops
.map((s) => s.trainType?.typeId)
.filter((id): id is number => id != null);
return new Set(typeIds).size > 1;
},
[routes],
);
Expand Down Expand Up @@ -317,7 +319,7 @@ const RoutesListBox = ({
)}
</p>
<div className="mt-1">
<div className="flex">
<div className="flex flex-wrap gap-1">
{Array.from(
new Map(
route.stops.map((stop) => [
Expand All @@ -336,7 +338,7 @@ const RoutesListBox = ({
.map((stop) => (
<div
key={`${stop.line?.id}:${stop.line?.color}`}
className="w-2 h-2 rounded-full ml-1"
className="w-2 h-2 rounded-full flex-shrink-0"
style={{ background: stop.line?.color }}
/>
))}
Expand Down Expand Up @@ -406,7 +408,7 @@ const StationListBox = ({
textValue={sta.id.toString()}
>
<p className="font-medium opacity-90">{sta.name ?? ""}</p>
<div className="mt-1 flex">
<div className="mt-1 flex flex-wrap gap-1">
{sta.lines
.filter((stop, idx, arr) => {
const lineColors = arr.map((l) => l?.color);
Expand All @@ -418,7 +420,7 @@ const StationListBox = ({
.map((l) => (
<div
key={`${l.id}:${l.color}`}
className="w-2 h-2 rounded-full ml-1"
className="w-2 h-2 rounded-full flex-shrink-0"
style={{ background: l.color }}
/>
))}
Expand Down Expand Up @@ -519,12 +521,10 @@ export default function Home() {
const {
stations: fromStationsByGroupId = [],
error: fetchFromStationsByGroupIdError,
isLoading: isFromStationsByGroupIdLoading,
} = useFetchStationsByGroupId(Number(params.get("fsid")));
const {
stations: toStationsByGroupId = [],
error: fetchToStationsByGroupIdError,
isLoading: isToStationsByGroupIdLoading,
} = useFetchStationsByGroupId(Number(params.get("tsid")));

const debouncedToStationName = useDebounce(toStationName, DEBOUNCE_DELAY);
Expand Down Expand Up @@ -659,42 +659,69 @@ export default function Home() {
[selectedToStationId, toStationsByGroupId],
);

const getStationDisplayName = useCallback(
(stationName: string | undefined, stationGroupId: string) => {
if (stationName) return stationName;
const groupId = Number(stationGroupId);
const stop = routes
?.flatMap((r) => r.stops)
.find((s) => s.groupId === groupId);
if (!stop) return undefined;
return stop.name.endsWith("駅") ? stop.name : `${stop.name}駅`;
},
[routes],
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const fromStationDisplayName = useMemo(
() => getStationDisplayName(fromStation?.name, selectedFromStationId),
[getStationDisplayName, fromStation?.name, selectedFromStationId],
);

const toStationDisplayName = useMemo(
() => getStationDisplayName(toStation?.name, selectedToStationId),
[getStationDisplayName, toStation?.name, selectedToStationId],
);

const handleLaunchApp = useCallback(() => {
const appScheme = devMode ? "trainlcd-canary://" : "trainlcd://";

const lineGroupId = route?.stops.find(
(stop) => stop.trainType?.groupId === Number(selectedRouteId),
)?.trainType?.groupId;

const direction =
(route?.stops ?? []).findIndex(
(s) => s.groupId === fromStation?.groupId,
) <
(route?.stops ?? []).findIndex((s) => s.groupId === toStation?.groupId)
? 1
: 0;
const fromIndex = (route?.stops ?? []).findIndex(
(s) => s.groupId === Number(selectedFromStationId),
);
const toIndex = (route?.stops ?? []).findIndex(
(s) => s.groupId === Number(selectedToStationId),
);
if (fromIndex === -1 || toIndex === -1) return;
const direction = fromIndex < toIndex ? 0 : 1;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const lineId = fromStop?.line?.id;
const sgid = fromStation?.groupId;
if (!sgid) return;

if (lineId && lineGroupId) {
window.open(
`${appScheme}?sgid=${fromStation?.groupId}&lid=${lineId}&lgid=${lineGroupId}&dir=${direction}`,
`${appScheme}?sgid=${sgid}&lid=${lineId}&lgid=${lineGroupId}&dir=${direction}`,
);
return;
}

if (lineId) {
window.open(
`${appScheme}?sgid=${fromStation?.groupId}&lid=${lineId}&dir=${direction}`,
`${appScheme}?sgid=${sgid}&lid=${lineId}&dir=${direction}`,
);
}
}, [
devMode,
fromStation?.groupId,
fromStop?.line?.id,
route?.stops,
selectedFromStationId,
selectedToStationId,
selectedRouteId,
toStation?.groupId,
]);

const handleUpdateSearchMode = useCallback(
Expand Down Expand Up @@ -768,22 +795,17 @@ export default function Home() {
</p>

{params.get("mode") !== "line" &&
(isFromStationsLoading ||
isToStationsLoading ||
!fromStation ||
!toStation) ? (
!fromStationDisplayName &&
!toStationDisplayName ? (
<Skeleton className="w-32 h-4 mt-1 mb-4 lg:mb-8 self-center rounded-md" />
) : null}

{params.get("mode") !== "line" &&
!isFromStationsLoading &&
!isToStationsLoading &&
fromStation &&
toStation ? (
(fromStationDisplayName || toStationDisplayName) ? (
<p className="font-medium opacity-50 mt-1 mb-4 lg:mb-8 text-center text-xs">
{fromStation?.name}
{fromStationDisplayName ?? "..."}
&nbsp;-&nbsp;
{toStation?.name}
{toStationDisplayName ?? "..."}
</p>
) : null}

Expand All @@ -804,27 +826,25 @@ export default function Home() {
<Skeleton className="w-32 h-4 mt-1 mb-4 lg:mb-8 self-center rounded-md" />
) : null}

<>
{selectedLineId ? (
<StationListBox
isLoading={isStationsLoading}
stations={stationsByLineId}
onTrainTypeClick={handleStationClick}
error={fetchStationsError}
/>
) : (
<RoutesListBox
isLoading={isRoutesLoading}
fromStationId={Number(selectedFromStationId)}
routes={routes ?? []}
onStationClick={handleTrainTypeClick}
error={routesLoadingError}
/>
)}
<p className="font-medium my-2 text-xs opacity-50">
TrainLCDアプリで利用可能なデータであるため、実際の情報とは異なる場合があります。
</p>
</>
{selectedLineId ? (
<StationListBox
isLoading={isStationsLoading}
stations={stationsByLineId}
onTrainTypeClick={handleStationClick}
error={fetchStationsError}
/>
) : (
Comment on lines +829 to +836
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

handleStationClick が no-op のため、路線モードで駅をタップしても何も起きません

handleStationClick(Line 621)は () => {} を返すだけです。StationListBoxonTrainTypeClick に渡されており、路線モード(selectedLineId が存在するケース)で駅をクリックしても一切のアクションが発生しません。意図的な未実装であれば TODO コメントを残すことを推奨します。

未実装の handleStationClick の動作(ルート情報モーダルを開くなど)を実装する issue を作成しましょうか?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/page.tsx` around lines 824 - 831, handleStationClick is currently a no-op
(returns () => {}) but is passed into StationListBox as onTrainTypeClick when
selectedLineId is set, so tapping a station does nothing; implement
handleStationClick to perform the intended action (e.g., open the route/station
info modal or navigate to station details) by setting the relevant state and
invoking the modal/display function used elsewhere in the component (for
example, setSelectedStation(...) and setIsRouteModalOpen(true) or call the
existing showRouteModal/showStationDetails helper), and replace the noop with
that implementation so StationListBox.onTrainTypeClick triggers the UI action in
route (selectedLineId) mode.

<RoutesListBox
isLoading={isRoutesLoading}
fromStationId={Number(selectedFromStationId)}
routes={routes ?? []}
onStationClick={handleTrainTypeClick}
error={routesLoadingError}
/>
)}
<p className="font-medium my-2 text-xs opacity-50">
TrainLCDアプリで利用可能なデータであるため、実際の情報とは異なる場合があります。
</p>
</div>
)}

Expand Down
Loading