mirror of
https://github.com/Mastermindzh/react-starter-kit.git
synced 2025-05-10 23:33:41 +02:00
Compare commits
No commits in common. "e733c4a9f6d53fb77d00a4a829f6cf298b66d4b6" and "7b6cd6d2864338832b178e927c917aa4c746736a" have entirely different histories.
e733c4a9f6
...
7b6cd6d286
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -5,16 +5,13 @@
|
|||||||
"deepmerge",
|
"deepmerge",
|
||||||
"flexbugs",
|
"flexbugs",
|
||||||
"Immer",
|
"Immer",
|
||||||
"Keycloak",
|
|
||||||
"languagedetector",
|
"languagedetector",
|
||||||
"luxon",
|
"luxon",
|
||||||
"oidc",
|
|
||||||
"pmmmwh",
|
"pmmmwh",
|
||||||
"preinstall",
|
"preinstall",
|
||||||
"reduxjs",
|
"reduxjs",
|
||||||
"SVGR",
|
"SVGR",
|
||||||
"tailwindcss",
|
"tailwindcss",
|
||||||
"tendersguru",
|
|
||||||
"testid",
|
"testid",
|
||||||
"typeahead",
|
"typeahead",
|
||||||
"uncompiled"
|
"uncompiled"
|
||||||
|
4
.vscode/typescriptreact.code-snippets
vendored
4
.vscode/typescriptreact.code-snippets
vendored
@ -68,9 +68,5 @@
|
|||||||
"",
|
"",
|
||||||
"export default ${1:${TM_FILENAME_BASE}}Slice.reducer;"
|
"export default ${1:${TM_FILENAME_BASE}}Slice.reducer;"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"react-i18next useTranslate hook": {
|
|
||||||
"prefix": ["useTranslation", "translate", "i18-trans"],
|
|
||||||
"body": ["const [translate] = useTranslation();"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -4,18 +4,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [0.5.0] - 2022-06-26
|
|
||||||
|
|
||||||
- Added react-oidc (use demo/demo)
|
|
||||||
- Added an example of an authentication protected page (tenders)
|
|
||||||
- Added an example with the built in proxy (to combat CORS) (tendersguru)
|
|
||||||
|
|
||||||
## [0.4.1] - 2022-06-26
|
|
||||||
|
|
||||||
- Moved examples into example directory
|
|
||||||
- Moved routes to separate file
|
|
||||||
- Used route constants
|
|
||||||
|
|
||||||
## [0.4.0] - 2022-07-25
|
## [0.4.0] - 2022-07-25
|
||||||
|
|
||||||
- Added the possibility to override partial configs during deployments
|
- Added the possibility to override partial configs during deployments
|
||||||
|
12
README.md
12
README.md
@ -17,7 +17,6 @@ Includes:
|
|||||||
|
|
||||||
- [Getting started](#getting-started)
|
- [Getting started](#getting-started)
|
||||||
- [Project structure](#project-structure)
|
- [Project structure](#project-structure)
|
||||||
- ["Forking" outside of Github](#forking-outside-of-github)
|
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Using the `config.ts` file](#using-the-configts-file)
|
- [Using the `config.ts` file](#using-the-configts-file)
|
||||||
- [adding values](#adding-values)
|
- [adding values](#adding-values)
|
||||||
@ -57,17 +56,6 @@ Only the important files are shown
|
|||||||
└── tsconfig.json
|
└── tsconfig.json
|
||||||
```
|
```
|
||||||
|
|
||||||
## "Forking" outside of Github
|
|
||||||
|
|
||||||
To use this base in other git software (not Github) you will have to manually manage the upstream.
|
|
||||||
Go into your existing repo and execute the following commands:
|
|
||||||
|
|
||||||
1. `git remote add upstream <clone-url>`
|
|
||||||
2. `git pull upstream master` # or other branchname
|
|
||||||
3. `git push`
|
|
||||||
|
|
||||||
Then, when you need to sync again you can repeat step 2 and 3
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
This starter kit comes with runtime configuration out-of-the-box.
|
This starter kit comes with runtime configuration out-of-the-box.
|
||||||
|
142
package-lock.json
generated
142
package-lock.json
generated
@ -1,16 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.4.1",
|
"version": "0.4.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.4.1",
|
"version": "0.4.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@axa-fr/react-oidc": "^6.0.0-beta10",
|
|
||||||
"@reduxjs/toolkit": "^1.8.3",
|
"@reduxjs/toolkit": "^1.8.3",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"i18next-http-backend": "^1.4.1",
|
"i18next-http-backend": "^1.4.1",
|
||||||
@ -61,7 +60,6 @@
|
|||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"i18next": "^21.8.14",
|
"i18next": "^21.8.14",
|
||||||
"i18next-browser-languagedetector": "^6.1.4",
|
"i18next-browser-languagedetector": "^6.1.4",
|
||||||
@ -114,18 +112,6 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@axa-fr/react-oidc": {
|
|
||||||
"version": "6.0.0-beta10",
|
|
||||||
"resolved": "https://registry.npmjs.org/@axa-fr/react-oidc/-/react-oidc-6.0.0-beta10.tgz",
|
|
||||||
"integrity": "sha512-BWHuIn9b+5O35It+V3m/8MWAV6pOjoMy2SihKfeDlsQs2Bp4HMBb4x46zygZ1IGs/u43jtTsnZkrPhwJU6VdqQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@openid/appauth": "1.3.1"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "x",
|
|
||||||
"react-dom": "x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.18.6",
|
"version": "7.18.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||||
@ -3323,32 +3309,6 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@openid/appauth": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openid/appauth/-/appauth-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-e54kpi219wES2ijPzeHe1kMnT8VKH8YeTd1GAn9BzVBmutz3tBgcG1y8a4pziNr4vNjFnuD4W446Ua7ELnNDiA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/base64-js": "^1.3.0",
|
|
||||||
"@types/jquery": "^3.5.5",
|
|
||||||
"base64-js": "^1.5.1",
|
|
||||||
"follow-redirects": "^1.13.3",
|
|
||||||
"form-data": "^4.0.0",
|
|
||||||
"opener": "^1.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@openid/appauth/node_modules/form-data": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
|
||||||
"dependencies": {
|
|
||||||
"asynckit": "^0.4.0",
|
|
||||||
"combined-stream": "^1.0.8",
|
|
||||||
"mime-types": "^2.1.12"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@pmmmwh/react-refresh-webpack-plugin": {
|
"node_modules/@pmmmwh/react-refresh-webpack-plugin": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz",
|
||||||
@ -4059,11 +4019,6 @@
|
|||||||
"@babel/types": "^7.3.0"
|
"@babel/types": "^7.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/base64-js": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/base64-js/-/base64-js-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-ZmI0sZGAUNXUfMWboWwi4LcfpoVUYldyN6Oe0oJ5cCsHDU/LlRq8nQKPXhYLOx36QYSW9bNIb1vvRrD6K7Llgw=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/body-parser": {
|
"node_modules/@types/body-parser": {
|
||||||
"version": "1.19.2",
|
"version": "1.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
||||||
@ -4248,14 +4203,6 @@
|
|||||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/jquery": {
|
|
||||||
"version": "3.5.14",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz",
|
|
||||||
"integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/sizzle": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@ -4391,7 +4338,8 @@
|
|||||||
"node_modules/@types/sizzle": {
|
"node_modules/@types/sizzle": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
|
||||||
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
|
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/sockjs": {
|
"node_modules/@types/sockjs": {
|
||||||
"version": "0.3.33",
|
"version": "0.3.33",
|
||||||
@ -5304,7 +5252,8 @@
|
|||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/at-least-node": {
|
"node_modules/at-least-node": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -5717,6 +5666,7 @@
|
|||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -6404,6 +6354,7 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
},
|
},
|
||||||
@ -7589,6 +7540,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
@ -9684,6 +9636,7 @@
|
|||||||
"version": "1.15.1",
|
"version": "1.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
||||||
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
|
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
|
||||||
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@ -15700,14 +15653,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/opener": {
|
|
||||||
"version": "1.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
|
||||||
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
|
|
||||||
"bin": {
|
|
||||||
"opener": "bin/opener-bin.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/optionator": {
|
"node_modules/optionator": {
|
||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||||
@ -21392,14 +21337,6 @@
|
|||||||
"@jridgewell/trace-mapping": "^0.3.9"
|
"@jridgewell/trace-mapping": "^0.3.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@axa-fr/react-oidc": {
|
|
||||||
"version": "6.0.0-beta10",
|
|
||||||
"resolved": "https://registry.npmjs.org/@axa-fr/react-oidc/-/react-oidc-6.0.0-beta10.tgz",
|
|
||||||
"integrity": "sha512-BWHuIn9b+5O35It+V3m/8MWAV6pOjoMy2SihKfeDlsQs2Bp4HMBb4x46zygZ1IGs/u43jtTsnZkrPhwJU6VdqQ==",
|
|
||||||
"requires": {
|
|
||||||
"@openid/appauth": "1.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@babel/code-frame": {
|
"@babel/code-frame": {
|
||||||
"version": "7.18.6",
|
"version": "7.18.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||||
@ -23651,31 +23588,6 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@openid/appauth": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@openid/appauth/-/appauth-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-e54kpi219wES2ijPzeHe1kMnT8VKH8YeTd1GAn9BzVBmutz3tBgcG1y8a4pziNr4vNjFnuD4W446Ua7ELnNDiA==",
|
|
||||||
"requires": {
|
|
||||||
"@types/base64-js": "^1.3.0",
|
|
||||||
"@types/jquery": "^3.5.5",
|
|
||||||
"base64-js": "^1.5.1",
|
|
||||||
"follow-redirects": "^1.13.3",
|
|
||||||
"form-data": "^4.0.0",
|
|
||||||
"opener": "^1.5.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"form-data": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
|
||||||
"requires": {
|
|
||||||
"asynckit": "^0.4.0",
|
|
||||||
"combined-stream": "^1.0.8",
|
|
||||||
"mime-types": "^2.1.12"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": {
|
"@pmmmwh/react-refresh-webpack-plugin": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz",
|
||||||
@ -24155,11 +24067,6 @@
|
|||||||
"@babel/types": "^7.3.0"
|
"@babel/types": "^7.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/base64-js": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/base64-js/-/base64-js-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-ZmI0sZGAUNXUfMWboWwi4LcfpoVUYldyN6Oe0oJ5cCsHDU/LlRq8nQKPXhYLOx36QYSW9bNIb1vvRrD6K7Llgw=="
|
|
||||||
},
|
|
||||||
"@types/body-parser": {
|
"@types/body-parser": {
|
||||||
"version": "1.19.2",
|
"version": "1.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
||||||
@ -24337,14 +24244,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/jquery": {
|
|
||||||
"version": "3.5.14",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz",
|
|
||||||
"integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==",
|
|
||||||
"requires": {
|
|
||||||
"@types/sizzle": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/json-schema": {
|
"@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||||
@ -24480,7 +24379,8 @@
|
|||||||
"@types/sizzle": {
|
"@types/sizzle": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
|
||||||
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
|
"integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/sockjs": {
|
"@types/sockjs": {
|
||||||
"version": "0.3.33",
|
"version": "0.3.33",
|
||||||
@ -25158,7 +25058,8 @@
|
|||||||
"asynckit": {
|
"asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"at-least-node": {
|
"at-least-node": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -25468,7 +25369,8 @@
|
|||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"batch": {
|
"batch": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
@ -25972,6 +25874,7 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
}
|
}
|
||||||
@ -26839,7 +26742,8 @@
|
|||||||
"delayed-stream": {
|
"delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"depd": {
|
"depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@ -28427,7 +28331,8 @@
|
|||||||
"follow-redirects": {
|
"follow-redirects": {
|
||||||
"version": "1.15.1",
|
"version": "1.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
|
||||||
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
|
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"forever-agent": {
|
"forever-agent": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
@ -32855,11 +32760,6 @@
|
|||||||
"is-wsl": "^2.2.0"
|
"is-wsl": "^2.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"opener": {
|
|
||||||
"version": "1.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
|
||||||
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A=="
|
|
||||||
},
|
|
||||||
"optionator": {
|
"optionator": {
|
||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.5.0",
|
"version": "0.4.0",
|
||||||
"description": "A modern, create-react-app-based, starter kit for React projects",
|
"description": "A modern, create-react-app-based, starter kit for React projects",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
@ -45,7 +45,6 @@
|
|||||||
"*.{ts,js,jsx,tsx,css,scss,json,md}": "prettier --write"
|
"*.{ts,js,jsx,tsx,css,scss,json,md}": "prettier --write"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@axa-fr/react-oidc": "^6.0.0-beta10",
|
|
||||||
"@reduxjs/toolkit": "^1.8.3",
|
"@reduxjs/toolkit": "^1.8.3",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
"i18next-http-backend": "^1.4.1",
|
"i18next-http-backend": "^1.4.1",
|
||||||
@ -96,7 +95,6 @@
|
|||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"i18next": "^21.8.14",
|
"i18next": "^21.8.14",
|
||||||
"i18next-browser-languagedetector": "^6.1.4",
|
"i18next-browser-languagedetector": "^6.1.4",
|
||||||
|
@ -1,24 +1,6 @@
|
|||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
version: "0.1.0",
|
version: "0.1.0",
|
||||||
name: "React-starter-kit",
|
name: "React-starter-kit",
|
||||||
// oidc: {
|
|
||||||
// url: "private_url",
|
|
||||||
// realm: "inforit",
|
|
||||||
// clientId: "react-base",
|
|
||||||
// scope: "openid profile email",
|
|
||||||
// redirectUri: "http://localhost:3000/authentication/callback",
|
|
||||||
// silentRedirectUri: "http://localhost:3000/authentication/silent-callback",
|
|
||||||
// serviceWorkerOnly: false,
|
|
||||||
// },
|
|
||||||
oidc: {
|
|
||||||
url: "https://sso.mastermindzh.tech/realms/public-tests",
|
|
||||||
realm: "public-tests",
|
|
||||||
clientId: "react-starter-kit",
|
|
||||||
scope: "openid profile email",
|
|
||||||
redirectUri: "http://localhost:3000/authentication/callback",
|
|
||||||
silentRedirectUri: "http://localhost:3000/authentication/silent-callback",
|
|
||||||
serviceWorkerOnly: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ignore this :)
|
// ignore this :)
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
"nav": {
|
"nav": {
|
||||||
"home": "home",
|
"home": "home",
|
||||||
"about": "about",
|
"about": "about",
|
||||||
"counter": "counter",
|
"counter": "counter"
|
||||||
"tenders": "tenders (with auth)"
|
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About"
|
"title": "About"
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
"nav": {
|
"nav": {
|
||||||
"home": "home",
|
"home": "home",
|
||||||
"about": "over ons",
|
"about": "over ons",
|
||||||
"counter": "teller",
|
"counter": "teller"
|
||||||
"tenders": "aanbestedingen (met auth)"
|
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "Over ons"
|
"title": "Over ons"
|
||||||
|
19
src/App.tsx
19
src/App.tsx
@ -1,13 +1,26 @@
|
|||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||||
|
import { AboutContainer } from "./features/about/About";
|
||||||
|
import { CounterContainer } from "./features/counter/Counter";
|
||||||
|
import { HomeContainer } from "./features/home/Home";
|
||||||
import { Navbar } from "./infrastructure/navbar/Navbar";
|
import { Navbar } from "./infrastructure/navbar/Navbar";
|
||||||
import { AppRoutes } from "./Routes";
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<AppRoutes />
|
<Routes>
|
||||||
|
<Route path="/" element={<HomeContainer />} />
|
||||||
|
<Route path="/about" element={<AboutContainer />} />
|
||||||
|
<Route path="/counter" element={<CounterContainer />} />
|
||||||
|
{/* <Route index element={<Home />} /> */}
|
||||||
|
{/* <Route path="teams" element={<Teams />}>
|
||||||
|
<Route path=":teamId" element={<Team />} />
|
||||||
|
<Route path="new" element={<NewTeamForm />} />
|
||||||
|
<Route index element={<LeagueStandings />} />
|
||||||
|
</Route> */}
|
||||||
|
{/* </Route> */}
|
||||||
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
);
|
);
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import { OidcSecure } from "@axa-fr/react-oidc";
|
|
||||||
import { FunctionComponent } from "react";
|
|
||||||
import { Route, Routes } from "react-router-dom";
|
|
||||||
import { AboutContainer } from "./features/about/About";
|
|
||||||
import { CounterContainer } from "./features/examples/counter/Counter";
|
|
||||||
import { Tenders } from "./features/examples/tenders/Tenders";
|
|
||||||
import { HomeContainer } from "./features/home/Home";
|
|
||||||
type Props = {};
|
|
||||||
|
|
||||||
export const ROUTE_KEYS = {
|
|
||||||
home: "",
|
|
||||||
about: "about",
|
|
||||||
counter: "counter",
|
|
||||||
tenders: "tenders",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AppRoutes: FunctionComponent<Props> = () => {
|
|
||||||
const { home, about, counter, tenders } = ROUTE_KEYS;
|
|
||||||
return (
|
|
||||||
<Routes>
|
|
||||||
<Route path={home} element={<HomeContainer />} />
|
|
||||||
<Route path={about} element={<AboutContainer />} />
|
|
||||||
<Route path={counter} element={<CounterContainer />} />
|
|
||||||
{/* a route with authentication */}
|
|
||||||
<Route
|
|
||||||
path={tenders}
|
|
||||||
element={
|
|
||||||
<OidcSecure>
|
|
||||||
<Tenders />
|
|
||||||
</OidcSecure>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{/* <Route index element={<Home />} /> */}
|
|
||||||
{/* <Route path="teams" element={<Teams />}>
|
|
||||||
<Route path=":teamId" element={<Team />} />
|
|
||||||
<Route path="new" element={<NewTeamForm />} />
|
|
||||||
<Route index element={<LeagueStandings />} />
|
|
||||||
</Route> */}
|
|
||||||
{/* </Route> */}
|
|
||||||
</Routes>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit";
|
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit";
|
||||||
import counterReducer from "../features/examples/counter/state/counterSlice";
|
import counterReducer from "../features/counter/state/counterSlice";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
|
@ -2,14 +2,7 @@ import { FunctionComponent, ReactNode } from "react";
|
|||||||
import { I18nextProvider, useTranslation } from "react-i18next";
|
import { I18nextProvider, useTranslation } from "react-i18next";
|
||||||
import i18n from "./i18n";
|
import i18n from "./i18n";
|
||||||
|
|
||||||
type Props = {
|
type Props = { children?: ReactNode; keysOnly?: boolean };
|
||||||
children?: ReactNode;
|
|
||||||
/**
|
|
||||||
* Whether to show the translation keys instead of translated text
|
|
||||||
* Can be useful to test languages that don't have full translations
|
|
||||||
*/
|
|
||||||
keysOnly?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ProvidedComponent: FunctionComponent<Props> = ({ children, keysOnly }) => {
|
const ProvidedComponent: FunctionComponent<Props> = ({ children, keysOnly }) => {
|
||||||
const [_translate, i18nSettings] = useTranslation();
|
const [_translate, i18nSettings] = useTranslation();
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@ -60,7 +60,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.asyncButton:after {
|
.asyncButton:after {
|
||||||
content: "";
|
content: '';
|
||||||
background-color: rgba(112, 76, 182, 0.15);
|
background-color: rgba(112, 76, 182, 0.15);
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAppDispatch, useAppSelector } from "../../../app/hooks";
|
import { useAppDispatch, useAppSelector } from "../../app/hooks";
|
||||||
import styles from "./Counter.module.css";
|
import styles from "./Counter.module.css";
|
||||||
import { incrementAsync } from "./state/actions/incrementAsync";
|
import { incrementAsync } from "./state/actions/incrementAsync";
|
||||||
import {
|
import {
|
4
src/features/counter/services/counterAPI.ts
Normal file
4
src/features/counter/services/counterAPI.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// A mock function to mimic making an async request for data
|
||||||
|
export function fetchCount(amount = 1) {
|
||||||
|
return new Promise<{ data: number }>((resolve) => setTimeout(() => resolve({ data: amount }), 500));
|
||||||
|
}
|
@ -1,4 +1,8 @@
|
|||||||
import counterReducer, { increment, decrement, incrementByAmount } from "./counterSlice";
|
import counterReducer, {
|
||||||
|
increment,
|
||||||
|
decrement,
|
||||||
|
incrementByAmount,
|
||||||
|
} from "./counterSlice";
|
||||||
import { CounterState } from "../models/CounterState";
|
import { CounterState } from "../models/CounterState";
|
||||||
|
|
||||||
describe("counter reducer", () => {
|
describe("counter reducer", () => {
|
@ -1,5 +1,5 @@
|
|||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import { AppThunk, RootState } from "../../../../app/store";
|
import { AppThunk, RootState } from "../../../app/store";
|
||||||
import { CounterState } from "../models/CounterState";
|
import { CounterState } from "../models/CounterState";
|
||||||
import { incrementAsync } from "./actions/incrementAsync";
|
import { incrementAsync } from "./actions/incrementAsync";
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
// A mock function to mimic making an async request for data
|
|
||||||
export function fetchCount(amount = 1) {
|
|
||||||
return new Promise<{ data: number }>((resolve) =>
|
|
||||||
setTimeout(() => resolve({ data: amount }), 500),
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import { useOidcAccessToken } from "@axa-fr/react-oidc";
|
|
||||||
import { FunctionComponent, useEffect, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
type Props = {};
|
|
||||||
|
|
||||||
export const Tenders: FunctionComponent<Props> = () => {
|
|
||||||
const [tenders, setTenders] = useState(null);
|
|
||||||
const [translate] = useTranslation();
|
|
||||||
const { accessToken } = useOidcAccessToken();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// this uses the CORS proxy in our webpack setup
|
|
||||||
// tendersguru is mapped to "https://tenders.guru" in setupProxy.js
|
|
||||||
// it will strip the tendersguru part, so the full url will be: https://tenders.guru/api/ro/tenders
|
|
||||||
fetch("tendersguru/api/ro/tenders", {
|
|
||||||
// fetch's way of adding headers. Not required to access the api... but :shrug:
|
|
||||||
headers: new Headers({
|
|
||||||
Authorization: `Bearer ${accessToken}`,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((data) => {
|
|
||||||
setTenders(data);
|
|
||||||
});
|
|
||||||
}, [accessToken]);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>{translate("nav.tenders")}</h1>
|
|
||||||
{tenders ? <pre>{JSON.stringify(tenders, null, 2)}</pre> : <h2>loading...</h2>}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -8,39 +8,19 @@ export const HomeContainer: FunctionComponent<Props> = () => {
|
|||||||
<p>This is the react base app :)</p>
|
<p>This is the react base app :)</p>
|
||||||
<span>
|
<span>
|
||||||
<span>Learn </span>
|
<span>Learn </span>
|
||||||
<a
|
<a className="App-link" href="https://reactjs.org/" target="_blank" rel="noopener noreferrer">
|
||||||
className="App-link"
|
|
||||||
href="https://reactjs.org/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
React
|
React
|
||||||
</a>
|
</a>
|
||||||
<span>, </span>
|
<span>, </span>
|
||||||
<a
|
<a className="App-link" href="https://redux.js.org/" target="_blank" rel="noopener noreferrer">
|
||||||
className="App-link"
|
|
||||||
href="https://redux.js.org/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Redux
|
Redux
|
||||||
</a>
|
</a>
|
||||||
<span>, </span>
|
<span>, </span>
|
||||||
<a
|
<a className="App-link" href="https://redux-toolkit.js.org/" target="_blank" rel="noopener noreferrer">
|
||||||
className="App-link"
|
|
||||||
href="https://redux-toolkit.js.org/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Redux Toolkit
|
Redux Toolkit
|
||||||
</a>
|
</a>
|
||||||
,<span> and </span>
|
,<span> and </span>
|
||||||
<a
|
<a className="App-link" href="https://react-redux.js.org/" target="_blank" rel="noopener noreferrer">
|
||||||
className="App-link"
|
|
||||||
href="https://react-redux.js.org/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
React Redux
|
React Redux
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -5,7 +5,6 @@ import App from "./App";
|
|||||||
import { store } from "./app/store";
|
import { store } from "./app/store";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import "./infrastructure/i18n/init";
|
import "./infrastructure/i18n/init";
|
||||||
import { OidcProvider } from "./infrastructure/sso/OidcProvider";
|
|
||||||
import { Loader } from "./infrastructure/wrappers/WithPageSuspense";
|
import { Loader } from "./infrastructure/wrappers/WithPageSuspense";
|
||||||
import reportWebVitals from "./reportWebVitals";
|
import reportWebVitals from "./reportWebVitals";
|
||||||
|
|
||||||
@ -15,11 +14,9 @@ const root = createRoot(container);
|
|||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<OidcProvider>
|
<Loader>
|
||||||
<Loader>
|
<App />
|
||||||
<App />
|
</Loader>
|
||||||
</Loader>
|
|
||||||
</OidcProvider>
|
|
||||||
</Provider>
|
</Provider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import { OIDCConfig } from "../sso/models/OIDCConfig";
|
|
||||||
|
|
||||||
export interface RunTimeConfig {
|
export interface RunTimeConfig {
|
||||||
version: number;
|
version: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Settings for the OIDC connection
|
|
||||||
*/
|
|
||||||
oidc: OIDCConfig;
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import deepmerge from "deepmerge";
|
import deepmerge from "deepmerge";
|
||||||
import { RunTimeConfig } from "./RunTimeConfig";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets and merges both the regular config and the override config from the window
|
* gets and merges both the regular config and the override config from the window
|
||||||
@ -13,4 +12,4 @@ export const mergeConfigs = () => {
|
|||||||
|
|
||||||
mergeConfigs();
|
mergeConfigs();
|
||||||
|
|
||||||
export const Config: RunTimeConfig = window.mergedConfig;
|
export const Config = window.mergedConfig;
|
||||||
|
@ -1,25 +1,18 @@
|
|||||||
import { render, screen, waitFor } from "@testing-library/react";
|
import { render, screen } from "@testing-library/react";
|
||||||
import { WithTestTranslations } from "../../app/tests/mocks/i18n/WithTestTranslations";
|
import { WithTestTranslations } from "../../app/tests/mocks/i18n/WithTestTranslations";
|
||||||
import { OidcProvider } from "../sso/OidcProvider";
|
|
||||||
import { WithRouter } from "../wrappers/WithRouter";
|
import { WithRouter } from "../wrappers/WithRouter";
|
||||||
import { Navbar } from "./Navbar";
|
import { Navbar } from "./Navbar";
|
||||||
|
|
||||||
describe("Navbar container", () => {
|
describe("Navbar container", () => {
|
||||||
it.only("renders a navigation section identified by the nav test-id", async () => {
|
it.only("renders a navigation section identified by the nav test-id", () => {
|
||||||
render(
|
render(
|
||||||
<WithTestTranslations>
|
<WithTestTranslations>
|
||||||
{/* for simple tests where we don't need auth we don't actually have to mock responses */}
|
<WithRouter>
|
||||||
<OidcProvider>
|
<Navbar />
|
||||||
<WithRouter>
|
</WithRouter>
|
||||||
<Navbar />
|
|
||||||
</WithRouter>
|
|
||||||
</OidcProvider>
|
|
||||||
</WithTestTranslations>,
|
</WithTestTranslations>,
|
||||||
);
|
);
|
||||||
// because of the extra loaders we wait for a result just to be sure
|
|
||||||
// see: https://testing-library.com/docs/guide-disappearance/
|
expect(screen.getAllByTestId("nav")?.length).toBeGreaterThan(0);
|
||||||
await waitFor(() => {
|
|
||||||
expect(screen.getAllByTestId("nav")?.length).toBeGreaterThan(0);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
import { useOidc, useOidcAccessToken } from "@axa-fr/react-oidc";
|
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { FunctionComponent } from "react";
|
import { FunctionComponent } from "react";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { ROUTE_KEYS } from "../../Routes";
|
|
||||||
import { Config } from "../config";
|
import { Config } from "../config";
|
||||||
import "./Navbar.css";
|
import "./Navbar.css";
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
export const Navbar: FunctionComponent<Props> = () => {
|
export const Navbar: FunctionComponent<Props> = () => {
|
||||||
const [translate, i18n] = useTranslation();
|
const [translate, i18n] = useTranslation();
|
||||||
const { login, logout, isAuthenticated } = useOidc();
|
|
||||||
const { accessTokenPayload } = useOidcAccessToken();
|
|
||||||
const { home, about, counter } = ROUTE_KEYS;
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>{translate("navBar.intro")}</h1>
|
<h1>{translate("navBar.intro")}</h1>
|
||||||
@ -20,30 +15,20 @@ export const Navbar: FunctionComponent<Props> = () => {
|
|||||||
{/* trans can also be used to translate */}
|
{/* trans can also be used to translate */}
|
||||||
{Config.name} <Trans i18nKey="navBar.version">version:</Trans>
|
{Config.name} <Trans i18nKey="navBar.version">version:</Trans>
|
||||||
{JSON.stringify(Config.version)}
|
{JSON.stringify(Config.version)}
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
isAuthenticated ? logout() : login("/");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isAuthenticated ? `logout (${accessTokenPayload.email})` : "login"}
|
|
||||||
</button>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* This translation uses a formatter in the translation files */}
|
{/* This translation uses a formatter in the translation files */}
|
||||||
<p>{translate("navBar.currentDate", { date: DateTime.now().toJSDate() })}</p>
|
<p>{translate("navBar.currentDate", { date: DateTime.now().toJSDate() })}</p>
|
||||||
<nav data-testid="nav">
|
<nav data-testid="nav">
|
||||||
<Link to={home} data-testid="nav.home">
|
<Link to="/" data-testid="nav.home">
|
||||||
{translate("nav.home")}
|
{translate("nav.home")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={about} data-testid="nav.about">
|
<Link to="/about" data-testid="nav.about">
|
||||||
{translate("nav.about")}
|
{translate("nav.about")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={counter} data-testid="nav.counter">
|
<Link to="/counter" data-testid="nav.counter">
|
||||||
{translate("nav.counter")}
|
{translate("nav.counter")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to="/tenders" data-testid="nav.tenders">
|
|
||||||
{translate("nav.tenders")}
|
|
||||||
</Link>
|
|
||||||
<button onClick={() => i18n.changeLanguage("en")}>en</button>
|
<button onClick={() => i18n.changeLanguage("en")}>en</button>
|
||||||
<button onClick={() => i18n.changeLanguage("nl")}>nl</button>
|
<button onClick={() => i18n.changeLanguage("nl")}>nl</button>
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { OidcConfiguration } from "@axa-fr/react-oidc/dist/vanilla/oidc";
|
|
||||||
import { Config } from "../config";
|
|
||||||
|
|
||||||
const { clientId, redirectUri, silentRedirectUri, scope, url } = Config.oidc;
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
export const SSOConfiguration: OidcConfiguration = {
|
|
||||||
client_id: clientId,
|
|
||||||
redirect_uri: redirectUri,
|
|
||||||
silent_redirect_uri: silentRedirectUri,
|
|
||||||
scope,
|
|
||||||
authority: url,
|
|
||||||
service_worker_only: false,
|
|
||||||
};
|
|
@ -1,28 +0,0 @@
|
|||||||
import { OidcProvider as ReactOidcProvider } from "@axa-fr/react-oidc";
|
|
||||||
import { FunctionComponent, ReactNode } from "react";
|
|
||||||
import { AppLoader } from "../loader/appLoader";
|
|
||||||
import { SSOConfiguration } from "./Configuration";
|
|
||||||
import { Authenticating } from "./overrides/Authenticating";
|
|
||||||
import { AuthenticatingError } from "./overrides/AuthenticatingError";
|
|
||||||
import { CallBackSuccess } from "./overrides/CallBackSuccess";
|
|
||||||
import { ServiceWorkerNotSupported } from "./overrides/ServiceWorkerNotSupported";
|
|
||||||
import { SessionLost } from "./overrides/SessionLost";
|
|
||||||
|
|
||||||
type Props = { children?: ReactNode; [x: string]: any };
|
|
||||||
|
|
||||||
export const OidcProvider: FunctionComponent<Props> = ({ children, ...rest }) => {
|
|
||||||
return (
|
|
||||||
<ReactOidcProvider
|
|
||||||
loadingComponent={AppLoader}
|
|
||||||
authenticatingErrorComponent={AuthenticatingError}
|
|
||||||
authenticatingComponent={Authenticating}
|
|
||||||
sessionLostComponent={SessionLost}
|
|
||||||
serviceWorkerNotSupportedComponent={ServiceWorkerNotSupported}
|
|
||||||
callbackSuccessComponent={CallBackSuccess}
|
|
||||||
configuration={SSOConfiguration}
|
|
||||||
{...rest}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</ReactOidcProvider>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,31 +0,0 @@
|
|||||||
export interface OIDCConfig {
|
|
||||||
/**
|
|
||||||
* Authority URL
|
|
||||||
*/
|
|
||||||
url: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Realm to authenticate against
|
|
||||||
*/
|
|
||||||
realm: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Id of this client
|
|
||||||
*/
|
|
||||||
clientId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scope(s) that you want to request
|
|
||||||
*/
|
|
||||||
scope: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URI to redirect to after successful login
|
|
||||||
*/
|
|
||||||
redirectUri: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* redirect uri for the silent refresh
|
|
||||||
*/
|
|
||||||
silentRedirectUri: string;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export interface SSOResult {
|
|
||||||
configurationName: string;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { FunctionComponent } from "react";
|
|
||||||
import { SSOResult } from "../models/SSOResult";
|
|
||||||
|
|
||||||
export const Authenticating: FunctionComponent<SSOResult> = ({ configurationName }) => (
|
|
||||||
<>
|
|
||||||
<h1>Authentication in progress for {configurationName}</h1>
|
|
||||||
<p>You will be redirected to the login page.</p>
|
|
||||||
</>
|
|
||||||
);
|
|
@ -1,9 +0,0 @@
|
|||||||
import { FunctionComponent } from "react";
|
|
||||||
import { SSOResult } from "../models/SSOResult";
|
|
||||||
|
|
||||||
export const AuthenticatingError: FunctionComponent<SSOResult> = ({ configurationName }) => (
|
|
||||||
<>
|
|
||||||
<h1>Error for {configurationName}</h1>
|
|
||||||
<p>An error occurred during authentication.</p>
|
|
||||||
</>
|
|
||||||
);
|
|
@ -1,9 +0,0 @@
|
|||||||
import { FunctionComponent } from "react";
|
|
||||||
import { SSOResult } from "../models/SSOResult";
|
|
||||||
|
|
||||||
export const CallBackSuccess: FunctionComponent<SSOResult> = ({ configurationName }) => (
|
|
||||||
<>
|
|
||||||
<h1>Authentication complete for {configurationName}</h1>
|
|
||||||
<p>You will be redirected...</p>
|
|
||||||
</>
|
|
||||||
);
|
|
@ -1,9 +0,0 @@
|
|||||||
import { FunctionComponent } from "react";
|
|
||||||
import { SSOResult } from "../models/SSOResult";
|
|
||||||
|
|
||||||
export const ServiceWorkerNotSupported: FunctionComponent<SSOResult> = ({ configurationName }) => (
|
|
||||||
<>
|
|
||||||
<h1>Unable to authenticate on this browser for {configurationName}</h1>
|
|
||||||
<p>Your browser is not configured to support Service Workers.</p>
|
|
||||||
</>
|
|
||||||
);
|
|
@ -1,17 +0,0 @@
|
|||||||
import { useOidc } from "@axa-fr/react-oidc";
|
|
||||||
import { FunctionComponent } from "react";
|
|
||||||
import { SSOResult } from "../models/SSOResult";
|
|
||||||
|
|
||||||
export const SessionLost: FunctionComponent<SSOResult> = ({ configurationName }) => {
|
|
||||||
const { login } = useOidc(configurationName);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>Session timed out for {configurationName}</h1>
|
|
||||||
<p>Your session has expired. Please re-authenticate.</p>
|
|
||||||
<button type="button" onClick={() => login("/")}>
|
|
||||||
Login
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,28 +0,0 @@
|
|||||||
const { createProxyMiddleware } = require("http-proxy-middleware");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a simple proxy that automatically removes the prefix endpoint
|
|
||||||
* @param {*} app app to configure proxy on
|
|
||||||
* @param {*} endpoint endpoint you want to use for the proxy
|
|
||||||
* @param {*} target proxy target
|
|
||||||
*/
|
|
||||||
const createSimpleProxy = (app, endpoint, target) => {
|
|
||||||
app.use(
|
|
||||||
endpoint,
|
|
||||||
createProxyMiddleware({
|
|
||||||
target,
|
|
||||||
changeOrigin: true,
|
|
||||||
pathRewrite: {
|
|
||||||
[`^${endpoint}`]: "",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actual proxy configuration
|
|
||||||
* @param {*} app app to configure proxy on
|
|
||||||
*/
|
|
||||||
module.exports = function (app) {
|
|
||||||
createSimpleProxy(app, "/tendersguru", "https://tenders.guru");
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user