+ {/* Mobile: card list */}
+
+
{isLoading ? (
+ ) : rows.length === 0 ? (
+
+ ) : (
+
+ {rows.map((r, idx) => {
+ const key = `${r.status?.id ?? 'no-status'}-${idx}`;
+ const name = r.user.name ?? 'Technician';
+ const msg = r.status?.message ?? 'No status';
+ const updatedBy = r.status?.updatedBy?.name ?? null;
+ const stamp = r.status
+ ? `${formatTime(r.status.updatedAt)} · ${formatDate(
+ r.status.updatedAt,
+ )}`
+ : '--:-- · --/--';
+
+ return (
+
+
+
+ {updatedBy && (
+
+ {updatedBy}
+
+ )}
+
+
+
+ {stamp}
+
+
+ );
+ })}
+
+ )}
+
+
+
+ {/* Desktop: original table */}
+
+
+ {isLoading ? (
+
) : rows.length === 0 ? (
@@ -115,32 +185,38 @@ export const HistoryTable = () => {
-
-
- {
- e.preventDefault();
- handlePrev();
- }}
- aria-disabled={!canPrev}
- className={!canPrev ? 'pointer-events-none opacity-50' : ''}
- />
-
- Page
- {pageIndex + 1}
-
- {
- e.preventDefault();
- handleNext();
- }}
- aria-disabled={!canNext}
- className={!canNext ? 'pointer-events-none opacity-50' : ''}
- />
-
-
+ {/* Pagination */}
+
+
+
+ {
+ e.preventDefault();
+ handlePrev();
+ }}
+ aria-disabled={!canPrev}
+ className={!canPrev ? 'pointer-events-none opacity-50' : ''}
+ />
+
+ Page
+ {pageIndex + 1}
+
+ {
+ e.preventDefault();
+ handleNext();
+ }}
+ aria-disabled={!canNext}
+ className={!canNext ? 'pointer-events-none opacity-50' : ''}
+ />
+
+
+
);
};
diff --git a/src/components/layout/status/list/index.tsx b/src/components/layout/status/list/index.tsx
index b5a95d0..1ba137f 100644
--- a/src/components/layout/status/list/index.tsx
+++ b/src/components/layout/status/list/index.tsx
@@ -44,8 +44,8 @@ export const StatusList = ({
}: StatusListProps) => {
const user = usePreloadedQuery(preloadedUser);
const statuses = usePreloadedQuery(preloadedStatuses);
-
const { tvMode } = useTVMode();
+
const [selectedUserIds, setSelectedUserIds] = useState
[]>([]);
const [selectAll, setSelectAll] = useState(false);
const [statusInput, setStatusInput] = useState('');
@@ -59,17 +59,20 @@ export const StatusList = ({
const newAnimatingIds = new Set();
statuses.forEach((curr) => {
const previous = previousStatuses.find((p) => p.user.id === curr.user.id);
- if (previous?.status?.updatedAt !== curr.status?.updatedAt)
+ if (previous?.status?.updatedAt !== curr.status?.updatedAt) {
newAnimatingIds.add(curr.user.id);
+ }
});
if (newAnimatingIds.size > 0) {
setAnimatingIds(newAnimatingIds);
setTimeout(() => setAnimatingIds(new Set()), 800);
}
setPreviousStatuses(
- statuses.sort(
- (a, b) => (b.status?.updatedAt ?? 0) - (a.status?.updatedAt ?? 0),
- ),
+ statuses
+ .slice()
+ .sort(
+ (a, b) => (b.status?.updatedAt ?? 0) - (a.status?.updatedAt ?? 0),
+ ),
);
}, [statuses]);
@@ -91,11 +94,14 @@ export const StatusList = ({
const message = statusInput.trim();
setUpdatingStatus(true);
try {
- if (message.length < 3 || message.length > 80)
+ if (message.length < 3 || message.length > 80) {
throw new Error('Status must be between 3 & 80 characters');
- if (selectedUserIds.length === 0 && user?.id)
+ }
+ if (selectedUserIds.length === 0 && user?.id) {
await bulkCreate({ message, userIds: [user.id] });
- else await bulkCreate({ message, userIds: selectedUserIds });
+ } else {
+ await bulkCreate({ message, userIds: selectedUserIds });
+ }
toast.success('Status updated.');
setSelectedUserIds([]);
setSelectAll(false);
@@ -118,14 +124,14 @@ export const StatusList = ({
const containerCn = ccn({
context: tvMode,
- className: 'w-full max-w-4xl mx-auto',
- on: 'px-12 max-w-3xl',
- off: 'px-6',
+ className: 'max-w-4xl mx-auto',
+ on: 'px-6',
+ off: 'px-4 sm:px-6',
});
const tabsCn = ccn({
context: tvMode,
- className: 'w-full py-8',
+ className: 'w-full py-4 sm:py-8',
on: 'hidden',
off: '',
});
@@ -134,31 +140,54 @@ export const StatusList = ({
context: tvMode,
className: 'w-full mb-2',
on: 'hidden',
- off: 'flex justify-end items-center',
+ off: 'hidden sm:flex justify-end items-center',
});
return (
-
-
-
-
Team Status
+
+
-
-
-
-
Status History
+
+
+
+
+ Status History
+
+
+ {/* Mobile toolbar */}
+
+
+
+ {statuses.length} members
+
+
+
+
+ Table
+
+
+
+
+ {/* Desktop header */}
-
+
-
+
{statuses.length} members
@@ -168,83 +197,78 @@ export const StatusList = ({
-
+
+ {/* Card list */}
+
{statuses.map((statusData) => {
const { user: u, status: s } = statusData;
const isSelected = selectedUserIds.includes(u.id);
const isAnimating = animatingIds.has(u.id);
const isUpdatedByOther = s?.updatedBy?.id !== u.id;
+
return (
handleSelectUser(u.id) : undefined}
+ role='button'
+ aria-pressed={isSelected}
>
- {/* Selection indicator */}
{isSelected && !tvMode && (
)}
- {/* Enhanced animation effect */}
- {isAnimating && (
-
- )}
-
-
+
{/* Avatar */}
-
+
- {/* Main Content */}
+ {/* Content */}
-
+
{u.name ?? u.email ?? 'User'}
{isUpdatedByOther && s?.updatedBy && (
-
-
- via
-
+
+
via
-
+
{s.updatedBy.name ??
s.updatedBy.email ??
'another user'}
@@ -255,36 +279,41 @@ export const StatusList = ({
{s?.message ?? 'No status yet.'}
- {/* Time Info */}
-
-
-
-
+ {/* Meta */}
+
+
+
+
{s ? formatTime(s.updatedAt) : '--:--'}
-
-
-
+
+
+
{s ? formatDate(s.updatedAt) : '--/--'}
{s && (
-
-
-
+
+
+
{getStatusAge(s.updatedAt)}
@@ -292,43 +321,72 @@ export const StatusList = ({
- {/* History Drawer */}
+ {/* Actions */}
{!tvMode && (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
)}
+
+ {/* Mobile "via user" line */}
+ {isUpdatedByOther && s?.updatedBy && (
+
+ via
+
+
+ {s.updatedBy.name ??
+ s.updatedBy.email ??
+ 'another user'}
+
+
+ )}
);
})}
- {/* Update Status Section */}
+
+ {/* Desktop composer */}
{!tvMode && (
-
+
Update Status
{selectedUserIds.length > 0 && (
-
+
{selectedUserIds.length} selected
)}
-
{selectedUserIds.length > 0
- ? `Update ${selectedUserIds.length} ${selectedUserIds.length > 1 ? 'users' : 'user'}`
+ ? `Update ${selectedUserIds.length} ${
+ selectedUserIds.length > 1 ? 'users' : 'user'
+ }`
: 'Update Status'}
-