Skip to content

Commit

Permalink
Estimate gas costs (#249)
Browse files Browse the repository at this point in the history
* init commit

* second commit

* third commit

* fourth commit

* fifth commit

* clean up code

* add currency types

* add migrations

* add balance api

* refactor code

* get project balance

* use same api for both substrate and non substrate balance

* add payment address to offchain database

* fixes

* only withdraw approved funds

* clean up console logs

* withdraw via api

* fix sync issue

* more code refactors

* more code refactors

* add better error message

* refactor sync

* refactor poll

* withdrawal fees

* fix bugs with payment address

* Merge branch 'main' into multichain_backup

# Conflicts:
#	src/model.ts
#	src/pages/projects/[id].tsx
#	src/pages/relay/index.tsx

(cherry picked from commit 0d78ab4a4be77eb2e7ecbcdab60a5569fe0bad03)

* revert changes to legacy milestone

* remove console log

* lint fixes

* build fixes

* more build fixes

* use new signer

* refactor

* build fixes

* init commit

* take fee from escrow by default

* only call milestone attachments once

* build fixes

* gas costs fixes

* remove typo

* fix for migrations

* fix error status

* only call similar briefs once

* reduce user briefs calls

* simplify dashboard

* disable strict mode on prod

* fix nav bar
  • Loading branch information
samelamin authored Nov 3, 2023
1 parent 5d5fe06 commit 8b93af3
Show file tree
Hide file tree
Showing 20 changed files with 328 additions and 223 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ db_up: migrate
db_down: migrate_reset

cmd: db_up
npm run build
yarn build
yarn start

.PHONY: all clean clean_build clean_deps build \
Expand Down
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
});

