From ffb6d2da38fd12f82f9f274936c7ce19276835a4 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:20:09 +0200 Subject: [PATCH 1/6] feat(libra): color-code income/expense entries and add type filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transaction History now shows a left green/red stripe on each card and tints the matching income-entry/expense-entry tag badge — mirrors the Record page's red/green palette so the two screens read consistently. Adds an All / Income / Expenses filter row (with Filter icon, aligned to the Calendar-iconed date range row above) that applies on top of search and date filtering. --- .../expenses/views/TransactionsPage.vue | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index 416c645..ae0618d 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -17,7 +17,8 @@ import { Flag, XCircle, RefreshCw, - Calendar + Calendar, + Filter } from 'lucide-vue-next' const { user } = useAuth() @@ -29,6 +30,21 @@ const isLoading = ref(false) const dateRangeType = ref(15) // 15, 30, 60, or 'custom' const customStartDate = ref('') const customEndDate = ref('') +const typeFilter = ref<'all' | 'income' | 'expense'>('all') + +const typeFilterOptions = [ + { label: 'All', value: 'all' as const }, + { label: 'Income', value: 'income' as const }, + { label: 'Expenses', value: 'expense' as const } +] + +function isIncome(t: Transaction): boolean { + return t.tags?.includes('income-entry') ?? false +} + +function isExpense(t: Transaction): boolean { + return t.tags?.includes('expense-entry') ?? false +} const walletKey = computed(() => user.value?.wallets?.[0]?.inkey) @@ -55,9 +71,12 @@ const searchOptions: FuzzySearchOptions = { matchAllWhenSearchEmpty: true } -// Transactions to display (search results or all transactions) +// Transactions to display (search results or all transactions), filtered by type const transactionsToDisplay = computed(() => { - return searchResults.value.length > 0 ? searchResults.value : transactions.value + const base = searchResults.value.length > 0 ? searchResults.value : transactions.value + if (typeFilter.value === 'income') return base.filter(isIncome) + if (typeFilter.value === 'expense') return base.filter(isExpense) + return base }) // Handle search results @@ -205,6 +224,22 @@ onMounted(() => { + +
+ + +
+
@@ -281,7 +316,11 @@ onMounted(() => {
@@ -335,7 +374,16 @@ onMounted(() => {
- + {{ tag }}
From aef59cfc0c9bbcd7a1d1d4c0e9c4fd846e448030 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:21:04 +0200 Subject: [PATCH 2/6] feat(libra): drop User and Source rows from transaction cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User row is noise on a personal history view, and Source is always libra-api right now — both just clutter the card. Drop them; can bring back if/when there's a second source to disambiguate. --- src/modules/expenses/views/TransactionsPage.vue | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index ae0618d..4a56a21 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -367,11 +367,6 @@ onMounted(() => { Ref: {{ transaction.reference }}
- -
- User: {{ transaction.username }} -
-
{ {{ tag }}
- - -
- Source: {{ transaction.meta.source }} -
From 396b0127074eacfe417ceaa973cb1d50ceb043e2 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:24:20 +0200 Subject: [PATCH 3/6] feat(libra): color-code income/expense entries in transaction history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Left green/red stripe on each card plus a matching tint on the income-entry / expense-entry tag badge — mirrors the Record page's red/green palette so the two screens read consistently. --- .../expenses/views/TransactionsPage.vue | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index 416c645..62cac0c 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -30,6 +30,14 @@ const dateRangeType = ref(15) // 15, 30, 60, or 'custom' const customStartDate = ref('') const customEndDate = ref('') +function isIncome(t: Transaction): boolean { + return t.tags?.includes('income-entry') ?? false +} + +function isExpense(t: Transaction): boolean { + return t.tags?.includes('expense-entry') ?? false +} + const walletKey = computed(() => user.value?.wallets?.[0]?.inkey) // Fuzzy search state and configuration @@ -281,7 +289,11 @@ onMounted(() => {
@@ -335,7 +347,16 @@ onMounted(() => {
- + {{ tag }}
From 8b91c7bd7206b67ad7e3853065d6460f6f69d612 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:25:59 +0200 Subject: [PATCH 4/6] feat(libra): add income/expense type filter to transaction history All / Income / Expenses toggle row with a Filter icon, aligned to the Calendar-iconed date range row above. Filters transactionsToDisplay client-side using the existing isIncome/isExpense helpers; works on top of the search and date filters. --- .../expenses/views/TransactionsPage.vue | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index 62cac0c..ae0618d 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -17,7 +17,8 @@ import { Flag, XCircle, RefreshCw, - Calendar + Calendar, + Filter } from 'lucide-vue-next' const { user } = useAuth() @@ -29,6 +30,13 @@ const isLoading = ref(false) const dateRangeType = ref(15) // 15, 30, 60, or 'custom' const customStartDate = ref('') const customEndDate = ref('') +const typeFilter = ref<'all' | 'income' | 'expense'>('all') + +const typeFilterOptions = [ + { label: 'All', value: 'all' as const }, + { label: 'Income', value: 'income' as const }, + { label: 'Expenses', value: 'expense' as const } +] function isIncome(t: Transaction): boolean { return t.tags?.includes('income-entry') ?? false @@ -63,9 +71,12 @@ const searchOptions: FuzzySearchOptions = { matchAllWhenSearchEmpty: true } -// Transactions to display (search results or all transactions) +// Transactions to display (search results or all transactions), filtered by type const transactionsToDisplay = computed(() => { - return searchResults.value.length > 0 ? searchResults.value : transactions.value + const base = searchResults.value.length > 0 ? searchResults.value : transactions.value + if (typeFilter.value === 'income') return base.filter(isIncome) + if (typeFilter.value === 'expense') return base.filter(isExpense) + return base }) // Handle search results @@ -213,6 +224,22 @@ onMounted(() => {
+ +
+ + +
+
From 22ad5fd9749064bd3b7421753fde6f4a9a709488 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:27:41 +0200 Subject: [PATCH 5/6] feat(libra): drop User and Source rows from transaction cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User row is noise on a personal history view, and Source is always libra-api right now — both just clutter the card. Drop them; can bring back if/when there's a second source to disambiguate. --- src/modules/expenses/views/TransactionsPage.vue | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index ae0618d..4a56a21 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -367,11 +367,6 @@ onMounted(() => { Ref: {{ transaction.reference }}
- -
- User: {{ transaction.username }} -
-
{ {{ tag }}
- - -
- Source: {{ transaction.meta.source }} -
From 9252c86f5c7dd44ac1559345dc75298ab75061b2 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 16 May 2026 23:28:29 +0200 Subject: [PATCH 6/6] feat(libra): shrink filter controls on mobile Drop the date-range/type-filter buttons and custom-date inputs from h-8 to h-7 below md to claw back a bit of vertical space on phones, keeping h-8 on tablet/desktop where it's comfortable. --- src/modules/expenses/views/TransactionsPage.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/expenses/views/TransactionsPage.vue b/src/modules/expenses/views/TransactionsPage.vue index 4a56a21..70b560c 100644 --- a/src/modules/expenses/views/TransactionsPage.vue +++ b/src/modules/expenses/views/TransactionsPage.vue @@ -216,7 +216,7 @@ onMounted(() => { :key="option.value" :variant="dateRangeType === option.value ? 'default' : 'outline'" size="sm" - class="h-8 px-3 text-xs" + class="h-7 md:h-8 px-3 text-xs" @click="onDateRangeTypeChange(option.value)" :disabled="isLoading" > @@ -232,7 +232,7 @@ onMounted(() => { :key="option.value" :variant="typeFilter === option.value ? 'default' : 'outline'" size="sm" - class="h-8 px-3 text-xs" + class="h-7 md:h-8 px-3 text-xs" @click="typeFilter = option.value" :disabled="isLoading" > @@ -247,7 +247,7 @@ onMounted(() => {
@@ -256,13 +256,13 @@ onMounted(() => {