Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from Programming-Club-Ahmedabad-University/all…
Browse files Browse the repository at this point in the history
…/leaderboards-carousel

uploading all changes ...
  • Loading branch information
JeelRajodiya authored Oct 18, 2023
2 parents 3204889 + 8e1e3cf commit 533c973
Show file tree
Hide file tree
Showing 14 changed files with 363 additions and 109 deletions.
4 changes: 4 additions & 0 deletions client/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tabWidth": 2,
"useTabs": true
}
21 changes: 21 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@chakra-ui/icons": "^2.1.1",
"@chakra-ui/next-js": "^2.1.5",
"@chakra-ui/react": "^2.8.1",
"@emotion/react": "^11.11.1",
Expand Down
22 changes: 22 additions & 0 deletions client/pages/Admin/LeaderboardConfig.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,25 @@
overflow-y: auto;
padding: 0 1em;
}

.listItem{
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 2em;
align-items: center;
padding: 0.5em 1em;
border-radius: 0.5em;
background-color: rgb(45, 44, 44);
margin-bottom:1em ;
}

.deleteBtn{
display: flex;
justify-content: center;
align-items: center;
padding: 0.8em !important;
height: 1.2em !important;
font-size: 1.5em;
cursor: pointer;
}
186 changes: 105 additions & 81 deletions client/pages/Admin/LeaderboardConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,104 +1,128 @@
import { fetcher, myToast } from "@/util/functions";
import { DeleteIcon } from "@chakra-ui/icons";
import RootLayout from "../Layout";
import styles from "./LeaderboardConfig.module.css";
import useSWR from "swr";

function useContests() {
const { data, error, isLoading, mutate } = useSWR(
`/api/admin/contestConfig`,
fetcher
);
const { data, error, isLoading, mutate } = useSWR(
`/api/admin/contestConfig`,
fetcher
);

return {
contests: data,
isLoading,
isError: error,
mutate,
};
return {
contests: data,
isLoading,
isError: error,
mutate,
};
}

function verfiyContest(contest: string) {
return contest.length > 0;
}

async function postContest(
contest: string,
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>,
setIsError: React.Dispatch<React.SetStateAction<boolean>>,
mutate: () => void
contest: string,
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>,
setIsError: React.Dispatch<React.SetStateAction<boolean>>,
mutate: () => void
) {
setIsLoading(true);
const res = await fetch(`/api/admin/contestConfig`, {
method: "POST",
body: JSON.stringify({ contest }),
headers: {
"Content-Type": "application/json",
},
});
setIsLoading(false);
mutate();
if (!res.ok) {
setIsError(true);
}
setIsLoading(true);

if (!verfiyContest(contest)) {
setIsLoading(false);
setIsError(true);
return;
}

const res = await fetch(`/api/admin/contestConfig`, {
method: "POST",
body: JSON.stringify({ contest }),
headers: {
"Content-Type": "application/json",
},
});

setIsLoading(false);
mutate();
if (!res.ok) {
setIsError(true);
}
}

import toast, { Toaster } from "react-hot-toast";
import { Box, Button, Input } from "@chakra-ui/react";
import { Box, Button, IconButton, Input } from "@chakra-ui/react";
import React from "react";

function listComp({ contest }: { contest: string }) {
return (
<div className={styles.listItem}>
<div>{contest}</div>
<IconButton
className={styles.deleteBtn}
variant="outline"
colorScheme="red"
aria-label="Delete Contest"
icon={<DeleteIcon />}
// onClick={}
/>
</div>
);
}

