-}
-
-export default BotonFavorito;
\ No newline at end of file
diff --git a/src/componentes/botones/boton-favorito.componente.tsx b/src/componentes/botones/boton-favorito.componente.tsx
new file mode 100644
index 0000000..1ffef93
--- /dev/null
+++ b/src/componentes/botones/boton-favorito.componente.tsx
@@ -0,0 +1,41 @@
+
+import './boton-favorito.css';
+import { useAppDispatch, useAppSelector } from '../../store';
+import { ADD_FAVORITOS } from '../../store/characters/slice';
+import { ICharacter } from '../../interfaces/character.interface';
+/**
+ * Boton que indica si un elemento es favorito o no, y da la posibilidad de marcarlo/desmarcarlo
+ *
+ * Deberás tipar las propiedades si usas este componente
+ *
+ *
+ * @returns un JSX element
+ */
+export interface IBotonFavorito {
+ isFavorite: boolean;
+ source: string
+ id: number
+}
+
+const BotonFavorito = ({isFavorite, id, name, image }: ICharacter) => {
+ const dispatch = useAppDispatch()
+ useAppSelector((state) => state.characters)
+
+
+
+/**
+ * Disparador de Agregar a favoritos
+ * @author 'Carmen Vargas'
+ * @return {Array} un array de favoritos
+ */
+ const addFavorito = () => {
+ console.log('Botón Favorito ON CLICK');
+ dispatch(ADD_FAVORITOS( {isFavorite, id, name, image} ));
+ }
+ const src = isFavorite ? "/imagenes/star-filled.png" : "/imagenes/star.png"
+ return
+
+
+}
+
+export default BotonFavorito;
\ No newline at end of file
diff --git a/src/componentes/episodios/tarjeta-episodio.componente.jsx b/src/componentes/episodios/tarjeta-episodio.componente.jsx
deleted file mode 100644
index 11cd257..0000000
--- a/src/componentes/episodios/tarjeta-episodio.componente.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import './tarjeta-episodio.css';
-
-/**
- * Tarjeta para cada episodio dentro de la vista de personaje.
- *
- * Deberás agregar las propiedades necesarias para mostrar los datos de los episodios
- *
- *
- * @returns un JSX element
- */
-const TarjetaEpisodio = () => {
-
- return
-
Close Rick-counters of the Rick Kind
-
- S01E01
- Lanzado el: April 7, 2014
-
-
-}
-
-export default TarjetaEpisodio;
\ No newline at end of file
diff --git a/src/componentes/episodios/tarjeta-episodio.componente.tsx b/src/componentes/episodios/tarjeta-episodio.componente.tsx
new file mode 100644
index 0000000..7b85fba
--- /dev/null
+++ b/src/componentes/episodios/tarjeta-episodio.componente.tsx
@@ -0,0 +1,27 @@
+import './tarjeta-episodio.css';
+
+/**
+ * Tarjeta para cada episodio dentro de la vista de personaje.
+ *
+ * Deberás agregar las propiedades necesarias para mostrar los datos de los episodios
+ *
+ *
+ * @returns un JSX element
+ */
+export interface IEpisodio {
+ nombre: string;
+ numeroDeEpisodio: string;
+ fechaDeLanzamiento: Date;
+}
+const TarjetaEpisodio = ({nombre,numeroDeEpisodio,fechaDeLanzamiento}: IEpisodio) => {
+ const dateString = fechaDeLanzamiento.toLocaleDateString()
+ return
+
{nombre}
+
+ {numeroDeEpisodio}
+ Lanzado el:{dateString}
+
+
+}
+
+export default TarjetaEpisodio;
\ No newline at end of file
diff --git a/src/componentes/paginacion/paginacion.componente.jsx b/src/componentes/paginacion/paginacion.componente.jsx
deleted file mode 100644
index 53804a3..0000000
--- a/src/componentes/paginacion/paginacion.componente.jsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import './paginacion.css';
-
-/**
- * Componente que contiene los botones para paginar
- *
- * Deberás agregar las propiedades necesarias para que funcione correctamente
- *
- *
- * @returns un JSX element
- */
-const Paginacion = () => {
-
- return
-
-
-
-}
-
-export default Paginacion;
\ No newline at end of file
diff --git a/src/componentes/paginacion/paginacion.componente.tsx b/src/componentes/paginacion/paginacion.componente.tsx
new file mode 100644
index 0000000..8320000
--- /dev/null
+++ b/src/componentes/paginacion/paginacion.componente.tsx
@@ -0,0 +1,35 @@
+import './paginacion.css';
+import { useAppDispatch, useAppSelector } from '../../store';
+
+import { GET_CHARACTERS } from '../../store/characters/thunk';
+
+/**
+ * Componente que contiene los botones para paginar
+ *
+ * Deberás agregar las propiedades necesarias para que funcione correctamente
+ *
+ *
+ * @returns un JSX element
+ */
+export interface IPaginacion {
+ pageValue: number
+ }
+
+const Paginacion = () => {
+ const dispatch = useAppDispatch()
+ const {nextPage, prevPage} = useAppSelector((state)=> state.characters)
+
+ const handelNextPage = () =>{
+ dispatch(GET_CHARACTERS(nextPage))
+ }
+ const handelPrevPage = () =>{
+ dispatch(GET_CHARACTERS(prevPage))
+ }
+ return
+
+
+
+
+}
+
+export default Paginacion;
\ No newline at end of file
diff --git a/src/componentes/personajes/filtros.componente.jsx b/src/componentes/personajes/filtros.componente.jsx
deleted file mode 100644
index b82f7c3..0000000
--- a/src/componentes/personajes/filtros.componente.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import './filtros.css';
-
-const Filtros = () => {
-
- return
+ }
+
+ export default Filtros;
\ No newline at end of file
diff --git a/src/componentes/personajes/grilla-personajes.componente.jsx b/src/componentes/personajes/grilla-personajes.componente.jsx
deleted file mode 100644
index 759b71b..0000000
--- a/src/componentes/personajes/grilla-personajes.componente.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import './grilla-personajes.css';
-import TarjetaPersonaje from './tarjeta-personaje.componente';
-
-/**
- * Grilla de personajes para la pagina de inicio
- *
- * Deberás agregar las funciones necesarias para mostrar y paginar los personajes
- *
- *
- * @returns un JSX element
- */
-const GrillaPersonajes = () => {
-
- return
-
-
-
-
-}
-
-export default GrillaPersonajes;
\ No newline at end of file
diff --git a/src/componentes/personajes/grilla-personajes.componente.tsx b/src/componentes/personajes/grilla-personajes.componente.tsx
new file mode 100644
index 0000000..2fe3f59
--- /dev/null
+++ b/src/componentes/personajes/grilla-personajes.componente.tsx
@@ -0,0 +1,42 @@
+import { useAppSelector } from '../../store';
+import './grilla-personajes.css';
+import TarjetaPersonaje from './tarjeta-personaje.componente';
+import { IGrillaPersonajes } from './personaje.interface';
+
+
+
+
+/**
+ * Grilla de personajes para la pagina de inicio
+ *
+ * Deberás agregar las funciones necesarias para mostrar y paginar los personajes
+ *
+ *
+ * @returns un JSX element
+ */
+const GrillaPersonajes = ({initialCharacters} : IGrillaPersonajes) => {
+
+ const {isError, isLoading, listFavoritos} = useAppSelector((state) => state.characters)
+ // Crea una copia de la lista de favoritos con los IDs de los personajes
+ const favoritosIds = listFavoritos.map(character => character.id);
+
+ // Mapea los personajes iniciales y establece esFavorito en true si están en la lista de favoritos
+ const charactersWithFavoritos = initialCharacters.map(character => ({
+ ...character,
+ isFavorite: favoritosIds.includes(character.id),
+ }));
+
+ return
+ }
+
+ export default GrillaPersonajes;
\ No newline at end of file
diff --git a/src/componentes/personajes/personaje.interface.ts b/src/componentes/personajes/personaje.interface.ts
new file mode 100644
index 0000000..6e3e3d2
--- /dev/null
+++ b/src/componentes/personajes/personaje.interface.ts
@@ -0,0 +1,13 @@
+import { ICharacter } from "../../interfaces/character.interface";
+
+export interface IFiltros{
+ name: string | null,
+ setName: (name: string | null )=> void
+ urlBase: string
+ }
+
+
+
+ export interface IGrillaPersonajes{
+ initialCharacters: ICharacter[]
+ }
diff --git a/src/componentes/personajes/tarjeta-personaje.componente.jsx b/src/componentes/personajes/tarjeta-personaje.componente.tsx
similarity index 56%
rename from src/componentes/personajes/tarjeta-personaje.componente.jsx
rename to src/componentes/personajes/tarjeta-personaje.componente.tsx
index 332edfe..14bb1ad 100644
--- a/src/componentes/personajes/tarjeta-personaje.componente.jsx
+++ b/src/componentes/personajes/tarjeta-personaje.componente.tsx
@@ -1,5 +1,7 @@
import BotonFavorito from '../botones/boton-favorito.componente';
import './tarjeta-personaje.css';
+import { ICharacter } from '../../interfaces/character.interface';
+
/**
* Tarjeta para cada personaje dentro de la grilla de personajes.
@@ -7,15 +9,15 @@ import './tarjeta-personaje.css';
* Deberás agregar las propiedades necesarias para mostrar los datos de los personajes
*
*
- * @returns un JSX element
+* @returns un JSX element
*/
-const TarjetaPersonaje = () => {
+const TarjetaPersonaje = ({name, image, isFavorite, id}: ICharacter) => {
return
-
+
- Rick Sanchez
-
+ {name}
+
}
diff --git a/src/index.jsx b/src/index.tsx
similarity index 63%
rename from src/index.jsx
rename to src/index.tsx
index 44f96ac..b22cfe0 100644
--- a/src/index.jsx
+++ b/src/index.tsx
@@ -1,20 +1,24 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import './index.css';
-import App from './App';
+import { Provider } from "react-redux";
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from "react-router-dom";
+import store from "./store";
+import App from "./App";
+
+
ReactDOM.render(
-
-
-
-
- ,
- document.getElementById('root')
+
+
+
+
+ ,
+document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
+reportWebVitals();
\ No newline at end of file
diff --git a/src/interfaces/character.interface.ts b/src/interfaces/character.interface.ts
new file mode 100644
index 0000000..69afdf4
--- /dev/null
+++ b/src/interfaces/character.interface.ts
@@ -0,0 +1,12 @@
+export interface ICharacter {
+ id:number;
+ name: string;
+ image: string;
+ isFavorite: boolean;
+
+}
+export interface IAllCharacters{
+ allCharacters:ICharacter[]
+ nextPage: string;
+ prevPage: string;
+}
\ No newline at end of file
diff --git a/src/interfaces/episodio.interface.ts b/src/interfaces/episodio.interface.ts
new file mode 100644
index 0000000..3d54e08
--- /dev/null
+++ b/src/interfaces/episodio.interface.ts
@@ -0,0 +1,9 @@
+export interface episodio {
+ id: number;
+ name: string;
+ air_date: string;
+ episode: string;
+ characters: string[];
+ url: string;
+ created: Date;
+}
\ No newline at end of file
diff --git a/src/paginas/Detalle.pagina.jsx b/src/paginas/Detalle.pagina.tsx
similarity index 62%
rename from src/paginas/Detalle.pagina.jsx
rename to src/paginas/Detalle.pagina.tsx
index b0db4c7..f87c0e2 100644
--- a/src/paginas/Detalle.pagina.jsx
+++ b/src/paginas/Detalle.pagina.tsx
@@ -1,6 +1,7 @@
import "./Detalle.css";
import BotonFavorito from "../componentes/botones/boton-favorito.componente";
import TarjetaEpisodio from "../componentes/episodios/tarjeta-episodio.componente";
+import { IEpisodio } from "../componentes/episodios/tarjeta-episodio.componente";
/**
* Esta es la pagina de detalle. Aqui se puede mostrar la vista sobre el personaje seleccionado junto con la lista de episodios en los que aparece
@@ -15,6 +16,12 @@ import TarjetaEpisodio from "../componentes/episodios/tarjeta-episodio.component
* @returns la pagina de detalle
*/
const PaginaDetalle = () => {
+ const episodio: IEpisodio = {
+ nombre: 'Juan',
+ numeroDeEpisodio: '1l',
+ fechaDeLanzamiento: new Date()
+ }
+
return
Rick Sanchez
@@ -26,14 +33,14 @@ const PaginaDetalle = () => {
Planeta: Earth
Genero: Male
-
+ {/* */}
Lista de episodios donde apareció el personaje
-
-
-
+
+
+
}
diff --git a/src/paginas/Favoritos.pagina.jsx b/src/paginas/Favoritos.pagina.jsx
deleted file mode 100644
index 5187d1e..0000000
--- a/src/paginas/Favoritos.pagina.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import GrillaPersonajes from "../componentes/personajes/grilla-personajes.componente";
-
-/**
- * Esta es la pagina de favoritos. Aquí se deberan ver todos los personajes marcados como favoritos
- *
- * Uso:
- * ``` ```
- *
- * @returns la pagina de favoritos
- */
-const PaginaFavoritos = () => {
- return
-
-
Personajes Favoritos
-
-
-
-
-}
-
-export default PaginaFavoritos
\ No newline at end of file
diff --git a/src/paginas/Favoritos.pagina.tsx b/src/paginas/Favoritos.pagina.tsx
new file mode 100644
index 0000000..ca229a8
--- /dev/null
+++ b/src/paginas/Favoritos.pagina.tsx
@@ -0,0 +1,55 @@
+import { useEffect } from "react";
+import GrillaPersonajes from "../componentes/personajes/grilla-personajes.componente";
+import { useAppDispatch, useAppSelector } from "../store";
+import { GET_CHARACTERS } from "../store/characters/thunk";
+
+/**
+ * Esta es la pagina de favoritos. Aquí se deberan ver todos los personajes marcados como favoritos
+ *
+ * Uso:
+ * ``` ```
+ *
+ * @returns la pagina de favoritos
+ */
+const PaginaFavoritos = () => {
+ const dispatch = useAppDispatch()
+ const { listFavoritos, urlBase} = useAppSelector((state) => state.characters)
+ useEffect(() => {
+ dispatch(GET_CHARACTERS(urlBase))
+
+ .then((response) => {
+ // Handle a successful API request here
+ console.log("Characters fetched successfully:", response);
+ })
+ .catch((error) => {
+ // Handle API request errors here
+ console.error("Error fetching characters:", error);
+ });
+ }, [dispatch,urlBase]);
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await dispatch(GET_CHARACTERS(urlBase));
+ // Handle a successful API request here
+ console.log("Characters fetched successfully:", response);
+ } catch (error) {
+ // Handle API request errors here
+ console.error("Error fetching characters:", error);
+ }
+ };
+
+ fetchData();
+ }, [dispatch,urlBase]);
+
+
+
+ return
+
+
Personajes Favoritos
+
+
+
+
+}
+
+export default PaginaFavoritos
\ No newline at end of file
diff --git a/src/paginas/Inicio.pagina.jsx b/src/paginas/Inicio.pagina.jsx
deleted file mode 100644
index bb2b011..0000000
--- a/src/paginas/Inicio.pagina.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import Filtros from "../componentes/personajes/filtros.componente"
-import GrillaPersonajes from "../componentes/personajes/grilla-personajes.componente"
-import Paginacion from "../componentes/paginacion/paginacion.componente";
-
-/**
- * Esta es la pagina principal. Aquí se debera ver el panel de filtros junto con la grilla de personajes.
- *
- * Uso:
- * ``` ```
- *
- * @returns la pagina de inicio
- */
-const PaginaInicio = () => {
- return
-
-
Catálogo de Personajes
-
-
-
-
-
-
-
-}
-
-export default PaginaInicio
\ No newline at end of file
diff --git a/src/paginas/Inicio.pagina.tsx b/src/paginas/Inicio.pagina.tsx
new file mode 100644
index 0000000..475a229
--- /dev/null
+++ b/src/paginas/Inicio.pagina.tsx
@@ -0,0 +1,48 @@
+import Filtros from "../componentes/personajes/filtros.componente"
+import GrillaPersonajes from "../componentes/personajes/grilla-personajes.componente"
+import Paginacion from "../componentes/paginacion/paginacion.componente";
+import { useAppDispatch, useAppSelector } from "../store";
+import { useEffect, useRef, useState } from "react";
+import { GET_CHARACTERS } from "../store/characters/thunk";
+
+/**
+ * Esta es la pagina principal. Aquí se debera ver el panel de filtros junto con la grilla de personajes.
+ *
+ * Uso:
+ * ``` ```
+ *
+ * @returns la pagina de inicio
+ */
+
+const PaginaInicio = () => {
+ const dispatch = useAppDispatch()
+ const { allCharacters, urlBase} = useAppSelector((state) => state.characters)
+ const ref = useRef(null)
+
+
+ const [name, setName] = useState('');
+
+ const handleCleanFilter = () =>{
+ setName(null)
+ }
+
+ useEffect(() => {
+ dispatch(GET_CHARACTERS(urlBase));
+ }, [])
+
+ return
+
+
Catálogo de Personajes
+
+k
+
+
+
+
+
+
+
+}
+
+
+export default PaginaInicio
\ No newline at end of file
diff --git a/src/store/characters/slice.ts b/src/store/characters/slice.ts
new file mode 100644
index 0000000..a662436
--- /dev/null
+++ b/src/store/characters/slice.ts
@@ -0,0 +1,130 @@
+import { PayloadAction, createSlice } from '@reduxjs/toolkit';
+import { GET_CHARACTERS, GET_CHARACTERS_FILTER, } from './thunk';
+import { IAllCharacters, ICharacter} from '../../interfaces/character.interface';
+
+
+
+export type CharacterState = {
+urlBase: string
+allCharacters: ICharacter[],
+isLoading: boolean,
+isError: string | null,
+nextPage: string,
+prevPage: string,
+esfavorito: boolean
+listFavoritos: ICharacter[]
+
+}
+
+
+const initialState : CharacterState= {
+ urlBase: 'https://rickandmortyapi.com/api/character/',
+ allCharacters: [],
+ isLoading: true,
+ isError : null,
+ prevPage: '',
+ nextPage: '',
+ esfavorito: false,
+ listFavoritos: []
+}
+
+
+export const charactersSlice = createSlice({
+ name : 'character',
+ initialState: initialState,
+ reducers : {
+ /**
+ * Agrega a favoritos un nuevo personaje agregándolo al estado de la propiedad listfavoritos[]
+ * @author 'Carmen Vargas'
+ * @param { WritableDraft } state
+ * @return {Object} retorna el objeto, personaje agregado al array de favoritos
+ * @param {PayloadAction} action
+ *
+ */
+ ADD_FAVORITOS: (state, action: PayloadAction) => {
+ const personaje = action.payload;
+ const esFavorito = state.listFavoritos.find(
+ (fav) => fav.id === personaje.id
+ );
+ if (esFavorito) {
+ esFavorito.isFavorite = false;
+ state.listFavoritos = state.listFavoritos.filter(
+ (item) => item.id !== esFavorito.id
+ );
+ } else {
+ personaje.isFavorite = true;
+ state.listFavoritos.push(personaje);
+ }
+ },
+
+
+ /**
+ * Limpia el estado del array de favoritos para dejarlo como array vacío
+ * @author 'Carmen Vargas'
+ * @param {WritableDraft} state
+ * @return {Array} retorna un array vacío para el estado de listFavoritos[]
+ */
+ CLEAR_ALL_FAVORITES: (state) => {
+ state.listFavoritos = []
+ }
+
+ },
+ extraReducers : (builder) =>{
+
+ /**
+ * Usa el método GET_CHARACTES para guardar en el estado del array allCharacters además, g
+ * uarda los estados de la página anterior y la siguiente
+ * @author 'Carmen Vargas'
+ * @param { WritableDraft} state
+ * @param {PayloadAction} action
+ * @return {Array} retorna un array de personajes
+ */
+
+ builder.addCase(GET_CHARACTERS.pending, ( state ) => {
+ state.isLoading = true;
+ })
+
+ builder.addCase(GET_CHARACTERS.fulfilled, (state, action : PayloadAction) => {
+ state.allCharacters = action.payload.allCharacters;
+ state.prevPage = action.payload.prevPage
+ state.nextPage = action.payload.nextPage
+ state.isLoading = false;
+ })
+
+ builder.addCase(GET_CHARACTERS.rejected, ( state, action ) => {
+ state.isLoading = false;
+ state.isError = action.error.message ?? 'Ha ocurrido un error'
+
+
+ })
+
+ /**
+ * Usa el método GET_CHARACTES_FILTER para filtrar por nombre. Necesita recibir el nombre buscado que se ingresa en el input.
+ * @author 'Carmen Vargas'
+ * @return {Array} retorna un array de personajes filtrados por nombre de tipo IAllCharacters
+ */
+ builder.addCase(GET_CHARACTERS_FILTER.pending, ( state ) => {
+ state.isLoading = true;
+ })
+
+ builder.addCase(GET_CHARACTERS_FILTER.fulfilled, (state, action : PayloadAction) => {
+ state.allCharacters = action.payload.allCharacters;
+ state.prevPage = action.payload.prevPage
+ state.nextPage = action.payload.nextPage
+ state.isLoading = false;
+ })
+
+ builder.addCase(GET_CHARACTERS_FILTER.rejected, ( state, action ) => {
+ state.isLoading = false;
+ state.isError = action.error.message ?? 'Ha ocurrido un error'
+
+
+ })
+ },
+
+ });
+
+
+const characterReducer = charactersSlice.reducer;
+export const {ADD_FAVORITOS} = charactersSlice.actions;
+export default characterReducer;
diff --git a/src/store/characters/thunk.ts b/src/store/characters/thunk.ts
new file mode 100644
index 0000000..19abd80
--- /dev/null
+++ b/src/store/characters/thunk.ts
@@ -0,0 +1,51 @@
+import {createAsyncThunk} from '@reduxjs/toolkit';
+import { IAllCharacters, ICharacter } from '../../interfaces/character.interface'
+
+export const GET_CHARACTERS = createAsyncThunk(
+ 'character/GET_CHARACTERS',
+ async (urlBase: string): Promise => {
+
+ try {
+ const resp = await fetch(urlBase);
+ const data = await resp.json();
+ const resultsCharacters = {
+ allCharacters: data.results,
+ nextPage: data.info.next,
+ prevPage: data.info.prev
+ }
+ return resultsCharacters;
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ throw error;
+ }
+
+ }
+ );
+
+ export const GET_CHARACTERS_FILTER = createAsyncThunk(
+ 'character/GET_CHARACTERS_FILTER',
+ async ({name}: {name: string | null | undefined}): Promise => {
+
+ try {
+ const resp = await fetch(`https://rickandmortyapi.com/api/character/?name=${name}`)
+ const data = await resp.json();
+ const resultsCharacters: IAllCharacters = {
+ allCharacters: data.results,
+ nextPage: data.info.next,
+ prevPage: data.info.prev
+ }
+ return resultsCharacters;
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ throw error;
+ }
+
+ }
+ );
+
+
+export const GET_CHARACTER_ID = createAsyncThunk('character/GET_CHARACTERS_ID', async (id: number) : Promise=> {
+ const resp = await fetch(`https://rickandmortyapi.com/api/character/${id}`)
+ const data = await resp.json();
+ return data;
+})
\ No newline at end of file
diff --git a/src/store/index.tsx b/src/store/index.tsx
new file mode 100644
index 0000000..8e0eecd
--- /dev/null
+++ b/src/store/index.tsx
@@ -0,0 +1,19 @@
+import { configureStore} from "@reduxjs/toolkit";
+import { TypedUseSelectorHook,useDispatch, useSelector } from "react-redux";
+import characterReducer from "./characters/slice";
+
+const store = configureStore({
+ reducer :{
+ characters: characterReducer,
+ },
+})
+
+// Tipamos el hook useSelector y useDispatch
+export type RootState = ReturnType;
+export type AppDispatch = typeof store.dispatch;
+
+type DispatchFunc = () => AppDispatch;
+
+export const useAppDispatch : DispatchFunc = useDispatch
+export const useAppSelector : TypedUseSelectorHook = useSelector;
+export default store;
\ No newline at end of file