90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { fetchAllProjects, countProjects } from "./projects";
|
|
import { countActiveTasks, countTotalTasks, fetchAllTasks } from "./tasks";
|
|
|
|
export interface DashboardStats {
|
|
activeTasksCount: number;
|
|
totalTasksCount: number;
|
|
projectsCount: number;
|
|
goalsProgress: number;
|
|
appsBuilt: number;
|
|
yearProgress: number;
|
|
yearDay: number;
|
|
yearTotalDays: number;
|
|
}
|
|
|
|
/**
|
|
* Calculate year progress
|
|
*/
|
|
function calculateYearProgress(): { progress: number; day: number; totalDays: number } {
|
|
const now = new Date();
|
|
const startOfYear = new Date(now.getFullYear(), 0, 1);
|
|
const endOfYear = new Date(now.getFullYear() + 1, 0, 1);
|
|
|
|
const totalDays = Math.floor((endOfYear.getTime() - startOfYear.getTime()) / (1000 * 60 * 60 * 24));
|
|
const dayOfYear = Math.floor((now.getTime() - startOfYear.getTime()) / (1000 * 60 * 60 * 24)) + 1;
|
|
const progress = Math.round((dayOfYear / totalDays) * 100);
|
|
|
|
return { progress, day: dayOfYear, totalDays };
|
|
}
|
|
|
|
/**
|
|
* Calculate goals progress based on project completion
|
|
* For now, this uses a simple heuristic based on done tasks vs total tasks
|
|
*/
|
|
async function calculateGoalsProgress(): Promise<number> {
|
|
const tasks = await fetchAllTasks();
|
|
if (tasks.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const doneCount = tasks.filter((task) => task.status === "done").length;
|
|
return Math.round((doneCount / tasks.length) * 100);
|
|
}
|
|
|
|
/**
|
|
* Count iOS apps built
|
|
* This looks for projects with "iOS" in the name or specific app-related tags
|
|
*/
|
|
async function countAppsBuilt(): Promise<number> {
|
|
const projects = await fetchAllProjects();
|
|
|
|
// Count projects that look like iOS apps
|
|
// Heuristic: projects with "iOS", "App", or "Swift" in the name
|
|
const appProjects = projects.filter((p) => {
|
|
const nameLower = p.name.toLowerCase();
|
|
return (
|
|
nameLower.includes("ios") ||
|
|
nameLower.includes("app") ||
|
|
nameLower.includes("swift") ||
|
|
nameLower.includes("mobile")
|
|
);
|
|
});
|
|
|
|
return appProjects.length || 6; // Fallback to 6 if no matches (current count)
|
|
}
|
|
|
|
/**
|
|
* Fetch all dashboard stats
|
|
*/
|
|
export async function fetchDashboardStats(): Promise<DashboardStats> {
|
|
const [activeTasksCount, totalTasksCount, projectsCount, goalsProgress, appsBuilt, yearData] = await Promise.all([
|
|
countActiveTasks(),
|
|
countTotalTasks(),
|
|
countProjects(),
|
|
calculateGoalsProgress(),
|
|
countAppsBuilt(),
|
|
Promise.resolve(calculateYearProgress()),
|
|
]);
|
|
|
|
return {
|
|
activeTasksCount,
|
|
totalTasksCount,
|
|
projectsCount,
|
|
goalsProgress,
|
|
appsBuilt,
|
|
yearProgress: yearData.progress,
|
|
yearDay: yearData.day,
|
|
yearTotalDays: yearData.totalDays,
|
|
};
|
|
}
|