Skip to content

Commit

Permalink
add GymId field to contest
Browse files Browse the repository at this point in the history
  • Loading branch information
Mekdeskebede authored and Endalebob committed Jun 26, 2023
1 parent 1f754b5 commit e3ccc7a
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 272 deletions.
183 changes: 102 additions & 81 deletions src/components/contest/ContestList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import {
import { useRouter } from "next/router";
import { getCookie } from "<@>/utils/cookie";
import Error from "<@>/components/common/Error";
import OverViewContests from "<@>/components/contest/OverViewContests";

const ContestList: React.FC = () => {
const { data: contests = [], error, isLoading } = useGetContestsQuery({});
const [deleteContest, response] = useDeleteContestMutation();
const router = useRouter();
const role = getCookie("role");
console.log(role);
const handleDelete = async (id: any) => {
try {
await deleteContest(id);
Expand All @@ -24,16 +24,21 @@ const ContestList: React.FC = () => {
if (isLoading) {
return (
<div className="rounded-md p-4 w-full mx-auto m-12">
<div className="animate-pulse flex flex-row flex-wrap">
<div className="h-20 bg-slate-200 mt-8 w-64 rounded-xl ml-4 sm:ml-6"></div>
<div className="h-20 bg-slate-200 rounded-xl mt-8 w-64 ml-4 sm:ml-6"></div>
<div className="h-20 bg-slate-200 rounded mt-8 w-64 ml-4 sm:ml-6"></div>
</div>
<div className="animate-pulse flex space-x-4 space-y-8">
<div className="flex-1 space-y-6 py-1">
<div className="space-y-3">
<div className="pl-12 pr-12">
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="h-8 bg-slate-100 rounded mt-8"></div>
<div className="pl-8 pr-8">
<div className="h-8 bg-slate-200 rounded mt-8"></div>
<div className="h-8 bg-slate-200 rounded mt-8"></div>
<div className="h-8 bg-slate-200 rounded mt-8"></div>
<div className="h-8 bg-slate-200 rounded mt-8"></div>
<div className="h-8 bg-slate-200 rounded mt-8"></div>
<div className="h-8 bg-slate-200 rounded mt-8"></div>
</div>
</div>
</div>
Expand All @@ -49,98 +54,114 @@ const ContestList: React.FC = () => {
</div>
);
}

console.log(contests.value);
console.log("the length is", contests.value.length);
const contestData = contests.value;
return (
<div>
<div className="relative overflow-x-auto shadow-md sm:rounded-lg p-12">
<div className="mt-8 sm:ml-2">
<h1 className="text-secondary-text font-semibold ml-6 text-lg">
OverView
</h1>
<OverViewContests />
</div>
<div className="relative overflow-x-auto shadow-md sm:rounded-lg pl-4 pr-8">
{role === "HeadOfEducation" && (
<div className="first:flex items-center justify-end pb-4">
<button
className="px-4 py-1 bg-primary text-white rounded-md hover:bg-blue-300"
onClick={() => router.push("/contests/create-contest")}
>
<span className="font-bold">+</span> New Contest
</button>
<div className="grid grid-cols-2 mt-8">
<div>
<h1 className="text-secondary-text font-semibold ml-2 text-lg col-span-1">
Contests
</h1>
</div>
<div className="pb-4 col-span-1 justify-self-end">
<button
className="px-4 py-1 bg-primary text-white rounded-md justify-self-end"
onClick={() => router.push("/contests/create-contest")}
>
<span className="font-bold">+</span> New Contest
</button>
</div>
</div>
)}
{contestData.length === 0 ? (
<div className="max-auto text-center font-bold">
<div className="max-auto text-center font-bold mb-4">
No contests added yet. Check back soon for updates!
</div>
) : (
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="px-6 py-4">
Title
</th>
<th scope="col" className="px-6 py-4">
Date
</th>
<th scope="col" className="px-6 py-4">
Time
</th>
<th scope="col" className="px-6 py-4">
Codeforces
</th>
{role === "HeadOfEducation" && (
<div>
{role !== "HeadOfEducation" && (
<h1 className="text-secondary-text font-semibold mt-8 mb-4 text-lg">
Contests
</h1>
)}
<table className="w-full text-sm text-left text-gray-500">
<thead className="text-xs text-gray-700 bg-gray-50">
<tr>
<th scope="col" className="px-6 py-4">
Actions
Title
</th>
<th scope="col" className="px-6 py-4">
Date
</th>
<th scope="col" className="px-6 py-4">
Time
</th>
<th scope="col" className="px-6 py-4">
Codeforces
</th>
)}
</tr>
</thead>
<tbody>
{contestData.map((contest: any, index: any) => (
<tr
key={index}
className={`border-b dark:bg-gray-900 dark:border-gray-700 py-8 ${
index % 2 ? "bg-gray-50" : "bg-white"
}`}
>
<td
scope="row"
className="px-6 py-5 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
{contest.title}
</td>
<td className="px-6 py-4 font-medium text-gray-900">
{contest.date.split("T")[0]}
</td>
<td className="px-6 py-4 font-medium text-gray-900">
{contest.date.split("T")[1]}
</td>
<td className="px-6 py-4 font-medium text-primary underline">
<a href={contest.link}>Link</a>
</td>
{role === "HeadOfEducation" && (
<td className="flex flex-row py-4">
<div>
<a
href={`/contests/${contest.id}`}
className="font-medium text-primary dark:text-primary hover:underline px-4"
>
Edit
</a>
</div>
<th scope="col" className="px-6 py-4">
Actions
</th>
)}
</tr>
</thead>
<tbody>
{contestData.map((contest: any, index: any) => (
<tr
key={index}
className={`border-b ${
index % 2 ? "bg-gray-50" : "bg-white"
}`}
>
<td
scope="row"
className="px-6 py-5 font-medium text-gray-900 whitespace-nowrap"
>
{contest.title}
</td>
<td className="px-6 py-4 font-medium text-gray-900">
{contest.date.split("T")[0]}
</td>
<td className="px-6 py-4 font-medium text-gray-900">
{contest.date.split("T")[1]}
</td>
<td className="px-6 py-4 font-medium text-primary underline">
<a href={contest.link}>Link</a>
</td>
{role === "HeadOfEducation" && (
<td className="flex flex-row py-4 font-medium my-auto flex-wrap">
<div></div>
<div className="mx-auto my-auto mt-4 md:mt-0 text-center">
<a
href={`/contests/${contest.id}`}
className="text-primary hover:underline"
>
Edit
</a>
</div>

<div>
<button
onClick={() => handleDelete(contest.id)}
className="font-medium text-red-600 dark:text-red-500 hover:underline px-4"
className="text-red-600 hover:underline px-4"
>
Remove
</button>
</div>
</td>
)}
</tr>
))}
</tbody>
</table>
</td>
)}
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
Expand Down
34 changes: 29 additions & 5 deletions src/components/contest/CreateContest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useRouter } from "next/router";
import ProgressIndicator from "../common/ProgressIndicator";

const initialState = {
GymId: "",
title: "",
description: "",
date: "",
Expand Down Expand Up @@ -41,7 +42,7 @@ const ContestForm: React.FC = () => {
const handleSubmit = async (e: any) => {
e.preventDefault();

const { title, description, date, time, link } = contest;
const { GymId, title, description, date, time, link } = contest;

if (!title) {
setErrors((prevErrors) => ({
Expand All @@ -51,6 +52,14 @@ const ContestForm: React.FC = () => {
return;
}

if (!GymId) {
setErrors((prevErrors) => ({
...prevErrors,
GymId: "Gym Id is required",
}));
return;
}

if (!description) {
setErrors((prevErrors) => ({
...prevErrors,
Expand Down Expand Up @@ -85,17 +94,17 @@ const ContestForm: React.FC = () => {
const dateTime = `${date}T${time}:00Z`;
try {
await createContest({
GymId,
title,
description,
date: dateTime,
link,
}).unwrap();
// Contest creation successful, reset form fields
setContest(initialState);
setErrors(initialState);
} catch (error) {
router.push("/contests");
} catch (error: any) {
// Handle contest creation error
setBackendError("An error occurred while creating the contest");
setBackendError(`An error occurred : ${error.data.title}`);
}
};

Expand All @@ -121,6 +130,21 @@ const ContestForm: React.FC = () => {
/>
{errors.title && <p className="text-red-500">{errors.title}</p>}
</div>
<div className="mb-8">
<label htmlFor="GymId" className="block mb-2 font-semibold">
GymId
</label>
<input
type="number"
id="GymId"
name="GymId"
value={contest.GymId}
onChange={handleChange}
placeholder="0"
className="w-full p-2 border rounded h-8 focus:outline-none"
/>
{errors.GymId && <p className="text-red-500">{errors.GymId}</p>}
</div>
<div className="mb-8">
<label htmlFor="description" className="block mb-2 font-semibold">
Description
Expand Down
29 changes: 26 additions & 3 deletions src/components/contest/UpdateContest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ProgressIndicator from "../common/ProgressIndicator";

const initialState = {
id: "",
GymId: "",
title: "",
description: "",
date: "",
Expand All @@ -32,9 +33,9 @@ const EditContestForm: React.FC = () => {
useEffect(() => {
if (response.value) {
const curr = response.value;
console.log(curr.date.split("T")[1].slice(0, 5));
const currContest = {
id: id as string,
GymId: curr.GymId,
title: curr.title,
description: curr.description,
date: curr.date.split("T")[0],
Expand Down Expand Up @@ -63,10 +64,11 @@ const EditContestForm: React.FC = () => {
e.preventDefault();

// Validate form fields
const { id, title, description, time, date, link } = contest;
const { id, GymId, title, description, time, date, link } = contest;
const dateTime = `${date}T${time}:00Z`;
const updatedContest: Partial<Contest> = {
id,
GymId,
title,
description,
date: dateTime,
Expand All @@ -80,7 +82,13 @@ const EditContestForm: React.FC = () => {
}));
return;
}

if (!GymId) {
setErrors((prevErrors) => ({
...prevErrors,
GymId: "Gym Id is required",
}));
return;
}
if (!description) {
setErrors((prevErrors) => ({
...prevErrors,
Expand Down Expand Up @@ -164,6 +172,21 @@ const EditContestForm: React.FC = () => {
/>
{errors.title && <p className="text-red-500">{errors.title}</p>}
</div>
<div className="mb-8">
<label htmlFor="GymId" className="block mb-2 font-semibold">
GymId
</label>
<input
type="number"
id="GymId"
name="GymId"
value={contest.GymId || ""}
onChange={handleChange}
placeholder="0"
className="w-full p-2 border rounded h-8 focus:outline-none"
/>
{errors.GymId && <p className="text-red-500">{errors.GymId}</p>}
</div>
<div className="mb-8">
<label htmlFor="description" className="block mb-2 font-semibold">
Description
Expand Down
8 changes: 0 additions & 8 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +0,0 @@
import ContestList from "<@>/pages/contests";
import React from "react";

const Contests: React.FC = () => {
return <ContestList />;
};

export default Contests;
Loading

1 comment on commit e3ccc7a

@vercel
Copy link

@vercel vercel bot commented on e3ccc7a Jun 26, 2023

Choose a reason for hiding this comment

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

Deployment failed with the following error:

Resource is limited - try again in 10 hours (more than 100, code: "api-deployments-free-per-day").

Please sign in to comment.