Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions templates/react-front-template/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
2 changes: 2 additions & 0 deletions templates/react-front-template/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_GRAPHQL_GATEWAY_URL=https://graphql-pokeapi.graphcdn.app/
VITE_TRANSLATIONS_ENDPOINT_URI=/translations
2 changes: 2 additions & 0 deletions templates/react-front-template/.env.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_GRAPHQL_GATEWAY_URL=https://graphql-pokeapi.graphcdn.app/
VITE_TRANSLATIONS_ENDPOINT_URI=/translations
2 changes: 2 additions & 0 deletions templates/react-front-template/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/graphql/types-and-hooks.ts
src/vite-env.d.ts
3 changes: 3 additions & 0 deletions templates/react-front-template/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@eleven-labs/eslint-config-react"
}
9 changes: 9 additions & 0 deletions templates/react-front-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Logs
logs
*.log
yarn-debug.log*
yarn-error.log*

node_modules
dist
build
38 changes: 38 additions & 0 deletions templates/react-front-template/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
WORKSPACE ?= $(PWD)
REPORTS_DIR ?= build/reports
STAGE ?= dev

install: ## Install the project
@yarn --production=false --frozen-lockfile

start-server: install ## Build assets and launch server
@STAGE=${STAGE} yarn dev

build: ## Build for production
@STAGE=${STAGE} yarn build

prepare-ci: ## Prepare workspace to run CI targets
@mkdir -p build/reports

lint: ## Run Lint
@yarn lint

lint-ci: prepare-ci ## Run Lint and generate report file
- yarn lint:ci
- sed -e 's#$(PWD)#$(WORKSPACE)#g' -i $(REPORTS_DIR)/checkstyle.xml

unit-tests: ## Run unit tests and generate report file
@yarn test

unit-tests-ci: prepare-ci ## Run unit tests and generate report file
@yarn test:ci

graphql-codegen: ## Generate Operation Apollo GraphQL
@yarn graphql:codegen

.PHONY: install

.DEFAULT_GOAL := help
help:
@grep -E '(^[0-9a-zA-Z_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-25s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
.PHONY: help
90 changes: 90 additions & 0 deletions templates/react-front-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# React Front Template

## Context

This repositories contains templates that we should use to bootstrap new GraphQL Gateway.

It contains:
- basic React configuration
- CI/CD configuration
- React Router configurations
- I18Next configurations
- GraphQL configurations

## How to use?

1. Create a new Github repository using this template.

2. Replace all the places where there is `react-front-template` with the name of your repository

3. Commit and push.

## Installation

```bash
$ make install
```

## Running the app

```bash
$ make start-server
```

## Unit Tests

```bash
$ make unit-tests
```

## GraphQL

To use GraphQL with react, we use two libraries:

