diff --git a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.module.css b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.module.css index 350542e16..e4eb6ad75 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.module.css +++ b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.module.css @@ -58,6 +58,35 @@ font-weight: 600; } +.mobilePageHeader { + min-width: 0; +} + +.mobilePageSection { + padding: 4px 0 2px; +} + +.mobileSectionLabel { + font-size: 12px; + font-weight: 600; +} + +.mobileSelectedPageButton { + width: 100%; + text-align: left; + border: 1px solid var(--border-base); + background: var(--surface-raised); + border-radius: 8px; + padding: 10px 12px; + cursor: pointer; + font: inherit; + color: inherit; +} + +.mobileSelectedPageButton:hover { + background: var(--surface-sunken); +} + .summaryHeader { min-width: 0; } @@ -98,6 +127,10 @@ min-width: 0; } +.mobileSummaryControls { + width: 100%; +} + .screenWidthCount { margin-left: auto; font-variant-numeric: tabular-nums; @@ -228,3 +261,38 @@ pointer-events: auto; mix-blend-mode: multiply; } + +@media (max-width: 640px) { + .summaryStats, + .summaryHeader { + width: 100%; + align-items: stretch; + } + + .summaryStats { + gap: 8px; + } + + .summaryStat { + width: 100%; + justify-content: flex-start; + } + + .screenWidthControl { + width: 100%; + margin-left: 0; + justify-content: space-between; + } + + .screenWidthLabel { + font-size: 12px; + } + + .canvasWrapper { + max-height: 70vh; + } + + .scrollBandLabel { + display: none; + } +} diff --git a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx index da6392142..15375066c 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx @@ -1,19 +1,25 @@ 'use client'; import { + Button, Column, + Dialog, Grid, Heading, Icon, ListItem, Loading, + Modal, Row, Select, Text, } from '@umami/react-zen'; import { Laptop, Monitor, Smartphone, Tablet } from 'lucide-react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { ControlledDialog } from '@/components/common/ControlledDialog'; +import { IconLabel } from '@/components/common/IconLabel'; import { LoadingPanel } from '@/components/common/LoadingPanel'; -import { useResultQuery } from '@/components/hooks'; +import { useMobile, useResultQuery } from '@/components/hooks'; +import { ListCheck } from '@/components/icons'; import { formatLongNumber } from '@/lib/format'; import type { HeatmapMode, HeatmapPoint, HeatmapResult, HeatmapSnapshot } from '@/queries/sql'; import styles from './Heatmap.module.css'; @@ -53,6 +59,8 @@ interface HeatmapProps { } export function Heatmap({ websiteId, urlPath, onUrlPathChange, mode, search }: HeatmapProps) { + const { isPhone } = useMobile(); + const [isPagePickerOpen, setIsPagePickerOpen] = useState(false); const { data: pagesData, error, @@ -88,6 +96,7 @@ export function Heatmap({ websiteId, urlPath, onUrlPathChange, mode, search }: H return pages.filter(page => page.urlPath.toLowerCase().includes(value)); }, [pages, search]); + const selectedPage = filteredPages.find(page => page.urlPath === urlPath) ?? null; const points = detailData?.points ?? []; const scroll = detailData?.scroll; const snapshot = detailData?.snapshot ?? null; @@ -122,16 +131,33 @@ export function Heatmap({ websiteId, urlPath, onUrlPathChange, mode, search }: H return ( - - -