From b7edae4b17c9b43fd436959916e98e2d7e78d560 Mon Sep 17 00:00:00 2001 From: Cyrildab <144703835+Cyrildab@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:07:11 +0100 Subject: [PATCH] Feat 5410 create login page (#22) * add login page elements * added logo * added login page & components * add translations * add translations * added modifications * added modifications * added new scss * added tests * modified PR * [fix] router == >LoginPage --------- Co-authored-by: blackstars --- .github/workflows/e2e_tests.yml | 3 + backend/package-lock.json | 284 ++---------------- backend/package.json | 2 +- frontend/src/App.tsx | 2 +- frontend/src/assets/_variables.scss | 41 +++ frontend/src/assets/icons/blob/blob3.svg | 3 + frontend/src/assets/icons/loging-page-img.svg | 10 + .../atoms/BasicButton/BasicButton.scss | 39 ++- .../atoms/BasicButton/BasicButton.type.ts | 2 +- .../components/atoms/BasicButton/index.tsx | 4 +- .../atoms/ImputField/ImputField.scss | 26 ++ .../atoms/ImputField/ImputField.tsx | 36 +++ .../atoms/LittleLogo/LittleLogo.scss | 10 + .../atoms/LittleLogo/LittleLogo.type.ts | 1 + .../src/components/atoms/LittleLogo/index.tsx | 48 +-- .../atoms/LoginImage/LoginImage.scss | 4 + .../atoms/LoginImage/LoginImage.type.ts | 3 + .../src/components/atoms/LoginImage/index.tsx | 24 ++ frontend/src/index.css | 6 +- .../components/FirstView/FirstView.scss | 6 +- .../components/FirstView/index.tsx | 8 +- frontend/src/pages/LoginPage/LoginPage.scss | 210 +++++++++++++ frontend/src/pages/LoginPage/index.tsx | 92 ++++++ frontend/src/routes.tsx | 16 +- frontend/src/tests/App.test.tsx | 13 +- .../src/tests/__snapshots__/App.test.tsx.snap | 10 +- .../pages/LandingPage/LandingPage.test.tsx | 7 +- .../__snapshots__/LandingPage.test.tsx.snap | 10 +- .../LandingPage/components/FirstView.test.tsx | 7 +- .../__snapshots__/FirstView.test.tsx.snap | 10 +- .../locales/en/translation.json | 10 + .../locales/fr/translation.json | 10 + 32 files changed, 643 insertions(+), 314 deletions(-) create mode 100644 frontend/src/assets/icons/blob/blob3.svg create mode 100644 frontend/src/assets/icons/loging-page-img.svg create mode 100644 frontend/src/components/atoms/ImputField/ImputField.scss create mode 100644 frontend/src/components/atoms/ImputField/ImputField.tsx create mode 100644 frontend/src/components/atoms/LoginImage/LoginImage.scss create mode 100644 frontend/src/components/atoms/LoginImage/LoginImage.type.ts create mode 100644 frontend/src/components/atoms/LoginImage/index.tsx create mode 100644 frontend/src/pages/LoginPage/LoginPage.scss create mode 100644 frontend/src/pages/LoginPage/index.tsx diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index e41237c3..f31288f3 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -20,6 +20,9 @@ jobs: - name: Debugs logs 2 run: ls -l + - name: install playwright + run: npm init playwright@latest + - name: Run interface test run: docker compose -f docker-compose.e2e.yml up --build --exit-code-from e2e diff --git a/backend/package-lock.json b/backend/package-lock.json index 075edf05..2c8faf17 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -23,7 +23,7 @@ "typeorm": "^0.3.20" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "^1.9.4", "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/jsonwebtoken": "^9.0.6", @@ -1018,74 +1018,6 @@ "@biomejs/cli-win32-x64": "1.9.4" } }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, "node_modules/@biomejs/cli-linux-x64": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", @@ -1120,23 +1052,6 @@ "node": ">=14.21.3" } }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, "node_modules/@biomejs/cli-win32-x64": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", @@ -1443,6 +1358,13 @@ "@types/node": "*" } }, + "node_modules/@jest/core/node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, "node_modules/@jest/core/node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1747,21 +1669,6 @@ "dev": true, "license": "ISC" }, - "node_modules/@jest/core/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/@jest/core/node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -3019,20 +2926,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, - "node_modules/@jest/transform/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/@jest/transform/node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3439,6 +3332,12 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "license": "MIT" }, + "node_modules/@jest/types/node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, "node_modules/@jest/types/node_modules/@types/istanbul-reports": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", @@ -3539,45 +3438,13 @@ "license": "MIT" }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } + "dev": true }, "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "dev": true }, + "node_modules/@types/body-parser": {}, + "node_modules/@types/connect": {}, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -3602,27 +3469,7 @@ "@types/send": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, + "node_modules/@types/istanbul-lib-report": {}, "node_modules/@types/jest": { "version": "29.5.14", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", @@ -3645,18 +3492,8 @@ "@types/node": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/node": { "version": "22.13.1", @@ -3739,45 +3576,16 @@ "node": ">= 0.6" } }, - "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, + "node_modules/@types/qs": {}, + "node_modules/@types/range-parser": {}, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "license": "MIT" }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, + "node_modules/@types/send": {}, + "node_modules/@types/serve-static": {}, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3790,12 +3598,7 @@ "integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==", "license": "MIT" }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, + "node_modules/@types/yargs-parser": {}, "node_modules/apollo-server": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-3.13.0.tgz", @@ -5895,21 +5698,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chokidar/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -7644,6 +7432,13 @@ "@types/node": "*" } }, + "node_modules/jest-cli/node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, "node_modules/jest-cli/node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -7906,21 +7701,6 @@ "dev": true, "license": "ISC" }, - "node_modules/jest-cli/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/jest-cli/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", diff --git a/backend/package.json b/backend/package.json index 7ff132dc..1b111b38 100644 --- a/backend/package.json +++ b/backend/package.json @@ -28,7 +28,7 @@ "typeorm": "^0.3.20" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "^1.9.4", "@types/express": "^4.17.21", "@types/jest": "^29.5.14", "@types/jsonwebtoken": "^9.0.6", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3b9c32ec..84842a6c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,5 @@ import "./App.css"; -import LandingPage from "@pages/LandingPage"; +import LandingPage from "./pages/LandingPage"; function App() { return ; diff --git a/frontend/src/assets/_variables.scss b/frontend/src/assets/_variables.scss index 6592dbcf..5d0b5a67 100644 --- a/frontend/src/assets/_variables.scss +++ b/frontend/src/assets/_variables.scss @@ -40,6 +40,47 @@ margin: 0; } +@mixin landing-page-title-desktop{ + font-size: 80px; + font-weight: 600; + margin: 0; +} + +@mixin landing-page-title-phone{ + font-size: 40px; + font-weight: 600; + margin: 0; +} + +@mixin logo-big-label{ + font-size: 34px; + font-weight: bold; + margin: 0; +} + +@mixin h1-phone{ + font-size: 24px; + font-weight: bold; + margin: 0; +} + +@mixin h2-phone{ + font-size: 18px; + font-weight: bold; + margin: 0; +} + +@mixin h3-phone{ + font-size: 14px; + margin: 0; +} + +@mixin logo-litle-label{ + font-size: 14px; + font-weight: bold; + margin: 0; +} + //Color $primary: #132945; $secondary: #E23823; diff --git a/frontend/src/assets/icons/blob/blob3.svg b/frontend/src/assets/icons/blob/blob3.svg new file mode 100644 index 00000000..21d1a86b --- /dev/null +++ b/frontend/src/assets/icons/blob/blob3.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/icons/loging-page-img.svg b/frontend/src/assets/icons/loging-page-img.svg new file mode 100644 index 00000000..294bb7a5 --- /dev/null +++ b/frontend/src/assets/icons/loging-page-img.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/frontend/src/components/atoms/BasicButton/BasicButton.scss b/frontend/src/components/atoms/BasicButton/BasicButton.scss index 1e935198..bf51f1dd 100644 --- a/frontend/src/components/atoms/BasicButton/BasicButton.scss +++ b/frontend/src/components/atoms/BasicButton/BasicButton.scss @@ -9,13 +9,18 @@ border-radius: 10px; padding: 14px 24px; border: none; - width: 300; - height: 50; + width: 300px; + height: 50px; + transition: background-color 0.3s ease; &:disabled { opacity: 0.5; border: 1px solid $white; } + + &:hover { + background-color: darken($secondary, 10%); + } } &--white { @@ -26,8 +31,9 @@ border-radius: 10px; padding: 14px 24px; border: none; - width: 300; - height: 50; + width: 300px; + height: 50px; + transition: background-color 0.3s ease; &--focus { &:focus { @@ -46,4 +52,29 @@ color: $white; } } + + &--orange { + background-color: $secondary; + color: $white; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + padding: 14px 24px; + width: 260px; + transition: background-color 0.3s ease; + + &:hover { + background-color: darken($secondary, 10%); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &--focus { + outline: 2px solid $primary; + } + } } diff --git a/frontend/src/components/atoms/BasicButton/BasicButton.type.ts b/frontend/src/components/atoms/BasicButton/BasicButton.type.ts index 3470220a..cf1d5564 100644 --- a/frontend/src/components/atoms/BasicButton/BasicButton.type.ts +++ b/frontend/src/components/atoms/BasicButton/BasicButton.type.ts @@ -2,6 +2,6 @@ export interface BasicButtonProps extends React.ButtonHTMLAttributes { children: React.ReactNode; classnames?: string; - typeButton?: "basic" | "white"; + typeButton?: "basic" | "white" | "orange"; hasFocus?: boolean; } diff --git a/frontend/src/components/atoms/BasicButton/index.tsx b/frontend/src/components/atoms/BasicButton/index.tsx index ed9ea8f1..5105f288 100644 --- a/frontend/src/components/atoms/BasicButton/index.tsx +++ b/frontend/src/components/atoms/BasicButton/index.tsx @@ -12,7 +12,9 @@ function BasicButton({ const buttonClass = classNames("basic-button", className, { "basic-button--basic": typeButton === "basic", "basic-button--white": typeButton === "white", - "basic-button--white--focus": hasFocus, + "basic-button--orange": typeButton === "orange", + "basic-button--white--focus": typeButton === "white" && hasFocus, + "basic-button--orange--focus": typeButton === "orange" && hasFocus, }); return ( diff --git a/frontend/src/components/atoms/ImputField/ImputField.scss b/frontend/src/components/atoms/ImputField/ImputField.scss new file mode 100644 index 00000000..e532fbed --- /dev/null +++ b/frontend/src/components/atoms/ImputField/ImputField.scss @@ -0,0 +1,26 @@ +@import "@assets/variables.scss"; + +.input__login-page { + background-color: $white; + border: 2px solid grey; + border-radius: 5px; + padding: 10px 15px; + width: 230px; + font-size: 16px; + z-index: 1; + transition: border-color 0.3s ease, box-shadow 0.3s ease; + + &:hover { + border-color: $primary; + } + + &:focus { + outline: none; + border-color: $secondary; + box-shadow: 0 0 5px $secondary; + } + + &::placeholder { + color: grey; + } +} \ No newline at end of file diff --git a/frontend/src/components/atoms/ImputField/ImputField.tsx b/frontend/src/components/atoms/ImputField/ImputField.tsx new file mode 100644 index 00000000..1d9e3951 --- /dev/null +++ b/frontend/src/components/atoms/ImputField/ImputField.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import "./ImputField.scss"; + +interface InputFieldProps { + name: string; + type: string; + placeholderKey: string; + register: any; + required?: boolean; + ariaLabel: string; +} + +const InputField: React.FC = ({ + name, + type, + placeholderKey, + register, + required = false, + ariaLabel, +}) => { + const { t } = useTranslation(); + + return ( + + ); +}; + +export default InputField; \ No newline at end of file diff --git a/frontend/src/components/atoms/LittleLogo/LittleLogo.scss b/frontend/src/components/atoms/LittleLogo/LittleLogo.scss index cfd807d8..79032253 100644 --- a/frontend/src/components/atoms/LittleLogo/LittleLogo.scss +++ b/frontend/src/components/atoms/LittleLogo/LittleLogo.scss @@ -6,6 +6,16 @@ align-items: center; justify-content: center; + @media (min-width: 768px) { + display: flex; + position: absolute; + top: 40px; + left: 40px; + flex-direction: column; + align-items: center; + justify-content: center; + } + &--giant { width: 408px; height: 284px; diff --git a/frontend/src/components/atoms/LittleLogo/LittleLogo.type.ts b/frontend/src/components/atoms/LittleLogo/LittleLogo.type.ts index e597b8a8..da81499b 100644 --- a/frontend/src/components/atoms/LittleLogo/LittleLogo.type.ts +++ b/frontend/src/components/atoms/LittleLogo/LittleLogo.type.ts @@ -1,4 +1,5 @@ export interface LittleLogoProps { hasLabel?: boolean; size?: "mobile" | "giant" | "desktop"; + className?: string; } diff --git a/frontend/src/components/atoms/LittleLogo/index.tsx b/frontend/src/components/atoms/LittleLogo/index.tsx index 2ea3863a..5421d60d 100644 --- a/frontend/src/components/atoms/LittleLogo/index.tsx +++ b/frontend/src/components/atoms/LittleLogo/index.tsx @@ -4,29 +4,33 @@ import "./LittleLogo.scss"; import logoMobile from "@assets/icons/mobile-logo.svg"; import type { LittleLogoProps } from "./LittleLogo.type"; -function LittleLogo({ hasLabel = false, size = "desktop" }: LittleLogoProps) { - const littleLogoClassName = classNames("little-logo", { - "little-logo--mobile": size === "mobile", - "little-logo--giant": size === "giant", - "little-logo--desktop": size === "desktop", - }); +const LittleLogo: React.FC = ({ + hasLabel = false, + size = "desktop", + className, +}) => { + const littleLogoClassName = classNames("little-logo", className, { + "little-logo--mobile": size === "mobile", + "little-logo--giant": size === "giant", + "little-logo--desktop": size === "desktop", + }); - const littleLogoTitleClassName = classNames("little-logo__title", { - "little-logo__title--mobile": size === "mobile", - "little-logo__title--giant": size === "giant", - "little-logo__title--desktop": size === "desktop", - }); + const littleLogoTitleClassName = classNames("little-logo__title", { + "little-logo__title--mobile": size === "mobile", + "little-logo__title--giant": size === "giant", + "little-logo__title--desktop": size === "desktop", + }); - return ( -
- Logo Pulse Form - {hasLabel &&

{"Pulse Form"}

} -
- ); -} + return ( +
+ Logo Pulse Form + {hasLabel &&

Pulse Form

} +
+ ); +}; export default LittleLogo; diff --git a/frontend/src/components/atoms/LoginImage/LoginImage.scss b/frontend/src/components/atoms/LoginImage/LoginImage.scss new file mode 100644 index 00000000..88c28066 --- /dev/null +++ b/frontend/src/components/atoms/LoginImage/LoginImage.scss @@ -0,0 +1,4 @@ +.login-image__img { + box-shadow: 50px 50px 50px rgba(0, 0, 0, 0.4); + width: 600px; +} \ No newline at end of file diff --git a/frontend/src/components/atoms/LoginImage/LoginImage.type.ts b/frontend/src/components/atoms/LoginImage/LoginImage.type.ts new file mode 100644 index 00000000..4eaecd1d --- /dev/null +++ b/frontend/src/components/atoms/LoginImage/LoginImage.type.ts @@ -0,0 +1,3 @@ +export interface LoginImageProps { + size?: "mobile" | "giant" | "desktop"; +} \ No newline at end of file diff --git a/frontend/src/components/atoms/LoginImage/index.tsx b/frontend/src/components/atoms/LoginImage/index.tsx new file mode 100644 index 00000000..6130e466 --- /dev/null +++ b/frontend/src/components/atoms/LoginImage/index.tsx @@ -0,0 +1,24 @@ +import classNames from "classnames"; + +import loginImage from "@assets/icons/loging-page-img.svg"; +import type { LoginImageProps } from "./LoginImage.type"; +import "./LoginImage.scss"; + +const LoginImage: React.FC = ({ size = "desktop" }) => { + const LoginImageClassName = classNames("login-image", { + "login-image--mobile": size === "mobile", + "login-image--desktop": size === "desktop", + }); + + return ( +
+ Login Illustration +
+ ); +}; + +export default LoginImage; diff --git a/frontend/src/index.css b/frontend/src/index.css index 8e898c6a..a3c84f0e 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,4 +1,4 @@ body { - margin: 0; - padding: 0; -} + margin: 0; + padding: 0; +} \ No newline at end of file diff --git a/frontend/src/pages/LandingPage/components/FirstView/FirstView.scss b/frontend/src/pages/LandingPage/components/FirstView/FirstView.scss index a4672e52..b95fe4da 100644 --- a/frontend/src/pages/LandingPage/components/FirstView/FirstView.scss +++ b/frontend/src/pages/LandingPage/components/FirstView/FirstView.scss @@ -101,9 +101,13 @@ &__connect { @include h2-phone; color: $white; + text-decoration: none; + &:hover { + cursor: pointer; + } } } - } + } &__description { @include landing-page-title-phone; diff --git a/frontend/src/pages/LandingPage/components/FirstView/index.tsx b/frontend/src/pages/LandingPage/components/FirstView/index.tsx index 1ba67399..4c8ae3bb 100644 --- a/frontend/src/pages/LandingPage/components/FirstView/index.tsx +++ b/frontend/src/pages/LandingPage/components/FirstView/index.tsx @@ -1,9 +1,11 @@ import BasicButton from "@components/atoms/BasicButton"; import LittleLogo from "@components/atoms/LittleLogo"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; + import blobFirstView from "@assets/blobs/blob.svg"; import girldImage from "@assets/images/girl.svg"; -import { useTranslation } from "react-i18next"; import "./FirstView.scss"; function FirstView() { @@ -30,9 +32,9 @@ function FirstView() { {t("CREATE_ACCOUNT")} -

+ {t("CONNECT_MY")} -

+

{t("LANDING_DESCRIPTION")}

diff --git a/frontend/src/pages/LoginPage/LoginPage.scss b/frontend/src/pages/LoginPage/LoginPage.scss new file mode 100644 index 00000000..6840ba80 --- /dev/null +++ b/frontend/src/pages/LoginPage/LoginPage.scss @@ -0,0 +1,210 @@ +@import '@assets/variables'; + +.login-page { + &__logo { + display: none; + + @media screen and (min-width: 768px) { + display: flex; + } + } + + &__blob { + position: absolute; + width: 85%; + top: 0; + right: 0; + z-index: 0; + overflow: hidden; + + @media screen and (min-width: 768px) { + display: none; + } + } + + &__form-section { + display: flex; + align-items: center; + flex-direction: column; + min-height: 100vh; + + @media screen and (min-width: 768px) { + flex-direction: row; + align-items: center; + background-color: $white; + } + } + + &__title { + @include h1-phone; + color: $primary; + position: relative; + z-index: 1; + margin: 200px 0px 100px; + + @media screen and (min-width: 768px) { + color: $white; + background-color: $primary; + margin: 100px 0px 100px; + } + } + + &__form { + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + z-index: 1; + + @media screen and (min-width: 768px) { + color: $white; + background-color: $primary; + } + } + + &__connect-button { + background-color: $secondary; + color: $white; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + margin: 40px 0px 80px; + width: 260px; + } + + &__section { + @include landing-page-title-desktop; + display: flex; + flex-direction: column; + align-items: center; + + @media screen and (min-width: 768px) { + background-color: $primary; + } + } + + &__align { + display: flex; + flex-direction: row; + align-items: start; + } + + &__motivation-block, + &__create-account-block { + display: flex; + flex-direction: column; + align-items: center; + + @media screen and (min-width: 768px) { + background-color: $primary; + } + } + + &__motivation-title, + &__create-account-button { + display: flex; + align-items: center; + width: 75px; + height: 40px; + padding: 0; + margin: 0; + } + + &__motivation-title { + @include h3-phone; + color: $primary; + justify-content: end; + margin-right: 2px; + + @media screen and (min-width: 768px) { + background-color: $primary; + color: $white; + } + } + + &__create-account-button { + @include h3-phone; + background-color: $white; + color: $secondary; + border: none; + width: 140px; + + @media screen and (min-width: 768px) { + background-color: $primary; + } + } + + &__primary-trait { + width: 70px; + background-color: $primary; + border-radius: 5px 0 0 5px; + height: 5px; + + @media screen and (min-width: 768px) { + background-color: $white; + width: 68px; + } + } + + &__secondary-trait { + width: 140px; + height: 6px; + background-color: $secondary; + border-radius: 0 5px 5px 0; + + @media screen and (min-width: 768px) { + width: 150px; + } + } + + &__image-side { + display: none; + + @media screen and (min-width: 768px) { + display: flex; + align-items: center; + justify-content: end; + background-color: $white; + flex: 1; + } + } + + &__form-container { + background-color: $white; + + @media screen and (min-width: 768px) { + background-color: $primary; + padding: 60px 250px 100px; + margin-right: 20%; + border-radius: 10px; + box-shadow: 50px 50px 50px rgba(0, 0, 0, 0.4); + } + } + + &__test-program-container { + display: none; + + @media screen and (min-width: 768px) { + display: flex; + justify-content: center; + align-items: center; + position: absolute; + width: 100%; + top: 7%; + background-color: transparent; + z-index: 2; + } + } + + &__test-program-button { + @include h1-phone; + padding: 10px 20px; + font-size: 18px; + color: $primary; + background-color: transparent; + border: 2px solid black; + border-radius: 10px; + cursor: pointer; + } +} diff --git a/frontend/src/pages/LoginPage/index.tsx b/frontend/src/pages/LoginPage/index.tsx new file mode 100644 index 00000000..8746ab7a --- /dev/null +++ b/frontend/src/pages/LoginPage/index.tsx @@ -0,0 +1,92 @@ +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +import blopLoginPage from "@assets/icons/blob/blob3.svg"; +import BasicButton from "@components/atoms/BasicButton"; +import InputField from "@components/atoms/ImputField/ImputField"; +import LittleLogo from "@components/atoms/LittleLogo/index"; +import LoginImage from "@components/atoms/LoginImage"; + +import "./LoginPage.scss"; + +interface LoginFormValues { + email: string; + password: string; +} + +function LoginPage() { + const { t } = useTranslation(); + const { register, handleSubmit } = useForm(); + + const onSubmit = (data: LoginFormValues) => { + console.log("Form Data: ", data); + }; + + return ( + <> + + {t("BLOB_ALT_TEXT")} +
+
+ +
+
+ +
+
+

{t("READY")}

+
+ + + + {t("CONNECT")} + + +
+
+
+

{t("MOTIVATED")}

+
+
+
+ +
+
+
+
+
+
+ + ); +} + +export default LoginPage; diff --git a/frontend/src/routes.tsx b/frontend/src/routes.tsx index 8f4e73bb..3a1c4f20 100644 --- a/frontend/src/routes.tsx +++ b/frontend/src/routes.tsx @@ -1,14 +1,12 @@ import { createBrowserRouter } from "react-router-dom"; + +import HomePage from "@pages/HomePage"; +import LoginPage from "@pages/LoginPage"; +import ProgramPage from "@pages/ProgramPage"; +import SignUpPage from "@pages/SignUpPage"; import App from "./App"; -import HomePage from "./pages/HomePage"; -import ProgramPage from "./pages/ProgramPage"; -import SignUpPage from "./pages/SignUpPage"; const router = createBrowserRouter([ - { - path: "/", - element: , - }, { path: "/", element: , @@ -17,6 +15,10 @@ const router = createBrowserRouter([ path: "/sign-up", element: , }, + { + path: "/login", + element: , + }, { path: "/program/:id", element: , diff --git a/frontend/src/tests/App.test.tsx b/frontend/src/tests/App.test.tsx index 5c86f0e3..b44316f0 100644 --- a/frontend/src/tests/App.test.tsx +++ b/frontend/src/tests/App.test.tsx @@ -1,10 +1,15 @@ import { render } from "@testing-library/react"; +import { MemoryRouter } from "react-router-dom"; import App from "../App"; describe("App", () => { - it("renders the App component", () => { - const tree = render(); + it("renders the App component", () => { + const tree = render( + + + , + ); - expect(tree).toMatchSnapshot(); - }); + expect(tree).toMatchSnapshot(); + }); }); diff --git a/frontend/src/tests/__snapshots__/App.test.tsx.snap b/frontend/src/tests/__snapshots__/App.test.tsx.snap index adadee03..686be424 100644 --- a/frontend/src/tests/__snapshots__/App.test.tsx.snap +++ b/frontend/src/tests/__snapshots__/App.test.tsx.snap @@ -81,11 +81,12 @@ exports[`App > renders the App component 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+

renders the App component 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+

{ it("renders the Landing Page", () => { - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); diff --git a/frontend/src/tests/pages/LandingPage/__snapshots__/LandingPage.test.tsx.snap b/frontend/src/tests/pages/LandingPage/__snapshots__/LandingPage.test.tsx.snap index 28f1b2a1..74c8d7a7 100644 --- a/frontend/src/tests/pages/LandingPage/__snapshots__/LandingPage.test.tsx.snap +++ b/frontend/src/tests/pages/LandingPage/__snapshots__/LandingPage.test.tsx.snap @@ -81,11 +81,12 @@ exports[`LandingPage > renders the Landing Page 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+

renders the Landing Page 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+

{ it("renders the FirstView component", () => { - const tree = render(); + const tree = render( + + + , + ); expect(tree).toMatchSnapshot(); }); }); diff --git a/frontend/src/tests/pages/LandingPage/components/__snapshots__/FirstView.test.tsx.snap b/frontend/src/tests/pages/LandingPage/components/__snapshots__/FirstView.test.tsx.snap index f33109e8..dbaec752 100644 --- a/frontend/src/tests/pages/LandingPage/components/__snapshots__/FirstView.test.tsx.snap +++ b/frontend/src/tests/pages/LandingPage/components/__snapshots__/FirstView.test.tsx.snap @@ -78,11 +78,12 @@ exports[`FirstView > renders the FirstView component 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+

renders the FirstView component 1`] = ` CREATE_ACCOUNT -

CONNECT_MY -

+