aboutsummaryrefslogtreecommitdiff
path: root/app/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/components')
-rw-r--r--app/src/components/Dashboard.tsx42
-rw-r--r--app/src/components/Login.tsx66
-rw-r--r--app/src/components/Navbar.tsx56
-rw-r--r--app/src/components/Signup.tsx84
4 files changed, 149 insertions, 99 deletions
diff --git a/app/src/components/Dashboard.tsx b/app/src/components/Dashboard.tsx
index e16c44e..f3442e0 100644
--- a/app/src/components/Dashboard.tsx
+++ b/app/src/components/Dashboard.tsx
@@ -47,10 +47,7 @@ function Dashboard() {
.catch((error: unknown) => {
if (axios.isAxiosError(error)) {
- if (error.response?.status === 404) {
- // Create a message alerting the user there are no links
- navigate('/login');
- } else {
+ if (error.response?.status != 404) {
navigate('/login');
}
}
@@ -68,11 +65,12 @@ function Dashboard() {
navigate('/login');
}
})
-
- // Catch 404 error = user has no logs
-
- .catch(() => {
- navigate('/login');
+ .catch((error: unknown) => {
+ if (axios.isAxiosError(error)) {
+ if (error.response?.status != 404) {
+ navigate('/login');
+ }
+ }
});
}, []);
@@ -117,7 +115,7 @@ function Dashboard() {
return (
<>
<Navbar />
- <table id={styles.mainTable}>
+ <table className={styles.mainTable}>
<thead>
<tr style={{ border: '2px solid #ccc' }}>
<th>Link</th>
@@ -127,6 +125,17 @@ function Dashboard() {
</tr>
</thead>
<tbody>
+ {/* If there are no links, put a special message */}
+ {links.length === 0 && (
+ <tr>
+ <td colSpan={4}>
+ <div className={styles.noLinks}>
+ You do not have any shortened links - try creating one.
+ </div>
+ </td>
+ </tr>
+ )}
+
{/* For every link and its logs */}
{links.map((link) => (
<React.Fragment key={link.link}>
@@ -161,7 +170,7 @@ function Dashboard() {
</tr>
</thead>
<tbody>
- {/* Render logs only if visibleLog matches the link */}
+ {/* Render all logs for the link */}
{logs
.filter((log) => log.link === link.link)
.map((log, index, filteredLogs) => (
@@ -181,6 +190,17 @@ function Dashboard() {
</td>
</tr>
))}
+ {/* If the link has no logs, put a special message */}
+ {logs.filter((log) => log.link === link.link).length ===
+ 0 && (
+ <tr>
+ <td colSpan={6}>
+ <div className={styles.noLogs}>
+ No logs for this link
+ </div>
+ </td>
+ </tr>
+ )}
</tbody>
</table>
</td>
diff --git a/app/src/components/Login.tsx b/app/src/components/Login.tsx
index 807face..badb5b1 100644
--- a/app/src/components/Login.tsx
+++ b/app/src/components/Login.tsx
@@ -1,5 +1,5 @@
import { useState, FormEvent } from 'react';
-import styles from '../styles/Login.module.css';
+import styles from '../styles/Auth.module.css';
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';
@@ -51,42 +51,36 @@ function Login() {
return (
<>
<Navbar />
- <div id={styles.container}>
- <p id={styles.loginText}>Log In</p>
- <p id={styles.error} className={error ? 'visible' : 'hidden'}>
- {error}
+ <div className={styles.container}>
+ <h1>Log In</h1>
+ <h2 className={error ? 'errorVisible' : 'errorHidden'}>{error}</h2>
+ <hr></hr>
+ <form onSubmit={handleSubmit}>
+ <input
+ type="text"
+ placeholder="username"
+ value={username}
+ onChange={(e) => setUsername(e.target.value)}
+ required
+ />
+ <input
+ type="password"
+ placeholder="password"
+ value={password}
+ onChange={(e) => setPassword(e.target.value)}
+ required
+ />
+ <button type="submit" disabled={isSubmitting}>
+ {isSubmitting ? 'Submitting...' : 'Submit'}
+ </button>
+ </form>
+ <hr></hr>
+ <p className={styles.footnote}>
+ Don't have an account?{' '}
+ <Link to="/signup" className={styles.footnoteLink}>
+ Create one now
+ </Link>
</p>
- <div>
- <header>
- <hr></hr>
- <form onSubmit={handleSubmit}>
- <input
- type="text"
- placeholder="username"
- value={username}
- onChange={(e) => setUsername(e.target.value)}
- required
- />
- <input
- type="password"
- placeholder="password"
- value={password}
- onChange={(e) => setPassword(e.target.value)}
- required
- />
- <button type="submit" disabled={isSubmitting}>
- {isSubmitting ? 'Submitting...' : 'Submit'}
- </button>
- </form>
- <hr></hr>
- <p id={styles.bottomText}>
- Don't have an account?{' '}
- <Link to="/signup" className={styles.link}>
- Create one now
- </Link>
- </p>
- </header>
- </div>
</div>
</>
);
diff --git a/app/src/components/Navbar.tsx b/app/src/components/Navbar.tsx
index 5107bf4..53c1f52 100644
--- a/app/src/components/Navbar.tsx
+++ b/app/src/components/Navbar.tsx
@@ -1,21 +1,63 @@
+import { useState, useEffect } from 'react';
import styles from '../styles/Navbar.module.css';
import { Link } from 'react-router-dom';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCircleUp, faCircleDown } from '@fortawesome/free-solid-svg-icons';
function Navbar() {
+ const [isOnline, setIsOnline] = useState<boolean | null>(null);
+
+ useEffect(() => {
+ const checkAPIStatus = async () => {
+ try {
+ const res = await fetch('/api/ping');
+
+ if (res.status === 200) {
+ setIsOnline(true);
+ } else {
+ setIsOnline(false);
+ }
+ } catch (error) {
+ setIsOnline(false);
+ }
+ };
+
+ checkAPIStatus();
+ });
+
return (
<div className={styles.navbar}>
- <div className={styles.navbarLeft}>
+ <div className={styles.left}>
<Link to={'/login'}>
- <a className={styles.navbarLink}>Login</a>
+ <a className={styles.link}>Login</a>
</Link>
<Link to={'/signup'}>
- <a className={styles.navbarLink}>Signup</a>
+ <a className={styles.link}>Signup</a>
</Link>
</div>
- <div className={styles.navbarRight}>
- <Link to={'/status'}>
- <a className={styles.navbarLink}>API Status</a>
- </Link>
+ <div className={styles.right}>
+ <a
+ className={styles.link}
+ title={
+ isOnline === null
+ ? 'Loading...'
+ : isOnline
+ ? 'API is online'
+ : 'API is offline'
+ }
+ >
+ API Status:{' '}
+ {isOnline === null ? (
+ 'Loading...'
+ ) : isOnline ? (
+ <FontAwesomeIcon icon={faCircleUp} className={styles.circleUp} />
+ ) : (
+ <FontAwesomeIcon
+ icon={faCircleDown}
+ className={styles.circleDown}
+ />
+ )}
+ </a>
</div>
</div>
);
diff --git a/app/src/components/Signup.tsx b/app/src/components/Signup.tsx
index 5ec2e17..f4a3368 100644
--- a/app/src/components/Signup.tsx
+++ b/app/src/components/Signup.tsx
@@ -1,5 +1,5 @@
import { useState, FormEvent } from 'react';
-import styles from '../styles/Login.module.css';
+import styles from '../styles/Auth.module.css';
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';
@@ -64,51 +64,45 @@ function Signup() {
return (
<>
<Navbar />
- <div id={styles.container}>
- <p id={styles.signupText}>Sign up</p>
- <p id={styles.error} className={error ? 'visible' : 'hidden'}>
- {error}
+ <div className={styles.container}>
+ <h1>Sign up</h1>
+ <h2 className={error ? 'errorVisible' : 'errorHidden'}>{error}</h2>
+ <hr></hr>
+ <form onSubmit={handleSubmit}>
+ <input
+ type="text"
+ placeholder="username"
+ value={username}
+ onChange={(e) => setUsername(e.target.value)}
+ required
+ />
+ <input
+ type="password"
+ placeholder="password"
+ value={password}
+ minLength={8}
+ onChange={(e) => setPassword(e.target.value)}
+ required
+ />
+ <input
+ type="password"
+ placeholder="confirm password"
+ value={passwordConfirm}
+ minLength={8}
+ onChange={(e) => setPasswordConfirm(e.target.value)}
+ required
+ />
+ <button type="submit" disabled={isSubmitting}>
+ {isSubmitting ? 'Submitting...' : 'Submit'}
+ </button>
+ </form>
+ <hr></hr>
+ <p className={styles.footnote}>
+ Already have an account?{' '}
+ <Link to="/login" className={styles.footnoteLink}>
+ Log in here.
+ </Link>
</p>
- <div>
- <header>
- <hr></hr>
- <form onSubmit={handleSubmit}>
- <input
- type="text"
- placeholder="username"
- value={username}
- onChange={(e) => setUsername(e.target.value)}
- required
- />
- <input
- type="password"
- placeholder="password"
- value={password}
- minLength={8}
- onChange={(e) => setPassword(e.target.value)}
- required
- />
- <input
- type="password"
- placeholder="confirm password"
- value={passwordConfirm}
- minLength={8}
- onChange={(e) => setPasswordConfirm(e.target.value)}
- required
- />
- <button type="submit" disabled={isSubmitting}>
- {isSubmitting ? 'Submitting...' : 'Submit'}
- </button>
- </form>
- <hr></hr>
- <p id={styles.bottomText}>
- Already have an account?{' '}
- <Link to="/login" className={styles.link}>
- Log in here.
- </Link>
- </p>
- </header>
- </div>
</div>
</>
);