feat: Implement task notes functionality with CRUD operations and integrate into project tasks section

This commit is contained in:
Chop
2025-06-03 20:46:37 +02:00
parent a9afebdda5
commit 330744daf9
9 changed files with 309 additions and 20 deletions

View File

@@ -0,0 +1,73 @@
import {
getNotesByTaskId,
addNoteToTask,
deleteNote,
} from "@/lib/queries/notes";
import { NextResponse } from "next/server";
// GET: Get notes for a specific task
export async function GET(req) {
const { searchParams } = new URL(req.url);
const taskId = searchParams.get("task_id");
if (!taskId) {
return NextResponse.json({ error: "task_id is required" }, { status: 400 });
}
try {
const notes = getNotesByTaskId(taskId);
return NextResponse.json(notes);
} catch (error) {
console.error("Error fetching task notes:", error);
return NextResponse.json(
{ error: "Failed to fetch task notes" },
{ status: 500 }
);
}
}
// POST: Add a note to a task
export async function POST(req) {
try {
const { task_id, note } = await req.json();
if (!task_id || !note) {
return NextResponse.json(
{ error: "task_id and note are required" },
{ status: 400 }
);
}
addNoteToTask(task_id, note);
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error adding task note:", error);
return NextResponse.json(
{ error: "Failed to add task note" },
{ status: 500 }
);
}
}
// DELETE: Delete a note
export async function DELETE(req) {
try {
const { searchParams } = new URL(req.url);
const noteId = searchParams.get("note_id");
if (!noteId) {
return NextResponse.json(
{ error: "note_id is required" },
{ status: 400 }
);
}
deleteNote(noteId);
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error deleting note:", error);
return NextResponse.json(
{ error: "Failed to delete note" },
{ status: 500 }
);
}
}

View File

@@ -1,7 +1,8 @@
import ProjectForm from "@/components/ProjectForm";
export default async function EditProjectPage({ params }) {
const res = await fetch(`http://localhost:3000/api/projects/${params.id}`, {
const { id } = await params;
const res = await fetch(`http://localhost:3000/api/projects/${id}`, {
cache: "no-store",
});
const project = await res.json();

View File

@@ -13,8 +13,9 @@ import PageContainer from "@/components/ui/PageContainer";
import PageHeader from "@/components/ui/PageHeader";
export default async function ProjectViewPage({ params }) {
const project = getProjectWithContract(params.id);
const notes = getNotesForProject(params.id);
const { id } = await params;
const project = getProjectWithContract(id);
const notes = getNotesForProject(id);
const daysRemaining = differenceInCalendarDays(
parseISO(project.finish_date),
new Date()
@@ -70,8 +71,8 @@ export default async function ProjectViewPage({ params }) {
</svg>
Back to Projects
</Button>
</Link>
<Link href={`/projects/${params.id}/edit`}>
</Link>{" "}
<Link href={`/projects/${id}/edit`}>
<Button variant="secondary">Edit Project</Button>
</Link>
</div>
@@ -142,7 +143,6 @@ export default async function ProjectViewPage({ params }) {
)}
</CardContent>
</Card>
<Card>
<CardHeader>
<h2 className="text-xl font-semibold text-gray-900">
@@ -175,10 +175,10 @@ export default async function ProjectViewPage({ params }) {
<p className="text-gray-900">{project.investor}</p>
</div>
</CardContent>
</Card>
</Card>{" "}
</div>
<ProjectTasksSection projectId={params.id} />
<ProjectTasksSection projectId={id} />
<Card>
<CardHeader>
@@ -186,7 +186,7 @@ export default async function ProjectViewPage({ params }) {
</CardHeader>
<CardContent>
<div className="mb-6">
<NoteForm projectId={params.id} />
<NoteForm projectId={id} />
</div>
{notes.length === 0 ? (
<div className="text-center py-8">

View File

@@ -6,10 +6,11 @@ import Button from "@/components/ui/Button";
import TaskTemplateForm from "@/components/TaskTemplateForm";
export default async function EditTaskTemplatePage({ params }) {
const { id } = await params;
// Fetch the task template
const template = db
.prepare("SELECT * FROM tasks WHERE task_id = ? AND is_standard = 1")
.get(params.id);
.get(id);
if (!template) {
notFound();