import type { LucideIcon } from 'lucide-react'; import type { DavCollection } from './shared'; import { Link, useSearchParams } from 'react-router'; import { CalendarDays, Contact as ContactIcon, Smartphone } from 'lucide-react'; import { davCollectionPath, COLLECTION_PARAM } from './shared'; import { useDavCollections, matchCollection } from './useDavData'; import { AppPasswordsModal, useAppPasswordsModal } from '../AppPasswordsModal'; import { useTranslation } from 'officerdev'; // Left panel for both /calendar and /contacts: the list of collections belonging to this user. // // Rows are real links carrying ?collection=, so a calendar is a bookmarkable address and the // right-hand panel reads the same URL rather than being told over a channel. Active state is compared // against the URL directly instead of NavLink's isActive, because every row shares one pathname and // differs only in the query string. type Props = { kind: DavCollection['kind']; base: '/calendar' | '/contacts'; title: string; icon: LucideIcon; }; const ROW = 'group relative flex items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors'; const CollectionNav = ({ kind, base, title, icon: Icon }: Props) => { const { t } = useTranslation(); const [, setSyncOpen] = useAppPasswordsModal(); const [params] = useSearchParams(); const { collections, isLoading } = useDavCollections(kind); // Resolved the same way the right-hand panel resolves it, so the highlight cannot disagree with what // is on screen — including the fallback to the first collection when the URL names nothing. const active = matchCollection(collections, params.get(COLLECTION_PARAM)); return (
{title}
{isLoading ? 'loading…' : `${collections.length} ${collections.length === 1 ? 'collection' : 'collections'}`}
{/* Sync setup lives at the bottom of the nav, and the modal is mounted here once. It was Settings → Integrations → DAV sync until caldav became a plugin; a plugin ships panels and cannot contribute a settings section, so it follows email's AccountsModal. Pushed down by `mt-auto` because it is a twice-a-year task that should not compete with the collections. */}
); }; export const CalendarNav = () => { const { t } = useTranslation(); return ; }; export const ContactsNav = () => { const { t } = useTranslation(); return ; };