diff --git a/src/utils/rounding.ts b/src/utils/rounding.ts
new file mode 100644
index 0000000..1d8ced9
--- /dev/null
+++ b/src/utils/rounding.ts
@@ -0,0 +1,10 @@
+export function roundDuration(seconds: number, incrementMinutes: number, method: 'nearest' | 'up' | 'down'): number {
+ if (incrementMinutes <= 0) return seconds
+ const incSeconds = incrementMinutes * 60
+ switch (method) {
+ case 'up': return Math.ceil(seconds / incSeconds) * incSeconds
+ case 'down': return Math.floor(seconds / incSeconds) * incSeconds
+ case 'nearest': return Math.round(seconds / incSeconds) * incSeconds
+ default: return seconds
+ }
+}
diff --git a/src/views/Settings.vue b/src/views/Settings.vue
index 61dbff2..a2b8b12 100644
--- a/src/views/Settings.vue
+++ b/src/views/Settings.vue
@@ -264,6 +264,44 @@
@change="saveShortcutSettings"
/>
+
+
+
+
+
+ Goals
+
+
+
+
Daily Goal
+
Target hours per day
+
+
+
+
+
+
+
Weekly Goal
+
Target hours per week
+
+
+
@@ -285,6 +323,63 @@
@update:model-value="saveSettings"
/>
+
+
+
+
+
+
+
Time Rounding
+
Round time entries for billing
+
+
+
+
+
+
+
+
Increment
+
Round to nearest increment
+
+
+
+
+
+
Method
+
Rounding direction
+
+
+
+
@@ -448,6 +543,31 @@ const accentColor = ref('amber')
const shortcutToggleTimer = ref('CmdOrCtrl+Shift+T')
const shortcutShowApp = ref('CmdOrCtrl+Shift+Z')
+// Goal settings
+const dailyGoalHours = ref(8)
+const weeklyGoalHours = ref(40)
+
+// Rounding settings
+const roundingEnabled = ref(false)
+const roundingIncrement = ref(15)
+const roundingMethod = ref('nearest')
+
+const roundingIncrements = [
+ { value: 1, label: '1 minute' },
+ { value: 5, label: '5 minutes' },
+ { value: 6, label: '6 minutes' },
+ { value: 10, label: '10 minutes' },
+ { value: 15, label: '15 minutes' },
+ { value: 30, label: '30 minutes' },
+ { value: 60, label: '1 hour' },
+]
+
+const roundingMethods = [
+ { value: 'nearest', label: 'Nearest' },
+ { value: 'up', label: 'Round up' },
+ { value: 'down', label: 'Round down' },
+]
+
const themeModes = [
{ value: 'dark', label: 'Dark' },
{ value: 'light', label: 'Light' },
@@ -560,6 +680,25 @@ async function saveShortcutSettings() {
await settingsStore.updateSetting('shortcut_show_app', shortcutShowApp.value)
}
+// Save goal settings
+async function saveGoalSettings() {
+ await settingsStore.updateSetting('daily_goal_hours', dailyGoalHours.value.toString())
+ await settingsStore.updateSetting('weekly_goal_hours', weeklyGoalHours.value.toString())
+}
+
+// Toggle rounding
+function toggleRounding() {
+ roundingEnabled.value = !roundingEnabled.value
+ saveRoundingSettings()
+}
+
+// Save rounding settings
+async function saveRoundingSettings() {
+ await settingsStore.updateSetting('rounding_enabled', roundingEnabled.value.toString())
+ await settingsStore.updateSetting('rounding_increment', roundingIncrement.value.toString())
+ await settingsStore.updateSetting('rounding_method', roundingMethod.value)
+}
+
// Import file handling
async function handleImportFile() {
try {
@@ -670,5 +809,10 @@ onMounted(async () => {
accentColor.value = settingsStore.settings.accent_color || 'amber'
shortcutToggleTimer.value = settingsStore.settings.shortcut_toggle_timer || 'CmdOrCtrl+Shift+T'
shortcutShowApp.value = settingsStore.settings.shortcut_show_app || 'CmdOrCtrl+Shift+Z'
+ dailyGoalHours.value = parseFloat(settingsStore.settings.daily_goal_hours) || 8
+ weeklyGoalHours.value = parseFloat(settingsStore.settings.weekly_goal_hours) || 40
+ roundingEnabled.value = settingsStore.settings.rounding_enabled === 'true'
+ roundingIncrement.value = parseInt(settingsStore.settings.rounding_increment) || 15
+ roundingMethod.value = settingsStore.settings.rounding_method || 'nearest'
})