From 233ce6fea49c95e1bea3653fda7c6d17c3f45281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A4ser?= Date: Mon, 23 Jan 2023 13:13:32 +0100 Subject: [PATCH] feat: Add mysql client --- apps/backend/.env.prod | 26 ++ apps/backend/.env.staging | 26 ++ apps/backend/config/database.ts | 5 +- apps/backend/config/plugins.ts | 7 +- apps/backend/mysql.yml | 20 ++ apps/backend/package-lock.json | 229 ++++++++++++++++++ apps/backend/package.json | 2 + .../src/admin/webpack.config.example.js | 3 + apps/backend/src/components/shared/seo.json | 2 +- apps/backend/tsconfig.json | 2 +- .../components/layout/layout.module.scss | 1 + apps/client/libs/api.ts | 2 +- apps/client/pages/home/index.tsx | 11 +- apps/client/pages/index.tsx | 11 +- .../pages/lost-password/index.module.scss | 7 + apps/client/pages/lost-password/index.tsx | 56 +++++ apps/client/pages/sign-in/index.tsx | 13 +- apps/client/pages/sign-up/index.module.scss | 2 +- apps/client/pages/sign-up/index.tsx | 33 ++- .../signup-confirmation/index.module.scss | 7 + .../pages/signup-confirmation/index.tsx | 42 ++++ docker-compose.yml | 14 +- package.json | 2 +- 23 files changed, 499 insertions(+), 24 deletions(-) create mode 100644 apps/backend/.env.prod create mode 100644 apps/backend/.env.staging create mode 100644 apps/backend/mysql.yml create mode 100644 apps/client/pages/lost-password/index.module.scss create mode 100644 apps/client/pages/lost-password/index.tsx create mode 100644 apps/client/pages/signup-confirmation/index.module.scss create mode 100644 apps/client/pages/signup-confirmation/index.tsx diff --git a/apps/backend/.env.prod b/apps/backend/.env.prod new file mode 100644 index 0000000..f2c9238 --- /dev/null +++ b/apps/backend/.env.prod @@ -0,0 +1,26 @@ +HOST=0.0.0.0 +PORT=1337 +APP_KEYS=chUnDYzQYwe0TBtXVv4sPg==,fVrGPGw5Xd4UdPisWHOHxQ==,Qre2n8wneae2BrXOotmagw==,B3suExWQFpyJS9mhqNcOLg== +API_TOKEN_SALT=tyYia7Nui8Y0lM0IRTDjmg== +ADMIN_JWT_SECRET=q1dnfyvh3K7yhTYbYNS7jw== +JWT_SECRET=nc8prafomnDTfDdS00OqTQ== + +PG_DATABASE_HOST=localhost +PG_DATABASE_PORT=5432 +PG_DATABASE_NAME=gs_database +PG_DATABASE_USERNAME=gs_username +PG_DATABASE_ROOT_PASSWORD=gs_root_username +PG_DATABASE_PASSWORD=gs_password +PG_DATABASE_SCHEMA=public + +MYSQL_DATABASE_HOST=localhost +MYSQL_DATABASE_PORT=3306 +MYSQL_DATABASE_NAME=dpxtrufj_gs_database +MYSQL_DATABASE_USERNAME=dpxtrufj_gs_username +MYSQL_DATABASE_ROOT_PASSWORD=gs_root_username +MYSQL_DATABASE_PASSWORD=q7=@oa*F*s4?8*Hq4H + +SMTP_HOST=node143-eu.n0c.com +SMTP_PORT=587 +SMTP_USERNAME=no-reply@nasercloud.fr +SMTP_PASSWORD=GuitarSchool123! diff --git a/apps/backend/.env.staging b/apps/backend/.env.staging new file mode 100644 index 0000000..f2c9238 --- /dev/null +++ b/apps/backend/.env.staging @@ -0,0 +1,26 @@ +HOST=0.0.0.0 +PORT=1337 +APP_KEYS=chUnDYzQYwe0TBtXVv4sPg==,fVrGPGw5Xd4UdPisWHOHxQ==,Qre2n8wneae2BrXOotmagw==,B3suExWQFpyJS9mhqNcOLg== +API_TOKEN_SALT=tyYia7Nui8Y0lM0IRTDjmg== +ADMIN_JWT_SECRET=q1dnfyvh3K7yhTYbYNS7jw== +JWT_SECRET=nc8prafomnDTfDdS00OqTQ== + +PG_DATABASE_HOST=localhost +PG_DATABASE_PORT=5432 +PG_DATABASE_NAME=gs_database +PG_DATABASE_USERNAME=gs_username +PG_DATABASE_ROOT_PASSWORD=gs_root_username +PG_DATABASE_PASSWORD=gs_password +PG_DATABASE_SCHEMA=public + +MYSQL_DATABASE_HOST=localhost +MYSQL_DATABASE_PORT=3306 +MYSQL_DATABASE_NAME=dpxtrufj_gs_database +MYSQL_DATABASE_USERNAME=dpxtrufj_gs_username +MYSQL_DATABASE_ROOT_PASSWORD=gs_root_username +MYSQL_DATABASE_PASSWORD=q7=@oa*F*s4?8*Hq4H + +SMTP_HOST=node143-eu.n0c.com +SMTP_PORT=587 +SMTP_USERNAME=no-reply@nasercloud.fr +SMTP_PASSWORD=GuitarSchool123! diff --git a/apps/backend/config/database.ts b/apps/backend/config/database.ts index e838feb..c9d5916 100644 --- a/apps/backend/config/database.ts +++ b/apps/backend/config/database.ts @@ -1,13 +1,12 @@ export default ({env}) => ({ connection: { - client: 'postgres', + client: 'mysql', connection: { host: env('DATABASE_HOST', 'localhost'), - port: env.int('DATABASE_PORT', 5432), + port: env.int('DATABASE_PORT', 3306), database: env('DATABASE_NAME', 'bank'), user: env('DATABASE_USERNAME', 'postgres'), password: env('DATABASE_PASSWORD', '0000'), - schema: env('DATABASE_SCHEMA', 'public'), // Not required ssl: false, }, debug: false, diff --git a/apps/backend/config/plugins.ts b/apps/backend/config/plugins.ts index b269e93..22a9096 100644 --- a/apps/backend/config/plugins.ts +++ b/apps/backend/config/plugins.ts @@ -13,10 +13,13 @@ module.exports = ({env}) => ({ // ... any custom nodemailer options }, settings: { - defaultFrom: 'no-reply@naser.fr', - defaultReplyTo: 'contact@naser.fr', + defaultFrom: 'no-reply@strapi.io', + defaultReplyTo: 'synology@naser.fr', }, }, }, + 'import-export-entries': { + enabled: true + } // ... }); diff --git a/apps/backend/mysql.yml b/apps/backend/mysql.yml new file mode 100644 index 0000000..1f98a98 --- /dev/null +++ b/apps/backend/mysql.yml @@ -0,0 +1,20 @@ +services: + gs_mysql: + image: 'mariadb:10.3' + environment: + MYSQL_DATABASE: ${DATABASE_NAME} + # So you don't have to use root, but you can if you like + MYSQL_USER: ${DATABASE_USERNAME} + # You can use whatever password you like + MYSQL_PASSWORD: ${DATABASE_PASSWORD} + # Password for root access + MYSQL_ROOT_PASSWORD: ${DATABASE_ROOT_PASSWORD} + ports: + # : < MySQL Port running inside container> + - '3307:3306' + expose: + # Opens port 3306 on the container + - '3307' + # Where our data will be persisted + volumes: + - gs_mariadb-master:/var/lib/mysql diff --git a/apps/backend/package-lock.json b/apps/backend/package-lock.json index 79f8598..7fcedc5 100644 --- a/apps/backend/package-lock.json +++ b/apps/backend/package-lock.json @@ -15,7 +15,9 @@ "@strapi/strapi": "4.5.4", "@strapi/utils": "^4.5.6", "better-sqlite3": "7.4.6", + "mysql": "^2.18.1", "pg": "^8.8.0", + "strapi-plugin-import-export-entries": "^1.18.0", "strapi-plugin-menus": "^1.2.1", "strapi-plugin-populate-deep": "^1.1.2" }, @@ -2457,6 +2459,19 @@ "react": ">=16.3" } }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, "node_modules/@internationalized/number": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.1.2.tgz", @@ -2560,6 +2575,31 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@monaco-editor/loader": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.2.tgz", + "integrity": "sha512-BTDbpHl3e47r3AAtpfVFTlAi7WXv4UQ/xZmz8atKl4q7epQV5e7+JbigFDViWF71VBi4IIBdcWP57Hj+OWuc9g==", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.4.5.tgz", + "integrity": "sha512-IImtzU7sRc66OOaQVCG+5PFHkSWnnhrUWGBuH6zNmH2h0YgmAhcjHZQc/6MY9JWEbUtVF1WPBMJ9u1XuFbRrVA==", + "dependencies": { + "@monaco-editor/loader": "^1.3.2", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@mswjs/cookies": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.2.2.tgz", @@ -2833,6 +2873,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/@sideway/address": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "node_modules/@simov/deep-extend": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@simov/deep-extend/-/deep-extend-1.0.0.tgz", @@ -5598,6 +5656,14 @@ "node": "*" } }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -5637,6 +5703,11 @@ "node": ">= 6" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -7070,6 +7141,22 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "node_modules/csvtojson": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz", + "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==", + "dependencies": { + "bluebird": "^3.5.1", + "lodash": "^4.17.3", + "strip-bom": "^2.0.0" + }, + "bin": { + "csvtojson": "bin/csvtojson" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -10235,6 +10322,11 @@ "upper-case": "^1.1.0" } }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==" + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -10315,6 +10407,18 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/joi": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", + "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", + "dependencies": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.3", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + } + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -11497,6 +11601,23 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "node_modules/monaco-editor": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", + "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==" + }, + "node_modules/monaco-editor-webpack-plugin": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-7.0.1.tgz", + "integrity": "sha512-M8qIqizltrPlIbrb73cZdTWfU9sIsUVFvAZkL3KGjAHmVWEJ0hZKa/uad14JuOckc0GwnCaoGHvMoYtJjVyCzw==", + "dependencies": { + "loader-utils": "^2.0.2" + }, + "peerDependencies": { + "monaco-editor": ">= 0.31.0", + "webpack": "^4.5.0 || 5.x" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -11626,6 +11747,52 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, + "node_modules/mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dependencies": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mysql/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/mysql/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/mysql/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/mysql/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -13835,6 +14002,22 @@ "react": "^16.3.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-singleton-hook": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-singleton-hook/-/react-singleton-hook-3.3.0.tgz", + "integrity": "sha512-U0qLp7LkpqPAnSQkKNPQmMd0mhar8hAm4VL+3y/bJFoi9H817wl+gM0z7RAMfOE49E8tlCMroEavqwJa6wItlg==", + "peerDependencies": { + "react": "15 - 18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -15264,6 +15447,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -15301,6 +15492,11 @@ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, "node_modules/static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -15402,6 +15598,28 @@ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.1.tgz", "integrity": "sha512-3H20QlwQsSm2OvAxWIYhs+j01MzzqwMwGiiO1NQaJYZgJZFPuAbf95/DiKRBSTYIJ2FeGUc+B/6mPGcWP9dO3Q==" }, + "node_modules/strapi-plugin-import-export-entries": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/strapi-plugin-import-export-entries/-/strapi-plugin-import-export-entries-1.18.0.tgz", + "integrity": "sha512-pAokLrqjd08JS7N/LUvsym3JTvja25J0xKw4zbPUDEt5Fdr/N9/N7wthKy6cv7TA7f6qJFq3q1RNtyjhJ5Cf/Q==", + "dependencies": { + "@monaco-editor/react": "4.4.5", + "csvtojson": "2.0.10", + "deepmerge": "^4.2.2", + "joi": "17.6.0", + "lodash": "4.17.21", + "monaco-editor": "0.33.0", + "monaco-editor-webpack-plugin": "7.0.1", + "react-singleton-hook": "3.3.0" + }, + "engines": { + "node": ">=12.x.x <=18.x.x", + "npm": ">=6.0.0" + }, + "peerDependencies": { + "@strapi/strapi": "^4.0.0" + } + }, "node_modules/strapi-plugin-menus": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/strapi-plugin-menus/-/strapi-plugin-menus-1.2.1.tgz", @@ -15619,6 +15837,17 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", diff --git a/apps/backend/package.json b/apps/backend/package.json index ef0b305..a7bbddc 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -20,7 +20,9 @@ "@strapi/strapi": "4.5.4", "@strapi/utils": "^4.5.6", "better-sqlite3": "7.4.6", + "mysql": "^2.18.1", "pg": "^8.8.0", + "strapi-plugin-import-export-entries": "^1.18.0", "strapi-plugin-menus": "^1.2.1", "strapi-plugin-populate-deep": "^1.1.2" }, diff --git a/apps/backend/src/admin/webpack.config.example.js b/apps/backend/src/admin/webpack.config.example.js index 1ca45c2..b42dfe6 100644 --- a/apps/backend/src/admin/webpack.config.example.js +++ b/apps/backend/src/admin/webpack.config.example.js @@ -1,9 +1,12 @@ 'use strict'; +const MonacoWebackPlugin = require('monaco-editor-webpack-plugin'); /* eslint-disable no-unused-vars */ module.exports = (config, webpack) => { // Note: we provide webpack above so you should not `require` it // Perform customizations to webpack config // Important: return the modified config + + config.plugins.push(new MonacoWebackPlugin()) return config; }; diff --git a/apps/backend/src/components/shared/seo.json b/apps/backend/src/components/shared/seo.json index c9f433e..a4a386a 100644 --- a/apps/backend/src/components/shared/seo.json +++ b/apps/backend/src/components/shared/seo.json @@ -11,7 +11,7 @@ "type": "string" }, "metaDescription": { - "type": "string" + "type": "text" }, "SharedImage": { "displayName": "SharedImage", diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index b9532e3..76e3e00 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@strapi/typescript-utils/tsconfigs/server", "compilerOptions": { - "outDir": "dist", + "outDir": "../../dist/backend/dist", "rootDir": "." }, "include": [ diff --git a/apps/client/components/layout/layout.module.scss b/apps/client/components/layout/layout.module.scss index 3c10a36..76fd24c 100644 --- a/apps/client/components/layout/layout.module.scss +++ b/apps/client/components/layout/layout.module.scss @@ -64,6 +64,7 @@ @media (min-width: 1024px) { .app-container:not(.without-footer) { .app-content { + padding-top: 135px; min-height: calc(100vh - 181px); } } diff --git a/apps/client/libs/api.ts b/apps/client/libs/api.ts index 88f13d5..9103767 100644 --- a/apps/client/libs/api.ts +++ b/apps/client/libs/api.ts @@ -28,7 +28,7 @@ export const signUpRequest = async (inputs: Inputs) => { username: inputs.username, newsletter: inputs.newsletter }); - return registerResponse && !registerResponse.data.error; + return registerResponse.data; } catch (err) { return Promise.reject('Internal error'); } diff --git a/apps/client/pages/home/index.tsx b/apps/client/pages/home/index.tsx index 6b8e476..b130843 100644 --- a/apps/client/pages/home/index.tsx +++ b/apps/client/pages/home/index.tsx @@ -4,11 +4,20 @@ import delve from "dlv"; import SeoConfig from "../../components/seo-config/seo-config"; import Layout from "../../components/layout/layout"; +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} + export const getServerSideProps = async (context) => { const path = context.resolvedUrl; const menuHeader = await axios.get(`${process.env.STRAPI_URL_API}/menus/1?nested&populate=deep`); const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); - const page = await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + const page = await getPageMetadata(path); return { props: { menuHeader: delve(menuHeader, 'data.data.attributes.items.data', []), diff --git a/apps/client/pages/index.tsx b/apps/client/pages/index.tsx index 48cf67c..47093d8 100644 --- a/apps/client/pages/index.tsx +++ b/apps/client/pages/index.tsx @@ -5,11 +5,20 @@ import SeoConfig from "../components/seo-config/seo-config"; import Layout from "../components/layout/layout"; +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} + export const getServerSideProps = async (context) => { const path = context.resolvedUrl; const menuHeader = await axios.get(`${process.env.STRAPI_URL_API}/menus/1?nested&populate=deep`); const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); - const page = await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path}&populate=deep`); + const page = await getPageMetadata(path); return { props: { menuHeader: delve(menuHeader, 'data.data.attributes.items.data', []), diff --git a/apps/client/pages/lost-password/index.module.scss b/apps/client/pages/lost-password/index.module.scss new file mode 100644 index 0000000..45c2aa4 --- /dev/null +++ b/apps/client/pages/lost-password/index.module.scss @@ -0,0 +1,7 @@ +/* + * Replace this with your own classes + * + * e.g. + * .container { + * } +*/ diff --git a/apps/client/pages/lost-password/index.tsx b/apps/client/pages/lost-password/index.tsx new file mode 100644 index 0000000..dcbc6ca --- /dev/null +++ b/apps/client/pages/lost-password/index.tsx @@ -0,0 +1,56 @@ +import axios from "axios"; +import delve from "dlv"; +import SeoConfig from "../../components/seo-config/seo-config"; +import Layout from "../../components/layout/layout"; +import styles from "../sign-up/index.module.scss"; + +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} + +export const getServerSideProps = async (context) => { + const path = context.resolvedUrl; + const menuHeader = await axios.get(`${process.env.STRAPI_URL_API}/menus/1?nested&populate=deep`); + const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); + const page = await getPageMetadata(path); + return { + props: { + menuHeaders: delve(menuHeader, 'data.data.attributes.items.data', []), + menuFooter: delve(menuFooter, 'data.data.attributes.items.data', []), + page: delve(page, "data.data.0.attributes", {}), + seo: delve(page, "data.data.0.attributes.seo", {}) + } + } +} + +export function LostPassword({menuHeaders, menuFooter, page, seo}) { + return ( + <> + + +
+
+
+
+
+

Form here

+
+
+ Phone image +
+
+
+
+
+
+ + ); +} + +export default LostPassword; diff --git a/apps/client/pages/sign-in/index.tsx b/apps/client/pages/sign-in/index.tsx index 732487a..0cd70bb 100644 --- a/apps/client/pages/sign-in/index.tsx +++ b/apps/client/pages/sign-in/index.tsx @@ -8,10 +8,19 @@ import Layout from "../../components/layout/layout"; import styles from './index.module.scss'; import {createJwtToken} from "../../libs/auth"; +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} + export const getServerSideProps = async (context) => { const path = context.resolvedUrl; const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); - const page = await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + const page = await getPageMetadata(path); return { props: { @@ -95,7 +104,7 @@ export function SignIn({seo, menuFooter}) { Rester connecté ? - Mot de passe oublié ? diff --git a/apps/client/pages/sign-up/index.module.scss b/apps/client/pages/sign-up/index.module.scss index b20d148..1199be9 100644 --- a/apps/client/pages/sign-up/index.module.scss +++ b/apps/client/pages/sign-up/index.module.scss @@ -8,7 +8,7 @@ .page-sign-up { .section { - min-height: 70vh; + min-height: 63vh; justify-content: center; display: flex; align-items: center; diff --git a/apps/client/pages/sign-up/index.tsx b/apps/client/pages/sign-up/index.tsx index 9067176..7e2918e 100644 --- a/apps/client/pages/sign-up/index.tsx +++ b/apps/client/pages/sign-up/index.tsx @@ -9,13 +9,22 @@ import Layout from "../../components/layout/layout"; import {Inputs, signUpRequest} from "../../libs/api"; import {createJwtToken} from "../../libs/auth"; import {useEffect, useState} from "react"; -import {BehaviorSubject, debounceTime, distinctUntilChanged, filter, map, switchMap} from "rxjs"; +import {BehaviorSubject, catchError, debounceTime, distinctUntilChanged, filter, map, of, switchMap} from "rxjs"; + +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} export const getServerSideProps = async (context) => { const path = context.resolvedUrl; const menuHeader = await axios.get(`${process.env.STRAPI_URL_API}/menus/1?nested&populate=deep`); const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); - const page = await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + const page = await getPageMetadata(path); return { props: { @@ -61,17 +70,27 @@ export function SignUp({seo, menuHeaders, menuFooter}) { clearErrors('email'); } }), + catchError((err) => of(false)) ).subscribe(() => setSpinner(false)); } }, [subject]); const onSubmit: SubmitHandler = async (data: Inputs) => { try { - await signUpRequest(data); - const result = await createJwtToken(data.email, data.password); - if (result.ok) { - await router.replace('/'); - return; + const response = await signUpRequest(data); + if (response && response.user) { + if (response.user.confirmed) { + const result = await createJwtToken(data.email, data.password); + if (result.ok) { + await router.replace('/'); + return; + } + } else { + await router.push('/signup-confirmation') + return; + } + } else { + throw new Error('no registered'); } } catch (e) { console.error(e); diff --git a/apps/client/pages/signup-confirmation/index.module.scss b/apps/client/pages/signup-confirmation/index.module.scss new file mode 100644 index 0000000..45c2aa4 --- /dev/null +++ b/apps/client/pages/signup-confirmation/index.module.scss @@ -0,0 +1,7 @@ +/* + * Replace this with your own classes + * + * e.g. + * .container { + * } +*/ diff --git a/apps/client/pages/signup-confirmation/index.tsx b/apps/client/pages/signup-confirmation/index.tsx new file mode 100644 index 0000000..f3c7e00 --- /dev/null +++ b/apps/client/pages/signup-confirmation/index.tsx @@ -0,0 +1,42 @@ +import axios from "axios"; +import delve from 'dlv'; + +import SeoConfig from "../../components/seo-config/seo-config"; +import Layout from "../../components/layout/layout"; + +const getPageMetadata = async (path) => { + try { + return await axios.get(`${process.env.STRAPI_URL_API}/pages?filters[slug]=${path === '/' ? 'home' : path.slice(1, path.length)}&populate=deep`); + } catch (e) { + console.error(e); + return Promise.resolve({}) + } +} + +export const getServerSideProps = async (context) => { + const path = context.resolvedUrl; + const menuHeader = await axios.get(`${process.env.STRAPI_URL_API}/menus/1?nested&populate=deep`); + const menuFooter = await axios.get(`${process.env.STRAPI_URL_API}/menus/2?nested&populate=deep`); + const page = await getPageMetadata(path); + return { + props: { + menuHeader: delve(menuHeader, 'data.data.attributes.items.data', []), + menuFooter: delve(menuFooter, 'data.data.attributes.items.data', []), + page: delve(page, "data.data.0.attributes", {}), + seo: delve(page, "data.data.0.attributes.seo", {}) + } + } +} + +export function SignupConfirmation({menuHeader, menuFooter, page, seo}) { + return ( + <> + + +

Page d'accueil

+
+ + ); +} + +export default SignupConfirmation; diff --git a/docker-compose.yml b/docker-compose.yml index 3948b2f..c0b23ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,16 @@ services: # PostgreSQL (Database) - gs_postgres: + #gs_postgres: + # extends: + # file: apps/backend/postgres.yml + # service: gs_postgres + + # MySQL (Database) + gs_mysql: extends: - file: apps/backend/postgres.yml - service: gs_postgres + file: apps/backend/mysql.yml + service: gs_mysql gs_redis: image: "redis:alpine" @@ -23,3 +29,5 @@ services: volumes: gs_postgres-master: driver: local + gs_mariadb-master: + driver: local diff --git a/package.json b/package.json index c603546..cfb5547 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "license": "MIT", "scripts": { - "start:docker": "env $(cat apps/backend/.env) docker-compose up -d", + "start:docker": "env $(cat apps/backend/.env) docker-compose up -d --force-recreate", "install:backend": "cd apps/backend && npm install", "generate:backend": "cd apps/backend && npm run generate", "build:backend": "cd apps/backend && npm run build",