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

Migrates project submission to judging #58

Draft
wants to merge 28 commits into
base: rewrite-nova
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
53b4e66
implements getProjects trpc procedure
anudaweerasinghe Mar 26, 2024
9b3ee2a
Adds getUserProject trpc procedure
anudaweerasinghe Mar 26, 2024
86fd897
implements saveProject trpc procedure
anudaweerasinghe Mar 26, 2024
c56328b
implements submit and unsubmit project to a prize routes
anudaweerasinghe Mar 26, 2024
7f4699e
project submission page wip
anudaweerasinghe Mar 26, 2024
5ca7444
fixes prize/project relations in prisma schema
anudaweerasinghe Mar 27, 2024
50d0ab0
fixes project procedures to match correct schema
anudaweerasinghe Mar 27, 2024
7f6ebfd
implements project submission form
anudaweerasinghe Mar 27, 2024
526aaed
implements project submit button
anudaweerasinghe Mar 27, 2024
6bcf677
project submission and update logic complete
anudaweerasinghe Mar 27, 2024
31defaf
adds user email if it doesn't exist
anudaweerasinghe Mar 27, 2024
88905d3
adds user email if it doesn't exist
anudaweerasinghe Mar 27, 2024
7b8c601
refactors project details into separate component
anudaweerasinghe Mar 27, 2024
26703cd
refactors project details into separate component
anudaweerasinghe Mar 27, 2024
7f85920
adds nullish coalescing of otherResources to empty string
anudaweerasinghe Mar 29, 2024
0ea3972
adds trim to each individual email
anudaweerasinghe Mar 29, 2024
83d170d
Add error handling and error codes in projects router
anudaweerasinghe Mar 29, 2024
f42a1aa
uses single prisma query to get user project
anudaweerasinghe Mar 29, 2024
f2e6634
removes console.log in project router
anudaweerasinghe Mar 29, 2024
ef54628
switches from using promise to prisma. on project save
anudaweerasinghe Mar 29, 2024
41188b7
adds check that team members aren't on a different team
anudaweerasinghe Mar 30, 2024
df99eaa
increases project submit form width
anudaweerasinghe Mar 30, 2024
d5dda3d
tabs styling wip
anudaweerasinghe Mar 30, 2024
b7ef5d5
implements tabs
anudaweerasinghe Mar 30, 2024
1e5e18f
adds drop shadow to tabs
anudaweerasinghe Mar 30, 2024
e982b83
adds new tabs to admin page
anudaweerasinghe Mar 30, 2024
d7b5765
implements get user prizes endpoint
anudaweerasinghe Mar 30, 2024
b391748
prize submission cards wip
anudaweerasinghe Mar 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ model Prize {
judgeAssignments JudgePrizeAssignment[]
judgingInstances JudgingInstance[]
judgments ProjectComparisonResult[]
Project Project? @relation(fields: [projectId], references: [id])
projectId String?
}

