Skip to content

Commit 2c2990f

Browse files
Merge pull request #177 from Nemenwa/Escrow
Allow clients to fund escrow directly from their Stellar wallet.
2 parents b745f56 + d240d4b commit 2c2990f

4 files changed

Lines changed: 792 additions & 1 deletion

File tree

app/dashboard/contracts/[id]/page.tsx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ProfileCard } from "@/components/dashboard/profile-card";
1111
import { ContractMilestoneList, type ContractMilestone } from "@/components/dashboard/contract-milestone-list";
1212
import { ContractEscrowSummary } from "@/components/dashboard/contract-escrow-summary";
1313
import { EscrowStatusTracker, type EscrowStage } from "@/components/dashboard/escrow-status-tracker";
14+
import { EscrowFundingDialog } from "@/components/dashboard/escrow-funding-dialog";
1415

1516
interface ProfileInfo {
1617
display_name: string | null;
@@ -72,6 +73,7 @@ export default function ContractDetailPage() {
7273
const [contract, setContract] = useState<ContractDetail | null>(null);
7374
const [loading, setLoading] = useState(true);
7475
const [error, setError] = useState<string | null>(null);
76+
const [fundingDialogOpen, setFundingDialogOpen] = useState(false);
7577

7678
useEffect(() => {
7779
if (!id) return;
@@ -95,6 +97,29 @@ export default function ContractDetailPage() {
9597
})();
9698
}, [id]);
9799

100+
const handleFundingSuccess = () => {
101+
// Reload contract data to show updated escrow status
102+
if (id) {
103+
(async () => {
104+
try {
105+
const res = await fetch(`/api/contracts/${id}`, {
106+
headers: getAuthHeaders(),
107+
credentials: "include",
108+
});
109+
if (res.ok) {
110+
const data = await res.json();
111+
setContract(data.contract);
112+
}
113+
} catch (err) {
114+
console.error("Failed to reload contract:", err);
115+
}
116+
})();
117+
}
118+
};
119+
120+
// Check if funding button should be shown
121+
const canFund = contract && contract.escrow && contract.escrow.escrow_status === "unfunded" && contract.escrow.escrow_address;
122+
98123
if (loading) {
99124
return (
100125
<div className="flex items-center justify-center min-h-[60vh] text-muted-foreground gap-2">
@@ -185,9 +210,33 @@ export default function ContractDetailPage() {
185210
)}
186211
</div>
187212
</Card>
188-
<ContractEscrowSummary escrow={contract.escrow} currency={contract.currency} />
213+
<div className="md:col-span-2">
214+
<ContractEscrowSummary escrow={contract.escrow} currency={contract.currency} />
215+
{canFund && (
216+
<div className="mt-4 flex justify-end">
217+
<Button
218+
onClick={() => setFundingDialogOpen(true)}
219+
className="bg-accent hover:bg-accent/90"
220+
>
221+
<Wallet className="h-4 w-4 mr-2" />
222+
Fund Escrow
223+
</Button>
224+
</div>
225+
)}
226+
</div>
189227
</div>
190228
</div>
229+
230+
{/* Escrow Funding Dialog */}
231+
<EscrowFundingDialog
232+
open={fundingDialogOpen}
233+
onOpenChange={setFundingDialogOpen}
234+
contractId={contract.id}
235+
contractAddress={contract.escrow?.escrow_address ?? null}
236+
requiredAmount={contract.total_amount}
237+
currency={contract.currency}
238+
onFundingSuccess={handleFundingSuccess}
239+
/>
191240
</div>
192241
);
193242
}

0 commit comments

Comments
 (0)