Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions apps/frontend/component/escrow/ConditionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useState } from 'react';
import FulfillConditionModal from './FulfillConditionModal';

interface Condition {
id: string;
description: string;
fulfilled: boolean;
confirmed: boolean;
}

interface Props {
condition: Condition;
role: 'seller' | 'buyer';
}

const ConditionItem: React.FC<Props> = ({ condition, role }) => {
const [showModal, setShowModal] = useState(false);

const handleFulfill = () => setShowModal(true);
const handleConfirm = async () => {
// API call to confirm condition
await fetch(`/api/escrow/conditions/${condition.id}/confirm`, { method: 'POST' });
};

return (
<div className="condition-item">
<p>{condition.description}</p>
{role === 'seller' && !condition.fulfilled && (
<button onClick={handleFulfill}>Fulfill</button>
)}
{role === 'buyer' && condition.fulfilled && !condition.confirmed && (
<button onClick={handleConfirm}>Confirm</button>
)}
{showModal && (
<FulfillConditionModal
conditionId={condition.id}
onClose={() => setShowModal(false)}
/>
)}
</div>
);
};

export default ConditionItem;
26 changes: 26 additions & 0 deletions apps/frontend/component/escrow/ConditionsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import ConditionItem from './ConditionItem';

interface Condition {
id: string;
description: string;
fulfilled: boolean;
confirmed: boolean;
}

interface Props {
conditions: Condition[];
role: 'seller' | 'buyer';
}

const ConditionsList: React.FC<Props> = ({ conditions, role }) => {
return (
<div>
{conditions.map((condition) => (
<ConditionItem key={condition.id} condition={condition} role={role} />
))}
</div>
);
};

export default ConditionsList;
40 changes: 40 additions & 0 deletions apps/frontend/component/escrow/FulfillConditionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useState } from 'react';

interface Props {
conditionId: string;
onClose: () => void;
}

const FulfillConditionModal: React.FC<Props> = ({ conditionId, onClose }) => {
const [notes, setNotes] = useState('');
const [file, setFile] = useState<File | null>(null);

const handleSubmit = async () => {
const formData = new FormData();
formData.append('notes', notes);
if (file) formData.append('evidence', file);

await fetch(`/api/escrow/conditions/${conditionId}/fulfill`, {
method: 'POST',
body: formData,
});

onClose();
};

return (
<div className="modal">
<h3>Fulfill Condition</h3>
<textarea
value={notes}
onChange={(e) => setNotes(e.target.value)}
placeholder="Add notes or evidence..."
/>
<input type="file" onChange={(e) => setFile(e.target.files?.[0] || null)} />
<button onClick={handleSubmit}>Submit</button>
<button onClick={onClose}>Cancel</button>
</div>
);
};

export default FulfillConditionModal;
68 changes: 68 additions & 0 deletions apps/frontend/component/escrow/modals/FundEscrowModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useState, useContext } from 'react';
import { WalletContext } from '../../services/WalletContext';

interface Props {
escrowId: string;
onClose: () => void;
}

const FundEscrowModal: React.FC<Props> = ({ escrowId, onClose }) => {
const { connectWallet, signTransaction } = useContext(WalletContext);
const [amount, setAmount] = useState('');
const [fees, setFees] = useState('0.1'); // Example fee
const [status, setStatus] = useState<'idle' | 'pending' | 'success' | 'failed'>('idle');
const [txHash, setTxHash] = useState<string | null>(null);

const total = parseFloat(amount || '0') + parseFloat(fees);

const handleFund = async () => {
try {
setStatus('pending');
await connectWallet();

// Build transaction preview
const tx = {
escrowId,
amount,
fees,
};

// Sign and submit transaction
const result = await signTransaction(tx);
setTxHash(result.hash);
setStatus('success');
} catch (err) {
console.error(err);
setStatus('failed');
}
};

return (
<div className="modal">
<h3>Fund Escrow</h3>
<label>
Amount:
<input
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</label>
<p>Fees: {fees} XLM</p>
<p>Total: {total} XLM</p>

{status === 'idle' && <button onClick={handleFund}>Fund Escrow</button>}
{status === 'pending' && <p>Transaction pending...</p>}
{status === 'success' && (
<p>
Transaction successful! Hash: <code>{txHash}</code>
</p>
)}
{status === 'failed' && <p>Transaction failed. Please try again.</p>}

<button onClick={onClose}>Close</button>
</div>
);
};

export default FundEscrowModal;
Loading