
This commit adds new functionality for tracking user activities within the application, including: - Implementation of a new activity service to fetch and manage group activities. - Creation of a dedicated activity store to handle state management for activities. - Introduction of new API endpoints for retrieving paginated activity data. - Enhancements to the UI with new components for displaying activity feeds and items. - Refactoring of existing components to utilize the new activity features, improving user engagement and interaction. These changes aim to enhance the application's activity tracking capabilities and provide users with a comprehensive view of their interactions.
113 lines
3.1 KiB
TypeScript
113 lines
3.1 KiB
TypeScript
import { ref, computed } from 'vue'
|
|
import type { Expense, SettlementActivityCreate } from '@/types/expense'
|
|
import type { CreateExpenseData, UpdateExpenseData } from '@/services/expenseService'
|
|
import { expenseService } from '@/services/expenseService'
|
|
|
|
export function useExpenses() {
|
|
const expenses = ref<Expense[]>([])
|
|
const loading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
const recurringExpenses = computed(() => expenses.value.filter((expense) => expense.isRecurring))
|
|
|
|
const fetchExpenses = async (params?: {
|
|
list_id?: number
|
|
group_id?: number
|
|
isRecurring?: boolean
|
|
}) => {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
expenses.value = await expenseService.getExpenses(params)
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to fetch expenses'
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const createExpense = async (data: CreateExpenseData) => {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const newExpense = await expenseService.createExpense(data)
|
|
expenses.value.push(newExpense)
|
|
return newExpense
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to create expense'
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const updateExpense = async (id: number, data: UpdateExpenseData) => {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const updatedExpense = await expenseService.updateExpense(id, data)
|
|
const index = expenses.value.findIndex((e) => e.id === id)
|
|
if (index !== -1) {
|
|
expenses.value[index] = updatedExpense
|
|
}
|
|
return updatedExpense
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to update expense'
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const deleteExpense = async (id: number) => {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
await expenseService.deleteExpense(id)
|
|
expenses.value = expenses.value.filter((e) => e.id !== id)
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to delete expense'
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const settleExpenseSplit = async (expense_split_id: number, activity: SettlementActivityCreate) => {
|
|
try {
|
|
await expenseService.settleExpenseSplit(expense_split_id, activity)
|
|
// refetch or update locally later
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to settle split'
|
|
throw err
|
|
}
|
|
}
|
|
|
|
const getExpense = async (id: number) => {
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
return await expenseService.getExpense(id)
|
|
} catch (err) {
|
|
error.value = err instanceof Error ? err.message : 'Failed to fetch expense'
|
|
throw err
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
return {
|
|
expenses,
|
|
recurringExpenses,
|
|
loading,
|
|
error,
|
|
fetchExpenses,
|
|
createExpense,
|
|
updateExpense,
|
|
deleteExpense,
|
|
settleExpenseSplit,
|
|
getExpense,
|
|
}
|
|
}
|