import React, { useState, useEffect } from 'react'; import axios from 'axios'; import styles from '../styles/Dashboard.module.css'; import { useNavigate } from 'react-router-dom'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import Navbar from './Navbar'; function Dashboard() { document.title = 'LinkLogger | Dashboard'; interface Log { id: number; link: string; timestamp: string; ip: string; location: string; browser: string; os: string; userAgent: string; isp: string; } interface Link { link: string; owner: number; redirect_link: string; expire_date: string; } const [links, setLinks] = useState([]); const [logs, setLogs] = useState([]); const [visibleLog, setVisibleLog] = useState(null); const navigate = useNavigate(); // Fetch links from API useEffect(() => { axios .get('/api/links') .then((res) => { if (res.status === 200) { setLinks(res.data); } else { navigate('/login'); } }) .catch((error: unknown) => { if (axios.isAxiosError(error)) { if (error.response?.status != 404) { navigate('/login'); } } }); }, []); // Fetch logs from API useEffect(() => { axios .get('/api/logs') .then((res) => { if (res.status === 200) { setLogs(res.data); } else { navigate('/login'); } }) .catch((error: unknown) => { if (axios.isAxiosError(error)) { if (error.response?.status != 404) { navigate('/login'); } } }); }, []); /** * Display or hide logs for a specific link * @param link The link to toggle logs for */ const toggleLogRow = (link: string) => { setVisibleLog(visibleLog === link ? null : link); }; /** * Delete a specific log * Gets the log ID from the SVG element's ID attribute * @param e The event object from the click * @returns void - updates state (setLogs) if successful */ const deleteLog = (e: React.MouseEvent) => { const confirmDelete = confirm('Are you sure you want to delete this log?'); if (!confirmDelete) return; const id = parseInt(e.currentTarget.id); axios .delete(`/api/logs/${id}`) .then((res) => { if (res.status === 200) { setLogs(logs.filter((log) => log.id !== id)); } }) .catch((error: unknown) => { if (axios.isAxiosError(error)) { // Return to login if we are unauthorized for some reason if (error.response?.status === 401) { navigate('/login'); } else { alert('Failed to delete log. Please try again.'); } } }); }; return ( <> {/* If there are no links, put a special message */} {links.length === 0 && ( )} {/* For every link and its logs */} {links.map((link) => ( {/* Conditionally render logs for this link */} {visibleLog === link.link && ( )} ))}
Link Visits Redirect Expire Date
You do not have any shortened links - try creating one.
{logs.filter((log) => log.link === link.link).length || 0} {link.redirect_link} {link.expire_date}
{/* Render all logs for the link */} {logs .filter((log) => log.link === link.link) .map((log, index, filteredLogs) => ( ))} {/* If the link has no logs, put a special message */} {logs.filter((log) => log.link === link.link).length === 0 && ( )}
ID Timestamp IP Location ISP
{filteredLogs.length - index} {log.timestamp} {log.ip} {log.location} {log.isp}
No logs for this link
); } export default Dashboard;