diff --git a/src/Data/DataSources/Todo/TodoLocalStorageDataSource.ts b/src/Data/DataSources/Todo/TodoLocalStorageDataSource.ts index e6e9827..1be9630 100644 --- a/src/Data/DataSources/Todo/TodoLocalStorageDataSource.ts +++ b/src/Data/DataSources/Todo/TodoLocalStorageDataSource.ts @@ -2,7 +2,7 @@ import { TodoDataSource } from "../../../Data/DataSources/Todo/TodoDataSource"; import { Todo } from "../../../Domain/Models/Todo"; export class TodoLocalStorageDataSource implements TodoDataSource { - STORAGE_KEY = "Todos"; + private STORAGE_KEY = "Todos"; async getTodos() { return new Promise((resolve) => { @@ -26,12 +26,12 @@ export class TodoLocalStorageDataSource implements TodoDataSource { }); } - getItems() { + private getItems() { const raw = localStorage.getItem(this.STORAGE_KEY); return raw === null ? [] : JSON.parse(raw); } - setItems(items: Todo[]) { + private setItems(items: Todo[]) { localStorage.setItem(this.STORAGE_KEY, JSON.stringify(items)); } } diff --git a/src/Domain/UseCases/useClearTodos.ts b/src/Domain/UseCases/useClearTodos.ts index ed2ac98..f1e5318 100644 --- a/src/Domain/UseCases/useClearTodos.ts +++ b/src/Domain/UseCases/useClearTodos.ts @@ -1,12 +1,13 @@ -import { TodoRepositoryImpl } from "../../Data/Repositories/TodoRepositoryImpl"; import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useAppServicesContainer } from "../../Services/AppServicesContainer"; import { useNotification } from "../../Services/useNotification"; -export const useClearTodos = (repository: TodoRepositoryImpl) => { +export const useClearTodos = () => { + const { todoRepository } = useAppServicesContainer() const notify = useNotification(); const queryClient = useQueryClient(); const clearTodos = useMutation({ - mutationFn: () => repository.clearTodos(), + mutationFn: () => todoRepository.clearTodos(), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["todos"] }); notify.success("Cleared Correctly!"); diff --git a/src/Domain/UseCases/useCreateTodo.ts b/src/Domain/UseCases/useCreateTodo.ts index 3753b21..f7ba21b 100644 --- a/src/Domain/UseCases/useCreateTodo.ts +++ b/src/Domain/UseCases/useCreateTodo.ts @@ -1,16 +1,17 @@ -import { Todo } from "../../Domain/Models/Todo"; -import { TodoRepositoryImpl } from "../../Data/Repositories/TodoRepositoryImpl"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { useNotification } from "../../Services/useNotification"; +import { Todo } from "../../Domain/Models/Todo"; +import { useAppServicesContainer } from "../../Services/AppServicesContainer"; import { useLogger } from "../../Services/useLogger"; +import { useNotification } from "../../Services/useNotification"; -export const useCreateTodo = (repository: TodoRepositoryImpl) => { +export const useCreateTodo = () => { + const { todoRepository } = useAppServicesContainer() const logger = useLogger(); const notify = useNotification(); const queryClient = useQueryClient(); const createTodo = useMutation({ - mutationFn: (todo: Omit) => repository.createTodo(todo), + mutationFn: (todo: Omit) => todoRepository.createTodo(todo), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["todos"] }); notify.success("Created Correctly!"); diff --git a/src/Domain/UseCases/useFetchTodos.ts b/src/Domain/UseCases/useFetchTodos.ts index fc2c1a6..39587d6 100644 --- a/src/Domain/UseCases/useFetchTodos.ts +++ b/src/Domain/UseCases/useFetchTodos.ts @@ -1,11 +1,12 @@ -import { Todo } from "../../Domain/Models/Todo"; import { useQuery } from "@tanstack/react-query"; -import { TodoRepositoryImpl } from "../../Data/Repositories/TodoRepositoryImpl"; +import { Todo } from "../../Domain/Models/Todo"; +import { useAppServicesContainer } from "../../Services/AppServicesContainer"; -export const useFetchTodos = (repository: TodoRepositoryImpl) => { +export const useFetchTodos = () => { + const { todoRepository } = useAppServicesContainer() const { data, isLoading } = useQuery({ queryKey: ["todos"], - queryFn: () => repository.getTodos(), + queryFn: () => todoRepository.getTodos(), }); return { diff --git a/src/Domain/UseCases/useFetchUsers.ts b/src/Domain/UseCases/useFetchUsers.ts index 3e1ff8f..a313a46 100644 --- a/src/Domain/UseCases/useFetchUsers.ts +++ b/src/Domain/UseCases/useFetchUsers.ts @@ -1,11 +1,12 @@ -import { User } from "../../Domain/Models/User"; import { useQuery } from "@tanstack/react-query"; -import { UserRepositoryImpl } from "../../Data/Repositories/UserRepositoryImpl"; +import { User } from "../../Domain/Models/User"; +import { useAppServicesContainer } from "../../Services/AppServicesContainer"; -export const useFetchUsers = (repository: UserRepositoryImpl) => { +export const useFetchUsers = () => { + const { userRepository } = useAppServicesContainer() const { data, isLoading, isError, isSuccess } = useQuery({ queryKey: ["users"], - queryFn: () => repository.getUsers(), + queryFn: () => userRepository.getUsers(), }); return { diff --git a/src/Presentation/Todo/CreateTodoForm.tsx b/src/Presentation/Todo/CreateTodoForm.tsx index 97e7e1d..20059da 100644 --- a/src/Presentation/Todo/CreateTodoForm.tsx +++ b/src/Presentation/Todo/CreateTodoForm.tsx @@ -1,22 +1,16 @@ import * as React from "react"; +import { useClearTodos } from "../../Domain/UseCases/useClearTodos"; import { useCreateTodo } from "../../Domain/UseCases/useCreateTodo"; -import { TodoRepositoryImpl } from "../../Data/Repositories/TodoRepositoryImpl"; -import { TodoLocalStorageDataSource } from "../../Data/DataSources/Todo/TodoLocalStorageDataSource"; import { useNotification } from "../../Services/useNotification"; -import { useClearTodos } from "../../Domain/UseCases/useClearTodos"; export function CreateTodoForm() { const notify = useNotification(); const inputRef = React.useRef(null); const formRef = React.useRef(null); - const createTodo = useCreateTodo( - new TodoRepositoryImpl(new TodoLocalStorageDataSource()) - ); + const createTodo = useCreateTodo(); - const clearTodos = useClearTodos( - new TodoRepositoryImpl(new TodoLocalStorageDataSource()) - ); + const clearTodos = useClearTodos(); const handleCreate = async () => { const title = inputRef.current?.value; diff --git a/src/Presentation/Todo/TodoList.tsx b/src/Presentation/Todo/TodoList.tsx index 353db3e..60e2253 100644 --- a/src/Presentation/Todo/TodoList.tsx +++ b/src/Presentation/Todo/TodoList.tsx @@ -1,11 +1,7 @@ import { useFetchTodos } from "../../Domain/UseCases/useFetchTodos"; -import { TodoRepositoryImpl } from "../../Data/Repositories/TodoRepositoryImpl"; -import { TodoLocalStorageDataSource } from "../../Data/DataSources/Todo/TodoLocalStorageDataSource"; export function TodoList() { - const { todos, isFetchTodosLoading } = useFetchTodos( - new TodoRepositoryImpl(new TodoLocalStorageDataSource()) - ); + const { todos, isFetchTodosLoading } = useFetchTodos(); return (
diff --git a/src/Presentation/User/UserList.tsx b/src/Presentation/User/UserList.tsx index d22d067..cd0d17c 100644 --- a/src/Presentation/User/UserList.tsx +++ b/src/Presentation/User/UserList.tsx @@ -1,11 +1,7 @@ -import { UserRepositoryImpl } from "../../Data/Repositories/UserRepositoryImpl"; -import { UserDataSourceImpl } from "../../Data/DataSources/User/UserAPIDataSource"; import { useFetchUsers } from "../../Domain/UseCases/useFetchUsers"; export function UserList() { - const { users, isFetchUsersLoading, isFetchUsersSuccess } = useFetchUsers( - new UserRepositoryImpl(new UserDataSourceImpl()) - ); + const { users, isFetchUsersLoading, isFetchUsersSuccess } = useFetchUsers(); return (
diff --git a/src/Services/AppServicesContainer.tsx b/src/Services/AppServicesContainer.tsx new file mode 100644 index 0000000..671636c --- /dev/null +++ b/src/Services/AppServicesContainer.tsx @@ -0,0 +1,28 @@ +import { createContext, useContext } from 'react'; +import { TodoLocalStorageDataSource } from '../Data/DataSources/Todo/TodoLocalStorageDataSource'; +import { UserDataSourceImpl } from '../Data/DataSources/User/UserAPIDataSource'; + +const SERVICES = { + todoRepository: new TodoLocalStorageDataSource(), // Need to inject another dep ? easy, new TodoDataSourceImpl(), no need to change in anywhere else, you just need to make sure your new dep are following the same Interface, in this case: TodoDataSource. + userRepository: new UserDataSourceImpl() +}; + +const AppServicesContainer = createContext(undefined); + +const AppServicesContainerProvider = ({ children }: { children: JSX.Element }) => ( + {children} +); + +const useAppServicesContainer = () => { + const ctx = useContext(AppServicesContainer); + + if (!ctx) + throw new Error( + "It's seems you've tryied to use useAppServicesContainer hook outside " + ); + + return ctx; +}; + +export { useAppServicesContainer, AppServicesContainerProvider }; + diff --git a/src/index.tsx b/src/index.tsx index ba5933b..a4bea01 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,10 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import React from "react"; import ReactDOM from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { TodosPage } from "./Presentation/UI/Pages/TodosPage"; import { UsersPage } from "./Presentation/UI/Pages/UsersPage"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { AppServicesContainerProvider } from "./Services/AppServicesContainer"; const queryClient = new QueryClient(); @@ -20,8 +21,10 @@ const router = createBrowserRouter([ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - + + + + + );