Skip to content

Commit d7f51eb

Browse files
Create a menu to allow selecting a category and endpoint to learn more about it
1 parent 9749c35 commit d7f51eb

File tree

6 files changed

+210
-12
lines changed

6 files changed

+210
-12
lines changed

src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default function RootLayout({
99
children: React.ReactNode;
1010
}>) {
1111
return (
12-
<html lang="en" className="bg-gray-900">
12+
<html lang="en" className="bg-gray-100">
1313
<link
1414
href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Syne+Mono&family=Ubuntu+Mono&display=swap"
1515
rel="stylesheet"

src/app/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
export default function Home() {
22
return (
3-
<main className="flex min-h-screen flex-col items-center justify-center p-24 bg-gray-900 text-white">
4-
<a href="/swapi" className="text-lg text-blue-500 hover:text-blue-700">
3+
<main className="flex min-h-screen flex-col items-center justify-center p-24 bg-gray-100 text-white">
4+
<a href="/swapi" className="text-lg text-pokemon-blue hover:underline">
55
Go to SWAPI
66
</a>
7-
<a href="/pokedex" className="text-lg text-blue-500 hover:text-blue-700">
7+
<a href="/pokedex" className="text-lg text-pokemon-yellow hover:underline">
88
Go to Pokedex
99
</a>
1010
</main>

src/app/pokedex/about/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const AboutPage = () => {
55
return (
66
<>
77
<Navbar />
8-
<main className="flex flex-col items-center justify-center p-24 bg-gray-900 text-white">
8+
<main className="flex flex-col items-center justify-center">
99
<h1>About Page</h1>
1010
<p>Under Construction</p>
1111
</main>

src/app/pokedex/api/page.tsx

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,111 @@
1-
import React from "react";
1+
"use client";
2+
import React, { useState } from "react";
23
import Navbar from "../components/navbar";
34

5+
import { categories } from "../data/categories";
6+
47
const APIPage = () => {
8+
const [selectedCategory, setSelectedCategory] = useState<string>(
9+
categories[0]?.id
10+
);
11+
const [selectedEndpoint, setselectedEndpoint] = useState<string | null>(
12+
categories[0]?.endpoints?.[0]?.id || null
13+
);
14+
15+
const handleEndpointSelect = (
16+
categoryId: string,
17+
endpointId: string | null
18+
) => {
19+
setSelectedCategory(categoryId);
20+
setselectedEndpoint(endpointId);
21+
};
22+
523
return (
624
<>
725
<Navbar />
8-
<main className="flex flex-col items-center justify-center p-24 bg-gray-900 text-white">
9-
<h1>API Documentation Page</h1>
10-
<p>Under Construction</p>
11-
</main>
26+
<div className="flex flex-row items-start">
27+
<div className="w-64 pl-4 pt-2 bg-gray-100">
28+
<SidebarMenu onEndpointSelect={handleEndpointSelect} />
29+
</div>
30+
<main className="flex flex-col flex-grow items-start justify-center rounded-md mt-24">
31+
<div className="w-full p-8 bg-white rounded-md">
32+
<h1 className="text-2xl font-press-start font-bold mb-4">
33+
{selectedCategory}
34+
</h1>
35+
{selectedEndpoint && (
36+
<p>
37+
Selected category: {selectedCategory}
38+
<br />
39+
Selected edndpoint: {selectedEndpoint}
40+
</p>
41+
)}
42+
{!selectedEndpoint && <p>Selected Category: {selectedCategory}</p>}
43+
</div>
44+
</main>
45+
<div className="w-64"></div>
46+
</div>
1247
</>
1348
);
1449
};
1550

51+
interface SidebarMenuProps {
52+
onEndpointSelect?: (categoryId: string, endpointId: string | null) => void;
53+
}
54+
55+
const SidebarMenu: React.FC<SidebarMenuProps> = ({ onEndpointSelect }) => {
56+
const [openCategory, setOpenCategory] = useState<string | null>(null);
57+
const [selectedEndpoint, setselectedEndpoint] = useState<string | null>(null);
58+
59+
const toggleCategory = (id: string) => {
60+
if (openCategory === id) {
61+
return;
62+
}
63+
64+
const isOpening = openCategory !== id;
65+
setOpenCategory(isOpening ? id : null);
66+
67+
const firstendpointId = isOpening
68+
? categories.find((category) => category.id === id)?.endpoints?.[0]?.id ||
69+
null
70+
: null;
71+
setselectedEndpoint(firstendpointId);
72+
73+
onEndpointSelect && onEndpointSelect(id, firstendpointId || null);
74+
};
75+
76+
const selectEndpoint = (id: string) => {
77+
setselectedEndpoint(id);
78+
onEndpointSelect && onEndpointSelect(openCategory || "", id);
79+
};
80+
81+
return (
82+
<div className="w-fit min-w-48 max-w-80 p-3 text-sm text-pokemon-gray">
83+
{categories.map((category) => (
84+
<div key={category.id} className="mb-1">
85+
<div
86+
className={`cursor-pointer px-2 py-1 mb-1 rounded-lg hover:bg-pokemon-yellow ${openCategory === category.id ? "underline decoration-2 underline-offset-2 decoration-pokemon-blue" : ""}`}
87+
onClick={() => toggleCategory(category.id)}
88+
>
89+
{category.id}
90+
</div>
91+
92+
{openCategory === category.id && category.endpoints && (
93+
<div className="pl-2">
94+
{category.endpoints.map((endpoint) => (
95+
<div
96+
key={endpoint.id}
97+
className={`cursor-pointer px-2 py-1 mb-1 rounded-lg hover:bg-pokemon-yellow ${selectedEndpoint === endpoint.id ? "underline decoration-2 underline-offset-2 decoration-pokemon-blue" : ""}`}
98+
onClick={() => selectEndpoint(endpoint.id)}
99+
>
100+
{endpoint.id}
101+
</div>
102+
))}
103+
</div>
104+
)}
105+
</div>
106+
))}
107+
</div>
108+
);
109+
};
110+
16111
export default APIPage;

src/app/pokedex/data/categories.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
export interface Category {
2+
id: string;
3+
endpoints?: Array<{ id: string }>;
4+
}
5+
6+
export const categories: Category[] = [
7+
{
8+
id: "Information",
9+
},
10+
{
11+
id: "Berries",
12+
endpoints: [
13+
{ id: "Berries" },
14+
{ id: "Berry Firmnesses" },
15+
{ id: "Berry Flavors" },
16+
],
17+
},
18+
{
19+
id: "Contests",
20+
endpoints: [
21+
{ id: "Contest Types" },
22+
{ id: "Contest Effects" },
23+
{ id: "Super Contest Effects" },
24+
],
25+
},
26+
{
27+
id: "Encounters",
28+
endpoints: [
29+
{ id: "Encounter Methods" },
30+
{ id: "Encounter Conditions" },
31+
{ id: "Encounter Condition Values" },
32+
],
33+
},
34+
{
35+
id: "Evolution",
36+
endpoints: [{ id: "Evolution Chains" }, { id: "Evolution Triggers" }],
37+
},
38+
{
39+
id: "Games",
40+
endpoints: [
41+
{ id: "Generations" },
42+
{ id: "Pokedexes" },
43+
{ id: "Version" },
44+
{ id: "Version Groups" },
45+
],
46+
},
47+
{
48+
id: "Items",
49+
endpoints: [
50+
{ id: "Item" },
51+
{ id: "Item Attributes" },
52+
{ id: "Item Categories" },
53+
{ id: "Item Fling Effects" },
54+
{ id: "Item Pockets" },
55+
],
56+
},
57+
{
58+
id: "Locations",
59+
endpoints: [
60+
{ id: "Locations" },
61+
{ id: "Location Areas" },
62+
{ id: "Pal Park Areas" },
63+
{ id: "Regions" },
64+
],
65+
},
66+
{
67+
id: "Machines",
68+
endpoints: [{ id: "Machines" }],
69+
},
70+
{
71+
id: "Moves",
72+
endpoints: [
73+
{ id: "Moves" },
74+
{ id: "Move Ailments" },
75+
{ id: "Move Battle Styles" },
76+
{ id: "Move Categories" },
77+
{ id: "Move Damage Classes" },
78+
{ id: "Move Learn Methods" },
79+
{ id: "Move Targets" },
80+
],
81+
},
82+
{
83+
id: "Pokemon",
84+
endpoints: [
85+
{ id: "Abilities" },
86+
{ id: "Characteristics" },
87+
{ id: "Egg Groups" },
88+
{ id: "Genders" },
89+
{ id: "Growth Rates" },
90+
{ id: "Natures" },
91+
{ id: "Pokeathlon Stats" },
92+
{ id: "Pokemon" },
93+
{ id: "Pokemon Location Areas" },
94+
{ id: "Pokemon Colors" },
95+
{ id: "Pokemon Forms" },
96+
{ id: "Pokemon Habitats" },
97+
{ id: "Pokemon Shapes" },
98+
{ id: "Pokemon Species" },
99+
{ id: "Stats" },
100+
{ id: "Types" },
101+
],
102+
},
103+
];

src/app/pokedex/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default function PokemonAPI() {
1111
return (
1212
<>
1313
<Navbar />
14-
<main className="flex flex-col items-center justify-center p-24 bg-gray-900 text-white">
14+
<main className="flex flex-col items-center justify-center p-24 text-pokemon-gray">
1515
<h1 className="text-5xl font-bold mb-6 font-press-start">Pokedex</h1>
1616
<h2 className="text-3xl font-semibold mb-8 -mt-4">by Mimo</h2>
1717
<p className="text-lg mb-4">
@@ -49,7 +49,7 @@ export default function PokemonAPI() {
4949
width="64"
5050
height="64"
5151
/>
52-
<code className="bg-gray-700 text-sm p-2 rounded">
52+
<code className="bg-gray-700 text-white text-sm p-2 rounded">
5353
GET /api/pokemon/charizard
5454
</code>
5555
</section>

0 commit comments

Comments
 (0)