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
42 changes: 27 additions & 15 deletions donorfront/src/App.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Navigation from './Navigation';
import BeneficiaryList from './BeneficiaryList';
import BeneficiaryDetails from './BeneficiaryDetails';
import DonationForm from './DonationForm';
import UtilizationList from './UtilizationList';
import AdminPanel from './AdminPanel';
import { useWeb3 } from '../hooks/useWeb3';
// import { getContractInstance } from '../utils/contractHelpers';
import UserDashboard from './UserDashboard';
import { Web3Provider } from '../contexts/Web3Context';
import { UserProvider } from '../contexts/UserContext';

const App = () => {
const [userRole, setUserRole] = useState(null);
const [beneficiaries, setBeneficiaries] = useState([]);
const [donations, setDonations] = useState([]);
const [utilizations, setUtilizations] = useState([]);
const { account, web3 } = useWeb3();

useEffect(() => {
// TODO: Fetch user role, beneficiaries, donations, and utilizations from the smart contract
// TODO: Fetch user role from the smart contract
}, []);

return (
<div className="app">
<h1>Charity Smart Contract UI</h1>
<BeneficiaryList beneficiaries={beneficiaries} />
<DonationForm beneficiaries={beneficiaries} />
<UtilizationList utilizations={utilizations} />
{userRole === 'ROLE_ADMIN' && <AdminPanel />}
</div>
<Web3Provider>
<UserProvider>
<Router>
<div className="min-h-screen bg-gray-50 text-gray-900">
<Navigation userRole={userRole} />
<main className="container mx-auto px-4 py-8">
<Switch>
<Route exact path="/" component={BeneficiaryList} />
<Route path="/beneficiary/:id" component={BeneficiaryDetails} />
<Route path="/donate/:id" component={DonationForm} />
<Route path="/utilization/:id" component={UtilizationList} />
{userRole === 'admin' && <Route path="/admin" component={AdminPanel} />}
<Route path="/dashboard" component={UserDashboard} />
</Switch>
</main>
</div>
</Router>
</UserProvider>
</Web3Provider>
);
};

export default App;
export default App;
Empty file added donorfront/src/UserDashboard.js
Empty file.
160 changes: 93 additions & 67 deletions donorfront/src/components/AdminPanel.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,107 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { useWeb3 } from '../hooks/useWeb3';
import { getBeneficiaries, registerBeneficiary, approveUtilization } from '../utils/contractHelpers';

