mobile dashboard

This commit is contained in:
Chris Wanstrath 2026-02-15 17:22:52 -08:00
parent f085d78fc1
commit 9c0762c882
8 changed files with 62 additions and 11 deletions

View File

@ -16,7 +16,7 @@ export function Dashboard({ render }: { render: () => void }) {
{selected ? (
<AppDetail app={selected} render={render} />
) : (
<DashboardLanding />
<DashboardLanding render={render} />
)}
<Modal />
</Layout>

View File

@ -1,9 +1,10 @@
import { useEffect } from 'hono/jsx'
import { apps, setSelectedApp } from '../state'
import { openAppSelectorModal } from '../modals'
import { apps, isNarrow, setSelectedApp } from '../state'
import {
AppSelectorChevron,
DashboardContainer,
DashboardHeader,
DashboardSubtitle,
DashboardTitle,
StatusDot,
StatusDotLink,
@ -13,16 +14,25 @@ import { update } from '../update'
import { UnifiedLogs, initUnifiedLogs } from './UnifiedLogs'
import { Vitals, initVitals } from './Vitals'
export function DashboardLanding() {
export function DashboardLanding({ render }: { render: () => void }) {
useEffect(() => {
initUnifiedLogs()
initVitals()
}, [])
const narrow = isNarrow || undefined
return (
<DashboardContainer>
<DashboardContainer narrow={narrow}>
<DashboardHeader>
<DashboardTitle>🐾 Toes</DashboardTitle>
<DashboardTitle narrow={narrow}>
🐾 Toes
{isNarrow && (
<AppSelectorChevron onClick={() => openAppSelectorModal(render)}>
</AppSelectorChevron>
)}
</DashboardTitle>
{/*<DashboardSubtitle>Your personal web appliance</DashboardSubtitle>*/}
</DashboardHeader>

View File

@ -1,6 +1,7 @@
import { define } from '@because/forge'
import type { App, LogLine as LogLineType } from '../../shared/types'
import { getLogDates, getLogsForDate } from '../api'
import { isNarrow } from '../state'
import { LogLine, LogsContainer, LogsHeader, LogTime, Section, SectionTitle } from '../styles'
import { theme } from '../themes'
import { update } from '../update'
@ -228,7 +229,7 @@ export function LogsSection({ app }: { app: App }) {
</SmallSelect>
</LogsControls>
</LogsHeader>
<LogsContainer id="logs-content">
<LogsContainer id="logs-content" narrow={isNarrow || undefined}>
<LogsContent />
</LogsContainer>
</Section>

View File

@ -1,3 +1,4 @@
import { isNarrow } from '../state'
import {
LogApp,
LogEntry,
@ -59,10 +60,11 @@ function parseLogText(text: string): { method?: string, path?: string, status?:
function LogLineEntry({ log }: { log: UnifiedLogLine }) {
const parsed = parseLogText(log.text)
const statusColor = getStatusColor(parsed.status)
const narrow = isNarrow || undefined
return (
<LogEntry>
<LogTimestamp>{formatTime(log.time)}</LogTimestamp>
<LogApp>{log.app}</LogApp>
<LogEntry narrow={narrow}>
<LogTimestamp narrow={narrow}>{formatTime(log.time)}</LogTimestamp>
<LogApp narrow={narrow}>{log.app}</LogApp>
<LogText style={statusColor ? { color: statusColor } : undefined}>
{log.text}
</LogText>

View File

@ -1,3 +1,4 @@
import { isNarrow } from '../state'
import {
GaugeContainer,
GaugeSvg,
@ -158,7 +159,7 @@ export function initVitals() {
export function Vitals() {
return (
<VitalsSection id="vitals">
<VitalsSection id="vitals" narrow={isNarrow || undefined}>
<VitalsContent />
</VitalsSection>
)

View File

@ -8,6 +8,11 @@ export const VitalsSection = define('VitalsSection', {
gap: 24,
width: '100%',
maxWidth: 800,
variants: {
narrow: {
gridTemplateColumns: '1fr',
},
},
})
export const VitalCard = define('VitalCard', {
@ -144,17 +149,32 @@ export const LogEntry = define('LogEntry', {
background: theme('colors-bgHover'),
},
},
variants: {
narrow: {
padding: '2px 8px',
},
},
})
export const LogTimestamp = define('LogTimestamp', {
color: theme('colors-textFaint'),
flexShrink: 0,
variants: {
narrow: {
display: 'none',
},
},
})
export const LogApp = define('LogApp', {
color: theme('colors-textMuted'),
flexShrink: 0,
minWidth: 80,
variants: {
narrow: {
minWidth: 50,
},
},
})
export const LogText = define('LogText', {

View File

@ -205,6 +205,13 @@ export const DashboardContainer = define('DashboardContainer', {
padding: 40,
paddingTop: 0,
gap: 40,
variants: {
narrow: {
padding: 20,
paddingTop: 0,
gap: 24,
},
},
})
export const DashboardHeader = define('DashboardHeader', {
@ -215,6 +222,11 @@ export const DashboardTitle = define('DashboardTitle', {
fontSize: 48,
fontWeight: 'bold',
margin: 0,
variants: {
narrow: {
fontSize: 32,
},
},
})
export const DashboardSubtitle = define('DashboardSubtitle', {

View File

@ -10,6 +10,11 @@ export const LogsContainer = define('LogsContainer', {
color: theme('colors-textMuted'),
maxHeight: 200,
overflow: 'auto',
variants: {
narrow: {
padding: 8,
},
},
render({ props: { children, id }, parts: { Root } }) {
return <Root id={id} ref={(el: HTMLElement | null) => {