Skip to content

Commit

Permalink
chore(debtor): split into two components
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperVK committed Feb 23, 2025
1 parent 2a5375a commit 8ab3d9b
Show file tree
Hide file tree
Showing 4 changed files with 382 additions and 203 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<CardComponent
:header="t('modules.financial.fine.handoutEvents.header')"
class="w-full">
<DataTable
paginator
v-model:rows="take"
v-model:first="skip"
:rowsPerPageOptions="[5, 10, 25, 50, 100]"
:value="debtorStore.fineHandoutEvents"
>
<Column field="id" id="id" :header="t('common.id')">
<template #body v-if="debtorStore.isFineHandoutEventsLoading">
<Skeleton class="w-4 my-1 h-1rem surface-300"/>
</template>
</Column>
<Column field="createdAt" id="date" :header="t('common.date')">
<template #body v-if="debtorStore.isFineHandoutEventsLoading">
<Skeleton class="w-7 my-1 h-1rem surface-300"/>
</template>
<template #body="slotProps" v-else>{{ formatDateTime(new Date(slotProps.data.createdAt)) }}</template>
</Column>
<Column
field="referenceDate"
id="referenceDate"
:header="t('modules.financial.fine.handoutEvents.referenceDate')">
<template #body v-if="debtorStore.isFineHandoutEventsLoading">
<Skeleton class="w-4 my-1 h-1rem surface-300"/>
</template>
<template #body="slotProps" v-else>{{ formatDateTime(new Date(slotProps.data.referenceDate)) }}</template>
</Column>
<Column id="info" :header="t('common.info')" >
<template #body v-if="debtorStore.isFineHandoutEventsLoading">
<Skeleton class="w-2 my-1 h-1rem surface-300"/>
</template>
<template #body v-else>
<i class="pi pi-info-circle"/>
</template>
</Column>
</DataTable>
</CardComponent>
<!-- <Dialog-->
<!-- v-model:visible="showModal"-->
<!-- class="w-auto flex w-9 md:w-4"-->
<!-- :header="t('modules.financial.fine.handoutEvents.details')">-->
<!-- <div class="flex flex-column">-->
<!-- <div class="flex flex-row justify-content-between">-->
<!-- <p>{{ t("modules.financial.fine.handoutEvents.number") }}</p>-->
<!-- <p>{{ selectedHandoutEvent?.fines.length }}</p>-->
<!-- </div>-->
<!-- <div class="flex flex-row justify-content-between">-->
<!-- <p>{{ t("modules.financial.fine.handoutEvents.total") }}</p>-->
<!-- <p>{{ formatPrice(modalTotalFines) }}-->
<!-- </p>-->
<!-- </div>-->
<!-- <div class="flex flex-row justify-content-between">-->
<!-- <p>{{ t("common.createdAt") }}</p>-->
<!-- <p>{{ formatDateTime(new Date(selectedHandoutEvent?.createdAt || '')) }}</p>-->
<!-- </div>-->
<!-- <div class="flex flex-row justify-content-between">-->
<!-- <p>{{ t("modules.financial.fine.handoutEvents.referenceDate") }}</p>-->
<!-- <p>{{ formatDateTime(new Date(selectedHandoutEvent?.referenceDate || '')) }}</p>-->
<!-- </div>-->
<!-- </div>-->
<!-- </Dialog>-->
</template>

<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { formatDateTime } from "@/utils/formatterUtils";
import Column from "primevue/column";
import CardComponent from "@/components/CardComponent.vue";
import Skeleton from "primevue/skeleton";
import DataTable from "primevue/datatable";
import { ref, watch } from "vue";
import { useDebtorStore } from "@/stores/debtor.store";
const { t } = useI18n();
const debtorStore = useDebtorStore();
const take = ref(10);
const skip = ref(0);
watch(take, () => debtorStore.fetchFineHandoutEvents(take.value, skip.value));
watch(skip, () => debtorStore.fetchFineHandoutEvents(take.value, skip.value));
</script>


<style scoped lang="scss">
</style>
210 changes: 210 additions & 0 deletions apps/dashboard/src/modules/financial/components/debtor/DebtorTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<template>
<CardComponent :header="t('modules.financial.debtor.debtorUsers.header')" class="w-full">
<DataTable :value="debtorRows" tableStyle="min-width: 50rem"
removableSort
filterDisplay="row"
@sort="onSortClick"
striped-rows
v-model:selection="selectedUsers">

<Column selectionMode="multiple" style="width: 2%" >
</Column>

<Column field="id" header="Id" style="width: 5%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
</Column>

<Column field="name" header="Name" :sortable="true" style="width: 15%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
<template #body="{ data }" v-else>
{{ data.name }}
</template>
<template #filter>
<InputText v-model="nameFilter" type="text" class="p-column-filter" placeholder="Search" />
</template>
</Column>

