From 7801c4a49150a4103e6ba1c349b3034bbc749403 Mon Sep 17 00:00:00 2001 From: Arnaud Nelissen Date: Fri, 17 Apr 2026 14:13:01 +0200 Subject: [PATCH] Navigate between similar targets within the detail drawer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clicking a nearby target opens it inside the same drawer: the drawer content switches to the new target (fetched via useTarget) and all tabs/hooks update automatically. A '← [name]' back button appears in the tab bar to return to the previous target. Navigation is stackable (can chain through multiple nearby targets). Tab and filter selection reset on each navigation step. Co-Authored-By: Claude Sonnet 4.6 --- .../src/components/targets/DetailDrawer.tsx | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/targets/DetailDrawer.tsx b/frontend/src/components/targets/DetailDrawer.tsx index a0d64a5..47d468d 100644 --- a/frontend/src/components/targets/DetailDrawer.tsx +++ b/frontend/src/components/targets/DetailDrawer.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import type { Target, Workflow } from '../../api/types'; -import { useTargetCurve, useTargetFilters, useTargetSimilar, useTargetVisibility, useTargetWorkflow, useTargetYearly } from '../../hooks/useTargets'; +import { useTarget, useTargetCurve, useTargetFilters, useTargetSimilar, useTargetVisibility, useTargetWorkflow, useTargetYearly } from '../../hooks/useTargets'; import { useTargetLog } from '../../hooks/useLog'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { api } from '../../api'; @@ -231,12 +231,35 @@ function ImagingCalculator({ target, filterId }: { target: Target; filterId: str ); } -export default function DetailDrawer({ target }: Props) { +export default function DetailDrawer({ target: propTarget }: Props) { const [tab, setTab] = useState(0); const [selectedFilter, setSelectedFilter] = useState('sv220'); const [notes, setNotes] = useState(null); + const [navStack, setNavStack] = useState([]); // stack of navigated target IDs const qc = useQueryClient(); + const navId = navStack.length > 0 ? navStack[navStack.length - 1] : ''; + const { data: navTarget } = useTarget(navId); + // Use navigated target when available, otherwise fall back to the prop target + const target = (navId && navTarget) ? navTarget : propTarget; + + const navigateTo = (id: string) => { + setNavStack(prev => [...prev, id]); + setTab(0); + setSelectedFilter('sv220'); + setNotes(null); + }; + const navigateBack = () => { + setNavStack(prev => prev.slice(0, -1)); + setTab(0); + setSelectedFilter('sv220'); + setNotes(null); + }; + // Name of the target we'd go back to + const backName = navStack.length === 1 + ? (propTarget.common_name ?? propTarget.name) + : navStack.length > 1 ? navStack[navStack.length - 2] : null; + const { data: tonight } = useTonight(); const { data: visData } = useTargetVisibility(target.id); const { data: curveData } = useTargetCurve(target.id); @@ -265,8 +288,24 @@ export default function DetailDrawer({ target }: Props) { return (
- {/* Tabs */} -
+ {/* Tabs + optional back button */} +
+ {navStack.length > 0 && ( + + )} {TABS.map((t, i) => (
+ + ))}