Files

115 lines
3.1 KiB
TypeScript

"use client";
import { createContext, useContext, useState, useEffect, ReactNode } from "react";
import { Task, TaskStatus, initialTasks } from "./types";
interface MissionControlStore {
tasks: Task[];
toggleTask: (id: string) => void;
updateTaskStatus: (id: string, status: TaskStatus) => void;
addTask: (task: Omit<Task, "id" | "order">) => void;
getProjectProgress: (projectId: string) => number;
getTasksByProject: (projectId: string) => Task[];
}
const MissionControlContext = createContext<MissionControlStore | null>(null);
const STORAGE_KEY = "sitemente:mission-control";
export function MissionControlProvider({ children }: { children: ReactNode }) {
const [tasks, setTasks] = useState<Task[]>(initialTasks);
// Load from localStorage on mount
useEffect(() => {
if (typeof window === "undefined") return;
const saved = localStorage.getItem(STORAGE_KEY);
if (saved) {
try {
const parsed = JSON.parse(saved);
if (Array.isArray(parsed) && parsed.length > 0) {
setTasks(parsed);
}
} catch {
// Use default
}
}
}, []);
// Save to localStorage on change
useEffect(() => {
if (typeof window === "undefined") return;
localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
}, [tasks]);
const toggleTask = (id: string) => {
setTasks((prev) =>
prev.map((t) => {
if (t.id !== id) return t;
const newStatus: TaskStatus = t.status === "done" ? "todo" : "done";
return {
...t,
status: newStatus,
completedAt: newStatus === "done" ? new Date().toISOString().split("T")[0] : undefined,
};
})
);
};
const updateTaskStatus = (id: string, status: TaskStatus) => {
setTasks((prev) =>
prev.map((t) =>
t.id === id
? {
...t,
status,
completedAt: status === "done" ? new Date().toISOString().split("T")[0] : undefined,
}
: t
)
);
};
const addTask = (task: Omit<Task, "id" | "order">) => {
const newTask: Task = {
...task,
id: `t-${Date.now()}`,
order: tasks.length + 1,
};
setTasks((prev) => [...prev, newTask]);
};
const getProjectProgress = (projectId: string) => {
const projectTasks = tasks.filter((t) => t.project === projectId);
if (projectTasks.length === 0) return 0;
const done = projectTasks.filter((t) => t.status === "done").length;
return Math.round((done / projectTasks.length) * 100);
};
const getTasksByProject = (projectId: string) => {
return tasks.filter((t) => t.project === projectId).sort((a, b) => a.order - b.order);
};
return (
<MissionControlContext.Provider
value={{
tasks,
toggleTask,
updateTaskStatus,
addTask,
getProjectProgress,
getTasksByProject,
}}
>
{children}
</MissionControlContext.Provider>
);
}
export function useMissionControl() {
const ctx = useContext(MissionControlContext);
if (!ctx) {
throw new Error("useMissionControl must be used within MissionControlProvider");
}
return ctx;
}