diff --git a/packages/nextjs/app/admin/_components/SubmissionCard.tsx b/packages/nextjs/app/admin/_components/SubmissionCard.tsx index e3a66d4..b6305ae 100644 --- a/packages/nextjs/app/admin/_components/SubmissionCard.tsx +++ b/packages/nextjs/app/admin/_components/SubmissionCard.tsx @@ -2,26 +2,23 @@ import { useRouter } from "next/navigation"; import { SubmissionComments } from "./SubmissionComments"; +import { SubmissionEligible } from "./SubmissionEligible"; import "./submission-rating.css"; import { useMutation } from "@tanstack/react-query"; +import clsx from "clsx"; import { useAccount } from "wagmi"; import { Address } from "~~/components/scaffold-eth"; import { Submission } from "~~/services/database/repositories/submissions"; -import { getFormattedDateTime } from "~~/utils/date"; import { postMutationFetcher } from "~~/utils/react-query"; import { notification } from "~~/utils/scaffold-eth"; export const SubmissionCard = ({ submission }: { submission: Submission }) => { const { address: connectedAddress } = useAccount(); - const { mutateAsync: postNewVote } = useMutation({ + const { mutateAsync: postNewVote, isPending: isVotePending } = useMutation({ mutationFn: (newVote: { score: number }) => postMutationFetcher(`/api/submissions/${submission.id}/votes`, { body: newVote }), }); - const { mutateAsync: postNewEligible } = useMutation({ - mutationFn: (newEligible: { eligible: boolean; clear: boolean }) => - postMutationFetcher(`/api/submissions/${submission.id}/eligible`, { body: newEligible }), - }); const { refresh } = useRouter(); const vote = async (newScore: number) => { @@ -44,36 +41,6 @@ export const SubmissionCard = ({ submission }: { submission: Submission }) => { } }; - const setEligible = async (newEligible: boolean) => { - try { - const result = await postNewEligible({ eligible: newEligible, clear: false }); - - notification.success(result.message); - refresh(); - } catch (error: any) { - if (error instanceof Error) { - notification.error(error.message); - return; - } - notification.error("Something went wrong"); - } - }; - - const clearEligible = async () => { - try { - const result = await postNewEligible({ eligible: false, clear: true }); - - notification.success(result.message); - refresh(); - } catch (error: any) { - if (error instanceof Error) { - notification.error(error.message); - return; - } - notification.error("Something went wrong"); - } - }; - const scoreAvg = submission.votes.length > 0 ? (submission.votes.map(vote => vote.score).reduce((a, b) => a + b, 0) / submission.votes.length).toFixed(2) @@ -85,60 +52,10 @@ export const SubmissionCard = ({ submission }: { submission: Submission }) => { return (
-
+ +

{submission.title}

-
- setEligible(false)} - /> - {submission.eligible === false ? ( -
- -
- ) : ( - - )} - setEligible(true)} - /> - {submission.eligible === true ? ( -
- -
- ) : ( - - )} - {submission.eligible !== undefined && ( - - )} -

{submission.description}

- {submission.feedback &&

Extensions feedback: {submission.feedback}

} + {submission.feedback &&

Extensions Feedback: {submission.feedback}

} + +
@@ -186,16 +105,21 @@ export const SubmissionCard = ({ submission }: { submission: Submission }) => { ))}
{score > 0 && ( - +
+ {isVotePending && } + +
)}
-
+
{scoreAvg}
{submission.votes.length} votes
diff --git a/packages/nextjs/app/admin/_components/SubmissionEligible.tsx b/packages/nextjs/app/admin/_components/SubmissionEligible.tsx new file mode 100644 index 0000000..f73871a --- /dev/null +++ b/packages/nextjs/app/admin/_components/SubmissionEligible.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import "./submission-rating.css"; +import { useMutation } from "@tanstack/react-query"; +import clsx from "clsx"; +import { QuestionMarkCircleIcon } from "@heroicons/react/24/outline"; +import { Submission } from "~~/services/database/repositories/submissions"; +import { getFormattedDateTime } from "~~/utils/date"; +import { postMutationFetcher } from "~~/utils/react-query"; +import { notification } from "~~/utils/scaffold-eth"; + +const eligibleLabelStyles = "label cursor-pointer text-sm justify-start gap-2"; + +// Close the dropdown by blurring the active element +const closeDropdown = () => { + const elem = document.activeElement; + if (elem instanceof HTMLElement) { + elem.blur(); + } +}; + +export const SubmissionEligible = ({ submission }: { submission: Submission }) => { + const { mutateAsync: postNewEligible, isPending } = useMutation({ + mutationFn: (newEligible: { eligible: boolean; clear: boolean }) => + postMutationFetcher(`/api/submissions/${submission.id}/eligible`, { body: newEligible }), + }); + const { refresh } = useRouter(); + + const setEligible = async (newEligible: boolean) => { + try { + const result = await postNewEligible({ eligible: newEligible, clear: false }); + + closeDropdown(); + notification.success(result.message); + refresh(); + } catch (error: any) { + if (error instanceof Error) { + notification.error(error.message); + return; + } + notification.error("Something went wrong"); + } + }; + + const clearEligible = async () => { + try { + const result = await postNewEligible({ eligible: false, clear: true }); + + closeDropdown(); + notification.success(result.message); + refresh(); + } catch (error: any) { + if (error instanceof Error) { + notification.error(error.message); + return; + } + notification.error("Something went wrong"); + } + }; + + let buttonLabel = "Eligibility"; + if (submission.eligible === false) { + buttonLabel = "Not Eligible"; + } + if (submission.eligible === true) { + buttonLabel = "Eligible"; + } + + return ( +
+
+ {buttonLabel} +
+
+
+
+ +
+
+ +
+
+ {submission.eligible !== undefined && ( +
+ + {isPending && } +
+ )} + + {submission.eligible === false && ( +
+ +
+ )} + + {submission.eligible === true && ( +
+ +
+ )} +
+
+
+
+ ); +}; diff --git a/packages/nextjs/app/admin/_components/SubmissionTabs.tsx b/packages/nextjs/app/admin/_components/SubmissionTabs.tsx index 10cc007..723a71f 100644 --- a/packages/nextjs/app/admin/_components/SubmissionTabs.tsx +++ b/packages/nextjs/app/admin/_components/SubmissionTabs.tsx @@ -55,6 +55,11 @@ export const SubmissionTabs = ({ submissions }: { submissions: Submission[] }) = return ; }) )} + {notVoted.length === 0 && ( +
+ There are no submissions to vote on. +
+ )}
@@ -67,6 +72,11 @@ export const SubmissionTabs = ({ submissions }: { submissions: Submission[] }) = />
+ {voted.length === 0 && ( +
+ You have not voted on any submissions yet. +
+ )} {voted.map(submission => { return ; })}