shoc-frontend-new/src/components/common/comment-timeline.tsx

60 lines
1.8 KiB
TypeScript
Raw Normal View History

import { useMemo } from "react";
import { Box, Stack } from "@mui/material";
import { CommentBodyWithMentions } from "@/components/common/comment-body-with-mentions";
import { Text } from "@/components/ui/text";
import type { MentionLookup } from "@/domain/work-orders/utils/comment-mentions";
import { formatDateTime } from "@/lib/time-utils";
export type CommentTimelineItem = {
id: string | number;
author: string;
createdAt?: string;
body: string;
mentions?: string[];
};
type CommentTimelineProps = {
items: CommentTimelineItem[];
emptyMessage?: string;
maxHeightClass?: string;
mentionUsers?: MentionLookup[];
};
export function CommentTimeline({
items,
emptyMessage = "No comments yet.",
maxHeightClass = "max-h-72",
mentionUsers,
}: CommentTimelineProps) {
const sorted = useMemo(
() =>
[...items].sort((a, b) => {
const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;
const bTime = b.createdAt ? new Date(b.createdAt).getTime() : 0;
return aTime - bTime;
}),
[items],
);
if (!sorted.length) {
return <Text tone="muted">{emptyMessage}</Text>;
}
return (
<Stack spacing={2} className={`${maxHeightClass} overflow-y-auto`}>
{sorted.map((item) => (
<Box key={String(item.id)} className="rounded border border-border p-3">
<Stack direction="row" className="mb-1" sx={{ justifyContent: "space-between" }}>
<Text variant="caption" className="font-semibold">
{item.author}
</Text>
<Text variant="caption" tone="muted">
{item.createdAt ? formatDateTime(item.createdAt) : ""}
</Text>
</Stack>
<CommentBodyWithMentions text={item.body} mentions={item.mentions} users={mentionUsers} />
</Box>
))}
</Stack>
);
}