From 918a04076fa582200cc5b5b542f6d7b47c0fa5e0 Mon Sep 17 00:00:00 2001 From: Parker Date: Mon, 11 Nov 2024 20:29:56 -0600 Subject: [PATCH] Fix formatting - mainly spacing --- app/.prettierrc | 6 + app/public/vite.svg | 1 - app/src/App.tsx | 26 ++-- app/src/components/Dashboard.tsx | 233 ++++++++++++++++--------------- app/src/components/Login.tsx | 151 ++++++++++---------- app/src/components/Signup.tsx | 189 +++++++++++++------------ app/src/helpers/api.js | 27 ---- app/src/main.tsx | 10 +- 8 files changed, 323 insertions(+), 320 deletions(-) create mode 100644 app/.prettierrc delete mode 100644 app/public/vite.svg delete mode 100644 app/src/helpers/api.js diff --git a/app/.prettierrc b/app/.prettierrc new file mode 100644 index 0000000..0205ecf --- /dev/null +++ b/app/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5" +} \ No newline at end of file diff --git a/app/public/vite.svg b/app/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/app/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/src/App.tsx b/app/src/App.tsx index 14fa571..858ad44 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,18 +1,18 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; -import Login from './components/Login' -import Signup from './components/Signup' -import Dashboard from './components/Dashboard' +import Login from './components/Login'; +import Signup from './components/Signup'; +import Dashboard from './components/Dashboard'; function App() { - return ( - - - } /> - } /> - } /> - - - ) + return ( + + + } /> + } /> + } /> + + + ); } -export default App +export default App; diff --git a/app/src/components/Dashboard.tsx b/app/src/components/Dashboard.tsx index ccbfd99..851308e 100644 --- a/app/src/components/Dashboard.tsx +++ b/app/src/components/Dashboard.tsx @@ -6,124 +6,139 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; function Dashboard() { - document.title = 'LinkLogger | 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 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; - } + 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(); + 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(() => { - navigate('/login'); - }); - }, []); + // Fetch links from API + useEffect(() => { + Axios.get('/api/links') + .then((res) => { + if (res.status === 200) { + setLinks(res.data); + } 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'); - }); - }, []); + // 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); + }; - const toggleLogRow = (link: string) => { - setVisibleLog(visibleLog === link ? null : link); - }; + return ( + + + + + + + + + + + {/* For every link and its logs */} + {links.map((link) => ( + + + + + + + - return ( -
LinkVisitsRedirectExpire Date
+ + + {logs.filter((log) => log.link === link.link).length || 0} + {link.redirect_link}{link.expire_date}
- - - - - - - - - - {/* For every link and its logs */} - {links.map((link) => ( - - + {/* Conditionally render logs for this link */} + {visibleLog === link.link && ( + + + ))} + +
LinkVisitsRedirectExpire Date
+ + + + + + + + + + + + {/* Render logs only if visibleLog matches the link */} + {logs + .filter((log) => log.link === link.link) + .map((log, index, filteredLogs) => ( + + + + + + - - - - - - {/* Conditionally render logs for this link */} - {visibleLog === link.link && ( - - - - )} - - ))} - -
IDTimestampIPLocationISP
{filteredLogs.length - index}{log.timestamp}{log.ip}{log.location}{log.isp} - + {logs.filter((log) => log.link === link.link).length || 0}{link.redirect_link}{link.expire_date}
- - - - - - - - - - - - {/* Render logs only if visibleLog matches the link */} - {logs - .filter((log) => log.link === link.link) - .map((log, index, filteredLogs) => ( - - - - - - - - - ))} - -
IDTimestampIPLocationISP
{filteredLogs.length - index}{log.timestamp}{log.ip}{log.location}{log.isp}
-
- ) +
+ + + )} + + ))} + + + ); } -export default Dashboard; \ No newline at end of file +export default Dashboard; diff --git a/app/src/components/Login.tsx b/app/src/components/Login.tsx index a3e5cf9..2a81295 100644 --- a/app/src/components/Login.tsx +++ b/app/src/components/Login.tsx @@ -5,82 +5,87 @@ import { useNavigate } from 'react-router-dom'; import axios from 'axios'; function Login() { - document.title = 'LinkLogger | Login' + document.title = 'LinkLogger | Login'; - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [isSubmitting, setIsSubmitting] = useState(false); - const [error, setError] = useState(null); - const navigate = useNavigate(); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); + const navigate = useNavigate(); - const handleSubmit = async (e: FormEvent) => { - e.preventDefault(); - setIsSubmitting(true); - try { - const res = await axios.post( - '/api/auth/token', - new URLSearchParams({ - username: username, - password: password, - }), - { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - } - ); - - if (res.status === 200) { - navigate('/dashboard'); - } - } catch (error: unknown) { - if (axios.isAxiosError(error)) { - const customErrorMessage = error.response?.data?.detail || null; - setPassword(''); - setError(customErrorMessage || 'An error occurred. Please try again.'); - } else { - setPassword(''); - setError('Unknown error. Please try again.'); - } - } finally { - setIsSubmitting(false); + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + try { + const res = await axios.post( + '/api/auth/token', + new URLSearchParams({ + username: username, + password: password, + }), + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, } - }; + ); - return ( -
-

Log In

-

- {error} -

-
-
-
-
- setUsername(e.target.value)} - required - /> - setPassword(e.target.value)} - required - /> - -
-
-

