feat: add project budgets and rounding override columns
This commit is contained in:
113
src/stores/projects.ts
Normal file
113
src/stores/projects.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export interface Project {
|
||||
id?: number
|
||||
client_id?: number
|
||||
name: string
|
||||
hourly_rate: number
|
||||
color: string
|
||||
archived: boolean
|
||||
budget_hours?: number | null
|
||||
budget_amount?: number | null
|
||||
rounding_override?: number | null
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id?: number
|
||||
project_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export const useProjectsStore = defineStore('projects', () => {
|
||||
const projects = ref<Project[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
async function fetchProjects() {
|
||||
loading.value = true
|
||||
try {
|
||||
projects.value = await invoke<Project[]>('get_projects')
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch projects:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function createProject(project: Project): Promise<number | null> {
|
||||
try {
|
||||
const id = await invoke<number>('create_project', { project })
|
||||
projects.value.push({ ...project, id: Number(id) })
|
||||
return Number(id)
|
||||
} catch (error) {
|
||||
console.error('Failed to create project:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function updateProject(project: Project): Promise<boolean> {
|
||||
try {
|
||||
await invoke('update_project', { project })
|
||||
const index = projects.value.findIndex(p => p.id === project.id)
|
||||
if (index !== -1) {
|
||||
projects.value[index] = project
|
||||
}
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Failed to update project:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteProject(id: number): Promise<boolean> {
|
||||
try {
|
||||
await invoke('delete_project', { id })
|
||||
projects.value = projects.value.filter(p => p.id !== id)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Failed to delete project:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchTasks(projectId: number): Promise<Task[]> {
|
||||
try {
|
||||
return await invoke<Task[]>('get_tasks', { projectId })
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch tasks:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
async function createTask(task: Task): Promise<number | null> {
|
||||
try {
|
||||
return await invoke<number>('create_task', { task })
|
||||
} catch (error) {
|
||||
console.error('Failed to create task:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteTask(id: number): Promise<boolean> {
|
||||
try {
|
||||
await invoke('delete_task', { id })
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Failed to delete task:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
projects,
|
||||
loading,
|
||||
fetchProjects,
|
||||
createProject,
|
||||
updateProject,
|
||||
deleteProject,
|
||||
fetchTasks,
|
||||
createTask,
|
||||
deleteTask
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user