ledgerrz/resources/js/components/MutationList.vue
Daan Meijer 2ab1acf040
Some checks failed
linter / quality (push) Failing after 1m6s
tests / ci (8.3) (push) Failing after 50s
tests / ci (8.4) (push) Failing after 1m6s
tests / ci (8.5) (push) Failing after 1m6s
mutations hebben single
2026-07-06 17:47:14 +02:00

156 lines
4.7 KiB
Vue

<script setup lang="ts">
import { Link } from '@inertiajs/vue3';
import { route } from 'ziggy-js';
const props = defineProps<{
dynamicId: string;
ledgerId: string;
ledgerAlignment?: string;
mutations: Array<{
id: string; // Now a UUID
user_id: number;
user: { name: string };
amount: number;
description: string;
status: string;
created_at: string;
}>;
}>();
function getAmountClass(amount: number): string {
const alignment = props.ledgerAlignment || 'neutral';
if (alignment === 'positive') {
return amount > 0
? 'c-mutation-list__item-amount--positive'
: 'c-mutation-list__item-amount--negative';
}
if (alignment === 'negative') {
// Lower is better: negative amount is positive/favorable, positive amount is negative/unfavorable
return amount < 0
? 'c-mutation-list__item-amount--positive'
: 'c-mutation-list__item-amount--negative';
}
// Neutral alignment
return 'c-mutation-list__item-amount--neutral';
}
</script>
<template>
<div class="c-mutation-list">
<h4 class="c-mutation-list__title">Mutations</h4>
<ul class="c-mutation-list__list">
<li
v-for="mutation in mutations"
:key="mutation.id"
>
<Link
:href="route('dynamics.ledgers.mutations.show', { dynamic: dynamicId, ledger: ledgerId, mutation: mutation.id })"
class="c-mutation-list__item-link"
>
<div class="c-mutation-list__item-content">
<p class="c-mutation-list__item-desc">
{{ mutation.description }}
</p>
<div class="c-mutation-list__item-meta">
<span
:class="getAmountClass(mutation.amount)"
class="c-mutation-list__item-amount"
>
{{ mutation.amount > 0 ? '+' : ''
}}{{ mutation.amount }}
</span>
<span
:class="{
'c-mutation-list__item-status--pending':
mutation.status === 'pending',
'c-mutation-list__item-status--approved':
mutation.status === 'approved',
'c-mutation-list__item-status--rejected':
mutation.status === 'rejected',
}"
class="c-mutation-list__item-status"
>
{{ mutation.status }}
</span>
</div>
</div>
</Link>
</li>
</ul>
<div v-if="mutations.length === 0" class="c-mutation-list__empty">
No mutations found for this ledger.
</div>
</div>
</template>
<style scoped>
@reference "../../css/app.css";
.c-mutation-list {
@apply mt-8;
}
.c-mutation-list__title {
@apply text-lg font-medium text-gray-900 dark:text-gray-100;
}
.c-mutation-list__list {
@apply mt-4 space-y-2;
}
.c-mutation-list__item-link {
@apply block overflow-hidden bg-white p-4 shadow-sm sm:rounded-lg dark:bg-gray-800 transition-all duration-200 hover:shadow-md hover:bg-gray-50 dark:hover:bg-gray-700;
}
.c-mutation-list__item-content {
@apply flex items-center justify-between;
}
.c-mutation-list__item-desc {
@apply text-sm text-gray-600 dark:text-gray-400;
}
.c-mutation-list__item-meta {
@apply flex items-center gap-2;
}
.c-mutation-list__item-amount {
@apply text-sm font-bold;
}
.c-mutation-list__item-amount--positive {
@apply text-green-500;
}
.c-mutation-list__item-amount--negative {
@apply text-red-500;
}
.c-mutation-list__item-amount--neutral {
@apply text-gray-500 dark:text-gray-400;
}
.c-mutation-list__item-status {
@apply rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wider uppercase;
}
.c-mutation-list__item-status--pending {
@apply bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400;
}
.c-mutation-list__item-status--approved {
@apply bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400;
}
.c-mutation-list__item-status--rejected {
@apply bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400;
}
.c-mutation-list__empty {
@apply mt-4 text-gray-500;
}
</style>