diff --git a/app/contacts/components/ContactDetailsPanel.tsx b/app/contacts/components/ContactDetailsPanel.tsx index f209ca1..783b584 100644 --- a/app/contacts/components/ContactDetailsPanel.tsx +++ b/app/contacts/components/ContactDetailsPanel.tsx @@ -294,7 +294,8 @@ export function ContactDetailsPanel({ contact, isOpen, onClose }: ContactDetails ? "text-gray-900 dark:text-white" : "text-brand-green dark:text-brand-gold" )}> - {txn.senderWallet?.userId === userId ? '-' : '+'}RWF {parseFloat(txn.amount).toLocaleString()} + {/* A covered split share came from their wallet, not yours: no +/- */} + {txn.coveredShare ? '' : txn.senderWallet?.userId === userId ? '-' : '+'}RWF {parseFloat(txn.amount).toLocaleString()} )) diff --git a/app/home/bills/[billId]/page.tsx b/app/home/bills/[billId]/page.tsx new file mode 100644 index 0000000..b435f2d --- /dev/null +++ b/app/home/bills/[billId]/page.tsx @@ -0,0 +1,36 @@ +"use client"; +import React from "react"; +import { useParams } from "next/navigation"; +import Navigation from "@/components/Navigation"; +import { Header } from "@/components/Header"; +import BillDetail from "@/components/bills/BillDetail"; +import { useSidebar } from "@/context/SidebarContext"; +import { cn } from "@/lib/utils"; +import { useAccent } from "@/hooks/use-accent"; + +const BillDetailPage = () => { + const { isExpanded } = useSidebar(); + const accent = useAccent(); + const params = useParams<{ billId: string }>(); + + return ( +
Manage your pending payments
You haven't sent any payment requests yet
+You haven't sent any payment requests yet
{error || "No request details found. The link may be invalid or expired."} @@ -434,6 +438,17 @@ const AmountPageInner = () => { const isQRFlow = !!requestId && !!requestMeta; const allowEditAmount = requestMeta ? requestMeta.allowEditAmount : true; + // Splitting is a person-to-person/business feature: not for payment requests, scheduled + // transfers, raw wallet ids, or when sending from an organization/sub-action wallet. + const selectedSender = getSelectedSenderFromSession(); + const canSplit = + !isQRFlow && + !schedule.enabled && + recipient.type !== "wallet" && + !recipient.walletId && + (!selectedSender || selectedSender.type === "user"); + const splitActive = splitEnabled && canSplit; + return (
"{requestMeta.note}"
+“{requestMeta.note}”
)}This split isn't available anymore.
+ ++ To {bill.recipient?.name ?? "recipient"} + {bill.recipient?.type === "organization" && " (business)"} · organized by{" "} + {isOrganizer ? "you" : bill.organizer.name} +
+"{bill.note}"
} + +Paid in the app
++ {fmt(bill.paidInAmount)} of {fmt(bill.totalAmount)} {bill.currency} +
++ The remaining {fmt(bill.totalAmount - bill.paidInAmount)} {bill.currency} was settled outside the app. +
+ )} +Your share
++ {fmt(myShare.amount)} {bill.currency} +
++ Goes straight to {bill.recipient?.name}. Nothing passes through {isOrganizer ? "anyone else" : bill.organizer.name}. +
+You declined this. You can still pay it until it is resolved.
+ )} ++ {share.payerId === myId ? "You" : share.payerName} +
+ {share.status === "covered" && share.paidByName && ( +covered by {share.paidByUserId === myId ? "you" : share.paidByName}
+ )} + {share.status === "declined" && share.declineNote && ( +"{share.declineNote}"
+ )} ++ Some shares are already paid, so this split can't be cancelled. Mark the rest as settled outside the app to close it. +
+ )} + + {/* Pay my own share */} + {myShare && ( +No other contacts available.
+ ) : ( +Or give it to someone who isn't a contact:
++ Start one from Send Money by turning on "Split this payment". +
+Nothing here yet.
+{b.title}
++ To {b.recipient?.name ?? "recipient"} · {b.role === "organizer" ? "you organized" : `by ${b.organizer.name}`} +
+