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

Implement payout justification publishing #342

Merged
merged 14 commits into from
Feb 16, 2025
Prev Previous commit
Next Next commit
Indicate pending publishing
carina-akaia committed Feb 16, 2025
commit 652904e059b995c86437d79951553d1de604f59a
6 changes: 4 additions & 2 deletions src/common/ui/components/atoms/alert.tsx
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@ const alertVariants = cva(
cn(
"flex flex-col relative w-full rounded-lg border p-4 gap-2",
"[&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
"[&>svg]:text-foreground",
"[&>.spinner~*]:pl-7 [&>.spinner+div]:translate-y-[-3px] [&>.spinner]:absolute",
"[&>.spinner]:left-4 [&>.spinner]:top-4",
"[&>svg]:text-foreground [&>.spinner]:text-foreground",
),

{
@@ -20,7 +22,7 @@ const alertVariants = cva(

destructive: cn(
"border-destructive/50 text-destructive dark:border-destructive",
"[&>svg]:text-destructive",
"[&>svg]:text-destructive [&>.spinner]:text-destructive",
),
},
},
4 changes: 1 addition & 3 deletions src/common/ui/components/atoms/spinner.tsx
Original file line number Diff line number Diff line change
@@ -17,10 +17,8 @@ export type SpinnerProps = {
export const Spinner: React.FC<SpinnerProps> = ({ width = 18, height = 18, className }) => {
return (
<span
className={cn("loader border-[2px]", className)}
className={cn("spinner border-[2px]", className)}
style={className ? undefined : { width: `${width}px`, height: `${height}px` }}
/>
);
};

export default Spinner;
2 changes: 1 addition & 1 deletion src/common/ui/components/atoms/splash-screen.tsx
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ export const SplashScreen: React.FC<SplashScreenProps> = ({ className }) => (
<div
className={cn("min-h-105 flex h-full w-full flex-col items-center justify-center", className)}
>
<span className="loader"></span>
<span className="spinner"></span>

<div className={cn("hover:decoration-none decoration-none mt-6 flex items-baseline gap-2")}>
<img src="/favicon.png" alt="logo" width={28.72} height={23.94} />
4 changes: 2 additions & 2 deletions src/common/ui/styles/theme.css
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ body {
}
}

.loader {
.spinner {
width: 32px;
height: 32px;
border: 4px solid #2e2e2e;
@@ -119,7 +119,7 @@ body {
animation: rotation 0.7s linear infinite;
}

.dark .loader {
.dark .spinner {
border-color: #fff;
border-bottom-color: transparent;
}
39 changes: 24 additions & 15 deletions src/features/proportional-funding/components/actions.tsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import { useCallback } from "react";
import Link from "next/link";
import { MdOutlineWarningAmber } from "react-icons/md";

import { Alert, AlertDescription, AlertTitle, Button } from "@/common/ui/components";
import { Alert, AlertDescription, AlertTitle, Button, Spinner } from "@/common/ui/components";
import { useToast } from "@/common/ui/hooks";

import {
@@ -43,22 +43,31 @@ export const PFPayoutJustificationPublicationAction: React.FC<

return typeof pfJustification.publish === "function" ? (
<Alert variant="warning">
<MdOutlineWarningAmber className="h-6 w-6" />
<AlertTitle>{"Action Required"}</AlertTitle>
{pfJustification.isPublishing ? (
<Spinner className="h-6 w-6" />
) : (
<MdOutlineWarningAmber className="h-6 w-6" />
)}

<AlertDescription className="flex items-center gap-2 text-lg">
{typeof href === "string" ? (
<Button asChild>
<Link href={href}>{"Publish Payout Justification"}</Link>
</Button>
) : (
<Button onClick={pfJustification.publish}>{"Publish Payout Justification"}</Button>
)}
<AlertTitle>{pfJustification.isPublishing ? "Publishing..." : "Action Required"}</AlertTitle>

<span className="prose font-500">
{"in order to prove legitimacy of the pool distribution."}
</span>
</AlertDescription>
{!pfJustification.isPublishing && (
<AlertDescription className="flex items-center gap-2 text-lg">
{typeof href === "string" ? (
<Button asChild>
<Link href={href}>{"Publish Payout Justification"}</Link>
</Button>
) : (
<Button disabled={pfJustification.isPublishing} onClick={pfJustification.publish}>
{"Publish Payout Justification"}
</Button>
)}

<span className="prose font-500">
{"in order to prove legitimacy of the pool distribution."}
</span>
</AlertDescription>
)}
</Alert>
) : null;
};
15 changes: 11 additions & 4 deletions src/features/proportional-funding/hooks/payout-justification.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useMemo } from "react";
import { useCallback, useMemo, useState } from "react";

import { isNonNullish } from "remeda";
import useSWR from "swr";
@@ -26,13 +26,15 @@ export const usePFPayoutJustification = ({
const viewer = useWalletUserSession();
const viewerPower = usePotAuthorization({ potId, accountId: viewer.accountId });
const votingRound = useVotingRoundResults({ potId });
const [isPublishing, setIsPublishing] = useState(false);

const {
isLoading: isPayoutChallengeListLoading,
data: potPayoutChallengeList,
mutate: refetchPayoutChallenges,
} = potContractHooks.usePayoutChallenges({ potId });
} = potContractHooks.usePayoutChallenges({ enabled: viewer.isSignedIn, potId });

// TODO: Explicitly consider valid only if submitted by admin or greater
const documentUrl = useMemo(
() => potPayoutChallengeList?.map(pfPayoutChallengeToJustificationUrl).find(isNonNullish),
[potPayoutChallengeList],
@@ -46,13 +48,15 @@ export const usePFPayoutJustification = ({
? undefined
: fetch(urlQueryKey)
.then((res) => res.json())
.then((data: PFPayoutJustificationV1) => data),
.then((data) => data as PFPayoutJustificationV1),
);

const isLoading = votingRound.isLoading || isPayoutChallengeListLoading || isDocumentLoading;

const publish = useCallback(() => {
if (viewer.isSignedIn && votingRound.data !== undefined) {
setIsPublishing(true);

publishPayoutJustification({
potId,
votingRoundResult: votingRound.data,
@@ -65,7 +69,8 @@ export const usePFPayoutJustification = ({
.catch((error) => {
console.error(error);
onPublishError?.(error.message);
});
})
.finally(() => setIsPublishing(false));
}
}, [
onPublishError,
@@ -80,11 +85,13 @@ export const usePFPayoutJustification = ({
return !viewer.isSignedIn || (!votingRound.isLoading && votingRound.data === undefined)
? {
isLoading: false as const,
isPublishing: false,
data: undefined,
publish: undefined,
}
: {
isLoading,
isPublishing,
data: document,

publish:

Unchanged files with check annotations Beta

import { useCallback } from "react";
import { useRouter } from "next/navigation";

Check failure on line 3 in src/entities/list/components/ListHero.tsx

GitHub Actions / build (20.x)

_tests/homepage.tests.tsx

Error: [vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock ❯ src/entities/list/components/ListHero.tsx:3:31 Caused by: ReferenceError: Cannot access '__vi_import_2__' before initialization ❯ _tests/homepage.tests.tsx:2:50 ❯ src/entities/list/components/ListHero.tsx:3:31

Check failure on line 3 in src/entities/list/components/ListHero.tsx

GitHub Actions / build (20.x)

_tests/homepage.tests.tsx

Error: [vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock ❯ src/entities/list/components/ListHero.tsx:3:31 Caused by: ReferenceError: Cannot access '__vi_import_2__' before initialization ❯ _tests/homepage.tests.tsx:2:50 ❯ src/entities/list/components/ListHero.tsx:3:31
import { walletApi } from "@/common/blockchains/near-protocol/client";
import { Button } from "@/common/ui/components";