port-nimara-client-portal/components/ExpenseDuplicateNotificatio...

102 lines
2.9 KiB
Vue

<template>
<v-alert
v-if="showBanner && (duplicateCount > 0 || payerVariations > 0)"
type="warning"
variant="tonal"
closable
@click:close="dismissBanner"
class="ma-4"
>
<template #prepend>
<v-icon>mdi-content-duplicate</v-icon>
</template>
<div class="d-flex align-center justify-space-between">
<div>
<div class="text-subtitle-1 font-weight-medium">
<span v-if="duplicateCount > 0">
{{ duplicateCount }} duplicate expense{{ duplicateCount > 1 ? 's' : '' }} detected
</span>
<span v-if="duplicateCount > 0 && payerVariations > 0"> and </span>
<span v-if="payerVariations > 0">
{{ payerVariations }} payer name variation{{ payerVariations > 1 ? 's' : '' }} found
</span>
</div>
<div class="text-body-2">
Duplicate expenses and inconsistent payer names can affect reporting accuracy.
</div>
</div>
<v-btn
color="warning"
variant="elevated"
size="small"
:to="'/dashboard/expenses/duplicates'"
prepend-icon="mdi-wrench"
>
Clean Up Duplicates
</v-btn>
</div>
</v-alert>
</template>
<script setup>
const { hasRole } = useAuthorization();
const showBanner = ref(true);
const duplicateCount = ref(0);
const payerVariations = ref(0);
const loading = ref(false);
// Check for duplicates on mount (only for sales/admin users)
const checkForDuplicates = async () => {
if (loading.value) return;
// Only check for users with sales or admin role
const canViewExpenses = await hasRole(['sales', 'admin']);
if (!canViewExpenses) return;
try {
loading.value = true;
const response = await $fetch('/api/expenses/duplicates/find', {
method: 'GET',
query: { dateRange: '30' } // Last 30 days
});
if (response.success && response.data) {
duplicateCount.value = response.data.duplicateGroups?.length || 0;
payerVariations.value = response.data.payerVariations?.length || 0;
}
} catch (error) {
console.error('[ExpenseDuplicateNotification] Failed to check for duplicates:', error);
// Silently fail - this is just a notification banner
} finally {
loading.value = false;
}
};
// Dismiss the banner for this session
const dismissBanner = () => {
showBanner.value = false;
// Store dismissal in session storage
if (process.client) {
sessionStorage.setItem('expense-duplicates-banner-dismissed', 'true');
}
};
// Check if banner was already dismissed this session
onMounted(() => {
if (process.client) {
const dismissed = sessionStorage.getItem('expense-duplicates-banner-dismissed');
if (dismissed === 'true') {
showBanner.value = false;
return;
}
}
// Check for duplicates for sales/admin users
// Small delay to let other components load first
setTimeout(checkForDuplicates, 2000);
});
</script>