// src/lib/taskStore.svelte.js
import { untrack } from "svelte";
import { showSuccess, showError } from '$lib/notificationStore.svelte.js';
// Initialize tasks from localStorage or use defaults
export const tasks = $state([]);
function loadTasksFromStorage() {
try {
const savedTasks = localStorage.getItem('kanban-tasks');
return savedTasks ? JSON.parse(savedTasks) : [
{ id: 1, title: 'Learn Svelte 5', description: 'Study the new Runes API', status: 'todo', createdAt: new Date().toISOString() },
{ id: 2, title: 'Design components', description: '', status: 'todo', createdAt: new Date().toISOString() },
{ id: 3, title: 'Build Kanban board', description: 'Create the main layout', status: 'inprogress', createdAt: new Date().toISOString() },
{ id: 4, title: 'Setup project', description: 'Initialize SvelteKit', status: 'done', createdAt: new Date().toISOString() }
];
} catch (error) {
console.error('Failed to load tasks from localStorage:', error);
showError('Failed to load saved tasks. Using defaults.');
return [
{ id: 1, title: 'Learn Svelte 5', description: 'Study the new Runes API', status: 'todo', createdAt: new Date().toISOString() }
];
}
}
$effect.root(() => {
$effect(() => {
if (typeof window !== undefined) {
untrack(() => {
tasks.push(...loadTasksFromStorage());
})
}
})
// Save tasks to localStorage whenever tasks change
$effect(() => {
try {
if (tasks.length > 0) {
localStorage.setItem('kanban-tasks', JSON.stringify(tasks));
}
} catch (error) {
console.error('Failed to save tasks to localStorage:', error);
showError('Failed to save changes. Your work might be lost.');
}
});
})
// Actions with notification integration
export function addTask(title, description = '') {
try {
const newTask = {
id: Date.now(),
title,
description,
status: 'todo',
createdAt: new Date().toISOString()
};
tasks.push(newTask);
showSuccess(`Task "${title}" added successfully!`);
return newTask;
} catch (error) {
console.error('Failed to add task:', error);
showError(`Failed to add task: ${error.message}`);
throw error;
}
}
export function updateTaskStatus(id, newStatus) {
try {
const taskIndex = tasks.findIndex(task => task.id === id);
if (taskIndex === -1) {
throw new Error('Task not found');
}
const oldStatus = tasks[taskIndex].status;
const title = tasks[taskIndex].title;
if (oldStatus !== newStatus) {
tasks[taskIndex].status = newStatus;
tasks[taskIndex].updatedAt = new Date().toISOString();
// Show appropriate success message
const statusText = formatStatus(newStatus);
showSuccess(`Task "${title}" moved to ${statusText}`);
}
return true;
} catch (error) {
console.error('Failed to update task:', error);
showError(`Failed to move task: ${error.message}`);
return false;
}
}
export function deleteTask(id) {
try {
const taskIndex = tasks.findIndex(task => task.id === id);
if (taskIndex === -1) {
throw new Error('Task not found');
}
const title = tasks[taskIndex].title;
tasks.splice(taskIndex, 1);
showSuccess(`Task "${title}" deleted`);
return true;
} catch (error) {
console.error('Failed to delete task:', error);
showError(`Failed to delete task: ${error.message}`);
return false;
}
}
// Helper function to format status for display
function formatStatus(status) {
switch (status) {
case 'todo': return 'To Do';
case 'inprogress': return 'In Progress';
case 'done': return 'Done';
default: return status;
}
}
// Derived state
const todoTasks = $derived(tasks.filter(task => task.status === 'todo'));
const inProgressTasks = $derived(tasks.filter(task => task.status === 'inprogress'));
const doneTasks = $derived(tasks.filter(task => task.status === 'done'));
const totalTasks = $derived(tasks.length);
export const getTodoTasks = () => todoTasks;
export const getInProgressTasks = () => inProgressTasks;
export const getDoneTasks = () => doneTasks;
export const getTotalTasks = () => totalTasks;
// Add latest task tracking for notifications (still needed for backward compatibility)
const latestTask = $derived(
tasks.length > 0
? [...tasks].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))[0]
: null
);
export const getLatestTask = () => latestTask;