feat(costs): filter expenses by category and by a single day

Adds two filter dropdowns next to the Search Expenses field (height-matched
to it): one filters by expense category, the other narrows to a single day.
Selecting a day shows a prominent summary banner with that day's total, and
hides the now-redundant per-day header. Both filters work on the desktop and
mobile layouts and compose with the existing search + all/mine/owed filters.

New i18n keys (costs.filter.allCategories / allDays, costs.expensesCount)
across every locale.
This commit is contained in:
Maurice
2026-07-02 15:44:06 +02:00
committed by Maurice
parent 8eb5e19fea
commit bd2d91845b
23 changed files with 125 additions and 5 deletions
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'كل الفئات',
'costs.filter.allDays': 'كل الأيام',
'costs.expensesCount': '{count} مصروف',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Todas as categorias',
'costs.filter.allDays': 'Todos os dias',
'costs.expensesCount': '{count} despesas',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Všechny kategorie',
'costs.filter.allDays': 'Všechny dny',
'costs.expensesCount': '{count} výdajů',
};
export default budget;
+3
View File
@@ -58,6 +58,9 @@ const budget: TranslationStrings = {
'costs.filter.all': 'Alle',
'costs.filter.mine': 'Von mir bezahlt',
'costs.filter.owed': 'Mir geschuldet',
'costs.filter.allCategories': 'Alle Kategorien',
'costs.filter.allDays': 'Alle Tage',
'costs.expensesCount': '{count} Ausgaben',
'costs.addExpense': 'Ausgabe hinzufügen',
'costs.editExpense': 'Ausgabe bearbeiten',
'costs.noMatch': 'Keine Ausgaben passen zur Suche.',
+3
View File
@@ -58,6 +58,9 @@ const budget: TranslationStrings = {
'costs.filter.all': 'All',
'costs.filter.mine': 'Paid by me',
'costs.filter.owed': "I'm owed",
'costs.filter.allCategories': 'All categories',
'costs.filter.allDays': 'All days',
'costs.expensesCount': '{count} expenses',
'costs.addExpense': 'Add expense',
'costs.editExpense': 'Edit expense',
'costs.noMatch': 'No expenses match your search.',
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Todas las categorías',
'costs.filter.allDays': 'Todos los días',
'costs.expensesCount': '{count} gastos',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Toutes les catégories',
'costs.filter.allDays': 'Tous les jours',
'costs.expensesCount': '{count} dépenses',
};
export default budget;
+3
View File
@@ -121,5 +121,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Όλες οι κατηγορίες',
'costs.filter.allDays': 'Όλες οι ημέρες',
'costs.expensesCount': '{count} έξοδα',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Összes kategória',
'costs.filter.allDays': 'Összes nap',
'costs.expensesCount': '{count} kiadás',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Semua kategori',
'costs.filter.allDays': 'Semua hari',
'costs.expensesCount': '{count} pengeluaran',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Tutte le categorie',
'costs.filter.allDays': 'Tutti i giorni',
'costs.expensesCount': '{count} spese',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'すべてのカテゴリー',
'costs.filter.allDays': 'すべての日',
'costs.expensesCount': '{count}件の支出',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': '모든 카테고리',
'costs.filter.allDays': '모든 날짜',
'costs.expensesCount': '지출 {count}건',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Alle categorieën',
'costs.filter.allDays': 'Alle dagen',
'costs.expensesCount': '{count} uitgaven',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Wszystkie kategorie',
'costs.filter.allDays': 'Wszystkie dni',
'costs.expensesCount': '{count} wydatków',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Все категории',
'costs.filter.allDays': 'Все дни',
'costs.expensesCount': 'Расходов: {count}',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Alla kategorier',
'costs.filter.allDays': 'Alla dagar',
'costs.expensesCount': '{count} utgifter',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Tüm kategoriler',
'costs.filter.allDays': 'Tüm günler',
'costs.expensesCount': '{count} harcama',
};
export default budget;
+3
View File
@@ -120,5 +120,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': 'Усі категорії',
'costs.filter.allDays': 'Усі дні',
'costs.expensesCount': '{count} витрат',
};
export default budget;
+3
View File
@@ -120,6 +120,9 @@ const budget: TranslationStrings = {
'costs.splitEqually': 'Chia đều',
'costs.splitCustom': 'Tùy chỉnh',
'costs.splitTicket': 'Hóa đơn',
'costs.filter.allCategories': 'Tất cả danh mục',
'costs.filter.allDays': 'Tất cả các ngày',
'costs.expensesCount': '{count} chi phí',
};
export default budget;
+3
View File
@@ -119,5 +119,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': '所有類別',
'costs.filter.allDays': '所有日期',
'costs.expensesCount': '{count} 筆支出',
};
export default budget;
+3
View File
@@ -119,5 +119,8 @@ const budget: TranslationStrings = {
'costs.splitEqually': "Equally",
'costs.splitCustom': "Custom",
'costs.splitTicket': "Ticket",
'costs.filter.allCategories': '所有类别',
'costs.filter.allDays': '所有日期',
'costs.expensesCount': '{count} 笔支出',
};
export default budget;