Skip to content

Commit

Permalink
Add "voter" role to /admin (#87)
Browse files Browse the repository at this point in the history
Co-authored-by: Damian <[email protected]>
  • Loading branch information
Pabl0cks and damianmarti authored Sep 19, 2024
1 parent 14007e1 commit 3943b3f
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 35 deletions.
16 changes: 12 additions & 4 deletions packages/nextjs/app/admin/_components/SubmissionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const SubmissionCard = ({ submission, tabName }: { submission: Submission

const telegramUser = submission.telegram?.replace("@", "");

const showResults = tabName === "all";

return (
<div key={submission.id} className="card bg-base-200 text-secondary-content border border-gray-300 rounded-none">
<SubmissionEligible submission={submission} />
Expand Down Expand Up @@ -124,10 +126,16 @@ export const SubmissionCard = ({ submission, tabName }: { submission: Submission
</div>

<div className="mt-3 flex items-center justify-between">
<div className="badge badge-accent flex flex-col shrink-0 p-8 border border-accent-content">
<div className="text-2xl font-bold">{scoreAvg}</div>
<div>{submission.votes.length} votes</div>
</div>
{showResults ? (
<div className="badge badge-accent flex flex-col shrink-0 p-8 border border-accent-content">
<div className="text-2xl font-bold">{scoreAvg}</div>
<div>{submission.votes.length} votes</div>
</div>
) : (
<div className="badge badge-accent flex flex-col shrink-0 p-8 border border-accent-content">
<div>{submission.votes.length} votes</div>
</div>
)}
<SubmissionComments submission={submission} />
</div>
</div>
Expand Down
64 changes: 38 additions & 26 deletions packages/nextjs/app/admin/_components/SubmissionTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"use client";

import { SubmissionCard } from "./SubmissionCard";
import { useSession } from "next-auth/react";
import { useAccount } from "wagmi";
import { Submission, SubmissionWithAvg } from "~~/services/database/repositories/submissions";

const skeletonClasses = "animate-pulse bg-gray-200 rounded-none w-full h-96";

export const SubmissionTabs = ({ submissions }: { submissions: Submission[] }) => {
const { data: session } = useSession();
const isAdmin = session?.user?.role === "admin";

const { address: connectedAddress } = useAccount();

const { voted, notVoted, all } = submissions.reduce(
Expand Down Expand Up @@ -61,15 +65,14 @@ export const SubmissionTabs = ({ submissions }: { submissions: Submission[] }) =
<div className={skeletonClasses}></div>
<div className={skeletonClasses}></div>
</>
) : (
notVoted.map(submission => {
return <SubmissionCard key={submission.id} submission={submission} tabName="notVoted" />;
})
)}
{notVoted.length === 0 && (
) : notVoted.length === 0 ? (
<div role="alert" className="alert col-span-2">
<span>There are no submissions to vote on.</span>
</div>
) : (
notVoted.map(submission => (
<SubmissionCard key={submission.id} submission={submission} tabName="notVoted" />
))
)}
</div>
</div>
Expand All @@ -84,34 +87,43 @@ export const SubmissionTabs = ({ submissions }: { submissions: Submission[] }) =
/>
<div role="tabpanel" className="tab-content py-6">
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
{voted.length === 0 && (
{voted.length === 0 ? (
<div role="alert" className="alert col-span-2">
<span>You have not voted on any submissions yet.</span>
</div>
)}
{voted
.sort((a, b) => b.avgScore - a.avgScore)
.map(submission => {
return <SubmissionCard key={submission.id} submission={submission} tabName="voted" />;
})}
</div>
</div>

{/* All Submissions Tab */}
<input type="radio" name="submission_tabs" role="tab" className="tab whitespace-nowrap" aria-label={allLabel} />
<div role="tabpanel" className="tab-content py-6">
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
{all.length === 0 ? (
<div role="alert" className="alert col-span-2">
<span>There are no submissions yet.</span>
</div>
) : (
all
voted
.sort((a, b) => b.avgScore - a.avgScore)
.map(submission => <SubmissionCard key={submission.id} submission={submission} tabName="all" />)
.map(submission => <SubmissionCard key={submission.id} submission={submission} tabName="voted" />)
)}
</div>
</div>

{/* All Submissions Tab (only for admins) */}
{isAdmin && (
<>
<input
type="radio"
name="submission_tabs"
role="tab"
className="tab whitespace-nowrap"
aria-label={allLabel}
/>
<div role="tabpanel" className="tab-content py-6">
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
{all.length === 0 ? (
<div role="alert" className="alert col-span-2">
<span>There are no submissions yet.</span>
</div>
) : (
all
.sort((a, b) => b.avgScore - a.avgScore)
.map(submission => <SubmissionCard key={submission.id} submission={submission} tabName="all" />)
)}
</div>
</div>
</>
)}
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Admin: NextPage = async () => {
);
}

if (session?.user?.role !== "admin") {
if (!session?.user?.voter) {
return <div className="flex items-center text-xl flex-col flex-grow pt-10 space-y-4">Access denied</div>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function POST(req: NextRequest, { params }: { params: { submissionI
try {
const session = await getServerSession(authOptions);

if (session?.user.role !== "admin") {
if (!session?.user.voter) {
return NextResponse.json({ error: "Only admins can add comments" }, { status: 401 });
}
const { submissionId } = params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function POST(req: NextRequest, { params }: { params: { submissionI
try {
const session = await getServerSession(authOptions);

if (session?.user.role !== "admin") {
if (!session?.user.voter) {
return NextResponse.json({ error: "Only admins can set eligible" }, { status: 401 });
}
const { submissionId } = params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export async function POST(req: NextRequest, { params }: { params: { submissionI
try {
const session = await getServerSession(authOptions);

if (session?.user.role !== "admin") {
return NextResponse.json({ error: "Only admins can vote" }, { status: 401 });
if (!session?.user.voter) {
return NextResponse.json({ error: "Only admins and voters can vote" }, { status: 401 });
}

if (!votingEnabled) {
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/services/database/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ async function seed() {
.values([
{ id: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", role: "admin" },
{ id: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", role: "user" },
{ id: "0x08fc7400ba37fc4ee1bf73bed5ddcb5db6a1036a", role: "voter" },
])
.execute();

Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/types/next-auth/next-auth.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare module "next-auth" {
user: {
address?: string | null;
role?: string | null;
voter?: boolean;
};
expires: ISODateString;
}
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const authOptions: AuthOptions = {
async session({ session, token }: { session: Session; token: JWT }) {
session.user.address = token.sub;
session.user.role = token.role;
session.user.voter = token.role ? ["admin", "voter"].includes(token.role) : false;
return session;
},
},
Expand Down

0 comments on commit 3943b3f

Please sign in to comment.