ldc-laravel-base-project/resources/ts/back/Pages/ActivityLogs/Index.tsx
2026-07-09 17:32:17 +02:00

237 lines
7.1 KiB
TypeScript

import { usePage } from "@inertiajs/react";
import { type Row } from "@tanstack/react-table";
import { FileTextIcon, UserIcon } from "lucide-react";
import BtnOptionnalLinkWithTooltip from "@/back/Components/BtnOptionnalLinkWithTooltip";
import DataTable from "@/back/Components/Table/DataTable";
import DataTableFilterButton from "@/back/Components/Table/DataTableFilterButton";
import DataTableSearch from "@/back/Components/Table/DataTableSearch";
import AuthenticatedLayout from "@/back/Layouts/AuthenticatedLayout";
import { Views } from "@/back/lib/actions";
import type { ActivityLogModel } from "@/back/types/activity-logs";
import type { ConfigBackend, Resource } from "@/back/types/global";
import { Badge } from "@/components/ui/badge";
import str from "@/hooks/use-string";
import useTrans from "@/hooks/use-translations";
import { GetFormatedDate, GetTranslation } from "@/lib/utils";
type ActivityLogsEventEnumProps = Record<
string,
{ value: number; name: string; label: string; tailwindclass: string }
>;
interface ActivityLogsIndexProps {
activitylogModels: Resource;
searchFields: string;
activityLogsEventEnum: ActivityLogsEventEnumProps;
}
const getColumns = (
routeName: string,
activityLogsEventEnum: ActivityLogsEventEnumProps,
) => {
return [
{
accessorKey: "event",
header: ({ column }: { column: { id: string } }) => (
<DataTableFilterButton
label={str(
GetTranslation(`uwil-activity-logs::trans.attributes.${column.id}`),
)
.ucFirst()
.value()}
field={column.id}
/>
),
cell: ({ row }: { row: Row<ActivityLogModel> }) => {
const eventValue = row.getValue<number>("event");
const currentEvent = Object.values(activityLogsEventEnum).find(
(event) => event.value === eventValue,
);
if (!currentEvent) {
return GetTranslation(`uwil-activity-logs::trans.event_not_match`);
}
const bgClass = `bg-${currentEvent.tailwindclass}`;
const hoverClass = `hover:bg-${currentEvent.tailwindclass}/90`;
const textClass = `text-${currentEvent.tailwindclass}-foreground`;
return (
<Badge className={`${textClass} ${bgClass} ${hoverClass}`}>
{str(GetTranslation(currentEvent.label)).ucFirst().value()}
</Badge>
);
},
},
{
accessorKey: "user_id",
header: ({ column }: { column: { id: string } }) => (
<DataTableFilterButton
label={str(
GetTranslation(`uwil-activity-logs::trans.attributes.${column.id}`),
)
.ucFirst()
.value()}
field={column.id}
/>
),
cell: ({ row }: { row: Row<ActivityLogModel> }) => {
const {
user,
user_id: userId,
is_console: isConsole,
is_anonymous: isAnonymous,
} = row.original;
if (user) {
return (
<BtnOptionnalLinkWithTooltip
link={route(`${routeName}users.show`, {
user: userId,
})}
content={
<>
<UserIcon />
{`${user.first_name} ${user.last_name}`}
</>
}
tooltipContent={
<p>
{GetTranslation(`uwil-activity-logs::trans.access_model`, {
params: {
model: GetTranslation(
"uwil-backend::models.classes.users",
{ choice: 1 },
),
},
})}
</p>
}
size="sm"
variant="secondary"
/>
);
}
if (isConsole) {
return GetTranslation(`uwil-activity-logs::trans.user_in_console`);
}
if (isAnonymous) {
return GetTranslation(`uwil-activity-logs::trans.user_anonym`);
}
return GetTranslation(`uwil-activity-logs::trans.user_deleted`);
},
},
{
accessorKey: "model_class",
header: ({ column }: { column: { id: string } }) => (
<DataTableFilterButton
label={str(
GetTranslation(`uwil-activity-logs::trans.attributes.${column.id}`),
)
.ucFirst()
.value()}
field={column.id}
/>
),
cell: ({ row }: { row: Row<ActivityLogModel> }) => {
const modelClass = row.getValue<string>("model_class");
const { event, model_id: modelId } = row.original;
const modelSplit = modelClass.split("\\");
const modelTargetName = modelSplit[modelSplit.length - 1];
const model = str(modelTargetName).kebabCase().value();
const targetRoute = `${routeName}${str(model).plural().value()}.show`;
if (
event !== activityLogsEventEnum.deleted.value &&
route().has(targetRoute)
) {
return (
<BtnOptionnalLinkWithTooltip
link={route(targetRoute, modelId)}
content={
<>
<FileTextIcon />
{modelClass}
</>
}
tooltipContent={
<p>
{GetTranslation(`uwil-activity-logs::trans.access_model`, {
params: {
model: GetTranslation(
`uwil-activity-logs::trans.attributes.model_class`,
),
},
})}
</p>
}
size="sm"
variant="secondary"
/>
);
}
return <Badge variant="outline">{modelClass}</Badge>;
},
},
{
accessorKey: "created_at",
header: ({ column }: { column: { id: string } }) => (
<DataTableFilterButton
label={str(
GetTranslation(`uwil-activity-logs::trans.attributes.${column.id}`),
)
.ucFirst()
.value()}
field={column.id}
/>
),
cell: ({ row }: { row: Row<ActivityLogModel> }) => {
const createdAt = row.getValue<string>("created_at");
return <Badge variant="secondary">{GetFormatedDate(createdAt)}</Badge>;
},
},
];
};
export default function Index({
activitylogModels,
searchFields,
activityLogsEventEnum,
}: ActivityLogsIndexProps) {
const routeName = (usePage().props.configBackend as ConfigBackend).routes
.name;
const modelName = usePage().props.modelName as string;
const columns = getColumns(routeName, activityLogsEventEnum);
const actionModels = [Views.VISUALIZATION];
return (
<AuthenticatedLayout
title={str(
useTrans(`uwil-activity-logs::models.classes.${modelName}`, {
choice: 2,
}),
)
.ucFirst()
.value()}
>
<DataTableSearch
modelRoute={modelName}
prefixRoute={routeName}
searchFields={searchFields}
/>
<DataTable
columns={columns}
modelRoute={modelName}
modelsPaginate={activitylogModels}
actions={actionModels}
/>
</AuthenticatedLayout>
);
}