diff --git a/.github/workflows/docker_image.yml b/.github/workflows/docker_image.yml new file mode 100644 index 00000000..fa3641ee --- /dev/null +++ b/.github/workflows/docker_image.yml @@ -0,0 +1,71 @@ +name: Docker image + +on: + push: + branches: + - develop + tags: + - "[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + release: + name: Build & push backend image to Dockerhub + runs-on: ubuntu-latest + if: github.repository == 'MobileTeleSystems/syncmaster-ui' # prevent running on forks + + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set tag + id: set_tag + run: | + if [[ "${{ github.ref_type }}" == "branch" && "${{ github.ref_name }}" == "develop" ]]; then + echo "TAG=mtsrus/syncmaster-ui:develop" >> $GITHUB_ENV + elif [[ "${{ github.ref_type }}" == "tag" ]]; then + echo "TAG=mtsrus/syncmaster-ui:latest,mtsrus/syncmaster-ui:${{ github.ref_name }}" >> $GITHUB_ENV + fi + + - name: Build UI image + uses: docker/build-push-action@v6 + with: + tags: ${{ env.TAG }} + context: . + target: prod + file: Dockerfile + pull: true + push: true + cache-to: type=inline + cache-from: mtsrus/syncmaster-ui:develop + platforms: | + linux/amd64 + linux/arm64/v8 + provenance: mode=max + + - name: Update DockerHub Description + uses: peter-evans/dockerhub-description@v4 + if: github.ref_type == 'tag' + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + # this requires token with read+write+delete permissions. read+write is not enough! + password: ${{ secrets.DOCKERHUB_TOKEN }} + repository: mtsrus/syncmaster-ui + short-description: ${{ github.event.repository.description }} + enable-url-completion: true diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 00000000..29efa3db --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,37 @@ +name: Code analysis + +on: + push: + branches: + - develop + pull_request: + branches-ignore: + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + linters: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install modules + run: npm ci + + - name: Cache modules + uses: actions/cache@v4 + with: + path: ./node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} + ${{ runner.os }}-npm- + + - name: Run ESLint + run: npx eslint . + + - name: Run Prettier + run: npx prettier . --check diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.prettierrc b/.prettierrc index 4e6cb344..a4e2d239 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "tabWidth": 4, - "useTabs": false, - "printWidth": 80 + "tabWidth": 4, + "useTabs": false, + "printWidth": 80 } diff --git a/README.md b/README.md index b1092a96..1cdc7ed0 100644 --- a/README.md +++ b/README.md @@ -3,36 +3,37 @@ This interface is designed to work with the SyncMaster service. This interface contains 4 menu sections: Transfers, Connections, Queues, Groups. - To explore the source code, start with [src/App.tsx](https://github.com/MobileTeleSystems/syncmaster-ui/blob/develop/src/App.tsx). -## How to run +# How to run After having cloned the SyncMaster repository, run the following commands at the root directory: ```sh -npm install --global yarn - -yarn install - -yarn build - -yarn dev + npm install --global yarn + yarn install + yarn build + yarn dev ``` -These commands will install dependencies and launch the dev server, by going to localhost:3000 you can go to the SyncMaster_UI interface. -## How to format code +These commands will install dependencies and launch the dev server, by going to localhost:3000 you can go to the Syncmaster UI interface. + +# How to format code Run the following command at the root directory: ```sh -npm run prettier-format + npm run prettier-format ``` -## How to run linters +# How to run linters Run the following command at the root directory: ```sh -npx eslint --fix -``` \ No newline at end of file + npx eslint --fix +``` + +# Install pre-commit hooks + +Follow the instructions [here](https://prettier.io/docs/en/install). diff --git a/docker-compose.yml b/docker-compose.yml index 01b289cc..0fe756fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,11 @@ version: "3.8" services: syncmaster-ui: - image: syncmaster_ui + image: mtsrus/syncmaster-ui build: dockerfile: Dockerfile context: . network: host target: prod ports: - - 3000:3000 \ No newline at end of file + - 3000:3000 diff --git a/index.html b/index.html index e6606139..cef53f65 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -55,7 +55,7 @@ .loader:before, .loader:after { position: absolute; - content: ''; + content: ""; } .loader:before { @@ -111,10 +111,22 @@ href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet" /> - - - - + + + + diff --git a/index.tsx b/index.tsx index af3fd047..76774892 100644 --- a/index.tsx +++ b/index.tsx @@ -1,8 +1,8 @@ -import 'proxy-polyfill'; +import "proxy-polyfill"; -import * as React from 'react'; -import ReactDOM from 'react-dom'; +import * as React from "react"; +import ReactDOM from "react-dom"; -import App from './src/App'; +import App from "./src/App"; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render(, document.getElementById("root")); diff --git a/package-lock.json b/package-lock.json index dca0babd..044ad430 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,8 @@ "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.2", "globals": "^15.6.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.7", "prettier": "^3.3.2", "rewire": "^5.0.0", "rollup-plugin-visualizer": "^5.9.2", @@ -3195,6 +3197,112 @@ "node": ">=8" } }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", @@ -3244,6 +3352,21 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4417,6 +4540,68 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", @@ -4890,6 +5075,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -4909,6 +5106,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5215,6 +5424,30 @@ "node": ">= 0.8" } }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5647,6 +5880,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -6258,6 +6503,18 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -6279,6 +6536,159 @@ "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==", "license": "MIT" }, + "node_modules/lint-staged": { + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", + "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.2.tgz", + "integrity": "sha512-sy0dq+JPS+RAFiFk2K8Nbub7khNmeeoFALNUJ4Wzk34wZKAzaOhEXqGWs4RA5aui0RaM6Hgn7VEKhCj0mlKNLA==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -6319,6 +6729,178 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "license": "MIT" }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6407,6 +6989,12 @@ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "license": "MIT" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6615,6 +7203,33 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "license": "MIT" }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -7031,6 +7646,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", @@ -8494,6 +9121,12 @@ "which": "bin/which" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -8944,6 +9577,15 @@ "node": ">=4" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9058,6 +9700,18 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/package.json b/package.json index 39420567..f028aab7 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,11 @@ "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", - "prettier-format": "prettier --config .prettierrc 'src/**/*.tsx' --write" + "prettier-format": "prettier --config .prettierrc 'src/**/*.tsx' 'src/**/*.ts' --write", + "prepare": "husky" }, "devDependencies": { "@eslint/compat": "^1.1.0", - "eslint": "^8.57.0", "@eslint/js": "^9.5.0", "@types/fetch-mock": "^7.3.2", "@types/jest": "^29.5.2", @@ -58,8 +58,11 @@ "@types/react": "^17.0.20", "@types/react-dom": "^17.0.9", "@vitejs/plugin-react": "^2.2.0", + "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.2", "globals": "^15.6.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.7", "prettier": "^3.3.2", "rewire": "^5.0.0", "rollup-plugin-visualizer": "^5.9.2", @@ -70,5 +73,8 @@ "prettier": { "tabWidth": 4, "printWidth": 80 + }, + "lint-staged": { + "**/*": "prettier --write --ignore-unknown" } } diff --git a/public/manifest.json b/public/manifest.json index ef19ec24..1b288ed1 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,15 +1,15 @@ { - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": "./index.html", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" } diff --git a/src/i18n/en.ts b/src/i18n/en.ts index b2ffc73a..3c9f291e 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -1,223 +1,222 @@ -import { TranslationMessages } from 'react-admin'; -import englishMessages from 'ra-language-english'; +import { TranslationMessages } from "react-admin"; +import englishMessages from "ra-language-english"; const customEnglishMessages: TranslationMessages = { ...englishMessages, pos: { - search: 'Search', - configuration: 'Configuration', - language: 'Language', + search: "Search", + configuration: "Configuration", + language: "Language", theme: { - name: 'Theme', - light: 'Light', - dark: 'Dark', + name: "Theme", + light: "Light", + dark: "Dark", }, dashboard: { - monthly_revenue: 'Monthly Revenue', - month_history: '30 Day Revenue History', - new_orders: 'New Orders', - pending_reviews: 'Pending Reviews', - all_reviews: 'See all reviews', - new_customers: 'New Customers', - all_customers: 'See all customers', - pending_orders: 'Pending Orders', + monthly_revenue: "Monthly Revenue", + month_history: "30 Day Revenue History", + new_orders: "New Orders", + pending_reviews: "Pending Reviews", + all_reviews: "See all reviews", + new_customers: "New Customers", + all_customers: "See all customers", + pending_orders: "Pending Orders", order: { - items: - 'by %{customer_name}, one item |||| by %{customer_name}, %{nb_items} items', + items: "by %{customer_name}, one item |||| by %{customer_name}, %{nb_items} items", }, welcome: { - title: 'Welcome to the react-admin e-commerce demo', + title: "Welcome to the react-admin e-commerce demo", subtitle: "This is the admin of an imaginary poster shop. Feel free to explore and modify the data - it's local to your computer, and will reset each time you reload.", - ra_button: 'react-admin site', - demo_button: 'Source for this demo', + ra_button: "react-admin site", + demo_button: "Source for this demo", }, }, menu: { - sales: 'Sales', - catalog: 'Catalog', - customers: 'Customers', + sales: "Sales", + catalog: "Catalog", + customers: "Customers", }, events: { review: { title: 'Posted review on "%{product}"', }, order: { - title: 'Ordered 1 poster |||| Ordered %{smart_count} posters', + title: "Ordered 1 poster |||| Ordered %{smart_count} posters", }, }, }, resources: { customers: { - name: 'Customer |||| Customers', + name: "Customer |||| Customers", fields: { - commands: 'Orders', - first_seen: 'First seen', - full_name: 'Name', - groups: 'Segments', - last_seen: 'Last seen', - last_seen_gte: 'Visited Since', - name: 'Name', - total_spent: 'Total spent', - password: 'Password', - confirm_password: 'Confirm password', - stateAbbr: 'State', + commands: "Orders", + first_seen: "First seen", + full_name: "Name", + groups: "Segments", + last_seen: "Last seen", + last_seen_gte: "Visited Since", + name: "Name", + total_spent: "Total spent", + password: "Password", + confirm_password: "Confirm password", + stateAbbr: "State", }, filters: { - last_visited: 'Last visited', - today: 'Today', - this_week: 'This week', - last_week: 'Last week', - this_month: 'This month', - last_month: 'Last month', - earlier: 'Earlier', - has_ordered: 'Has ordered', - has_newsletter: 'Has newsletter', - group: 'Segment', + last_visited: "Last visited", + today: "Today", + this_week: "This week", + last_week: "Last week", + this_month: "This month", + last_month: "Last month", + earlier: "Earlier", + has_ordered: "Has ordered", + has_newsletter: "Has newsletter", + group: "Segment", }, fieldGroups: { - identity: 'Identity', - address: 'Address', - stats: 'Stats', - history: 'History', - password: 'Password', - change_password: 'Change Password', + identity: "Identity", + address: "Address", + stats: "Stats", + history: "History", + password: "Password", + change_password: "Change Password", }, page: { - delete: 'Delete Customer', + delete: "Delete Customer", }, errors: { password_mismatch: - 'The password confirmation is not the same as the password.', + "The password confirmation is not the same as the password.", }, }, commands: { - name: 'Order |||| Orders', - amount: '1 order |||| %{smart_count} orders', - title: 'Order %{reference}', + name: "Order |||| Orders", + amount: "1 order |||| %{smart_count} orders", + title: "Order %{reference}", fields: { basket: { - delivery: 'Delivery', - reference: 'Reference', - quantity: 'Quantity', - sum: 'Sum', - tax_rate: 'Tax Rate', - taxes: 'Tax', - total: 'Total', - unit_price: 'Unit Price', + delivery: "Delivery", + reference: "Reference", + quantity: "Quantity", + sum: "Sum", + tax_rate: "Tax Rate", + taxes: "Tax", + total: "Total", + unit_price: "Unit Price", }, - address: 'Address', - customer_id: 'Customer', - date_gte: 'Passed Since', - date_lte: 'Passed Before', - nb_items: 'Nb Items', - total_gte: 'Min amount', - status: 'Status', - returned: 'Returned', + address: "Address", + customer_id: "Customer", + date_gte: "Passed Since", + date_lte: "Passed Before", + nb_items: "Nb Items", + total_gte: "Min amount", + status: "Status", + returned: "Returned", }, section: { - order: 'Order', - customer: 'Customer', - shipping_address: 'Shipping Address', - items: 'Items', - total: 'Totals', + order: "Order", + customer: "Customer", + shipping_address: "Shipping Address", + items: "Items", + total: "Totals", }, }, invoices: { - name: 'Invoice |||| Invoices', + name: "Invoice |||| Invoices", fields: { - date: 'Invoice date', - customer_id: 'Customer', - command_id: 'Order', - date_gte: 'Passed Since', - date_lte: 'Passed Before', - total_gte: 'Min amount', - address: 'Address', + date: "Invoice date", + customer_id: "Customer", + command_id: "Order", + date_gte: "Passed Since", + date_lte: "Passed Before", + total_gte: "Min amount", + address: "Address", }, }, products: { - name: 'Poster |||| Posters', + name: "Poster |||| Posters", fields: { - category_id: 'Category', - height_gte: 'Min height', - height_lte: 'Max height', - height: 'Height', - image: 'Image', - price: 'Price', - reference: 'Reference', - sales: 'Sales', - stock_lte: 'Low Stock', - stock: 'Stock', - thumbnail: 'Thumbnail', - width_gte: 'Min width', - width_lte: 'Max width', - width: 'Width', + category_id: "Category", + height_gte: "Min height", + height_lte: "Max height", + height: "Height", + image: "Image", + price: "Price", + reference: "Reference", + sales: "Sales", + stock_lte: "Low Stock", + stock: "Stock", + thumbnail: "Thumbnail", + width_gte: "Min width", + width_lte: "Max width", + width: "Width", }, tabs: { - image: 'Image', - details: 'Details', - description: 'Description', - reviews: 'Reviews', + image: "Image", + details: "Details", + description: "Description", + reviews: "Reviews", }, filters: { - categories: 'Categories', - stock: 'Stock', - no_stock: 'Out of stock', - low_stock: '1 - 9 items', - average_stock: '10 - 49 items', - enough_stock: '50 items & more', - sales: 'Sales', - best_sellers: 'Best sellers', - average_sellers: 'Average', - low_sellers: 'Low', - never_sold: 'Never sold', + categories: "Categories", + stock: "Stock", + no_stock: "Out of stock", + low_stock: "1 - 9 items", + average_stock: "10 - 49 items", + enough_stock: "50 items & more", + sales: "Sales", + best_sellers: "Best sellers", + average_sellers: "Average", + low_sellers: "Low", + never_sold: "Never sold", }, }, categories: { - name: 'Category |||| Categories', + name: "Category |||| Categories", fields: { - products: 'Products', + products: "Products", }, }, reviews: { - name: 'Review |||| Reviews', - amount: '1 review |||| %{smart_count} reviews', - relative_to_poster: 'Review on poster', - detail: 'Review detail', + name: "Review |||| Reviews", + amount: "1 review |||| %{smart_count} reviews", + relative_to_poster: "Review on poster", + detail: "Review detail", fields: { - customer_id: 'Customer', - command_id: 'Order', - product_id: 'Product', - date_gte: 'Posted since', - date_lte: 'Posted before', - date: 'Date', - comment: 'Comment', - rating: 'Rating', + customer_id: "Customer", + command_id: "Order", + product_id: "Product", + date_gte: "Posted since", + date_lte: "Posted before", + date: "Date", + comment: "Comment", + rating: "Rating", }, action: { - accept: 'Accept', - reject: 'Reject', + accept: "Accept", + reject: "Reject", }, notification: { - approved_success: 'Review approved', - approved_error: 'Error: Review not approved', - rejected_success: 'Review rejected', - rejected_error: 'Error: Review not rejected', + approved_success: "Review approved", + approved_error: "Error: Review not approved", + rejected_success: "Review rejected", + rejected_error: "Error: Review not rejected", }, }, segments: { - name: 'Segment |||| Segments', + name: "Segment |||| Segments", fields: { - customers: 'Customers', - name: 'Name', + customers: "Customers", + name: "Name", }, data: { - compulsive: 'Compulsive', - collector: 'Collector', - ordered_once: 'Ordered once', - regular: 'Regular', - returns: 'Returns', - reviewer: 'Reviewer', + compulsive: "Compulsive", + collector: "Collector", + ordered_once: "Ordered once", + regular: "Regular", + returns: "Returns", + reviewer: "Reviewer", }, }, }, diff --git a/src/i18n/fr.ts b/src/i18n/fr.ts index 7154a150..14909fa9 100644 --- a/src/i18n/fr.ts +++ b/src/i18n/fr.ts @@ -1,238 +1,237 @@ -import { TranslationMessages } from 'react-admin'; -import frenchMessages from 'ra-language-french'; +import { TranslationMessages } from "react-admin"; +import frenchMessages from "ra-language-french"; const customFrenchMessages: TranslationMessages = { ...frenchMessages, pos: { - search: 'Rechercher', - configuration: 'Configuration', - language: 'Langue', + search: "Rechercher", + configuration: "Configuration", + language: "Langue", theme: { - name: 'Theme', - light: 'Clair', - dark: 'Obscur', + name: "Theme", + light: "Clair", + dark: "Obscur", }, dashboard: { - monthly_revenue: 'CA à 30 jours', + monthly_revenue: "CA à 30 jours", month_history: "Chiffre d'affaire sur 30 jours", - new_orders: 'Nouvelles commandes', - pending_reviews: 'Commentaires à modérer', - all_reviews: 'Voir tous les commentaires', - new_customers: 'Nouveaux clients', - all_customers: 'Voir tous les clients', - pending_orders: 'Commandes à traiter', + new_orders: "Nouvelles commandes", + pending_reviews: "Commentaires à modérer", + all_reviews: "Voir tous les commentaires", + new_customers: "Nouveaux clients", + all_customers: "Voir tous les clients", + pending_orders: "Commandes à traiter", order: { - items: - 'par %{customer_name}, un poster |||| par %{customer_name}, %{nb_items} posters', + items: "par %{customer_name}, un poster |||| par %{customer_name}, %{nb_items} posters", }, welcome: { - title: 'Bienvenue sur la démo e-commerce de react-admin', + title: "Bienvenue sur la démo e-commerce de react-admin", subtitle: "Ceci est le back-office d'un magasin de posters imaginaire. N'hésitez pas à explorer et à modifier les données. La démo s'exécute en local dans votre navigateur, et se remet à zéro chaque fois que vous rechargez la page.", - ra_button: 'Site web de react-admin', - demo_button: 'Code source de cette démo', + ra_button: "Site web de react-admin", + demo_button: "Code source de cette démo", }, }, menu: { - sales: 'Ventes', - catalog: 'Catalogue', - customers: 'Clients', + sales: "Ventes", + catalog: "Catalogue", + customers: "Clients", }, events: { review: { title: 'Commente sur "%{product}"', }, order: { - title: 'Commande 1 poster |||| Commande %{smart_count} posters', + title: "Commande 1 poster |||| Commande %{smart_count} posters", }, }, }, resources: { customers: { - name: 'Client |||| Clients', + name: "Client |||| Clients", fields: { - address: 'Rue', - birthday: 'Anniversaire', - city: 'Ville', - stateAbbr: 'Etat', - commands: 'Commandes', - first_name: 'Prénom', - first_seen: 'Première visite', - full_name: 'Nom', - groups: 'Segments', - has_newsletter: 'Abonné à la newsletter', - has_ordered: 'A commandé', - last_name: 'Nom', - last_seen: 'Vu le', - last_seen_gte: 'Vu depuis', - latest_purchase: 'Dernier achat', - name: 'Nom', - total_spent: 'Dépenses', - zipcode: 'Code postal', - password: 'Mot de passe', - confirm_password: 'Confirmez le mot de passe', + address: "Rue", + birthday: "Anniversaire", + city: "Ville", + stateAbbr: "Etat", + commands: "Commandes", + first_name: "Prénom", + first_seen: "Première visite", + full_name: "Nom", + groups: "Segments", + has_newsletter: "Abonné à la newsletter", + has_ordered: "A commandé", + last_name: "Nom", + last_seen: "Vu le", + last_seen_gte: "Vu depuis", + latest_purchase: "Dernier achat", + name: "Nom", + total_spent: "Dépenses", + zipcode: "Code postal", + password: "Mot de passe", + confirm_password: "Confirmez le mot de passe", }, filters: { - last_visited: 'Dernière visite', + last_visited: "Dernière visite", today: "Aujourd'hui", - this_week: 'Cette semaine', - last_week: 'La semaine dernière', - this_month: 'Ce mois-ci', - last_month: 'Le mois dernier', - earlier: 'Plus tôt', - has_ordered: 'A déjà commandé', - has_newsletter: 'Abonné newsletter', - group: 'Segment', + this_week: "Cette semaine", + last_week: "La semaine dernière", + this_month: "Ce mois-ci", + last_month: "Le mois dernier", + earlier: "Plus tôt", + has_ordered: "A déjà commandé", + has_newsletter: "Abonné newsletter", + group: "Segment", }, fieldGroups: { - identity: 'Identité', - address: 'Adresse', - stats: 'Statistiques', - history: 'Historique', - password: 'Mot de passe', - change_password: 'Changer le mot de passe', + identity: "Identité", + address: "Adresse", + stats: "Statistiques", + history: "Historique", + password: "Mot de passe", + change_password: "Changer le mot de passe", }, page: { - delete: 'Supprimer le client', + delete: "Supprimer le client", }, errors: { password_mismatch: - 'La confirmation du mot de passe est différent du mot de passe.', + "La confirmation du mot de passe est différent du mot de passe.", }, }, commands: { - name: 'Commande |||| Commandes', - amount: '1 commande |||| %{smart_count} commandes', - title: 'Commande n°%{reference}', + name: "Commande |||| Commandes", + amount: "1 commande |||| %{smart_count} commandes", + title: "Commande n°%{reference}", fields: { basket: { - delivery: 'Frais de livraison', - reference: 'Référence', - quantity: 'Quantité', - sum: 'Sous-total', - tax_rate: 'TVA', - taxes: 'TVA', - total: 'Total', - unit_price: 'P.U.', + delivery: "Frais de livraison", + reference: "Référence", + quantity: "Quantité", + sum: "Sous-total", + tax_rate: "TVA", + taxes: "TVA", + total: "Total", + unit_price: "P.U.", }, - address: 'Adresse', - customer_id: 'Client', - date_gte: 'Emises depuis', - date_lte: 'Emises avant', - nb_items: 'Nb articles', - reference: 'Référence', - returned: 'Annulée', - status: 'Etat', - total_gte: 'Montant minimum', + address: "Adresse", + customer_id: "Client", + date_gte: "Emises depuis", + date_lte: "Emises avant", + nb_items: "Nb articles", + reference: "Référence", + returned: "Annulée", + status: "Etat", + total_gte: "Montant minimum", }, section: { - order: 'Commande', - customer: 'Client', - shipping_address: 'Adresse de livraison', - items: 'Articles', - total: 'Total', + order: "Commande", + customer: "Client", + shipping_address: "Adresse de livraison", + items: "Articles", + total: "Total", }, }, invoices: { - name: 'Facture |||| Factures', + name: "Facture |||| Factures", fields: { - id: 'Numéro', - date: 'Date de facture', - customer_id: 'Client', - command_id: 'Commande', - date_gte: 'Emises depuis', - date_lte: 'Emises avant', - address: 'Adresse', - total_ex_taxes: 'Montant HT', - delivery_fees: 'Frais de livraison', - taxes: 'TVA', + id: "Numéro", + date: "Date de facture", + customer_id: "Client", + command_id: "Commande", + date_gte: "Emises depuis", + date_lte: "Emises avant", + address: "Adresse", + total_ex_taxes: "Montant HT", + delivery_fees: "Frais de livraison", + taxes: "TVA", }, }, products: { - name: 'Poster |||| Posters', + name: "Poster |||| Posters", fields: { - category_id: 'Catégorie', - height_gte: 'Hauteur mini', - height_lte: 'Hauteur maxi', - height: 'Hauteur', - image: 'Photo', - price: 'Prix', - reference: 'Référence', - sales: 'Ventes', - stock_lte: 'Stock faible', - stock: 'Stock', - thumbnail: 'Aperçu', - width_gte: 'Largeur mini', - width_lte: 'Margeur maxi', - width: 'Largeur', + category_id: "Catégorie", + height_gte: "Hauteur mini", + height_lte: "Hauteur maxi", + height: "Hauteur", + image: "Photo", + price: "Prix", + reference: "Référence", + sales: "Ventes", + stock_lte: "Stock faible", + stock: "Stock", + thumbnail: "Aperçu", + width_gte: "Largeur mini", + width_lte: "Margeur maxi", + width: "Largeur", }, tabs: { - image: 'Image', - details: 'Détails', - description: 'Description', - reviews: 'Commentaires', + image: "Image", + details: "Détails", + description: "Description", + reviews: "Commentaires", }, filters: { - categories: 'Catégories', - stock: 'Stock', - no_stock: 'En rupture', - low_stock: '1 - 9 unités', - average_stock: '10 - 49 unités', - enough_stock: '50 unités et plus', - sales: 'Ventes', - best_sellers: 'Meilleures ventes', - average_sellers: 'Moyennes', - low_sellers: 'Peu vendu', - never_sold: 'Jamais vendu', + categories: "Catégories", + stock: "Stock", + no_stock: "En rupture", + low_stock: "1 - 9 unités", + average_stock: "10 - 49 unités", + enough_stock: "50 unités et plus", + sales: "Ventes", + best_sellers: "Meilleures ventes", + average_sellers: "Moyennes", + low_sellers: "Peu vendu", + never_sold: "Jamais vendu", }, }, categories: { - name: 'Catégorie |||| Catégories', + name: "Catégorie |||| Catégories", fields: { - name: 'Nom', - products: 'Produits', + name: "Nom", + products: "Produits", }, }, reviews: { - name: 'Commentaire |||| Commentaires', - amount: '1 commentaire |||| %{smart_count} commentaires', - relative_to_poster: 'Commentaire sur', - detail: 'Détail du commentaire', + name: "Commentaire |||| Commentaires", + amount: "1 commentaire |||| %{smart_count} commentaires", + relative_to_poster: "Commentaire sur", + detail: "Détail du commentaire", fields: { - customer_id: 'Client', - command_id: 'Commande', - product_id: 'Produit', - date_gte: 'Publié depuis', - date_lte: 'Publié avant', - date: 'Date', - comment: 'Texte', - status: 'Statut', - rating: 'Classement', + customer_id: "Client", + command_id: "Commande", + product_id: "Produit", + date_gte: "Publié depuis", + date_lte: "Publié avant", + date: "Date", + comment: "Texte", + status: "Statut", + rating: "Classement", }, action: { - accept: 'Accepter', - reject: 'Rejeter', + accept: "Accepter", + reject: "Rejeter", }, notification: { - approved_success: 'Commentaire approuvé', - approved_error: 'Erreur: Commentaire non approuvé', - rejected_success: 'Commentaire rejeté', - rejected_error: 'Erreur: Commentaire non rejeté', + approved_success: "Commentaire approuvé", + approved_error: "Erreur: Commentaire non approuvé", + rejected_success: "Commentaire rejeté", + rejected_error: "Erreur: Commentaire non rejeté", }, }, segments: { - name: 'Segment |||| Segments', + name: "Segment |||| Segments", fields: { - customers: 'Clients', - name: 'Nom', + customers: "Clients", + name: "Nom", }, data: { - compulsive: 'Compulsif', - collector: 'Collectionneur', - ordered_once: 'A commandé', - regular: 'Régulier', - returns: 'A renvoyé', - reviewer: 'Commentateur', + compulsive: "Compulsif", + collector: "Collectionneur", + ordered_once: "A commandé", + regular: "Régulier", + returns: "A renvoyé", + reviewer: "Commentateur", }, }, }, diff --git a/src/shared/api/authProvider.ts b/src/shared/api/authProvider.ts index 5564b43b..838ef5e5 100644 --- a/src/shared/api/authProvider.ts +++ b/src/shared/api/authProvider.ts @@ -1,7 +1,6 @@ import { AuthProvider } from "react-admin"; import { getApiUrl } from "@shared/api/types"; - const authProvider: AuthProvider = { login: ({ username, password }) => { const formdata = new FormData(); diff --git a/src/themes/chiptuneTheme.ts b/src/themes/chiptuneTheme.ts index ff3cf65a..8dba9c79 100644 --- a/src/themes/chiptuneTheme.ts +++ b/src/themes/chiptuneTheme.ts @@ -1,16 +1,16 @@ -import { RaThemeOptions } from 'react-admin'; +import { RaThemeOptions } from "react-admin"; /** Just for fun */ export const chiptuneTheme: RaThemeOptions = { palette: { - mode: 'dark' as const, + mode: "dark" as const, primary: { - main: '#0f0', + main: "#0f0", }, background: { - default: '#111111', - paper: '#212121', + default: "#111111", + paper: "#212121", }, }, typography: { diff --git a/src/themes/softTheme.ts b/src/themes/softTheme.ts index 77c62d97..10fe8096 100644 --- a/src/themes/softTheme.ts +++ b/src/themes/softTheme.ts @@ -1,4 +1,4 @@ -import { defaultTheme } from 'react-admin'; +import { defaultTheme } from "react-admin"; /** * Soft: A gentle theme for apps with rich content (images, charts, maps, etc). @@ -9,12 +9,12 @@ import { defaultTheme } from 'react-admin'; export const softDarkTheme = { palette: { primary: { - main: '#90caf9', + main: "#90caf9", }, secondary: { - main: '#FBBA72', + main: "#FBBA72", }, - mode: 'dark' as const, // Switching the dark mode on is a single property value change. + mode: "dark" as const, // Switching the dark mode on is a single property value change. }, sidebar: { width: 200, @@ -24,9 +24,9 @@ export const softDarkTheme = { RaMenuItemLink: { styleOverrides: { root: { - borderLeft: '3px solid #000', - '&.RaMenuItemLink-active': { - borderLeft: '3px solid #90caf9', + borderLeft: "3px solid #000", + "&.RaMenuItemLink-active": { + borderLeft: "3px solid #90caf9", }, }, }, @@ -34,8 +34,8 @@ export const softDarkTheme = { MuiAppBar: { styleOverrides: { colorSecondary: { - color: '#ffffffb3', - backgroundColor: '#616161', + color: "#ffffffb3", + backgroundColor: "#616161", }, }, defaultProps: { @@ -48,18 +48,18 @@ export const softDarkTheme = { export const softLightTheme = { palette: { primary: { - main: '#4f3cc9', + main: "#4f3cc9", }, secondary: { - light: '#5f5fc4', - main: '#283593', - dark: '#001064', - contrastText: '#fff', + light: "#5f5fc4", + main: "#283593", + dark: "#001064", + contrastText: "#fff", }, background: { - default: '#fcfcfe', + default: "#fcfcfe", }, - mode: 'light' as const, + mode: "light" as const, }, shape: { borderRadius: 10, @@ -72,9 +72,9 @@ export const softLightTheme = { RaMenuItemLink: { styleOverrides: { root: { - borderLeft: '3px solid #fff', - '&.RaMenuItemLink-active': { - borderLeft: '3px solid #4f3cc9', + borderLeft: "3px solid #fff", + "&.RaMenuItemLink-active": { + borderLeft: "3px solid #4f3cc9", }, }, }, @@ -82,19 +82,19 @@ export const softLightTheme = { MuiPaper: { styleOverrides: { elevation1: { - boxShadow: 'none', + boxShadow: "none", }, root: { - border: '1px solid #e0e0e3', - backgroundClip: 'padding-box', + border: "1px solid #e0e0e3", + backgroundClip: "padding-box", }, }, }, MuiAppBar: { styleOverrides: { colorSecondary: { - color: '#808080', - backgroundColor: '#fff', + color: "#808080", + backgroundColor: "#fff", }, }, defaultProps: { @@ -104,17 +104,17 @@ export const softLightTheme = { MuiLinearProgress: { styleOverrides: { colorPrimary: { - backgroundColor: '#f5f5f5', + backgroundColor: "#f5f5f5", }, barColorPrimary: { - backgroundColor: '#d7d7d7', + backgroundColor: "#d7d7d7", }, }, }, MuiTableRow: { styleOverrides: { root: { - '&:last-child td': { border: 0 }, + "&:last-child td": { border: 0 }, }, }, }, diff --git a/tsconfig.json b/tsconfig.json index 47008f84..b990bd50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,47 +1,41 @@ { - "compilerOptions": { - "target": "es5", - "baseUrl": ".", - "paths": { - "@/*": [ - "src/*" - ], - "@widgets/*": ["src/widgets/*"], - "@themes/*": ["src/themes/*"], - "@shared/*": ["src/shared/*"], - "@i18n/*": ["src/i18n/*"], - "@hooks/*": ["src/hooks/*"], - "@features/*": ["src/features/*"], - "@entities/*": ["src/entities/*"], + "compilerOptions": { + "target": "es5", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "@widgets/*": ["src/widgets/*"], + "@themes/*": ["src/themes/*"], + "@shared/*": ["src/shared/*"], + "@i18n/*": ["src/i18n/*"], + "@hooks/*": ["src/hooks/*"], + "@features/*": ["src/features/*"], + "@entities/*": ["src/entities/*"] + }, + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" }, - "lib": [ - "dom", - "dom.iterable", - "esnext" + "include": [ + "./src/**/*.ts", + "./src/**/*.d.ts", + "./src/**/*.tsx", + "./src/**/*.d.tsx" ], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" - }, - "include": [ - "./src/**/*.ts", - "./src/**/*.d.ts", - "./src/**/*.tsx", - "./src/**/*.d.tsx", - ], - "references": [ - { - "path": "./tsconfig.node.json" - } - ] + "references": [ + { + "path": "./tsconfig.node.json" + } + ] } diff --git a/tsconfig.node.json b/tsconfig.node.json index f48610d7..13b35d0b 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,10 +1,9 @@ { "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] - } - \ No newline at end of file +} diff --git a/vite.config.ts b/vite.config.ts index 897a56da..6f860a6e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,7 +2,7 @@ import alias from "@rollup/plugin-alias"; import react from "@vitejs/plugin-react"; import visualizer from "rollup-plugin-visualizer"; import { defineConfig } from "vite"; -import path from 'path'; +import path from "path"; // https://vitejs.dev/config/ export default defineConfig({