Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/develop/resources/scripts/components/dashboard/activity/ActivityLogContainer.tsx
7454 views
1
import { useEffect, useState } from 'react';
2
import { ActivityLogFilters, useActivityLogs } from '@/api/account/activity';
3
import { useFlashKey } from '@/plugins/useFlash';
4
import PageContentBlock from '@/components/elements/PageContentBlock';
5
import FlashMessageRender from '@/components/FlashMessageRender';
6
import { Link } from 'react-router-dom';
7
import PaginationFooter from '@/components/elements/table/PaginationFooter';
8
import { DesktopComputerIcon, XCircleIcon } from '@heroicons/react/solid';
9
import Spinner from '@/components/elements/Spinner';
10
import { styles as btnStyles } from '@/components/elements/button/index';
11
import classNames from 'classnames';
12
import ActivityLogEntry from '@/components/elements/activity/ActivityLogEntry';
13
import Tooltip from '@/components/elements/tooltip/Tooltip';
14
import useLocationHash from '@/plugins/useLocationHash';
15
16
export default () => {
17
const { hash } = useLocationHash();
18
const { clearAndAddHttpError } = useFlashKey('account');
19
const [filters, setFilters] = useState<ActivityLogFilters>({ page: 1, sorts: { timestamp: -1 } });
20
const { data, isValidating, error } = useActivityLogs(filters, {
21
revalidateOnMount: true,
22
revalidateOnFocus: false,
23
});
24
25
useEffect(() => {
26
setFilters(value => ({ ...value, filters: { ip: hash.ip, event: hash.event } }));
27
}, [hash]);
28
29
useEffect(() => {
30
clearAndAddHttpError(error);
31
}, [error]);
32
33
return (
34
<PageContentBlock title={'Account Activity Log'}>
35
<FlashMessageRender byKey={'account'} />
36
{(filters.filters?.event || filters.filters?.ip) && (
37
<div className={'mb-2 flex justify-end'}>
38
<Link
39
to={'#'}
40
className={classNames(btnStyles.button, btnStyles.text, 'w-full sm:w-auto')}
41
onClick={() => setFilters(value => ({ ...value, filters: {} }))}
42
>
43
Clear Filters <XCircleIcon className={'ml-2 h-4 w-4'} />
44
</Link>
45
</div>
46
)}
47
{!data && isValidating ? (
48
<Spinner centered />
49
) : (
50
<div className={'bg-slate-700'}>
51
{data?.items.map(activity => (
52
<ActivityLogEntry key={activity.id} activity={activity}>
53
{typeof activity.properties.useragent === 'string' && (
54
<Tooltip content={activity.properties.useragent} placement={'top'}>
55
<span>
56
<DesktopComputerIcon />
57
</span>
58
</Tooltip>
59
)}
60
</ActivityLogEntry>
61
))}
62
</div>
63
)}
64
{data && (
65
<PaginationFooter
66
pagination={data.pagination}
67
onPageSelect={page => setFilters(value => ({ ...value, page }))}
68
/>
69
)}
70
</PageContentBlock>
71
);
72
};
73
74