mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
feat(collections): detail redesign + categories, close-on-map, highlight fix (#1081)
- Rebuild the place detail as a clean, opaque, sectioned sheet (cover → meta → status segment → description → links) with a proper footer action bar — the loose "white lower half" is gone. - Assign a place to a central (admin-defined) category, both in the detail edit and when adding a place; categories are fetched once for the page. - Add-place now sets category + description (markdown) + links + status in the same step, closer to the trip's place form. - Switching to the full-map view now closes the (list-docked) detail. - Fix the selected-row highlight: it was clipped by the column's overflow — use an inset ring and only clip during the map-collapse animation; a picked row now scrolls into view above the detail sheet. - New category strings across all 22 locales.
This commit is contained in:
@@ -48,7 +48,11 @@ export default function CollectionsPage(): React.ReactElement {
|
||||
const mappable = mappablePlaces(c.visiblePlaces)
|
||||
const openPlace = (id: number) => c.setSelectedPlaceId(c.selectedPlaceId === id ? null : id)
|
||||
const deselect = () => c.setSelectedPlaceId(null)
|
||||
const toggleView = () => c.setView(c.view === 'map' ? 'list' : 'map')
|
||||
const toggleView = () => {
|
||||
// Going to the full-map view closes the (list-docked) detail sheet.
|
||||
if (c.view !== 'map') c.setSelectedPlaceId(null)
|
||||
c.setView(c.view === 'map' ? 'list' : 'map')
|
||||
}
|
||||
// Clicking a marker in the full-map view drops back to the split so the list
|
||||
// + detail come into view alongside the map.
|
||||
const onMapSelect = (id: number) => { openPlace(id); if (c.view === 'map') c.setView('list') }
|
||||
@@ -247,11 +251,12 @@ export default function CollectionsPage(): React.ReactElement {
|
||||
visible + interactive). On the desktop split it docks over the list
|
||||
column so the map stays clear; otherwise it's a full-width sheet.
|
||||
Clicking another place / the map background re-points the selection. */}
|
||||
{c.selectedPlace && (
|
||||
{c.selectedPlace && c.view !== 'map' && (
|
||||
<CollectionPlaceDetail
|
||||
place={c.selectedPlace}
|
||||
canEdit
|
||||
anchorRect={desktopSplit && c.view === 'list' ? c.listColRect : null}
|
||||
categories={c.categories}
|
||||
anchorRect={desktopSplit ? c.listColRect : null}
|
||||
onClose={c.handleCloseDetail}
|
||||
onSetStatus={c.handleDetailStatus}
|
||||
onSave={patch => c.updatePlace(c.selectedPlace!.id, patch)}
|
||||
@@ -268,6 +273,7 @@ export default function CollectionsPage(): React.ReactElement {
|
||||
isOpen={c.showAddPlace}
|
||||
collectionId={c.activeId}
|
||||
collectionName={c.activeCollection.name}
|
||||
categories={c.categories}
|
||||
onClose={() => c.setShowAddPlace(false)}
|
||||
onAdded={c.handlePlaceAdded}
|
||||
t={t}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { getApiErrorMessage } from '../../types'
|
||||
import { addListener, removeListener } from '../../api/websocket'
|
||||
import { useCollectionStore, ALL_SAVED } from '../../store/collectionStore'
|
||||
import type { ActiveCollectionId } from '../../store/collectionStore'
|
||||
import { categoriesApi } from '../../api/client'
|
||||
import type { Collection, CollectionStatus } from '@trek/shared'
|
||||
import type { Category, Place } from '../../types'
|
||||
import { filterPlaces, sortPlaces, statusCounts } from './collectionsModel'
|
||||
@@ -70,6 +71,10 @@ export function useCollections() {
|
||||
// Initial load.
|
||||
useEffect(() => { loadAll() }, [])
|
||||
|
||||
// Central admin-defined categories, for assigning a category to a saved place.
|
||||
const [categories, setCategories] = useState<Category[]>([])
|
||||
useEffect(() => { categoriesApi.list().then((d: { categories: Category[] }) => setCategories(d.categories ?? [])).catch(() => {}) }, [])
|
||||
|
||||
// When the list↔map split toggles, its grid columns animate; keep nudging the
|
||||
// mounted map to re-layout during the transition (Leaflet's trackResize hooks
|
||||
// window resize; MapLibre observes its own box). Skip the initial mount — the
|
||||
@@ -277,7 +282,7 @@ export function useCollections() {
|
||||
return {
|
||||
t, language, dark, navigate,
|
||||
isWide, heroRef: hero.ref, heroHeight: hero.height,
|
||||
listColRef: listCol.ref, listColRect: listCol.rect,
|
||||
listColRef: listCol.ref, listColRect: listCol.rect, categories,
|
||||
// store data
|
||||
collections, ownedLists, sharedLists, activeCollection, isAllSaved, isOwner,
|
||||
canShare, shareMemberCount,
|
||||
|
||||
Reference in New Issue
Block a user