diff --git a/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/[proposalId]/page.tsx b/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/[proposalId]/page.tsx index 08b19ca04..dcbd4e397 100644 --- a/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/[proposalId]/page.tsx +++ b/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/[proposalId]/page.tsx @@ -8,7 +8,13 @@ import { getProposalDataDocument, getProposalDataQuery, } from "#/subgraph/.graphclient"; -import { Badge, Button, DisplayNumber, EthAddress, Statistic } from "@/components"; +import { + Badge, + Button, + DisplayNumber, + EthAddress, + Statistic, +} from "@/components"; import { ConvictionBarChart } from "@/components/Charts/ConvictionBarChart"; import { LoadingSpinner } from "@/components/LoadingSpinner"; import { usePubSubContext } from "@/contexts/pubsub.context"; @@ -80,9 +86,17 @@ export default function Page({ !!proposalData && (proposalStatus[proposalData.proposalStatus] === "executed" || proposalStatus[proposalData.proposalStatus] === "cancelled"); - logOnce("debug", { isProposalEnded, proposalStatus: proposalStatus[proposalData?.proposalStatus] }); + logOnce("debug", { + isProposalEnded, + proposalStatus: proposalStatus[proposalData?.proposalStatus], + }); - const { currentConvictionPct, thresholdPct, totalSupportPct, updateConvictionLast } = useConvictionRead({ + const { + currentConvictionPct, + thresholdPct, + totalSupportPct, + updateConvictionLast, + } = useConvictionRead({ proposalData, tokenData: data?.tokenGarden, }); @@ -125,7 +139,7 @@ export default function Page({ topic: "proposal", type: "update", function: "distribute", - id:proposalId, + id: proposalId, containerId: data?.cvproposal?.strategy?.id, chainId, }); @@ -171,8 +185,8 @@ export default function Page({
-

- {prettyTimestamp(proposalData?.createdAt ?? 0)} +

+ Submitted: {prettyTimestamp(proposalData?.createdAt ?? 0)}

@@ -192,26 +206,27 @@ export default function Page({ /> }> - + )} }> - +
-

Metrics

- {/* TODO: need designs for this entire section */} {status && proposalStatus[status] === "executed" ? -
-
- Proposal passed and executed successfully -
-
- : ( +

+ Proposal passed and executed successfully! +

+ : <> +

Metrics

- )} + + }
- {proposalStatus[status] !== "executed" && !isSignalingType && ( )} - + {proposalStatus[status] !== "executed" && !isSignalingType && ( + + )}
); } - diff --git a/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/page.tsx b/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/page.tsx index 27665e603..55380b91a 100644 --- a/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/page.tsx +++ b/apps/web/app/(app)/gardens/[chain]/[garden]/[community]/[poolId]/page.tsx @@ -196,7 +196,6 @@ export default function Page({ communityAddress={communityAddress} tokenGarden={tokenGarden} chainId={chain} - spendingLimitPct={spendingLimitPct} /> )}
-

Registration cost:

+

Registration stake:

diff --git a/apps/web/app/(app)/gardens/[chain]/[garden]/page.tsx b/apps/web/app/(app)/gardens/[chain]/[garden]/page.tsx index 1fc184377..d5d950338 100644 --- a/apps/web/app/(app)/gardens/[chain]/[garden]/page.tsx +++ b/apps/web/app/(app)/gardens/[chain]/[garden]/page.tsx @@ -166,12 +166,12 @@ export default function Page({ tree tree { - if (fetching) { - return ; - } - if (tokenGardens?.length) { - return ( - <> - {tokenGardens.map((garden) => ( + return fetching ? + + : <> + {tokenGardens?.map((garden) => (
))} - - ); - } - return ( -

No Gardens

- ); + ; }, [fetching, tokenGardens?.length]); return ( -
-
-
-
- clouds -
-
-
-

- Explore and Join Gardens Ecosystems -

-

- A place where you help shape digital economies -

+ <> +
+
+
+
+ clouds +
+
+
+

+ Explore and Join Gardens Ecosystems +

+

+ A place where you help shape digital economies +

+
+
+
+ clouds
-
- clouds +
+
+
+
+ {GardenList}
-
-
-
-
-
- {GardenList} -
- gardens -
-
+
+
+ gardens + ); } diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx index eba7d0732..056276278 100644 --- a/apps/web/app/page.tsx +++ b/apps/web/app/page.tsx @@ -8,11 +8,10 @@ import { ArrowPathIcon, FingerPrintIcon, LockClosedIcon, - ArrowLongRightIcon, Battery50Icon, } from "@heroicons/react/24/outline"; import Image from "next/image"; -import { newLogo, commF } from "@/assets"; +import { newLogo, commF, HomeBanner } from "@/assets"; import { Button } from "@/components"; import { ChainIcon } from "@/configs/chainServer"; @@ -75,16 +74,6 @@ const Hero = () => { ))} */} -
- - - -
{ healthy, fun, intuitive, secure, and open.

- {/*
+
- Get started + - Learn more + {/* TODO: point to our url docs */} + -
*/} +
+ {"ecosystem { return (
-
-

+
+

Cultivate change with Gardens

-

- Join our Beta and start growing your community. +

+ Join our pre-beta release and start growing your community.

{/* TODO: link to gardnes form */} @@ -372,33 +367,15 @@ const SignUp = () => { > -
- +

diff --git a/apps/web/assets/Banner.png b/apps/web/assets/Banner.png new file mode 100644 index 000000000..80ae08088 Binary files /dev/null and b/apps/web/assets/Banner.png differ diff --git a/apps/web/assets/HomeBanner.png b/apps/web/assets/HomeBanner.png new file mode 100644 index 000000000..7ebf7fef7 Binary files /dev/null and b/apps/web/assets/HomeBanner.png differ diff --git a/apps/web/assets/TreeThree.svg b/apps/web/assets/TreeThree.svg index ae9574da2..e4dd76ac6 100644 --- a/apps/web/assets/TreeThree.svg +++ b/apps/web/assets/TreeThree.svg @@ -1,22 +1,89 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/assets/TreeThree3.svg b/apps/web/assets/TreeThree3.svg new file mode 100644 index 000000000..ae9574da2 --- /dev/null +++ b/apps/web/assets/TreeThree3.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/assets/TreeTwo.svg b/apps/web/assets/TreeTwo.svg index 9fc29db0c..4a77125e2 100644 --- a/apps/web/assets/TreeTwo.svg +++ b/apps/web/assets/TreeTwo.svg @@ -1,25 +1,32 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + diff --git a/apps/web/assets/TreeTwo2.svg b/apps/web/assets/TreeTwo2.svg new file mode 100644 index 000000000..9fc29db0c --- /dev/null +++ b/apps/web/assets/TreeTwo2.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/assets/WalletIcon.svg b/apps/web/assets/WalletIcon.svg index 57c63212f..37e93dd49 100644 --- a/apps/web/assets/WalletIcon.svg +++ b/apps/web/assets/WalletIcon.svg @@ -1,29 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/apps/web/assets/clouds1.svg b/apps/web/assets/clouds1.svg index d2a603b89..46cdc3e0f 100644 --- a/apps/web/assets/clouds1.svg +++ b/apps/web/assets/clouds1.svg @@ -1,49 +1,7 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + diff --git a/apps/web/assets/clouds11.svg b/apps/web/assets/clouds11.svg new file mode 100644 index 000000000..d2a603b89 --- /dev/null +++ b/apps/web/assets/clouds11.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/assets/clouds2.svg b/apps/web/assets/clouds2.svg index 052d93598..42448498e 100644 --- a/apps/web/assets/clouds2.svg +++ b/apps/web/assets/clouds2.svg @@ -1,23 +1,8 @@ - - - - - - - - - \ No newline at end of file + + + + + + + + diff --git a/apps/web/assets/clouds22.svg b/apps/web/assets/clouds22.svg new file mode 100644 index 000000000..052d93598 --- /dev/null +++ b/apps/web/assets/clouds22.svg @@ -0,0 +1,23 @@ + + + + + + + + + \ No newline at end of file diff --git a/apps/web/assets/index.ts b/apps/web/assets/index.ts index c340f952b..29973927e 100644 --- a/apps/web/assets/index.ts +++ b/apps/web/assets/index.ts @@ -25,3 +25,5 @@ export { default as TxError } from "./TxError.svg"; export { default as TxPreparing } from "./TxPreparing.svg"; export { default as TxInProgress } from "./TxInProgress.svg"; export { default as TxIdle } from "./TxIdle.svg"; +export { default as Banner } from "./Banner.png"; +export { default as HomeBanner } from "./HomeBanner.png"; diff --git a/apps/web/components/Breadcrumbs.tsx b/apps/web/components/Breadcrumbs.tsx index fda199a4b..4b27a3a4c 100644 --- a/apps/web/components/Breadcrumbs.tsx +++ b/apps/web/components/Breadcrumbs.tsx @@ -1,9 +1,13 @@ "use client"; import React, { useEffect, useState } from "react"; -import { ChevronRightIcon } from "@heroicons/react/24/solid"; +import { + ChevronRightIcon, + ExclamationTriangleIcon, +} from "@heroicons/react/24/solid"; import Link from "next/link"; import { usePathname } from "next/navigation"; +import { Button } from "./Button"; import { getTitlesFromUrlSegments } from "@/services/getTitlesFromUrlSegments"; interface Breadcrumb { @@ -18,6 +22,15 @@ const truncateString = (str: string) => { export function Breadcrumbs() { const path = usePathname(); const [breadcrumbs, setBreadcrumbs] = useState([]); + const notAuditedDisclaimerAckStorageKey = "NotAuditedDisclaimerAck"; + const [openDisclaimer, setOpenDisclaimer] = useState(false); + + useEffect(() => { + const disclaimerAcknowledged = localStorage.getItem( + notAuditedDisclaimerAckStorageKey, + ); + setOpenDisclaimer(disclaimerAcknowledged !== "true"); + }, []); const fetchBreadcrumbs = async (): Promise => { const segments = path.split("/").filter((segment) => segment !== ""); @@ -53,6 +66,11 @@ export function Breadcrumbs() { })(); }, [path]); + const handleDisclaimerAcknowledgment = () => { + setOpenDisclaimer(false); + localStorage.setItem(notAuditedDisclaimerAckStorageKey, "true"); + }; + if (!breadcrumbs.length) { return <>; } @@ -85,6 +103,32 @@ export function Breadcrumbs() { ))} + {openDisclaimer && ( +
+
+
+ +
Disclaimer
+
+

+ You are exploring the frontier with our contracts.{" "} + + Please note that they have not been audited yet + + . Exercise caution and proceed at your own risk. +

+
+ +
+
+
+ )} ); } diff --git a/apps/web/components/Charts/ChartWrapper.tsx b/apps/web/components/Charts/ChartWrapper.tsx index 75be28d00..4dbee2bad 100644 --- a/apps/web/components/Charts/ChartWrapper.tsx +++ b/apps/web/components/Charts/ChartWrapper.tsx @@ -28,12 +28,12 @@ export const ChartWrapper = ({ name: "Support", // TODO: missing color in Design system: ask designer className: "bg-[#A8E066] h-4 w-4 rounded-full", - info: "Represents the pool weight allocated in favor of a proposal.", + info: "Represents the total pool voting weight currently allocated to a proposal.", }, { name: "Conviction", className: "bg-primary-content h-4 w-4 rounded-full", - info: "Accumulated allocation power for a proposal, increasing over time.", + info: "Accumulated pool voting weight for a proposal, increasing over time, based on the conviction growth rate.", }, { name: "Threshold", @@ -59,8 +59,8 @@ export const ChartWrapper = ({
- :
} -

{item.name}

+ :
} +

