-
-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
131 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,17 @@ | ||
import { formatCurrency } from '@/lib/utils' | ||
|
||
type Props = { | ||
totalGroupSpendings: number | ||
currency: string | ||
totalGroupSpendings: number | ||
currency: string | ||
} | ||
|
||
export function TotalsGroupSpending({ totalGroupSpendings, currency }: Props) { | ||
return ( | ||
<div> | ||
<div className="text-muted-foreground"> | ||
Total group spendings | ||
</div> | ||
<div className="text-lg"> | ||
{formatCurrency(currency, totalGroupSpendings)} | ||
</div> | ||
</div> | ||
) | ||
} | ||
return ( | ||
<div> | ||
<div className="text-muted-foreground">Total group spendings</div> | ||
<div className="text-lg"> | ||
{formatCurrency(currency, totalGroupSpendings)} | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,34 @@ | ||
'use client' | ||
import { formatCurrency } from '@/lib/utils' | ||
import { getGroup, getGroupExpenses } from '@/lib/api' | ||
import { getTotalActiveUserShare } from '@/lib/totals' | ||
import { formatCurrency } from '@/lib/utils' | ||
import { useEffect, useState } from 'react' | ||
|
||
|
||
type Props = { | ||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>> | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>> | ||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>> | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>> | ||
} | ||
|
||
export function TotalsYourShare({ group, expenses }: Props) { | ||
|
||
const [activeUser, setActiveUser] = useState('') | ||
|
||
useEffect(() => { | ||
const activeUser = localStorage.getItem(`${group.id}-activeUser`) | ||
if (activeUser) setActiveUser(activeUser) | ||
|
||
}, [group, expenses]) | ||
|
||
const totalActiveUserShare = (activeUser === '' || activeUser === 'None') ? 0 : getTotalActiveUserShare(activeUser, expenses) | ||
const currency = group.currency | ||
|
||
return ( | ||
<div> | ||
<div className="text-muted-foreground"> | ||
Your total share | ||
|
||
</div> | ||
<div className="text-lg"> | ||
{formatCurrency(currency, totalActiveUserShare)} | ||
</div> | ||
</div> | ||
|
||
) | ||
} | ||
const [activeUser, setActiveUser] = useState('') | ||
|
||
useEffect(() => { | ||
const activeUser = localStorage.getItem(`${group.id}-activeUser`) | ||
if (activeUser) setActiveUser(activeUser) | ||
}, [group, expenses]) | ||
|
||
const totalActiveUserShare = | ||
activeUser === '' || activeUser === 'None' | ||
? 0 | ||
: getTotalActiveUserShare(activeUser, expenses) | ||
const currency = group.currency | ||
|
||
return ( | ||
<div> | ||
<div className="text-muted-foreground">Your total share</div> | ||
<div className="text-lg"> | ||
{formatCurrency(currency, totalActiveUserShare)} | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,35 @@ | ||
'use client' | ||
import { formatCurrency } from '@/lib/utils' | ||
import { getGroup, getGroupExpenses } from '@/lib/api' | ||
import { getTotalActiveUserPaidFor } from '@/lib/totals' | ||
import { formatCurrency } from '@/lib/utils' | ||
import { useEffect, useState } from 'react' | ||
|
||
|
||
type Props = { | ||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>> | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>> | ||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>> | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>> | ||
} | ||
|
||
export function TotalsYourSpendings({ group, expenses }: Props) { | ||
|
||
const [activeUser, setActiveUser] = useState('') | ||
|
||
useEffect(() => { | ||
const activeUser = localStorage.getItem(`${group.id}-activeUser`) | ||
if (activeUser) setActiveUser(activeUser) | ||
|
||
}, [group, expenses]) | ||
|
||
const totalYourSpendings = (activeUser === '' || activeUser === 'None') ? 0 : getTotalActiveUserPaidFor(activeUser, expenses) | ||
const currency = group.currency | ||
|
||
return ( | ||
<div> | ||
<div className="text-muted-foreground"> | ||
Total you paid for | ||
</div> | ||
|
||
<div className="text-lg"> | ||
{formatCurrency(currency, totalYourSpendings)} | ||
</div> | ||
</div> | ||
|
||
) | ||
} | ||
const [activeUser, setActiveUser] = useState('') | ||
|
||
useEffect(() => { | ||
const activeUser = localStorage.getItem(`${group.id}-activeUser`) | ||
if (activeUser) setActiveUser(activeUser) | ||
}, [group, expenses]) | ||
|
||
const totalYourSpendings = | ||
activeUser === '' || activeUser === 'None' | ||
? 0 | ||
: getTotalActiveUserPaidFor(activeUser, expenses) | ||
const currency = group.currency | ||
|
||
return ( | ||
<div> | ||
<div className="text-muted-foreground">Total you paid for</div> | ||
|
||
<div className="text-lg"> | ||
{formatCurrency(currency, totalYourSpendings)} | ||
</div> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,66 @@ | ||
import { getGroupExpenses } from "@/lib/api"; | ||
import { match } from 'ts-pattern' | ||
import { getGroupExpenses } from '@/lib/api' | ||
|
||
export function getTotalGroupSpending(expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>): number { | ||
return expenses.reduce((total, expense) => (!expense.isReimbursement ? total + expense.amount : total + 0), 0) | ||
export function getTotalGroupSpending( | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>, | ||
): number { | ||
return expenses.reduce( | ||
(total, expense) => | ||
!expense.isReimbursement ? total + expense.amount : total + 0, | ||
0, | ||
) | ||
} | ||
|
||
export function getTotalActiveUserPaidFor(activeUserId: string | null, expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>): number { | ||
return expenses.reduce((total, expense) => (expense.paidBy.id === activeUserId ? total + expense.amount : total + 0),0) | ||
export function getTotalActiveUserPaidFor( | ||
activeUserId: string | null, | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>, | ||
): number { | ||
return expenses.reduce( | ||
(total, expense) => | ||
expense.paidBy.id === activeUserId ? total + expense.amount : total + 0, | ||
0, | ||
) | ||
} | ||
|
||
export function getTotalActiveUserShare(activeUserId: string | null, expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>): number { | ||
let total = 0; | ||
export function getTotalActiveUserShare( | ||
activeUserId: string | null, | ||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>, | ||
): number { | ||
let total = 0 | ||
|
||
expenses.forEach(expense => { | ||
const paidFors = expense.paidFor; | ||
const userPaidFor = paidFors.find(paidFor => paidFor.participantId === activeUserId); | ||
expenses.forEach((expense) => { | ||
const paidFors = expense.paidFor | ||
const userPaidFor = paidFors.find( | ||
(paidFor) => paidFor.participantId === activeUserId, | ||
) | ||
|
||
if (!userPaidFor) { | ||
// If the active user is not involved in the expense, skip it | ||
return; | ||
} | ||
if (!userPaidFor) { | ||
// If the active user is not involved in the expense, skip it | ||
return | ||
} | ||
|
||
switch (expense.splitMode) { | ||
case 'EVENLY': | ||
// Divide the total expense evenly among all participants | ||
total += expense.amount / paidFors.length; | ||
break; | ||
case 'BY_AMOUNT': | ||
// Directly add the user's share if the split mode is BY_AMOUNT | ||
total += userPaidFor.shares; | ||
break; | ||
case 'BY_PERCENTAGE': | ||
// Calculate the user's share based on their percentage of the total expense | ||
total += (expense.amount * userPaidFor.shares) / 10000; // Assuming shares are out of 10000 for percentage | ||
break; | ||
case 'BY_SHARES': | ||
// Calculate the user's share based on their shares relative to the total shares | ||
const totalShares = paidFors.reduce((sum, paidFor) => sum + paidFor.shares, 0); | ||
total += (expense.amount * userPaidFor.shares) / totalShares; | ||
break; | ||
} | ||
}); | ||
switch (expense.splitMode) { | ||
case 'EVENLY': | ||
// Divide the total expense evenly among all participants | ||
total += expense.amount / paidFors.length | ||
break | ||
case 'BY_AMOUNT': | ||
// Directly add the user's share if the split mode is BY_AMOUNT | ||
total += userPaidFor.shares | ||
break | ||
case 'BY_PERCENTAGE': | ||
// Calculate the user's share based on their percentage of the total expense | ||
total += (expense.amount * userPaidFor.shares) / 10000 // Assuming shares are out of 10000 for percentage | ||
break | ||
case 'BY_SHARES': | ||
// Calculate the user's share based on their shares relative to the total shares | ||
const totalShares = paidFors.reduce( | ||
(sum, paidFor) => sum + paidFor.shares, | ||
0, | ||
) | ||
total += (expense.amount * userPaidFor.shares) / totalShares | ||
break | ||
} | ||
}) | ||
|
||
return parseFloat(total.toFixed(2)); | ||
} | ||
return parseFloat(total.toFixed(2)) | ||
} |