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, Search, RotateCcw, Calendar } from 'lucide-react'; import LogTable, { Activity } from '@/Components/ActivityLog/LogTable'; import ActivityDetailDialog from '@/Components/ActivityLog/ActivityDetailDialog'; import { Button } from '@/Components/ui/button'; import { Input } from '@/Components/ui/input'; import { Label } from '@/Components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/Components/ui/select"; import { getDateRange } from "@/utils/format"; 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'; search?: string; date_start?: string; date_end?: string; event?: string; subject_type?: string; causer_id?: string; }; subject_types: { label: string; value: string }[]; users: { label: string; value: string }[]; } export default function ActivityLogIndex({ activities, filters, subject_types, users }: Props) { const [perPage, setPerPage] = useState(filters.per_page || "10"); const [selectedActivity, setSelectedActivity] = useState(null); const [detailOpen, setDetailOpen] = useState(false); // Filter States const [search, setSearch] = useState(filters.search || ''); const [dateStart, setDateStart] = useState(filters.date_start || ''); const [dateEnd, setDateEnd] = useState(filters.date_end || ''); const [event, setEvent] = useState(filters.event || 'all'); const [subjectType, setSubjectType] = useState(filters.subject_type || 'all'); const [causer, setCauser] = useState(filters.causer_id || 'all'); const [dateRangeType, setDateRangeType] = useState('custom'); const handleDateRangeChange = (type: string) => { setDateRangeType(type); if (type === 'custom') return; const { start, end } = getDateRange(type); setDateStart(start); setDateEnd(end); }; const handleFilter = () => { router.get( route('activity-logs.index'), { ...filters, search: search, date_start: dateStart, date_end: dateEnd, event: event === 'all' ? undefined : event, subject_type: subjectType === 'all' ? undefined : subjectType, causer_id: causer === 'all' ? undefined : causer, page: 1 // Reset to first page on filter }, { preserveState: true, replace: true } ); }; const handleReset = () => { setSearch(''); setDateStart(''); setDateEnd(''); setEvent('all'); setSubjectType('all'); setCauser('all'); setDateRangeType('custom'); router.get( route('activity-logs.index'), { per_page: perPage, sort_by: filters.sort_by, sort_order: filters.sort_order }, { preserveState: true, replace: true } ); }; const handleViewDetail = (activity: Activity) => { setSelectedActivity(activity); setDetailOpen(true); }; const handlePerPageChange = (value: string) => { setPerPage(value); router.get( route('activity-logs.index'), { ...filters, per_page: value, page: 1 }, { 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 (

操作紀錄

檢視系統內的所有操作活動,包含新增、修改與刪除紀錄

{/* 篩選區塊 */}
{/* Top Config: Date Range & Quick Buttons */}
{[ { label: "今日", value: "today" }, { label: "昨日", value: "yesterday" }, { label: "本週", value: "this_week" }, { label: "本月", value: "this_month" }, { label: "上月", value: "last_month" }, ].map((opt) => ( ))}
{/* Date Inputs */}
{ setDateStart(e.target.value); setDateRangeType('custom'); }} className="pl-9 block w-full h-9 bg-white" />
{ setDateEnd(e.target.value); setDateRangeType('custom'); }} className="pl-9 block w-full h-9 bg-white" />
{/* Detailed Filters row */}
{/* 事件類型 */}
{/* 操作對象 */}
{/* 操作人員 */}
{/* 關鍵字搜尋 */}
setSearch(e.target.value)} className="pl-10 h-9 block bg-white" onKeyDown={(e) => e.key === 'Enter' && handleFilter()} />
{/* Action Buttons Integrated */}
每頁顯示
); }