mitlist/fe/src/components/expenses/ExpenseCreationSheet.vue
mohamad 229f6b7b1c feat: Introduce activity tracking and management features
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.
2025-06-28 19:14:51 +02:00

90 lines
2.8 KiB
Vue

<template>
<Dialog v-model="open" class="z-50">
<form @submit.prevent="handleSubmit"
class="bg-white dark:bg-neutral-800 p-6 rounded-lg shadow-xl w-full max-w-md">
<div class="flex items-center justify-between mb-4">
<Heading :level="3">{{ $t('expenseCreation.title', 'Add Expense') }}</Heading>
<Button variant="ghost" size="sm" @click="open = false">
<BaseIcon name="heroicons:x-mark-20-solid" class="w-5 h-5" />
</Button>
</div>
<Input v-model="form.description" :label="$t('expenseCreation.description', 'Description')" class="mb-3" />
<Input type="number" step="0.01" v-model="form.total_amount" :label="$t('expenseCreation.amount', 'Amount')"
class="mb-3" />
<div class="flex justify-end gap-2 mt-6">
<Button variant="ghost" @click.prevent="open = false">{{ $t('common.cancel', 'Cancel') }}</Button>
<Button type="submit" :loading="submitting">{{ $t('common.save', 'Save') }}</Button>
</div>
</form>
</Dialog>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { Dialog } from '@/components/ui'
import { Heading, Input, Button } from '@/components/ui'
import BaseIcon from '@/components/BaseIcon.vue'
import { useExpenses } from '@/composables/useExpenses'
import type { Expense } from '@/types/expense'
import { computed } from 'vue'
interface ExpenseForm {
description: string
total_amount: string
}
const open = defineModel<boolean>('modelValue', { default: false })
// Props
const props = defineProps<{ expense?: Expense | null }>()
const form = reactive<ExpenseForm>({ description: '', total_amount: '' })
const isEditing = computed(() => !!props.expense)
const { createExpense, updateExpense } = useExpenses()
// Sync form when editing
watch(
() => props.expense,
(val) => {
if (val) {
form.description = val.description
form.total_amount = val.total_amount
} else {
form.description = ''
form.total_amount = ''
}
},
{ immediate: true },
)
const submitting = ref(false)
async function handleSubmit() {
submitting.value = true
try {
if (isEditing.value && props.expense) {
await updateExpense(props.expense.id, { ...form, version: props.expense.version })
} else {
await createExpense({
...form,
currency: 'USD',
split_type: 'EQUAL',
isRecurring: false,
paid_by_user_id: 0,
})
}
open.value = false
} catch (e) {
console.error('Failed to create expense', e)
} finally {
submitting.value = false
}
}
</script>
<style scoped>
/* Tailwind styling */
</style>