dorfteich/apps/web/src/layout/PondSwitcher.tsx
Claude Sonnet 5 49beb45b3e
All checks were successful
CD / Build and push images (push) Successful in 1m59s
CI / Lint, typecheck, test (push) Successful in 1m38s
CI / Auth e2e pack (push) Successful in 1m48s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 9s
Add pond sidebar with page list, sort modes, and pond switcher (#26)
GET /ponds/:id/pages lists a pond's pages ordered by the pond's
persisted sidebarSort setting (alpha/created; manual arrives with #45).
The sidebar consumes it to show the page list with an active-page
highlight, an owner-only sort switch (persists via the existing
PATCH /ponds/:id), and an inline "new page" flow. The top bar gains a
pond switcher; a new /p/:pondSlug route gives it somewhere to land,
redirecting to the pond's first page once loaded. Sidebar collapse
gains a Ctrl/Cmd+\ shortcut and a slightly refined transition.

Closes #26
2026-07-06 12:37:44 +02:00

55 lines
1.6 KiB
TypeScript

import type { PondView } from '@dorfteich/shared';
import { useQuery } from '@tanstack/react-query';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { useAuth } from '../auth/auth-context';
import { apiGet } from '../lib/api';
import { useCurrentPondRoute } from './use-pond-route';
/** Top-bar dropdown to switch between the signed-in user's ponds (issue #26). */
export function PondSwitcher(): React.JSX.Element | null {
const { t } = useTranslation();
const { user } = useAuth();
const { pondSlug } = useCurrentPondRoute();
const [open, setOpen] = useState(false);
const ponds = useQuery({
queryKey: ['ponds'],
queryFn: () => apiGet<PondView[]>('/ponds'),
enabled: Boolean(user),
});
if (!ponds.data || ponds.data.length === 0) return null;
const current = ponds.data.find((pond) => pond.slug === pondSlug);
return (
<div className="user-menu">
<button
type="button"
className="user-menu__trigger"
aria-haspopup="menu"
aria-expanded={open}
aria-label={t('layout.pondSwitcher.label')}
onClick={() => setOpen(!open)}
>
{current?.name ?? t('layout.pondSwitcher.trigger')}
</button>
{open && (
<div className="user-menu__list" role="menu">
{ponds.data.map((pond) => (
<Link
key={pond.id}
role="menuitem"
to={`/p/${pond.slug}`}
onClick={() => setOpen(false)}
>
{pond.name}
</Link>
))}
</div>
)}
</div>
);
}