make tv mode list work better
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@sentry/nextjs": "^10.14.0",
|
||||
"@sentry/nextjs": "^10.15.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.8",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
@@ -122,8 +122,7 @@ export const AvatarUpload = ({ preloadedUser }: AvatarUploadProps) => {
|
||||
<BasedAvatar
|
||||
src={currentImageUrl ?? undefined}
|
||||
fullName={user?.name}
|
||||
className='h-42 w-42'
|
||||
fallbackProps={{ className: 'text-4xl font-semibold' }}
|
||||
className='h-42 w-42 text-6xl font-semibold'
|
||||
userIconProps={{ size: 100 }}
|
||||
/>
|
||||
<div
|
||||
|
@@ -124,9 +124,9 @@ export const StatusList = ({
|
||||
|
||||
const containerCn = ccn({
|
||||
context: tvMode,
|
||||
className: 'max-w-4xl mx-auto',
|
||||
on: 'px-6',
|
||||
off: 'px-4 sm:px-6',
|
||||
className: 'mx-auto',
|
||||
on: 'px-6 max-w-7xl',
|
||||
off: 'max-w-4xl px-4 sm:px-6',
|
||||
});
|
||||
|
||||
const tabsCn = ccn({
|
||||
@@ -185,22 +185,26 @@ export const StatusList = ({
|
||||
|
||||
{/* Desktop header */}
|
||||
<div className={headerCn}>
|
||||
<div className='flex items-center gap-4 text-xs sm:text-base'>
|
||||
<div className='flex items-center gap-2 text-muted-foreground'>
|
||||
<Users className='sm:w-4 sm:h-4 w-3 h-3' />
|
||||
<span>{statuses.length} members</span>
|
||||
<div className='flex w-full justify-between px-4'>
|
||||
<div className='flex items-center gap-4 text-xs sm:text-base'>
|
||||
<div className='flex items-center gap-2 text-muted-foreground'>
|
||||
<Users className='sm:w-4 sm:h-4 w-3 h-3' />
|
||||
<span>{statuses.length} members</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex items-center gap-2 text-xs'>
|
||||
<Link href='/table' className='font-medium hover:underline'>
|
||||
Miss the old table?
|
||||
</Link>
|
||||
<div className='flex items-center gap-4 text-xs sm:text-base'>
|
||||
<div className='flex items-center gap-2 text-xs'>
|
||||
<Link href='/table' className='font-medium hover:underline'>
|
||||
Miss the old table?
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card list */}
|
||||
<div className='space-y-2 sm:space-y-3 pb-24 sm:pb-0'>
|
||||
{statuses.map((statusData) => {
|
||||
{previousStatuses.map((statusData) => {
|
||||
const { user: u, status: s } = statusData;
|
||||
const isSelected = selectedUserIds.includes(u.id);
|
||||
const isAnimating = animatingIds.has(u.id);
|
||||
@@ -238,37 +242,35 @@ export const StatusList = ({
|
||||
fullName={u.name ?? 'User'}
|
||||
className={`
|
||||
transition-all duration-300
|
||||
${tvMode ? 'w-18 h-18' : 'w-10 h-10 sm:w-12 sm:h-12'}
|
||||
${tvMode ? 'w-36 h-36 text-4xl' : 'w-10 h-10 sm:w-12 sm:h-12'}
|
||||
${isAnimating ? 'ring-primary/30 ring-4' : ''}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className='flex-1 min-w-0'>
|
||||
<div className='flex items-center gap-2 sm:gap-3 mb-1'>
|
||||
<h3
|
||||
className={`
|
||||
font-semibold truncate
|
||||
${tvMode ? 'text-3xl' : 'text-base sm:text-xl'}
|
||||
${tvMode ? 'text-5xl' : 'text-base sm:text-xl'}
|
||||
`}
|
||||
title={u.name ?? u.email ?? 'User'}
|
||||
>
|
||||
{u.name ?? u.email ?? 'User'}
|
||||
</h3>
|
||||
|
||||
{isUpdatedByOther && s?.updatedBy && (
|
||||
<div
|
||||
className='hidden sm:flex items-center gap-2
|
||||
text-muted-foreground min-w-0'
|
||||
>
|
||||
<span className='text-sm'>via</span>
|
||||
<span className={`${tvMode ? 'text-3xl': 'text-sm'}`}>via</span>
|
||||
<BasedAvatar
|
||||
src={s.updatedBy.imageUrl}
|
||||
fullName={s.updatedBy.name ?? 'User'}
|
||||
className='w-4 h-4'
|
||||
className={`${tvMode ? 'w-14 h-14 text-xl' : 'w-6 h-6'}`}
|
||||
/>
|
||||
<span className='text-sm truncate'>
|
||||
<span className={`${tvMode ? 'text-4xl': 'truncate'}`}>
|
||||
{s.updatedBy.name ??
|
||||
s.updatedBy.email ??
|
||||
'another user'}
|
||||
@@ -276,51 +278,71 @@ export const StatusList = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`
|
||||
mb-2 sm:mb-3 leading-relaxed break-words
|
||||
${tvMode ? 'text-2xl' : 'text-[0.95rem] sm:text-lg'}
|
||||
${
|
||||
s
|
||||
? 'text-foreground'
|
||||
: 'text-muted-foreground italic'
|
||||
}
|
||||
line-clamp-2
|
||||
mb-2 sm:mb-3
|
||||
${tvMode ? 'text-6xl' : 'text-[0.95rem] sm:text-lg'}
|
||||
${s ? 'text-foreground' : 'text-muted-foreground italic'}
|
||||
`}
|
||||
title={s?.message ?? undefined}
|
||||
>
|
||||
{s?.message ?? 'No status yet.'}
|
||||
</div>
|
||||
|
||||
{/* Meta */}
|
||||
<div
|
||||
className='flex items-center gap-3 sm:gap-4
|
||||
text-muted-foreground'
|
||||
>
|
||||
{/* Meta - only show here when NOT in TV mode */}
|
||||
{!tvMode && (
|
||||
<div
|
||||
className={`
|
||||
flex items-center text-muted-foreground gap-3 sm:gap-4
|
||||
`}
|
||||
>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Clock className='w-4 h-4 sm:w-4 sm:h-4' />
|
||||
<span className='text-sm sm:text-lg'>
|
||||
{s ? formatTime(s.updatedAt) : '--:--'}
|
||||
</span>
|
||||
</div>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Calendar className='w-4 h-4 sm:w-4 sm:h-4' />
|
||||
<span className='text-sm sm:text-lg'>
|
||||
{s ? formatDate(s.updatedAt) : '--/--'}
|
||||
</span>
|
||||
</div>
|
||||
{s && (
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Activity className='w-4 h-4 sm:w-4 sm:h-4' />
|
||||
<span className='text-sm sm:text-lg'>
|
||||
{getStatusAge(s.updatedAt)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Date/Time Column - only show when in TV mode */}
|
||||
{tvMode && (
|
||||
<div className='flex flex-col items-end gap-2 text-muted-foreground min-w-0'>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Clock className='w-4 h-4 sm:w-4 sm:h-4' />
|
||||
<span className='text-xs sm:text-sm'>
|
||||
<Clock className='w-8 h-8' />
|
||||
<span className='text-4xl'>
|
||||
{s ? formatTime(s.updatedAt) : '--:--'}
|
||||
</span>
|
||||
</div>
|
||||
<div className='hidden xs:flex items-center gap-1.5'>
|
||||
<Calendar className='w-4 h-4' />
|
||||
<span className='text-xs sm:text-sm'>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Calendar className='w-8 h-8' />
|
||||
<span className='text-4xl'>
|
||||
{s ? formatDate(s.updatedAt) : '--/--'}
|
||||
</span>
|
||||
</div>
|
||||
{s && (
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Activity className='w-4 h-4' />
|
||||
<span className='text-xs sm:text-sm'>
|
||||
<Activity className='w-8 h-8' />
|
||||
<span className='text-4xl'>
|
||||
{getStatusAge(s.updatedAt)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{/* Actions */}
|
||||
{!tvMode && (
|
||||
<div className='flex flex-col items-end gap-2'>
|
||||
@@ -341,7 +363,6 @@ export const StatusList = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Mobile "via user" line */}
|
||||
{isUpdatedByOther && s?.updatedBy && (
|
||||
<div
|
||||
|
@@ -173,7 +173,7 @@ export const StatusTable = ({
|
||||
<BasedAvatar
|
||||
src={u.imageUrl}
|
||||
fullName={u.name}
|
||||
className={tvMode ? 'w-16 h-16' : 'w-12 h-12'}
|
||||
className={tvMode ? 'w-16 h-16 text-2xl' : 'w-12 h-12'}
|
||||
/>
|
||||
<div>
|
||||
<p> {u.name ?? 'Technician #' + (i + 1)} </p>
|
||||
@@ -182,7 +182,7 @@ export const StatusTable = ({
|
||||
<BasedAvatar
|
||||
src={s.updatedBy.imageUrl}
|
||||
fullName={s.updatedBy.name}
|
||||
className='w-5 h-5'
|
||||
className='w-5 h-5 text-xs'
|
||||
/>
|
||||
<span className={tvMode ? 'text-xl' : 'text-base'}>
|
||||
Updated by {s.updatedBy.name}
|
||||
|
Reference in New Issue
Block a user