import type { TourActivityTotals, TourTypeKey } from '@trek/shared'; import { Footprints } from 'lucide-react'; import { useId } from 'react'; import { useTranslation } from '../../../i18n'; import type { DistanceUnit } from '../../../types'; import { DialogButton, DialogFooter, DialogHeader, DialogSection, DialogShell, DialogTile, FooterSpacer, fs, NEUTRAL_TINT, } from '../../shared/DialogShell'; import { InfoDot, TourFactFields, type TourMetricField } from '../../Tours/tourParts'; import { TourActivityEntryRow } from './TourActivityEntryRow'; import { ActivityFilters, ActivityStatusLine, BasisBadges, distanceReading, heightReading, MeasurePills, partialHint, typeIcon, UncountedBadges, useDistanceUnit, } from './tourActivityParts'; import type { TourActivityStats } from './useTourActivityStats'; type Translate = (key: string, params?: Record) => string; /** The sums as labelled fields; a sum nobody knows is left out, a short one says at least and why. */ function totalFields(totals: TourActivityTotals, unit: DistanceUnit, t: Translate): TourMetricField[] { const fields: TourMetricField[] = [{ label: t('tours.mode.tours'), value: String(totals.count) }]; const sums = [ { label: t('tours.detail.distance'), sum: totals.distanceKm, reading: distanceReading(totals, unit) }, { label: t('tours.detail.ascent'), sum: totals.ascentM, reading: heightReading(totals.ascentM, unit) }, { label: t('tours.detail.descent'), sum: totals.descentM, reading: heightReading(totals.descentM, unit) }, ]; for (const { label, sum, reading } of sums) { if (!reading) continue; const info = reading.partial ? { label, description: partialHint(sum, t) } : undefined; fields.push({ label, value: reading.text, info }); } return fields; } /** One type of the period: its icon with how many tours at the corner, its name, its distance and climb. */ function TypeLine({ type, totals }: { type: TourTypeKey; totals: TourActivityTotals }) { const { t } = useTranslation(); const unit = useDistanceUnit(); const Icon = typeIcon(type); const distance = distanceReading(totals, unit); const ascent = heightReading(totals.ascentM, unit); return (
  • {t(`tourTypes.${type}`)} {`: ${t('tours.mode.tours')} ${totals.count}`}
  • ); } /** The sums, what they rest on, the split by type, and every tour of the period with its switch. */ function StatsBody({ stats }: { stats: TourActivityStats }) { const { t } = useTranslation(); const unit = useDistanceUnit(); const { summary, data } = stats; if (!summary || !data) return ; const showTypes = stats.type === 'all' && summary.types.length > 1; return ( <>
    {showTypes && (
      {summary.types.map(({ type, ...totals }) => ( ))}
    )} {summary.done.length} } > {summary.done.length === 0 ? (

    {t(data.entries.length === 0 ? 'tours.stats.empty' : 'tours.stats.none')}

    ) : (
      {summary.done.map((entry) => ( void stats.setExcluded(target, !target.excluded)} /> ))}
    )}
    ); } /** * STA-02: the user's tour activities in full, opened from the Atlas: the * period and type on the head band, the sums with what they rest on, the * split by type, and every tour done in the period, each one able to be left * out (a tour that fell through) and counted again without touching its plan. */ export function TourActivityStatsDialog({ stats, open, onClose, }: { stats: TourActivityStats; open: boolean; onClose: () => void; }) { const { t } = useTranslation(); const labelId = useId(); return ( } tint={NEUTRAL_TINT} labelId={labelId} onClose={onClose} title={t('tours.stats.title')} sub={t('tours.stats.sub')} subWraps pills={} /> } footer={ {t('common.close')} } > ); }