// Projects are compared against each other by judges
Expand All @@ -97,8 +95,7 @@ model Project {
teamName String
teamMembers User[]

prizes Prize[]
leadingPrizes JudgePrizeAssignment[]
prizes JudgePrizeAssignment[]
incomingJudges Judge[]
judgingInstances JudgingInstance[]
ignores IgnoreProjects[]
Expand Down
149 changes: 149 additions & 0 deletions src/components/projectSubmission/ProjectDetailsForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { useEffect, useState } from "react";
import { api } from "../../utils/api";
import Button from "../Button";
import Spinner from "../Spinner";

interface Props {
email: string;
}

export default function ProjectDetailsForm({ email }: Props) {
const {
isFetching,
data: project,
refetch,
} = api.projects.getUserProject.useQuery();

const [teamName, setTeamName] = useState(project?.teamName);
const [projectName, setProjectName] = useState(project?.name);
const [description, setDescription] = useState(project?.description);
const [githubUrl, setGithubUrl] = useState(project?.githubUrl ?? "");
const [otherResources, setOtherResources] = useState(project?.otherResources);
const [teamMembers, setTeamMembers] = useState(
project?.teamMembers.map((member) => member.email) ?? []
);

useEffect(() => {
if (project) {
setTeamName(project.teamName);
setProjectName(project.name);
setDescription(project.description);
setGithubUrl(project.githubUrl ?? "");
setOtherResources(project.otherResources);
setTeamMembers(project.teamMembers.map((member) => member.email));
} else {
setTeamMembers([email]);
}
}, [project, email]);
const { isLoading, mutate: saveProject } =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to have some failure logic to let the user know some of the inputs are incorrect

api.projects.saveProject.useMutation({
onSuccess: async () => {
await refetch();
},
});

return isFetching || isLoading ? (
<Spinner />
) : (
<>
<div className="flex w-full flex-col gap-2">
<label htmlFor="teamName" className="font-bold">
Team Name*
</label>
<input
type="text"
id="teamName"
placeholder="Enter team name"
value={teamName}
required
onChange={(e) => setTeamName(e.target.value)}
className="border-grey w-full rounded-md border-2 p-2"
/>
</div>

<div className="flex w-full flex-col gap-2">
<label htmlFor="teamMembers" className="font-bold">
Team Member Emails*
</label>
<input
type="text"
id="teamMembers"
placeholder="Enter team member emails (comma separated)"
value={teamMembers.join(",")}
required
onChange={(e) => setTeamMembers(e.target.value.trim().split(","))}
anudaweerasinghe marked this conversation as resolved.
Show resolved Hide resolved
className="border-grey w-full rounded-md border-2 p-2"
/>
</div>

<div className="flex w-full flex-col gap-2">
<label htmlFor="projectName" className="font-bold">
Project Name*
</label>
<input
type="text"
id="projectName"
placeholder="Enter project name"
value={projectName}
required
onChange={(e) => setProjectName(e.target.value)}
className="border-grey w-full rounded-md border-2 p-2"
/>
</div>

<div className="flex w-full flex-col gap-2">
<label htmlFor="githubUrl" className="font-bold">
GitHub Link
</label>
<input
type="text"
id="githubUrl"
placeholder="Enter GitHub link"
value={githubUrl}
onChange={(e) => setGithubUrl(e.target.value)}
className="border-grey w-full rounded-md border-2 p-2"
/>
</div>

<div className="flex w-full flex-col gap-2">
<label htmlFor="description" className="font-bold">
Description*
</label>
<textarea
id="description"
placeholder="Enter project description"
value={description}
onChange={(e) => setDescription(e.target.value)}
className="border-grey w-full rounded-md border-2 p-2"
></textarea>
</div>

<div className="flex w-full flex-col gap-2">
<label htmlFor="otherResources" className="font-bold">
Other Resources
</label>
<textarea
id="otherResources"
placeholder="Links to other resources associated with your project."
value={otherResources as string}
anudaweerasinghe marked this conversation as resolved.
Show resolved Hide resolved
onChange={(e) => setOtherResources(e.target.value)}
className="border-grey w-full rounded-md border-2 p-2"
></textarea>
</div>
<Button
text="Save"
className="m-4 w-full font-bold"
onClick={() => {
saveProject({
name: projectName ?? "",
githubUrl: githubUrl,
teamName: teamName ?? "",
description: description ?? "",
otherResources: otherResources ?? "",
teamMembers: teamMembers,
});
}}
/>
</>
);
}
31 changes: 31 additions & 0 deletions src/pages/submit-project.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { GetServerSidePropsContext, NextPage } from "next";
import Header from "../components/Header";
import { getSession } from "next-auth/react";
import ProjectDetailsForm from "../components/projectSubmission/ProjectDetailsForm";
interface Props {
email: string;
}
const SubmitProject: NextPage<Props> = ({ email }) => {
return (
<div className="flex min-h-screen flex-col">
<Header />
<main className="flex flex-col items-center gap-5 py-5 px-2 md:px-10">
<div className="flex w-96 flex-col items-center justify-center gap-3">
<h2 className="m-2 text-2xl font-bold">Submit your project</h2>
<ProjectDetailsForm email={email} />
</div>
</main>
</div>
);
};
export async function getServerSideProps(context: GetServerSidePropsContext) {
const session = await getSession(context);
const email = session?.user?.email as string;
return {
props: {
email: email,
},
};
}

export default SubmitProject;
2 changes: 2 additions & 0 deletions src/server/api/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { prizesRouter } from "./routers/prizes";
import { settingsRouter } from "./routers/settings";
import { usersRouter } from "./routers/users";
import { authRouter } from "./routers/auth";
import { projectsRouter } from "./routers/projects";

/**
* This is the primary router for your server.
Expand All @@ -16,6 +17,7 @@ export const appRouter = createTRPCRouter({
settings: settingsRouter,
users: usersRouter,
auth: authRouter,
projects: projectsRouter,
});

// export type definition of API
Expand Down
Loading