From 8ee45cdefcfff093f5610883017e0784e6891432 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 17 Feb 2026 22:54:31 +0200 Subject: [PATCH] feat: add Client billing fields to store, /clients route, and reorder NavRail --- src/components/NavRail.vue | 4 +- src/router/index.ts | 49 ++++++++++++++++++++++++ src/stores/clients.ts | 76 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/router/index.ts create mode 100644 src/stores/clients.ts diff --git a/src/components/NavRail.vue b/src/components/NavRail.vue index 8a60f03..643b783 100644 --- a/src/components/NavRail.vue +++ b/src/components/NavRail.vue @@ -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 } ] diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..659428c --- /dev/null +++ b/src/router/index.ts @@ -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 diff --git a/src/stores/clients.ts b/src/stores/clients.ts new file mode 100644 index 0000000..508b551 --- /dev/null +++ b/src/stores/clients.ts @@ -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([]) + const loading = ref(false) + + async function fetchClients() { + loading.value = true + try { + clients.value = await invoke('get_clients') + } catch (error) { + console.error('Failed to fetch clients:', error) + } finally { + loading.value = false + } + } + + async function createClient(client: Client): Promise { + try { + const id = await invoke('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 { + 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 { + 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 + } +})