awesome ui changes

This commit is contained in:
2025-04-07 19:58:58 +02:00
parent 0cec39717e
commit 2ddbef6627
52 changed files with 1965 additions and 484 deletions
+117
View File
@@ -0,0 +1,117 @@
import type { SplitType } from "@/hooks/use-expense-split";
export type Debt = {
from: string;
to: string;
amount: number;
};
export type Payment = {
userId: string;
amount: number;
};
export function calculateSplits(args: {
amount: number;
users: Array<string>;
splitType: SplitType;
payments?: Array<Payment>;
}): Record<string, string> {
const result: Record<string, string> = {};
const { splitType = "Equal", amount, users, payments } = args;
// If splits are provided, validate them
// const amount = Object.values(payments).reduce((sum, value) => sum + value, 0);
switch (splitType) {
case "Equal":
var splits: Record<string, string> = {};
users.forEach((userId) => {
splits[userId] = `${amount / users.length}€`;
});
return splits;
// case "Percentage":
// if (!customDepts) {
// throw new Error("Splits must be provided for percentage type.");
// }
// participants.forEach((userId) => {
// if (customDepts[userId] !== undefined) {
// const percentage = customDepts[userId] / 100;
// const amountSplit = amount * percentage;
// result[userId] = `${amountSplit.toFixed(2)}%`; // Add "%" for percentage
// } else {
// throw new Error(`No percentage split defined for user ID: ${userId}`);
// }
// });
// break;
// case "Fixed":
// if (!customDepts) {
// throw new Error("Splits must be provided for fixed type.");
// }
// participants.forEach((userId) => {
// if (customDepts[userId] !== undefined) {
// result[userId] = `${customDepts[userId].toFixed(2)}`; // Format to 2 decimal places
// } else {
// throw new Error(`No fixed amount defined for user ID: ${userId}`);
// }
// });
// break;
default:
return {};
// throw new Error("Invalid split type.");
}
return result;
}
export function calculateDepts(
total: number,
users: string[],
payments: Array<Payment>
): Debt[] {
console.log("Payments: ", payments);
const share = total / users.length;
const balances: Record<string, number> = {};
// Initialize balances
users.forEach((userId) => {
const paid = payments.find((p) => p.userId === userId)?.amount || 0;
balances[userId] = paid - share;
});
// Separate creditors and debtors
const creditors = Object.entries(balances)
.filter(([_, balance]) => balance > 0)
.map(([userId, balance]) => ({ userId, balance }));
const debtors = Object.entries(balances)
.filter(([_, balance]) => balance < 0)
.map(([userId, balance]) => ({ userId, balance: -balance }));
const debts: Debt[] = [];
for (const debtor of debtors) {
let amountToPay = debtor.balance;
for (const creditor of creditors) {
if (amountToPay === 0) break;
if (creditor.balance === 0) continue;
const payment = Math.min(amountToPay, creditor.balance);
debts.push({
from: debtor.userId,
to: creditor.userId,
amount: parseFloat(payment.toFixed(2)), // for rounding safety
});
amountToPay -= payment;
creditor.balance -= payment;
}
}
return debts;
}
-3
View File
@@ -3,13 +3,10 @@ import { z } from "zod";
export const expenseSchema = z.object({
amount: z.number().min(0.01),
description: z.string().optional(),
friendId: z.string().optional(),
groupId: z.string().optional(),
});
export const expenseSplitSchema = z.object({
expenseId: z.string(),
groupId: z.string().optional(),
paidById: z.string().min(1),
owedById: z.string().min(1),
amount: z.number().min(1),