Skip to content

Commit

Permalink
[web] create route to list all solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
PhantomKnight287 committed Mar 8, 2024
1 parent 6360afe commit 389c123
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
1 change: 1 addition & 0 deletions apps/web/app/solutions/loading.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from "@/components/shared/loading"
82 changes: 82 additions & 0 deletions apps/web/app/solutions/page.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
'use client';

import {useQueryState,} from 'nuqs'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import {Track, Challenge} from "@repo/db/types";
import {upperFirst} from "@repo/utils";


export default function SolutionsFilter({tracks, challenges}: {
tracks: Track[],
challenges: { slug: string, label: string }[]
}) {
const [track, setTrack] = useQueryState('track',{history:"replace",shallow:false})
const [challenge, setChallenge] = useQueryState('challenge',{history:"replace",shallow:false})
const [orderBy, setOrderBy] = useQueryState("orderBy",{history:"replace",shallow:false})


return (
<div className={"flex flex-row gap-4 w-full my-4"}>

<Select onValueChange={setTrack} value={track || undefined}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Track"/>
</SelectTrigger>
<SelectContent>
{
tracks.map((track) => (
<SelectItem value={track.slug}
key={track.slug}
>
{track.name}
</SelectItem>
))
}
</SelectContent>
</Select>
<Select onValueChange={setChallenge} value={challenge || undefined}>
<SelectTrigger
className={"max-w-[200px]"}
>
<SelectValue placeholder="Challenge"/>
</SelectTrigger>
<SelectContent>
{
challenges.map((challenge) => (
<SelectItem value={challenge.slug}
key={challenge.slug}
>
{challenge.label}
</SelectItem>
))
}
</SelectContent>
</Select>
<Select onValueChange={setOrderBy} value={orderBy || undefined}>
<SelectTrigger
className={"max-w-[200px]"}
>
<SelectValue placeholder="Order By"/>
</SelectTrigger>
<SelectContent>
{
["asc","desc"].map((option) => (
<SelectItem value={option}
key={option}
>
{upperFirst(option)}ending
</SelectItem>
))
}
</SelectContent>
</Select>

</div>
)
}
110 changes: 110 additions & 0 deletions apps/web/app/solutions/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {getCachedSolutions} from "@/cache/solutions";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import {fromNow} from "@/utils/time";
import Link from "next/link"
import SolutionsFilter from "@/app/solutions/page.client";
import {getAllTracks} from "@/cache/tracks";
import {getAllChallenges} from "@/cache/challenge";
import {searchParamsCache} from "@/utils/seachParams";
import {Metadata} from "next";

export const dynamic = "force-dynamic"

export const metadata:Metadata = {
title:"Solutions",
description:"View Solutions of Challenges",
openGraph:{
title:"Solutions",
description:"View Solutions of Challenges",
}
}

export default async function Solutions({searchParams}: {
searchParams: Record<string, string | string[] | undefined>
}) {
console.log(searchParams)
const {track, orderBy, challenge} = searchParamsCache.parse(searchParams)
const solutions = await getCachedSolutions(
track,
challenge,
orderBy !== "asc" && orderBy !== "desc" ? "asc" : orderBy
)
const tracks = await getAllTracks()
const challenges = await getAllChallenges(track)
return (
<>
<div className={"container"}>
<h1 className={"font-semibold text-2xl mb-4"}>
Solutions
</h1>
<SolutionsFilter tracks={tracks} challenges={challenges}/>
<Table>
<TableHeader>
<TableRow
className={"not-in-markdown"}>
<TableHead className="not-in-markdown">Title</TableHead>
<TableHead className={"not-in-markdown"}>Track</TableHead>
<TableHead className={"not-in-markdown"}>Challenge</TableHead>
<TableHead className="not-in-markdown">Posted</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{
solutions.map(solution => (
<TableRow
className={"not-in-markdown"}
key={solution.id}
>
<TableCell className="not-in-markdown">
<Link
href={`/solutions/${solution.id}`}
className={"text-clamp-1 hover:underline"}>
{solution.title}
</Link>
</TableCell>
<TableCell className={"not-in-markdown"}>
<Link
href={`/tracks/${solution.challenge.track!.slug}`}
className={"hover:underline"}
>
{solution.challenge.track!.name}
</Link>
</TableCell>
<TableCell className={"not-in-markdown"}>
<Link
href={`/tracks/${solution.challenge.track!.slug}/challenge/${solution.challenge.slug}`}
className={"hover:underline"}
>
{solution.challenge.label}
</Link>
</TableCell>
<TableCell className="not-in-markdown">
{fromNow(solution.createdAt)}
</TableCell>
</TableRow>
))
}

</TableBody>
</Table>
{
solutions.length === 0 ? (
<p
className={"text-center mt-4 text-muted-foreground"}
>
No Solutions Found
</p>
):null
}

</div>
</>
)
}

0 comments on commit 389c123

Please sign in to comment.