"use client"; import Link from "next/link"; import { ABUNDANCES, ABUNDANCE_LABELS, ABUNDANCE_RANGES, Dive, type Sighting, } from "@/lib/api/dives"; import { labelOrFallback } from "@/lib/api/labels"; import { gearTypeLabel } from "@/lib/api/gear"; import { SPECIES_CARD_GRID, SpeciesCard, } from "@/components/species/species-card"; import type { BackdropCardFigure } from "@/components/ui/backdrop-card"; import { Badge } from "@/components/ui/badge"; import { CARD_SECTION_CONTENT, Card, CardContent } from "@/components/ui/card"; import { DiveProfileCard } from "@/components/dives/dive-profile-card"; import { DiveMixturesCard } from "@/components/dives/dive-mixtures-card"; import { DiveExposureCard } from "@/components/dives/dive-exposure-card"; import { DiveGasConsumptionCard } from "@/components/dives/dive-gas-consumption-card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Weight } from "lucide-react"; import { DiveCardHeader } from "@/components/dives/dive-card-header"; import type { DiveCardSection } from "@/components/dives/dive-section-dialog"; import { useUnits } from "@/hooks/useUnits"; import { cn } from "@/lib/utils"; import { useWithReturnTo } from "@/hooks/useReturnTo"; import { formatWeight } from "@/lib/units"; // One figure per sighting: its count, or its band with the band's range, and none for // "seen, not counted", which is not 1. function sightingFigures(sighting: Sighting): BackdropCardFigure[] { if (sighting.count != null) { return [{ label: "Count", value: sighting.count }]; } if (sighting.abundance != null) { // A band this build has no range for yet reads as its de-snaked label alone. const range = ABUNDANCES.includes(sighting.abundance) ? ABUNDANCE_RANGES[sighting.abundance] : undefined; return [ { label: "Abundance", value: ( <> {labelOrFallback(ABUNDANCE_LABELS, sighting.abundance)} {range && {range}} > ), }, ]; } return []; } interface DiveDetailMainProps { dive: Dive; /** Opens a section's edit dialog; absent, the cards have no edit control. */ onEdit?: (section: DiveCardSection) => void; } /** * The dive detail page's main column, ordered so each card's inputs are already on screen * by the time a card derived from them appears: under the hero's dive time and depth * numbers, the profile that is their detailed form, then the tanks whose pressures its * third curve traces, then the consumption figures derived from all three, then the * exposure those same tanks produced. * * Every card renders only when the dive carries the relevant data, so a hand-logged dive * shows whatever else was filled in. */ export function DiveDetailMain({ dive, onEdit }: DiveDetailMainProps) { const hasGearInfo = (dive.gear_items?.length ?? 0) > 0 || dive.weight != null; const units = useUnits(); const withReturnTo = useWithReturnTo(); const sightings = dive.sightings ?? []; return (
{dive.notes}