working leantime widget 37

This commit is contained in:
Alma 2025-04-12 14:32:25 +02:00
parent 2b4958506a
commit 9ef9f79e32

View File

@ -1,16 +1,19 @@
import { NextRequest } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { NextResponse } from "next/server";
interface Task {
interface StatusLabel {
id: string;
headline: string;
projectName: string;
projectId: number;
status: string;
dueDate: string | null;
milestone: string | null;
details: string | null;
name: string;
statusType: string;
class: string;
}
interface Project {
id: string;
name: string;
labels: StatusLabel[];
}
// Cache for user IDs to avoid repeated lookups
@ -37,7 +40,6 @@ async function getLeantimeUserId(email: string): Promise<number | null> {
});
if (!response.ok) {
console.error('Failed to fetch users from Leantime:', response.status, response.statusText);
throw new Error('Failed to fetch users from Leantime');
}
@ -52,7 +54,6 @@ async function getLeantimeUserId(email: string): Promise<number | null> {
return user.id;
}
console.error('User not found in Leantime:', email);
return null;
} catch (error) {
console.error('Error getting Leantime user ID:', error);
@ -60,22 +61,18 @@ async function getLeantimeUserId(email: string): Promise<number | null> {
}
}
export async function GET() {
export async function GET(request: NextRequest) {
try {
const session = await getServerSession(authOptions);
console.log('Session in tasks route:', session);
if (!session || !session.user?.email) {
console.error('Unauthorized: No session or email found');
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Get Leantime user ID
const leantimeUserId = await getLeantimeUserId(session.user.email);
console.log('Leantime user ID:', leantimeUserId);
if (!leantimeUserId) {
console.error('User not found in Leantime:', session.user.email);
return NextResponse.json({ error: "User not found in Leantime" }, { status: 404 });
}
@ -99,15 +96,13 @@ export async function GET() {
});
if (!response.ok) {
console.error('Failed to fetch tasks from Leantime:', response.status, response.statusText);
throw new Error('Failed to fetch tasks from Leantime');
}
const data = await response.json();
console.log('Tasks response:', data);
if (!data.result) {
return NextResponse.json({ tasks: [] });
return NextResponse.json({ projects: [] });
}
// Get project details to include project names
@ -125,43 +120,71 @@ export async function GET() {
});
if (!projectsResponse.ok) {
console.error('Failed to fetch projects from Leantime:', projectsResponse.status, projectsResponse.statusText);
throw new Error('Failed to fetch projects from Leantime');
}
const projectsData = await projectsResponse.json();
const projectsMap = new Map(
projectsData.result.map((project: any) => [project.id, project.name])
);
// Transform and sort the tasks
const tasks = data.result.map((task: any) => {
const dueDate = task.dateToFinish ? new Date(task.dateToFinish * 1000).toISOString() : null;
// Create a map of projects with their tasks grouped by status
const projectMap = new Map<string, Project>();
data.result.forEach((task: any) => {
const project = projectsData.result.find((p: any) => p.id === task.projectId);
const projectName = project ? project.name : `Project ${task.projectId}`;
const projectId = task.projectId.toString();
if (!projectMap.has(projectId)) {
projectMap.set(projectId, {
id: projectId,
name: projectName,
labels: []
});
}
const currentProject = projectMap.get(projectId)!;
return {
id: task.id,
headline: task.headline,
projectName: projectsMap.get(task.projectId) || `Project ${task.projectId}`,
projectId: task.projectId,
status: task.status,
dueDate: dueDate,
milestone: task.milestoneid || null,
details: task.description || null
};
// Check if this status label already exists for this project
const existingLabel = currentProject.labels.find(label => label.name === task.status);
if (!existingLabel) {
let statusType;
let statusClass;
switch (task.status.toLowerCase()) {
case 'new':
statusType = 'NEW';
statusClass = 'bg-blue-100 text-blue-800';
break;
case 'in_progress':
statusType = 'INPROGRESS';
statusClass = 'bg-yellow-100 text-yellow-800';
break;
case 'done':
statusType = 'DONE';
statusClass = 'bg-green-100 text-green-800';
break;
default:
statusType = 'NONE';
statusClass = 'bg-gray-100 text-gray-800';
}
currentProject.labels.push({
id: `${projectId}-${task.status}`,
name: task.status,
statusType: statusType,
class: statusClass
});
}
});
// Sort tasks by due date (overdue first)
tasks.sort((a: Task, b: Task) => {
if (!a.dueDate) return 1;
if (!b.dueDate) return -1;
return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime();
});
// Convert the map to an array and sort projects by name
const projects = Array.from(projectMap.values()).sort((a, b) => a.name.localeCompare(b.name));
return NextResponse.json({ tasks });
return NextResponse.json({ projects });
} catch (error) {
console.error('Error in tasks route:', error);
console.error('Error fetching status labels:', error);
return NextResponse.json(
{ error: "Failed to fetch tasks" },
{ error: "Failed to fetch status labels" },
{ status: 500 }
);
}