const AdminPanel = () => {
const [beneficiaryName, setBeneficiaryName] = useState('');
const [beneficiaryDescription, setBeneficiaryDescription] = useState('');
const [beneficiaryTargetAmount, setBeneficiaryTargetAmount] = useState('');
const [utilizationBeneficiaryId, setUtilizationBeneficiaryId] = useState('');
const [utilizationDescription, setUtilizationDescription] = useState('');
const [utilizationAmount, setUtilizationAmount] = useState('');
const [beneficiaries, setBeneficiaries] = useState([]);
const [newBeneficiary, setNewBeneficiary] = useState({ name: '', description: '', targetAmount: '' });
const [utilizationRequests, setUtilizationRequests] = useState([]);
const { contract, address } = useWeb3();

const handleRegisterBeneficiary = (e) => {
e.preventDefault();
// TODO: Call the register-beneficiary function from the smart contract
console.log('Register beneficiary:', { beneficiaryName, beneficiaryDescription, beneficiaryTargetAmount });
useEffect(() => {
fetchBeneficiaries();
fetchUtilizationRequests();
}, [contract]);

const fetchBeneficiaries = async () => {
if (contract) {
const beneficiaryList = await getBeneficiaries(contract);
setBeneficiaries(beneficiaryList);
}
};

const fetchUtilizationRequests = async () => {
// TODO: Implement fetching utilization requests from the contract
};

const handleAddUtilization = (e) => {
const handleRegisterBeneficiary = async (e) => {
e.preventDefault();
// TODO: Call the add-utilization function from the smart contract
console.log('Add utilization:', { utilizationBeneficiaryId, utilizationDescription, utilizationAmount });
try {
await registerBeneficiary(contract, address, newBeneficiary.name, newBeneficiary.description, newBeneficiary.targetAmount);
setNewBeneficiary({ name: '', description: '', targetAmount: '' });
fetchBeneficiaries();
} catch (error) {
console.error('Error registering beneficiary:', error);
}
};

const handleApproveUtilization = async (beneficiaryId, milestoneId) => {
try {
await approveUtilization(contract, address, beneficiaryId, milestoneId);
fetchUtilizationRequests();
} catch (error) {
console.error('Error approving utilization:', error);
}
};

return (
<div className="admin-panel">
<h2>Admin Panel</h2>
<form onSubmit={handleRegisterBeneficiary}>
<h3>Register Beneficiary</h3>
<input
type="text"
value={beneficiaryName}
onChange={(e) => setBeneficiaryName(e.target.value)}
placeholder="Name"
required
/>
<input
type="text"
value={beneficiaryDescription}
onChange={(e) => setBeneficiaryDescription(e.target.value)}
placeholder="Description"
required
/>
<input
type="number"
value={beneficiaryTargetAmount}
onChange={(e) => setBeneficiaryTargetAmount(e.target.value)}
placeholder="Target Amount"
required
/>
<button type="submit">Register Beneficiary</button>
</form>
<div className="space-y-8">
<h1 className="text-3xl font-bold text-blue-800">Admin Panel</h1>

<div className="bg-white shadow-md rounded-lg p-6">
<h2 className="text-2xl font-semibold mb-4 text-blue-700">Register New Beneficiary</h2>
<form onSubmit={handleRegisterBeneficiary} className="space-y-4">
<input
type="text"
placeholder="Beneficiary Name"
value={newBeneficiary.name}
onChange={(e) => setNewBeneficiary({...newBeneficiary, name: e.target.value})}
className="w-full p-2 border border-gray-300 rounded"
required
/>
<textarea
placeholder="Description"
value={newBeneficiary.description}
onChange={(e) => setNewBeneficiary({...newBeneficiary, description: e.target.value})}
className="w-full p-2 border border-gray-300 rounded"
required
></textarea>
<input
type="number"
placeholder="Target Amount"
value={newBeneficiary.targetAmount}
onChange={(e) => setNewBeneficiary({...newBeneficiary, targetAmount: e.target.value})}
className="w-full p-2 border border-gray-300 rounded"
required
/>
<button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors">
Register Beneficiary
</button>
</form>
</div>

<form onSubmit={handleAddUtilization}>
<h3>Add Utilization</h3>
<input
type="number"
value={utilizationBeneficiaryId}
onChange={(e) => setUtilizationBeneficiaryId(e.target.value)}
placeholder="Beneficiary ID"
required
/>
<input
type="text"
value={utilizationDescription}
onChange={(e) => setUtilizationDescription(e.target.value)}
placeholder="Description"
required
/>
<input
type="number"
value={utilizationAmount}
onChange={(e) => setUtilizationAmount(e.target.value)}
placeholder="Amount"
required
/>
<button type="submit">Add Utilization</button>
</form>
<div className="bg-white shadow-md rounded-lg p-6">
<h2 className="text-2xl font-semibold mb-4 text-blue-700">Utilization Requests</h2>
{utilizationRequests.length === 0 ? (
<p>No pending utilization requests.</p>
) : (
<ul className="space-y-4">
{utilizationRequests.map((request) => (
<li key={request.id} className="flex justify-between items-center">
<span>{request.description} - {request.amount} STX</span>
<button
onClick={() => handleApproveUtilization(request.beneficiaryId, request.milestoneId)}
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 transition-colors"
>
Approve
</button>
</li>
))}
</ul>
)}
</div>
</div>
);
};

export default AdminPanel;
export default AdminPanel;
Empty file.
64 changes: 49 additions & 15 deletions donorfront/src/components/BeneficiaryList.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useWeb3 } from '../hooks/useWeb3';
import { getBeneficiaries } from '../utils/contractHelpers';

const BeneficiaryList = () => {
const [beneficiaries, setBeneficiaries] = useState([]);
const { contract } = useWeb3();

useEffect(() => {
const fetchBeneficiaries = async () => {
if (contract) {
const beneficiaryList = await getBeneficiaries(contract);
setBeneficiaries(beneficiaryList);
}
};

fetchBeneficiaries();
}, [contract]);

const BeneficiaryList = ({ beneficiaries }) => {
return (
<div className="beneficiary-list">
<h2>Beneficiaries</h2>
<ul>
<div className="space-y-8">
<h1 className="text-3xl font-bold text-blue-800">Beneficiaries</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{beneficiaries.map((beneficiary) => (
<li key={beneficiary.id}>
<h3>{beneficiary.name}</h3>
<p>{beneficiary.description}</p>
<p>Target Amount: {beneficiary.targetAmount}</p>
<p>Received Amount: {beneficiary.receivedAmount}</p>
<p>Status: {beneficiary.status}</p>
</li>
<div key={beneficiary.id} className="bg-white shadow-md rounded-lg overflow-hidden transition-shadow hover:shadow-lg">
<div className="p-6">
<h2 className="text-xl font-semibold mb-2 text-blue-700">{beneficiary.name}</h2>
<p className="text-gray-600 mb-4">{beneficiary.description}</p>
<div className="flex justify-between items-center">
<span className="text-blue-600 font-semibold">
{beneficiary.receivedAmount} / {beneficiary.targetAmount} STX
</span>
<Link
to={`/beneficiary/${beneficiary.id}`}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors"
>
View Details
</Link>
</div>
</div>
<div className="bg-blue-100 px-6 py-4">
<div className="w-full bg-blue-200 rounded-full h-2.5">
<div
className="bg-blue-600 h-2.5 rounded-full"
style={{ width: `${(beneficiary.receivedAmount / beneficiary.targetAmount) * 100}%` }}
></div>
</div>
</div>
</div>
))}
</ul>
</div>
</div>
);
};

export default BeneficiaryList;

export default BeneficiaryList;
Loading