diff options
author | Parker <contact@pkrm.dev> | 2024-11-10 23:11:17 -0600 |
---|---|---|
committer | Parker <contact@pkrm.dev> | 2024-11-10 23:11:17 -0600 |
commit | 8985eecfeac5887f59fdf36d9b3f2584692ff5ed (patch) | |
tree | 908b05eacbad8def836dae7ccf67c534675bb912 /app/src | |
parent | 691aa744a0398f185b3ca98a36fbd83806c7786c (diff) |
Add log routes and update dashboard
Diffstat (limited to 'app/src')
-rw-r--r-- | app/src/App.tsx | 1 | ||||
-rw-r--r-- | app/src/components/Dashboard.tsx | 142 | ||||
-rw-r--r-- | app/src/styles/Dashboard.module.css | 33 |
3 files changed, 130 insertions, 46 deletions
diff --git a/app/src/App.tsx b/app/src/App.tsx index 75cd203..14fa571 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,5 +1,4 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; -// Import components import Login from './components/Login' import Signup from './components/Signup' import Dashboard from './components/Dashboard' diff --git a/app/src/components/Dashboard.tsx b/app/src/components/Dashboard.tsx index bcab092..373a07f 100644 --- a/app/src/components/Dashboard.tsx +++ b/app/src/components/Dashboard.tsx @@ -1,46 +1,126 @@ -import { useState, useEffect } from 'react'; +import React, { useState, useEffect } from 'react'; import Axios from 'axios'; import styles from '../styles/Dashboard.module.css'; -// import { accessAPI } from '../helpers/api'; - +import { useNavigate } from 'react-router-dom'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; function Dashboard() { - // Get the links from the API - const [links, setLinks] = useState([]); + 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<Link[]>([]); + const [logs, setLogs] = useState<Log[]>([]); + const [visibleLog, setVisibleLog] = useState<string | null>(null); + const navigate = useNavigate(); + + // Fetch links from API useEffect(() => { - Axios.get('/api/links') - .then((res) => { + Axios.get('/api/links').then((res) => { + if (res.status === 200) { setLinks(res.data); - }) - .catch((err) => { - console.log(err); - }); + } else { + navigate('/login'); + } + }).catch(() => { + navigate('/login'); + }); + }, []); + + // Fetch logs from API + useEffect(() => { + Axios.get('/api/logs').then((res) => { + if (res.status === 200) { + setLogs(res.data); + } else { + navigate('/login'); + } + }).catch(() => { + navigate('/login'); + }); }, []); + const toggleLogRow = (link: string) => { + setVisibleLog(visibleLog === link ? null : link); + }; + return ( - <div id={styles.container}> - <table> - <thead> - <tr style={{ border: '2px solid #ccc' }}> - <th>Link</th> - <th>Visits</th> - <th>Redirect</th> - <th>Expire Date</th> - </tr> - </thead> - <tbody> - {/* {links.map((link: any) => ( - <tr key={link.id}> - <td>{link.url}</td> - <td>{link.visits}</td> - <td>{link.redirect}</td> + <table id={styles.mainTable}> + <thead> + <tr style={{ border: '2px solid #ccc' }}> + <th>Link</th> + <th>Visits</th> + <th>Redirect</th> + <th>Expire Date</th> + </tr> + </thead> + <tbody> + {/* For every link and its logs */} + {links.map((link) => ( + <React.Fragment key={link.link}> + <tr className={styles.linkTableRow}> + <td> + <button onClick={() => toggleLogRow(link.link)} className={styles.linkButton}>{link.link}</button> + </td> + <td>{logs.filter((log) => log.link === link.link).length || 0}</td> + <td>{link.redirect_link}</td> <td>{link.expire_date}</td> </tr> - ))} */} - </tbody> - </table> - </div> + + {/* Conditionally render logs for this link */} + {visibleLog === link.link && ( + <tr className={styles.logTableRow}> + <td colSpan={6}> + <table> + <thead> + <tr> + <th>ID</th> + <th>Timestamp</th> + <th>IP</th> + <th>Location</th> + <th colSpan={2}>ISP</th> + </tr> + </thead> + <tbody> + {/* Render logs only if visibleLog matches the link */} + {logs + .filter((log) => log.link === link.link) + .map((log, index, filteredLogs) => ( + <tr key={log.id}> + <td>{filteredLogs.length - index}</td> + <td>{log.timestamp}</td> + <td>{log.ip}</td> + <td>{log.location}</td> + <td>{log.isp}</td> + <td><FontAwesomeIcon icon={faTrash} className={styles.trashBin}/></td> + </tr> + ))} + </tbody> + </table> + </td> + </tr> + )} + </React.Fragment> + ))} + </tbody> + </table> ) } diff --git a/app/src/styles/Dashboard.module.css b/app/src/styles/Dashboard.module.css index 042a2f1..ef6b451 100644 --- a/app/src/styles/Dashboard.module.css +++ b/app/src/styles/Dashboard.module.css @@ -5,15 +5,15 @@ body { background-color: #2c3338; } -#container { - display: flex; - justify-content: center; - margin-top: 100px; +#mainTable { + position: absolute; + top: 100px; + left: 50%; + transform: translateX(-50%); } - table { - margin: 20px 0 20px 0; + margin: 0 auto; text-align: center; font-size: 25px; width: 1000px; @@ -23,11 +23,11 @@ table { } /* Center all sub tables */ -.log-table-row table { +.logTableRow table { margin: 0 auto; } -.log-table-row table { +.logTableRow table { width: 90%; } @@ -37,7 +37,7 @@ table th { padding: 10px; } -.link-table-row { +.linkTableRow { border: 2px solid #ccc; } @@ -45,20 +45,20 @@ table td { padding: 10px; } -.link-table-row td { +.linkTableRow td { padding: 20px; } -.log-table-row table td { +.logTableRow table td { background-color: #3b4148; padding: 10px; } -.log-table-row table tr { +.logTableRow table tr { border: 2px solid #ccc; } -.link-button { +.linkButton { background-color: #3b4148; color: #ccc; border: none; @@ -68,7 +68,12 @@ table td { border-radius: 5px; } -.fa-trash:hover { +.trashBin:hover { color: rgb(238, 86, 86); cursor: pointer; + transition: color 0.2s ease; +} + +.trashBin:active { + transform: scale(0.95); }
\ No newline at end of file |