Skip to content

Commit 5862559

Browse files
[web] add metadata and add check when creating solution
1 parent 9a2384d commit 5862559

File tree

6 files changed

+63
-43
lines changed

6 files changed

+63
-43
lines changed

apps/web/app/[username]/layout.client.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,18 @@ export function ProfileButtons({
6969
Enrolled in {user._count.tracks}{" "}
7070
{user._count.tracks <= 1 ? "Track" : "Tracks"}
7171
</Link>
72-
<Button
73-
variant={"outline"}
74-
className="rounded-xl text-left flex flex-row items-center justify-start gap-2"
72+
<Link
73+
href={`/@${username}/solutions`}
74+
className={buttonVariants({
75+
variant: pathname === "solutions" ? "secondary" : "outline",
76+
className:
77+
"rounded-xl text-left flex flex-row items-center !justify-start gap-2",
78+
})}
7579
>
7680
<CheckCheck className="text-purple-500" />
7781
{user._count.solutions}{" "}
7882
{user._count.solutions <= 1 ? "Solution" : "Solutions"} Posted
79-
</Button>
83+
</Link>
8084
<LayoutClientComponents username={username} />
8185
</div>
8286
);

apps/web/app/tracks/[track]/challenge/[challenge]/solutions/create/page.client.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,15 @@ import Link from "next/link";
1616
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
1717
import { Markdown } from "@/components/markdown";
1818

19+
1920
let timeout: NodeJS.Timeout;
20-
function CreateSolutionPage({ files }: { files: ChallengeFilesStructure[] }) {
21+
function CreateSolutionPage({
22+
files,
23+
solved,
24+
}: {
25+
files: ChallengeFilesStructure[];
26+
solved: boolean;
27+
}) {
2128
const [editableFiles, setEditableFiles] = useState(files);
2229
const [activeFile, setActiveFile] = useState<string>(
2330
`${editableFiles[0].name}-0`
@@ -86,8 +93,8 @@ function CreateSolutionPage({ files }: { files: ChallengeFilesStructure[] }) {
8693
<Label htmlFor="title" className="text-lg">
8794
Title
8895
</Label>
89-
<Button type="submit" disabled={loading}>
90-
Create Solution
96+
<Button type="submit" disabled={loading || !solved}>
97+
{!solved ? "Solve the challenge first" : "Create Solution"}
9198
</Button>
9299
</div>
93100
<TextareaAutosize
@@ -97,6 +104,7 @@ function CreateSolutionPage({ files }: { files: ChallengeFilesStructure[] }) {
97104
ref={titleRef}
98105
required
99106
autoFocus
107+
disabled={!solved}
100108
/>
101109
<Label htmlFor="description" className="text-lg">
102110
Description
@@ -120,6 +128,7 @@ function CreateSolutionPage({ files }: { files: ChallengeFilesStructure[] }) {
120128
placeholder="Write description of your solution here(supports Markdown)"
121129
minRows={3}
122130
value={description}
131+
disabled={!solved}
123132
onChange={(e) => setDescription(e.target.value)}
124133
required
125134
/>
@@ -167,6 +176,12 @@ function CreateSolutionPage({ files }: { files: ChallengeFilesStructure[] }) {
167176
?.name.split(".")[1] as any
168177
]
169178
}
179+
options={{
180+
readOnly: !solved,
181+
readOnlyMessage: {
182+
value: "Please solve the challenge first",
183+
},
184+
}}
170185
value={
171186
(editableFiles.find(
172187
(file, index) => `${file.name}-${index}` === activeFile

apps/web/app/tracks/[track]/challenge/[challenge]/solutions/create/page.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import CreateSolutionPage from "./page.client";
33
import { prisma } from "@repo/db";
44
import { ChallengeFilesStructure } from "@repo/challenges/src";
55
import { auth } from "@/auth";
6+
import { Metadata } from "next";
7+
8+
export const metadata: Metadata = {
9+
title: "Create a solution",
10+
description: "Create a solution",
11+
};
612

713
async function CreateSolution({
814
params,
@@ -21,6 +27,14 @@ async function CreateSolution({
2127
track: { slug: params.track },
2228
},
2329
});
30+
const solved = await prisma.solves.findFirst({
31+
where: {
32+
type: "accepted",
33+
challenge: {
34+
slug: params.challenge,
35+
},
36+
},
37+
});
2438
if (!challenge) notFound();
2539
const editableFiles: ChallengeFilesStructure[] = [];
2640
const files = challenge.initialFiles;
@@ -47,7 +61,7 @@ async function CreateSolution({
4761

4862
return (
4963
<div className="container">
50-
<CreateSolutionPage files={editableFiles} />
64+
<CreateSolutionPage files={editableFiles} solved={!!solved?.id} />
5165
</div>
5266
);
5367
}

apps/web/app/tracks/[track]/challenge/[challenge]/solved/_components/solutions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async function Solutions({
4545
<Link
4646
className="flex flex-col gap-2 p-2 bg-border rounded-md hover:bg-zinc-100 dark:hover:bg-zinc-700"
4747
key={solution.id}
48-
href={`/solution/${solution.id}`}
48+
href={`/solutions/${solution.id}`}
4949
>
5050
<div className="flex flex-row items-center justify-between">
5151
<div className="flex flex-row items-center gap-2">

apps/web/app/tracks/page.tsx

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TrackCard } from "@/components/track-card";
33
import { prisma } from "@/lib/db";
44
import { Metadata, Viewport } from "next";
55
import { env } from "@/env.mjs";
6+
import { getCachedTracks } from "@/cache/tracks";
67

78
export const dynamic = "force-dynamic";
89

@@ -38,24 +39,7 @@ export const viewport: Viewport = {
3839

3940
export default async function Tracks({}: { searchParams: { type?: string } }) {
4041
const session = await auth();
41-
const tracks = await prisma.track.findMany({
42-
include: {
43-
_count: {
44-
select: {
45-
users: true,
46-
},
47-
},
48-
...(session?.user?.id
49-
? {
50-
users: {
51-
where: {
52-
id: session.user.id,
53-
},
54-
},
55-
}
56-
: undefined),
57-
},
58-
});
42+
const tracks = await getCachedTracks(session?.user?.id);
5943

6044
return (
6145
<main className="flex mt-12">

apps/web/components/hero/index.tsx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,26 @@ export async function Hero() {
1313
<div className="grid gap-6 lg:grid-cols-[1fr_400px] lg:gap-12 xl:grid-cols-[1fr_600px]">
1414
<div className="flex flex-col justify-center space-y-4">
1515
<div className="space-y-2">
16-
{githubStars != null ? (
17-
<Link
18-
href={siteConfig.urls.github}
19-
target="_blank"
20-
rel="noreferrer"
21-
>
22-
<Badge
23-
aria-hidden="true"
24-
className="rounded-md px-3.5 py-1.5"
25-
variant="secondary"
16+
<div className="w-full flex">
17+
{githubStars != null ? (
18+
<Link
19+
href={siteConfig.urls.github}
20+
target="_blank"
21+
rel="noreferrer"
22+
className="mx-auto lg:mx-0"
2623
>
27-
<Github className="mr-2 size-3.5" aria-hidden="true" />
28-
{githubStars} stars on GitHub
29-
</Badge>
30-
<span className="sr-only">GitHub</span>
31-
</Link>
32-
) : null}
24+
<Badge
25+
aria-hidden="true"
26+
className="rounded-md px-3.5 py-1.5"
27+
variant="secondary"
28+
>
29+
<Github className="mr-2 size-3.5" aria-hidden="true" />
30+
{githubStars} stars on GitHub
31+
</Badge>
32+
<span className="sr-only">GitHub</span>
33+
</Link>
34+
) : null}
35+
</div>
3336
<h1 className="text-3xl font-bold tracking-tighter sm:text-5xl xl:text-6xl/none text-center lg:text-left">
3437
Learn JavaScript frameworks with interactive challenges
3538
</h1>

0 commit comments

Comments
 (0)