-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Frontend for treasury transfer status (#137)
* cancel transfer component * mock data for status transfer * added status transfer * new treasury_abi * render live transfers * logical cancel transfer * Fix 'There are no transfers' bug * fix condition * fix * deleted unused file * added handler click token_addr or receiver * Format * Remove refetch --------- Co-authored-by: Ondřej Sojka <[email protected]>
- Loading branch information
1 parent
b6317b9
commit 47ed5b0
Showing
5 changed files
with
1,059 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react'; | ||
import { useContractWrite } from "@starknet-react/core"; | ||
import { TREASURY_ADDRESS } from "../lib/config"; | ||
import { Contract } from "starknet"; | ||
import TreasuryABI from "../lib/treasury_abi.json"; | ||
|
||
interface CancelTransferButtonProps { | ||
transferId: number; | ||
} | ||
|
||
const CancelTransferBtn: React.FC<CancelTransferButtonProps> = ({ transferId }) => { | ||
|
||
const contract = new Contract(TreasuryABI, TREASURY_ADDRESS) | ||
|
||
const { writeAsync, error } = useContractWrite({ | ||
calls: [ | ||
contract.populateTransaction["cancel_transfer"](transferId) | ||
], | ||
}); | ||
|
||
const handleCancelTransfer = async () => { | ||
try { | ||
await writeAsync(); | ||
console.log(`Transfer ${transferId} cancelled successfully.`); | ||
} catch (err) { | ||
console.error(`Error cancelling transfer ${transferId}:`, err); | ||
console.error(`Error write ${transferId}:`, error); | ||
} | ||
}; | ||
|
||
return ( | ||
<button | ||
type="button" | ||
className='bg-blue-500 rounded-md text-white disabled:opacity-50 p-1 w-full' | ||
onClick={handleCancelTransfer}> | ||
Сancel | ||
</button> | ||
); | ||
}; | ||
|
||
export default CancelTransferBtn; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import React from "react"; | ||
import { | ||
useAccount, | ||
useContractRead, useNetwork | ||
} from "@starknet-react/core"; | ||
import TreasuryABI from "../lib/treasury_abi.json"; | ||
import CancelTransferBtn from "./CancelTransferBtn"; | ||
import { formatBalance } from "../lib/erc20"; | ||
import { TREASURY_ADDRESS } from "../lib/config"; | ||
|
||
const StatusTransfer = () => { | ||
const { address } = useAccount() | ||
const { data, isLoading } = useContractRead({ | ||
functionName: 'get_live_transfers', | ||
address: TREASURY_ADDRESS, | ||
args: [], | ||
abi: TreasuryABI, | ||
watch: false, | ||
retry: false | ||
}) | ||
|
||
const renderCancelBtn = (status, transfer_id) => | ||
getTransferStatus(status) == 'PENDING' && address && | ||
<CancelTransferBtn transferId={transfer_id.toString()} /> | ||
|
||
const { chain: { network } } = useNetwork() | ||
|
||
const handleAddress = address => { | ||
const sub_domain = network === 'sepolia' ? 'sepolia.' : '' | ||
const url = `https://${sub_domain}starkscan.co/contract/${getAddressToHex(address)}` | ||
window.open(`${url}`, '_blank') | ||
} | ||
|
||
const renderData = () => { | ||
if (Array.isArray(data)) { | ||
if (data.length === 0) { | ||
return <div className='p-2'>There are no transfers</div>; | ||
} | ||
|
||
return data.map((transfer_item, index) => { | ||
|
||
return ( | ||
<div key={index} className="flex flex-wrap flex-row"> | ||
<div className='flex flex-wrap flex-row w-full'> | ||
<div className="flex-1 w-1/2 basis-1/2 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider border-r border-slate-400">token</div> | ||
<div className="flex-1 w-1/2 basis-1/2 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider">receiver</div> | ||
<div className="flex-1 w-1/2 basis-1/2 p-2 overflow-hidden cursor-pointer" onClick={() => handleAddress(transfer_item.token_addr)}>{getFormatAddress(transfer_item.token_addr.toString())}</div> | ||
<div className="flex-1 w-1/2 basis-1/2 p-2 overflow-hidden cursor-pointer" onClick={() => handleAddress(transfer_item.receiver)}>{getFormatAddress(transfer_item.receiver.toString())}</div> | ||
</div> | ||
<div className='flex flex-wrap flex-row w-full'> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider">amount</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider">cooldown_end</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider">status</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 bg-slate-200 text-left text-gray-700 uppercase tracking-wider">actions</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 ">{formatBalance(transfer_item.amount.toString())}</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 ">{getHoursLeft(transfer_item.cooldown_end.toString())}</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 ">{getTransferStatus(transfer_item.status)}</div> | ||
<div className="flex-1 w-1/4 basis-1/4 p-2 "> | ||
{renderCancelBtn(transfer_item?.status, transfer_item?.id)} | ||
</div> | ||
</div> | ||
|
||
</div> | ||
) | ||
}) | ||
} else { | ||
return null | ||
} | ||
} | ||
|
||
return ( | ||
<div> | ||
<div className="flex w-full flex-grow pb-4 text-2xl font-bold">Transfer status</div> | ||
{isLoading ? ( | ||
<div>Loading...</div> | ||
) : ( | ||
<div className="w-[50rem] max-w-[50rem] grid items-center pl-0 rounded-lg bg-slate-200"> | ||
<div className="min-w-full bg-white border border-gray-200 rounded-lg"> | ||
|
||
<div> | ||
{renderData()} | ||
</div> | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
const getHoursLeft = (target_date: number): string => { | ||
const targetTimestamp = Number(target_date) * 1000; | ||
const currentTimestamp = Date.now(); | ||
|
||
const timeLeft = targetTimestamp - currentTimestamp; | ||
if (timeLeft > 0) { | ||
const secondsLeft = Math.floor(timeLeft / 1000); | ||
const minutesLeft = Math.floor(secondsLeft / 60); | ||
const hoursLeft = Math.floor(minutesLeft / 60); | ||
return `hours ${hoursLeft} left`; | ||
} else { | ||
return 'expired'; | ||
} | ||
}; | ||
|
||
const getTransferStatus = status => { | ||
if (status?.variant?.PENDING) { | ||
return 'PENDING' | ||
} | ||
if (status?.variant?.CANCELLED) { | ||
return 'CANCELLED' | ||
} | ||
if (status?.variant?.FINISHED) { | ||
return 'FINISHED' | ||
} | ||
|
||
} | ||
|
||
const getFormatAddress = address => address.slice(0, 12) + "..." + address.slice(-4) | ||
const getAddressToHex = address => "0x" + address.toString(16) | ||
|
||
|
||
export default StatusTransfer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.