87 lines
3.9 KiB
TypeScript
87 lines
3.9 KiB
TypeScript
import clsx from "clsx";
|
|
import { useTranslation } from "react-i18next";
|
|
import { LogWithDetails } from "~/utils/db/logs.db.server";
|
|
import { useLocaleFormatters } from "~/locale/format";
|
|
import { CalendarIcon } from "~/components/ui/icons/vendor";
|
|
|
|
interface Props {
|
|
items: LogWithDetails[];
|
|
}
|
|
|
|
export default function RowLogs({ items }: Props) {
|
|
const { t } = useTranslation();
|
|
const formatters = useLocaleFormatters();
|
|
|
|
const sortedItems = () => {
|
|
return items.slice().sort((x, y) => {
|
|
if (x.createdAt && y.createdAt) {
|
|
return x.createdAt > y.createdAt ? -1 : 1;
|
|
}
|
|
return -1;
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<div className="space-y-3">
|
|
<h3 className="text-foreground text-sm font-medium leading-3">
|
|
<div className="flex items-center space-x-1">
|
|
<div>
|
|
<span className=" font-light italic"></span> {t("app.shared.activity.title")}
|
|
</div>
|
|
</div>
|
|
</h3>
|
|
<div className="bg-background border-border rounded-md border px-4 py-5 shadow-xs">
|
|
<div className="flow-root">
|
|
<ul className="-mb-8">
|
|
{sortedItems().length === 0 && <div className=" text-muted-foreground mb-6 flex justify-center text-sm italic">{t("models.row.logs.noEvents")}</div>}
|
|
{sortedItems().map((activity, idxActivity) => {
|
|
return (
|
|
<li key={idxActivity}>
|
|
<div className="relative pb-8">
|
|
{items.length > 0 && idxActivity + 1 < items.length && (
|
|
<span className="absolute left-4 top-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
|
|
)}
|
|
|
|
<div className="relative flex space-x-3">
|
|
<div>
|
|
<span className={clsx("bg-secondary/90 flex h-8 w-8 items-center justify-center rounded-full ring-8 ring-white")}>
|
|
<CalendarIcon className="text-muted-foreground h-4 w-4" />
|
|
</span>
|
|
</div>
|
|
<div className="grow">
|
|
<div className="flex min-w-0 flex-1 justify-between space-x-4">
|
|
<div className="truncate">
|
|
<div className="text-muted-foreground text-sm">
|
|
<div className="text-foreground truncate">
|
|
<span title={activity.action}>{activity.action}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="text-muted-foreground truncate whitespace-nowrap text-right text-xs lowercase">
|
|
{activity.createdAt && (
|
|
<time dateTime={new Date(activity.createdAt).toISOString()} title={formatters.dateTime(activity.createdAt, { timeStyle: "medium" })}>
|
|
{formatters.date(activity.createdAt, { month: "short", day: "numeric" })}, {formatters.date(activity.createdAt, { timeStyle: "medium" })}
|
|
</time>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex min-w-0 flex-1 justify-between space-x-4">
|
|
{activity.user && <div className="text-xs font-light">{activity.user.email}</div>}
|
|
{activity.apiKey && <div className="text-xs font-light">{activity.apiKey.alias}</div>}
|
|
{!activity.user && !activity.apiKey && <div className="text-xs font-light">{t("shared.anonymousUser")}</div>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|