Skip to content

Commit

Permalink
feat: support for showing results
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkPhoenix2704 committed Apr 20, 2024
1 parent 862cf1f commit 5dfef90
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 55 deletions.
2 changes: 1 addition & 1 deletion app/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Button = ({
type={type}
disabled={pending || loading}
className={twMerge(
"w-full h-11 px-4 bg-white/15 hover:shadow-primary focus:text-secondary focus:bg-primary hover:bg-primary duration-500 transition-all hover:text-secondary text-white/50 rounded-[10px]",
"w-full h-11 px-4 bg-white/15 focus:text-secondary focus-visible:text-white hover:bg-primary duration-500 transition-all hover:text-secondary text-white/50 rounded-[10px]",
className,
)}
{...rest}
Expand Down
37 changes: 8 additions & 29 deletions app/events/results/[eventID]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,19 @@ export async function GET(
if (!event) {
return new Response("Event not found", { status: 404 });
}

const bestProjects = db.team.findMany({
where: {
eventId: data.eventID,
projectStatus: ProjectStatus.BEST_PROJECT,
},
select: {
id: true,
name: true,
members: {
select: {
user: {
select: {
name: true,
avatar: true,
githubId: true,
},
},
},
},
},
});

const completedProjects = db.team.findMany({
const projects = await db.team.findMany({
where: {
eventId: data.eventID,
projectStatus: ProjectStatus.COMPLETED,
projectStatus: {
in: [ProjectStatus.COMPLETED, ProjectStatus.BEST_PROJECT],
},
},
select: {
id: true,
name: true,
projectStatus: true,
repo: true,
members: {
select: {
user: {
Expand All @@ -68,13 +50,10 @@ export async function GET(
},
});

const res = await Promise.all([bestProjects, completedProjects]);

return new Response(
JSON.stringify({
event: event,
bestProjects: res[0],
completedProjects: res[1],
event,
projects
}),
);
}
4 changes: 3 additions & 1 deletion app/events/ui/CopyLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { toast } from "sonner";

const CopyLink = ({ id }: { id: string }) => {
const copyLink = () => {
navigator.clipboard.writeText(`${window.location.href}?eventID=${id}`);
navigator.clipboard.writeText(
`${window.location.href}?eventID=${id}&results=true`,
);
toast.success("Copied to clipboard!");
};

Expand Down
4 changes: 2 additions & 2 deletions app/events/ui/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const EventCard = ({
>
<Button
type="button"
className="w-full bg-white rounded-md text-black hover:shadow-none active:bg-primary active:ring-2 active:ring-primary disabled:opacity-50 disabled:cursor-not-allowed"
className="w-full bg-white rounded-md text-black active:bg-primary active:ring-2 active:ring-primary disabled:opacity-50 disabled:cursor-not-allowed"
disabled={status !== "RESULTS"}
>
View Projects
Expand All @@ -58,7 +58,7 @@ export const EventCard = ({
<Link className="w-full rounded-md" href={details} target="_blank">
<Button
type="button"
className="text-white w-full rounded-md hover:text-black hover:shadow-none"
className="text-white w-full rounded-md hover:text-black"
>
More Info
</Button>
Expand Down
54 changes: 54 additions & 0 deletions app/events/ui/ProjectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Button } from "@/app/components/Button";
import type { ExtractedTeamType } from "@/utils/types";
import Link from "next/link";
import { toast } from "sonner";
export const ProjectCard = ({ team }: { team: ExtractedTeamType }) => {
return (
<div
key={team.repo}
className="resultBox relative w-72 bg-white bg-opacity-15 rounded-lg overflow-hidden"
>
<div className="bg-white p-7 w-full text-secondary rounded-t-lg">
<p className="text-center">{team.name}</p>
</div>
<div className="w-full p-2 flex flex-col items-start flex-grow gap-1">
{team.members.map(({ user }) => (
<Link
key={user.githubId}
href={`https://www.github.com/${user.githubId}`}
target="_blank"
rel="noopener noreferrer"
className="flex items-center hover:underline"
>
<img
src={user.avatar}
alt={user.name ?? user.githubId}
className="h-7 w-7 rounded-full"
/>
<p className="text-sm text-white ml-2">
{user.name ?? user.githubId}
</p>
</Link>
))}
<div className="w-full text-sm font-medium rounded-b-lg gap-2 flex justify-end pt-2">
<Link className="w-full" href={team.repo} target="_blank">
<Button className="rounded-md bg-white text-black">
View Project
</Button>
</Link>

<Button
className="rounded-md text-white"
onClick={() => {
navigator.clipboard.writeText(team.repo).then(() => {
toast.success("Copied to clipboard");
});
}}
>
Copy Link
</Button>
</div>
</div>
</div>
);
};
97 changes: 87 additions & 10 deletions app/events/ui/modal/ProjectModal.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
"use client";

import { useSearchParams, usePathname, useRouter } from "next/navigation";

import * as Dialog from "@radix-ui/react-dialog";
import { useEffect, useState } from "react";
import { X } from "lucide-react";
import useSWR from "swr";
import { fetcher } from "@/utils/fetcher";
import { ProjectStatus, type ProjectResults } from "@/utils/types";
import { twMerge } from "tailwind-merge";
import { groupBy } from "@/utils/groupBy";
import { ProjectCard } from "../ProjectCard";

export const ProjectModal = () => {
const router = useRouter();

const [isOpen, setIsOpen] = useState(false);

const [eventID, setEventID] = useState<string | null>(null);

const searchParams = useSearchParams();
const eventId = searchParams.get("eventId");
const eventId = searchParams.get("eventID");
const [isOpen, setIsOpen] = useState(false);

useEffect(() => {
setEventID(searchParams.get("eventId"));
setIsOpen(!!searchParams.get("results"));
setIsOpen(!!searchParams.get("results") && !!searchParams.get("eventID"));
}, [searchParams]);

const { data, error, isLoading } = useSWR(
eventId && isOpen ? `/events/results/${eventId}` : null,
fetcher<ProjectResults>,
);

const pathName = usePathname();
const onOpenChange = () => {
router.push(pathName);
Expand All @@ -31,10 +37,10 @@ export const ProjectModal = () => {
<Dialog.Portal>
<Dialog.Overlay className="fixed transition-all animate-overlayShow ease-in-out inset-0 bg-secondary/50" />
<Dialog.Content
className="fixed w-full h-full top-1/2 z-50 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-secondary text-white animate-contentShow rounded-lg p-8 min-w-container"
className="fixed w-full h-full top-1/2 z-50 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-secondary text-white animate-contentShow rounded-lg min-w-container"
onCloseAutoFocus={(e) => e.preventDefault()}
>
<div className="flex justify-end">
<div className="flex absolute top-8 right-8 justify-end">
<span className="border-2 rounded-full border-red-500">
<X
aria-label="Close Modal"
Expand All @@ -43,6 +49,77 @@ export const ProjectModal = () => {
/>
</span>
</div>
<div
className={twMerge(
"text-white text-2xl flex flex-col h-full w-full",
isLoading || error ? "items-center justify-center " : "",
)}
>
{isLoading && (
<svg
className="animate-spin -ml-1 mr-3 h-16 w-16 text-primary"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<title>Spinning Loading Icon</title>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
)}
{error && (
<>
<X className="text-red-500 h-16 w-16 text-5xl" />
<div className="text-center">
<h1 className="text-3xl font-bold">Error</h1>
<p className="text-lg">{error.message}</p>
</div>
</>
)}
{data && (
<>
<div className="bg-white/15 flex items-center justify-center p-4">
<img
className="w-full sm:w-72"
src={data.event.imageWhite}
alt={data.event.title}
/>
</div>
{groupBy(data.projects, "projectStatus")
.sort()
.map((group, _index) => {
const statusText =
group[0].projectStatus === ProjectStatus.BEST_PROJECT
? "Best Projects ⭐"
: "Completed Projects ⭐";
console.log(group);
return (
<div key={group[0].id}>
<h1 className="font-semibold text-2xl md:text-4xl p-4">
{statusText}
</h1>
<div className="flex items-center justify-center md:justify-start flex-wrap p-4">
{group.map((project) => (
<ProjectCard key={project.id} team={project} />
))}
</div>
</div>
);
})}
</>
)}
</div>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
Expand Down
11 changes: 7 additions & 4 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Navbar } from "./ui/Navbar";
import { validateRequest } from "@/utils/lucia";
import { Footer } from "./ui/Footer";
import { Toaster } from "sonner";
import { SWRProvider } from "@/provider/SwrProvider";

const inter = Inter({ subsets: ["latin"] });

Expand Down Expand Up @@ -40,10 +41,12 @@ export default async function RootLayout({
</head>

<body>
<Navbar user={user} />
{children}
<Toaster richColors />
<Footer />
<SWRProvider>
<Navbar user={user} />
{children}
<Toaster richColors />
<Footer />
</SWRProvider>
</body>
</html>
);
Expand Down
33 changes: 30 additions & 3 deletions 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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"react-hook-form": "^7.51.2",
"react-select": "^5.8.0",
"sonner": "^1.4.41",
"swr": "^2.2.5",
"tailwind-merge": "^2.2.2",
"zod": "^3.22.4"
},
Expand Down
Loading

0 comments on commit 5dfef90

Please sign in to comment.