);
}
diff --git a/frontend/src/Register.jsx b/frontend/src/Register.jsx
index 7044f68..79678f9 100644
--- a/frontend/src/Register.jsx
+++ b/frontend/src/Register.jsx
@@ -3,13 +3,12 @@ import { Link, useNavigate } from "react-router-dom";
import api from "./api";
export default function Register({ onAuth }) {
- // form data
const [form, setForm] = useState({ username: "", email: "", password: "" });
- // error message
- const [err, setErr] = useState("");
+ const [err, setErr] = useState("");
const nav = useNavigate();
- // submit registration
+ const handle = (key) => (e) => setForm({ ...form, [key]: e.target.value });
+
const submit = async (e) => {
e.preventDefault();
try {
@@ -22,32 +21,21 @@ export default function Register({ onAuth }) {
};
return (
-
-
Register
- {err &&
{err}
}
-
-
- Already have an account? Login
-
+
+
+
Create account
+
+ {err &&
{err}
}
+
+
+
+
Already have an account? Log in
+
);
}
diff --git a/frontend/src/Tasks.jsx b/frontend/src/Tasks.jsx
index 98b4c48..1356cda 100644
--- a/frontend/src/Tasks.jsx
+++ b/frontend/src/Tasks.jsx
@@ -1,231 +1,187 @@
import { useState, useEffect } from "react";
import api from "./api";
+/* -------------------------------------------------- */
+/* Main component */
+/* -------------------------------------------------- */
export default function Tasks({ onLogout }) {
+ /* state */
const [tasks, setTasks] = useState([]);
- const [title, setTitle] = useState("");
- const [deadline, setDeadline] = useState("");
- const [importance, setImportance] = useState("2");
- const [difficulty, setDifficulty] = useState("3");
- const [editTaskId, setEditTaskId] = useState(null);
- const [editTaskText, setEditTaskText] = useState("");
-
-
- /* load tasks once */
+ const [form, setForm] = useState({
+ title: "",
+ deadline: "",
+ importance: "2",
+ difficulty: "3",
+ });
+ const [editId, setEditId] = useState(null);
+ const [editTxt, setEditTxt] = useState("");
+
+ /* load once */
useEffect(() => {
- api
- .get("/api/tasks")
- .then((res) => setTasks(res.data))
- .catch(console.error);
+ api.get("/api/tasks").then((r) => setTasks(r.data)).catch(console.error);
}, []);
- /* create new task */
- const add = async (e) => {
+ /* helpers */
+ const handleForm = (k) => (e) => setForm({ ...form, [k]: e.target.value });
+
+ const addTask = async (e) => {
e.preventDefault();
- if (!title.trim()) return;
+ if (!form.title.trim()) return;
try {
- const { data } = await api.post("/api/tasks", { title, deadline, importance, difficulty });
+ const { data } = await api.post("/api/tasks", form);
setTasks([data, ...tasks]);
- setTitle("");
- setDeadline("");
- setImportance("2");
- setDifficulty("3");
- } catch (err) {
- console.error(err);
- alert("Create failed");
+ setForm({ title: "", deadline: "", importance: "2", difficulty: "3" });
+ } catch {
+ alert("Failed to create task");
}
};
- /* delete a task */
- const remove = async (id) => {
+ const delTask = async (id) => {
try {
await api.delete(`/api/tasks/${id}`);
setTasks(tasks.filter((t) => t._id !== id));
- } catch (err) {
- console.error(err);
+ } catch {
alert("Delete failed");
}
};
- /* toggle task completion between 0 and 100 */
- const toggle = async (task) => {
- const newComp = task.completion === 100 ? 0 : 100;
+ const toggleComplete = async (t) => {
+ const newComp = t.completion === 100 ? 0 : 100;
try {
- const { data } = await api.put(`/api/tasks/${task._id}`, {
- ...task,
+ const { data } = await api.put(`/api/tasks/${t._id}`, {
+ ...t,
completion: newComp,
});
- setTasks(tasks.map((t) => (t._id === data._id ? data : t)));
- } catch (err) {
- console.error(err);
+ setTasks(tasks.map((task) => (task._id === data._id ? data : task)));
+ } catch {
alert("Update failed");
}
};
- const handleUpdateTask = async (id) => {
+ const saveEdit = async (id) => {
try {
- const { data } = await api.put(`/api/tasks/${id}`, {
- title: editTaskText,
- });
- const updated = tasks.map((t) => (t._id === data._id ? data : t));
- setTasks(updated);
- setEditTaskId(null);
- setEditTaskText("");
- } catch (err) {
- console.error(err);
- alert("Failed to update task.");
+ const { data } = await api.put(`/api/tasks/${id}`, { title: editTxt });
+ setTasks(tasks.map((t) => (t._id === data._id ? data : t)));
+ setEditId(null);
+ setEditTxt("");
+ } catch {
+ alert("Edit failed");
}
};
+ /* -------------------------------------------------- */
return (
-
-
-
Your Tasks
-
-
-
-
- {tasks.map((t) => {
- const diffMs = t.deadline ? new Date(t.deadline) - new Date() : null;
- const isOverdue = diffMs !== null && diffMs < 0 && t.completion !== 100;
-
- let dueText = "";
- if (t.deadline) {
- if (isOverdue) {
- dueText = "Overdue!";
- } else {
- const days = Math.floor(diffMs / 86400000);
- const hours = Math.floor((diffMs % 86400000) / 3600000);
- if (days === 0 && hours === 0) {
- dueText = "Due now";
- } else if (days === 0) {
- dueText = `Due in ${hours}h`;
- } else {
- dueText = `Due in ${days}d ${hours}h`;
+ <>
+ {/* top bar */}
+
+
+ {/* page content */}
+
+ Your Tasks
+
+ {/* new-task form */}
+
+
+ {/* task list */}
+
+ {tasks.map((t) => {
+ /* --- helpers per task --- */
+ const diffMs = t.deadline ? new Date(t.deadline) - new Date() : null;
+ const overdue = diffMs !== null && diffMs < 0 && t.completion !== 100;
+
+ let dueTxt = "";
+ if (t.deadline) {
+ if (overdue) dueTxt = "Overdue!";
+ else {
+ const d = Math.floor(diffMs / 86400000);
+ const h = Math.floor((diffMs % 86400000) / 3600000);
+ dueTxt = d === 0 && h === 0 ? "Due now"
+ : `Due in ${d ? d + "d " : ""}${h}h`;
}
}
- }
-
- let priorityLabel = "Low";
- let priorityColor = "green";
- if (t.score > 15) {
- priorityLabel = "High";
- priorityColor = "red";
- } else if (t.score > 8) {
- priorityLabel = "Medium";
- priorityColor = "orange";
- }
-
- return (
- -
- {/* completion checkbox */}
- toggle(t)}
- />
-
- {/* task title */}
- {editTaskId === t._id ? (
+
+ /* score → priority badge */
+ let pri = "Low", badge = "badge low";
+ if (t.score > 15) { pri = "High"; badge = "badge high"; }
+ else if (t.score > 8) { pri = "Med"; badge = "badge med"; }
+
+ return (
+
-
+ {/* complete toggle */}
setEditTaskText(e.target.value)}
- onKeyDown={(e) => {
- if (e.key === "Enter") handleUpdateTask(t._id);
- }}
- onBlur={() => setEditTaskId(null)}
- style={{
- flexGrow: 1,
- padding: "4px 8px",
- fontSize: "1rem",
- }}
- autoFocus
+ type="checkbox"
+ checked={t.completion === 100}
+ onChange={() => toggleComplete(t)}
/>
- ) : (
- {
- setEditTaskId(t._id);
- setEditTaskText(t.title);
- }}
- style={{
- flexGrow: 1,
- textDecoration:
- t.completion === 100 ? "line-through" : "none",
- opacity: t.completion === 100 ? 0.6 : 1,
- cursor: "pointer",
- userSelect: "none",
- }}
- >
- {t.title}
-
- )}
-
- {/* NEW: Priority Label */}
-
- ({priorityLabel})
-
-
- {/* due date display */}
- {t.deadline && (
- {dueText}
- )}
-
- {/* delete button */}
-
-
- );
- })}
-
-
+
+ {/* title or edit */}
+ {editId === t._id ? (
+
setEditTxt(e.target.value)}
+ onKeyDown={(e) => e.key === "Enter" && saveEdit(t._id)}
+ onBlur={() => setEditId(null)}
+ autoFocus
+ />
+ ) : (
+
{
+ setEditId(t._id);
+ setEditTxt(t.title);
+ }}
+ className={t.completion === 100 ? "strike" : ""}
+ >
+ {t.title}
+
+ )}
+
+ {/* meta row */}
+
+ {pri}
+ {t.deadline && {dueTxt}}
+
+
+ {/* delete */}
+
+
+ );
+ })}
+
+
+ >
);
}
-
-
-//GitHub testing to see if terminal works
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 08a3ac9..4460eb6 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -1,11 +1,15 @@
+/* ---- Global theme (light) ---- */
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
+
:root {
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+ font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
+ /* light mode by default */
+ color-scheme: light;
+ color: #0f172a; /* dark slate text */
+ background-color: #f8fafc; /* soft light background */
font-synthesis: none;
text-rendering: optimizeLegibility;
@@ -13,28 +17,25 @@
-moz-osx-font-smoothing: grayscale;
}
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
+/* ---- Elements ---- */
body {
- margin: 0;
- display: flex;
- place-items: center;
+ margin: 0; /* remove default margin */
+ /* remove the old flex + place-items that pushed content left */
min-width: 320px;
min-height: 100vh;
}
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
+a {
+ font-weight: 500;
+ color: #3b82f6;
+ text-decoration: none;
+}
+a:hover {
+ color: #2563eb;
}
+h1 { font-size: 3.2em; line-height: 1.1; }
+
button {
border-radius: 8px;
border: 1px solid transparent;
@@ -42,27 +43,23 @@ button {
font-size: 1em;
font-weight: 500;
font-family: inherit;
- background-color: #1a1a1a;
+ background-color: #1d4ed8;
+ color: #ffffff;
cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
+ transition: border-color 0.25s, background-color 0.25s;
}
+button:hover { background-color: #2563eb; }
button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
+button:focus-visible { outline: 4px auto -webkit-focus-ring-color; }
-@media (prefers-color-scheme: light) {
+/* ---- Dark-mode override ---- */
+@media (prefers-color-scheme: dark) {
:root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #1e293b; /* slate-900 */
}
+ a { color: #93c5fd; }
+ a:hover { color: #bfdbfe; }
+ button { background-color: #3b82f6; }
+ button:hover { background-color: #60a5fa; }
}