Files
star-erp/resources/js/Pages/Admin/ActivityLog/Index.tsx

132 lines
4.6 KiB
TypeScript
Raw Normal View History

import { useState } from 'react';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head, router } from '@inertiajs/react';
import { PageProps } from '@/types/global';
import Pagination from '@/Components/shared/Pagination';
import { SearchableSelect } from "@/Components/ui/searchable-select";
import { FileText } from 'lucide-react';
import LogTable, { Activity } from '@/Components/ActivityLog/LogTable';
import ActivityDetailDialog from '@/Components/ActivityLog/ActivityDetailDialog';
interface PaginationLinks {
url: string | null;
label: string;
active: boolean;
}
interface Props extends PageProps {
activities: {
data: Activity[];
links: PaginationLinks[];
current_page: number;
last_page: number;
total: number;
from: number;
};
filters: {
per_page?: string;
sort_by?: string;
sort_order?: 'asc' | 'desc';
};
}
export default function ActivityLogIndex({ activities, filters }: Props) {
const [perPage, setPerPage] = useState<string>(filters.per_page || "10");
const [selectedActivity, setSelectedActivity] = useState<Activity | null>(null);
const [detailOpen, setDetailOpen] = useState(false);
const handleViewDetail = (activity: Activity) => {
setSelectedActivity(activity);
setDetailOpen(true);
};
const handlePerPageChange = (value: string) => {
setPerPage(value);
router.get(
route('activity-logs.index'),
{ ...filters, per_page: value },
{ preserveState: false, replace: true, preserveScroll: true }
);
};
const handleSort = (field: string) => {
let newSortBy: string | undefined = field;
let newSortOrder: 'asc' | 'desc' | undefined = 'asc';
if (filters.sort_by === field) {
if (filters.sort_order === 'asc') {
newSortOrder = 'desc';
} else {
newSortBy = undefined;
newSortOrder = undefined;
}
}
router.get(
route('activity-logs.index'),
{ ...filters, sort_by: newSortBy, sort_order: newSortOrder },
{ preserveState: true, replace: true }
);
};
return (
<AuthenticatedLayout
breadcrumbs={[
{ label: '系統管理', href: '#' },
{ label: '操作紀錄', href: route('activity-logs.index'), isPage: true },
]}
>
<Head title="操作紀錄" />
<div className="container mx-auto p-6 max-w-7xl">
<div className="flex items-center justify-between mb-6">
<div>
<h1 className="text-2xl font-bold text-grey-0 flex items-center gap-2">
<FileText className="h-6 w-6 text-primary-main" />
</h1>
<p className="text-gray-500 mt-1">
</p>
</div>
</div>
<LogTable
activities={activities.data}
sortField={filters.sort_by}
sortOrder={filters.sort_order}
onSort={handleSort}
onViewDetail={handleViewDetail}
from={activities.from}
/>
<div className="mt-4 flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="flex items-center gap-2 text-sm text-gray-500">
<span></span>
<SearchableSelect
value={perPage}
onValueChange={handlePerPageChange}
options={[
{ label: "10", value: "10" },
{ label: "20", value: "20" },
{ label: "50", value: "50" },
{ label: "100", value: "100" }
]}
className="w-[80px] h-8"
showSearch={false}
/>
<span></span>
</div>
<Pagination links={activities.links} />
</div>
</div>
<ActivityDetailDialog
open={detailOpen}
onOpenChange={setDetailOpen}
activity={selectedActivity}
/>
</AuthenticatedLayout>
);
}