Skip to content

Commit

Permalink
Merge pull request #500 from 1Hive/reject-pool
Browse files Browse the repository at this point in the history
Reject pool
  • Loading branch information
Corantin authored Dec 7, 2024
2 parents e4305a1 + 9388363 commit 3aec24d
Show file tree
Hide file tree
Showing 20 changed files with 443 additions and 145 deletions.
5 changes: 4 additions & 1 deletion apps/web/components/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type BadgeProps = {
className?: string;
icon?: React.ReactNode;
isCapitalize?: boolean;
tooltip?: string;
};

// Styles for different pool badge types
Expand Down Expand Up @@ -39,6 +40,7 @@ export function Badge({
status,
label,
className,
tooltip,
icon,
}: BadgeProps): JSX.Element {
const isStatusBadge = status !== undefined;
Expand Down Expand Up @@ -70,7 +72,8 @@ export function Badge({

return (
<div
className={`${BASE_STYLES} ${styles} ${className} flex items-center gap-2`}
className={`${BASE_STYLES} ${styles} ${tooltip ? "tooltip" : ""} ${className} flex items-center gap-2`}
data-tip={tooltip}
>
{iconIncluded && (
<div className="h-6 w-6 text-inherit">{iconIncluded}</div>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ const btnStyles: BtnStyles = {
},
outline: {
primary:
"text-primary-content border border-primary-content hover:text-primary-hover-content hover:outline-primary-hover-content",
"text-primary-content border border-primary-content hover:text-primary-hover-content hover:border-primary-hover-content",
secondary:
"text-secondary-content border border-secondary-content hover:text-secondary-hover-content hover:outline-secondary-hover-content",
"text-secondary-content border border-secondary-content hover:text-secondary-hover-content hover:border-secondary-hover-content",
tertiary: "",
danger:
"text-danger-button border border-danger-button hover:text-danger-hover-content hover:outline-danger-hover-content",
"text-danger-button border border-danger-button hover:text-danger-hover-content hover:border-danger-hover-content",
disabled: "text-neutral-soft-content border border-neutral-soft-content",
},
link: {
Expand Down
19 changes: 7 additions & 12 deletions apps/web/components/Forms/PoolForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import { FormRadioButton } from "./FormRadioButton";
import { FormSelect } from "./FormSelect";
import { EthAddress } from "../EthAddress";
import { Button } from "@/components/Button";
import { DEFAULT_RULING_TIMEOUT_SEC } from "@/configs/constants";
import {
DEFAULT_RULING_TIMEOUT_SEC,
VOTING_POINT_SYSTEM_DESCRIPTION,
} from "@/configs/constants";
import { QUERY_PARAMS } from "@/constants/query-params";
import { usePubSubContext } from "@/contexts/pubsub.context";
import { useChainFromPath } from "@/hooks/useChainFromPath";
Expand Down Expand Up @@ -595,14 +598,6 @@ export function PoolForm({ token, communityAddr }: Props) {
}
}, [customTokenData, watchedAddress, trigger]);

const votingWeightSystemDescriptions = {
fixed: "Everyone has the same voting weight, limited to registration stake",
capped: "Voting weight is equal to tokens staked, up to a limit",
unlimited: "Voting weight is equal to tokens staked, no limit.",
quadratic:
"Voting weight increases as more tokens are staked, following a quadratic curve.",
};

return (
<form onSubmit={handleSubmit(handlePreview)} className="w-full">
{showPreview ?
Expand Down Expand Up @@ -676,18 +671,18 @@ export function PoolForm({ token, communityAddr }: Props) {
<span className="ml-1">*</span>
</label>
<div className="ml-2 flex flex-col gap-2">
{Object.entries(PointSystems).map(([value, label], i) => (
{Object.entries(PointSystems).map(([value, id], i) => (
<div key={value}>
<FormRadioButton
value={value}
label={capitalize(label)}
label={capitalize(id)}
inline={true}
onChange={() =>
setValue("pointSystemType", parseInt(value))
}
checked={parseInt(value) === pointSystemType}
registerKey="pointSystemType"
description={votingWeightSystemDescriptions[label]}
description={VOTING_POINT_SYSTEM_DESCRIPTION[id]}
/>
{PointSystems[pointSystemType] === "capped" &&
i === Object.values(PointSystems).indexOf("capped") && (
Expand Down
167 changes: 130 additions & 37 deletions apps/web/components/PoolHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import {
ChartBarIcon,
CheckIcon,
ClockIcon,
Cog6ToothIcon,
InformationCircleIcon,
Square3Stack3DIcon,
} from "@heroicons/react/24/outline";
import { StopIcon } from "@heroicons/react/24/solid";
import {
ArchiveBoxIcon,
NoSymbolIcon,
StopIcon,
Cog6ToothIcon,
} from "@heroicons/react/24/solid";
import { FetchTokenResult } from "@wagmi/core";
import Image from "next/image";
import { usePathname, useRouter } from "next/navigation";
import { Address, zeroAddress } from "viem";
import { useAccount, useContractRead } from "wagmi";
import {
Expand All @@ -32,6 +37,7 @@ import { Skeleton } from "./Skeleton";
import { Statistic } from "./Statistic";
import { blueLand, grassLarge } from "@/assets";
import { chainConfigMap } from "@/configs/chains";
import { VOTING_POINT_SYSTEM_DESCRIPTION } from "@/configs/constants";
import { usePubSubContext } from "@/contexts/pubsub.context";
import { useChainFromPath } from "@/hooks/useChainFromPath";
import { useContractWriteWithConfirmations } from "@/hooks/useContractWriteWithConfirmations";
Expand Down Expand Up @@ -95,7 +101,6 @@ function calculateMinimumConviction(weight: number, spendingLimit: number) {

return minimumConviction;
}

export default function PoolHeader({
ipfsResult,
poolId,
Expand All @@ -110,6 +115,9 @@ export default function PoolHeader({
const { address } = useAccount();
const { publish } = usePubSubContext();
const { id: chainId, safePrefix } = useChainFromPath()!;
const router = useRouter();
const path = usePathname();
const isArchived = strategy.archived;

const { data: passportStrategyData } =
useSubgraphQuery<getPassportStrategyQuery>({
Expand All @@ -128,7 +136,6 @@ export default function PoolHeader({
passportStrategy?.threshold ?
Number(passportStrategy?.threshold) / CV_PASSPORT_THRESHOLD_SCALE
: null;

const blockTime = chainConfigMap[chainId!].blockTime;
const spendingLimitPct =
(Number(strategy.config.maxRatio || 0) / CV_SCALE_PRECISION) * 100;
Expand Down Expand Up @@ -275,6 +282,31 @@ export default function PoolHeader({
},
});

const { write: rejectPoolWrite } = useContractWriteWithConfirmations({
address: communityAddr,
abi: registryCommunityABI,
contractName: "Registry Community",
functionName: "rejectPool",
fallbackErrorMessage: "Error rejecting pool, please report a bug.",
args: [strategy.id as Address],
onConfirmations: () => {
publish({
topic: "pool",
function: "rejectPool",
type: "update",
containerId: communityAddr,
chainId: chainId,
});
const pathSegments = path.split("/");
pathSegments.pop();
if (pathSegments.length === 6) {
pathSegments.pop();
}
const newPath = pathSegments.join("/");
router.push(newPath);
},
});

const { write: addStrategyByPoolId } = useContractWriteWithConfirmations({
address: communityAddr,
abi: registryCommunityABI,
Expand Down Expand Up @@ -338,22 +370,6 @@ export default function PoolHeader({
</h2>
{(!!isCouncilMember || isCouncilSafe) && (
<div className="flex gap-2 flex-wrap">
<div className="flex flex-col gap-1 p-1 w-48">
<a
href={`https://app.safe.global/transactions/queue?safe=${safePrefix}:${strategy.registryCommunity.councilSafe}`}
className="text-info whitespace-nowrap flex flex-nowrap gap-1 items-center"
target="_blank"
rel="noreferrer"
>
Council safe
<ArrowTopRightOnSquareIcon width={16} height={16} />
</a>
<EthAddress
address={strategy.registryCommunity.councilSafe as Address}
shortenAddress={true}
actions="copy"
/>
</div>
<Button
btnStyle="outline"
icon={<Cog6ToothIcon height={24} width={24} />}
Expand All @@ -365,39 +381,110 @@ export default function PoolHeader({
>
Edit
</Button>
{isEnabled ?
{isArchived ?
<Button
icon={<StopIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={tooltipMessage}
onClick={() => removeStrategyByPoolId()}
btnStyle="outline"
color="danger"
>
Disable
</Button>
: <Button
icon={<CheckIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={tooltipMessage}
tooltip={
tooltipMessage ?? "Restore the pool will also enable it."
}
showToolTip={true}
onClick={() => addStrategyByPoolId()}
>
Approve
Restore
</Button>
: isEnabled ?
<>
<Button
icon={<StopIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={
tooltipMessage ??
"Disable pool will pause all interactions with this pool. It is possible to enable it back."
}
showToolTip={true}
onClick={() => removeStrategyByPoolId()}
btnStyle="outline"
color="secondary"
>
Disable
</Button>
<Button
icon={<ArchiveBoxIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={
tooltipMessage ??
"Archive pool will remove it from the list of pools. Need to contact the Gardens team to restore it."
}
showToolTip={true}
onClick={() => rejectPoolWrite()}
btnStyle="outline"
color="danger"
>
Archive
</Button>
</>
: <>
<Button
icon={<CheckIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={tooltipMessage ?? "Approve pool to enable it."}
showToolTip={true}
onClick={() => addStrategyByPoolId()}
>
Approve
</Button>
<Button
icon={<NoSymbolIcon height={24} width={24} />}
disabled={
!isConnected || missmatchUrl || disableCouncilSafeButtons
}
tooltip={
tooltipMessage ??
"Reject pool will remove it from the list. \nNeed to contact the Gardens team to\n restore it."
}
showToolTip={true}
onClick={() => rejectPoolWrite()}
btnStyle="outline"
color="danger"
>
Reject
</Button>
</>
}
</div>
)}
</div>
<div>
<div className="w-full flex flex-col gap-2">
<EthAddress
icon={false}
address={strategy.id as Address}
label="Pool address"
/>
<div className="flex flex-col gap-1 p-1 w-48">
<a
href={`https://app.safe.global/transactions/queue?safe=${safePrefix}:${strategy.registryCommunity.councilSafe}`}
className="text-info whitespace-nowrap flex flex-nowrap gap-1 items-center"
target="_blank"
rel="noreferrer"
>
Council safe
<ArrowTopRightOnSquareIcon width={16} height={16} />
</a>
<EthAddress
address={strategy.registryCommunity.councilSafe as Address}
shortenAddress={true}
actions="copy"
/>
</div>
</div>
<Modal
title={`Edit ${ipfsResult?.title} #${poolId}`}
Expand Down Expand Up @@ -455,7 +542,13 @@ export default function PoolHeader({
className="text-secondary-content"
icon={<ChartBarIcon />}
/>
<Badge label={PointSystems[pointSystem]} icon={<BoltIcon />} />
<Badge
label={PointSystems[pointSystem]}
tooltip={
VOTING_POINT_SYSTEM_DESCRIPTION[PointSystems[pointSystem]]
}
icon={<BoltIcon />}
/>
</div>
</Statistic>
</div>
Expand Down
24 changes: 13 additions & 11 deletions apps/web/components/PoolMetrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,19 @@ export const PoolMetrics: FC<PoolMetricsProps> = ({
className="subtitle2 text-primary-content"
/>
</div>
<div className="flex gap-3">
<p className="subtitle2">Wallet balance:</p>
<Skeleton isLoading={!balance}>
<DisplayNumber
number={[balance?.value ?? BigInt(0), poolToken.decimals]}
tokenSymbol={poolToken.symbol}
compact={true}
className="subtitle2 text-primary-content"
/>
</Skeleton>
</div>
{accountAddress && (
<div className="flex gap-3">
<p className="subtitle2">Wallet balance:</p>
<Skeleton isLoading={!balance}>
<DisplayNumber
number={[balance?.value ?? BigInt(0), poolToken.decimals]}
tokenSymbol={poolToken.symbol}
compact={true}
className="subtitle2 text-primary-content"
/>
</Skeleton>
</div>
)}
</div>
<form
className="flex gap-2 flex-wrap"
Expand Down
9 changes: 8 additions & 1 deletion apps/web/configs/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
export const DEFAULT_RULING_TIMEOUT_SEC = +(
(process.env.NEXT_PUBLIC_DEFAULT_RULING_TIMEOUT ?? 604800) // 7 days
);
);
export const VOTING_POINT_SYSTEM_DESCRIPTION = {
fixed: "Everyone has the same voting weight, limited to registration stake",
capped: "Voting weight is equal to tokens staked, up to a limit",
unlimited: "Voting weight is equal to tokens staked, no limit.",
quadratic:
"Voting weight increases as more tokens are staked, following a quadratic curve.",
} as const;
2 changes: 1 addition & 1 deletion apps/web/styles/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ caption {
}

.page-layout {
@apply flex w-full max-w-6xl flex-col gap-10 p-4 md:p-8 overflow-x-hidden;
@apply flex w-full max-w-6xl flex-col gap-10 p-4 md:p-8 overflow-x-visible;
}

.tooltip {
Expand Down
Loading

0 comments on commit 3aec24d

Please sign in to comment.