feat: add Client billing fields to store, /clients route, and reorder NavRail

This commit is contained in:
Your Name
2026-02-17 22:54:31 +02:00
parent 5ab96769ac
commit c949a08981
3 changed files with 128 additions and 1 deletions

View File

@@ -5,6 +5,7 @@ import { useTimerStore } from '../stores/timer'
import {
LayoutDashboard,
Clock,
Users,
FolderKanban,
List,
BarChart3,
@@ -19,10 +20,11 @@ const timerStore = useTimerStore()
const navItems = [
{ name: 'Dashboard', path: '/', icon: LayoutDashboard },
{ name: 'Timer', path: '/timer', icon: Clock },
{ name: 'Clients', path: '/clients', icon: Users },
{ name: 'Projects', path: '/projects', icon: FolderKanban },
{ name: 'Entries', path: '/entries', icon: List },
{ name: 'Reports', path: '/reports', icon: BarChart3 },
{ name: 'Invoices', path: '/invoices', icon: FileText },
{ name: 'Reports', path: '/reports', icon: BarChart3 },
{ name: 'Settings', path: '/settings', icon: Settings }
]

49
src/router/index.ts Normal file
View File

@@ -0,0 +1,49 @@
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
name: 'Dashboard',
component: () => import('../views/Dashboard.vue')
},
{
path: '/timer',
name: 'Timer',
component: () => import('../views/Timer.vue')
},
{
path: '/clients',
name: 'Clients',
component: () => import('../views/Clients.vue')
},
{
path: '/projects',
name: 'Projects',
component: () => import('../views/Projects.vue')
},
{
path: '/entries',
name: 'Entries',
component: () => import('../views/Entries.vue')
},
{
path: '/reports',
name: 'Reports',
component: () => import('../views/Reports.vue')
},
{
path: '/invoices',
name: 'Invoices',
component: () => import('../views/Invoices.vue')
},
{
path: '/settings',
name: 'Settings',
component: () => import('../views/Settings.vue')
}
]
})
export default router

76
src/stores/clients.ts Normal file
View File

@@ -0,0 +1,76 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'
export interface Client {
id?: number
name: string
email?: string
address?: string
company?: string
phone?: string
tax_id?: string
payment_terms?: string
notes?: string
}
export const useClientsStore = defineStore('clients', () => {
const clients = ref<Client[]>([])
const loading = ref(false)
async function fetchClients() {
loading.value = true
try {
clients.value = await invoke<Client[]>('get_clients')
} catch (error) {
console.error('Failed to fetch clients:', error)
} finally {
loading.value = false
}
}
async function createClient(client: Client): Promise<number | null> {
try {
const id = await invoke<number>('create_client', { client })
clients.value.push({ ...client, id: Number(id) })
return Number(id)
} catch (error) {
console.error('Failed to create client:', error)
return null
}
}
async function updateClient(client: Client): Promise<boolean> {
try {
await invoke('update_client', { client })
const index = clients.value.findIndex(c => c.id === client.id)
if (index !== -1) {
clients.value[index] = client
}
return true
} catch (error) {
console.error('Failed to update client:', error)
return false
}
}
async function deleteClient(id: number): Promise<boolean> {
try {
await invoke('delete_client', { id })
clients.value = clients.value.filter(c => c.id !== id)
return true
} catch (error) {
console.error('Failed to delete client:', error)
return false
}
}
return {
clients,
loading,
fetchClients,
createClient,
updateClient,
deleteClient
}
})