summaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/history-view.tsx93
1 files changed, 86 insertions, 7 deletions
diff --git a/frontend/history-view.tsx b/frontend/history-view.tsx
index 2faa1c0..12af1ea 100644
--- a/frontend/history-view.tsx
+++ b/frontend/history-view.tsx
@@ -3,7 +3,8 @@
3import { useState, useEffect } from "react" 3import { useState, useEffect } from "react"
4import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" 4import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
5import { Badge } from "@/components/ui/badge" 5import { Badge } from "@/components/ui/badge"
6import { FileText, Folder, Trash2, Edit, Plus } from "lucide-react" 6import { Button } from "@/components/ui/button"
7import { FileText, Folder, Trash2, Edit, Plus, ChevronLeft, ChevronRight } from "lucide-react"
7import { DriveLogEntry } from "@/lib/drive_types" 8import { DriveLogEntry } from "@/lib/drive_types"
8import { formatFileSize } from "@/lib/utils" 9import { formatFileSize } from "@/lib/utils"
9 10
@@ -62,10 +63,13 @@ function getActionBadge(action: string) {
62 } 63 }
63} 64}
64 65
66const ENTRIES_PER_PAGE = 100
67
65export default function HistoryView() { 68export default function HistoryView() {
66 const [logEntries, setLogEntries] = useState<DriveLogEntry[]>([]) 69 const [logEntries, setLogEntries] = useState<DriveLogEntry[]>([])
67 const [loading, setLoading] = useState(true) 70 const [loading, setLoading] = useState(true)
68 const [error, setError] = useState<string | null>(null) 71 const [error, setError] = useState<string | null>(null)
72 const [currentPage, setCurrentPage] = useState(1)
69 73
70 useEffect(() => { 74 useEffect(() => {
71 async function fetchLogEntries() { 75 async function fetchLogEntries() {
@@ -88,6 +92,24 @@ export default function HistoryView() {
88 fetchLogEntries() 92 fetchLogEntries()
89 }, []) 93 }, [])
90 94
95 // Calculate pagination values
96 const totalPages = Math.ceil(logEntries.length / ENTRIES_PER_PAGE)
97 const startIndex = (currentPage - 1) * ENTRIES_PER_PAGE
98 const endIndex = startIndex + ENTRIES_PER_PAGE
99 const currentEntries = logEntries.slice(startIndex, endIndex)
100
101 const handlePageChange = (page: number) => {
102 setCurrentPage(page)
103 }
104
105 const handlePreviousPage = () => {
106 setCurrentPage(prev => Math.max(1, prev - 1))
107 }
108
109 const handleNextPage = () => {
110 setCurrentPage(prev => Math.min(totalPages, prev + 1))
111 }
112
91 if (loading) { 113 if (loading) {
92 return ( 114 return (
93 <div className="space-y-6"> 115 <div className="space-y-6">
@@ -136,27 +158,25 @@ export default function HistoryView() {
136 <Table> 158 <Table>
137 <TableHeader> 159 <TableHeader>
138 <TableRow> 160 <TableRow>
139 <TableHead className="w-[50px]">Action</TableHead>
140 <TableHead>Type</TableHead> 161 <TableHead>Type</TableHead>
141 <TableHead>File/Directory Name</TableHead> 162 <TableHead>File/Directory Name</TableHead>
163 <TableHead>Time</TableHead>
142 <TableHead>User</TableHead> 164 <TableHead>User</TableHead>
143 <TableHead>Timestamp</TableHead>
144 <TableHead>Size</TableHead> 165 <TableHead>Size</TableHead>
145 </TableRow> 166 </TableRow>
146 </TableHeader> 167 </TableHeader>
147 <TableBody> 168 <TableBody>
148 {logEntries.map((entry) => ( 169 {currentEntries.map((entry) => (
149 <TableRow key={`${entry.log_id}`} className="hover:bg-muted/50"> 170 <TableRow key={`${entry.log_id}`} className="hover:bg-muted/50">
150 <TableCell>{getActionIcon(entry.action)}</TableCell>
151 <TableCell>{getActionBadge(entry.action)}</TableCell> 171 <TableCell>{getActionBadge(entry.action)}</TableCell>
152 <TableCell className="font-medium"> 172 <TableCell className="font-medium">
153 <span className="break-words">{entry.path}</span> 173 <span className="break-words">{entry.path}</span>
154 </TableCell> 174 </TableCell>
155 <TableCell> 175 <TableCell>
156 <span className="text-sm font-mono">{entry.email}</span> 176 <span className="text-sm">{formatTimestamp(entry.timestamp)}</span>
157 </TableCell> 177 </TableCell>
158 <TableCell> 178 <TableCell>
159 <span className="text-sm">{formatTimestamp(entry.timestamp)}</span> 179 <span className="text-sm font-mono">{entry.email}</span>
160 </TableCell> 180 </TableCell>
161 <TableCell> 181 <TableCell>
162 <span className="text-sm text-muted-foreground"> 182 <span className="text-sm text-muted-foreground">
@@ -168,6 +188,65 @@ export default function HistoryView() {
168 </TableBody> 188 </TableBody>
169 </Table> 189 </Table>
170 </div> 190 </div>
191
192 {/* Pagination */}
193 {totalPages > 1 && (
194 <div className="flex items-center justify-between">
195 <div className="text-sm text-muted-foreground">
196 Showing {startIndex + 1} to {Math.min(endIndex, logEntries.length)} of {logEntries.length} entries
197 </div>
198 <div className="flex items-center gap-2">
199 <Button
200 variant="outline"
201 size="sm"
202 onClick={handlePreviousPage}
203 disabled={currentPage === 1}
204 >
205 <ChevronLeft className="h-4 w-4" />
206 Previous
207 </Button>
208
209 <div className="flex items-center gap-1">
210 {Array.from({ length: totalPages }, (_, i) => i + 1)
211 .filter(page => {
212 // Show first page, last page, current page, and pages around current
213 return page === 1 ||
214 page === totalPages ||
215 Math.abs(page - currentPage) <= 2
216 })
217 .map((page, index, filteredPages) => {
218 // Add ellipsis where there are gaps
219 const showEllipsisBefore = index > 0 && page - filteredPages[index - 1] > 1
220 return (
221 <div key={page} className="flex items-center gap-1">
222 {showEllipsisBefore && (
223 <span className="text-muted-foreground px-2">...</span>
224 )}
225 <Button
226 variant={currentPage === page ? "default" : "outline"}
227 size="sm"
228 onClick={() => handlePageChange(page)}
229 className="w-8 h-8 p-0"
230 >
231 {page}
232 </Button>
233 </div>
234 )
235 })}
236 </div>
237
238 <Button
239 variant="outline"
240 size="sm"
241 onClick={handleNextPage}
242 disabled={currentPage === totalPages}
243 >
244 Next
245 <ChevronRight className="h-4 w-4" />
246 </Button>
247 </div>
248 </div>
249 )}
171 </div> 250 </div>
172 ) 251 )
173} 252}