Don't have an account? Create one now

-
-
-
- ); + if (res.status === 200) { + navigate('/dashboard'); + } + } catch (error: unknown) { + if (axios.isAxiosError(error)) { + const customErrorMessage = error.response?.data?.detail || null; + setPassword(''); + setError(customErrorMessage || 'An error occurred. Please try again.'); + } else { + setPassword(''); + setError('Unknown error. Please try again.'); + } + } finally { + setIsSubmitting(false); + } + }; + + return ( +
+

Log In

+

+ {error} +

+
+
+
+
+ setUsername(e.target.value)} + required + /> + setPassword(e.target.value)} + required + /> + +
+
+

+ Don't have an account?{' '} + + Create one now + +

+
+
+
+ ); } -export default Login; \ No newline at end of file +export default Login; diff --git a/app/src/components/Signup.tsx b/app/src/components/Signup.tsx index 547fa9e..388396c 100644 --- a/app/src/components/Signup.tsx +++ b/app/src/components/Signup.tsx @@ -5,104 +5,109 @@ import { useNavigate } from 'react-router-dom'; import axios from 'axios'; function Signup() { - document.title = 'LinkLogger | Signup' + document.title = 'LinkLogger | Signup'; - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [passwordConfirm, setPasswordConfirm] = useState(''); - const [isSubmitting, setIsSubmitting] = useState(false); - const [error, setError] = useState(null); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [passwordConfirm, setPasswordConfirm] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); - const navigate = useNavigate(); + const navigate = useNavigate(); - const handleSubmit = async (e: FormEvent) => { - e.preventDefault(); - setIsSubmitting(true); + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); - if (password !== passwordConfirm) { - setPassword(''); - setPasswordConfirm(''); - return setError('Passwords do not match.'); + if (password !== passwordConfirm) { + setPassword(''); + setPasswordConfirm(''); + return setError('Passwords do not match.'); + } + + try { + const res = await axios.post( + '/api/users/register', + new URLSearchParams({ + username: username, + password: password, + }), + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, } + ); - try { - const res = await axios.post( - '/api/users/register', - new URLSearchParams({ - username: username, - password: password, - }), - { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - } - ); + if (res.status === 200) { + navigate('/login'); + } + } catch (error: unknown) { + if (axios.isAxiosError(error)) { + const customErrorMessage = error.response?.data?.detail || null; + setUsername(''); + setPassword(''); + setPasswordConfirm(''); + setError(customErrorMessage || 'An error occurred. Please try again.'); + } else { + setUsername(''); + setPassword(''); + setPasswordConfirm(''); + setError('Unknown error. Please try again.'); + } + } finally { + setIsSubmitting(false); + } + }; - if (res.status === 200) { - navigate('/login'); - } - } catch (error: unknown) { - if (axios.isAxiosError(error)) { - const customErrorMessage = error.response?.data?.detail || null; - setUsername(''); - setPassword(''); - setPasswordConfirm(''); - setError(customErrorMessage || 'An error occurred. Please try again.'); - } else { - setUsername(''); - setPassword(''); - setPasswordConfirm(''); - setError('Unknown error. Please try again.'); - } - } finally { - setIsSubmitting(false); - } - }; - - return ( -
-

Sign up

-

- {error} -

-
-
-
-
- setUsername(e.target.value)} - required - /> - setPassword(e.target.value)} - required - /> - setPasswordConfirm(e.target.value)} - required - /> - -
-
-

Already have an account? Log in here.

-
-
-
- ); + return ( +
+

Sign up

+

+ {error} +

+
+
+
+
+ setUsername(e.target.value)} + required + /> + setPassword(e.target.value)} + required + /> + setPasswordConfirm(e.target.value)} + required + /> + +
+
+

+ Already have an account?{' '} + + Log in here. + +

+
+
+
+ ); } -export default Signup; \ No newline at end of file +export default Signup; diff --git a/app/src/helpers/api.js b/app/src/helpers/api.js deleted file mode 100644 index 0381f18..0000000 --- a/app/src/helpers/api.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Accept an API endpoint, method, and body to send to the API. - * - If successful, return the response - * - If not, return false - * @param {*} endpoint API endpoint - * @param {*} method String (GET, POST, PUT, DELETE) - * @param {*} body Data to send to the API - * @returns response.json or false - */ -async function accessAPI(endpoint, method, body) { - let response = await fetch(`http://127.0.0.1:5252/api${endpoint}`, { - method: method, - credentials: 'include', - body: body, - }); - - if (response.ok) { - let data = await response.json(); - data = await data; - return data; - - } - - return false; -} - -export { accessAPI }; \ No newline at end of file diff --git a/app/src/main.tsx b/app/src/main.tsx index 4aff025..3a8bd35 100644 --- a/app/src/main.tsx +++ b/app/src/main.tsx @@ -1,9 +1,9 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import App from './App.tsx' +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import App from './App.tsx'; createRoot(document.getElementById('root')!).render( - , -) + +);