-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/plezanje-net/next-web
- Loading branch information
Showing
10 changed files
with
279 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
...g]/crag/[cragSlug]/components/crag-routes/crag-route-list/crag-route/difficulty-votes.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { useEffect, useState } from "react"; | ||
import difficultyVotesAction from "./server-actions/difficulty-votes-action"; | ||
import { DifficultyVote, Route } from "@/graphql/generated"; | ||
import displayDate from "@/utils/display-date"; | ||
import Grade, { diffToGrade } from "@/components/grade"; | ||
import { pluralizeNoun } from "@/utils/text-helpers"; | ||
import { gradingSystems } from "@/utils/grading-systems"; | ||
|
||
interface Props { | ||
route: Route; | ||
difficultyVotes: DifficultyVote[]; | ||
} | ||
|
||
function DifficultyVotes({ route, difficultyVotes }: Props) { | ||
const routeGradeDifficulty = route.difficulty | ||
? diffToGrade(route.difficulty, "french", false).difficulty | ||
: null; | ||
|
||
const nrVotesPerDifficulty = difficultyVotes.reduce( | ||
(acc, vote) => ({ | ||
...acc, | ||
[vote.difficulty]: (acc[vote.difficulty] || 0) + 1, | ||
}), | ||
{} as Record<number, number> | ||
); | ||
|
||
if (routeGradeDifficulty && !nrVotesPerDifficulty[routeGradeDifficulty]) { | ||
nrVotesPerDifficulty[routeGradeDifficulty] = 0; | ||
} | ||
|
||
const maxVotesPerDifficulty = Math.max( | ||
...Object.values(nrVotesPerDifficulty) | ||
); | ||
|
||
return ( | ||
<> | ||
<table className="w-full max-w-sm"> | ||
<tbody> | ||
{Object.entries(nrVotesPerDifficulty).map(([difficulty, nrVotes]) => ( | ||
<tr key={difficulty}> | ||
<td className="pr-4"> | ||
<Grade | ||
difficulty={parseInt(difficulty)} | ||
displayIntermediate={true} | ||
/> | ||
</td> | ||
<td className="w-full"> | ||
<span | ||
className={`float-left block h-5 w-0.5 ${ | ||
nrVotes === maxVotesPerDifficulty && "w-full" | ||
} rounded ${ | ||
routeGradeDifficulty === parseInt(difficulty) | ||
? "bg-blue-500" | ||
: "bg-neutral-200" | ||
}`} | ||
style={ | ||
nrVotes > 0 | ||
? { | ||
width: `${Math.round( | ||
(nrVotes / maxVotesPerDifficulty) * 100 | ||
)}%`, | ||
} | ||
: {} | ||
} | ||
></span> | ||
<span className="relative float-left"> | ||
<span className="absolute whitespace-nowrap pl-3 align-middle text-sm"> | ||
{nrVotes !== maxVotesPerDifficulty && | ||
pluralizeNoun("glas", nrVotes)} | ||
</span> | ||
</span> | ||
</td> | ||
<td className="whitespace-nowrap pl-3 align-middle text-sm"> | ||
{nrVotes === maxVotesPerDifficulty && | ||
pluralizeNoun("glas", nrVotes)} | ||
</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
<table className="mt-8"> | ||
<tbody> | ||
{difficultyVotes.map((vote) => ( | ||
<tr | ||
key={vote.id} | ||
className={ | ||
vote.includedInCalculation | ||
? "text-neutral-900" | ||
: "text-neutral-500" | ||
} | ||
> | ||
<td className="pr-4"> | ||
<Grade | ||
difficulty={vote.difficulty} | ||
displayIntermediate={true} | ||
/> | ||
</td> | ||
<td className="pr-4"> | ||
{vote.isBase ? "(bazna ocena)" : vote.user?.fullName} | ||
</td> | ||
<td>{displayDate(vote.created)}</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
</> | ||
); | ||
} | ||
|
||
export default DifficultyVotes; |
55 changes: 55 additions & 0 deletions
55
.../[lang]/crag/[cragSlug]/components/crag-routes/crag-route-list/crag-route/route-grade.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { useRouter } from "next/navigation"; | ||
import Dialog, { | ||
DialogSize, | ||
} from "../../../../../../../../components/ui/dialog"; | ||
import DifficultyVotes from "./difficulty-votes"; | ||
import { Crag, DifficultyVote, Route } from "@/graphql/generated"; | ||
import Grade from "@/components/grade"; | ||
import useIsVisible from "@/hooks/useIsVisible"; | ||
import { useEffect, useRef, useState } from "react"; | ||
import difficultyVotesAction from "./server-actions/difficulty-votes-action"; | ||
|
||
interface RouteGradeProps { | ||
route: Route; | ||
crag: Crag; | ||
} | ||
|
||
function RouteGrade({ route, crag }: RouteGradeProps) { | ||
const router = useRouter(); | ||
const ref = useRef<HTMLButtonElement>(null); | ||
const handleOpenRoutePage = () => { | ||
router.push(`/plezalisce/${crag.slug}/smer/${route.slug}`); | ||
}; | ||
|
||
const visible = useIsVisible(ref); | ||
|
||
const [difficultyVotes, setDifficultyVotes] = useState<DifficultyVote[]>([]); | ||
|
||
useEffect(() => { | ||
if (visible) { | ||
difficultyVotesAction(route.id).then((votes) => { | ||
setDifficultyVotes(votes); | ||
}); | ||
} | ||
}, [visible, route.id]); | ||
|
||
return route.isProject ? ( | ||
<>P</> | ||
) : ( | ||
<Dialog | ||
openTrigger={ | ||
<button ref={ref}> | ||
{route.difficulty && <Grade difficulty={route.difficulty} />} | ||
</button> | ||
} | ||
dialogSize={DialogSize.medium} | ||
title="Glasovi uporabnikov" | ||
confirm={{ label: "Več", callback: handleOpenRoutePage }} | ||
cancel={{ label: "Zapri" }} | ||
> | ||
<DifficultyVotes route={route} difficultyVotes={difficultyVotes} /> | ||
</Dialog> | ||
); | ||
} | ||
|
||
export default RouteGrade; |
53 changes: 53 additions & 0 deletions
53
...mponents/crag-routes/crag-route-list/crag-route/server-actions/difficulty-votes-action.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
"use server"; | ||
|
||
import { gql } from "urql/core"; | ||
import { | ||
DifficultyVote, | ||
RouteDifficultyVotesDocument, | ||
} from "@/graphql/generated"; | ||
import urqlServer from "@/graphql/urql-server"; | ||
|
||
async function difficultyVotesAction( | ||
routeId: string | ||
): Promise<DifficultyVote[]> { | ||
const result = await urqlServer().query(RouteDifficultyVotesDocument, { | ||
routeId, | ||
}); | ||
|
||
if (result.error) { | ||
return Promise.reject(result.error); | ||
} | ||
|
||
return result.data.route.difficultyVotes; | ||
} | ||
|
||
export default difficultyVotesAction; | ||
|
||
gql` | ||
query RouteDifficultyVotes($routeId: String!) { | ||
route(id: $routeId) { | ||
id | ||
slug | ||
difficulty | ||
defaultGradingSystem { | ||
id | ||
} | ||
name | ||
length | ||
difficultyVotes { | ||
user { | ||
id | ||
fullName | ||
firstname | ||
lastname | ||
} | ||
id | ||
difficulty | ||
created | ||
updated | ||
isBase | ||
includedInCalculation | ||
} | ||
} | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.