137 lines
4.2 KiB
TypeScript
137 lines
4.2 KiB
TypeScript
import { createClient } from "@supabase/supabase-js";
|
|
|
|
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
|
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY!;
|
|
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
|
|
// Matt's user ID
|
|
const MATT_USER_ID = "0a3e400c-3932-48ae-9b65-f3f9c6f26fe9";
|
|
const MAX_USER_ID = "9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa";
|
|
|
|
interface ParsedTask {
|
|
title: string;
|
|
description?: string;
|
|
assigneeId: string;
|
|
priority: "low" | "medium" | "high";
|
|
dueDate?: string;
|
|
projectId?: string;
|
|
}
|
|
|
|
export function parseTaskInput(input: string): ParsedTask {
|
|
const lower = input.toLowerCase();
|
|
|
|
// Extract assignee
|
|
let assigneeId = MATT_USER_ID;
|
|
if (lower.includes("assign to max") || lower.includes("for max")) {
|
|
assigneeId = MAX_USER_ID;
|
|
}
|
|
|
|
// Extract priority
|
|
let priority: "low" | "medium" | "high" = "medium";
|
|
if (lower.includes("urgent") || lower.includes("asap") || lower.includes("high priority")) {
|
|
priority = "high";
|
|
} else if (lower.includes("low priority") || lower.includes("whenever") || lower.includes("eventually")) {
|
|
priority = "low";
|
|
}
|
|
|
|
// Extract due date phrases
|
|
let dueDate: string | undefined;
|
|
const today = new Date();
|
|
|
|
if (lower.includes("tomorrow")) {
|
|
const d = new Date(today);
|
|
d.setDate(d.getDate() + 1);
|
|
dueDate = d.toISOString().split("T")[0];
|
|
} else if (lower.includes("next week")) {
|
|
const d = new Date(today);
|
|
d.setDate(d.getDate() + 7);
|
|
dueDate = d.toISOString().split("T")[0];
|
|
} else if (lower.includes("by friday") || lower.includes("this friday")) {
|
|
const d = new Date(today);
|
|
const daysUntilFriday = (5 - d.getDay() + 7) % 7 || 7;
|
|
d.setDate(d.getDate() + daysUntilFriday);
|
|
dueDate = d.toISOString().split("T")[0];
|
|
} else if (lower.includes("by monday") || lower.includes("this monday")) {
|
|
const d = new Date(today);
|
|
const daysUntilMonday = (1 - d.getDay() + 7) % 7 || 7;
|
|
d.setDate(d.getDate() + daysUntilMonday);
|
|
dueDate = d.toISOString().split("T")[0];
|
|
}
|
|
|
|
// Clean up the title - remove assignee/priority/due date phrases
|
|
let title = input
|
|
.replace(/assign to (max|matt)/gi, "")
|
|
.replace(/for (max|matt)/gi, "")
|
|
.replace(/urgent|asap|high priority|low priority/gi, "")
|
|
.replace(/tomorrow|next week|by friday|this friday|by monday|this monday/gi, "")
|
|
.replace(/\s+/g, " ")
|
|
.trim();
|
|
|
|
// If it starts with "add task" or similar, remove that
|
|
title = title.replace(/^(add|create|new)\s+(task|todo|item)\s*[:\-]?\s*/i, "");
|
|
|
|
// Capitalize first letter
|
|
title = title.charAt(0).toUpperCase() + title.slice(1);
|
|
|
|
return {
|
|
title,
|
|
assigneeId,
|
|
priority,
|
|
dueDate,
|
|
};
|
|
}
|
|
|
|
interface TaskResult {
|
|
id: string;
|
|
title: string;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export async function addTaskToGantt(input: string): Promise<{ success: boolean; task?: TaskResult; error?: string }> {
|
|
try {
|
|
const parsed = parseTaskInput(input);
|
|
|
|
// Get default project (first one) or use a specific project
|
|
const { data: projects } = await supabase
|
|
.from("projects")
|
|
.select("id")
|
|
.order("created_at", { ascending: true })
|
|
.limit(1);
|
|
|
|
const projectId = projects?.[0]?.id;
|
|
|
|
if (!projectId) {
|
|
return { success: false, error: "No projects found in gantt board" };
|
|
}
|
|
|
|
// Create the task
|
|
const { data: task, error } = await supabase
|
|
.from("tasks")
|
|
.insert({
|
|
title: parsed.title,
|
|
description: parsed.description || null,
|
|
status: "todo",
|
|
priority: parsed.priority,
|
|
assignee_id: parsed.assigneeId,
|
|
created_by: MATT_USER_ID,
|
|
project_id: projectId,
|
|
due_date: parsed.dueDate || null,
|
|
start_date: new Date().toISOString().split("T")[0],
|
|
end_date: parsed.dueDate || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split("T")[0],
|
|
})
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error("Error adding task:", error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
|
|
return { success: true, task };
|
|
} catch (err: unknown) {
|
|
console.error("Failed to add task:", err);
|
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
return { success: false, error: message };
|
|
}
|
|
}
|