Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add vaults in fund page #2763

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 99 additions & 3 deletions src/plugins/admin/Funds.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, { useEffect, useState } from 'react'
import type { UndefinedOr } from '@devprotocol/util-ts'

import StakeInfo from './StakeInfo'
import { KYCStatuses } from './Withdrawal'
import { ALL_CURRENCIES } from '@constants/memberships'
import CreateClubsVault from './components/CreateClubsVault'
import CurrencyMembershipInfo from './CurrencyMembershipInfo'
import NotVerifiedBannerImg from './assets/NotVerifiedBannerImg.svg'

const FundsInfo = (props: {
vaultAddress: UndefinedOr<string>
propertyAddress: string
chainId: number
uniqueBeneficiaries: string[]
Expand Down Expand Up @@ -64,9 +66,103 @@ const FundsInfo = (props: {

return (
<>
{/* <!-- Memberships/NFT section --> */}
{/* <!-- Clubs vault section --> */}
<div>
<p className="text-3xl font-bold">Memberships/NFTs</p>
<p className="text-3xl font-bold">Clubs Vault</p>

{/* <!-- Create vault button --> */}
{!props.vaultAddress && (
<div className="mt-8 w-full max-w-full">
<CreateClubsVault
isKYCVerified={KYCStatuses.VERIFIED === props.KYCStatus}
/>
</div>
)}

{/* <!-- Your withdrawable funds --> */}
{props.vaultAddress && (
<div className="mt-8 w-full max-w-full rounded-2xl border border-dp-blue-grey-300 p-4 dark:border-dp-blue-grey-200 lg:p-8">
<p className="w-fit text-base font-bold opacity-50">
Your withdrawable funds
</p>
<section className="mt-5 flex items-center gap-5">
<p className="text-4xl">
$
{new Intl.NumberFormat(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 3,
}).format(
Number(
yourTotalWithdrawableInDollars.reduce(
(prev: string, curr: string) =>
String(Number(prev) + Number(curr)),
),
) || 0,
)}
</p>
<p className="w-fit text-base font-bold opacity-50">
equivalent tokens
</p>
</section>
{ALL_CURRENCIES.map((curr, id) => (
<CurrencyMembershipInfo
key={`${curr}:=:${id}`}
chainId={props.chainId}
currency={curr}
allCurrencyIndex={id}
isYourWithdrawable={true}
uniqueBeneficiaries={[]}
updateWithdrawableInDollars={updateYourTotalWithdrawable}
isKYCVerified={KYCStatuses.VERIFIED === props.KYCStatus}
/>
))}
</div>
)}

{/* <!-- Total withdrawable funds --> */}
{props.vaultAddress && (
<div className="mt-8 w-full max-w-full rounded-2xl border border-dp-blue-grey-300 p-4 dark:border-dp-blue-grey-200 lg:p-8">
<p className="w-fit text-base font-bold opacity-50">
Total withdrawable funds
</p>
<section className="mt-5 flex items-center gap-5">
<p className="text-2xl">
$
{new Intl.NumberFormat(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 3,
}).format(
Number(
totalWithrawableInDollars.reduce(
(prev: string, curr: string) =>
String(Number(prev) + Number(curr)),
),
) || 0,
)}
</p>
<p className="w-fit text-base font-bold opacity-50">
equivalent tokens
</p>
</section>
{ALL_CURRENCIES.map((curr, id) => (
<CurrencyMembershipInfo
key={`${curr}:=:${id}`}
chainId={props.chainId}
currency={curr}
allCurrencyIndex={id}
isYourWithdrawable={false}
uniqueBeneficiaries={props.uniqueBeneficiaries}
updateWithdrawableInDollars={updateTotalWithdrawable}
isKYCVerified={false}
/>
))}
</div>
)}
</div>

{/* <!-- Direct payments section --> */}
<div>
<p className="text-3xl font-bold">Direct Payments</p>

{/* <!-- Your withdrawable funds --> */}
<div className="mt-8 w-full max-w-full rounded-2xl border border-dp-blue-grey-300 p-4 dark:border-dp-blue-grey-200 lg:p-8">
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/admin/Withdrawal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from 'react'

import KYCInfo from './KYCInfo'
import FundsInfo from './Funds'
import type { UndefinedOr } from '@devprotocol/util-ts'

export enum KYCStatuses {
VERIFIED,
Expand All @@ -10,6 +11,7 @@ export enum KYCStatuses {
}

export const Withdrawal = (props: {
vaultAddress: UndefinedOr<string>
propertyAddress: string
chainId: number
uniqueBeneficiaries: string[]
Expand All @@ -30,6 +32,7 @@ export const Withdrawal = (props: {
<FundsInfo
KYCStatus={KYCStatus}
chainId={props.chainId}
vaultAddress={props.vaultAddress}
uniqueBeneficiaries={props.uniqueBeneficiaries}
propertyAddress={props.propertyAddress}
/>
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/admin/assets/CreateVault.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions src/plugins/admin/components/CreateClubsVault.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState } from 'react'

import CreateVaultSVG from '../assets/CreateVault.svg'

interface ICreateClubsVaultProps {
isKYCVerified: boolean
}

const CreateClubsVault = (props: ICreateClubsVaultProps) => {
const [isCreatingVault, setIsCreatingVault] = useState<boolean>(false)

const createVault = async () => {
setIsCreatingVault(true)

// @TODO: add logic to create vault here.

setIsCreatingVault(false)
}

return (
<button
onClick={() => createVault()}
disabled={!props.isKYCVerified}
className={`hs-button is-filled col-span-2 flex justify-center items-center py-4 px-8 ${
!props.isKYCVerified
? 'disabled:cursor-not-allowed disabled:hover:animate-[horizontal-shaking_.06s_5]'
: ''
} lg:col-span-1 ${
isCreatingVault ? 'animate-pulse bg-dp-blue-grey-600' : ''
}`}
>
<div className="min-w-6 min-h-6">
<img src={CreateVaultSVG.src} alt="Create clubs vault" />
</div>
<p className="w-fit font-body text-base text-center font-bold text-dp-white-ink">
Create Clubs Vault
</p>
</button>
)
}

export default CreateClubsVault
6 changes: 3 additions & 3 deletions src/plugins/admin/funds.astro
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
---
import FundsTeaser from './FundsTeaser.tsx'
import { ZeroAddress } from 'ethers'
import type { Membership } from '@plugins/memberships'

import { KYCStatuses, Withdrawal } from './Withdrawal'
import { Withdrawal } from './Withdrawal'

const { memberships, chainId, propertyAddress } = Astro.props
const { memberships, chainId, propertyAddress, vaultAddress } = Astro.props

let beneficiaries: string[] = memberships.map(
(membership: Membership) => membership.fee?.beneficiary ?? ZeroAddress,
Expand All @@ -22,6 +21,7 @@ const uniqueBeneficiaries = new Array(...new Set(beneficiaries))
chainId={chainId}
uniqueBeneficiaries={uniqueBeneficiaries}
propertyAddress={propertyAddress}
vaultAddress={vaultAddress}
/>
</div>
</section>
6 changes: 5 additions & 1 deletion src/plugins/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ import { default as Overview } from './overview.astro'

export const getPagePaths = (async () => []) satisfies ClubsFunctionGetPagePaths

export const getAdminPaths = (async (_, config) => {
export const getAdminPaths = (async (options, config) => {
const membersihpPlugin = config.plugins.find(
(plg) => plg.id === 'devprotocol:clubs:simple-memberships',
)
const memberships =
(membersihpPlugin?.options.find((opt) => opt.key === 'memberships')
?.value as UndefinedOr<Membership[]>) ?? []

const vaultAddress = config.options?.find((option) => option.key === 'vault')
?.value as UndefinedOr<string>

return [
{
paths: ['general'],
Expand Down Expand Up @@ -52,6 +55,7 @@ export const getAdminPaths = (async (_, config) => {
propertyAddress: config.propertyAddress,
rpcUrl: config.rpcUrl,
chainId: config.chainId,
vaultAddress,
},
},
]
Expand Down