- [GraphQL Codegen](https://the-guild.dev/graphql/codegen)

It's role will be to generate the hooks of the queries and mutations that we have created in the `.graphql` files

- [React Query](https://tanstack.com/query/v4/docs/react/graphql)

Similar to React Apollo on the use of hooks Query and Mutation, the only difference is that this one has a simplified cache management which will avoid many bugs in the case of refetch and cache policy.

Example of usage for a query:

```
...
import { usePokemonsQuery } from '@/graphql';

export const Component = (): React.FC => {
const pokemonsResult = usePokemonsQuery();

return (
{(pokemonsResult.isLoading && pokemons?.length) ? (
<span>Loading ...</span>
) : (
<div>
{pokemonsResult.data?.pokemons?.results.map((pokemonItem) => (
<h1>
{pokemonItem.name}
</h1>
))}
</div>
)}
)
}
```

Example of usage to invalidate a query:

```
...
import { useQueryClient } from '@tanstack/react-query';
import { namedOperations } from '@/graphql';

export const Component = (): React.FC => {
const queryClient = useQueryClient();
const invalidateCachePokemonsQuery = (): void => {
queryClient.invalidateQueries({ queryKey: [namedOperations.Query.Pokemons] });
};
}
```
21 changes: 21 additions & 0 deletions templates/react-front-template/codegen.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
overwrite: true,
schema: process.env.VITE_GRAPHQL_GATEWAY_URL,
documents: ['src/**/*.graphql'],
generates: {
'src/graphql/types-and-hooks.ts': {
plugins: [
'typescript',
'typescript-operations',
'typescript-react-query',
'named-operations-object'
],
config: {
maybeValue: 'T',
fetcher: {
func: './fetcher#fetcher',
},
}
},
},
};
17 changes: 17 additions & 0 deletions templates/react-front-template/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charSet="utf8" />
<meta content="index, follow, noarchive" name="robots" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<meta content="yes" name="mobile-web-app-capable" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<link href='/favicon.ico' rel="shortcut icon" type="image/x-icon" />
<link href='/web-app-manifest.json' rel="manifest" />
<title>Eleven Labs - React Front Template</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1 change: 1 addition & 0 deletions templates/react-front-template/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
71 changes: 71 additions & 0 deletions templates/react-front-template/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "react-front-template",
"version": "0.0.1",
"scripts": {
"graphql:codegen": "graphql-codegen-esm --config codegen.cjs -r dotenv/config",
"dev": "concurrently \"vite --mode=$STAGE\" \"yarn graphql:codegen --watch\"",
"build": "tsc && vite build --mode=$STAGE --outDir dist-$STAGE",
"prestart": "yarn build",
"start": "NODE_ENV=production vite preview",
"lint": "eslint src",
"lint:ci": "yarn lint --format checkstyle --output-file build/reports/checkstyle.xml || true",
"test": "jest",
"test:ci": "jest --ci"
},
"lint-staged": {
"*.(ts|tsx)": [
"eslint --fix"
]
},
"engines": {
"npm": "please-use-yarn-instead",
"yarn": ">= 1.2.0",
"node": ">= 18.0"
},
"prettier": "@eleven-labs/prettier-config",
"dependencies": {
"@eleven-labs/design-system": "^0.6.2",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-query-devtools": "^4.36.1",
"graphql": "^16.8.1",
"graphql-request": "^6.1.0",
"hoofd": "^1.7.1",
"i18next": "^23.5.1",
"i18next-browser-languagedetector": "^7.1.0",
"i18next-http-backend": "^2.2.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.2.2",
"react-router-dom": "^6.16.0"
},
"devDependencies": {
"@eleven-labs/eslint-config-react": "^1.0.1",
"@eleven-labs/prettier-config": "^1.0.0",
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/named-operations-object": "^3.0.0",
"@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-operations": "^4.0.1",
"@graphql-codegen/typescript-react-query": "^5.0.0",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.5",
"@types/react": "^18.2.28",
"@types/react-dom": "^18.2.13",
"@types/react-router-dom": "^5.3.3",
"@types/sha.js": "^2.4.2",
"@vitejs/plugin-react-swc": "^3.4.0",
"concurrently": "^8.2.1",
"dotenv": "^16.3.1",
"eslint": "^8.51.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-junit": "^16.0.0",
"lint-staged": "^14.0.1",
"prettier": "^3.0.3",
"sass": "^1.69.3",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2",
"vite": "^4.4.11",
"vite-tsconfig-paths": "^4.2.1"
}
}
Binary file added templates/react-front-template/public/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions templates/react-front-template/public/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"layout": {
"change-lang": "change language to {{lang}}",
"menu": {
"home": "Home",
"pokemon-list": "Pokemon List"
}
},
"pages": {
"home": {
"title": "React SSR with Vite + React Router + I18Next + Hoofd",
"description": "Edit <code>src/pages/HomePage/HomePage.tsx</code> and save to test"
},
"pokemon-list": {
"title": "Pokemon List",
"description": "Vivamus laoreet ex non tellus hendrerit ullamcorper. Nulla nec varius elit. Sed rutrum pharetra ante."
},
"not-found": {
"title": "404",
"description": "Something's missing.",
"sub-description": "Sorry, we can't find that page. You'll find lots to explore on the home page."
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"layout": {
"change-lang": "changer de langue en {{lang}}",
"menu": {
"home": "Accueil",
"pokemon-list": "Liste de Pokemon"
}
},
"pages": {
"home": {
"title": "React SSR avec Vite + React Router + I18Next + Hoofd",
"description": "Modifier <code>src/pages/HomePage/HomePage.tsx</code> et sauvegarder pour tester"
},
"pokemon-list": {
"title": "Liste de Pokemon",
"description": "Vivamus laoreet ex non tellus hendrerit ullamcorper. Nulla nec varius elit. Sed rutrum pharetra ante."
},
"other-page": {
"title": "Autre Page",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce convallis ligula erat, at malesuada ante venenatis ac"
},
"not-found": {
"title": "404",
"description": "Il manque quelque chose.",
"sub-description": "Désolé, nous ne trouvons pas cette page. Vous trouverez beaucoup de choses à explorer sur la page d'accueil."
}
}
}
1 change: 1 addition & 0 deletions templates/react-front-template/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions templates/react-front-template/public/web-app-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"short_name": "Eleven Labs",
"name": "Eleven Labs",
"icons": [],
"background_color": "#224579",
"theme_color": "#3767B6",
"display": "standalone",
"scope": "/",
"shortcuts": []
}
25 changes: 25 additions & 0 deletions templates/react-front-template/src/config/i18n/i18n.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type InitOptions } from 'i18next';

import { AUTHORIZED_LANGUAGES, DEFAULT_LANGUAGE, TRANSLATIONS_ENDPOINT_URI } from '@/constants';

export const i18nConfig: InitOptions = {
backend: {
crossDomain: true,
loadPath: `${TRANSLATIONS_ENDPOINT_URI}/{{ns}}.{{lng}}.json`,
},
defaultNS: 'messages',
detection: {
lookupFromPathIndex: 0,
order: ['path'],
},
fallbackLng: DEFAULT_LANGUAGE,
load: 'languageOnly',
ns: 'messages',
preload: AUTHORIZED_LANGUAGES,
react: {
bindI18n: 'languageChanged',
bindI18nStore: false,
useSuspense: false,
},
returnEmptyString: false,
};
1 change: 1 addition & 0 deletions templates/react-front-template/src/config/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './i18n.config';
1 change: 1 addition & 0 deletions templates/react-front-template/src/config/router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './routes';
Loading