Skip to content

Commit

Permalink
Redesign Archived Challenges (#98)
Browse files Browse the repository at this point in the history
* Change padding

* Change gap size

* Allow testing on archived challenges

* Change text size

* Add minimum height for inputs/outputs

* Swap archive icon
  • Loading branch information
ImJunny authored Dec 10, 2024
1 parent 623e9f6 commit e3b4afd
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ArchivedChallenges from "@/app/_components/challenges/archived-challenges";
import { Card, CardContent } from "@/app/_components/ui/card";
import { cn } from "@/app/_lib/client-utils";
import { serverTRPC } from "@/app/_trpc/server";
import { type Metadata } from "next";
import React from "react";
Expand All @@ -13,10 +14,10 @@ export default async function ChallengesPage() {
const challenges = await serverTRPC.challenges.get_archived_challenges.query();

return (
<div className="container grid max-w-6xl grid-cols-1 gap-y-8">
<div className="container grid max-w-6xl grid-cols-1 gap-y-4">
<Card>
<CardContent className="p-6">
<h1 className="font-semibold tracking-tight text-xl">Welcome to the Challenge Archive</h1>
<CardContent className="p-6 grid gap-y-1.5">
<h1 className="font-semibold tracking-tight text-lg">Challenge Archive</h1>
<p className="text-sm">These are challenges that have been used in past events and are currently not being used.
You can still run and test them, but they will not give you any points. It is possible for some of these challenges to appear
in the next event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MiniAnnouncements } from "@/app/_components/announcement/mini-announcem
import { Challenges } from "@/app/_components/challenges/challenges";
import ChallengesProgress from "@/app/_components/challenges/challenges-progress";
import DashboardTeamInfo from "@/app/_components/dashboard/dashboard-team-info";
import { cn } from "@/app/_lib/client-utils";
import { serverTRPC } from "@/app/_trpc/server";
import { type TUserRole } from "@/db/drizzle/startup_seed";
import { composeServerComponentClient } from "@/server/lib/supabase/server";
Expand All @@ -27,20 +28,21 @@ export default async function ChallengesPage() {
user_uuid: user.id,
});

const challengeCount = challenges.solvedChallenges.length + challenges.unsolvedChallenges.length

return (
<div className="container grid max-w-6xl grid-cols-1 gap-y-8">
<div className={cn(challengeCount > 0 ? "gap-y-8" : "gap-y-4","container grid max-w-6xl grid-cols-1")}>
<div className="grid gap-4 lg:grid-cols-2">
<DashboardTeamInfo />
<ChallengesProgress challenges={challenges} />
</div>

<div className="flex gap-4">
<Challenges
challenges={challenges}
challengesEnabled={is_challenges_enabled}
userRole={get_user_role as TUserRole}
/>
<MiniAnnouncements />
<MiniAnnouncements className={challengeCount > 0 ? "mt-8":""}/>
</div>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions src/app/_components/announcement/mini-announcements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { MiniAnnouncementPost } from "./mini-announcement-post";
import { Card, CardContent } from "../ui/card";
import Link from "next/link";
import { siteConfig } from "@/app/_config/site";
import { cn } from "@/app/_lib/client-utils";

export async function MiniAnnouncements({}: React.HTMLAttributes<HTMLDivElement>) {
export async function MiniAnnouncements({className}: React.HTMLAttributes<HTMLDivElement>) {
const serverAnnouncementPosts =
await serverTRPC.announcements.get_announcement_posts.query();

Expand All @@ -23,7 +24,7 @@ export async function MiniAnnouncements({}: React.HTMLAttributes<HTMLDivElement>
});

return (
<div className="hidden lg:block">
<div className={cn(className, "hidden lg:block")}>
<Card className="w-80">
<CardContent className="flex flex-col space-y-4 p-6">
<div className="flex justify-between">
Expand Down
15 changes: 9 additions & 6 deletions src/app/_components/challenges/archived-challenges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ export default function ArchivedChallenges({
return a.challenge_points - b.challenge_points;
});

for (const challenge of challenges){
for (let i=0; i<challenges.length; i++){
const challenge = challenges[i]!
challengeElements.push(
<Link href={siteConfig.paths.challenge + "/" + challenge.challenge_id}>
<Card className="cursor-pointer transition-colors hover:bg-accent/50">
<Link href={siteConfig.paths.challenge + "/" + challenge.challenge_id} key={`challenge-${challenge.challenge_id}`}
className={cn(i===challenges.length-2 && i%2==0 ? "border-b lg:border-b-0" : "border-b last:border-b-0",
"border-r-0 lg:border-r")}>
<div className="transition-colors hover:bg-accent/50">
<div className="flex flex-row items-center px-6 py-3">
<h1 className="mr-4">{challenge.challenge_title}</h1>
<div className="ml-auto flex items-center justify-center space-x-2">
Expand All @@ -46,16 +49,16 @@ export default function ArchivedChallenges({
</Badge>
</div>
</div>
</Card>
</div>
</Link>
)
}

if (challengeElements.length>0){
return(
<div className="grid md:grid-cols-2 gap-4">
<Card className="grid lg:grid-cols-2">
{challengeElements}
</div>
</Card>
)
}else{
return(
Expand Down
69 changes: 19 additions & 50 deletions src/app/_components/challenges/challenge-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,56 +25,25 @@ export default function ChallengeCard({
challenge_points,
} = challengeData;

const router = useRouter();

if (challengesEnabled || userRole !== "participant") {
return (
if(challengesEnabled || userRole!=="participant"){
return(
<Link
href={siteConfig.paths.challenge + "/" + challenge_id}
className="border-b last:border-0"
className="border-b last:border-0 transition-colors hover:bg-accent/50"
>
<div
className="cursor-pointer transition-colors hover:bg-accent/50"
onClick={() => {
if (challengesEnabled || userRole !== "participant")
router.push(siteConfig.paths.challenge + "/" + challenge_id);
}}
>
<div className="flex flex-row items-center px-6 py-3">
<h1 className="mr-4">{challenge_title}</h1>
<div className="ml-auto flex items-center justify-center space-x-2">
<Badge className="w-16 justify-center bg-foreground text-background hover:bg-foreground/90">
{challenge_points}
</Badge>
<Badge
className={cn(
"w-16 justify-center bg-foreground capitalize text-foreground dark:text-background",
challenge_difficulty == "easy"
? "bg-green-500 hover:bg-green-500/90"
: challenge_difficulty == "medium"
? "bg-primary hover:bg-primary/90"
: challenge_difficulty == "hard"
? "bg-red-500 hover:bg-red-500/90"
: "",
)}
>
{challenge_difficulty}
</Badge>
</div>
</div>
</div>
</Link>
);
<ChallengeCardLink/>
</Link>
)
}else{
return (
<div className="border-b last:border-0">
<ChallengeCardLink/>
</div>
)
}

return (
<div
className="cursor-pointer border-b transition-colors last:border-0 hover:bg-accent/50"
onClick={() => {
if (challengesEnabled || userRole !== "participant")
router.push(siteConfig.paths.challenge + "/" + challenge_id);
}}
>

function ChallengeCardLink(){
return (
<div className="flex flex-row items-center px-6 py-3">
<h1 className="mr-4">{challenge_title}</h1>
<div className="ml-auto flex items-center justify-center space-x-2">
Expand All @@ -83,7 +52,7 @@ export default function ChallengeCard({
</Badge>
<Badge
className={cn(
"w-16 justify-center bg-foreground capitalize text-background ",
"w-16 justify-center bg-foreground capitalize text-foreground dark:text-background",
challenge_difficulty == "easy"
? "bg-green-500 hover:bg-green-500/90"
: challenge_difficulty == "medium"
Expand All @@ -96,7 +65,7 @@ export default function ChallengeCard({
{challenge_difficulty}
</Badge>
</div>
</div>
</div>
);
</div>
)
}
}
4 changes: 2 additions & 2 deletions src/app/_components/challenges/challenge-content-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ export default function ChallengeContentInfo({
</HoverCardContent>
</HoverCard>
</Label>
<pre className="word-break whitespace-pre-line break-words bg-background-variant font-mono">
<pre className="word-break whitespace-pre-line break-words bg-background-variant font-mono min-h-6">
{challengeData?.challenge_example_input}
</pre>
<Label>Output</Label>
<pre className="word-break whitespace-pre-line break-words bg-background-variant font-mono">
<pre className="word-break whitespace-pre-line break-words bg-background-variant font-mono min-h-6">
{challengeData?.challenge_example_output}
</pre>
<Label>Explanation</Label>
Expand Down
1 change: 1 addition & 0 deletions src/app/_components/challenges/challenge-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export default function ChallengeContentPage({
solved={solved}
setLanguage={setLanguage}
setOutputData={setOutputData}
challengeLive={challengeData!.challenge_is_live!}
/>
</ProtectedEditorSiteHeader>

Expand Down
10 changes: 6 additions & 4 deletions src/app/_components/challenges/challenge-nav-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type ChallengeNavActionsProps = {
solved: boolean;
setLanguage: Dispatch<SetStateAction<TLanguages>>;
setOutputData: Dispatch<SetStateAction<TSubmitData | null>>;
challengeLive: boolean
};

export default function ChallengeNavActions({
Expand All @@ -40,6 +41,7 @@ export default function ChallengeNavActions({
solved,
setLanguage,
setOutputData,
challengeLive
}: ChallengeNavActionsProps) {
//runs code
const { refetch: runCode, isFetching: isRunning } =
Expand Down Expand Up @@ -76,23 +78,23 @@ export default function ChallengeNavActions({
//runs code
async function attemptRunCode() {
await checkUserOnTeam();
if (onTeam?.is_on_team) await runCode();
if (!challengeLive || (onTeam?.is_on_team && challengeLive)) await runCode();
else {
toast({
variant: "destructive",
description: "You must be on a team to participate in challenges.",
description: "You must be on a team to participate in live challenges.",
duration: 4000,
});
}
}
//submits code
async function attemptSubmitCode() {
await checkUserOnTeam();
if (onTeam?.is_on_team) await submitCode();
if (!challengeLive || (onTeam?.is_on_team && challengeLive)) await submitCode();
else {
toast({
variant: "destructive",
description: "You must be on a team to participate in challenges.",
description: "You must be on a team to participate in live challenges.",
duration: 4000,
});
}
Expand Down
4 changes: 3 additions & 1 deletion src/app/_components/challenges/challenges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function Challenges({
return(
<Card className="w-full mt-0 self-start">
<CardContent className="p-6 text-center">
<h1 className="font-semibold tracking-tight text-xl">No challenges yet</h1>
<h1 className="font-semibold tracking-tight text-lg">No challenges yet</h1>
<p className="text-sm">You can visit the Challenge Archive to view past challenges.</p>
<Button className="mt-4 ml-auto" asChild>
<Link href={siteConfig.paths.challenge_archive}>
Expand All @@ -89,6 +89,8 @@ export function Challenges({
)
}



return (
<div className="flex w-full flex-col gap-8">
<div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/_components/dashboard/dashboard-team-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default async function DashboardTeamInfo() {
<Card>
<CardContent className="flex h-full items-center justify-between gap-4 p-6 text-sm">
<p className="text-md text-muted-foreground">
You must be on a team to participate in challenges.
You must be on a team to participate in live challenges.
</p>
<Link href={siteConfig.paths.join_team}>
<Button variant="outline" className="w-32">
Expand Down
4 changes: 2 additions & 2 deletions src/app/_components/nav/protected-side-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePathname } from "next/navigation";
import { cn } from "@/app/_lib/client-utils";
import { siteConfig } from "@/app/_config/site";
import { Button } from "../ui/button";
import { Archive, BarChart2, Bell, LayoutDashboard, Users } from "lucide-react";
import { BarChart2, Bell, History, LayoutDashboard, Users } from "lucide-react";

export function ProtectedSideNav() {
return (
Expand All @@ -26,7 +26,7 @@ export function ProtectedSideNav() {
</div>
<div className="flex flex-col">
<SideNavOption title="Challenge Archive" path={siteConfig.paths.challenge_archive}>
<Archive/>
<History />
</SideNavOption>
</div>
</nav>
Expand Down

0 comments on commit e3b4afd

Please sign in to comment.