Files
coms3011a-lab1/app/dashboard/page.tsx
2026-08-04 03:36:02 +02:00

202 lines
4.1 KiB
TypeScript

"use client";
import { useState } from "react";
export default function Dashboard() {
const [tasks, setTasks] = useState({
todo: [
{
title: "Finish lab",
description: "Complete physics lab report",
dueDate: "2026-08-10",
topic: "Physics",
},
{
title: "Study Next.js",
description: "Learn routing and layouts",
dueDate: "2026-08-08",
topic: "Coding",
},
],
inProgress: [],
done: [],
});
const addTask = () => {
const title = prompt("Task title:");
if (!title) return;
const description = prompt("Description:") || "";
const dueDate = prompt("Due date (YYYY-MM-DD):") || "";
const topic = prompt("Topic:") || "";
const newTask = { title, description, dueDate, topic };
setTasks((prev) => ({
...prev,
todo: [...prev.todo, newTask],
}));
};
return (
<main style={styles.container}>
<h1 style={styles.title}>Planner Danner</h1>
<div style={styles.board}>
<Column title="To Do" tasks={tasks.todo} onAdd={addTask} />
<Column title="In Progress" tasks={tasks.inProgress} />
<Column title="Done" tasks={tasks.done} />
</div>
</main>
);
}
function Column({
title,
tasks,
onAdd,
}: {
title: string;
tasks: any[];
onAdd?: () => void;
}) {
return (
<div style={styles.column}>
<div style={styles.columnHeader}>
<h2 style={styles.columnTitle}>{title}</h2>
<div style={styles.headerActions}>
{onAdd && (
<button onClick={onAdd} style={styles.iconButton}>
+
</button>
)}
{/* ✅ FIXED: sort now uses SAME button style */}
<button style={styles.iconButton}></button>
<button style={styles.iconButton}></button>
</div>
</div>
{tasks.map((task, index) => (
<div key={index} style={styles.card}>
<div style={styles.cardHeader}>
<div style={styles.cardTitle}>{task.title}</div>
{/* same exact style */}
<button style={styles.iconButton}></button>
</div>
<div style={styles.cardDescription}>
{task.description.slice(0, 30)}
{task.description.length > 30 && "..."}
</div>
<div style={styles.cardDate}>📅 {task.dueDate}</div>
</div>
))}
</div>
);
}
const styles = {
container: {
minHeight: "100vh",
background: "linear-gradient(to bottom, #38bdf8, #0ea5e9)",
padding: "30px",
},
title: {
textAlign: "center" as const,
fontSize: "90px",
fontWeight: "900",
color: "white",
letterSpacing: "2px",
textShadow: `
0 4px 0 #0284c7,
0 8px 20px rgba(0,0,0,0.2)
`,
marginBottom: "30px",
},
board: {
display: "flex",
gap: "20px",
justifyContent: "center",
},
column: {
background: "#f8fafc",
padding: "15px",
borderRadius: "12px",
flex: 1,
minHeight: "65vh",
maxHeight: "65vh",
overflowY: "auto",
boxShadow: "0 10px 25px rgba(0,0,0,0.1)",
},
columnHeader: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "15px",
},
columnTitle: {
color: "#0f172a",
fontWeight: "700",
fontSize: "25px",
margin: 0,
},
/* ✅ SINGLE SOURCE OF TRUTH FOR ALL ICONS */
iconButton: {
background: "transparent",
border: "none",
color: "#0f172a",
fontSize: "22px",
fontWeight: "600",
cursor: "pointer",
padding: "0",
},
headerActions: {
display: "flex",
gap: "10px",
alignItems: "center",
},
card: {
background: "#dae4f0",
padding: "18px",
borderRadius: "12px",
marginBottom: "15px",
color: "#0f172a",
fontSize: "16px",
},
cardHeader: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "6px",
},
cardTitle: {
fontWeight: "700",
marginBottom: "6px",
},
cardDescription: {
fontSize: "13px",
opacity: 0.7,
marginBottom: "8px",
},
cardDate: {
fontSize: "12px",
opacity: 0.6,
},
};