95 lines
2.3 KiB
Vue
95 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import type { ExpenseView, PotView } from '~/types';
|
|
|
|
const route = useRoute();
|
|
const slug = route.params.slug as string;
|
|
const { name } = useIdentity();
|
|
const { confirm } = useConfirm();
|
|
|
|
const { data, refresh } = await useFetch<PotView>(`/api/pots/${slug}`);
|
|
|
|
const me = computed(() =>
|
|
data.value?.participants.find(
|
|
(p) => p.name.toLowerCase() === name.value?.toLowerCase(),
|
|
),
|
|
);
|
|
|
|
const showExpenseForm = ref(false);
|
|
const editingExpense = ref<ExpenseView | null>(null);
|
|
|
|
async function submitExpense(payload: {
|
|
description: string;
|
|
amountCents: number;
|
|
payerId: number;
|
|
participantIds: number[];
|
|
}) {
|
|
if (editingExpense.value) {
|
|
await $fetch(`/api/pots/${slug}/expenses/${editingExpense.value.id}`, {
|
|
method: 'PATCH',
|
|
body: payload,
|
|
});
|
|
} else {
|
|
await $fetch(`/api/pots/${slug}/expenses`, {
|
|
method: 'POST',
|
|
body: payload,
|
|
});
|
|
}
|
|
editingExpense.value = null;
|
|
showExpenseForm.value = false;
|
|
await refresh();
|
|
}
|
|
|
|
function editExpense(expense: ExpenseView) {
|
|
editingExpense.value = expense;
|
|
showExpenseForm.value = true;
|
|
}
|
|
|
|
function newExpense() {
|
|
editingExpense.value = null;
|
|
showExpenseForm.value = true;
|
|
}
|
|
|
|
function cancelExpenseForm() {
|
|
editingExpense.value = null;
|
|
showExpenseForm.value = false;
|
|
}
|
|
|
|
async function removeExpense(id: number) {
|
|
if (!confirm('Delete this expense?')) return;
|
|
await $fetch(`/api/pots/${slug}/expenses/${id}`, { method: 'DELETE' });
|
|
await refresh();
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section v-if="data" class="space-y-3">
|
|
<ExpenseList
|
|
v-if="!showExpenseForm"
|
|
:expenses="data.expenses"
|
|
:participants="data.participants"
|
|
:currency="data.pot.currency"
|
|
@edit="editExpense"
|
|
@remove="removeExpense"
|
|
/>
|
|
|
|
<AddExpenseForm
|
|
v-if="showExpenseForm"
|
|
:participants="data.participants"
|
|
:currency="data.pot.currency"
|
|
:editing="editingExpense"
|
|
:default-payer-id="me?.id"
|
|
@submit="submitExpense"
|
|
@cancel="cancelExpenseForm"
|
|
/>
|
|
|
|
<button
|
|
v-if="!showExpenseForm"
|
|
type="button"
|
|
class="w-full rounded-xl bg-orange-500 px-4 py-2 font-medium text-white shadow-sm transition-colors hover:bg-orange-600"
|
|
@click="newExpense"
|
|
>
|
|
+ Add expense
|
|
</button>
|
|
</section>
|
|
</template>
|