Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dashboard redesign #162

Merged
merged 13 commits into from
Feb 5, 2025
2 changes: 1 addition & 1 deletion src/components/DeviceLocation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ const DeviceLocation: VoidComponent<DeviceLocationProps> = (props) => {

return (
<div class="relative">
<div ref={mapRef} class="h-[200px] w-full !bg-surface-container-low" />
<div ref={mapRef} class="h-[240px] w-full !bg-surface-container-low" />

<Show when={!userPosition()}>
<div class="absolute bottom-2 right-2 z-[9999]">
Expand Down
2 changes: 1 addition & 1 deletion src/components/RouteStaticMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getStaticMapUrl = (gpsPoints: GPSPathPoint[]): string | undefined => {
path.push([lng, lat])
})
const themeId = getThemeId()
return getPathStaticMapUrl(themeId, path, 343, 256, true)
return getPathStaticMapUrl(themeId, path, 512, 512, true)
}

const State = (props: {
Expand Down
4 changes: 3 additions & 1 deletion src/components/material/ButtonBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type ButtonBaseProps = JSX.ButtonHTMLAttributes<HTMLButtonElement> & {
class?: string
onClick?: (e: MouseEvent) => void
href?: string
activeClass?: string
}

const ButtonBase: Component<ButtonBaseProps> = (props) => {
Expand All @@ -32,8 +33,9 @@ const ButtonBase: Component<ButtonBaseProps> = (props) => {
{(href) => (
<A
class={clsx('relative isolate overflow-hidden', props.class)}
href={href}
onClick={onClick}
href={href}
activeClass={props.activeClass}
>
{props.children}
</A>
Expand Down
8 changes: 4 additions & 4 deletions src/components/material/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ type CardHeaderProps = {

export const CardHeader: VoidComponent<CardHeaderProps> = (props) => {
return (
<div
class={clsx('flex h-[72px] items-center gap-4 px-4 py-3', props.class)}
>
<div class={clsx('flex h-[72px] items-center gap-4 px-4 py-3', props.class)}>
{props.leading}
<div class="flex h-12 grow flex-col justify-between">
{props.headline && <span class="text-title-md">{props.headline}</span>}
Expand Down Expand Up @@ -75,17 +73,19 @@ type CardProps = {
class?: string
onClick?: () => void
href?: string
activeClass?: string
}

const Card: ParentComponent<CardProps> = (props) => {
return (
<ButtonBase
class={clsx(
'state-layer elevation-1 flex max-w-md flex-col rounded-lg bg-surface-container-low text-on-surface before:bg-on-surface',
'state-layer flex max-w-md flex-col rounded-lg bg-surface-container-low text-on-surface before:bg-on-surface',
props.class,
)}
onClick={props.onClick}
href={props.href}
activeClass={clsx('before:opacity-[.12]', props.activeClass)}
>
{props.children}
</ButtonBase>
Expand Down
2 changes: 2 additions & 0 deletions src/components/material/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type ListItemProps = {
trailing?: JSXElement
onClick?: () => void
href?: string
activeClass?: string
}

// TODO: guess variant from content
Expand All @@ -47,6 +48,7 @@ export const ListItem: ParentComponent<ListItemProps> = (props) => {
)}
onClick={props.onClick}
href={props.href}
activeClass={clsx('before:opacity-[.12]', props.activeClass)}
>
{props.leading}
{props.children}
Expand Down
12 changes: 6 additions & 6 deletions src/pages/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const DashboardDrawer: VoidComponent<DashboardDrawerProps> = (props) => {
>
comma connect
</TopAppBar>
<h2 class="mx-4 mb-2 text-label-sm">
<h2 class="mx-4 mb-2 text-label-sm uppercase">
Devices
</h2>
<Show when={props.devices} keyed>
Expand All @@ -52,7 +52,7 @@ const DashboardDrawer: VoidComponent<DashboardDrawerProps> = (props) => {
)
}

const TwoPaneLayout: Component<{
const DashboardLayout: Component<{
paneOne: JSXElement
paneTwo: JSXElement
paneTwoContent: boolean
Expand All @@ -61,7 +61,7 @@ const TwoPaneLayout: Component<{
<div class="relative size-full overflow-hidden">
<div
class={clsx(
'mx-auto size-full max-w-screen-2xl md:grid md:grid-cols-2 lg:gap-2',
'mx-auto size-full max-w-[1560px] md:grid md:grid-cols-2 lg:gap-2',
// Flex layout for mobile with horizontal transition
'flex transition-transform duration-300 ease-in-out',
props.paneTwoContent ? '-translate-x-full md:translate-x-0' : 'translate-x-0',
Expand All @@ -76,7 +76,7 @@ const TwoPaneLayout: Component<{
)
}

const DashboardLayout: Component<RouteSectionProps> = () => {
const Dashboard: Component<RouteSectionProps> = () => {
const location = useLocation()

const pathParts = () => location.pathname.split('/').slice(1).filter(Boolean)
Expand Down Expand Up @@ -107,7 +107,7 @@ const DashboardLayout: Component<RouteSectionProps> = () => {
<PairActivity />
</Match>
<Match when={dongleId()} keyed>{(id) => (
<TwoPaneLayout
<DashboardLayout
paneOne={<DeviceActivity dongleId={id} />}
paneTwo={<Switch
fallback={<div class="hidden size-full flex-col items-center justify-center gap-4 md:flex">
Expand All @@ -133,4 +133,4 @@ const DashboardLayout: Component<RouteSectionProps> = () => {
)
}

export default DashboardLayout
export default Dashboard
2 changes: 1 addition & 1 deletion src/pages/dashboard/activities/DeviceActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {
)}
</div>
<div class="flex flex-col gap-2">
<span class="text-label-sm">Routes</span>
<span class="text-label-sm uppercase">Routes</span>
<RouteList dongleId={props.dongleId} />
</div>
</div>
Expand Down
12 changes: 6 additions & 6 deletions src/pages/dashboard/activities/RouteActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {

import { getRoute } from '~/api/route'

import IconButton from '~/components/material/IconButton'
import TopAppBar from '~/components/material/TopAppBar'
import RouteStaticMap from '~/components/RouteStaticMap'
import RouteStatistics from '~/components/RouteStatistics'
import Timeline from '~/components/Timeline'
import { parseDateStr } from '~/utils/date'

import ActivityBar from '../components/ActivityBar'

const RouteVideoPlayer = lazy(() => import('~/components/RouteVideoPlayer'))

type RouteActivityProps = {
Expand All @@ -37,9 +37,9 @@ const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {

return (
<>
<ActivityBar backHref={`/${props.dongleId}`}>
<TopAppBar leading={<IconButton class="md:hidden" href={`/${props.dongleId}`}>arrow_back</IconButton>}>
{startTime()}
</ActivityBar>
</TopAppBar>

<div class="flex flex-col gap-6 px-4 pb-4">
<Suspense
Expand All @@ -64,8 +64,8 @@ const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {
</div>

<div class="flex flex-col gap-2">
<h3 class="text-label-sm">Route Map</h3>
<div class="h-64 overflow-hidden rounded-lg">
<h3 class="text-label-sm uppercase">Route Map</h3>
<div class="aspect-square overflow-hidden rounded-lg">
<Suspense fallback={<div class="skeleton-loader size-full bg-surface" />}>
<RouteStaticMap route={route()} />
</Suspense>
Expand Down
7 changes: 4 additions & 3 deletions src/pages/dashboard/activities/SettingsActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import ButtonBase from '~/components/material/ButtonBase'
import Button from '~/components/material/Button'
import CircularProgress from '~/components/material/CircularProgress'
import Icon from '~/components/material/Icon'
import IconButton from '~/components/material/IconButton'
import TopAppBar from '~/components/material/TopAppBar'
import { createQuery } from '~/utils/createQuery'

import ActivityBar from '../components/ActivityBar'

const useAction = <T,>(action: () => Promise<T>): [() => void, Resource<T>] => {
const [source, setSource] = createSignal(false)
Expand Down Expand Up @@ -352,9 +353,9 @@ const SettingsActivity: VoidComponent<PrimeActivityProps> = (props) => {
const [device] = createResource(() => props.dongleId, getDevice)
return (
<>
<ActivityBar backHref={`/${props.dongleId}`}>
<TopAppBar leading={<IconButton class="md:hidden" href={`/${props.dongleId}`}>arrow_back</IconButton>}>
Device Settings
</ActivityBar>
</TopAppBar>
<div class="max-w-lg px-4">
<h2 class="mb-4 text-headline-sm">comma prime</h2>
<Suspense>
Expand Down
19 changes: 0 additions & 19 deletions src/pages/dashboard/components/ActivityBar.tsx

This file was deleted.

1 change: 1 addition & 0 deletions src/pages/dashboard/components/DeviceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const DeviceList: VoidComponent<DeviceListProps> = (props) => {
selected={isSelected(device)}
onClick={onClick(device)}
href={`/${device.dongle_id}`}
activeClass="before:bg-primary"
>
<ListItemContent
headline={getDeviceName(device)}
Expand Down
17 changes: 7 additions & 10 deletions src/pages/dashboard/components/RouteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import dayjs from 'dayjs'

import { fetcher } from '~/api'
import Card, { CardContent, CardHeader } from '~/components/material/Card'
import RouteStaticMap from '~/components/RouteStaticMap'
import RouteStatistics from '~/components/RouteStatistics'
import type { RouteSegments } from '~/types'
import { useDimensions } from '~/utils/window'
Expand All @@ -28,18 +27,16 @@ const RouteCard: VoidComponent<RouteCardProps> = (props) => {
const endTime = () => dayjs(props.route.end_time_utc_millis)

return (
<Card href={`/${props.route.dongle_id}/${props.route.fullname.slice(17)}`}>
<Card
class="max-w-none"
href={`/${props.route.dongle_id}/${props.route.fullname.slice(17)}`}
activeClass="md:before:bg-primary"
>
<CardHeader
headline={startTime().format('ddd, MMM D, YYYY')}
subhead={`${startTime().format('h:mm A')} to ${endTime().format('h:mm A')}`}
/>

<div class="mx-2 h-48 overflow-hidden rounded-lg">
<Suspense fallback={<div class="skeleton-loader size-full bg-surface" />}>
<RouteStaticMap route={props.route} />
</Suspense>
</div>

<CardContent>
<RouteStatistics route={props.route} />
</CardContent>
Expand All @@ -54,7 +51,7 @@ type RouteListProps = {

const RouteList: VoidComponent<RouteListProps> = (props) => {
const dimensions = useDimensions()
const pageSize = () => Math.max(Math.ceil((dimensions().height / 2) / 348), 1)
const pageSize = () => Math.max(Math.ceil((dimensions().height / 2) / 140), 1)
const endpoint = () => `/v1/devices/${props.dongleId}/routes_segments?limit=${pageSize()}`
const getKey = (previousPageData?: RouteSegments[]): string | undefined => {
if (!previousPageData) return endpoint()
Expand Down Expand Up @@ -105,7 +102,7 @@ const RouteList: VoidComponent<RouteListProps> = (props) => {
return (
<Suspense
fallback={<Index each={new Array(pageSize())}>{() => (
<div class="skeleton-loader elevation-1 flex h-[336px] max-w-md flex-col rounded-lg bg-surface-container-low" />
<div class="skeleton-loader flex h-[140px] flex-col rounded-lg" />
)}</Index>}
>
<For each={routes()}>
Expand Down