2024-03-13 17:34:07 -05:00
|
|
|
import {
|
2024-03-18 14:03:53 -05:00
|
|
|
useCallback, useEffect, useState, useMemo,
|
2024-03-13 17:34:07 -05:00
|
|
|
} from 'react';
|
2024-03-07 21:27:37 -06:00
|
|
|
import { useSDK } from '@metamask/sdk-react';
|
2024-03-07 10:58:55 -06:00
|
|
|
import { Web3 } from 'web3';
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-07 21:27:37 -06:00
|
|
|
import Button from 'react-bootstrap/Button';
|
2024-03-14 18:38:54 -05:00
|
|
|
import Tab from 'react-bootstrap/Tab';
|
|
|
|
import Tabs from 'react-bootstrap/Tabs';
|
|
|
|
import Container from 'react-bootstrap/Container';
|
|
|
|
import Row from 'react-bootstrap/Row';
|
|
|
|
import Col from 'react-bootstrap/Col';
|
|
|
|
import Stack from 'react-bootstrap/Stack';
|
2024-03-13 16:14:59 -05:00
|
|
|
|
2024-03-20 09:32:50 -05:00
|
|
|
import './App.css';
|
|
|
|
|
2024-03-19 22:22:36 -05:00
|
|
|
import useList from './utils/List';
|
2024-03-20 16:30:27 -05:00
|
|
|
import { getContractAddressByChainId, getContractNameByAddress } from './utils/contract-config';
|
2024-03-19 22:22:36 -05:00
|
|
|
import Web3Context from './contexts/Web3Context';
|
2024-03-17 13:24:49 -05:00
|
|
|
import DAOArtifact from './assets/DAO.json';
|
2024-03-18 14:03:53 -05:00
|
|
|
import Work1Artifact from './assets/Work1.json';
|
|
|
|
import OnboardingArtifact from './assets/Onboarding.json';
|
2024-03-20 20:00:56 -05:00
|
|
|
import WorkContract from './components/work-contracts/WorkContract';
|
|
|
|
import AddPostModal from './components/posts/AddPostModal';
|
|
|
|
import ViewPostModal from './components/posts/ViewPostModal';
|
|
|
|
import Post from './utils/Post';
|
2024-03-28 18:01:55 -05:00
|
|
|
import Proposals from './components/Proposals';
|
2024-03-14 18:08:17 -05:00
|
|
|
|
2024-02-21 18:01:41 -06:00
|
|
|
function App() {
|
2024-03-07 21:27:37 -06:00
|
|
|
const {
|
|
|
|
sdk, connected, provider, chainId, account, balance,
|
|
|
|
} = useSDK();
|
|
|
|
|
|
|
|
const [DAO, setDAO] = useState();
|
2024-03-13 17:34:07 -05:00
|
|
|
const [work1, setWork1] = useState();
|
2024-03-18 14:03:53 -05:00
|
|
|
const [onboarding, setOnboarding] = useState();
|
2024-03-07 21:27:37 -06:00
|
|
|
const [balanceEther, setBalanceEther] = useState();
|
2024-03-14 14:40:27 -05:00
|
|
|
const [reputation, setReputation] = useState();
|
2024-03-10 19:39:15 -05:00
|
|
|
const [totalReputation, setTotalReputation] = useState();
|
2024-03-14 18:08:17 -05:00
|
|
|
const [posts, dispatchPost] = useList();
|
|
|
|
const [validationPools, dispatchValidationPool] = useList();
|
2024-03-07 21:27:37 -06:00
|
|
|
|
2024-03-19 22:22:36 -05:00
|
|
|
const [showAddPost, setShowAddPost] = useState(false);
|
|
|
|
const [showViewPost, setShowViewPost] = useState(false);
|
2024-03-29 12:19:34 -05:00
|
|
|
const [viewPost, setViewPost] = useState({});
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-16 21:42:22 -05:00
|
|
|
const web3ProviderValue = useMemo(() => ({
|
|
|
|
provider,
|
|
|
|
DAO,
|
|
|
|
work1,
|
2024-03-18 14:03:53 -05:00
|
|
|
onboarding,
|
2024-03-16 21:42:22 -05:00
|
|
|
reputation,
|
|
|
|
setReputation,
|
|
|
|
account,
|
|
|
|
chainId,
|
|
|
|
}), [
|
2024-03-18 14:03:53 -05:00
|
|
|
provider, DAO, work1, onboarding, reputation, setReputation, account, chainId]);
|
2024-03-16 21:42:22 -05:00
|
|
|
|
2024-03-13 17:34:07 -05:00
|
|
|
// In this effect, we initialize everything and add contract event listeners.
|
2024-03-07 21:27:37 -06:00
|
|
|
useEffect(() => {
|
2024-03-29 10:59:29 -05:00
|
|
|
if (!provider || !chainId || !account || balance === undefined) return () => {};
|
2024-03-20 16:30:27 -05:00
|
|
|
const DAOAddress = getContractAddressByChainId(chainId, 'DAO');
|
|
|
|
const Work1Address = getContractAddressByChainId(chainId, 'Work1');
|
|
|
|
const OnboardingAddress = getContractAddressByChainId(chainId, 'Onboarding');
|
2024-03-07 21:27:37 -06:00
|
|
|
const web3 = new Web3(provider);
|
2024-03-17 11:06:10 -05:00
|
|
|
const DAOContract = new web3.eth.Contract(DAOArtifact.abi, DAOAddress);
|
2024-03-18 14:03:53 -05:00
|
|
|
const Work1Contract = new web3.eth.Contract(Work1Artifact.abi, Work1Address);
|
|
|
|
const OnboardingContract = new web3.eth.Contract(OnboardingArtifact.abi, OnboardingAddress);
|
|
|
|
|
|
|
|
setDAO(DAOContract);
|
|
|
|
setWork1(Work1Contract);
|
|
|
|
setOnboarding(OnboardingContract);
|
2024-03-10 19:39:15 -05:00
|
|
|
|
2024-03-14 14:40:27 -05:00
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- BEGIN FETCHERS ------------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
|
2024-03-10 11:55:59 -05:00
|
|
|
const fetchReputation = async () => {
|
2024-03-16 21:19:57 -05:00
|
|
|
setReputation(await DAOContract.methods.balanceOf(account).call());
|
|
|
|
setTotalReputation(await DAOContract.methods.totalSupply().call());
|
2024-03-14 14:40:27 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
const fetchPost = async (postIndex) => {
|
|
|
|
const p = await DAOContract.methods.posts(postIndex).call();
|
|
|
|
p.id = Number(p.id);
|
2024-03-14 14:47:34 -05:00
|
|
|
dispatchPost({ type: 'update', item: p });
|
2024-03-14 14:40:27 -05:00
|
|
|
return p;
|
2024-03-07 21:27:37 -06:00
|
|
|
};
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-12 17:53:04 -05:00
|
|
|
const fetchPosts = async () => {
|
|
|
|
const count = await DAOContract.methods.postCount().call();
|
|
|
|
const promises = [];
|
2024-03-14 14:47:34 -05:00
|
|
|
dispatchPost({ type: 'refresh' });
|
2024-03-12 17:53:04 -05:00
|
|
|
for (let i = 0; i < count; i += 1) {
|
2024-03-14 14:40:27 -05:00
|
|
|
promises.push(fetchPost(i));
|
2024-03-12 17:53:04 -05:00
|
|
|
}
|
2024-03-14 14:40:27 -05:00
|
|
|
await Promise.all(promises);
|
2024-03-12 17:53:04 -05:00
|
|
|
};
|
|
|
|
|
2024-03-14 14:40:27 -05:00
|
|
|
const fetchValidationPool = async (poolIndex) => {
|
2024-03-14 18:08:17 -05:00
|
|
|
const getPoolStatus = (pool) => {
|
|
|
|
if (pool.resolved) {
|
|
|
|
return pool.outcome ? 'Accepted' : 'Rejected';
|
|
|
|
}
|
|
|
|
return pool.timeRemaining > 0 ? 'In Progress' : 'Ready to Evaluate';
|
|
|
|
};
|
2024-03-14 14:40:27 -05:00
|
|
|
const pool = await DAOContract.methods.validationPools(poolIndex).call();
|
|
|
|
pool.id = Number(pool.id);
|
|
|
|
pool.timeRemaining = new Date(Number(pool.endTime) * 1000) - new Date();
|
|
|
|
pool.status = getPoolStatus(pool);
|
2024-03-14 15:02:23 -05:00
|
|
|
dispatchValidationPool({ type: 'update', item: pool });
|
2024-03-14 14:40:27 -05:00
|
|
|
|
|
|
|
// When remaing time expires, we want to update the status for this pool
|
|
|
|
if (pool.timeRemaining > 0) {
|
|
|
|
setTimeout(() => {
|
|
|
|
pool.timeRemaining = 0;
|
|
|
|
pool.status = getPoolStatus(pool);
|
2024-03-14 14:47:34 -05:00
|
|
|
dispatchValidationPool({ type: 'update', item: pool });
|
2024-03-14 14:40:27 -05:00
|
|
|
}, pool.timeRemaining);
|
|
|
|
}
|
2024-03-13 12:02:08 -05:00
|
|
|
};
|
|
|
|
|
2024-03-12 17:53:04 -05:00
|
|
|
const fetchValidationPools = async () => {
|
2024-03-13 12:02:08 -05:00
|
|
|
// TODO: Pagination
|
|
|
|
// TODO: Memoization
|
|
|
|
// TODO: Caching
|
2024-03-12 17:53:04 -05:00
|
|
|
const count = await DAOContract.methods.validationPoolCount().call();
|
|
|
|
const promises = [];
|
2024-03-14 14:47:34 -05:00
|
|
|
dispatchValidationPool({ type: 'refresh' });
|
2024-03-12 17:53:04 -05:00
|
|
|
for (let i = 0; i < count; i += 1) {
|
2024-03-14 14:40:27 -05:00
|
|
|
promises.push(fetchValidationPool(i));
|
2024-03-12 17:53:04 -05:00
|
|
|
}
|
2024-03-14 14:40:27 -05:00
|
|
|
await Promise.all(promises);
|
|
|
|
};
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- END FETCHERS --------------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
|
2024-03-10 11:55:59 -05:00
|
|
|
fetchReputation();
|
2024-03-12 17:53:04 -05:00
|
|
|
fetchPosts();
|
|
|
|
fetchValidationPools();
|
2024-03-10 11:55:59 -05:00
|
|
|
|
2024-03-14 21:26:31 -05:00
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- BEGIN EVENT HANDLERS ------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
|
2024-03-12 18:02:07 -05:00
|
|
|
DAOContract.events.PostAdded({ fromBlock: 'latest' }).on('data', (event) => {
|
2024-03-28 18:01:55 -05:00
|
|
|
console.log('event: post added');
|
2024-03-14 14:40:27 -05:00
|
|
|
fetchPost(event.returnValues.postIndex);
|
2024-03-12 18:02:07 -05:00
|
|
|
});
|
|
|
|
|
2024-03-10 11:55:59 -05:00
|
|
|
DAOContract.events.ValidationPoolInitiated({ fromBlock: 'latest' }).on('data', (event) => {
|
2024-03-28 18:01:55 -05:00
|
|
|
console.log('event: validation pool initiated');
|
2024-03-14 14:40:27 -05:00
|
|
|
fetchValidationPool(event.returnValues.poolIndex);
|
2024-03-10 11:55:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
DAOContract.events.ValidationPoolResolved({ fromBlock: 'latest' }).on('data', (event) => {
|
2024-03-28 18:01:55 -05:00
|
|
|
console.log('event: validation pool resolved');
|
2024-03-10 19:39:15 -05:00
|
|
|
fetchReputation();
|
2024-03-14 14:40:27 -05:00
|
|
|
fetchValidationPool(event.returnValues.poolIndex);
|
|
|
|
});
|
|
|
|
|
2024-03-18 14:03:53 -05:00
|
|
|
Work1Contract.events.AvailabilityStaked({ fromBlock: 'latest' }).on('data', () => {
|
2024-03-14 16:05:02 -05:00
|
|
|
fetchReputation();
|
|
|
|
});
|
|
|
|
|
2024-03-18 14:03:53 -05:00
|
|
|
OnboardingContract.events.AvailabilityStaked({ fromBlock: 'latest' }).on('data', () => {
|
|
|
|
fetchReputation();
|
2024-03-14 16:05:02 -05:00
|
|
|
});
|
2024-03-29 10:59:29 -05:00
|
|
|
|
|
|
|
return () => {
|
|
|
|
DAOContract.events.PostAdded().off();
|
|
|
|
DAOContract.events.ValidationPoolInitiated().off();
|
|
|
|
DAOContract.events.ValidationPoolResolved().off();
|
|
|
|
Work1Contract.events.AvailabilityStaked().off();
|
|
|
|
OnboardingContract.events.AvailabilityStaked().off();
|
|
|
|
};
|
2024-03-18 14:03:53 -05:00
|
|
|
}, [provider, account, chainId, balance, dispatchValidationPool, dispatchPost]);
|
2024-03-14 14:40:27 -05:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- END MAIN INITIALIZION EFFECT ----------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
2024-03-07 21:27:37 -06:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-03-10 19:39:15 -05:00
|
|
|
if (!provider || balance === undefined) return;
|
|
|
|
const web3 = new Web3(provider);
|
|
|
|
setBalanceEther(web3.utils.fromWei(balance, 'ether'));
|
2024-03-07 21:27:37 -06:00
|
|
|
}, [provider, balance]);
|
|
|
|
|
2024-03-14 18:08:17 -05:00
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- BEGIN UI ACTIONS ----------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
const connect = useCallback(async () => {
|
2024-03-07 21:27:37 -06:00
|
|
|
try {
|
|
|
|
await sdk?.connect();
|
|
|
|
} catch (err) {
|
|
|
|
console.warn('failed to connect..', err);
|
|
|
|
}
|
2024-03-14 18:08:17 -05:00
|
|
|
}, [sdk]);
|
2024-03-07 21:27:37 -06:00
|
|
|
|
2024-03-14 18:08:17 -05:00
|
|
|
const disconnect = useCallback(async () => {
|
2024-03-07 21:27:37 -06:00
|
|
|
try {
|
|
|
|
sdk?.terminate();
|
|
|
|
} catch (err) {
|
|
|
|
console.warn('failed to disconnect..', err);
|
|
|
|
}
|
2024-03-14 18:08:17 -05:00
|
|
|
}, [sdk]);
|
2024-03-07 21:27:37 -06:00
|
|
|
|
2024-03-14 21:26:31 -05:00
|
|
|
const watchReputationToken = useCallback(async () => {
|
|
|
|
await provider.request({
|
|
|
|
method: 'wallet_watchAsset',
|
|
|
|
params: {
|
|
|
|
type: 'ERC20',
|
|
|
|
options: {
|
2024-03-20 16:30:27 -05:00
|
|
|
address: getContractAddressByChainId(chainId, 'DAO'),
|
2024-03-14 21:26:31 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}, [provider, chainId]);
|
2024-03-14 14:40:27 -05:00
|
|
|
|
|
|
|
const initiateValidationPool = useCallback(async (postIndex, poolDuration) => {
|
2024-03-18 14:03:53 -05:00
|
|
|
const web3 = new Web3(provider);
|
|
|
|
await DAO.methods.initiateValidationPool(
|
|
|
|
postIndex,
|
|
|
|
poolDuration ?? 3600,
|
2024-03-28 15:06:14 -05:00
|
|
|
[1, 3],
|
|
|
|
[1, 2],
|
2024-03-26 18:28:38 -05:00
|
|
|
100,
|
|
|
|
true,
|
2024-03-18 14:03:53 -05:00
|
|
|
false,
|
|
|
|
web3.eth.abi.encodeParameter('bytes', '0x00'),
|
|
|
|
).send({
|
2024-03-07 21:27:37 -06:00
|
|
|
from: account,
|
|
|
|
gas: 1000000,
|
|
|
|
value: 100,
|
2024-03-07 10:58:55 -06:00
|
|
|
});
|
2024-03-18 14:03:53 -05:00
|
|
|
}, [provider, DAO, account]);
|
2024-03-07 10:58:55 -06:00
|
|
|
|
2024-03-14 14:40:27 -05:00
|
|
|
const stake = useCallback(async (poolIndex, amount, inFavor) => {
|
|
|
|
console.log(`Attempting to stake ${amount} ${inFavor ? 'for' : 'against'} pool ${poolIndex}`);
|
|
|
|
await DAO.methods.stake(poolIndex, amount, inFavor).send({
|
|
|
|
from: account,
|
|
|
|
gas: 999999,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Since this is the result we expect from the server, we preemptively set it here.
|
|
|
|
// We can let this value be negative -- this would just mean we'll be getting
|
|
|
|
// at least one error from the server, and a corrected reputation.
|
2024-03-16 21:19:57 -05:00
|
|
|
setReputation((current) => current - BigInt(amount));
|
2024-03-14 14:40:27 -05:00
|
|
|
}, [DAO, account, setReputation]);
|
|
|
|
|
2024-03-16 21:19:57 -05:00
|
|
|
const stakeHalfInFavor = useCallback(async (poolIndex) => {
|
|
|
|
await stake(poolIndex, reputation / BigInt(2), true);
|
2024-03-14 14:40:27 -05:00
|
|
|
}, [stake, reputation]);
|
|
|
|
|
|
|
|
const evaluateOutcome = useCallback(async (poolIndex) => {
|
2024-03-12 17:53:04 -05:00
|
|
|
await DAO.methods.evaluateOutcome(poolIndex).send({
|
2024-03-07 21:27:37 -06:00
|
|
|
from: account,
|
|
|
|
gas: 1000000,
|
|
|
|
});
|
2024-03-14 14:40:27 -05:00
|
|
|
}, [DAO, account]);
|
2024-03-07 21:27:37 -06:00
|
|
|
|
2024-03-19 22:22:36 -05:00
|
|
|
const handleShowAddPost = () => setShowAddPost(true);
|
2024-03-20 14:53:34 -05:00
|
|
|
|
2024-03-29 12:19:34 -05:00
|
|
|
const handleShowViewPost = useCallback(async ({ contentId }) => {
|
|
|
|
const post = await Post.read(contentId);
|
|
|
|
setViewPost(post);
|
2024-03-19 22:22:36 -05:00
|
|
|
setShowViewPost(true);
|
2024-03-29 12:19:34 -05:00
|
|
|
}, [setViewPost, setShowViewPost]);
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-14 14:40:27 -05:00
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
/* --------------------------- END UI ACTIONS ------------------------------------- */
|
|
|
|
/* -------------------------------------------------------------------------------- */
|
|
|
|
|
2024-03-18 14:03:53 -05:00
|
|
|
const getAdressName = useCallback((address) => {
|
|
|
|
const contractName = getContractNameByAddress(chainId, address);
|
|
|
|
if (contractName) return `${contractName} Contract`;
|
|
|
|
return address;
|
|
|
|
}, [chainId]);
|
|
|
|
|
2024-02-21 18:01:41 -06:00
|
|
|
return (
|
2024-03-16 20:34:36 -05:00
|
|
|
<Web3Context.Provider value={web3ProviderValue}>
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-20 14:26:56 -05:00
|
|
|
<AddPostModal show={showAddPost} setShow={setShowAddPost} postToBlockchain />
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-29 12:19:34 -05:00
|
|
|
<ViewPostModal show={showViewPost} setShow={setShowViewPost} post={viewPost} />
|
2024-03-19 22:22:36 -05:00
|
|
|
|
2024-03-07 21:27:37 -06:00
|
|
|
{!connected && <Button onClick={() => connect()}>Connect</Button>}
|
|
|
|
|
|
|
|
{connected && (
|
|
|
|
<>
|
2024-03-14 18:38:54 -05:00
|
|
|
<Container>
|
|
|
|
<Row>
|
|
|
|
<Col>
|
2024-03-17 11:06:10 -05:00
|
|
|
{chainId !== '0xaa36a7' && (
|
2024-03-14 18:38:54 -05:00
|
|
|
<div>
|
|
|
|
Please switch MetaMask to Sepolia testnet!
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Row>
|
|
|
|
<Col>
|
|
|
|
<Stack>
|
|
|
|
<div>
|
|
|
|
{chainId && `Chain ID: ${chainId}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{`Account: ${account}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{`Balance: ${balanceEther} ETH`}
|
|
|
|
</div>
|
|
|
|
</Stack>
|
|
|
|
</Col>
|
|
|
|
<Col>
|
|
|
|
<Stack>
|
|
|
|
<div>
|
2024-03-16 21:19:57 -05:00
|
|
|
{`Your REP: ${reputation?.toString()}`}
|
2024-03-14 18:38:54 -05:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-03-16 21:19:57 -05:00
|
|
|
{`Total REP: ${totalReputation?.toString()}`}
|
2024-03-14 18:38:54 -05:00
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<Button onClick={() => disconnect()}>Disconnect</Button>
|
2024-03-14 21:26:31 -05:00
|
|
|
<Button onClick={() => watchReputationToken()}>Watch REP in MetaMask</Button>
|
2024-03-14 18:38:54 -05:00
|
|
|
</div>
|
|
|
|
</Stack>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
</Container>
|
|
|
|
<Tabs>
|
|
|
|
<Tab eventKey="admin" title="Admin">
|
2024-03-20 14:26:56 -05:00
|
|
|
<h2>Posts</h2>
|
|
|
|
<div>
|
|
|
|
<Button onClick={handleShowAddPost}>Add Post</Button>
|
|
|
|
</div>
|
2024-03-14 18:38:54 -05:00
|
|
|
<div>
|
|
|
|
{`Posts count: ${posts.length}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<table className="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>ID</th>
|
|
|
|
<th>Author</th>
|
|
|
|
<th>Sender</th>
|
|
|
|
<th>Actions</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{posts.filter((x) => !!x).map((post) => (
|
|
|
|
<tr key={post.id}>
|
|
|
|
<td>{post.id.toString()}</td>
|
|
|
|
<td>{post.author}</td>
|
2024-03-18 14:03:53 -05:00
|
|
|
<td>{getAdressName(post.sender)}</td>
|
2024-03-14 18:38:54 -05:00
|
|
|
<td>
|
2024-03-19 22:22:36 -05:00
|
|
|
<Button onClick={() => handleShowViewPost(post)}>
|
|
|
|
View Post
|
|
|
|
</Button>
|
|
|
|
{' '}
|
2024-03-14 18:38:54 -05:00
|
|
|
Initiate Validation Pool
|
|
|
|
{' '}
|
2024-03-28 18:01:55 -05:00
|
|
|
<Button onClick={() => initiateValidationPool(post.id, 20)}>
|
|
|
|
20 s
|
2024-03-14 18:38:54 -05:00
|
|
|
</Button>
|
|
|
|
{' '}
|
|
|
|
<Button onClick={() => initiateValidationPool(post.id, 3600)}>
|
|
|
|
1 Hr.
|
2024-03-14 14:40:27 -05:00
|
|
|
</Button>
|
|
|
|
{' '}
|
2024-03-14 18:38:54 -05:00
|
|
|
<Button onClick={() => initiateValidationPool(post.id, 86400)}>
|
|
|
|
1 Day
|
|
|
|
</Button>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
2024-03-20 14:26:56 -05:00
|
|
|
<h2>Validation Pools</h2>
|
2024-03-14 18:38:54 -05:00
|
|
|
<div>
|
|
|
|
{`Validation Pool Count: ${validationPools.length}`}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<table className="table">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>ID</th>
|
|
|
|
<th>Post ID</th>
|
2024-03-18 14:03:53 -05:00
|
|
|
<th>Sender</th>
|
2024-03-14 18:38:54 -05:00
|
|
|
<th>Fee</th>
|
|
|
|
<th>Duration</th>
|
|
|
|
<th>End Time</th>
|
|
|
|
<th>
|
|
|
|
Stake
|
|
|
|
<br />
|
|
|
|
Count
|
|
|
|
</th>
|
|
|
|
<th>Status</th>
|
|
|
|
<th>Actions</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{validationPools.filter((x) => !!x).map((pool) => (
|
|
|
|
<tr key={pool.id}>
|
|
|
|
<td>{pool.id.toString()}</td>
|
|
|
|
<td>{pool.postIndex.toString()}</td>
|
2024-03-18 14:03:53 -05:00
|
|
|
<td>{getAdressName(pool.sender)}</td>
|
2024-03-14 18:38:54 -05:00
|
|
|
<td>{pool.fee.toString()}</td>
|
|
|
|
<td>{pool.duration.toString()}</td>
|
|
|
|
<td>{new Date(Number(pool.endTime) * 1000).toLocaleString()}</td>
|
|
|
|
<td>{pool.stakeCount.toString()}</td>
|
|
|
|
<td>{pool.status}</td>
|
|
|
|
<td>
|
|
|
|
{!pool.resolved && reputation > 0 && pool.timeRemaining > 0 && (
|
|
|
|
<>
|
2024-03-16 21:19:57 -05:00
|
|
|
<Button onClick={() => stakeHalfInFavor(pool.id)}>
|
|
|
|
Stake 1/2 REP
|
2024-03-14 18:38:54 -05:00
|
|
|
</Button>
|
|
|
|
{' '}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
{!pool.resolved && pool.timeRemaining <= 0 && (
|
|
|
|
<Button onClick={() => evaluateOutcome(pool.id)}>
|
|
|
|
Evaluate Outcome
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</Tab>
|
|
|
|
<Tab eventKey="worker" title="Worker">
|
2024-03-18 14:03:53 -05:00
|
|
|
{work1 && (
|
|
|
|
<WorkContract workContract={work1} title="Work Contract 1" verb="Work" />
|
|
|
|
)}
|
|
|
|
{onboarding && (
|
|
|
|
<WorkContract workContract={onboarding} title="Onboarding" verb="Onboarding" showRequestWork />
|
|
|
|
)}
|
2024-03-14 18:38:54 -05:00
|
|
|
</Tab>
|
|
|
|
<Tab eventKey="customer" title="Customer">
|
2024-03-18 14:03:53 -05:00
|
|
|
{work1 && (
|
|
|
|
<WorkContract
|
|
|
|
workContract={work1}
|
|
|
|
showAvailabilityActions={false}
|
|
|
|
showAvailabilityAmount={false}
|
|
|
|
onlyShowAvailable
|
|
|
|
title="Work Contract 1"
|
|
|
|
verb="Work"
|
|
|
|
showRequestWork
|
|
|
|
/>
|
|
|
|
)}
|
2024-03-14 18:38:54 -05:00
|
|
|
</Tab>
|
2024-03-28 18:01:55 -05:00
|
|
|
<Tab eventKey="proposals" title="Proposals">
|
|
|
|
<Proposals />
|
|
|
|
</Tab>
|
2024-03-14 18:38:54 -05:00
|
|
|
</Tabs>
|
2024-03-07 21:27:37 -06:00
|
|
|
</>
|
2024-03-07 10:58:55 -06:00
|
|
|
)}
|
2024-03-16 20:34:36 -05:00
|
|
|
</Web3Context.Provider>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-02-21 18:01:41 -06:00
|
|
|
export default App;
|