diff --git a/frontend/src/components/layout/RightSidebar.tsx b/frontend/src/components/layout/RightSidebar.tsx index 8f69b15..a7703d1 100644 --- a/frontend/src/components/layout/RightSidebar.tsx +++ b/frontend/src/components/layout/RightSidebar.tsx @@ -249,6 +249,9 @@ export function RightSidebar() { } // ── Single-photo: full editor via PhotoInfoPanel ──────────────────── + // Heap card + header stay pinned at the top; the edit fields and + // readonly metadata sections scroll together in a single overflow + // region below. if (selectedPhotos.length === 1) { const id = activePhotoId ?? selectedPhotos[0] return ( @@ -259,7 +262,9 @@ export function RightSidebar() { >
- +
+ +
) } diff --git a/frontend/src/components/sidebar/PhotoInfoPanel.tsx b/frontend/src/components/sidebar/PhotoInfoPanel.tsx index 57d4307..d9f3e74 100644 --- a/frontend/src/components/sidebar/PhotoInfoPanel.tsx +++ b/frontend/src/components/sidebar/PhotoInfoPanel.tsx @@ -143,7 +143,7 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro const queryClient = useQueryClient() const [expandedSections, setExpandedSections] = useState>( - new Set(['basic', 'camera', 'location', 'tags']) + new Set(['metadata', 'basic', 'camera', 'location', 'tags']) ) const toggleSection = (section: string) => { const next = new Set(expandedSections) @@ -380,10 +380,13 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro : 'border-border bg-bg text-text placeholder-text-faint focus:border-primary' ) + // Note: no h-full / flex-1 here — the parent (RightSidebar) owns the + // scroll container so the edit fields and readonly metadata scroll + // together as one block beneath the pinned heap + header. return (
@@ -542,8 +545,24 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
- {/* Read-only metadata sections */} -
+ {/* Read-only metadata — collapsed/expanded as one block so the user + * can hide everything below the editable form with a single click. + * Sub-sections inside stay individually collapsible for finer + * control once the outer group is open. */} + toggleSection('metadata')} + className="border-b border-border" + > + + Metadata + {expandedSections.has('metadata') ? ( + + ) : ( + + )} + +
No GPS data
)} - - + + ) }