import { useState } from 'react' import useSWR from 'swr' import { Badge, Group, Stack, Text, Title, Paper, Table, TextInput, ActionIcon, Avatar, Code, Button, Box, Pagination, ThemeIcon, ScrollArea, Container, } from '@mantine/core' import { useMediaQuery } from '@mantine/hooks' import { createFileRoute, useParams } from '@tanstack/react-router' import { TbSearch, TbDownload, TbX, TbHistory, TbCalendar, TbUser, TbHome2 } from 'react-icons/tb' import { API_URLS } from '../config/api' export const Route = createFileRoute('/apps/$appId/logs')({ component: AppLogsPage, }) interface LogEntry { id: string createdAt: string action: string desc: string username: string village: string } const fetcher = (url: string) => fetch(url).then((res) => res.json()) function AppLogsPage() { const { appId } = useParams({ from: '/apps/$appId/logs' }) const [page, setPage] = useState(1) const [search, setSearch] = useState('') const [searchQuery, setSearchQuery] = useState('') const isDesaPlus = appId === 'desa-plus' const isMobile = useMediaQuery('(max-width: 768px)') const apiUrl = isDesaPlus ? API_URLS.getLogsAllVillages(page, searchQuery) : null const { data: response, error, isLoading } = useSWR(apiUrl, fetcher) const logs: LogEntry[] = response?.data?.log || [] const handleSearchChange = (val: string) => { setSearch(val) if (val.length >= 3 || val.length === 0) { setSearchQuery(val) setPage(1) } } const handleClearSearch = () => { setSearch('') setSearchQuery('') setPage(1) } const getActionColor = (action: string) => { const a = action.toUpperCase() if (a === 'LOGIN') return 'blue' if (a === 'LOGOUT') return 'gray' if (a === 'CREATE') return 'teal' if (a === 'UPDATE') return 'orange' if (a === 'DELETE') return 'red' return 'brand-blue' } if (!isDesaPlus) { return ( Activity Logs This feature is currently customized for Desa+. Other apps coming soon. ) } return ( Activity Logs {isLoading ? 'Loading logs...' : `Auditing ${response?.data?.total || 0} events across all villages`} } size="md" rightSection={ search ? ( ) : null } value={search} onChange={(e) => handleSearchChange(e.currentTarget.value)} radius="md" style={{ maxWidth: 500 }} ml={40} /> {isLoading ? ( Fetching activity logs... ) : error ? ( Failed to load logs from API. ) : logs.length === 0 ? ( No activity found for this search. ) : ( Timestamp User & Village Action Description {logs.map((log) => ( {log.createdAt.split(' ').slice(1).join(' ')} {log.createdAt.split(' ')[0]} {log.username.charAt(0)} {log.username} {log.village} {log.action} {log.desc} ))}
)} {!isLoading && !error && response?.data?.totalPage > 0 && ( )}
) }