-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add logic to hook * add gh-pages to dev dependencies Co-authored-by: nhatnm <[email protected]>
- Loading branch information
Showing
26 changed files
with
373 additions
and
169 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,118 @@ | ||
# Clean Architecture | ||
<img src="./clean-architecture.webp"/> | ||
<img src="./clean-architecture.png" style="max-width: 800px;"/> | ||
|
||
- ## Folder style ❤️ | ||
## Folder style ❤️ | ||
<pre> | ||
. | ||
├── modules | ||
│ ├── transaction | ||
│ │ ├── apdapter | ||
│ │ │ ├── createTransactionAdapter.ts | ||
│ │ │ └── deleteTransactionApdapter.ts | ||
│ │ ├── presentation | ||
│ │ ├── adapters | ||
│ │ │ ├── index.ts | ||
│ │ │ ├── useCreateTransactionAdapter.ts | ||
│ │ │ ├── useDeleteTransactionAdapter.ts | ||
│ │ │ └── useGetAllTransactionAdapter.ts | ||
│ │ ├── domains | ||
│ │ │ ├── transaction.entity.ts | ||
│ │ │ ├── transaction.model.ts | ||
│ │ │ └── transaction.repository.ts | ||
│ │ ├── presentations | ||
│ │ │ ├── TransactionCreate | ||
│ │ │ │ ├── index.tsx | ||
│ │ │ │ ├── style.css | ||
│ │ │ │ └── TransactionCreate.tsx | ||
│ │ │ └── TransactionList | ||
│ │ │ ├── index.tsx | ||
│ │ │ ├── style.css | ||
│ │ │ ├── TransactionItem.tsx | ||
│ │ │ └── TransactionList.tsx | ||
│ │ ├── use-case | ||
│ │ │ └── spendMoreThanIncomeUseCase.ts | ||
│ │ ├── config.ts | ||
│ │ ├── transaction.entity.ts | ||
│ │ ├── transaction.model.ts | ||
│ │ └── transaction.repository.ts | ||
│ │ │ ├── TransactionList | ||
│ │ │ │ ├── index.tsx | ||
│ │ │ │ ├── style.css | ||
│ │ │ │ ├── TransactionItem.tsx | ||
│ │ │ │ └── TransactionList.tsx | ||
│ │ │ └── .DS_Store | ||
│ │ ├── use-cases | ||
│ │ │ ├── createTransactionUseCase.ts | ||
│ │ │ ├── deleteTransactionUseCase.ts | ||
│ │ │ └── index.ts | ||
│ │ └── helper.ts | ||
│ └── user | ||
│ | ||
├── utils | ||
│ ├── dateUtils.ts | ||
│ ├── dateUtil.ts | ||
│ ├── exceptionUtil.ts | ||
│ └── toastUtil.ts | ||
├── App.test.tsx | ||
├── App.tsx | ||
├── index.css | ||
└── index.tsx | ||
|
||
</pre> | ||
|
||
## Usage 💪 | ||
## Flow 💪 | ||
<img src="./CA-flow.drawio.png" style="max-width: 600px;width:100%"/> | ||
|
||
<img src="./Clean-architecture-usage.png" style="max-width: 400px;"/> | ||
## Usage 🐾 | ||
|
||
1. Presentation | ||
|
||
export default Feature(){ | ||
const {state, handleSomething} = useAdapter() | ||
|
||
--- | ||
- ## Other Folder style 😌 | ||
<pre> | ||
. | ||
├── adapters | ||
├── domain | ||
│ ├── transaction | ||
│ │ ├── transaction.entity.ts | ||
│ │ ├── transaction.model.ts | ||
│ │ └── transaction.repository.ts | ||
│ └── user | ||
├── presentations | ||
│ ├── transaction | ||
│ │ ├── TransactionCreate | ||
│ │ │ ├── style.css | ||
│ │ │ └── TransactionCreate.tsx | ||
│ │ └── TransactionList | ||
│ │ ├── style.css | ||
│ │ ├── TransactionItem.tsx | ||
│ │ └── TransactionList.tsx | ||
│ └── user | ||
├── use-cases | ||
│ ├── transaction | ||
│ │ ├── createTransactionUseCase.ts | ||
│ │ ├── deleteTransactionUseCase.ts | ||
│ │ └── listTransactionUseCase.ts | ||
│ └── user | ||
├── utils | ||
│ ├── exceptionUtil.ts | ||
│ └── toastUtil.ts | ||
├── App.tsx | ||
</pre> | ||
return ( | ||
<button onClick={handleSomething}> | ||
{state} | ||
</button> | ||
) | ||
} | ||
2. Adapter | ||
|
||
import someUseCase from "../use-cases" | ||
export default useAdapter(service: ServiceRepository){ | ||
const [state, setState] = useState(); | ||
|
||
const handleSomething = ()=> { | ||
const result = someUseCase.execute(); | ||
setState(result); | ||
} | ||
return {state, handleSomething} | ||
} | ||
|
||
3. Use case | ||
|
||
import service from "../domain/model" | ||
|
||
export class SomeUseCase { | ||
execute (){ | ||
handleSomeUserStories(); | ||
service.doSomething(); | ||
} | ||
} | ||
|
||
4. Domain | ||
|
||
4.1 Entity | ||
|
||
export interface Something { | ||
id: number; | ||
... | ||
} | ||
|
||
4.2 Repository | ||
|
||
export interface SomethingRepository { | ||
getSomething(): Something; | ||
setSomething(st: Something): Something; | ||
... | ||
} | ||
|
||
4.3 Model | ||
|
||
export class SomethingService implements SomethingRepository { | ||
getSomething(){ | ||
callApi(); | ||
} | ||
|
||
setSomething(st: Something){ | ||
validate(st) | ||
callApi(st) | ||
} | ||
} | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 0 additions & 42 deletions
42
src/modules/transaction/adapters/createTransactionAdapter.ts
This file was deleted.
Oops, something went wrong.
13 changes: 0 additions & 13 deletions
13
src/modules/transaction/adapters/deleteTransactionAdapter.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export * from "./createTransactionAdapter"; | ||
export * from "./deleteTransactionAdapter"; | ||
export * from "./useCreateTransactionAdapter"; | ||
export * from "./useDeleteTransactionAdapter"; |
44 changes: 44 additions & 0 deletions
44
src/modules/transaction/adapters/useCreateTransactionAdapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { useCallback } from 'react'; | ||
import { abortError, notifyError } from 'utils/exceptionUtil'; | ||
import { toastSuccess } from 'utils/toastUtil'; | ||
import { v4 as uuid } from 'uuid'; | ||
import { Transaction } from "../domains/transaction.entity"; | ||
import { TransactionRepository } from '../domains/transaction.repository'; | ||
import CreateTransactionUseCase from '../use-cases/createTransactionUseCase'; | ||
|
||
export const useCreateTransactionAdapter = (transactionService: TransactionRepository) => { | ||
|
||
const convertFormToTransaction = (event: React.ChangeEvent<HTMLFormElement>): Transaction => { | ||
event.preventDefault(); | ||
const formData = new FormData(event.target); | ||
const transactionForm: Transaction = Object.fromEntries(formData.entries()) as unknown as Transaction; | ||
return { | ||
id: uuid(), | ||
amount: Number(transactionForm.amount), | ||
date: transactionForm.date, | ||
description: transactionForm.description, | ||
type: transactionForm.type, | ||
}; | ||
} | ||
|
||
const createTransactionAdapter = useCallback((event: React.ChangeEvent<HTMLFormElement>): boolean => { | ||
try { | ||
// transform data from third party library or framework (e.g. form, etc.) to domain model | ||
const transaction = convertFormToTransaction(event); | ||
const allTransactions = transactionService.getTransactions(); | ||
// execute use case or service | ||
// transform data from domain model to third party library framework or UI (e.g. form, component etc.) | ||
// interact with UI, e.g. show error message, show success message, etc. (not related to state management) | ||
|
||
const createTransactionUseCase = new CreateTransactionUseCase(transactionService); | ||
createTransactionUseCase.execute(transaction); | ||
toastSuccess("Thêm thành công"); | ||
return true | ||
} catch (error) { | ||
notifyError(error); | ||
throw abortError(error); | ||
} | ||
|
||
}, []) | ||
return { createTransactionAdapter } | ||
} |
20 changes: 20 additions & 0 deletions
20
src/modules/transaction/adapters/useDeleteTransactionAdapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { useCallback } from "react"; | ||
import { abortError, notifyError } from "utils/exceptionUtil"; | ||
import { toastSuccess } from "utils/toastUtil"; | ||
import { TransactionRepository } from "../domains/transaction.repository"; | ||
import DeleteTransactionUseCase from "../use-cases/deleteTransactionUseCase"; | ||
|
||
|
||
export const useDeleteTransactionAdapter = (transactionService: TransactionRepository) => { | ||
const deleteTransactionAdapter =useCallback((id: string): void => { | ||
try { | ||
const deleteTransactionUseCase = new DeleteTransactionUseCase(transactionService); | ||
deleteTransactionUseCase.execute(id); | ||
toastSuccess("Xóa thành công"); | ||
} catch (error) { | ||
notifyError(error); | ||
throw abortError(error); | ||
} | ||
}, []) | ||
return { deleteTransactionAdapter } | ||
} |
22 changes: 22 additions & 0 deletions
22
src/modules/transaction/adapters/useGetAllTransactionAdapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useCallback, useEffect, useState } from "react"; | ||
import { Transaction } from "../domains/transaction.entity"; | ||
import { TransactionRepository } from "../domains/transaction.repository"; | ||
|
||
export default function useGetTransactionAdapter(transactionRepo: TransactionRepository) { | ||
const [allTransactions, setAllTransactions] = useState<Transaction[]>([]); | ||
|
||
const loadTransactions = useCallback(() => { | ||
const transactions = transactionRepo.getTransactions().reverse(); | ||
if (transactions) { | ||
setAllTransactions(transactions); | ||
} else { | ||
setAllTransactions([]); | ||
} | ||
}, []); | ||
|
||
useEffect(() => { | ||
loadTransactions(); | ||
}, [loadTransactions]); | ||
|
||
return { allTransactions, loadTransactions } | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.