From 00f58d71d619780ab179d45e94ca3b78458c65aa Mon Sep 17 00:00:00 2001 From: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:38:45 +0100 Subject: [PATCH] [Website] update data/page.tsx (#1969) --- frontend/src/app/data/page.tsx | 422 +++++++++++++++------------------ 1 file changed, 192 insertions(+), 230 deletions(-) diff --git a/frontend/src/app/data/page.tsx b/frontend/src/app/data/page.tsx index 3f1d7ace..462158f6 100644 --- a/frontend/src/app/data/page.tsx +++ b/frontend/src/app/data/page.tsx @@ -1,33 +1,9 @@ "use client"; -import ApplicationChart from "@/components/ApplicationChart"; -import { Button } from "@/components/ui/button"; -import { Calendar } from "@/components/ui/calendar"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Input } from "@/components/ui/input"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; -import { format } from "date-fns"; -import { Calendar as CalendarIcon } from "lucide-react"; -import React, { useCallback, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import ApplicationChart from "../../components/ApplicationChart"; interface DataModel { id: number; @@ -64,41 +40,23 @@ const DataFetcher: React.FC = () => { const [reloadInterval, setReloadInterval] = useState(null); - const fetchData = useCallback(async () => { - try { - const response = await fetch("https://api.htl-braunau.at/data/json"); - if (!response.ok) throw new Error(`Failed to fetch data: ${response.statusText}`); - const result: DataModel[] = await response.json(); - setData(result); - setLoading(false); - } catch (err) { - setError((err as Error).message); - setLoading(false); - } + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch("https://api.htl-braunau.at/data/json"); + if (!response.ok) throw new Error("Failed to fetch data: ${response.statusText}"); + const result: DataModel[] = await response.json(); + setData(result); + } catch (err) { + setError((err as Error).message); + } finally { + setLoading(false); + } + }; + + fetchData(); }, []); - useEffect(() => { - fetchData(); - const storedInterval = localStorage.getItem('reloadInterval'); - if (storedInterval) { - setIntervalTime(Number(storedInterval)); - } - }, [fetchData]); - - useEffect(() => { - let intervalId: NodeJS.Timeout | null = null; - - if (interval > 0) { - intervalId = setInterval(fetchData, Math.max(interval, 10) * 1000); - localStorage.setItem('reloadInterval', interval.toString()); - } else { - localStorage.removeItem('reloadInterval'); - } - - return () => { - if (intervalId) clearInterval(intervalId); - }; - }, [interval, fetchData]); const filteredData = data.filter(item => { const matchesSearchQuery = Object.values(item).some(value => @@ -153,194 +111,198 @@ const DataFetcher: React.FC = () => { return `${day}.${month}.${year} ${hours}:${minutes} ${timezoneOffset} GMT`; }; + const handleItemsPerPageChange = (event: React.ChangeEvent) => { + setItemsPerPage(Number(event.target.value)); + setCurrentPage(1); + }; + const paginatedData = sortedData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); - const statusCounts = data.reduce((acc, item) => { - const status = item.status; - acc[status] = (acc[status] || 0) + 1; - return acc; - }, {} as Record); + useEffect(() => { + const storedInterval = localStorage.getItem('reloadInterval'); + if (storedInterval) { + setIntervalTime(Number(storedInterval)); + } + }, []); - if (loading) return
Loading...
; - if (error) return
Error: {error}
; + + useEffect(() => { + if (interval <= 10) { + const newInterval = setInterval(() => { + window.location.reload(); + }, 10000); + + + return () => clearInterval(newInterval); + } else { + const newInterval = setInterval(() => { + window.location.reload(); + }, interval * 1000); + } + + }, [interval]); + + + useEffect(() => { + if (interval > 0) { + localStorage.setItem('reloadInterval', interval.toString()); + } else { + localStorage.removeItem('reloadInterval'); + } + }, [interval]); + + if (loading) return

Loading...

; + if (error) return

Error: {error}

; + + var installingCounts: number = 0; + var failedCounts: number = 0; + var doneCounts: number = 0 + var unknownCounts: number = 0; + data.forEach((item) => { + if (item.status === "installing") { + installingCounts += 1; + } else if (item.status === "failed") { + failedCounts += 1; + } + else if (item.status === "done") { + doneCounts += 1; + } + else { + unknownCounts += 1; + } + }); return ( -
-

Created LXCs

- -
- - - Search - - - setSearchQuery(e.target.value)} - /> - - - - - - Start Date - - - - - - - - setStartDate(date || null)} - initialFocus - /> - - - - - - - - End Date - - - - - - - - setEndDate(date || null)} - initialFocus - /> - - - - - - - - Reload Interval - - - setIntervalTime(Number(e.target.value))} - placeholder="Interval (seconds)" - /> - - -
- - - -
-

{filteredData.length} results found

-
- 🔄 Installing: {statusCounts.installing || 0} - ✔️ Completed: {statusCounts.done || 0} - ❌ Failed: {statusCounts.failed || 0} - ❓ Unknown: {statusCounts.unknown || 0} +
+

Created LXCs

+
+
+ setSearchQuery(e.target.value)} + className="p-2 border" + /> + +
+
+ setStartDate(date)} + selectsStart + startDate={startDate} + endDate={endDate} + placeholderText="Start date" + className="p-2 border" + /> +
- -
-
- - - - requestSort('status')}>Status - requestSort('nsapp')}>Application - requestSort('os_type')}>OS - requestSort('os_version')}>OS Version - requestSort('disk_size')}>Disk Size - requestSort('core_count')}>Core Count - requestSort('ram_size')}>RAM Size - requestSort('hn')}>Hostname - requestSort('ssh')}>SSH - requestSort('verbose')}>Verb - requestSort('tags')}>Tags - requestSort('method')}>Method - requestSort('pve_version')}>PVE Version - requestSort('created_at')}>Created At - - - - {paginatedData.map((item, index) => ( - - {item.status === "done" ? ( - "✔️" - ) : item.status === "failed" ? ( - "❌" - ) : item.status === "installing" ? ( - "🔄" - ) : ( - item.status - )} - {item.nsapp} - {item.os_type} - {item.os_version} - {item.disk_size} - {item.core_count} - {item.ram_size} - {item.hn} - {item.ssh} - {item.verbose} - {item.tags.replace(/;/g, ' ')} - {item.method} - {item.pve_version} - {formatDate(item.created_at)} - - ))} - -
+
+ setEndDate(date)} + selectsEnd + startDate={startDate} + endDate={endDate} + placeholderText="End date" + className="p-2 border" + /> + +
+ +
+
+ setIntervalTime(Number(e.target.value))} + className="p-2 border" + placeholder="Interval (seconds)" + /> + +
+
- -
- - - Page {currentPage} of {Math.ceil(sortedData.length / itemsPerPage)} - - +
); }; + + export default DataFetcher;