Skip to content

Commit

Permalink
Merge pull request #138 from PotLock/cleanup
Browse files Browse the repository at this point in the history
payouts process modal
  • Loading branch information
M-Rb3 authored May 30, 2024
2 parents a94ce0c + f6369ae commit 1253408
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 43 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;
}
`;
11 changes: 0 additions & 11 deletions src/pages/Projects/components/AllProjects/AllProjects.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Social, createDebounce, useEffect, useState } from "alem";
import DonateSDK from "@app/SDK/donate";
import Card from "@app/components/Card/Card";
import FilterDropdown from "@app/components/Inputs/FilterDropdown/FilterDropdown";
import useModals from "@app/hooks/useModals";
import getProjects from "@app/services/getProjects";
import { Project } from "@app/types";
import getTagsFromSocialProfileData from "@app/utils/getTagsFromSocialProfileData";
import getTeamMembersFromSocialProfileData from "@app/utils/getTeamMembersFromSocialProfileData";
import yoctosToUsd from "@app/utils/yoctosToUsd";
import ListSection from "../ListSection";
import SearchBar from "../SearchBar/SearchBar";
import { ProjectsContainer, FilterWrapper, Title, Container, Header } from "./styles";
Expand All @@ -17,8 +15,6 @@ const AllProjects = () => {
const projectsData = getProjects();
const Modals = useModals();

const [totalDonation, setTotalDonation] = useState(0);
const [totalDonated, setTotalDonated] = useState("0");
const [projects, setProjects] = useState<any>([]);
const [filteredProjects, setFilteredProjects] = useState<any>([]);
const [sort, setSort] = useState("Sort");
Expand All @@ -36,13 +32,6 @@ const AllProjects = () => {
return "";
}

const donateConfig: any = DonateSDK.getConfig();
if (donateConfig && !totalDonated && !totalDonation) {
const lastDonationAmount = yoctosToUsd(donateConfig.net_donations_amount);
setTotalDonated(lastDonationAmount);
setTotalDonation(donateConfig.total_donations_count);
}

const handleSortChange = (sortType: string) => {
setSort(sortType);
const projects = [...filteredProjects];
Expand Down
38 changes: 19 additions & 19 deletions src/services/getPotData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Storage } from "alem";
import PotSDK from "@app/SDK/pot";
import { FlaggedAddress, Payout, PotApplication, PotDetail, PotDonation, CalculatedPayout } from "@app/types";
import { FlaggedAddress, Payout, PotApplication, PotDetail, PotDonation } from "@app/types";
import calculatePayouts from "@app/utils/calculatePayouts";

// type UpdateState = (newValues: Partial<ProjectsState>) => void;
Expand Down Expand Up @@ -51,26 +51,26 @@ function isEqual(obj1: any, obj2: any) {
return true;
}

function isObjectEqual(obj1: CalculatedPayout, obj2: CalculatedPayout): boolean {
return obj1.project_id === obj2.project_id && obj1.amount === obj2.amount;
}
// function isObjectEqual(obj1: CalculatedPayout, obj2: CalculatedPayout): boolean {
// return obj1.project_id === obj2.project_id && obj1.amount === obj2.amount;
// }

function areListsEqual(list1: CalculatedPayout[], list2: CalculatedPayout[]): boolean {
// Check if both lists have the same length
if (list1.length !== list2.length) {
return false;
}
// function areListsEqual(list1: CalculatedPayout[], list2: CalculatedPayout[]): boolean {
// // Check if both lists have the same length
// if (list1.length !== list2.length) {
// return false;
// }

// Check if all objects in the lists are equal
for (let i = 0; i < list1.length; i++) {
if (!isObjectEqual(list1[i], list2[i])) {
return false;
}
}
// // Check if all objects in the lists are equal
// for (let i = 0; i < list1.length; i++) {
// if (!isObjectEqual(list1[i], list2[i])) {
// return false;
// }
// }

// If no differences are found, return true
return true;
}
// // If no differences are found, return true
// return true;
// }

const getPotData = (potId: string, property: string) => Storage.get(`${potId}-${property}`);

Expand Down Expand Up @@ -200,7 +200,7 @@ export const getPayout = ({

// get matched donations
export const asyncGetPublicDonations = (potDetail: PotDetail, potId: string) => {
const limit = 480; // number of donations to fetch per req
const limit = 450; // number of donations to fetch per req

const donationsCount = potDetail.public_donations_count;
const paginations = [...Array(Math.ceil(donationsCount / limit)).keys()];
Expand Down
Loading

0 comments on commit 1253408

Please sign in to comment.