mirror of
https://github.com/CarGDev/debug-dojo.git
synced 2025-09-18 18:08:37 +00:00
feat: add autocomplete search with Zustand store and API layer
- Add PokemonAutoComplete atom component using Ant Design - Implement API layer with axios for Pokémon data fetching - Create Zustand store for centralized state management - Add autocomplete suggestions with real-time filtering - Update SearchBar molecule to use autocomplete functionality - Load all Pokémon names on app initialization - Add path aliases for cleaner imports (@api, @stores) - Remove old service layer in favor of API layer - Maintain intentional bugs for debugging practice - Update project structure and documentation
This commit is contained in:
37
src/api/config.ts
Normal file
37
src/api/config.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const BASE_URL = 'https://pokeapi.co/api/v2';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// Request interceptor
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
console.log(`Making ${config.method?.toUpperCase()} request to: ${config.url}`);
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
console.error('Request error:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Response interceptor
|
||||
api.interceptors.response.use(
|
||||
(response) => {
|
||||
console.log(`Response received from: ${response.config.url}`, response.status);
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
console.error('Response error:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
34
src/api/get/pokemon.ts
Normal file
34
src/api/get/pokemon.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import api from '../config';
|
||||
import type { Pokemon } from '@pokemonTypes/pokemon';
|
||||
|
||||
export const getPokemon = async (name: string): Promise<Pokemon> => {
|
||||
try {
|
||||
const response = await api.get<Pokemon>(`/pokemon/${name.toLowerCase()}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
// Intentional bug #1: No proper error handling for non-existent Pokémon
|
||||
console.error('Error fetching Pokémon:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getPokemonList = async (limit: number = 20, offset: number = 0) => {
|
||||
try {
|
||||
const response = await api.get(`/pokemon?limit=${limit}&offset=${offset}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching Pokémon list:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getAllPokemonNames = async (): Promise<string[]> => {
|
||||
try {
|
||||
// Fetch all Pokémon names (151 total in the original Pokédex)
|
||||
const response = await api.get('/pokemon?limit=151&offset=0');
|
||||
return response.data.results.map((pokemon: { name: string }) => pokemon.name);
|
||||
} catch (error) {
|
||||
console.error('Error fetching all Pokémon names:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
14
src/api/index.ts
Normal file
14
src/api/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// API configuration
|
||||
export { default as api } from './config';
|
||||
|
||||
// GET requests
|
||||
export * from './get/pokemon';
|
||||
|
||||
// POST requests (for future use)
|
||||
// export * from './post/';
|
||||
|
||||
// PUT requests (for future use)
|
||||
// export * from './put/';
|
||||
|
||||
// DELETE requests (for future use)
|
||||
// export * from './delete/';
|
Reference in New Issue
Block a user