@@ -2,12 +2,18 @@ import classNames from 'classnames';
22import { Link } from 'react-router-dom' ;
33import { Container } from '@/components/Container' ;
44import { useCompetitionRemoteControl } from '@/hooks/useCompetitionRemoteControl' ;
5+ import { useNow } from '@/hooks/useNow' ;
6+ import {
7+ formatElapsedMMSS ,
8+ formatUntilNextActivity ,
9+ getActiveGroupStartTime ,
10+ getRemoteBarProgress ,
11+ } from './remoteBarProgress' ;
512
613interface NotifyCompRemoteBarProps {
714 competitionId : string ;
815}
916
10- const groupLabel = ( count : number ) => `${ count } active activit${ count === 1 ? 'y' : 'ies' } ` ;
1117const iconButtonClassName =
1218 'flex h-8 w-8 items-center justify-center rounded-full border border-tertiary-weak bg-panel text-base leading-none text-default shadow-sm hover-transition hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-40 dark:hover:bg-gray-700 md:h-9 md:w-9 md:text-lg' ;
1319const primaryButtonClassName =
@@ -18,22 +24,22 @@ const confirmNextGroup = (groupName: string) =>
1824
1925export function NotifyCompRemoteBar ( { competitionId } : NotifyCompRemoteBarProps ) {
2026 const remote = useCompetitionRemoteControl ( { competitionId } ) ;
27+ const now = useNow ( ) ;
2128
2229 if ( ! remote . isAuthenticated || ! remote . competition || remote . scheduledActivities . length === 0 ) {
2330 return null ;
2431 }
2532
2633 const activeNames = remote . activeGroups . map ( ( group ) => group . name ) ;
27- const title = activeNames . length > 0 ? activeNames . join ( ', ' ) : 'No active activities' ;
28- const detail =
29- activeNames . length > 0
30- ? groupLabel ( activeNames . length )
31- : remote . nextGroup
32- ? `Next: ${ remote . nextGroup . name } `
33- : 'Remote overview' ;
34- const completedGroups = remote . activityGroups . filter ( ( group ) => group . status === 'done' ) . length ;
35- const progress =
36- remote . activityGroups . length > 0 ? ( completedGroups / remote . activityGroups . length ) * 100 : 0 ;
34+ const currentTitle = activeNames . length > 0 ? activeNames . join ( ', ' ) : 'No active activity' ;
35+ const nextTitle = remote . nextGroup ?. name || 'No next activity' ;
36+ const elapsed = formatElapsedMMSS ( getActiveGroupStartTime ( remote . activeGroups ) , now ) ;
37+ const nextStatus = formatUntilNextActivity ( remote . nextGroup , now ) ;
38+ const progress = getRemoteBarProgress ( {
39+ activeGroups : remote . activeGroups ,
40+ nextGroup : remote . nextGroup ,
41+ now,
42+ } ) ;
3743
3844 const runSwitch = ( direction : 'previous' | 'next' ) => {
3945 const group = direction === 'previous' ? remote . previousGroup : remote . nextGroup ;
@@ -65,16 +71,31 @@ export function NotifyCompRemoteBar({ competitionId }: NotifyCompRemoteBarProps)
6571 < Container
6672 fullWidth
6773 className = "relative flex-row min-h-16 items-center justify-center px-2 py-2" >
68- < Link
69- to = { `/competitions/${ competitionId } /remote` }
70- className = "absolute left-2 top-1/2 hidden max-w-[min(32vw,20rem)] -translate-y-1/2 rounded px-1 py-1 hover-transition hover:bg-gray-100 dark:hover:bg-gray-700 sm:block" >
71- < div className = "min-w-0 space-y-1" >
72- < div className = "truncate text-sm font-medium text-default" > { title } </ div >
73- < div className = "truncate text-xs text-muted" > { detail } </ div >
74- </ div >
75- </ Link >
74+ < div className = "w-full max-w-xl space-y-1" >
75+ < Link
76+ to = { `/competitions/${ competitionId } /remote` }
77+ className = { classNames (
78+ 'grid grid-cols-2 gap-2 rounded px-1 py-1 hover-transition hover:bg-gray-100 dark:hover:bg-gray-700' ,
79+ {
80+ 'opacity-60' : remote . isLoading ,
81+ } ,
82+ ) } >
83+ < span className = "min-w-0 space-y-0.5" >
84+ < span className = "block text-[0.625rem] font-medium uppercase leading-none text-muted" >
85+ Current
86+ </ span >
87+ < span className = "block truncate text-xs font-medium text-default" >
88+ { currentTitle }
89+ </ span >
90+ </ span >
91+ < span className = "min-w-0 space-y-0.5 text-right" >
92+ < span className = "block text-[0.625rem] font-medium uppercase leading-none text-muted" >
93+ Next
94+ </ span >
95+ < span className = "block truncate text-xs font-medium text-default" > { nextTitle } </ span >
96+ </ span >
97+ </ Link >
7698
77- < div className = "w-full max-w-sm space-y-1" >
7899 < div className = "flex items-center justify-center gap-2" >
79100 < button
80101 type = "button"
@@ -110,17 +131,20 @@ export function NotifyCompRemoteBar({ competitionId }: NotifyCompRemoteBarProps)
110131
111132 < Link
112133 to = { `/competitions/${ competitionId } /remote` }
113- className = { classNames ( 'grid grid-cols-[44px_minmax(0,1fr)_44px] items-center gap-2' , {
114- 'opacity-60' : remote . isLoading ,
115- } ) } >
116- < span className = "text-right text-xs tabular-nums text-muted" > { completedGroups } </ span >
134+ className = { classNames (
135+ 'grid grid-cols-[44px_minmax(0,1fr)_minmax(88px,1.5fr)] items-center gap-2 rounded px-1 py-1 hover-transition hover:bg-gray-100 dark:hover:bg-gray-700' ,
136+ {
137+ 'opacity-60' : remote . isLoading ,
138+ } ,
139+ ) } >
140+ < span className = "text-right text-xs tabular-nums text-muted" > { elapsed } </ span >
117141 < span className = "h-1 overflow-hidden rounded-full bg-tertiary" >
118142 < span
119143 className = "block h-full rounded-full bg-blue-500 dark:bg-blue-400"
120144 style = { { width : `${ progress } %` } }
121145 />
122146 </ span >
123- < span className = "text-xs tabular-nums text-muted" > { remote . activityGroups . length } </ span >
147+ < span className = "truncate text-xs text-muted" > { nextStatus } </ span >
124148 </ Link >
125149 </ div >
126150 </ Container >
0 commit comments