mirror of
https://github.com/spliit-app/spliit.git
synced 2026-02-20 14:36:13 +01:00
Add support for group income (= negative expenses) (#158)
* Allow negative amount for expenses to be entered - an expense becomes an income - this does not affect calculations, i.e. an income can be split just like an expense * Incomes should not be reimbursements when entering a negative number - deselect 'isReimbursement' - hide reimbursement checkbox * Change captions when entering a negative number - "expense" becomes "income" - "paid" becomes "received" * Format incomes on expense list - replace "paid by" with "received by" * Format incomes on "Stats" tab - a group's or participants balance might be negative - in this case "spendings" will be "earnings" (display accordingly) - always display positive numbers - for active user: highlight spendings/earnings in red/green * Fix typo --------- Co-authored-by: Sebastien Castiel <sebastien@castiel.me>
This commit is contained in:
@@ -38,7 +38,8 @@ export function ExpenseCard({ expense, currency, groupId }: Props) {
|
||||
{expense.title}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Paid by <strong>{expense.paidBy.name}</strong> for{' '}
|
||||
{expense.amount > 0 ? 'Paid by ' : 'Received by '}
|
||||
<strong>{expense.paidBy.name}</strong> for{' '}
|
||||
{expense.paidFor.map((paidFor, index) => (
|
||||
<Fragment key={index}>
|
||||
{index !== 0 && <>, </>}
|
||||
|
||||
@@ -6,11 +6,12 @@ type Props = {
|
||||
}
|
||||
|
||||
export function TotalsGroupSpending({ totalGroupSpendings, currency }: Props) {
|
||||
const balance = totalGroupSpendings < 0 ? 'earnings' : 'spendings'
|
||||
return (
|
||||
<div>
|
||||
<div className="text-muted-foreground">Total group spendings</div>
|
||||
<div className="text-muted-foreground">Total group {balance}</div>
|
||||
<div className="text-lg">
|
||||
{formatCurrency(currency, totalGroupSpendings)}
|
||||
{formatCurrency(currency, Math.abs(totalGroupSpendings))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import { getGroup, getGroupExpenses } from '@/lib/api'
|
||||
import { getTotalActiveUserShare } from '@/lib/totals'
|
||||
import { formatCurrency } from '@/lib/utils'
|
||||
import { cn, formatCurrency } from '@/lib/utils'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
type Props = {
|
||||
@@ -26,8 +26,13 @@ export function TotalsYourShare({ group, expenses }: Props) {
|
||||
return (
|
||||
<div>
|
||||
<div className="text-muted-foreground">Your total share</div>
|
||||
<div className="text-lg">
|
||||
{formatCurrency(currency, totalActiveUserShare)}
|
||||
<div
|
||||
className={cn(
|
||||
'text-lg',
|
||||
totalActiveUserShare < 0 ? 'text-green-600' : 'text-red-600',
|
||||
)}
|
||||
>
|
||||
{formatCurrency(currency, Math.abs(totalActiveUserShare))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { getGroup, getGroupExpenses } from '@/lib/api'
|
||||
import { useActiveUser } from '@/lib/hooks'
|
||||
import { getTotalActiveUserPaidFor } from '@/lib/totals'
|
||||
import { formatCurrency } from '@/lib/utils'
|
||||
import { cn, formatCurrency } from '@/lib/utils'
|
||||
|
||||
type Props = {
|
||||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>>
|
||||
@@ -17,13 +17,19 @@ export function TotalsYourSpendings({ group, expenses }: Props) {
|
||||
? 0
|
||||
: getTotalActiveUserPaidFor(activeUser, expenses)
|
||||
const currency = group.currency
|
||||
const balance = totalYourSpendings < 0 ? 'earnings' : 'spendings'
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="text-muted-foreground">Total you paid for</div>
|
||||
<div className="text-muted-foreground">Your total {balance}</div>
|
||||
|
||||
<div className="text-lg">
|
||||
{formatCurrency(currency, totalYourSpendings)}
|
||||
<div
|
||||
className={cn(
|
||||
'text-lg',
|
||||
totalYourSpendings < 0 ? 'text-green-600' : 'text-red-600',
|
||||
)}
|
||||
>
|
||||
{formatCurrency(currency, Math.abs(totalYourSpendings))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user