test
This commit is contained in:
		| @@ -0,0 +1,25 @@ | ||||
| import { cache } from "react" | ||||
| import { getPokemon } from "@/registry/new-york/complex-component/lib/pokemon" | ||||
| import { Card, CardContent } from "@/components/ui/card" | ||||
| import { PokemonImage } from "@/registry/new-york/complex-component/components/pokemon-image" | ||||
|  | ||||
| const cachedGetPokemon = cache(getPokemon) | ||||
|  | ||||
| export async function PokemonCard({ name }: { name: string }) { | ||||
|   const pokemon = await cachedGetPokemon(name) | ||||
|  | ||||
|   if (!pokemon) { | ||||
|     return null | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <Card> | ||||
|       <CardContent className="flex flex-col items-center p-2"> | ||||
|         <div> | ||||
|           <PokemonImage name={pokemon.name} number={pokemon.id} /> | ||||
|         </div> | ||||
|         <div className="text-center font-medium">{pokemon.name}</div> | ||||
|       </CardContent> | ||||
|     </Card> | ||||
|   ) | ||||
| } | ||||
| @@ -0,0 +1,20 @@ | ||||
| "use client" | ||||
|  | ||||
| /* eslint-disable @next/next/no-img-element */ | ||||
| import { usePokemonImage } from "@/registry/new-york/complex-component/hooks/use-pokemon" | ||||
|  | ||||
| export function PokemonImage({ | ||||
|   name, | ||||
|   number, | ||||
| }: { | ||||
|   name: string | ||||
|   number: number | ||||
| }) { | ||||
|   const imageUrl = usePokemonImage(number) | ||||
|  | ||||
|   if (!imageUrl) { | ||||
|     return null | ||||
|   } | ||||
|  | ||||
|   return <img src={imageUrl} alt={name} /> | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| "use client" | ||||
|  | ||||
| // Totally unnecessary hook, but it's a good example of how to use a hook in a custom registry. | ||||
|  | ||||
| export function usePokemonImage(number: number) { | ||||
|   return `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${number}.png` | ||||
| } | ||||
| @@ -0,0 +1,48 @@ | ||||
| import { z } from "zod" | ||||
|  | ||||
| export async function getPokemonList({ limit = 10 }: { limit?: number }) { | ||||
|   try { | ||||
|     const response = await fetch( | ||||
|       `https://pokeapi.co/api/v2/pokemon?limit=${limit}` | ||||
|     ) | ||||
|     return z | ||||
|       .object({ | ||||
|         results: z.array(z.object({ name: z.string() })), | ||||
|       }) | ||||
|       .parse(await response.json()) | ||||
|   } catch (error) { | ||||
|     console.error(error) | ||||
|     return null | ||||
|   } | ||||
| } | ||||
|  | ||||
| export async function getPokemon(name: string) { | ||||
|   try { | ||||
|     const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${name}`) | ||||
|  | ||||
|     if (!response.ok) { | ||||
|       throw new Error("Failed to fetch pokemon") | ||||
|     } | ||||
|  | ||||
|     return z | ||||
|       .object({ | ||||
|         name: z.string(), | ||||
|         id: z.number(), | ||||
|         sprites: z.object({ | ||||
|           front_default: z.string(), | ||||
|         }), | ||||
|         stats: z.array( | ||||
|           z.object({ | ||||
|             base_stat: z.number(), | ||||
|             stat: z.object({ | ||||
|               name: z.string(), | ||||
|             }), | ||||
|           }) | ||||
|         ), | ||||
|       }) | ||||
|       .parse(await response.json()) | ||||
|   } catch (error) { | ||||
|     console.error(error) | ||||
|     return null | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| import { cache } from "react" | ||||
| import { PokemonCard } from "@/registry/new-york/complex-component/components/pokemon-card" | ||||
| import { getPokemonList } from "@/registry/new-york/complex-component/lib/pokemon" | ||||
|  | ||||
| const getCachedPokemonList = cache(getPokemonList) | ||||
|  | ||||
| export default async function Page() { | ||||
|   const pokemons = await getCachedPokemonList({ limit: 12 }) | ||||
|  | ||||
|   if (!pokemons) { | ||||
|     return null | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <div className="mx-auto w-full max-w-2xl px-4"> | ||||
|       <div className="grid grid-cols-2 gap-4 py-10 sm:grid-cols-3 md:grid-cols-4"> | ||||
|         {pokemons.results.map((p) => ( | ||||
|           <PokemonCard key={p.name} name={p.name} /> | ||||
|         ))} | ||||
|       </div> | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user