Skip to content

Commit

Permalink
Merge pull request #139 from PotLock/staging
Browse files Browse the repository at this point in the history
Staging => main
  • Loading branch information
M-Rb3 authored May 30, 2024
2 parents 98d2d89 + f756fb0 commit 770699e
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 71 deletions.
1 change: 0 additions & 1 deletion src/components/Card/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const CardContainer = styled.div`
min-height: 405px;
width: 100%;
height: 100%;
/* overflow: hidden; */
border-radius: 12px;
background: white;
box-shadow: 0px -2px 0px #dbdbdb inset;
Expand Down
6 changes: 4 additions & 2 deletions src/components/Inputs/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Props = {
onBlur?: (value: any) => void;
validate?: () => void;
error?: string;
defaultValue?: string;
preInputChildren?: any;
postInputChildren?: any;
disabled?: boolean;
Expand All @@ -22,7 +23,7 @@ type Props = {
const Text = (props: Props) => {
const label = props.label ?? "";
const placeholder = props.placeholder ?? "";
const value = props.value ?? "";
const value = props.value;
const onChange = props.onChange ?? (() => {});
const onBlur = props.onBlur ?? (() => {});
const validate = props.validate ?? (() => {});
Expand All @@ -35,8 +36,9 @@ const Text = (props: Props) => {
{props.preInputChildren && props.preInputChildren}
<Input
type="text"
defaultValue={props.defaultValue || ""}
placeholder={placeholder}
value={value}
{...(value !== undefined && { value })}
onChange={({ target: { value } }) => onChange(value)}
onBlur={(value) => {
validate();
Expand Down
4 changes: 2 additions & 2 deletions src/modals/ModalDonation/Banners/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AlertBanner } from "./styles";

const Alert = ({ error }: any) => (
<AlertBanner>
const Alert = ({ error, style }: { error: string; style?: React.CSSProperties }) => (
<AlertBanner style={style || {}}>
<div className="icon">
<svg viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
Expand Down
14 changes: 7 additions & 7 deletions src/pages/Pot/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import yoctosToUsdWithFallback from "@app/utils/yoctosToUsdWithFallback";
import ChallengeModal from "../ChallengeModal/ChallengeModal";
import FundModal from "../FundModal/FundModal";
import NewApplicationModal from "../NewApplicationModal/NewApplicationModal";
import PayoutsModal from "../PayoutsModal/PayoutsModal";
import PoolAllocationTable from "../PoolAllocationTable/PoolAllocationTable";
import SuccessFundModal, { ExtendedFundDonation } from "../SuccessFundModal/SuccessFundModal";
import { ButtonsWrapper, Container, Description, Fund, HeaderWrapper, Referral, Title } from "./styles";
Expand Down Expand Up @@ -42,6 +43,7 @@ const Header = () => {
const [flaggedAddresses, setFlaggedAddresses] = useState(null);
const [potDetail, setPotDetail] = useState<null | PotDetail>(null);
const [allDonations, setAlldonations] = useState<null | PotDonation[]>(null);
const [payoutsToProcess, setPayoutsToProcess] = useState<any>(null);
// set fund mathcing pool success
const [fundDonation, setFundDonation] = useState<null | ExtendedFundDonation>(null);

Expand Down Expand Up @@ -165,13 +167,7 @@ const Header = () => {
const handleSetPayouts = () => {
if (allDonations && flaggedAddresses !== null) {
calculatePayouts(allDonations, matching_pool_balance, flaggedAddresses).then((calculatedPayouts: any) => {
const payouts = Object.entries(calculatedPayouts)
.map(([projectId, { matchingAmount }]: any) => ({
project_id: projectId,
amount: matchingAmount,
}))
.filter((payout) => payout.amount !== "0");
PotSDK.chefSetPayouts(potId, payouts);
setPayoutsToProcess(calculatedPayouts);
});
} else {
console.log("error fetching donations or flagged addresses");
Expand Down Expand Up @@ -293,6 +289,10 @@ const Header = () => {
}}
/>
)}
{/* Admin process Payout */}
{payoutsToProcess && (
<PayoutsModal setPayoutsToProcess={setPayoutsToProcess} potId={potId} originalPayouts={payoutsToProcess} />
)}
</Container>
);
};
Expand Down
147 changes: 147 additions & 0 deletions src/pages/Pot/components/PayoutsModal/PayoutsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { Big, useMemo, useState } from "alem";
import PotSDK from "@app/SDK/pot";
import Button from "@app/components/Button";
import Text from "@app/components/Inputs/Text/Text";
import Alert from "@app/modals/ModalDonation/Banners/Alert";
import ModalOverlay from "@app/modals/ModalOverlay";
import { CalculatedPayout } from "@app/types";
import _address from "@app/utils/_address";
import { ButtonWrapper, Container, PayoutItem, PayoutsView, Title, Total, ExitIcon } from "./styles";

const PayoutsModal = ({
originalPayouts,
setPayoutsToProcess,
potId,
}: {
originalPayouts: Record<string, CalculatedPayout>;
setPayoutsToProcess: (payouts: null) => void;
potId: string;
}) => {
const [payouts, setPayouts] = useState(originalPayouts);
const [error, setError] = useState("");

const calcNear = (amount: string) => Big(amount).div(Big(10).pow(24)).toNumber().toFixed(2);
const calcYoctos = (amount: string) => new Big(amount).mul(new Big(10).pow(24)).toString();

const sumAmount = (payouts: any) =>
payouts.reduce(
(acc: any, payout: any) =>
Big(acc)
.plus(new Big(payout.matchingAmount || payout.amount))
.toString(),
0,
);

const originalTotalAmountYoctos = useMemo(() => sumAmount(Object.values(originalPayouts)), [originalPayouts]);

const originalTotalAmount = calcNear(originalTotalAmountYoctos);

const [payoutsList, totalAmount, remainder] = useMemo(() => {
const payoutsArr = Object.entries(payouts).map(([projectId, { matchingAmount }]: any) => ({
project_id: projectId,
amount: calcNear(matchingAmount),
}));

const totalAmountYoctos = sumAmount(Object.values(payouts));

const totalAmount = calcNear(totalAmountYoctos);

const remainderYoctos = Big(originalTotalAmountYoctos).minus(Big(totalAmountYoctos)).toNumber();
if (remainderYoctos < 0) setError("The payout's total can not be greater than the original amount.");
else setError("");
const remainder = calcNear(remainderYoctos.toString());

return [payoutsArr, totalAmount, remainder, remainderYoctos];
}, [payouts]);

const handleChange = (projectId: string, amount: string) => {
setPayouts({
...payouts,
[projectId]: {
...payouts[projectId],
matchingAmount: calcYoctos(amount),
},
});
};

const handlePayout = () => {
let payoutsArr = Object.entries(payouts)
.map(([projectId, { matchingAmount }]: any) => ({
project_id: projectId,
amount: matchingAmount,
}))
.filter((payout) => payout.amount !== "0");
let yoctos = sumAmount(payoutsArr);

const remainder = Big(originalTotalAmountYoctos).minus(Big(yoctos));

payoutsArr[0].amount = Big(payoutsArr[0].amount).plus(remainder).toString();

yoctos = sumAmount(payoutsArr);

console.log("check if the original amount equal to the new one", Big(yoctos).cmp(Big(originalTotalAmountYoctos)));

PotSDK.chefSetPayouts(potId, payoutsArr);
};

return (
<ModalOverlay>
<Container>
<ExitIcon>
<svg
onClick={() => setPayoutsToProcess(null)}
className="close-icon"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z"
fill="#000000"
/>
</svg>
</ExitIcon>
<Title>{potId}</Title>
<Total>
<div className="original">Total amount</div>
<div className="amount">
{totalAmount} / <span>{originalTotalAmount} N</span>
</div>
</Total>
<Total>
<div className="original">Remainder</div>
<div className="amount">{remainder} N</div>
</Total>
{error && (
<Alert
style={{
marginTop: "0",
}}
error={error}
/>
)}
<ButtonWrapper>
<Button onClick={handlePayout} isDisabled={!!error}>
Set Payouts
</Button>
</ButtonWrapper>
<PayoutsView>
{payoutsList.map(({ project_id, amount }) => (
<PayoutItem>
<div className="id">{_address(project_id, 20)}</div>
<Text
containerStyles={{
width: "120px",
}}
onChange={(amount) => handleChange(project_id, amount)}
defaultValue={amount}
/>
</PayoutItem>
))}
</PayoutsView>
</Container>
</ModalOverlay>
);
};

export default PayoutsModal;
58 changes: 58 additions & 0 deletions src/pages/Pot/components/PayoutsModal/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import styled from "styled-components";

export const Container = styled.div`
display: flex;
flex-direction: column;
gap: 1rem;
position: relative;
height: 80vh;
`;

export const Title = styled.div`
font-size: 18px;
font-weight: 500;
overflow-wrap: break-word;
`;

export const PayoutsView = styled.div`
display: flex;
gap: 0.5rem;
flex-direction: column;
max-height: 100%;
overflow-y: scroll;
`;

export const PayoutItem = styled.div`
display: flex;
gap: 1rem;
align-items: center;
justify-content: space-between;
.id {
width: 172px;
}
`;

export const Total = styled.div`
display: flex;
gap: 0.5rem;
.original {
color: #656565;
}
span {
font-weight: 500;
color: var(--Primary-600);
}
`;
export const ButtonWrapper = styled.div`
display: flex;
gap: 1rem;
`;

export const ExitIcon = styled.div`
display: flex;
justify-content: flex-end;
svg {
cursor: pointer;
width: 18px;
}
`;
58 changes: 30 additions & 28 deletions src/pages/PotsHome/PotsHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,18 @@ const PotsHome = () => {
// Get all pots config
if (!pots) {
PotFactorySDK.asyncGetPots().then((pots: Pot[]) => {
pots.forEach(({ id }) => {
PotSDK.asyncGetConfig(id).then((potConfig: PotDetail) =>
setPots((prevPot: any) => ({
...prevPot,
[id]: { ...potConfig, id },
})),
);
const configsPromises = pots.map(({ id }) => PotSDK.asyncGetConfig(id));
Promise.all(configsPromises).then((configs) => {
const potDetails = configs.map((config: PotDetail, idx: number) => ({
...config,
id: pots[idx].id,
}));
setPots(potDetails);
});
});
}

const compareFunction = (pots: PotDetail[]) => {
// sort pots(round status)
const listOfPots: any = {};

const states = Object.keys(potsSort);

pots.forEach((pot) => {
Object.keys(potsSort).some((type) => {
const { check, items } = potsSort[type];
Expand Down Expand Up @@ -139,22 +134,29 @@ const PotsHome = () => {

{filteredRounds.length === 0 && <div>No pots</div>}

<ListSection
items={filteredRounds}
renderItem={(pot: any) => <PotCard potId={pot.id} key={pot.id} />}
maxCols={3}
responsive={[
{
breakpoint: 1114,
items: 2,
},
{
breakpoint: 768,
items: 1,
},
]}
/>

{pots === null ? (
<div className="m-auto">
<div className="spinner-border text-secondary" role="status" />
</div>
) : filteredRounds.length > 0 ? (
<ListSection
items={filteredRounds}
renderItem={(pot: any) => <PotCard potId={pot.id} key={pot.id} />}
maxCols={3}
responsive={[
{
breakpoint: 1114,
items: 2,
},
{
breakpoint: 768,
items: 1,
},
]}
/>
) : (
<div>No pots</div>
)}
<Line />
<Title>
Completed Pots <span>{completedRounds.length}</span>
Expand Down
Loading

0 comments on commit 770699e

Please sign in to comment.