11/**
22 * InstallationDetail — session history for a single installation.
3- * Matches R2 redesign: completion bar, grid table, filter buttons .
3+ * Responsive layout: adapts table and header to screen size .
44 */
55
66import { useState , useEffect , useCallback } from 'react'
@@ -12,6 +12,7 @@ import { Button, Card, Chip, Dot, Overline } from '../../shared/components'
1212
1313const STATUS_OPTIONS = [ 'all' , 'completed' , 'failed' , 'running' , 'pending' , 'timeout' ] as const
1414const PER_PAGE = 10
15+ const COL_TEMPLATE = 'minmax(24px, 32px) minmax(120px, 1fr) minmax(90px, 130px) minmax(80px, 110px) minmax(56px, 80px) minmax(56px, 80px) 28px'
1516
1617export default function InstallationDetail ( ) {
1718 const { installationId } = useParams < { installationId : string } > ( )
@@ -76,21 +77,20 @@ export default function InstallationDetail() {
7677
7778 return (
7879 < >
79- { /* 56px topbar + 32px py-8 top + 32px py-8 bottom = 120px */ }
80- < div className = "flex flex-col" style = { { height : 'calc(100vh - 120px)' } } >
81- { /* Header + filters */ }
82- < div className = "shrink-0 flex justify-between items-end mb-4" >
83- < div >
80+ < div className = "flex flex-col h-[calc(100dvh-120px)]" >
81+ { /* Header + filters — wraps on small screens */ }
82+ < div className = "shrink-0 flex flex-col lg:flex-row lg:justify-between lg:items-end gap-3 mb-4" >
83+ < div className = "min-w-0" >
8484 < Overline className = "mb-1" > { '\u25b8' } SESSIONS { '\u00b7' } { total } TOTAL</ Overline >
85- < h1 className = "font-mono text-2xl font-bold tracking-[-0.02em]" > Session History</ h1 >
85+ < h1 className = "font-mono text-xl lg:text- 2xl font-bold tracking-[-0.02em]" > Session History</ h1 >
8686 < p className = "font-mono text-[13px] text-dim mt-0.5" > // every time Claude ran against one of your PRs</ p >
8787 </ div >
88- < div className = "flex gap-2 " >
88+ < div className = "flex flex-wrap gap-1.5 " >
8989 { STATUS_OPTIONS . map ( ( opt ) => (
9090 < button
9191 key = { opt }
9292 onClick = { ( ) => handleStatusChange ( opt ) }
93- className = { `font-mono text-[12px] font-medium px-3 py-1.5 rounded-[6px] border transition-colors cursor-pointer ${
93+ className = { `font-mono text-[11px] lg:text-[ 12px] font-medium px-2.5 py-1 lg:px-3 lg: py-1.5 rounded-[6px] border transition-colors cursor-pointer ${
9494 statusFilter === opt
9595 ? 'bg-accent/15 border-accent/30 text-accent'
9696 : 'bg-card border-rule-str text-ink hover:bg-card-hi'
@@ -102,10 +102,10 @@ export default function InstallationDetail() {
102102 </ div >
103103 </ div >
104104
105- { /* Completion bar */ }
105+ { /* Completion bar — stacks on small screens */ }
106106 { ! loading && sessions . length > 0 && (
107- < div className = "shrink-0 flex items-center gap-4 px-4 py-2.5 bg-card border border-rule rounded-[8px] mb-4" >
108- < div className = "flex items-baseline gap-1.5" >
107+ < div className = "shrink-0 flex flex-col sm:flex-row sm: items-center gap-2 sm: gap-4 px-4 py-2.5 bg-card border border-rule rounded-[8px] mb-4" >
108+ < div className = "flex items-baseline gap-1.5 shrink-0 " >
109109 < span className = "font-mono text-lg font-bold" > { completionPct } %</ span >
110110 < span className = "font-mono text-[10px] text-dim tracking-[0.12em] uppercase" > completion</ span >
111111 </ div >
@@ -114,7 +114,7 @@ export default function InstallationDetail() {
114114 { timeout > 0 && < div className = "bg-warn" style = { { flex : timeout } } /> }
115115 { failed > 0 && < div className = "bg-danger" style = { { flex : failed } } /> }
116116 </ div >
117- < div className = "flex gap-4 font-mono text-[11px] text-dim" >
117+ < div className = "flex gap-3 sm:gap- 4 font-mono text-[10px] sm:text-[ 11px] text-dim shrink-0 " >
118118 < span > < Dot color = "ok" className = "mr-1" /> { completed } done</ span >
119119 < span > < Dot color = "warn" className = "mr-1" /> { timeout } timeout</ span >
120120 < span > < Dot color = "danger" className = "mr-1" /> { failed } failed</ span >
@@ -150,8 +150,8 @@ export default function InstallationDetail() {
150150 < div className = "flex-1 min-h-0 flex flex-col border border-rule-str rounded-[8px] overflow-hidden" >
151151 { /* Table header */ }
152152 < div
153- className = "shrink-0 grid bg-bg2 px-4 py-2 font-mono text-[10px] text-dim tracking-[0.18em] uppercase border-b border-rule"
154- style = { { gridTemplateColumns : '32px 1fr 130px 100px 72px 72px 32px' } }
153+ className = "shrink-0 grid bg-bg2 px-3 lg:px- 4 py-2 font-mono text-[9px] lg: text-[10px] text-dim tracking-[0.18em] uppercase border-b border-rule"
154+ style = { { gridTemplateColumns : COL_TEMPLATE } }
155155 >
156156 < span > #</ span >
157157 < span > REPO / PR</ span >
@@ -175,23 +175,23 @@ export default function InstallationDetail() {
175175 < button
176176 key = { session . id }
177177 onClick = { ( ) => navigate ( `/installations/${ installationId } /sessions/${ session . id } ` ) }
178- className = { `group w-full grid items-center px-4 py-2.5 text-[13px] transition-colors cursor-pointer hover:bg-card-hi ${
178+ className = { `group w-full grid items-center px-3 lg:px- 4 py-2 lg:py-2 .5 text-[12px] lg: text-[13px] transition-colors cursor-pointer hover:bg-card-hi ${
179179 idx < sessions . length - 1 ? 'border-b border-rule' : ''
180180 } `}
181- style = { { gridTemplateColumns : '32px 1fr 130px 100px 72px 72px 32px' } }
181+ style = { { gridTemplateColumns : COL_TEMPLATE } }
182182 >
183- < span className = "font-mono text-[11px] text-dim2" >
183+ < span className = "font-mono text-[10px] lg:text-[ 11px] text-dim2" >
184184 { String ( idx + 1 + ( page - 1 ) * PER_PAGE ) . padStart ( 2 , '0' ) }
185185 </ span >
186186 < span className = "font-mono text-ink truncate" >
187187 { session . repo_full_name } < span className = "text-accent" > #{ session . pr_number } </ span >
188188 </ span >
189189 < span > < Chip variant = "accent" > { session . skill_name } </ Chip > </ span >
190190 < span > < Chip variant = { statusColor } > { session . status } </ Chip > </ span >
191- < span className = "font-mono text-[11px] text-ink2 text-right" >
191+ < span className = "font-mono text-[10px] lg:text-[ 11px] text-ink2 text-right" >
192192 { formatDuration ( session . started_at , session . completed_at ) }
193193 </ span >
194- < span className = "font-mono text-[11px] text-dim text-right" >
194+ < span className = "font-mono text-[10px] lg:text-[ 11px] text-dim text-right" >
195195 { formatRelativeTime ( session . created_at ) }
196196 </ span >
197197 < span
@@ -242,7 +242,7 @@ export default function InstallationDetail() {
242242
243243 { /* Delete confirmation modal */ }
244244 { deleteTarget && (
245- < div className = "fixed inset-0 z-50 flex items-center justify-center bg-bg/80 backdrop-blur-sm" >
245+ < div className = "fixed inset-0 z-50 flex items-center justify-center bg-bg/80 backdrop-blur-sm p-4 " >
246246 < Card className = "w-full max-w-sm" >
247247 < Overline className = "mb-3 text-danger" > { '\u25b8' } DELETE SESSION</ Overline >
248248 < p className = "text-ink text-sm font-sans mb-1" >
0 commit comments