feat: Implement project search functionality and task management features
- Added search functionality to the Project List page, allowing users to filter projects by name, WP, plot, or investment number. - Created a new Project Tasks page to manage tasks across all projects, including filtering by status and priority. - Implemented task status updates and deletion functionality. - Added a new Task Template Edit page for modifying existing task templates. - Enhanced Task Template Form to include a description field and loading state during submission. - Updated UI components for better user experience, including badges for task status and priority. - Introduced new database queries for managing contracts and projects, including fetching tasks related to projects. - Added migrations to the database for new columns and improved data handling.
This commit is contained in:
15
src/app/api/all-project-tasks/route.js
Normal file
15
src/app/api/all-project-tasks/route.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { getAllProjectTasks } from "@/lib/queries/tasks";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
// GET: Get all project tasks across all projects
|
||||
export async function GET() {
|
||||
try {
|
||||
const tasks = getAllProjectTasks();
|
||||
return NextResponse.json(tasks);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch all project tasks" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
59
src/app/api/contracts/[id]/route.js
Normal file
59
src/app/api/contracts/[id]/route.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import db from "@/lib/db";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function GET(req, { params }) {
|
||||
const { id } = await params;
|
||||
|
||||
const contract = db
|
||||
.prepare(
|
||||
`
|
||||
SELECT * FROM contracts
|
||||
WHERE contract_id = ?
|
||||
`
|
||||
)
|
||||
.get(id);
|
||||
|
||||
if (!contract) {
|
||||
return NextResponse.json({ error: "Contract not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json(contract);
|
||||
}
|
||||
|
||||
export async function DELETE(req, { params }) {
|
||||
const { id } = params;
|
||||
|
||||
try {
|
||||
// Check if there are any projects linked to this contract
|
||||
const linkedProjects = db
|
||||
.prepare("SELECT COUNT(*) as count FROM projects WHERE contract_id = ?")
|
||||
.get(id);
|
||||
|
||||
if (linkedProjects.count > 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "Nie można usunąć umowy z przypisanymi projektami" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Delete the contract
|
||||
const result = db
|
||||
.prepare("DELETE FROM contracts WHERE contract_id = ?")
|
||||
.run(id);
|
||||
|
||||
if (result.changes === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "Contract not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error("Error deleting contract:", error);
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,17 @@ export async function GET() {
|
||||
const contracts = db
|
||||
.prepare(
|
||||
`
|
||||
SELECT contract_id, contract_number, contract_name FROM contracts
|
||||
`
|
||||
SELECT
|
||||
contract_id,
|
||||
contract_number,
|
||||
contract_name,
|
||||
customer,
|
||||
investor,
|
||||
date_signed,
|
||||
finish_date
|
||||
FROM contracts
|
||||
ORDER BY contract_number
|
||||
`
|
||||
)
|
||||
.all();
|
||||
return NextResponse.json(contracts);
|
||||
|
||||
@@ -5,8 +5,11 @@ import { NextResponse } from "next/server";
|
||||
// Make sure the DB is initialized before queries run
|
||||
initializeDatabase();
|
||||
|
||||
export async function GET() {
|
||||
const projects = getAllProjects();
|
||||
export async function GET(req) {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const contractId = searchParams.get("contract_id");
|
||||
|
||||
const projects = getAllProjects(contractId);
|
||||
return NextResponse.json(projects);
|
||||
}
|
||||
|
||||
|
||||
81
src/app/api/tasks/[id]/route.js
Normal file
81
src/app/api/tasks/[id]/route.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import db from "@/lib/db";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
// GET: Get a specific task template
|
||||
export async function GET(req, { params }) {
|
||||
try {
|
||||
const template = db
|
||||
.prepare("SELECT * FROM tasks WHERE task_id = ? AND is_standard = 1")
|
||||
.get(params.id);
|
||||
|
||||
if (!template) {
|
||||
return NextResponse.json(
|
||||
{ error: "Task template not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(template);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch task template" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT: Update a task template
|
||||
export async function PUT(req, { params }) {
|
||||
try {
|
||||
const { name, max_wait_days, description } = await req.json();
|
||||
|
||||
if (!name) {
|
||||
return NextResponse.json({ error: "Name is required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const result = db
|
||||
.prepare(
|
||||
`UPDATE tasks
|
||||
SET name = ?, max_wait_days = ?, description = ?
|
||||
WHERE task_id = ? AND is_standard = 1`
|
||||
)
|
||||
.run(name, max_wait_days || 0, description || null, params.id);
|
||||
|
||||
if (result.changes === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "Task template not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to update task template" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE: Delete a task template
|
||||
export async function DELETE(req, { params }) {
|
||||
try {
|
||||
const result = db
|
||||
.prepare("DELETE FROM tasks WHERE task_id = ? AND is_standard = 1")
|
||||
.run(params.id);
|
||||
|
||||
if (result.changes === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "Task template not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to delete task template" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { NextResponse } from "next/server";
|
||||
|
||||
// POST: create new template
|
||||
export async function POST(req) {
|
||||
const { name, max_wait_days } = await req.json();
|
||||
const { name, max_wait_days, description } = await req.json();
|
||||
|
||||
if (!name) {
|
||||
return NextResponse.json({ error: "Name is required" }, { status: 400 });
|
||||
@@ -11,10 +11,10 @@ export async function POST(req) {
|
||||
|
||||
db.prepare(
|
||||
`
|
||||
INSERT INTO tasks (name, max_wait_days, is_standard)
|
||||
VALUES (?, ?, 1)
|
||||
INSERT INTO tasks (name, max_wait_days, description, is_standard)
|
||||
VALUES (?, ?, ?, 1)
|
||||
`
|
||||
).run(name, max_wait_days || 0);
|
||||
).run(name, max_wait_days || 0, description || null);
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user