From 28a5361e9bfe463af7e339189cc689b1abafa5f9 Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 5 Sep 2024 18:25:39 -0300 Subject: [PATCH 1/3] Enable/Disable voting --- .../nextjs/app/admin/_components/SubmissionCard.tsx | 7 +++++++ .../nextjs/app/admin/_components/Submissions.tsx | 13 ++++++++++++- .../api/submissions/[submissionId]/votes/route.ts | 7 +++++++ packages/nextjs/scaffold.config.ts | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/app/admin/_components/SubmissionCard.tsx b/packages/nextjs/app/admin/_components/SubmissionCard.tsx index f154923..2f8eecd 100644 --- a/packages/nextjs/app/admin/_components/SubmissionCard.tsx +++ b/packages/nextjs/app/admin/_components/SubmissionCard.tsx @@ -8,11 +8,13 @@ import { useMutation } from "@tanstack/react-query"; import clsx from "clsx"; import { useAccount } from "wagmi"; import { Address } from "~~/components/scaffold-eth"; +import scaffoldConfig from "~~/scaffold.config"; import { SubmissionWithAvg } from "~~/services/database/repositories/submissions"; import { postMutationFetcher } from "~~/utils/react-query"; import { notification } from "~~/utils/scaffold-eth"; export const SubmissionCard = ({ submission }: { submission: SubmissionWithAvg }) => { + const { votingEnabled } = scaffoldConfig; const { address: connectedAddress } = useAccount(); const { mutateAsync: postNewVote, isPending: isVotePending } = useMutation({ @@ -23,6 +25,11 @@ export const SubmissionCard = ({ submission }: { submission: SubmissionWithAvg } const vote = async (newScore: number) => { try { + if (!votingEnabled) { + notification.error("Voting is disabled"); + return; + } + if (newScore < 0 || newScore > 10) { notification.error("Wrong score"); return; diff --git a/packages/nextjs/app/admin/_components/Submissions.tsx b/packages/nextjs/app/admin/_components/Submissions.tsx index cd63e76..6e887df 100644 --- a/packages/nextjs/app/admin/_components/Submissions.tsx +++ b/packages/nextjs/app/admin/_components/Submissions.tsx @@ -1,7 +1,18 @@ import { SubmissionTabs } from "./SubmissionTabs"; +import scaffoldConfig from "~~/scaffold.config"; import { getAllSubmissions } from "~~/services/database/repositories/submissions"; export const Submissions = async () => { const submissions = await getAllSubmissions(); - return ; + const { votingEnabled } = scaffoldConfig; + return ( + <> + {!votingEnabled && ( +
+
Voting period ended
+
+ )} + + + ); }; diff --git a/packages/nextjs/app/api/submissions/[submissionId]/votes/route.ts b/packages/nextjs/app/api/submissions/[submissionId]/votes/route.ts index 2565ebd..e761dcd 100644 --- a/packages/nextjs/app/api/submissions/[submissionId]/votes/route.ts +++ b/packages/nextjs/app/api/submissions/[submissionId]/votes/route.ts @@ -1,15 +1,22 @@ import { NextRequest, NextResponse } from "next/server"; import { getServerSession } from "next-auth"; +import scaffoldConfig from "~~/scaffold.config"; import { createOrUpdateVote, deleteVote } from "~~/services/database/repositories/votes"; import { authOptions } from "~~/utils/auth"; export async function POST(req: NextRequest, { params }: { params: { submissionId: number } }) { + const { votingEnabled } = scaffoldConfig; try { const session = await getServerSession(authOptions); if (session?.user.role !== "admin") { return NextResponse.json({ error: "Only admins can vote" }, { status: 401 }); } + + if (!votingEnabled) { + return NextResponse.json({ error: "Voting is disabled" }, { status: 400 }); + } + const { submissionId } = params; const { score } = (await req.json()) as { score: string }; diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index b00a22e..ffe76bf 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -6,6 +6,7 @@ export type ScaffoldConfig = { alchemyApiKey: string; walletConnectProjectId: string; onlyLocalBurnerWallet: boolean; + votingEnabled: boolean; }; const scaffoldConfig = { @@ -30,6 +31,9 @@ const scaffoldConfig = { // Only show the Burner Wallet when running on hardhat network onlyLocalBurnerWallet: true, + + // Enable voting on submissions + votingEnabled: false, } as const satisfies ScaffoldConfig; export default scaffoldConfig; From 40da76ebb299916dfe4dd7c18c306426745dd20b Mon Sep 17 00:00:00 2001 From: Damian Date: Thu, 5 Sep 2024 23:48:08 -0300 Subject: [PATCH 2/3] Winners tag --- .../_components/SubmissionCard.tsx | 9 ++++++-- packages/nextjs/app/submissions/page.tsx | 21 ++++++++++++++++--- packages/nextjs/scaffold.config.ts | 6 ++++++ .../database/repositories/submissions.ts | 3 +++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/app/submissions/_components/SubmissionCard.tsx b/packages/nextjs/app/submissions/_components/SubmissionCard.tsx index 44e0f80..efc73f1 100644 --- a/packages/nextjs/app/submissions/_components/SubmissionCard.tsx +++ b/packages/nextjs/app/submissions/_components/SubmissionCard.tsx @@ -1,10 +1,15 @@ import { Address } from "~~/components/scaffold-eth"; -import { Submission } from "~~/services/database/repositories/submissions"; +import { SubmissionWithWinnerTag } from "~~/services/database/repositories/submissions"; -export const SubmissionCard = ({ submission }: { submission: Submission }) => { +export const SubmissionCard = ({ submission }: { submission: SubmissionWithWinnerTag }) => { return (
+ {submission.winnerTag && ( +
+ {submission.winnerTag} +
+ )}

{submission.title}

diff --git a/packages/nextjs/app/submissions/page.tsx b/packages/nextjs/app/submissions/page.tsx index 4b8547d..cbf2f84 100644 --- a/packages/nextjs/app/submissions/page.tsx +++ b/packages/nextjs/app/submissions/page.tsx @@ -1,6 +1,7 @@ import { SubmissionCard } from "./_components/SubmissionCard"; import type { NextPage } from "next"; -import { getAllSubmissions } from "~~/services/database/repositories/submissions"; +import scaffoldConfig from "~~/scaffold.config"; +import { SubmissionWithWinnerTag, getAllSubmissions } from "~~/services/database/repositories/submissions"; import { getMetadata } from "~~/utils/scaffold-eth/getMetadata"; export const metadata = getMetadata({ @@ -10,16 +11,30 @@ export const metadata = getMetadata({ const Submissions: NextPage = async () => { const submissions = await getAllSubmissions(); + const { winnersThreshold, runnersUpThreshold } = scaffoldConfig; + + const submissionsWithAvgScore: SubmissionWithWinnerTag[] = submissions + .map(submission => { + const avgScore = + submission.votes.length > 0 + ? submission.votes.map(vote => vote.score).reduce((a, b) => a + b, 0) / submission.votes.length + : 0; + + const winnerTag = avgScore >= winnersThreshold ? "Winner" : avgScore >= runnersUpThreshold ? "Runner Up" : null; + + return { ...submission, avgScore, winnerTag }; + }) + .sort((a, b) => b.avgScore - a.avgScore); return (
-
+
{submissions.length === 0 && (
No submissions yet.
)} - {submissions.map(submission => { + {submissionsWithAvgScore.map((submission: SubmissionWithWinnerTag) => { return ; })}
diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index ffe76bf..ec8f25b 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -7,6 +7,8 @@ export type ScaffoldConfig = { walletConnectProjectId: string; onlyLocalBurnerWallet: boolean; votingEnabled: boolean; + winnersThreshold: number; + runnersUpThreshold: number; }; const scaffoldConfig = { @@ -34,6 +36,10 @@ const scaffoldConfig = { // Enable voting on submissions votingEnabled: false, + + // Score threshold for winners and runners up + winnersThreshold: 7, + runnersUpThreshold: 6, } as const satisfies ScaffoldConfig; export default scaffoldConfig; diff --git a/packages/nextjs/services/database/repositories/submissions.ts b/packages/nextjs/services/database/repositories/submissions.ts index 145fd27..117fa26 100644 --- a/packages/nextjs/services/database/repositories/submissions.ts +++ b/packages/nextjs/services/database/repositories/submissions.ts @@ -9,6 +9,9 @@ export type Submission = InferSelectModel & { comments: Comm export type SubmissionWithAvg = Submission & { avgScore: number; }; +export type SubmissionWithWinnerTag = Submission & { + winnerTag: string | null; +}; export async function getAllSubmissions() { return await db.query.submissions.findMany({ From 5a28efd2507bc0ea843fcd3b0de5e90c1b6ea8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez?= Date: Fri, 6 Sep 2024 13:00:11 +0200 Subject: [PATCH 3/3] Revert "Winners tag" This reverts commit 40da76ebb299916dfe4dd7c18c306426745dd20b. --- .../_components/SubmissionCard.tsx | 9 ++------ packages/nextjs/app/submissions/page.tsx | 21 +++---------------- packages/nextjs/scaffold.config.ts | 6 ------ .../database/repositories/submissions.ts | 3 --- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/packages/nextjs/app/submissions/_components/SubmissionCard.tsx b/packages/nextjs/app/submissions/_components/SubmissionCard.tsx index efc73f1..44e0f80 100644 --- a/packages/nextjs/app/submissions/_components/SubmissionCard.tsx +++ b/packages/nextjs/app/submissions/_components/SubmissionCard.tsx @@ -1,15 +1,10 @@ import { Address } from "~~/components/scaffold-eth"; -import { SubmissionWithWinnerTag } from "~~/services/database/repositories/submissions"; +import { Submission } from "~~/services/database/repositories/submissions"; -export const SubmissionCard = ({ submission }: { submission: SubmissionWithWinnerTag }) => { +export const SubmissionCard = ({ submission }: { submission: Submission }) => { return (
- {submission.winnerTag && ( -
- {submission.winnerTag} -
- )}

{submission.title}

diff --git a/packages/nextjs/app/submissions/page.tsx b/packages/nextjs/app/submissions/page.tsx index cbf2f84..4b8547d 100644 --- a/packages/nextjs/app/submissions/page.tsx +++ b/packages/nextjs/app/submissions/page.tsx @@ -1,7 +1,6 @@ import { SubmissionCard } from "./_components/SubmissionCard"; import type { NextPage } from "next"; -import scaffoldConfig from "~~/scaffold.config"; -import { SubmissionWithWinnerTag, getAllSubmissions } from "~~/services/database/repositories/submissions"; +import { getAllSubmissions } from "~~/services/database/repositories/submissions"; import { getMetadata } from "~~/utils/scaffold-eth/getMetadata"; export const metadata = getMetadata({ @@ -11,30 +10,16 @@ export const metadata = getMetadata({ const Submissions: NextPage = async () => { const submissions = await getAllSubmissions(); - const { winnersThreshold, runnersUpThreshold } = scaffoldConfig; - - const submissionsWithAvgScore: SubmissionWithWinnerTag[] = submissions - .map(submission => { - const avgScore = - submission.votes.length > 0 - ? submission.votes.map(vote => vote.score).reduce((a, b) => a + b, 0) / submission.votes.length - : 0; - - const winnerTag = avgScore >= winnersThreshold ? "Winner" : avgScore >= runnersUpThreshold ? "Runner Up" : null; - - return { ...submission, avgScore, winnerTag }; - }) - .sort((a, b) => b.avgScore - a.avgScore); return (
-
+
{submissions.length === 0 && (
No submissions yet.
)} - {submissionsWithAvgScore.map((submission: SubmissionWithWinnerTag) => { + {submissions.map(submission => { return ; })}
diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index ec8f25b..ffe76bf 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -7,8 +7,6 @@ export type ScaffoldConfig = { walletConnectProjectId: string; onlyLocalBurnerWallet: boolean; votingEnabled: boolean; - winnersThreshold: number; - runnersUpThreshold: number; }; const scaffoldConfig = { @@ -36,10 +34,6 @@ const scaffoldConfig = { // Enable voting on submissions votingEnabled: false, - - // Score threshold for winners and runners up - winnersThreshold: 7, - runnersUpThreshold: 6, } as const satisfies ScaffoldConfig; export default scaffoldConfig; diff --git a/packages/nextjs/services/database/repositories/submissions.ts b/packages/nextjs/services/database/repositories/submissions.ts index 117fa26..145fd27 100644 --- a/packages/nextjs/services/database/repositories/submissions.ts +++ b/packages/nextjs/services/database/repositories/submissions.ts @@ -9,9 +9,6 @@ export type Submission = InferSelectModel & { comments: Comm export type SubmissionWithAvg = Submission & { avgScore: number; }; -export type SubmissionWithWinnerTag = Submission & { - winnerTag: string | null; -}; export async function getAllSubmissions() { return await db.query.submissions.findMany({