<Column field="secondaryBalance" filter-match-mode="notEquals"
:header="secondaryBalanceHeader" :sortable="true" :showFilterMenu="false" style="width: 20%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
<template #body="{ data }" v-else>
{{ data.secondaryBalance }}
</template>
<template #filter>
<Calendar
v-model="secondaryBalanceDate"
id="firstDate"
showTime
hourFormat="24"
placeholder="Click to change date"
/>
</template>
</Column>

<Column field="primaryBalance" filter-match-mode="notEquals"
:header="primaryBalanceHeader" :sortable="true" :showFilterMenu="false" style="width: 20%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
<template #body="{ data }" v-else>
{{ data.primaryBalance }}
</template>
<template #filter>
<Calendar
v-model="primaryBalanceDate"
id="firstDate"
showTime
hourFormat="24"
placeholder="Click to change date"
/>
</template>
</Column>

<Column field="fine" header="Fine" :sortable="true" style="width: 10%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
</Column>

<Column field="fineSince" header="Fine since" :sortable="true" style="width: 10%">
<template #body v-if="debtorStore.isDebtorsLoading">
<Skeleton class="w-6 mr-8 my-1 h-2rem surface-300"/>
</template>
<template #body="slotProps" v-else>
<span v-if="slotProps.data.fineSince" class="text-red-500 font-bold">
{{ formatTimeSince(new Date(slotProps.data.fineSince), new Date()) }}
</span>
</template>
</Column>

</DataTable>
</CardComponent>
</template>

<script setup lang="ts">
import { useI18n } from "vue-i18n";
import CardComponent from "@/components/CardComponent.vue";
import { useDebtorStore, SortField } from "@/stores/debtor.store";
import { computed, type ComputedRef, onMounted, ref, watch } from "vue";
import Calendar from "primevue/calendar";
import Column from "primevue/column";
import { formatPrice, formatTimeSince } from "@/utils/formatterUtils";
import DataTable, { type DataTableSortEvent } from "primevue/datatable";
import Skeleton from "primevue/skeleton";
import { debounce } from "lodash";
const { t } = useI18n();
const debtorStore = useDebtorStore();
// All the users that have been selected for actions
const selectedUsers = ref();
// Primary balance
const primaryBalanceDate = ref<Date>();
const primaryBalanceHeader = computed(() => {
if(primaryBalanceDate.value == undefined) {
return "Primary balance now ";
} else {
return "Primary balance on " + primaryBalanceDate.value.toLocaleString('nl', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
}
});
// Secondary balance
const secondaryBalanceDate = ref<Date>();
const secondaryBalanceHeader = computed(() => {
if(secondaryBalanceDate.value == undefined) {
return "Secondary balance --/--/--";
} else {
return "Secondary balance on " + secondaryBalanceDate.value.toLocaleString('nl', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
}
});
// Fetch new calculated fines based on the dates
watch(primaryBalanceDate, updateCalculatedFines);
watch(secondaryBalanceDate, updateCalculatedFines);
async function updateCalculatedFines() {
selectedUsers.value = [];
await debtorStore.fetchCalculatedFines(primaryBalanceDate.value || new Date(), secondaryBalanceDate.value);
}
const nameFilter = ref<string>("");
watch(nameFilter, debounce(() => {
console.log(2);
debtorStore.filter = {
name: nameFilter.value
};
}, 50));
const onSortClick = (sort: DataTableSortEvent) => {
if (sort.sortField == SortField.SECONDARY_BALANCE
&& secondaryBalanceDate.value == undefined) {
return;
}
debtorStore.sort = {
field: sort.sortField as SortField || null,
direction: sort.sortOrder || null
};
};
// Row in the datatable
interface DebtorRow {
id: number | undefined;
name: string;
primaryBalance: string;
secondaryBalance: string;
fine?: string;
}
// Convert data from the store to something that can be displayed by the datatable
const debtorRows: ComputedRef<DebtorRow[]> = computed(() => {
if (debtorStore.isDebtorsLoading) {
return new Array(10);
}
const debtorRowsArr = [];
for (const debtorId in debtorStore.debtors) {
const debtor = debtorStore.debtors[debtorId];
debtorRowsArr.push({
id: debtor.user.gewisId,
name: debtor.user.firstName + " " + debtor.user.lastName,
primaryBalance: formatPrice(debtor.fine.balances[0].amount),
secondaryBalance: debtor.fine.balances[1] && formatPrice(debtor.fine.balances[1].amount),
fine: debtor.fine.balances[0].fine && formatPrice(
debtor.fine.balances[0].fine
),
fineSince: debtor.fine.balances[0].fineSince
});
}
return debtorRowsArr;
});
onMounted(() => {
updateCalculatedFines();
});
</script>


<style scoped lang="scss">
</style>
Loading

0 comments on commit 8ab3d9b

Please sign in to comment.