@pplancq/react-template 2.8.16 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/_README.md +57 -52
- package/mise.toml +2 -2
- package/package.json +28 -27
- package/scripts/removeDemo.cjs +105 -66
- package/src/README.md +81 -0
- package/src/app/App.tsx +18 -0
- package/src/{bootstrap.tsx → app/AppHTMLElement.tsx} +2 -2
- package/src/app/README.md +69 -0
- package/src/{__tests__/bootstraps.test.tsx → app/__tests__/AppHTMLElement.test.tsx} +5 -5
- package/src/app/config/serviceContainer.ts +6 -0
- package/src/app/providers/Providers/Providers.tsx +18 -0
- package/src/{providers → app/providers}/QueryClientProvider/QueryClientProvider.tsx +3 -3
- package/src/app/providers/ServiceProvider/ServiceContext.ts +8 -0
- package/src/app/providers/ServiceProvider/ServiceProvider.tsx +14 -0
- package/src/app/routing/Router.tsx +14 -0
- package/src/app/routing/appRoutes.ts +3 -0
- package/src/app/routing/routes.tsx +9 -0
- package/src/demo/README.md +148 -0
- package/src/demo/application/dtos/ArchitecturePrinciple.ts +5 -0
- package/src/{types/profileTypes.ts → demo/application/dtos/ProfileFormValues.ts} +1 -1
- package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCase.ts +11 -0
- package/src/demo/application/use-cases/GetArchitecturePrinciplesUseCaseInterface.ts +5 -0
- package/src/demo/application/use-cases/GetDemoUsersUseCase.ts +11 -0
- package/src/demo/application/use-cases/GetDemoUsersUseCaseInterface.ts +5 -0
- package/src/demo/domain/entities/DemoUser.ts +7 -0
- package/src/demo/domain/repositories/ArchitecturePrincipleRepositoryInterface.d.ts +5 -0
- package/src/demo/domain/repositories/DemoUserRepositoryInterface.d.ts +5 -0
- package/src/demo/infrastructure/repositories/HttpDemoUserRepository.ts +29 -0
- package/src/demo/infrastructure/repositories/StaticArchitecturePrincipleRepository.ts +33 -0
- package/src/demo/serviceDemo.ts +39 -0
- package/src/demo/serviceIdentifiers.ts +6 -0
- package/src/demo/ui/components/DemoFooter/DemoFooter.tsx +17 -0
- package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/Footer.test.tsx +2 -2
- package/src/{components/Footer → demo/ui/components/DemoFooter}/__tests__/__snapshots__/Footer.test.tsx.snap +3 -3
- package/src/demo/ui/components/DemoFooter/index.ts +1 -0
- package/src/demo/ui/components/DemoHeader/DemoHeader.tsx +25 -0
- package/src/{components/Header → demo/ui/components/DemoHeader}/__tests__/Header.test.tsx +2 -2
- package/src/demo/ui/components/DemoHeader/__tests__/__snapshots__/Header.test.tsx.snap +64 -0
- package/src/demo/ui/components/DemoHeader/index.ts +1 -0
- package/src/{ui/molecules/Navigation/Navigation.tsx → demo/ui/components/DemoNavigation/DemoNavigation.tsx} +4 -4
- package/src/demo/ui/components/DemoNavigation/index.ts +1 -0
- package/src/{components → demo/ui/components}/TextInput/TextInput.tsx +3 -3
- package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.tsx +7 -7
- package/src/demo/ui/hooks/useDemoUsersQuery/useDemoUsersQuery.ts +13 -0
- package/src/demo/ui/layouts/DemoLayout/DemoLayout.tsx +12 -0
- package/src/demo/ui/layouts/MainTemplate/MainTemplate.module.css +21 -0
- package/src/{ui/templates → demo/ui/layouts}/MainTemplate/MainTemplate.tsx +7 -7
- package/src/demo/ui/pages/DemoHome/DemoHome.tsx +117 -0
- package/src/demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.tsx +47 -0
- package/src/{pages/Demo → demo/ui/pages}/ReactHookFormDemo/ReactHookFormDemo.tsx +7 -7
- package/src/demo/ui/pages/ReactQueryDemo/ReactQueryDemo.module.scss +38 -0
- package/src/{pages/Demo → demo/ui/pages}/ReactQueryDemo/ReactQueryDemo.tsx +5 -4
- package/src/demo/ui/routing/demoAppRoutes.ts +6 -0
- package/src/demo/ui/routing/demoRoutes.tsx +31 -0
- package/src/main.ts +2 -2
- package/src/shared/README.md +53 -0
- package/src/shared/application/README.md +49 -0
- package/src/shared/domain/README.md +52 -0
- package/src/shared/infrastructure/README.md +51 -0
- package/src/{api → shared/infrastructure/http}/fetchApi.ts +1 -1
- package/src/shared/ui/README.md +50 -0
- package/src/shared/ui/hooks/useService/useService.ts +13 -0
- package/tsconfig.json +3 -1
- package/vitest.config.mts +5 -1
- package/src/api/README.md +0 -65
- package/src/api/demoApi.ts +0 -10
- package/src/assets/README.md +0 -54
- package/src/components/App/App.tsx +0 -18
- package/src/components/App/index.ts +0 -1
- package/src/components/Footer/Footer.tsx +0 -16
- package/src/components/Footer/index.ts +0 -1
- package/src/components/Header/Header.tsx +0 -17
- package/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +0 -37
- package/src/components/Header/index.ts +0 -1
- package/src/components/README.md +0 -33
- package/src/config/README.md +0 -63
- package/src/config/index.ts +0 -1
- package/src/forms/README.md +0 -142
- package/src/hooks/README.md +0 -83
- package/src/hooks/api/queryKey.ts +0 -1
- package/src/hooks/api/useDemoApi.ts +0 -16
- package/src/pages/Demo/Demo.tsx +0 -236
- package/src/pages/Demo/ReactHookFormDemo/index.ts +0 -1
- package/src/pages/Demo/ReactHookFormDemo/routes.tsx +0 -7
- package/src/pages/Demo/ReactQueryDemo/index.ts +0 -1
- package/src/pages/Demo/ReactQueryDemo/routes.tsx +0 -7
- package/src/pages/Demo/__tests__/Demo.test.tsx +0 -15
- package/src/pages/Demo/__tests__/__snapshots__/Demo.test.tsx.snap +0 -557
- package/src/pages/Demo/index.ts +0 -1
- package/src/pages/Demo/routes.tsx +0 -8
- package/src/pages/Layout/Layout.tsx +0 -12
- package/src/pages/Layout/index.ts +0 -1
- package/src/pages/README.md +0 -91
- package/src/pages/UnexpectedError/UnexpectedError.module.css +0 -8
- package/src/pages/UnexpectedError/UnexpectedError.tsx +0 -22
- package/src/pages/UnexpectedError/index.ts +0 -1
- package/src/providers/QueryClientProvider/index.ts +0 -1
- package/src/providers/README.md +0 -112
- package/src/providers/index.ts +0 -1
- package/src/providers/withProviders/index.ts +0 -1
- package/src/providers/withProviders/withProviders.tsx +0 -18
- package/src/routing/README.md +0 -76
- package/src/routing/appRoutes.ts +0 -5
- package/src/routing/routerFactory.ts +0 -12
- package/src/routing/routes.tsx +0 -13
- package/src/types/README.md +0 -62
- package/src/types/demoApi.ts +0 -25
- package/src/ui/README.md +0 -144
- package/src/ui/molecules/Navigation/index.ts +0 -1
- package/src/ui/organisms/Footer/Footer.module.css +0 -10
- package/src/ui/organisms/Footer/Footer.tsx +0 -10
- package/src/ui/organisms/Footer/index.ts +0 -1
- package/src/ui/organisms/Header/Header.module.css +0 -17
- package/src/ui/organisms/Header/Header.tsx +0 -16
- package/src/ui/organisms/Header/index.ts +0 -1
- package/src/ui/organisms/MainContent/MainContent.module.css +0 -3
- package/src/ui/organisms/MainContent/MainContent.tsx +0 -6
- package/src/ui/organisms/MainContent/index.ts +0 -1
- package/src/ui/templates/MainTemplate/MainTemplate.module.css +0 -5
- package/src/utils/README.md +0 -70
- /package/src/{assets → app/assets}/css/index.ts +0 -0
- /package/src/{assets → app/assets}/css/mainBody.css +0 -0
- /package/src/{assets → app/assets}/css/reset.css +0 -0
- /package/src/{config → app/config}/queryClientConfig.ts +0 -0
- /package/src/{assets → demo/ui/assets}/images/logo.png +0 -0
- /package/src/{assets → demo/ui/assets}/images/templatePlugins.png +0 -0
- /package/src/{components/Footer/Footer.module.css → demo/ui/components/DemoFooter/DemoFooter.module.css} +0 -0
- /package/src/{components/Header/Header.module.css → demo/ui/components/DemoHeader/DemoHeader.module.css} +0 -0
- /package/src/{ui/molecules/Navigation/Navigation.module.css → demo/ui/components/DemoNavigation/DemoNavigation.module.css} +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/Input.module.scss +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/Input.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Input/index.ts +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.module.css +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/Logo.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/__tests__/Logo.test.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/Logo/index.ts +0 -0
- /package/src/{ui/atoms → demo/ui/components}/NavLink/NavLink.tsx +0 -0
- /package/src/{ui/atoms → demo/ui/components}/NavLink/index.ts +0 -0
- /package/src/{components → demo/ui/components}/TextInput/index.ts +0 -0
- /package/src/{forms → demo/ui/forms}/ProfileForm/ProfileForm.module.scss +0 -0
- /package/src/{forms → demo/ui/forms}/ProfileForm/index.ts +0 -0
- /package/src/{ui/templates → demo/ui/layouts}/MainTemplate/index.ts +0 -0
- /package/src/{pages/Demo/Demo.module.scss → demo/ui/pages/DemoHome/DemoHome.module.scss} +0 -0
- /package/src/{pages/Demo/ReactQueryDemo/ReactQueryDemo.module.scss → demo/ui/pages/DependencyInjectionDemo/DependencyInjectionDemo.module.scss} +0 -0
- /package/src/{pages/Demo/ReactHookFormDemo/ReactHookFormDemo.module.css → demo/ui/pages/ReactHookFormDemo/ReactHookFormDemo.module.scss} +0 -0
- /package/src/{api → shared/infrastructure/http}/constant.ts +0 -0
- /package/src/{types/api.ts → shared/infrastructure/http/fetchApi.type.d.ts} +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# `shared/domain`
|
|
2
|
+
|
|
3
|
+
The `shared/domain` folder contains the **innermost layer** of the shared kernel — the most protected, most
|
|
4
|
+
stable, and most dependency-free part of the codebase.
|
|
5
|
+
|
|
6
|
+
## What the domain layer represents
|
|
7
|
+
|
|
8
|
+
In Clean Architecture, the **domain layer** is the heart of the application. It captures the business rules and
|
|
9
|
+
invariants that would still be true even if you replaced the database, the HTTP client, or the UI framework.
|
|
10
|
+
|
|
11
|
+
In DDD terms, the domain layer hosts:
|
|
12
|
+
|
|
13
|
+
- **Entities** — objects with a stable identity that persists across state changes (e.g., `User`, `Order`).
|
|
14
|
+
- **Value Objects** — immutable objects defined entirely by their attributes, with no identity (e.g., `Email`,
|
|
15
|
+
`Money`, `DateRange`). Two value objects with the same attributes are equal.
|
|
16
|
+
- **Domain Services** — stateless operations that belong to the domain but do not fit naturally on a single
|
|
17
|
+
entity.
|
|
18
|
+
- **Repository Interfaces** — contracts that define _what_ data access operations exist, without specifying
|
|
19
|
+
_how_ they are implemented. The concrete implementation lives in `infrastructure`.
|
|
20
|
+
- **Domain Errors** — typed, domain-meaningful error cases.
|
|
21
|
+
|
|
22
|
+
## Absolute constraints
|
|
23
|
+
|
|
24
|
+
This layer must have **zero external dependencies**:
|
|
25
|
+
|
|
26
|
+
| Forbidden | Why |
|
|
27
|
+
| ---------------------- | ----------------------------------------------- |
|
|
28
|
+
| React / JSX | Domain must not know how it is rendered |
|
|
29
|
+
| Inversify / decorators | DI is an infrastructure concern |
|
|
30
|
+
| HTTP / fetch / axios | I/O belongs to infrastructure |
|
|
31
|
+
| Browser APIs | Domain must run anywhere (browser, Node, tests) |
|
|
32
|
+
| External NPM packages | Brings in coupling and upgrade risk |
|
|
33
|
+
|
|
34
|
+
Only plain TypeScript (interfaces, types, classes, functions, constants) belongs here.
|
|
35
|
+
|
|
36
|
+
## Difference between `shared/domain` and a context's own domain
|
|
37
|
+
|
|
38
|
+
`shared/domain` is the shared kernel's domain — only types or interfaces that are **genuinely used by more
|
|
39
|
+
than one bounded context**. If a domain concept belongs only to `demo`, it lives in `demo/domain`.
|
|
40
|
+
|
|
41
|
+
## What you can put here
|
|
42
|
+
|
|
43
|
+
- Shared pure interfaces and type aliases
|
|
44
|
+
- Value-object-like primitives reused across contexts
|
|
45
|
+
- Shared domain error types
|
|
46
|
+
- Repository interface contracts shared by multiple contexts (rare)
|
|
47
|
+
|
|
48
|
+
## What you should not put here
|
|
49
|
+
|
|
50
|
+
- Anything with an `import` statement that references React, Inversify, or external libraries
|
|
51
|
+
- Demo-specific entities or repository interfaces
|
|
52
|
+
- Speculative types added "just in case" they might be needed later
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# `shared/infrastructure`
|
|
2
|
+
|
|
3
|
+
The `shared/infrastructure` folder contains **technical adapters and concrete implementations** that can be
|
|
4
|
+
reused across bounded contexts.
|
|
5
|
+
|
|
6
|
+
## What the infrastructure layer represents
|
|
7
|
+
|
|
8
|
+
In Clean Architecture, **infrastructure** is the outermost ring alongside UI. It is the layer that deals with
|
|
9
|
+
the real world: databases, HTTP APIs, browser storage, timers, external SDKs, and so on.
|
|
10
|
+
|
|
11
|
+
The key principle at work here is the **Dependency Inversion Principle (DIP)**:
|
|
12
|
+
|
|
13
|
+
> High-level modules (domain, application) should not depend on low-level modules (infrastructure). Both
|
|
14
|
+
> should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.
|
|
15
|
+
|
|
16
|
+
In practice this means:
|
|
17
|
+
|
|
18
|
+
- The **domain** defines a `UserRepositoryInterface` describing what it needs ("give me a user by ID").
|
|
19
|
+
- The **infrastructure** provides the concrete `HttpUserRepository` that knows _how_ to fetch the user.
|
|
20
|
+
- The domain and application layers never import `HttpUserRepository` directly — they work through the
|
|
21
|
+
interface. The DI container wires the concrete class to the interface at startup.
|
|
22
|
+
|
|
23
|
+
This **Ports and Adapters** pattern (also called Hexagonal Architecture) makes the domain fully testable in
|
|
24
|
+
isolation and lets you swap a real HTTP repository for a mock without touching any business logic.
|
|
25
|
+
|
|
26
|
+
## What you can put here
|
|
27
|
+
|
|
28
|
+
- Generic HTTP helpers and API client wrappers (e.g., `fetchApi`)
|
|
29
|
+
- Shared persistence adapters (local storage wrappers, IndexedDB helpers)
|
|
30
|
+
- Generic caching utilities
|
|
31
|
+
- Third-party SDK wrappers that multiple contexts share
|
|
32
|
+
- Base classes for repositories or adapters
|
|
33
|
+
|
|
34
|
+
## What you should not put here
|
|
35
|
+
|
|
36
|
+
- Feature-specific repositories or adapters (those belong in the bounded context's `infrastructure` folder)
|
|
37
|
+
- UI code, React components, or hooks
|
|
38
|
+
- Business rules or domain objects
|
|
39
|
+
|
|
40
|
+
## In this starter
|
|
41
|
+
|
|
42
|
+
The `http/` sub-folder holds a generic `fetchApi` helper used by the demo's HTTP repositories. It lives in
|
|
43
|
+
`shared/infrastructure` (not in `demo`) because the helper itself is context-agnostic — any bounded context
|
|
44
|
+
could use it to call an HTTP API.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
shared/infrastructure/http/
|
|
48
|
+
├── fetchApi.ts ← generic HTTP adapter
|
|
49
|
+
├── fetchApi.type.d.ts ← request/response type definitions
|
|
50
|
+
└── constant.ts ← HTTP-layer constants
|
|
51
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# `shared/ui`
|
|
2
|
+
|
|
3
|
+
The `shared/ui` folder contains **UI-layer code that is genuinely reusable across bounded contexts** — hooks,
|
|
4
|
+
utilities, and components that carry no feature identity.
|
|
5
|
+
|
|
6
|
+
## What the UI layer represents
|
|
7
|
+
|
|
8
|
+
In Clean Architecture, the **UI layer** is the outermost ring. Its job is to:
|
|
9
|
+
|
|
10
|
+
- Present data to the user
|
|
11
|
+
- Translate user actions into application-layer calls (use cases)
|
|
12
|
+
- Never execute business logic or call infrastructure directly
|
|
13
|
+
|
|
14
|
+
The UI layer depends on the application layer (via use cases and DTOs) and occasionally on domain types.
|
|
15
|
+
It must **never** import from `infrastructure`.
|
|
16
|
+
|
|
17
|
+
## What belongs here
|
|
18
|
+
|
|
19
|
+
### `hooks/useService`
|
|
20
|
+
|
|
21
|
+
`useService` is the bridge between the Inversify DI container and React components:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
const myService = useService<MyServiceInterface>(SERVICE_IDENTIFIER);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It reads the container from `ServiceContext` (provided by `ServiceProvider` in `app/providers`) and resolves
|
|
28
|
+
the requested service. This pattern means React components declare _what they need_ without knowing _how it is
|
|
29
|
+
constructed_. Swapping a real implementation for a test double requires only a different container binding —
|
|
30
|
+
zero changes to the component.
|
|
31
|
+
|
|
32
|
+
`useService` lives in `shared/ui` because any bounded context can use it to resolve its own services.
|
|
33
|
+
|
|
34
|
+
## Dependency rules
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
shared/ui
|
|
38
|
+
✅ can import from: shared/domain, shared/application
|
|
39
|
+
❌ must NOT import from: shared/infrastructure
|
|
40
|
+
❌ must NOT import from: any bounded context
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The UI layer must not call infrastructure directly — if it needs external data it does so through a use case or
|
|
44
|
+
React Query integration, not by importing an HTTP adapter.
|
|
45
|
+
|
|
46
|
+
## What you should not put here
|
|
47
|
+
|
|
48
|
+
- Demo-specific visual components (buttons, forms, layouts, logos, nav links)
|
|
49
|
+
- Feature-specific React hooks
|
|
50
|
+
- Infrastructure adapters or API calls
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ServiceContext } from '@App/providers/ServiceProvider/ServiceContext';
|
|
2
|
+
import type { ServiceIdentifier } from 'inversify';
|
|
3
|
+
import { useContext } from 'react';
|
|
4
|
+
|
|
5
|
+
export const useService = <T = unknown>(serviceIdentifier: ServiceIdentifier<T>): T => {
|
|
6
|
+
const context = useContext(ServiceContext);
|
|
7
|
+
|
|
8
|
+
if (!context) {
|
|
9
|
+
throw new Error('useService must be used within a ServiceProvider');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return context.container.get<T>(serviceIdentifier);
|
|
13
|
+
};
|
package/tsconfig.json
CHANGED
package/vitest.config.mts
CHANGED
|
@@ -18,7 +18,11 @@ export default defineConfig(({ mode }) => {
|
|
|
18
18
|
environment: 'jsdom',
|
|
19
19
|
setupFiles: 'vitest.setup.ts',
|
|
20
20
|
clearMocks: true,
|
|
21
|
-
css:
|
|
21
|
+
css: {
|
|
22
|
+
modules: {
|
|
23
|
+
classNameStrategy: 'non-scoped',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
22
26
|
reporters: ['default', 'junit', 'vitest-sonar-reporter'],
|
|
23
27
|
outputFile: {
|
|
24
28
|
'vitest-sonar-reporter': 'sonar-report.xml',
|
package/src/api/README.md
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# 📁 api
|
|
2
|
-
|
|
3
|
-
The "api" folder is designed to handle calls to native APIs using the fetch function. These calls are essential for retrieving real-time data from external sources, such as remote servers or web services.
|
|
4
|
-
|
|
5
|
-
## 📑 Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Folder Organization](#folder-organization)
|
|
8
|
-
- [Usage](#usage)
|
|
9
|
-
- [Error Handling](#error-handling)
|
|
10
|
-
- [Security](#security)
|
|
11
|
-
- [Documentation](#documentation)
|
|
12
|
-
- [Testing](#testing)
|
|
13
|
-
- [Best Practice](#best-practice)
|
|
14
|
-
|
|
15
|
-
## <span id="folder-organization">Folder Organization</span>
|
|
16
|
-
|
|
17
|
-
The "api" folder can be organized as follows :
|
|
18
|
-
|
|
19
|
-
1. **API Endpoints** : Create a separate file for each API you are calling. For example, if you have a user management API and a data retrieval API, you can have the files `users.ts` and `data.ts` to handle these respective calls.
|
|
20
|
-
|
|
21
|
-
2. **Call Functions** : Inside each API file, define dedicated functions to make `fetch` requests to the corresponding endpoints. These functions can also include handling responses and errors.
|
|
22
|
-
|
|
23
|
-
## <span id="usage">🧑🏻💻 Usage</span>
|
|
24
|
-
|
|
25
|
-
When you need to make a call to a native API, import the appropriate function from the "api" folder into your code. For example:
|
|
26
|
-
|
|
27
|
-
```javascript
|
|
28
|
-
import { getUsers } from '@Front/api/users';
|
|
29
|
-
|
|
30
|
-
const users = getUsers();
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## <span id="error-handling">Error Handling</span>
|
|
34
|
-
|
|
35
|
-
Ensure proper error handling in your API call functions. You can use error handling mechanisms such as promises or `try/catch` to capture and handle potential errors when making API calls.
|
|
36
|
-
|
|
37
|
-
## <span id="security">Security</span>
|
|
38
|
-
|
|
39
|
-
Be mindful of security when interacting with external APIs. Avoid storing sensitive information, such as API keys, directly in your source code. Use environment variables or external configuration files to manage this sensitive information securely.
|
|
40
|
-
|
|
41
|
-
## <span id="documentation">Documentation</span>
|
|
42
|
-
|
|
43
|
-
Document each API call function, specifying expected parameters, possible responses, and any relevant information about the API itself.
|
|
44
|
-
|
|
45
|
-
## <span id="testing">Testing</span>
|
|
46
|
-
|
|
47
|
-
Whenever possible, write unit tests to validate the behavior of API call functions. This will ensure that API calls work correctly and quickly detect potential issues.
|
|
48
|
-
|
|
49
|
-
## <span id="best-practice">🎖️ Best Practice</span>
|
|
50
|
-
|
|
51
|
-
It is recommended to implement a custom fetch function that serves as an enhancement or override of the default fetch function. This can be particularly useful for incorporating common configurations, such as adding headers like an API token.
|
|
52
|
-
|
|
53
|
-
Consider the following example of a custom fetch function :
|
|
54
|
-
|
|
55
|
-
```javascript
|
|
56
|
-
// Custom fetch function with common configurations
|
|
57
|
-
export const fetchApi = (uri, options) => {
|
|
58
|
-
const headers = new Headers(options.headers ?? []);
|
|
59
|
-
headers.append('x-api-key', '<token-api>');
|
|
60
|
-
|
|
61
|
-
return fetch(uri, { ...options, headers });
|
|
62
|
-
};
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
In this example, the fetchApi function extends the default fetch function by automatically including an API token in the request header. This practice helps centralize common configurations and promotes consistency across your application.
|
package/src/api/demoApi.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { fetchApi } from '@Front/api/fetchApi';
|
|
2
|
-
import type { Users } from '@Front/types/demoApi';
|
|
3
|
-
|
|
4
|
-
export const fetchDemoApi = async () => {
|
|
5
|
-
const users = await fetchApi<Users>({
|
|
6
|
-
path: 'https://jsonplaceholder.typicode.com/users',
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
return users.map(user => ({ ...user, username: user.username.toUpperCase(), email: user.email.toLowerCase() }));
|
|
10
|
-
};
|
package/src/assets/README.md
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# 📁 assets
|
|
2
|
-
|
|
3
|
-
The "assets" folder is a commonly used directory in a React application to store static resources such as images, CSS files, fonts, JSON data files, icons, and other non-JavaScript files used in your application. These resources are typically needed to style and customize the user interface of your application.
|
|
4
|
-
|
|
5
|
-
## 📑 Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Why Use an "assets" Folder](#folder-organization)
|
|
8
|
-
- [Usage Example](#usage)
|
|
9
|
-
- [Best Practice](#best-practice)
|
|
10
|
-
|
|
11
|
-
## <span id="folder-organization">Why Use an "assets" Folder?</span>
|
|
12
|
-
|
|
13
|
-
1. **Organization** : By storing your static resources in a separate folder named "assets," you maintain a cleaner and more organized project structure. This clearly separates static content from JavaScript files.
|
|
14
|
-
|
|
15
|
-
2. **Ease of Access** : Files in the "assets" folder can be easily referenced in your code using relative paths. This simplifies the inclusion of images, CSS, fonts, and other resources in your React components.
|
|
16
|
-
|
|
17
|
-
3. **Performance Optimization** : By storing static resources like images in an "assets" folder, you can optimize these files for better performance, for example, by using image compression tools.
|
|
18
|
-
|
|
19
|
-
## <span id="usage">🧑🏻💻 Usage Example </span>
|
|
20
|
-
|
|
21
|
-
To use an image stored in the "assets" folder, you can reference its relative path in your JavaScript or JSX code like this:
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
import logo from '@Front/assets/images/logo.png';
|
|
25
|
-
|
|
26
|
-
export const App = () => {
|
|
27
|
-
return (
|
|
28
|
-
<div>
|
|
29
|
-
<img src={logo} alt="Logo" />
|
|
30
|
-
{/* ... other elements of the application */}
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## <span id="best-practice">🎖️ Best Practice</span>
|
|
37
|
-
|
|
38
|
-
When it comes to styling and managing assets, adopting the following practices can enhance maintainability and structure in your project:
|
|
39
|
-
|
|
40
|
-
### - Global CSS Rules
|
|
41
|
-
|
|
42
|
-
Define all global CSS rules, such as resets, fonts, and general styling, in a centralized stylesheet (in the css folder under the assets ).
|
|
43
|
-
|
|
44
|
-
This ensures consistency across your entire application.
|
|
45
|
-
|
|
46
|
-
### - CSS Modules
|
|
47
|
-
|
|
48
|
-
For component-specific styles, leverage CSS Modules to encapsulate styles within the component scope.
|
|
49
|
-
|
|
50
|
-
This helps prevent unintentional styling conflicts and promotes a modular approach to styling.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
**_By adhering to these practices, you create a clear separation between global styles and component-specific styles, making your codebase more maintainable and scalable._**
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { queryClient } from '@Front/config';
|
|
2
|
-
import { withProvider } from '@Front/providers';
|
|
3
|
-
import { createRouter } from '@Front/routing/routerFactory';
|
|
4
|
-
import { RouterProvider } from 'react-router';
|
|
5
|
-
|
|
6
|
-
import '@Front/assets/css';
|
|
7
|
-
|
|
8
|
-
type AppProps = {
|
|
9
|
-
basename?: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const AppWithProviders = withProvider(RouterProvider);
|
|
13
|
-
|
|
14
|
-
export const App = ({ basename }: AppProps) => {
|
|
15
|
-
const router = createRouter({ basename });
|
|
16
|
-
|
|
17
|
-
return <AppWithProviders queryClient={queryClient} router={router} />;
|
|
18
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { App } from './App';
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import logo from '@Front/assets/images/logo.png';
|
|
2
|
-
import { Logo } from '@Front/ui/atoms/Logo';
|
|
3
|
-
import { Link } from 'react-router';
|
|
4
|
-
|
|
5
|
-
import classes from './Footer.module.css';
|
|
6
|
-
|
|
7
|
-
export const Footer = () => {
|
|
8
|
-
return (
|
|
9
|
-
<div className={classes.container}>
|
|
10
|
-
<hr />
|
|
11
|
-
<Link to="/">
|
|
12
|
-
<Logo size="50px" src={logo} alt="logo" />
|
|
13
|
-
</Link>
|
|
14
|
-
</div>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Footer } from './Footer';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import logo from '@Front/assets/images/logo.png';
|
|
2
|
-
import { Logo } from '@Front/ui/atoms/Logo';
|
|
3
|
-
import { Navigation } from '@Front/ui/molecules/Navigation';
|
|
4
|
-
import { Link } from 'react-router';
|
|
5
|
-
|
|
6
|
-
import classes from './Header.module.css';
|
|
7
|
-
|
|
8
|
-
export const Header = () => {
|
|
9
|
-
return (
|
|
10
|
-
<div className={classes.container}>
|
|
11
|
-
<Link to="/">
|
|
12
|
-
<Logo size="50px" src={logo} alt="logo" />
|
|
13
|
-
</Link>
|
|
14
|
-
<Navigation links={[{ label: 'Demo', url: '/' }]} />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
-
|
|
3
|
-
exports[`Header Component > should render the Header component correctly 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div
|
|
6
|
-
class="_container_a5b977"
|
|
7
|
-
>
|
|
8
|
-
<a
|
|
9
|
-
data-discover="true"
|
|
10
|
-
href="/"
|
|
11
|
-
>
|
|
12
|
-
<img
|
|
13
|
-
alt="logo"
|
|
14
|
-
class="_logoStyle_9e86a7"
|
|
15
|
-
src="/src/assets/images/logo.png"
|
|
16
|
-
style="width: 50px;"
|
|
17
|
-
/>
|
|
18
|
-
</a>
|
|
19
|
-
<nav>
|
|
20
|
-
<ul
|
|
21
|
-
class="_navList_eee024"
|
|
22
|
-
>
|
|
23
|
-
<li>
|
|
24
|
-
<a
|
|
25
|
-
aria-current="page"
|
|
26
|
-
class="_a_eee024 active"
|
|
27
|
-
data-discover="true"
|
|
28
|
-
href="/"
|
|
29
|
-
>
|
|
30
|
-
Demo
|
|
31
|
-
</a>
|
|
32
|
-
</li>
|
|
33
|
-
</ul>
|
|
34
|
-
</nav>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Header } from './Header';
|
package/src/components/README.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# 📁 components
|
|
2
|
-
|
|
3
|
-
The "components" folder is a crucial element of any React application. It is used to organize and store reusable components that make up the user interface of your application. React components are self-contained pieces of the user interface, each having its own logic and rendering.
|
|
4
|
-
|
|
5
|
-
## 📑 Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Why Use a "components" Folder](#folder-organization)
|
|
8
|
-
- [Usage](#usage)
|
|
9
|
-
|
|
10
|
-
## <span id="folder-organization">Why Use a "components" Folder?</span>
|
|
11
|
-
|
|
12
|
-
1. **Modularity** : Components can be reused across different parts of your application. This promotes code modularity and allows you to maintain your application more efficiently.
|
|
13
|
-
|
|
14
|
-
2. **Clarity** : By grouping all your components in a "components" folder, it is easier to understand the structure of your application. It also facilitates the search and management of components.
|
|
15
|
-
|
|
16
|
-
3. **Better Organization** : Organizing components in a dedicated folder helps clearly distinguish components from other elements of the application, such as styles, images, or configuration files.
|
|
17
|
-
|
|
18
|
-
## <span id="usage">🧑🏻💻 Usage Example </span>
|
|
19
|
-
|
|
20
|
-
Suppose you have a "Header.js" component in the "components" folder. You can import and use it in other parts of your application like this:
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
import Header from '@Front/components/Header';
|
|
24
|
-
|
|
25
|
-
export const App = () => {
|
|
26
|
-
return (
|
|
27
|
-
<div>
|
|
28
|
-
<Header />
|
|
29
|
-
{/* ... other elements of the application */}
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
```
|
package/src/config/README.md
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# 📁 config
|
|
2
|
-
|
|
3
|
-
The "config" folder is intended to store all important configurations and utilities needed for our React project. Bringing together this information in one place makes managing configuration settings easier and ensures better code organization.
|
|
4
|
-
|
|
5
|
-
## 📑 Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Folder Organization](#folder-organization)
|
|
8
|
-
- [Content Example](#content-example)
|
|
9
|
-
- [Usage](#usage)
|
|
10
|
-
- [Best Practice](#best-practice)
|
|
11
|
-
|
|
12
|
-
## <span id="folder-organization">Folder Organization</span>
|
|
13
|
-
|
|
14
|
-
Within the "config" folder, you can find the following elements:
|
|
15
|
-
|
|
16
|
-
1. **Configuration Files** : Files containing variables and configuration parameters, such as `apiConfig.ts` for configurations related to API calls, `appConfig.ts` for general application settings, `queryClientConfig.ts` for react-query-related configuration, etc.
|
|
17
|
-
|
|
18
|
-
2. **Configuration Scripts** : Scripts or utilities that facilitate dynamic configuration of the application, such as theme configuration, language management, etc.
|
|
19
|
-
|
|
20
|
-
## <span id="content-example">Content Example</span>
|
|
21
|
-
|
|
22
|
-
Here is an example folder structure for "config":
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
📁config/
|
|
26
|
-
├── 📄 apiConfig.ts
|
|
27
|
-
├── 📄 appConfig.ts
|
|
28
|
-
├── 📄 queryClientConfig.ts
|
|
29
|
-
├── 📄 translationConfig.ts
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## <span id="usage">🧑🏻💻Usage in the Project</span>
|
|
33
|
-
|
|
34
|
-
When you need to access a specific configuration in your code, import the appropriate file from the "config" folder. For example:
|
|
35
|
-
|
|
36
|
-
```javascript
|
|
37
|
-
// Example of using an API configuration
|
|
38
|
-
import { apiEndpoint } from '@Front/config/apiConfig';
|
|
39
|
-
|
|
40
|
-
// Example of using a react-query configuration
|
|
41
|
-
import { queryClient } from '@Front/config/queryConfig';
|
|
42
|
-
|
|
43
|
-
// Example of using a general application configuration
|
|
44
|
-
import { appName } from '@Front/config/appConfig';
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## <span id="best-practice">🎖️ Best Practice</span>
|
|
48
|
-
|
|
49
|
-
Efficient configuration management is crucial for maintaining a clear and organized codebase. Follow these best practices for managing configuration files:
|
|
50
|
-
|
|
51
|
-
#### - Context-Specific Configuration
|
|
52
|
-
|
|
53
|
-
Separate configuration files based on different contexts, such as API configurations, QueryClient configurations, translations, etc.
|
|
54
|
-
|
|
55
|
-
This helps in better organization and ease of maintenance.
|
|
56
|
-
|
|
57
|
-
#### - File Naming Convention
|
|
58
|
-
|
|
59
|
-
Suffix configuration files with `Config` to enhance visibility and make it easier to identify configuration files at a glance.
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
**_By adopting these practices, you create a modular and organized approach to configuration management, making it simpler to locate and manage context-specific settings._**
|
package/src/config/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { queryClient } from './queryClientConfig';
|