Skip to content

Commit b4ea7f9

Browse files
committed
docs: examples fixes
1 parent b40dcfa commit b4ea7f9

35 files changed

Lines changed: 700 additions & 115 deletions

File tree

examples/rick-and-morty/react-nano_kit/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
"@nano_kit/react-router": "*",
1919
"@nano_kit/router": "*",
2020
"@nano_kit/store": "*",
21-
"clsx": "^2.1.1",
22-
"rickmortyapi": "^2.3.0"
21+
"clsx": "^2.1.1"
2322
},
2423
"devDependencies": {
2524
"@types/react": "^19.2.4",
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import type {
2+
Character,
3+
Episode,
4+
Location,
5+
ApiResponse,
6+
Info,
7+
CharacterFilter,
8+
LocationFilter,
9+
EpisodeFilter
10+
} from './types'
11+
12+
export * from './types'
13+
14+
const BASE_URL = 'https://rickandmortyapi.com/api'
15+
16+
async function fetchApi<T>(url: string): Promise<ApiResponse<T>> {
17+
try {
18+
const response = await fetch(url)
19+
20+
if (!response.ok) {
21+
return {
22+
status: response.status,
23+
statusMessage: response.statusText || String(response.status),
24+
data: {} as T
25+
}
26+
}
27+
28+
const data = await response.json()
29+
30+
return {
31+
status: response.status,
32+
statusMessage: response.statusText || String(response.status),
33+
data
34+
}
35+
} catch (error) {
36+
return {
37+
status: 500,
38+
statusMessage: error instanceof Error ? error.message : 'Unknown error',
39+
data: {} as T
40+
}
41+
}
42+
}
43+
44+
export async function getCharacters(filters?: CharacterFilter): Promise<ApiResponse<Info<Character[]>>> {
45+
const params = new URLSearchParams()
46+
47+
if (filters?.page) {
48+
params.append('page', filters.page.toString())
49+
}
50+
51+
if (filters?.name) {
52+
params.append('name', filters.name)
53+
}
54+
55+
if (filters?.status) {
56+
params.append('status', filters.status)
57+
}
58+
59+
if (filters?.species) {
60+
params.append('species', filters.species)
61+
}
62+
63+
if (filters?.type) {
64+
params.append('type', filters.type)
65+
}
66+
67+
if (filters?.gender) {
68+
params.append('gender', filters.gender)
69+
}
70+
71+
const queryString = params.toString()
72+
const url = `${BASE_URL}/character${queryString ? `?${queryString}` : ''}`
73+
74+
return await fetchApi<Info<Character[]>>(url)
75+
}
76+
77+
export async function getCharacter<T extends number | number[]>(
78+
id: T
79+
): Promise<ApiResponse<T extends number ? Character : Character[]>> {
80+
const ids = Array.isArray(id) ? id.join(',') : id
81+
const url = `${BASE_URL}/character/${ids}`
82+
83+
return await fetchApi(url)
84+
}
85+
86+
export async function getLocations(filters?: LocationFilter): Promise<ApiResponse<Info<Location[]>>> {
87+
const params = new URLSearchParams()
88+
89+
if (filters?.page) {
90+
params.append('page', filters.page.toString())
91+
}
92+
93+
if (filters?.name) {
94+
params.append('name', filters.name)
95+
}
96+
97+
if (filters?.type) {
98+
params.append('type', filters.type)
99+
}
100+
101+
if (filters?.dimension) {
102+
params.append('dimension', filters.dimension)
103+
}
104+
105+
const queryString = params.toString()
106+
const url = `${BASE_URL}/location${queryString ? `?${queryString}` : ''}`
107+
108+
return await fetchApi<Info<Location[]>>(url)
109+
}
110+
111+
export async function getLocation<T extends number | number[]>(
112+
id: T
113+
): Promise<ApiResponse<T extends number ? Location : Location[]>> {
114+
const ids = Array.isArray(id) ? id.join(',') : id
115+
const url = `${BASE_URL}/location/${ids}`
116+
117+
return await fetchApi(url)
118+
}
119+
120+
export async function getEpisodes(filters?: EpisodeFilter): Promise<ApiResponse<Info<Episode[]>>> {
121+
const params = new URLSearchParams()
122+
123+
if (filters?.page) {
124+
params.append('page', filters.page.toString())
125+
}
126+
127+
if (filters?.name) {
128+
params.append('name', filters.name)
129+
}
130+
131+
if (filters?.episode) {
132+
params.append('episode', filters.episode)
133+
}
134+
135+
const queryString = params.toString()
136+
const url = `${BASE_URL}/episode${queryString ? `?${queryString}` : ''}`
137+
138+
return await fetchApi<Info<Episode[]>>(url)
139+
}
140+
141+
export async function getEpisode<T extends number | number[]>(
142+
id: T
143+
): Promise<ApiResponse<T extends number ? Episode : Episode[]>> {
144+
const ids = Array.isArray(id) ? id.join(',') : id
145+
const url = `${BASE_URL}/episode/${ids}`
146+
147+
return await fetchApi(url)
148+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-disable @typescript-eslint/naming-convention */
2+
export interface CharacterLocation {
3+
name: string
4+
url: string
5+
}
6+
7+
export interface ResourceBase {
8+
id: number
9+
name: string
10+
url: string
11+
created: string
12+
}
13+
14+
export interface CharacterFilter {
15+
name?: string
16+
type?: string
17+
species?: string
18+
status?: string
19+
gender?: string
20+
page?: number
21+
}
22+
23+
export interface LocationFilter {
24+
name?: string
25+
type?: string
26+
page?: number
27+
dimension?: string
28+
}
29+
30+
export interface EpisodeFilter {
31+
name?: string
32+
page?: number
33+
episode?: string
34+
}
35+
36+
export interface Character extends ResourceBase {
37+
status: 'Dead' | 'Alive' | 'unknown'
38+
species: string
39+
type: string
40+
gender: 'Female' | 'Male' | 'Genderless' | 'unknown'
41+
origin: CharacterLocation
42+
location: CharacterLocation
43+
image: string
44+
episode: string[]
45+
}
46+
47+
export interface Location extends ResourceBase {
48+
type: string
49+
dimension: string
50+
residents: string[]
51+
}
52+
53+
export interface Episode extends ResourceBase {
54+
air_date: string
55+
episode: string
56+
characters: string[]
57+
}
58+
59+
export interface ApiResponse<T> {
60+
status: number
61+
statusMessage: string
62+
data: T
63+
}
64+
65+
export interface Info<T> {
66+
info?: {
67+
count: number
68+
pages: number
69+
next: string | null
70+
prev: string | null
71+
}
72+
results?: T
73+
}

examples/rick-and-morty/react-nano_kit/src/stores/characters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type Character,
55
getCharacter,
66
getCharacters
7-
} from 'rickmortyapi'
7+
} from '#src/services/api'
88
import { OK_STATUS } from '#src/common/constants'
99
import {
1010
type Page,

examples/rick-and-morty/react-nano_kit/src/stores/episodes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type Episode,
55
getEpisode,
66
getEpisodes
7-
} from 'rickmortyapi'
7+
} from '#src/services/api'
88
import { OK_STATUS } from '#src/common/constants'
99
import {
1010
type Page,

examples/rick-and-morty/react-nano_kit/src/stores/locations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
type Location,
44
getLocation,
55
getLocations
6-
} from 'rickmortyapi'
6+
} from '#src/services/api'
77
import { OK_STATUS } from '#src/common/constants'
88
import {
99
type Page,

examples/rick-and-morty/react-nano_kit/src/ui/blocks/CharacterCard/CharacterCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* DISCLAIMER! VIBECODED! */
2-
import { type Character } from 'rickmortyapi'
32
import clsx from 'clsx'
3+
import { type Character } from '#src/services/api'
44
import { paths } from '#src/stores/router'
55
import styles from './CharacterCard.module.css'
66

examples/rick-and-morty/react-nano_kit/src/ui/blocks/CharactersGrid/CharactersGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* DISCLAIMER! VIBECODED! */
2-
import { type Character } from 'rickmortyapi'
2+
import { type Character } from '#src/services/api'
33
import { CharacterCard } from '#src/ui/blocks/CharacterCard'
44
import styles from './CharactersGrid.module.css'
55

examples/rick-and-morty/react-nano_kit/src/ui/blocks/EpisodeCard/EpisodeCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* DISCLAIMER! VIBECODED! */
2-
import { type Episode } from 'rickmortyapi'
2+
import { type Episode } from '#src/services/api'
33
import { paths } from '#src/stores/router'
44
import styles from './EpisodeCard.module.css'
55

examples/rick-and-morty/react-nano_kit/src/ui/blocks/EpisodesGrid/EpisodesGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* DISCLAIMER! VIBECODED! */
2-
import { type Episode } from 'rickmortyapi'
2+
import { type Episode } from '#src/services/api'
33
import { EpisodeCard } from '#src/ui/blocks/EpisodeCard'
44
import styles from './EpisodesGrid.module.css'
55

0 commit comments

Comments
 (0)