const nextConfig = {
reactStrictMode: true,
reactStrictMode: process.env.NODE_ENV != 'production',
output: 'standalone',
env: {
PORT: 8080,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"bad-words": "^3.0.4",
"bcryptjs": "^2.4.3",
"classnames": "^2.3.2",
"coingecko-api-v3": "^0.0.29",
"cookies-next": "^2.1.1",
"country-list": "^2.3.0",
"csv-parser": "^3.0.0",
Expand Down
11 changes: 5 additions & 6 deletions src/components/Briefs/BioInsights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { copyIcon } from '@/assets/svgs';
import { Brief, Project, User } from '@/model';
import {
getBriefApplications,
getUserBriefs,
} from '@/redux/services/briefService';

import CountrySelector from '../Profile/CountrySelector';
Expand All @@ -35,6 +34,7 @@ type BioInsightsProps = {
canSubmitProposal: boolean | undefined;
isSavedBrief?: boolean;
unsaveBrief?: () => Promise<void>;
allClientBriefs: any;
};

const BioInsights = ({
Expand All @@ -50,6 +50,7 @@ const BioInsights = ({
saveBrief,
unsaveBrief,
isSavedBrief,
allClientBriefs,
}: BioInsightsProps) => {
const router = useRouter();
const [copied, setCopied] = useState(false);
Expand All @@ -71,12 +72,10 @@ const BioInsights = ({

useEffect(() => {
const setUp = async () => {
if (!targetUser?.id) return;
const res = await getUserBriefs(targetUser?.id);
const allBriefs = [...res.acceptedBriefs, ...res.briefsUnderReview];

if (!targetUser?.id || !allClientBriefs) return;
const allBriefs = [...allClientBriefs.acceptedBriefs, ...allClientBriefs.briefsUnderReview];
setClientBrief(allBriefs);
setIOpenBriefs(res?.briefsUnderReview || []);
setIOpenBriefs(allClientBriefs.briefsUnderReview || []);
setBriefApplications(await getBriefApplications(brief?.id));
};

Expand Down
16 changes: 7 additions & 9 deletions src/components/Briefs/ClientHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';

import { Brief } from '@/model';
import { getUserBriefs } from '@/redux/services/briefService';

type ClientsHistoryType = {
client: any;
briefId: string;
allClientBriefs: any;
}

const ClientsHistory = ({ client, briefId }: ClientsHistoryType) => {
const ClientsHistory = ({ client, briefId, allClientBriefs }: ClientsHistoryType) => {
const [showClientHistory, setShowClientHistory] = useState<boolean>(false);
const [clientBriefs, setClientAllBriefs] = useState<Brief[]>([])
const [totalBriefs, setTotalBriefs] = useState<number>(0)
Expand All @@ -20,18 +20,16 @@ const ClientsHistory = ({ client, briefId }: ClientsHistoryType) => {

useEffect(() => {
const setUpClientHistory = async () => {
const res = await getUserBriefs(client.id)
// let allBriefs : Brief[] = []

// if(briefs?.briefsUnderReview?.length) allBriefs = [...allBriefs, ...briefs.briefsUnderReview]
// if(briefs?.acceptedBriefs?.length) allBriefs = [...allBriefs, ...briefs.acceptedBriefs]
const briefs = res.briefsUnderReview?.filter((brief: Brief) => brief.id != briefId)
if(!allClientBriefs) {
return
}
const briefs = allClientBriefs.briefsUnderReview?.filter((brief: Brief) => brief.id != briefId)
setTotalBriefs(briefs?.length)
briefs.splice(briefsToShow)
setClientAllBriefs(briefs)
}
client?.id && setUpClientHistory()
}, [client?.id, briefId, briefsToShow])
}, [client?.id, briefId, allClientBriefs, briefsToShow])

// const showBriefs = () =>{
// const truncatedBrief = [...clientBriefs]
Expand Down
7 changes: 1 addition & 6 deletions src/components/HirePopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,7 @@ export const HirePopup = ({

const selectedAccount = async (account: WalletAccount) => {
setLoading(true);

const mintResult = await mintTokens(application.id, account.address);
if (mintResult.txError) {
setError({ message: mintResult.errorMessage });
}

mintTokens(application.id, account.address);
const imbueApi = await initImbueAPIInfo();
const chainService = new ChainService(imbueApi, user);
const briefOwners: string[] = user?.web3_address
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navbar/NewNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function NewNavbar() {
src='/message-dots-square.svg'
width={23}
height={20}
onClick={() => router.push('/dashboard/message')}
onClick={() => router.push('/dashboard/messages')}
alt='message'
className='cursor-pointer'
/>
Expand Down
8 changes: 5 additions & 3 deletions src/components/Project/ProjectBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const Currencies = [
const ProjectBalance = (props: ProjectBalanceType) => {
const { balance, project, user, handlePopUpForUser, setBalance } = props;
const [balanceLoading, setBalanceLoading] = useState(true)
const [currency_id, setCurrency_id] = useState<number>(project?.currency_id || 0)
const [currency_id, setCurrency_id] = useState<number>();

const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const showOptions = Boolean(anchorEl);
Expand Down Expand Up @@ -75,8 +75,10 @@ const ProjectBalance = (props: ProjectBalanceType) => {
}
}

getAndSetBalace()
setCurrency_id(project.currency_id);
getAndSetBalace();
if (!currency_id) {
setCurrency_id(project.currency_id);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currency_id, project?.escrow_address, project.status_id, user.id])
Expand Down
8 changes: 5 additions & 3 deletions src/components/Project/V2/ExpandableMilestone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface ExpandableMilestonProps {
canVote: boolean;
loading: boolean;
targetUser: any;
hasMilestoneAttachments: boolean;
}

const ExpandableMilestone = (props: ExpandableMilestonProps) => {
Expand All @@ -58,6 +59,7 @@ const ExpandableMilestone = (props: ExpandableMilestonProps) => {
setSuccessTitle,
setSuccess,
targetUser,
hasMilestoneAttachments = false
} = props;
const [milestoneKeyInView, setMilestoneKeyInView] = useState<number>(0);
const [submittingMilestone, setSubmittingMilestone] =
Expand Down Expand Up @@ -96,7 +98,9 @@ const ExpandableMilestone = (props: ExpandableMilestonProps) => {
setAttachment(resp);
};

getAttachments();
if(hasMilestoneAttachments){
getAttachments();
}
}, [milestone.milestone_index, project.id]);

const [files, setFiles] = useState<File[]>();
Expand Down Expand Up @@ -285,8 +289,6 @@ const ExpandableMilestone = (props: ExpandableMilestonProps) => {

if (project.currency_id >= 100 && project.id) {
const withdrawResult = await withdrawOffchain(project.id);
console.log("**** withdraw result is ");
console.log(withdrawResult);
if (withdrawResult.txError) {
setSuccess(false);
setError({ message: withdrawResult.errorMessage });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable('milestones', (table) => {
table.boolean('withdrawn_offchain');
table.boolean('withdrawn_onchain');
table.boolean('withdrawn_offchain').defaultTo(false);
table.boolean('withdrawn_onchain').defaultTo(false);
table.string('withdrawal_transaction_hash').nullable();
table.string('imbue_fee_transaction_hash').nullable();
});
Expand All @@ -15,8 +15,8 @@ export async function up(knex: Knex): Promise<void> {
export async function down(knex: Knex): Promise<void> {
const tableName = 'milestones';
await knex.schema.alterTable(tableName, (builder) => {
builder.boolean('withdrawn_offchain');
builder.boolean('withdrawn_onchain');
builder.dropColumn('withdrawn_offchain');
builder.dropColumn('withdrawn_onchain');
builder.dropColumn('withdrawal_transaction_hash');
builder.dropColumn('imbue_fee_transaction_hash');
});
Expand Down
6 changes: 3 additions & 3 deletions src/pages/api/getstream/getnotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ export default nextConnect()
res
);

if (!userAuth) {
if(!userAuth) {
return res.status(404).send('unable to fetch notifications');
}

const client = connect(
process.env.GETSTREAM_API_KEY as string,
process.env.GETSTREAM_SECRET_KEY as string
Expand Down Expand Up @@ -57,8 +58,7 @@ export default nextConnect()
}
});
} catch (err) {
console.log(err);
return res.status(500).send('unable to send notification: ');
return res.status(404).end('unable to fetch notifications');
}
})
.post(async (req: NextApiRequest, res: NextApiResponse) => {
Expand Down
3 changes: 2 additions & 1 deletion src/pages/api/payments/[id]/withdraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export default nextConnect()
const { id } = req.query;
const projectId = Number(id);
try {
const withdrawnAmount = await withdraw(projectId);
const coverFees = true;
const withdrawnAmount = await withdraw(projectId, coverFees);
if (withdrawnAmount > 0) {
return res.status(200).json({ WithdrawnAmount: withdrawnAmount });
} else {
Expand Down
45 changes: 26 additions & 19 deletions src/pages/briefs/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
deleteSavedBrief,
getAllBriefs,
getBrief,
getUserBriefs,
saveBriefData,
} from '@/redux/services/briefService';
import { getFreelancerProfile } from '@/redux/services/freelancerService';
Expand Down Expand Up @@ -66,6 +67,9 @@ const BriefDetails = (): JSX.Element => {
const [freelancer, setFreelancer] = useState<Freelancer>();
const [targetUser, setTargetUser] = useState<User | null>(null);
const [showMessageBox, setShowMessageBox] = useState<boolean>(false);
const [similarBriefs, setSimilarBriefs] = useState<Brief[]>([]);
const [allClientBriefs, setAllClientBriefs] = useState<any>();

// const [showLoginPopup, setShowLoginPopup] = useState<boolean>(false);
const { setShowLoginPopup } = useContext(
LoginPopupContext
Expand Down Expand Up @@ -94,6 +98,13 @@ const BriefDetails = (): JSX.Element => {
briefData?.id,
browsingUser?.id
);

const allClientBriefsRes = await getUserBriefs(briefData.user_id);
setAllClientBriefs(allClientBriefsRes)

const briefs_all: any = await getAllBriefs(4, 1);
setSimilarBriefs(briefs_all?.currentData);

setIsSavedBrief(briefIsSaved.isSaved);
setFreelancer(_freelancer);
} else {
Expand All @@ -108,7 +119,7 @@ const BriefDetails = (): JSX.Element => {

useEffect(() => {
fetchData();
}, [id, browsingUser.username]);
}, [id]);

const redirectToApply = () => {
if (browsingUser?.id) router.push(`/briefs/${brief.id}/apply`);
Expand Down Expand Up @@ -155,30 +166,25 @@ const BriefDetails = (): JSX.Element => {
setSuccessTitle('Brief Unsaved Successfully');
};

const SimilarProjects = () => {
const [showSimilarBrief, setShowSimilarBrief] = useState<boolean>(false);
const [similarBriefs, setSimilarBriefs] = useState<Brief[]>([]);

useEffect(() => {
const setUpBriefs = async () => {
const briefs_all: any = await getAllBriefs(4, 1);
setSimilarBriefs(briefs_all?.currentData);
};
setUpBriefs();
}, []);
type SimilarBriefsType = {
similarBriefs: Brief[];
}


const SimilarProjects = ({ similarBriefs }: SimilarBriefsType) => {
const [showSimilarBrief, setShowSimilarBrief] = useState<boolean>(false);

return (
<div
className={`transparent-conatainer !bg-imbue-light-purple-three relative ${
showSimilarBrief ? '!pb-[3rem]' : ''
} `}
className={`transparent-conatainer !bg-imbue-light-purple-three relative ${showSimilarBrief ? '!pb-[3rem]' : ''
} `}
>
<div className='flex justify-between w-full lg:px-[4rem] px-[1rem]'>
<h3 className='text-imbue-purple-dark'>Similar projects on Imbue</h3>
<div
className={`transition transform ease-in-out duration-600 ${
showSimilarBrief && 'rotate-180'
} cursor-pointer`}
className={`transition transform ease-in-out duration-600 ${showSimilarBrief && 'rotate-180'
} cursor-pointer`}
>
<ArrowIcon
onClick={() => setShowSimilarBrief(!showSimilarBrief)}
Expand Down Expand Up @@ -255,10 +261,11 @@ const BriefDetails = (): JSX.Element => {
targetUser={targetUser}
browsingUser={browsingUser}
canSubmitProposal={brief.verified_only ? freelancer?.verified : true}
allClientBriefs = {allClientBriefs}
/>
</div>
<ClientsHistory briefId={id} client={targetUser} />
<SimilarProjects />
<ClientsHistory briefId={id} client={targetUser} allClientBriefs={allClientBriefs} />
<SimilarProjects similarBriefs={similarBriefs} />
<ErrorScreen {...{ error, setError }}>
<div className='flex flex-col gap-4 w-1/2'>
<button
Expand Down
2 changes: 1 addition & 1 deletion src/pages/briefs/[id]/applications/[applicationId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ const ApplicationPreview = (): JSX.Element => {
{isApplicationOwner && isEditingBio ? (
<input
type='string'
placeholder='Add an amount'
placeholder='Add a payment address'
className='input-budget text-base rounded-[5px] py-3 pl-14 pr-5 text-imbue-purple text-right placeholder:text-imbue-light-purple'
value={paymentAddress || ''}
onChange={(e) => setPaymentAddress(e.target.value)}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/briefs/[id]/apply.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ export const SubmitProposal = (): JSX.Element => {
<input
type='string'
data-testid={`payment address`}
placeholder='Add an amount'
placeholder='Add a payment address'
className='input-budget text-base rounded-[5px] py-3 pl-14 pr-5 text-imbue-purple text-right placeholder:text-imbue-light-purple'
value={paymentAddress || ''}
onChange={(e) => setPaymentAddress(e.target.value)}
Expand Down
Loading

0 comments on commit 8b93af3

Please sign in to comment.