export default function LeaderboardConfig() {
const { contests, isLoading, isError, mutate } = useContests();
const [contest, setContest] = React.useState("");
const [isLoadingPost, setIsLoadingPost] = React.useState(false);
const [isErrorPost, setIsErrorPost] = React.useState(false);
const { contests, isLoading, isError, mutate } = useContests();
const [contest, setContest] = React.useState("");
const [isLoadingPost, setIsLoadingPost] = React.useState(false);
const [isErrorPost, setIsErrorPost] = React.useState(false);

let listOfContests;
let listOfContests;

if (isLoading) {
listOfContests = <div>Loading...</div>;
} else if (isError) {
listOfContests = <div>Error...</div>;
} else {
console.log(contests);
listOfContests = contests.contests.map((contest: string) => {
return <div key={contest}>{contest}</div>;
});
}
if (isLoading) {
listOfContests = <div>Loading...</div>;
} else if (isError) {
listOfContests = <div>Error...</div>;
} else {
console.log(contests);
listOfContests = contests.contests.map((contest: string) => {
return listComp({ contest });
});
}

return (
<RootLayout>
<main className={styles.main}>
<h1>Contests on Leaderboard</h1>
<div className={styles.addWrapper}>
<Input
placeholder="Enter contest number"
className={styles.addInput}
value={contest}
onChange={(e: any) => setContest(e.target.value)}
/>
return (
<RootLayout>
<main className={styles.main}>
<h1>Contests on Leaderboard</h1>
<div className={styles.addWrapper}>
<Input
placeholder="Enter contest number"
className={styles.addInput}
value={contest}
onChange={(e: any) => setContest(e.target.value)}
/>

<Button
variant={"primary"}
className={styles.addBtn}
onClick={() => {
postContest(
contest,
setIsLoadingPost,
setIsErrorPost,
mutate
);
if (isErrorPost) {
myToast("Error", "error");
} else if (isLoadingPost) {
myToast("Loading...");
} else {
myToast("Contest added", "success");
}
}}
>
+
</Button>
</div>
<Button
variant={"primary"}
className={styles.addBtn}
onClick={() => {
postContest(contest, setIsLoadingPost, setIsErrorPost, mutate);
if (isErrorPost) {
myToast("Error", "error");
} else if (isLoadingPost) {
myToast("Loading...");
} else {
myToast("Contest added", "success");
}
}}
>
+
</Button>
</div>

<Toaster position="bottom-right" reverseOrder={false} />
<div className={styles.listConent}>{listOfContests}</div>
</main>
</RootLayout>
);
<Toaster position="bottom-right" reverseOrder={false} />
<div className={styles.listConent}>{listOfContests}</div>
</main>
</RootLayout>
);
}
37 changes: 22 additions & 15 deletions client/pages/api/admin/contestConfig.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
import type { NextApiRequest, NextApiResponse } from "next";
import redisClient from "@/util/redis";
type ResponseData = {
message: string;
message: string;
};

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === "GET") {
return GET(req, res);
} else if (req.method === "POST") {
return POST(req, res);
} else {
return res.status(400).send(`Method ${req.method} is not supported!`);
}
if (req.method === "GET") {
return GET(req, res);
} else if (req.method === "POST") {
return POST(req, res);
} else {
return res.status(400).send(`Method ${req.method} is not supported!`);
}
}

async function GET(req: NextApiRequest, res: NextApiResponse) {
const contests = await redisClient.lRange("Contests", 0, -1);
const contests = await redisClient.lRange("Contests", 0, -1);

return res.json({ contests });
return res.json({ contests });
}

async function POST(req: NextApiRequest, res: NextApiResponse) {
const { contest } = req.body;
await redisClient.lPush("Contests", contest);
const { contest } = req.body;
await redisClient.lPush("Contests", contest);

return res.send("success");
return res.send("success");
}

async function DELETE(req: NextApiRequest, res: NextApiResponse) {
const { contest } = req.body;
await redisClient.lRem("Contests", 0, contest);

return res.send("success");
}
1 change: 0 additions & 1 deletion client/pages/components/NavBar/Navbar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5em;
}
Expand Down
31 changes: 30 additions & 1 deletion client/pages/components/ScoreBoard/ScoreBoard.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
.title {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 1rem;
text-align: center;
}

/*TODO grid with 5 cols:
- first col === 2 cols
- 2nd col === 1 col
-3rd col === 2 cols*/

.tableHeader {
display: grid;
grid-template-columns: 2fr 1fr 2fr 2fr;
width: 100%;
padding: 0 1.5rem;
gap: 2.5rem;
width: 100%;
text-align: center;
}

.tableEntry {
display: grid;
grid-template-columns: 2fr 1fr 2fr 2fr;
width: 100%;
justify-content: space-around;
padding: 0 1rem;
text-align: center;
}

.tableEntry > div:nth-child(1),
.tableHeader > div:nth-child(1) {
text-align: left;
}

Loading

0 comments on commit 533c973

Please sign in to comment.