{item.name}

diff --git a/apps/web/components/Charts/ConvictionBarChart.tsx b/apps/web/components/Charts/ConvictionBarChart.tsx index 290d9185b..51182f699 100644 --- a/apps/web/components/Charts/ConvictionBarChart.tsx +++ b/apps/web/components/Charts/ConvictionBarChart.tsx @@ -235,7 +235,8 @@ export const ConvictionBarChart = ({ trigger: "axis", valueFormatter: (value) => value + "%", borderWidth: 1, - borderColor: "#191919", + borderColor: "#65AD18", + backgroundColor: "#FCFFF7", axisPointer: { type: "none", }, @@ -248,9 +249,7 @@ export const ConvictionBarChart = ({ bottom: compact ? "0%" : "25%", containLabel: false, }, - // TODO: realted to re render in PoolId page (check) - animation: false, - //animationDurationUpdate: 1200, + animation: true, barGap: "-100%", series: [ { @@ -261,7 +260,7 @@ export const ConvictionBarChart = ({ borderRadius: [20, 20, 20, 20], }, showBackground: true, - backgroundStyle:{ + backgroundStyle: { color: "#F0F0F0", borderRadius: [20, 20, 20, 20], }, diff --git a/apps/web/components/ConnectWalletButton.tsx b/apps/web/components/ConnectWalletButton.tsx index 5853ecf44..34c474b91 100644 --- a/apps/web/components/ConnectWalletButton.tsx +++ b/apps/web/components/ConnectWalletButton.tsx @@ -15,7 +15,7 @@ import { useSwitchNetwork, } from "wagmi"; import { walletIcon } from "@/assets"; -import { Button } from "@/components"; +import { Button, DisplayNumber } from "@/components"; import { ChainIcon } from "@/configs/chainServer"; import { useChainFromPath } from "@/hooks/useChainFromPath"; import { formatAddress } from "@/utils/formatAddress"; @@ -63,8 +63,9 @@ export function ConnectWallet() { alt="wallet" height={20} width={20} + loading="lazy" /> - Connect + Connect wallet ); } @@ -80,49 +81,49 @@ export function ConnectWallet() { ); } + //Is CONNECTED to a supported chains with condition => urlChainId(urlChain) === chainId(wallet) //Dropdown menu with wallet, balance, switch network and disconnect buttons return ( - + {({ open }) => ( <>
{"Chain
-

+

{formatAddress(accountAddress.address)} -
-
+ +
{( !urlChainId || isNaN(urlChainId!) || chain.id === urlChainId ) ? <> - Connected to -
- -
- {chain.name} + +

{chain.name}

- : - Network mismatch - + :

+ Switch to network {chainFromPath?.name ?? ""} +

}
- -
+ +
{/* wallet and token balance info */}
- Wallet{" "} - {wallet} +

Wallet

{" "} +

{wallet}

- Balance - - {" "} - {!tokenUrlAddress ? - "Unknow garden" - : Number(token?.formatted).toFixed(0)}{" "} - {token?.symbol === "ETH" ? "" : token?.symbol} - +

Balance

+ +
@@ -177,7 +178,7 @@ export function ConnectWallet() {
); })()} + {urlChainId === chain?.id && tokenUrlAddress !== undefined && ( +
+

Balance

+ +
+ )} ); }} diff --git a/apps/web/components/IncreasePower.tsx b/apps/web/components/IncreasePower.tsx index f191b0786..c0abddf39 100644 --- a/apps/web/components/IncreasePower.tsx +++ b/apps/web/components/IncreasePower.tsx @@ -1,6 +1,7 @@ "use client"; import { useEffect, useState } from "react"; +import { Dnum } from "dnum"; import { parseUnits } from "viem"; import { Address, useAccount, useBalance } from "wagmi"; import { @@ -11,6 +12,7 @@ import { import { Button } from "./Button"; import { DisplayNumber } from "./DisplayNumber"; import { InfoBox } from "./InfoBox"; +import { InfoIcon } from "./InfoIcon"; import { TransactionModal, TransactionProps } from "./TransactionModal"; import { usePubSubContext } from "@/contexts/pubsub.context"; import { useChainIdFromPath } from "@/hooks/useChainIdFromPath"; @@ -19,6 +21,7 @@ import { ConditionObject, useDisableButtons } from "@/hooks/useDisableButtons"; import { useHandleAllowance } from "@/hooks/useHandleAllowance"; import { registryCommunityABI } from "@/src/generated"; import { abiWithErrors2 } from "@/utils/abiWithErrors"; +import { parseToken } from "@/utils/numbers"; import { getTxMessage } from "@/utils/transactionMessages"; type IncreasePowerProps = { @@ -34,12 +37,14 @@ type IncreasePowerProps = { | "registerToken" >; tokenGarden: Pick; + registrationAmount: Dnum; }; export const IncreasePower = ({ memberData, registryCommunity, tokenGarden, + registrationAmount, }: IncreasePowerProps) => { const { symbol: tokenSymbol, @@ -207,8 +212,14 @@ export const IncreasePower = ({ if (!isMember) return null; + const AddedStake = [ + BigInt(memberStakedTokens - registerStakeAmountBigInt), + tokenDecimals, + ] as Dnum; + return ( -
+
+

Your stake

-
-
- -
+
-

Current Stake:

- -
-
-

Added Stake:

- +

Total Staked in the community:

+ + +
+
diff --git a/apps/web/components/NavBar.tsx b/apps/web/components/NavBar.tsx index d7145b047..217b62f4e 100644 --- a/apps/web/components/NavBar.tsx +++ b/apps/web/components/NavBar.tsx @@ -13,15 +13,18 @@ export function NavBar() { return ( {({ open }) => ( <> -
-
+
+
-
- +
+ logo - {/* */} - Gardens +

Gardens

- {/* TODO: change or remove after alpha */} -
- alpha version -
+

+ pre-beta release{" "} +

{/* {navItems.map(({ name, href }) => ( diff --git a/apps/web/components/PoolCard.tsx b/apps/web/components/PoolCard.tsx index 2bb147b81..034959452 100644 --- a/apps/web/components/PoolCard.tsx +++ b/apps/web/components/PoolCard.tsx @@ -58,24 +58,17 @@ export function PoolCard({ pool, tokenGarden }: Props) { label="proposals" /> {poolType && poolTypes[poolType] === "funding" && ( - } - - label="funds available" > + } label="funds available"> - - )}
{!isEnabled ? -
+
Waiting for approval
diff --git a/apps/web/components/PoolGovernance.tsx b/apps/web/components/PoolGovernance.tsx index 909f8c875..154ddc3a6 100644 --- a/apps/web/components/PoolGovernance.tsx +++ b/apps/web/components/PoolGovernance.tsx @@ -8,6 +8,7 @@ import { Badge, DisplayNumber, CheckPassport, + InfoBox, } from "@/components/"; import { LightCVStrategy } from "@/types"; @@ -32,62 +33,63 @@ export const PoolGovernance: React.FC = ({ }) => { const showPoolGovernanceData = isMemberCommunity && memberActivatedStrategy; + const poolSystem = strategy.config.pointSystem; + + const poolSystemDefinition: { [key: number]: string } = { + 0: "This pool has a fixed points system, meaning every member has the same governance weight, limited to their registration stake.", + 1: "This pool has a capped points system, meaning your governance weight will increase but capped based to maximum of tokens you have staked.", + 2: "This pool has an unlimited points system, allowing you to increase your governance weight without restrictions as you stake more tokens.", + 3: "This pool has a quadratic points system, meaning your governance weight grows at a squared rate relative to the tokens you have staked.", + }; + return (
-
+

Pool Governance

+
+ + + +
-
-
-
-
- {showPoolGovernanceData ? - <> -
-
Total staked in community:
- -
-
-
Status:
-
- -
-
-
-
Your governance weight:
-

- {memberPoolWeight.toFixed(2)} % - of the pool -

-
- - :
-
Status:
-
- -
-
- } -
-
-
- - +
+
+
+

Your stake in the community:

+ - + +
+ {showPoolGovernanceData && ( +
+
+

Your governance weight:

+

+ {memberPoolWeight.toFixed(2)} % +

+
+ + +
+ )}
diff --git a/apps/web/components/PoolMetrics.tsx b/apps/web/components/PoolMetrics.tsx index d84f2c5cf..6b0211ad2 100644 --- a/apps/web/components/PoolMetrics.tsx +++ b/apps/web/components/PoolMetrics.tsx @@ -14,14 +14,13 @@ import { useDisableButtons } from "@/hooks/useDisableButtons"; import { useHandleAllowance } from "@/hooks/useHandleAllowance"; import { alloABI } from "@/src/generated"; import { abiWithErrors } from "@/utils/abiWithErrors"; -import { formatTokenAmount, MAX_RATIO_CONSTANT } from "@/utils/numbers"; +import { formatTokenAmount } from "@/utils/numbers"; import { getTxMessage } from "@/utils/transactionMessages"; interface PoolMetricsProps { poolAmount: number; communityAddress: Address; tokenGarden: Pick; - spendingLimitPct: number; alloInfo: Allo; poolId: number; chainId: string; @@ -32,7 +31,6 @@ export const PoolMetrics: FC = ({ poolAmount, communityAddress, tokenGarden, - spendingLimitPct, poolId, chainId, }) => { @@ -116,28 +114,20 @@ export const PoolMetrics: FC = ({
-
-
-

Pool Metrics

-
-
-
-
-
Funds Available:
-

- {formatTokenAmount(poolAmount, tokenGarden.decimals)}{" "} - {tokenGarden.symbol} -

-
-
-
Spending Limit:
-

- {`${(spendingLimitPct * MAX_RATIO_CONSTANT).toFixed(2)} %`} -

-
+
+

Pool Funds

+
+
+

Funds available:

+
{ e.preventDefault(); handleFundPool(); @@ -147,7 +137,6 @@ export const PoolMetrics: FC = ({ type="number" placeholder="0" required - className="" step={INPUT_TOKEN_MIN_VALUE} onChange={(e) => setAmount(e.target.value)} value={amount} @@ -164,8 +153,9 @@ export const PoolMetrics: FC = ({ type="submit" disabled={missmatchUrl || !accountAddress} tooltip={tooltipMessage} + className="min-w-[200px]" > - Fund pool + Add Funds