Skip to content

Commit

Permalink
Merge pull request #57 from Oshioke-Salaki/burner-modal-components
Browse files Browse the repository at this point in the history
feat: modal components for burner wallets
  • Loading branch information
Darlington02 authored Apr 24, 2024
2 parents 26c22c2 + efd117a commit 4c1b531
Show file tree
Hide file tree
Showing 11 changed files with 362 additions and 11 deletions.
Binary file modified .DS_Store
Binary file not shown.
12 changes: 12 additions & 0 deletions frontend/public/assets/down-chevron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/public/assets/ethereumLogo2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/public/assets/right-arr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions frontend/public/starknetlogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion frontend/src/app/burner/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import Burners from "../components/Burner/Burner";

export default async function Page() {
export default function Page() {
return (
<div className="container mx-auto py-10">
<Burners />
Expand Down
200 changes: 200 additions & 0 deletions frontend/src/app/components/AssetTransferModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
"use client";
import GenericModal from "./GenericModal";
import starknetLogo from "../../../public/starknetlogo.svg";
import Image from "next/image";
import rightArr from "../../../public/assets/right-arr.svg";
import { useEffect, useState } from "react";
import { useAccount, useBalance } from "@starknet-react/core";
import downChevron from "../../../public/assets/down-chevron.svg";
import ethLogo from "../../../public/assets/ethereumLogo2.svg";

type Props = {
isOpen: boolean;
onClose: () => void;
};

function AssetTransferModal({ isOpen, onClose }: Props) {
const { address } = useAccount();
const { isLoading, isError, error, data } = useBalance({
address,
watch: true,
});

// Form Data
const [walletAddress, setWalletAddress] = useState("");
const [amount, setAmount] = useState("");

// useState Variables
const [animate, setAnimate] = useState(false);
const [activeToken, setActiveToken] = useState("strk");
const [assetDropDownIsOpen, setAssetDropDownIsOpen] = useState(false);

const closeModal = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
setAnimate(false);
setTimeout(() => {
onClose();
}, 400);
};

useEffect(() => {
if (isOpen) {
setAnimate(true);
} else {
setAnimate(false);
}
}, [isOpen]);

function onChangeToken(e: any, token: string) {
e.preventDefault();
setActiveToken(token);
setAssetDropDownIsOpen(false);
}

return (
<GenericModal
isOpen={isOpen}
onClose={closeModal}
animate={animate}
className={`w-[90vw] mx-auto md:h-fit md:w-[45rem] text-white py-4 px-5 relative bg-black`}
>
<div className="absolute right-5 top-4">
<button
onClick={(e) => {
closeModal(e);
e.stopPropagation();
}}
className="w-8 h-8 grid place-content-center rounded-full bg-outline-grey "
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="m6.4 18.308l-.708-.708l5.6-5.6l-5.6-5.6l.708-.708l5.6 5.6l5.6-5.6l.708.708l-5.6 5.6l5.6 5.6l-.708.708l-5.6-5.6z"
/>
</svg>
</button>
</div>
<h1 className="text-[24px] mb-2 font-semibold">Send</h1>
<h5 className="font-medium">Asset</h5>
<div>
<div
className="flex items-center justify-between mt-2 mb-5 bg-[#1f1f1f] py-2 px-3 rounded-md cursor-pointer"
onClick={() => setAssetDropDownIsOpen((open) => !open)}
>
<div className="flex items-center gap-3">
<Image
src={activeToken === "strk" ? starknetLogo : ethLogo}
alt="Stark logo"
width={28}
height={28}
/>
<div>
<h3 className="text-base font-medium">
{activeToken.toUpperCase() + " "}
<span className="text-sm font-normal">
({activeToken === "strk" ? "StarkNetToken" : "Ether"})
</span>
</h3>
{/* {isLoading && (
<Image src={miniSpinner} width={16} height={16} alt="spinner" />
)}
{data && (
<h5 className="text-sm">
{Number(data.value).toFixed(4).toString()}
</h5>
)} */}
2.0000
</div>
</div>
<Image
src={downChevron}
width={20}
height={20}
alt="drop-down"
className={`${
assetDropDownIsOpen && "-rotate-180"
} transition-all duration-200 ease-in`}
/>
</div>
<ul
className={`bg-[#1f1e1e] rounded-md overflow-hidden duration-150 transition-all ease-in-out absolute left-5 right-5 ${
assetDropDownIsOpen ? "h-fit" : "h-0"
}`}
>
<li className="cursor-pointer px-5 py-3">
<button
className="flex justify-between items-center w-full"
onClick={(e) => onChangeToken(e, "strk")}
>
<div className="flex gap-x-4">
<Image
src={starknetLogo}
alt="Stark logo"
width={28}
height={28}
/>
<div className="text-left">
<h3 className="text-sm">STRK</h3>
<h4 className="text-xs">StarkNet Token</h4>
</div>
</div>
</button>
</li>
<li className="cursor-pointer px-5 py-3">
<button
className="flex justify-between items-center w-full"
onClick={(e) => onChangeToken(e, "eth")}
>
<div className="flex gap-x-4">
<Image src={ethLogo} alt="ETH logo" width={28} height={28} />
<div className="text-left">
<h3 className="text-sm">ETH</h3>
<h4 className="text-xs">Ether</h4>
</div>
</div>
</button>
</li>
</ul>
</div>
<form action="">
<div className="flex flex-col gap-y-5">
<div className="flex flex-col gap-y-2">
<h2>Wallet Address</h2>
<input
type="text"
placeholder="Enter Wallet Address"
className="w-full p-2 rounded text-black outline-none focus:border-[#3b81f6] border-[2px]"
value={walletAddress}
onChange={(e) => setWalletAddress(e.target.value)}
/>
</div>

<div className="flex flex-col gap-y-2">
<h2>Amount</h2>
<input
type="text"
placeholder="Enter Amount"
className="w-full p-2 rounded text-black outline-none focus:border-[#3b81f6] border-[2px]"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</div>
</div>

<button
className="w-full mt-7 py-3 bg-[#3b81f6] rounded font-medium flex items-center gap-x-2 justify-center disabled:cursor-not-allowed"
disabled={isLoading || isError}
>
Send <Image src={rightArr} alt="right arrow" height={16} width={16} />
</button>
</form>
</GenericModal>
);
}

export default AssetTransferModal;
31 changes: 29 additions & 2 deletions frontend/src/app/components/BurnerWallet/BurnerWallet.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
"use client";

import { useState } from "react";
import { createPortal } from "react-dom";
import AssetTransferModal from "../AssetTransferModal";
import ConnectionModal from "../ConnectionModal";

function BurnerWallet() {
const [address, setAddress] = useState(
"0x07483a4f6bccee24ee02479530f662a031aca58c7294f71b63a64423cb240f35"
);
const [isSending, setIsSending] = useState(false);
const [isConnecting, setIsConnecting] = useState(false);
return (
<div className="rounded-lg border px-8 py-12 border-gray-300 bg-gray-100 dark:border-neutral-700 dark:bg-neutral-800/30 w-full">
{isSending &&
createPortal(
<AssetTransferModal
isOpen={isSending}
onClose={() => setIsSending(false)}
/>,
document.body
)}
{isConnecting &&
createPortal(
<ConnectionModal
isOpen={isConnecting}
onClose={() => setIsConnecting(false)}
/>,
document.body
)}
<h2 className="mb-[60px] text-2xl font-semibold">Burner Wallet</h2>
<div className="flex gap-[100px] text-2xl font-normal">
<div>
Expand All @@ -22,13 +43,19 @@ function BurnerWallet() {
<h3>{address.slice(0, 12).concat("....").concat(address.slice(-6))}</h3>
</div>
<div className="mt-[80px] flex gap-[60px]">
<button className=" px-6 py-4 bg-blue-500 text-white rounded-[5px] w-[200px] font-semibold">
<button
className=" px-6 py-4 bg-blue-500 text-white rounded-[5px] w-[200px] font-semibold"
onClick={() => setIsSending(true)}
>
SEND
</button>
<button className=" px-6 py-4 bg-blue-500 text-white rounded-[5px] w-[200px] font-semibold">
EXECUTE
</button>
<button className=" px-6 py-4 bg-blue-500 text-white rounded-[5px] w-[200px] font-semibold">
<button
className=" px-6 py-4 bg-blue-500 text-white rounded-[5px] w-[200px] font-semibold"
onClick={() => setIsConnecting(true)}
>
CONNECT
</button>
</div>
Expand Down
96 changes: 96 additions & 0 deletions frontend/src/app/components/ConnectionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"use client";
import GenericModal from "./GenericModal";
import { useEffect, useState } from "react";

type Props = {
isOpen: boolean;
onClose: () => void;
};

function ConnectionModal({ isOpen, onClose }: Props) {
// Form Data
const [accountAddress, setAccountAddress] = useState("");
const [privateKey, setPrivateKey] = useState("");

// useState Variables
const [animate, setAnimate] = useState(false);

const closeModal = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
setAnimate(false);
setTimeout(() => {
onClose();
}, 400);
};

useEffect(() => {
if (isOpen) {
setAnimate(true);
} else {
setAnimate(false);
}
}, [isOpen]);

return (
<GenericModal
isOpen={isOpen}
onClose={closeModal}
animate={animate}
className={`w-[90vw] mx-auto md:h-fit md:w-[45rem] text-white py-4 px-5 relative bg-black`}
>
<div className="absolute right-5 top-4">
<button
onClick={(e) => {
closeModal(e);
e.stopPropagation();
}}
className="w-8 h-8 grid place-content-center rounded-full bg-outline-grey "
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="m6.4 18.308l-.708-.708l5.6-5.6l-5.6-5.6l.708-.708l5.6 5.6l5.6-5.6l.708.708l-5.6 5.6l5.6 5.6l-.708.708l-5.6-5.6z"
/>
</svg>
</button>
</div>
<h1 className="text-[24px] mb-2 font-semibold">Connect Account</h1>
<form action="">
<div className="flex flex-col gap-y-5">
<div className="flex flex-col gap-y-2">
<h2>Private Key</h2>
<input
type="text"
placeholder="Enter Private Key"
className="w-full p-2 rounded text-black outline-none focus:border-[#3b81f6] border-[2px]"
value={privateKey}
onChange={(e) => setPrivateKey(e.target.value)}
/>
</div>

<div className="flex flex-col gap-y-2">
<h2>Account Address</h2>
<input
type="text"
placeholder="Enter Account Address"
className="w-full p-2 rounded text-black outline-none focus:border-[#3b81f6] border-[2px]"
value={accountAddress}
onChange={(e) => setAccountAddress(e.target.value)}
/>
</div>
</div>

<button className="w-full mt-7 py-3 bg-[#3b81f6] rounded font-bold flex items-center gap-x-2 justify-center disabled:cursor-not-allowed">
Connect
</button>
</form>
</GenericModal>
);
}

export default ConnectionModal;
1 change: 1 addition & 0 deletions frontend/src/app/components/GenericModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"use client";
const GenericModal = ({
isOpen,
onClose,
Expand Down
Loading

0 comments on commit 4c1b531

Please sign in to comment.