diff --git a/src/app/store.ts b/src/app/store.ts index 33d82ad..2db51dc 100644 --- a/src/app/store.ts +++ b/src/app/store.ts @@ -1,9 +1,11 @@ import { configureStore } from '@reduxjs/toolkit' import { reducer as bookReducer } from '../features/book/bookSlice' +import { reducer as categoryReducer } from '../features/category/categorySlice' export const store = configureStore({ reducer: { books: bookReducer, + categories: categoryReducer, }, }) diff --git a/src/components/BookList/index.tsx b/src/components/BookList/index.tsx index bd8b338..056032c 100644 --- a/src/components/BookList/index.tsx +++ b/src/components/BookList/index.tsx @@ -1,6 +1,7 @@ import React, { useEffect } from 'react' import { useAppDispatch, useAppSelector } from '../../app/hooks' import { fetchBooks } from '../../features/book/bookSlice' +import { fetchCategories } from '../../features/category/categorySlice' import LoadingSpinner from '../LoadingSpinner' import AddBookModal from '../AddBookModal' import BookCard from '../BookCard' @@ -11,11 +12,11 @@ const BookList: React.FC = () => { const isLoading = useAppSelector((state) => state.books.isLoading) useEffect(() => { - const fetchBooksData = async () => { - await dispatch(fetchBooks()) + const fetchBooksAndCategoriesData = async () => { + await Promise.all([dispatch(fetchBooks()), dispatch(fetchCategories())]) } - fetchBooksData() + fetchBooksAndCategoriesData() }, [dispatch]) return ( diff --git a/src/features/category/categorySlice.ts b/src/features/category/categorySlice.ts new file mode 100644 index 0000000..3cc5e79 --- /dev/null +++ b/src/features/category/categorySlice.ts @@ -0,0 +1,54 @@ +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit' +import axios from 'axios' + +export interface Category { + id: string + name: string + books: string[] + created_at: string + updated_at: string +} + +type initialState = { + categoriesData: Category[] + isLoading: 'idle' | 'loading' | 'succeeded' | 'failed' + error: string | null +} + +const initialState: initialState = { + categoriesData: [], + isLoading: 'idle', + error: '', +} + +export const fetchCategories = createAsyncThunk( + 'categories/fetchCategories', + async () => { + const response = await axios.get( + 'https://helm-bookstore-api.onrender.com/api/categories/' + ) + return response.data + } +) + +export const categorySlice = createSlice({ + name: 'categories', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(fetchCategories.pending, (state) => { + state.isLoading = 'loading' + }) + .addCase(fetchCategories.fulfilled, (state, action) => { + state.isLoading = 'succeeded' + state.categoriesData = action.payload.categories + }) + .addCase(fetchCategories.rejected, (state, action) => { + state.isLoading = 'failed' + state.error = action.error.message || 'Unknown error' + }) + }, +}) + +export const { actions, reducer } = categorySlice