Skip to content

Commit 5de5759

Browse files
committedNov 19, 2024·
Change the game page to be more easier to read and to interact with.
1 parent a1ecff4 commit 5de5759

File tree

6 files changed

+111
-62
lines changed

6 files changed

+111
-62
lines changed
 

‎app/games/[slug]/page.tsx

+36-23
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
11
import * as React from "react";
22
import { Game } from "@/types/game";
3-
import { games, } from "@/config/games";
4-
3+
import { games } from "@/config/games";
54
import { CH1, GameDesc } from "@/components/custom-typo";
65
import { GameLevel } from "@/components/game-level-component";
76
import { CodeComponent } from "@/components/code-component";
87

9-
export default function GamePrompt({ params }: { params: { slug: string } }) {
10-
const game = games.filter(game => game.href == params.slug)[0];
11-
if (!game) return <h1>404 - Page Not Found</h1>;
8+
function GameHeader({ game }: { game: Game }) {
129
return (
13-
<div className="px-1 max-w-full md:px-8 md:max-w-[1800px]">
14-
<div className="justify-between flex flex-row w-full">
15-
<div className="grow-1 self-start">
16-
<GameLevel level={game.level} />
17-
</div>
18-
<div className="grow-1 self-end flex bg-red-100">
19-
{/* Todo(): Add Score and the number of solved */}
20-
<div className="center"></div>
21-
<div className="center"></div>
22-
</div>
10+
<div className="justify-between flex flex-row w-full">
11+
<div className="grow-1 self-start">
12+
<GameLevel level={game.level} />
13+
</div>
14+
<div className="grow-1 self-end flex">
15+
{/* Score and solved count will go here */}
16+
</div>
17+
</div>
18+
);
19+
}
20+
21+
function GameContent({ game }: { game: Game }) {
22+
return (
23+
<div className="flex flex-col-reverse md:flex-row md:py-3 justify-between">
24+
<div className="grow-[3] w-full md:min-w-[600px] md:max-w-[1400px]">
25+
<CodeComponent game={game} />
2326
</div>
24-
<div className="flex flex-col-reverse md:flex-row md:py-3 justify-between wrap">
25-
<div className="grow-[3] w-full md:min-w-[600px] md:max-w-[1400px]">
26-
<CodeComponent game={game} />
27-
</div>
28-
<div className="grow-[1] max-w-full md:w-3/6 md:min-w-[300px] md:max-w-[800px] md:px-4 md:pt-4">
29-
<CH1 text={game.title} />
30-
<GameDesc text={game.text} />
31-
</div>
27+
<div className="grow-[1] max-w-full md:w-3/6 md:min-w-[300px] md:max-w-[800px] md:px-4 md:pt-4">
28+
<CH1 text={game.title} />
29+
<GameDesc text={game.text} />
3230
</div>
3331
</div>
3432
);
3533
}
3634

35+
export default function GamePrompt({ params }: { params: { slug: string } }) {
36+
const game = games.find((game) => game.href === params.slug);
37+
38+
if (!game) {
39+
return <h1>404 - Page Not Found</h1>;
40+
}
41+
42+
return (
43+
<div className="px-1 max-w-full md:px-8 md:max-w-[1800px]">
44+
<GameHeader game={game} />
45+
<GameContent game={game} />
46+
</div>
47+
);
48+
}
49+
3750
export async function generateStaticParams() {
3851
return games.map((game: Game) => ({
3952
slug: game.href,

‎app/layout.tsx

+16-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ import { SiteHeader } from "@/components/site-header";
99
import { Toaster as DefaultToaster } from "@/components/ui/toaster";
1010
import { GoogleTagManager } from "@next/third-parties/google";
1111
import type { Viewport } from "next";
12+
import { Inter } from "next/font/google";
13+
import { JetBrains_Mono } from "next/font/google";
14+
15+
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
16+
const jetbrains = JetBrains_Mono({
17+
subsets: ["latin"],
18+
variable: "--font-jetbrains",
19+
});
1220

1321
export const viewport: Viewport = {
1422
width: "device-width",
@@ -78,7 +86,11 @@ interface RootLayoutProps {
7886
export default function RootLayout({ children }: RootLayoutProps) {
7987
return (
8088
<>
81-
<html lang="en" suppressHydrationWarning>
89+
<html
90+
lang="en"
91+
className={`${inter.variable} ${jetbrains.variable}`}
92+
suppressHydrationWarning
93+
>
8294
<body
8395
className={cn(
8496
"min-h-screen bg-background font-sans antialiased",
@@ -93,7 +105,9 @@ export default function RootLayout({ children }: RootLayoutProps) {
93105
>
94106
<div className="relative flex min-h-screen w-full flex-col ">
95107
<SiteHeader />
96-
<div className="flex-1 p-1 py-8 w-full mx-auto max-w-[2000px]">{children}</div>
108+
<div className="flex-1 p-1 py-8 w-full mx-auto max-w-[2000px]">
109+
{children}
110+
</div>
97111
<SiteFooter />
98112
</div>
99113
</ThemeProvider>

‎components/code-component.tsx

+27-18
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,20 @@ import { reviver } from "@/utils/codeComponentUtils";
2222
import { useReward } from "react-rewards";
2323
import { Button } from "@/components/ui/button";
2424
import { Game } from "@/types/game";
25-
import { useProgressStore } from '@/stores/progress-store';
25+
import { useProgressStore } from "@/stores/progress-store";
2626

2727
export function CodeComponent(props: { game: Game }) {
2828
const [foundError, setFoundError] = useState(false);
2929
const [score, setScore] = useState(0);
3030
const [tried, setTried] = useState<CodeLine[]>([]);
3131
const [discovered, setDiscovered] = useState<CodeLine[]>([]);
32-
const {
33-
completeGame,
34-
setCurrentContent,
35-
isContentCompleted,
36-
} = useProgressStore();
32+
const { completeGame, setCurrentContent, isContentCompleted } =
33+
useProgressStore();
3734

3835
const [userSubHint, setUserSubHint] = useState(
3936
<>
40-
<Crosshair1Icon /> <span className="pl-1">Find the error</span>{" "}
37+
<Crosshair1Icon className="h-6 w-6" />
38+
<span className="pl-2 text-2xl">Find the error</span>
4139
</>
4240
);
4341
// undefined nextHref will assign one if we find another game and if the players win.
@@ -75,10 +73,10 @@ export function CodeComponent(props: { game: Game }) {
7573
setFoundError(true);
7674
setUserSubHint(
7775
<>
78-
<Crosshair2Icon />{" "}
79-
<span className="pl-1">
80-
Click on the line that fixes the problem.
81-
</span>{" "}
76+
<Crosshair2Icon className="h-6 w-6" />
77+
<span className="pl-2 text-2xl">
78+
Click on the line that fixes the problem
79+
</span>
8280
</>
8381
);
8482
}
@@ -109,8 +107,8 @@ export function CodeComponent(props: { game: Game }) {
109107
);
110108
setUserSubHint(
111109
<>
112-
{" "}
113-
<CheckCircledIcon /> <span className="pl-1">Congrats!</span>{" "}
110+
<CheckCircledIcon className="h-6 w-6" />
111+
<span className="pl-2 text-2xl">Congrats!</span>
114112
</>
115113
);
116114
setFoundError(false);
@@ -121,7 +119,7 @@ export function CodeComponent(props: { game: Game }) {
121119
//find out why not interactive anymore.
122120
return (
123121
<div id="rewardId">
124-
<div className="flex items-center font-bold text-muted-foreground text-green-500 text-xl pt-4">
122+
<div className="flex items-center font-bold text-muted-foreground text-green-900 py-6 px-4 bg-emerald-200 rounded-lg mb-4 shadow-sm">
125123
{userSubHint}
126124
</div>
127125
<div className="flex flex-col bg-[#475266] p-1 rounded">
@@ -141,7 +139,7 @@ export function CodeComponent(props: { game: Game }) {
141139

142140
const CustomPre = (props: any) => {
143141
const cn = "absolute top-3 right-3 text-white";
144-
let icon = <span></span>
142+
let icon = <span></span>;
145143
if (
146144
tried.includes(cl) &&
147145
(cl.state == StateEnum.ERROR || StateEnum.CORRECT)
@@ -158,9 +156,20 @@ export function CodeComponent(props: { game: Game }) {
158156
return (
159157
<span
160158
className={`relative group
161-
${isCandidate && "border-2 border-l-4 rounded border-green-500 cursor-cell"}
162-
${cl.state == StateEnum.NORMAL && foundError && "cursor-default blur-[0.8px] grayscale hover:translate-x-0"}
163-
${cl.state == StateEnum.ERROR && foundError && "cursor-default hover:translate-x-0"}
159+
${
160+
isCandidate &&
161+
"border-2 border-l-4 rounded border-green-500 cursor-cell"
162+
}
163+
${
164+
cl.state == StateEnum.NORMAL &&
165+
foundError &&
166+
"cursor-default blur-[0.8px] grayscale hover:translate-x-0"
167+
}
168+
${
169+
cl.state == StateEnum.ERROR &&
170+
foundError &&
171+
"cursor-default hover:translate-x-0"
172+
}
164173
`}
165174
>
166175
<span

‎components/custom-typo.tsx

+21-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function CH1(props: { text: string; id?: string }) {
88
id={props.id}
99
className="bg-gradient-to-r from-green-400 to-green-700
1010
inline-block text-transparent bg-clip-text scroll-m-20
11-
text-4xl font-extrabold tracking-tight lg:text-5xl pb-2"
11+
text-4xl font-extrabold tracking-tight lg:text-5xl pb-2 font-inter"
1212
>
1313
{props.text}
1414
</h1>
@@ -20,21 +20,31 @@ export function SubTitle(props: { text: string; class?: string; id?: string }) {
2020
return (
2121
<p
2222
id={props.id}
23-
className={`capitalize font-bold text-xl text-muted-foreground mt-4 ${props.class}`}
23+
className={`font-jetbrains text-xl text-muted-foreground mt-4 ${props.class}`}
2424
>
2525
{props.text}
2626
</p>
2727
);
2828
}
2929

3030
/** Game Description */
31-
export function GameDesc(props: { text: string; class?: string; id?: string }) {
31+
export function GameDesc({
32+
text,
33+
className,
34+
id,
35+
}: {
36+
text: string;
37+
className?: string;
38+
id?: string;
39+
}) {
3240
return (
3341
<p
34-
id={props.id}
35-
className={`capitalize text-m text-muted-foreground font-mono mt-4 ${props.class}`}
42+
id={id}
43+
className={`text-m text-muted-foreground font-jetbrains leading-relaxed mt-4 ${
44+
className ?? ""
45+
}`}
3646
>
37-
{props.text}
47+
{text}
3848
</p>
3949
);
4050
}
@@ -45,7 +55,7 @@ export function SectionTitle(props: { section?: Section; class?: string }) {
4555
return (
4656
<h3
4757
id={props.section.id}
48-
className={`capitalize mt-8 scroll-m-20 text-2xl font-bold tracking-tight mb-2 ${props.class}`}
58+
className={`mt-8 scroll-m-20 text-2xl font-bold tracking-tight mb-2 font-inter ${props.class}`}
4959
>
5060
&rarr; {props.section.title}
5161
</h3>
@@ -58,14 +68,15 @@ export function SectionSubTitle(props: { section?: Section; class?: string }) {
5868
return (
5969
<p
6070
id={props.section.id}
61-
className={`capitalize font-bold text-xl text-muted-foreground mt-3 ${props.class}`}
71+
className={`font-jetbrains text-xl text-muted-foreground mt-3 ${props.class}`}
6272
>
6373
{props.section?.title}
6474
</p>
6575
);
6676
}
6777

6878
export const boldPClasses =
69-
"leading-7 text-xl font-semibold tracking-tight text-wrap md:ml-8";
79+
"leading-7 text-xl font-semibold tracking-tight text-wrap md:ml-8 font-inter";
7080

71-
export const normalPClasses = "leading-7 text-xl tracking-tight text-wrap mt-4";
81+
export const normalPClasses =
82+
"leading-7 text-xl tracking-tight text-wrap mt-4 font-jetbrains";

‎styles/globals.css

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
@tailwind components;
33
@tailwind utilities;
44

5-
65
@layer base {
76
:root {
87
--background: 0 0% 100%;
@@ -50,7 +49,6 @@
5049
}
5150
}
5251

53-
5452
@layer base {
5553
* {
5654
@apply border-border;
@@ -99,7 +97,7 @@
9997
.markdown a {
10098
@apply text-green-500 hover:text-green-700 font-bold;
10199
}
102-
ul {
100+
ul {
103101
@apply list-disc pl-5 mt-4;
104102
}
105103
li {

‎tailwind.config.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
module.exports = {
33
darkMode: ["class"],
44
content: [
5-
'./pages/**/*.{ts,tsx}',
6-
'./components/**/*.{ts,tsx}',
7-
'./app/**/*.{ts,tsx}',
8-
'./src/**/*.{ts,tsx}',
9-
],
5+
"./pages/**/*.{ts,tsx}",
6+
"./components/**/*.{ts,tsx}",
7+
"./app/**/*.{ts,tsx}",
8+
"./src/**/*.{ts,tsx}",
9+
],
1010
theme: {
1111
container: {
1212
center: true,
@@ -70,7 +70,11 @@ module.exports = {
7070
"accordion-down": "accordion-down 0.2s ease-out",
7171
"accordion-up": "accordion-up 0.2s ease-out",
7272
},
73+
fontFamily: {
74+
inter: ["Inter", "sans-serif"],
75+
jetbrains: ["JetBrains Mono", "monospace"],
76+
},
7377
},
7478
},
7579
plugins: [require("tailwindcss-animate")],
76-
}
80+
};

0 commit comments

Comments
 (0)
Please sign in to comment.