-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dee5903
commit 99468b1
Showing
29 changed files
with
1,463 additions
and
190 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,52 @@ | ||
import React from 'react'; | ||
import HomeIcon from '../assets/home-icon.svg'; | ||
import ChevronRightIcon from '../assets/chevron-right-icon.svg'; | ||
import Image from 'next/image'; | ||
import Link from 'next/link'; | ||
|
||
interface BreadcrumbsProps { | ||
pages: Page[]; | ||
} | ||
|
||
interface Page { | ||
name: string; | ||
href: string; | ||
current?: boolean; | ||
} | ||
|
||
const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ pages }) => { | ||
return ( | ||
<nav aria-label="Breadcrumb" className="px-4 mt-4 flex"> | ||
<ol role="list" className="flex items-center space-x-4"> | ||
<li> | ||
<div> | ||
<a href="/" className="text-gray-400 hover:text-gray-500"> | ||
<Image className="ps-2 w-8 inline" src={HomeIcon} alt={'Home'} /> | ||
<span className="sr-only">Home</span> | ||
</a> | ||
</div> | ||
</li> | ||
{pages.map((page) => ( | ||
<li key={page.name}> | ||
<div className="flex items-center"> | ||
<Image | ||
className="ps-2 h-5 w-5 inline" | ||
src={ChevronRightIcon} | ||
alt={'>'} | ||
/> | ||
<Link | ||
href={page.href} | ||
aria-current={page.current ? 'page' : undefined} | ||
className="ml-4 text-sm font-medium text-gray-500 hover:text-gray-700" | ||
> | ||
{page.name} | ||
</Link> | ||
</div> | ||
</li> | ||
))} | ||
</ol> | ||
</nav> | ||
); | ||
}; | ||
|
||
export default Breadcrumbs; |
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,40 @@ | ||
import Image from 'next/image'; | ||
import CopyIcon from '../assets/copy-icon.png'; | ||
import React, { useState } from 'react'; | ||
import { InfoAlert } from '@/components'; | ||
|
||
interface CopyTextProps { | ||
text: string; | ||
alertMessage?: string; | ||
} | ||
|
||
const CopyText: React.FC<CopyTextProps> = ({ text, alertMessage }) => { | ||
const [alertText, setAlertText] = useState<string | null>(null); | ||
return ( | ||
<> | ||
<InfoAlert | ||
show={alertText != null} | ||
hide={() => setAlertText(null)} | ||
alertText={alertText || ''} | ||
className="my-3" | ||
/> | ||
<div className="flex flex-row no-wrap"> | ||
<div className="grow-0 outline rounded p-1"> | ||
<span className="font-mono">{text}</span> | ||
<Image | ||
className="ps-2 w-8 inline" | ||
src={CopyIcon} | ||
alt={'Copy'} | ||
onClick={() => | ||
navigator.clipboard | ||
.writeText(text || '') | ||
.then(() => setAlertText(alertMessage ?? 'Copied')) | ||
} | ||
/> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default CopyText; |
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,43 @@ | ||
import React from 'react'; | ||
import { useRouter } from 'next/router'; | ||
|
||
const tabs = [ | ||
{ name: 'Home', href: '/' }, | ||
{ name: 'Staking', href: '/staking' }, | ||
{ name: 'Staking positions', href: '/staking/positions' }, | ||
]; | ||
|
||
function classNames(...classes: string[]) { | ||
return classes.filter(Boolean).join(' '); | ||
} | ||
|
||
const NavigationBar: React.FC = () => { | ||
const router = useRouter(); | ||
const currentTab = tabs.find((tab) => tab.href === router.pathname); | ||
const tabName = currentTab ? currentTab.name : undefined; | ||
return ( | ||
<div> | ||
<div className="border-b border-gray-200"> | ||
<nav aria-label="Tabs" className="-mb-px flex space-x-8"> | ||
{tabs.map((tab) => ( | ||
<a | ||
key={tab.name} | ||
href={tab.href} | ||
aria-current={tab.name == tabName ? 'page' : undefined} | ||
className={classNames( | ||
tab.name == tabName | ||
? 'text-label-dark-primary border-b-2 border-brand-light-primary' | ||
: 'text-label-dark-secondary', | ||
'whitespace-nowrap h-10 p-2 text-sm font-medium' | ||
)} | ||
> | ||
{tab.name} | ||
</a> | ||
))} | ||
</nav> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default NavigationBar; |
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
159 changes: 159 additions & 0 deletions
159
apps/vault/src/components/staking/VaultStakeActionModal.tsx
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,159 @@ | ||
import { BasicButton, Modal } from 'ui'; | ||
import React, { useState } from 'react'; | ||
import { | ||
getStakingConstraints, | ||
validateStakeAction, | ||
} from '@/utils/stakingRules'; | ||
|
||
interface StakeActionModalProps { | ||
vaultStakeAssetId: string; | ||
available: number; | ||
hide: () => void; | ||
className?: string; | ||
} | ||
|
||
const VaultStakeActionModal: React.FC<StakeActionModalProps> = ({ | ||
vaultStakeAssetId, | ||
available, | ||
hide, | ||
className, | ||
}) => { | ||
let extraInfo; | ||
if (vaultStakeAssetId.startsWith('ETH')) { | ||
extraInfo = 'Staked ETH has to be less than 32, or multiple of 32.'; | ||
} | ||
const { minimumStakeAmount, maximumStakeAmount, minimumAvailable } = | ||
getStakingConstraints(available); | ||
const [stakeAmount, setStakeAmount] = useState<number>(maximumStakeAmount); | ||
const { balanceAfterStaking, stakeError, balanceAfterError } = | ||
validateStakeAction(vaultStakeAssetId, available, stakeAmount); | ||
const balanceAfterClassName = balanceAfterError | ||
? 'border-2 border-brand-light-primary disabled:bg-brand-light-primary text-label-dark-primary' | ||
: 'border disabled:ui-bg-default-systemGrey-light-2'; | ||
const stakeAmountClassName = stakeError | ||
? 'border-brand-light-primary bg-brand-light-primary text-label-dark-primary' | ||
: ''; | ||
const valid = !!balanceAfterError && !!stakeError; | ||
return ( | ||
<div className={className}> | ||
<Modal backdrop={true} open={true} onClose={() => {}} size={'small'}> | ||
<div className="space-y-12 sm:space-y-16"> | ||
<div> | ||
<h1 className="block text-label-light-secondary text-[32px]"> | ||
Stake | ||
</h1> | ||
<p className="mt-1 max-w-2xl text-sm leading-6 text-gray-600"> | ||
Stake your <span className="font-semibold text-[18px]">ETH</span>{' '} | ||
or <span className="font-bold text-[18px]">SOL</span> assets. | ||
<br /> | ||
Support to stake{' '} | ||
<span className="font-bold text-[18px]">MATIC</span> is coming | ||
soon. | ||
</p> | ||
|
||
<div className="pt-5"> | ||
<div> | ||
<label className="font-medium">Vault Asset</label> | ||
</div> | ||
<div className="p-2"> | ||
<input | ||
className="border px-1 w-full disabled:ui-bg-default-systemGrey-light-2" | ||
type="text" | ||
value={vaultStakeAssetId} | ||
disabled={true} | ||
/> | ||
</div> | ||
<div> | ||
<label className="font-medium">Available Balance</label> | ||
</div> | ||
<div className="p-2"> | ||
<input | ||
className="border px-1 w-full disabled:ui-bg-default-systemGrey-light-2" | ||
type="text" | ||
value={available} | ||
disabled={true} | ||
/> | ||
</div> | ||
<div> | ||
<label className="font-medium">Balance after staking</label>{' '} | ||
(minimum: {minimumAvailable}) | ||
</div> | ||
<div className="p-2"> | ||
<input | ||
className={`px-1 w-full ${balanceAfterClassName}`} | ||
type="text" | ||
value={balanceAfterStaking} | ||
disabled={true} | ||
/> | ||
<div className="text-brand-light-primary text-[16px]"> | ||
{balanceAfterError ?? ''} | ||
</div> | ||
</div> | ||
<div className="pt-4"> | ||
<label htmlFor="last-name" className="font-medium"> | ||
Stake Amount | ||
</label>{' '} | ||
(minimum: {minimumStakeAmount}) | ||
</div> | ||
<div className="p-2"> | ||
<input | ||
className={`border-2 px-1 w-full ${stakeAmountClassName}`} | ||
type="number" | ||
value={stakeAmount} | ||
onChange={(e) => { | ||
if (e.target.value === '') { | ||
setStakeAmount(0); | ||
} else { | ||
setStakeAmount(parseFloat(e.target.value)); | ||
} | ||
}} | ||
required={true} | ||
/> | ||
<div className="text-brand-light-primary text-[16px]"> | ||
{stakeError ?? ''} | ||
</div> | ||
</div> | ||
</div> | ||
<div className="mt-5"> | ||
<h1 className="block text-label-light-secondary text-[24px]"> | ||
Requirements | ||
</h1> | ||
</div> | ||
<div className="ms-5"> | ||
<ul className="list-disc"> | ||
{extraInfo && ( | ||
<li className="font-normal text-label-light-primary"> | ||
{extraInfo} | ||
</li> | ||
)} | ||
<li> | ||
<span className="font-normal text-label-light-primary"> | ||
Minimum stake amount: | ||
</span>{' '} | ||
<span className="font-mono">{minimumStakeAmount}</span> | ||
</li> | ||
<li> | ||
<span className="font-normal text-label-light-primary"> | ||
Minimum balance to be maintained: | ||
</span>{' '} | ||
<span className="font-mono">{minimumAvailable}</span> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div className="mt-6 flex items-center justify-end gap-x-6"> | ||
<BasicButton variant="secondary" size="medium" onClick={hide}> | ||
Cancel | ||
</BasicButton> | ||
<BasicButton variant="primary" size="medium" disabled={!valid}> | ||
Submit | ||
</BasicButton> | ||
</div> | ||
</Modal> | ||
</div> | ||
); | ||
}; | ||
|
||
export default VaultStakeActionModal; |
Oops, something went wrong.