diff --git a/api/package-lock.json b/api/package-lock.json index 597781784..334a95ab1 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -22,11 +22,11 @@ "@types/jest": "^29.5.12", "@types/jsonwebtoken": "^9.0.6", "@types/multer": "^1.4.11", - "@types/node": "^20.12.11", + "@types/node": "^20.12.12", "@types/nodemailer": "^6.4.15", "@types/supertest": "^6.0.2", "@types/uuid": "^9.0.8", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "babel-jest": "^29.7.0", "babel-plugin-add-import-extension": "^1.6.0", "babel-plugin-module-resolver": "^5.0.2", @@ -43,12 +43,12 @@ "i18n-js": "^4.4.3", "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.3.4", + "mongoose": "^8.4.0", "multer": "^1.4.5-lts.1", "nocache": "^4.0.0", "nodemailer": "^6.9.13", - "rimraf": "^5.0.5", - "stripe": "^15.6.0", + "rimraf": "^5.0.7", + "stripe": "^15.7.0", "supertest": "^7.0.0", "typescript": "^5.4.5", "uuid": "^9.0.1", @@ -56,14 +56,14 @@ "winston": "^3.13.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "eslint": "^8.57.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.29.1", "nodemon": "^3.1.0", "npm-check-updates": "^16.14.20", - "tsx": "^4.9.4" + "tsx": "^4.10.4" } }, "../packages/bookcars-types": { @@ -3029,9 +3029,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", - "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", + "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -3603,12 +3603,6 @@ "pretty-format": "^29.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -3642,9 +3636,9 @@ } }, "node_modules/@types/node": { - "version": "20.12.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", - "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dependencies": { "undici-types": "~5.26.4" } @@ -3667,12 +3661,6 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/semver-utils": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/semver-utils/-/semver-utils-1.1.3.tgz", @@ -3733,9 +3721,9 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==" }, "node_modules/@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + "version": "13.11.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", + "integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg==" }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", @@ -3764,21 +3752,19 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -3799,15 +3785,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { @@ -3827,13 +3813,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3844,13 +3830,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3871,9 +3857,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3884,13 +3870,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3936,18 +3922,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3961,12 +3944,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -4783,9 +4766,9 @@ } }, "node_modules/bson": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", - "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz", + "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==", "engines": { "node": ">=16.20.1" } @@ -6959,9 +6942,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -9286,12 +9269,12 @@ } }, "node_modules/mongodb": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", - "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz", + "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.4.0", + "bson": "^6.7.0", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -9331,22 +9314,22 @@ } }, "node_modules/mongodb-connection-string-url": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", - "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^13.0.0" } }, "node_modules/mongoose": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.4.tgz", - "integrity": "sha512-ckBaBzKgtWgCalW/LPkcBsR3wKCOYEJ9jLFPmYCYV7TLStpETY757ELx8/1stL11+6HxLLVffawBffXzd0Y7YA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.0.tgz", + "integrity": "sha512-fgqRMwVEP1qgRYfh+tUe2YBBFnPO35FIg2lfFH+w9IhRGg1/ataWGIqvf/MjwM29cZ60D5vSnqtN2b8Qp0sOZA==", "dependencies": { - "bson": "^6.5.0", + "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.5.0", + "mongodb": "6.6.2", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -11182,9 +11165,9 @@ } }, "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", "dependencies": { "glob": "^10.3.7" }, @@ -11192,7 +11175,7 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11813,9 +11796,9 @@ } }, "node_modules/stripe": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-15.6.0.tgz", - "integrity": "sha512-ARG46eQHMmHspnDpj3QTAH8GyEqtE0nesbzpTtQDT/C9nHvOFYri3mIzHEzArzDcKX7HSleTu2VpYoDZIIH7nA==", + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-15.7.0.tgz", + "integrity": "sha512-hTJhh0Gc+l+hj2vuzaFCh0T46l7793W3wg4J9Oyy3Wu+Ofswd0OgTS4XNt7G9XHJAyHpTmNRNbWgGwn73P4j7g==", "dependencies": { "@types/node": ">=8.1.0", "qs": "^6.11.0" @@ -12126,13 +12109,13 @@ } }, "node_modules/tsx": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.9.4.tgz", - "integrity": "sha512-TlSJTVn2taGGDgdV3jAqCj7WQ/CafCB5p4SbG7W2Bl/0AJWH1ShJlBbc0y2lOFTjQEVAAULSTlmehw/Mwv3S/Q==", + "version": "4.10.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.10.4.tgz", + "integrity": "sha512-Gtg9qnZWNqC/OtcgiXfoAUdAKx3/cgKOYvEocAsv+m21MV/eKpV/WUjRXe6/sDCaGBl2/v8S6v29BpUnGMCX5A==", "dev": true, "dependencies": { "esbuild": "~0.20.2", - "get-tsconfig": "^4.7.3" + "get-tsconfig": "^4.7.5" }, "bin": { "tsx": "dist/cli.mjs" diff --git a/api/package.json b/api/package.json index f156cf659..82017ad03 100644 --- a/api/package.json +++ b/api/package.json @@ -29,11 +29,11 @@ "@types/jest": "^29.5.12", "@types/jsonwebtoken": "^9.0.6", "@types/multer": "^1.4.11", - "@types/node": "^20.12.11", + "@types/node": "^20.12.12", "@types/nodemailer": "^6.4.15", "@types/supertest": "^6.0.2", "@types/uuid": "^9.0.8", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "babel-jest": "^29.7.0", "babel-plugin-add-import-extension": "^1.6.0", "babel-plugin-module-resolver": "^5.0.2", @@ -50,12 +50,12 @@ "i18n-js": "^4.4.3", "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.3.4", + "mongoose": "^8.4.0", "multer": "^1.4.5-lts.1", "nocache": "^4.0.0", "nodemailer": "^6.9.13", - "rimraf": "^5.0.5", - "stripe": "^15.6.0", + "rimraf": "^5.0.7", + "stripe": "^15.7.0", "supertest": "^7.0.0", "typescript": "^5.4.5", "uuid": "^9.0.1", @@ -63,13 +63,13 @@ "winston": "^3.13.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "eslint": "^8.57.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.29.1", "nodemon": "^3.1.0", "npm-check-updates": "^16.14.20", - "tsx": "^4.9.4" + "tsx": "^4.10.4" } } diff --git a/api/src/common/databaseHelper.ts b/api/src/common/databaseHelper.ts index e09c1861a..2df57303a 100644 --- a/api/src/common/databaseHelper.ts +++ b/api/src/common/databaseHelper.ts @@ -113,7 +113,7 @@ export const initialize = async (): Promise => { const bookingIndex = bookingIndexes.find((index: any) => index.name === BOOKING_EXPIRE_AT_INDEX_NAME && index.expireAfterSeconds !== env.BOOKING_EXPIRE_AT) if (bookingIndex) { try { - await Booking.collection.dropIndex(bookingIndex.name) + await Booking.collection.dropIndex(bookingIndex.name!) } catch (err) { logger.error('Failed dropping Booking TTL index', err) } finally { @@ -129,7 +129,7 @@ export const initialize = async (): Promise => { const tokenIndex = tokenIndexes.find((index: any) => index.name.includes(TOKEN_EXPIRE_AT_INDEX_NAME)) if (tokenIndex) { try { - await Token.collection.dropIndex(tokenIndex.name) + await Token.collection.dropIndex(tokenIndex.name!) } catch (err) { logger.error('Failed dropping Token TTL index', err) } finally { diff --git a/api/src/controllers/bookingController.ts b/api/src/controllers/bookingController.ts index 7eef47228..23a7d42ff 100644 --- a/api/src/controllers/bookingController.ts +++ b/api/src/controllers/bookingController.ts @@ -236,13 +236,13 @@ export const checkout = async (req: Request, res: Response) => { html: `

${i18n.t('HELLO')}${user.fullName},

${i18n.t('ACCOUNT_ACTIVATION_LINK')}

- ${helper.joinURL(env.FRONTEND_HOST, 'activate')}/?u=${encodeURIComponent(user._id.toString())}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

+ ${helper.joinURL(env.FRONTEND_HOST, 'activate')}/?u=${encodeURIComponent(user.id)}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

${i18n.t('REGARDS')}

`, } await mailHelper.sendMail(mailOptions) - body.booking.driver = user._id.toString() + body.booking.driver = user.id } else { user = await User.findById(body.booking.driver) } diff --git a/api/src/controllers/carController.ts b/api/src/controllers/carController.ts index 1f87cff75..43c61a268 100644 --- a/api/src/controllers/carController.ts +++ b/api/src/controllers/carController.ts @@ -399,7 +399,7 @@ export const getCars = async (req: Request, res: Response) => { const size = Number.parseInt(req.params.size, 10) const suppliers = body.suppliers.map((id) => new mongoose.Types.ObjectId(id)) const { - fuel, + carType, gearbox, mileage, deposit, @@ -412,8 +412,8 @@ export const getCars = async (req: Request, res: Response) => { $and: [{ name: { $regex: keyword, $options: options } }, { supplier: { $in: suppliers } }], } - if (fuel) { - $match.$and!.push({ type: { $in: fuel } }) + if (carType) { + $match.$and!.push({ type: { $in: carType } }) } if (gearbox) { @@ -564,7 +564,7 @@ export const getFrontendCars = async (req: Request, res: Response) => { const suppliers = body.suppliers.map((id) => new mongoose.Types.ObjectId(id)) const pickupLocation = new mongoose.Types.ObjectId(body.pickupLocation) const { - fuel, + carType, gearbox, mileage, deposit, @@ -574,7 +574,7 @@ export const getFrontendCars = async (req: Request, res: Response) => { $and: [ { supplier: { $in: suppliers } }, { locations: pickupLocation }, - { available: true }, { type: { $in: fuel } }, + { available: true }, { type: { $in: carType } }, { gearbox: { $in: gearbox } }, ], } diff --git a/api/src/controllers/stripeController.ts b/api/src/controllers/stripeController.ts index fe499dca0..ac84b0322 100644 --- a/api/src/controllers/stripeController.ts +++ b/api/src/controllers/stripeController.ts @@ -149,14 +149,14 @@ export const checkCheckoutSession = async (req: Request, res: Response) => { } i18n.locale = supplier.language let message = i18n.t('BOOKING_PAID_NOTIFICATION') - await bookingController.notify(user, booking._id.toString(), supplier, message) + await bookingController.notify(user, booking.id, supplier, message) // Notify admin const admin = !!env.ADMIN_EMAIL && await User.findOne({ email: env.ADMIN_EMAIL, type: bookcarsTypes.UserType.Admin }) if (admin) { i18n.locale = admin.language message = i18n.t('BOOKING_PAID_NOTIFICATION') - await bookingController.notify(user, booking._id.toString(), admin, message) + await bookingController.notify(user, booking.id, admin, message) } return res.sendStatus(200) diff --git a/api/src/controllers/userController.ts b/api/src/controllers/userController.ts index 1abed30a7..dd15d8c8a 100644 --- a/api/src/controllers/userController.ts +++ b/api/src/controllers/userController.ts @@ -206,7 +206,7 @@ export const create = async (req: Request, res: Response) => { ${helper.joinURL( user.type === bookcarsTypes.UserType.User ? env.FRONTEND_HOST : env.BACKEND_HOST, 'activate', - )}/?u=${encodeURIComponent(user._id)}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

+ )}/?u=${encodeURIComponent(user.id)}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

${i18n.t('REGARDS')}

`, } @@ -347,7 +347,7 @@ export const resend = async (req: Request, res: Response) => { ${helper.joinURL( user.type === bookcarsTypes.UserType.User ? env.FRONTEND_HOST : env.BACKEND_HOST, reset ? 'reset-password' : 'activate', - )}/?u=${encodeURIComponent(user._id)}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

+ )}/?u=${encodeURIComponent(user.id)}&e=${encodeURIComponent(user.email)}&t=${encodeURIComponent(token.token)}

${i18n.t('REGARDS')}

`, } @@ -478,7 +478,7 @@ export const signin = async (req: Request, res: Response) => { const token = jwt.sign(payload, env.JWT_SECRET, options) const loggedUser: bookcarsTypes.User = { - _id: user._id, + _id: user.id, email: user.email, fullName: user.fullName, language: user.language, diff --git a/api/src/models/Car.ts b/api/src/models/Car.ts index ff6fff99d..242fb0b36 100644 --- a/api/src/models/Car.ts +++ b/api/src/models/Car.ts @@ -42,7 +42,13 @@ const carSchema = new Schema( }, type: { type: String, - enum: [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline], + enum: [ + bookcarsTypes.CarType.Diesel, + bookcarsTypes.CarType.Gasoline, + bookcarsTypes.CarType.Electric, + bookcarsTypes.CarType.Hybrid, + bookcarsTypes.CarType.PlugInHybrid, + ], required: [true, "can't be blank"], }, gearbox: { diff --git a/api/tests/car.test.ts b/api/tests/car.test.ts index 2e2d0182c..083932085 100644 --- a/api/tests/car.test.ts +++ b/api/tests/car.test.ts @@ -372,7 +372,7 @@ describe('POST /api/cars/:page/:size', () => { const payload: bookcarsTypes.GetCarsPayload = { suppliers: [SUPPLIER2_ID], - fuel: [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline], + carType: [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline], gearbox: [bookcarsTypes.GearboxType.Manual, bookcarsTypes.GearboxType.Automatic], mileage: [bookcarsTypes.Mileage.Limited, bookcarsTypes.Mileage.Unlimited], availability: [bookcarsTypes.Availablity.Available, bookcarsTypes.Availablity.Unavailable], @@ -386,7 +386,7 @@ describe('POST /api/cars/:page/:size', () => { expect(res.statusCode).toBe(200) expect(res.body[0].resultData.length).toBeGreaterThan(0) - payload.fuel = undefined + payload.carType = undefined payload.gearbox = undefined payload.mileage = undefined payload.availability = undefined @@ -493,7 +493,7 @@ describe('POST /api/frontend-cars/:page/:size', () => { const payload: bookcarsTypes.GetCarsPayload = { suppliers: [SUPPLIER2_ID], pickupLocation: LOCATION2_ID, - fuel: [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline], + carType: [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline], gearbox: [bookcarsTypes.GearboxType.Manual, bookcarsTypes.GearboxType.Automatic], mileage: [bookcarsTypes.Mileage.Limited, bookcarsTypes.Mileage.Unlimited], deposit: -1, diff --git a/api/tests/index.test.ts b/api/tests/index.test.ts index ee7853118..22a2b538a 100644 --- a/api/tests/index.test.ts +++ b/api/tests/index.test.ts @@ -55,8 +55,8 @@ describe('Test database initialization', () => { if (tokenIndex) { const { expireAfterSeconds } = tokenIndex - await Token.collection.dropIndex(tokenIndex.name) - await createTokenIndex(expireAfterSeconds + 1) + await Token.collection.dropIndex(tokenIndex.name!) + await createTokenIndex(expireAfterSeconds! + 1) await delay() res = await databaseHelper.initialize() expect(res).toBeTruthy() @@ -69,8 +69,8 @@ describe('Test database initialization', () => { if (bookingIndex) { const { expireAfterSeconds } = bookingIndex - await Booking.collection.dropIndex(bookingIndex.name) - await createBookingIndex(expireAfterSeconds + 1) + await Booking.collection.dropIndex(bookingIndex.name!) + await createBookingIndex(expireAfterSeconds! + 1) await delay() res = await databaseHelper.initialize() expect(res).toBeTruthy() diff --git a/api/tests/miscellaneous.test.ts b/api/tests/miscellaneous.test.ts index ef3154fe3..cc5027d43 100644 --- a/api/tests/miscellaneous.test.ts +++ b/api/tests/miscellaneous.test.ts @@ -61,7 +61,7 @@ describe('Test User phone validation', () => { try { const user = new User(USER) await user.save() - userId = user._id + userId = user.id user.phone = 'unknown' await user.save() } catch (err) { diff --git a/backend/package-lock.json b/backend/package-lock.json index 5b64074bb..bae025437 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -11,21 +11,21 @@ "@craco/craco": "^7.1.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.17", - "@mui/material": "^5.15.17", - "@mui/x-data-grid": "^7.3.2", - "@mui/x-date-pickers": "^7.3.2", - "@types/node": "^20.12.11", - "@types/react": "^18.3.1", + "@mui/icons-material": "^5.15.18", + "@mui/material": "^5.15.18", + "@mui/x-data-grid": "^7.5.0", + "@mui/x-date-pickers": "^7.5.0", + "@types/node": "^20.12.12", + "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "axios": "^1.6.8", "date-fns": "^2.29.3", "react": "^18.3.1", "react-app-alias-ex": "^2.1.0", "react-dom": "^18.3.1", "react-localization": "^1.0.19", - "react-router-dom": "^6.23.0", + "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", "react-toastify": "^10.0.5", "typescript": "^4.9.5", @@ -1949,9 +1949,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -3577,18 +3577,18 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.17", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.17.tgz", - "integrity": "sha512-DVAejDQkjNnIac7MfP8sLzuo7fyrBPxNdXe+6bYqOqg1z2OPTlfFAejSNzWe7UenRMuFu9/AyFXj/X2vN2w6dA==", + "version": "5.15.18", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.18.tgz", + "integrity": "sha512-/9pVk+Al8qxAjwFUADv4BRZgMpZM4m5E+2Q/20qhVPuIJWqKp4Ie4tGExac6zu93rgPTYVQGgu+1vjiT0E+cEw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.15.17", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.17.tgz", - "integrity": "sha512-xVzl2De7IY36s/keHX45YMiCpsIx3mNv2xwDgtBkRSnZQtVk+Gqufwj1ktUxEyjzEhBl0+PiNJqYC31C+n1n6A==", + "version": "5.15.18", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.18.tgz", + "integrity": "sha512-jGhyw02TSLM0NgW+MDQRLLRUD/K4eN9rlK2pTBTL1OtzyZmQ8nB060zK1wA0b7cVrIiG+zyrRmNAvGWXwm2N9Q==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -3611,13 +3611,13 @@ } }, "node_modules/@mui/material": { - "version": "5.15.17", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.17.tgz", - "integrity": "sha512-ru/MLvTkCh0AZXmqwIpqGTOoVBS/sX48zArXq/DvktxXZx4fskiRA2PEc7Rk5ZlFiZhKh4moL4an+l8zZwq49Q==", + "version": "5.15.18", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.18.tgz", + "integrity": "sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==", "dependencies": { "@babel/runtime": "^7.23.9", "@mui/base": "5.0.0-beta.40", - "@mui/core-downloads-tracker": "^5.15.17", + "@mui/core-downloads-tracker": "^5.15.18", "@mui/system": "^5.15.15", "@mui/types": "^7.2.14", "@mui/utils": "^5.15.14", @@ -3791,14 +3791,14 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.3.2.tgz", - "integrity": "sha512-seuRiZ2yyhzeUa7Thzap0xvvizGPSEwJRNOjY9kffjUr+0iXGF3PZGEsMoJ7jCjZ2peHX7FjfqBdssDvizxIDQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.5.0.tgz", + "integrity": "sha512-CdIDjqMHPWJvG/M6z36fnqIR+z2nW8Guk/wLUOv7vRJNVeOJasrkqg3xVZ3IFEGtbkTlQQ6iu1Os8YlF2HPWww==", "dependencies": { - "@babel/runtime": "^7.24.0", + "@babel/runtime": "^7.24.5", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "prop-types": "^15.8.1", "reselect": "^4.1.8" }, @@ -3816,16 +3816,16 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.3.2.tgz", - "integrity": "sha512-i7JaDs1eXSZWyJihfszUHVV0t/C2HvtdMv5tHwv3E3enMx5Hup1vkJ64vZAH2fgGrTHQH8mjxvVsmI6jhDXIUg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.5.0.tgz", + "integrity": "sha512-azm9AX36/XzllKtfyHn8u8iYDsxf425/LacP4oVaCeQQgIasajSRFxU/g8vxpNWwgTuzIeWwKjj8cvTc/2UBAw==", "dependencies": { - "@babel/runtime": "^7.24.0", + "@babel/runtime": "^7.24.5", "@mui/base": "^5.0.0-beta.40", "@mui/system": "^5.15.14", "@mui/utils": "^5.15.14", "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, @@ -3841,7 +3841,7 @@ "@emotion/styled": "^11.8.1", "@mui/material": "^5.15.14", "date-fns": "^2.25.0 || ^3.2.0", - "date-fns-jalali": "^2.13.0-0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", "dayjs": "^1.10.7", "luxon": "^3.0.2", "moment": "^2.29.4", @@ -4262,9 +4262,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", - "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", + "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==", "engines": { "node": ">=14.0.0" } @@ -4926,9 +4926,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "20.12.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", - "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dependencies": { "undici-types": "~5.26.4" } @@ -4964,9 +4964,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", + "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5058,9 +5058,9 @@ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" }, "node_modules/@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + "version": "13.11.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", + "integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg==" }, "node_modules/@types/ws": { "version": "8.5.5", @@ -7198,9 +7198,9 @@ } }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } @@ -18150,11 +18150,11 @@ } }, "node_modules/react-router": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", - "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", "dependencies": { - "@remix-run/router": "1.16.0" + "@remix-run/router": "1.16.1" }, "engines": { "node": ">=14.0.0" @@ -18164,12 +18164,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", - "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", "dependencies": { - "@remix-run/router": "1.16.0", - "react-router": "6.23.0" + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" }, "engines": { "node": ">=14.0.0" diff --git a/backend/package.json b/backend/package.json index ebac08508..3b8ce45a6 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,21 +6,21 @@ "@craco/craco": "^7.1.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.17", - "@mui/material": "^5.15.17", - "@mui/x-data-grid": "^7.3.2", - "@mui/x-date-pickers": "^7.3.2", - "@types/node": "^20.12.11", - "@types/react": "^18.3.1", + "@mui/icons-material": "^5.15.18", + "@mui/material": "^5.15.18", + "@mui/x-data-grid": "^7.5.0", + "@mui/x-date-pickers": "^7.5.0", + "@types/node": "^20.12.12", + "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "axios": "^1.6.8", "date-fns": "^2.29.3", "react": "^18.3.1", "react-app-alias-ex": "^2.1.0", "react-dom": "^18.3.1", "react-localization": "^1.0.19", - "react-router-dom": "^6.23.0", + "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", "react-toastify": "^10.0.5", "typescript": "^4.9.5", diff --git a/backend/src/assets/css/car-type-filter.css b/backend/src/assets/css/car-type-filter.css new file mode 100644 index 000000000..d6fbabe3d --- /dev/null +++ b/backend/src/assets/css/car-type-filter.css @@ -0,0 +1,26 @@ +div.car-type-filter div.filter-elements { + padding: 7px 5px; +} + +div.car-type-filter div.filter-elements div.filter-element input[type='checkbox'].car-type-checkbox { + cursor: pointer; + margin-left: 5px; +} + +div.car-type-filter div.filter-elements div.filter-element span { + margin-left: 5px; + cursor: pointer; + font-size: 12px; + font-weight: 400; +} + +div.car-type-filter div.filter-actions { + text-align: center; + padding-bottom: 10px; +} + +div.car-type-filter div.filter-actions span.uncheckall { + text-decoration: underline; + cursor: pointer; + color: #0064c8; +} diff --git a/backend/src/assets/css/fuel-filter.css b/backend/src/assets/css/fuel-filter.css deleted file mode 100644 index ffec99901..000000000 --- a/backend/src/assets/css/fuel-filter.css +++ /dev/null @@ -1,26 +0,0 @@ -div.fuel-filter div.filter-elements { - padding: 7px 5px; -} - -div.fuel-filter div.filter-elements div.filter-element input[type='checkbox'].fuel-checkbox { - cursor: pointer; - margin-left: 5px; -} - -div.fuel-filter div.filter-elements div.filter-element span { - margin-left: 5px; - cursor: pointer; - font-size: 12px; - font-weight: 400; -} - -div.fuel-filter div.filter-actions { - text-align: center; - padding-bottom: 10px; -} - -div.fuel-filter div.filter-actions span.uncheckall { - text-decoration: underline; - cursor: pointer; - color: #0064c8; -} diff --git a/backend/src/common/helper.ts b/backend/src/common/helper.ts index b307e619c..dee1f0a99 100644 --- a/backend/src/common/helper.ts +++ b/backend/src/common/helper.ts @@ -73,6 +73,15 @@ export const getCarTypeShort = (type: string) => { case bookcarsTypes.CarType.Gasoline: return strings.GASOLINE_SHORT + case bookcarsTypes.CarType.Electric: + return strings.ELECTRIC_SHORT + + case bookcarsTypes.CarType.Hybrid: + return strings.HYBRID_SHORT + + case bookcarsTypes.CarType.PlugInHybrid: + return strings.PLUG_IN_HYBRID_SHORT + default: return '' } @@ -149,6 +158,15 @@ export const getCarTypeTooltip = (type: string) => { case bookcarsTypes.CarType.Gasoline: return strings.GASOLINE_TOOLTIP + case bookcarsTypes.CarType.Electric: + return strings.ELECTRIC_TOOLTIP + + case bookcarsTypes.CarType.Hybrid: + return strings.HYBRID_TOOLTIP + + case bookcarsTypes.CarType.PlugInHybrid: + return strings.PLUG_IN_HYBRID_TOOLTIP + default: return '' } diff --git a/backend/src/components/CarList.tsx b/backend/src/components/CarList.tsx index 2f2df49d9..01896721d 100644 --- a/backend/src/components/CarList.tsx +++ b/backend/src/components/CarList.tsx @@ -12,7 +12,7 @@ import { Typography } from '@mui/material' import { - LocalGasStation as FuelIcon, + LocalGasStation as CarTypeIcon, AccountTree as GearboxIcon, Person as SeatsIcon, AcUnit as AirconIcon, @@ -41,7 +41,7 @@ import '../assets/css/car-list.css' interface CarListProps { suppliers?: string[] keyword?: string - fuel?: string[] + carType?: string[] gearbox?: string[] mileage?: string[] deposit?: number @@ -62,7 +62,7 @@ interface CarListProps { const CarList = ({ suppliers: carSuppliers, keyword: carKeyword, - fuel: carFuel, + carType: _carType, gearbox: carGearbox, mileage: carMileage, deposit: carDeposit, @@ -114,7 +114,7 @@ const CarList = ({ _page: number, suppliers?: string[], keyword?: string, - fuel?: string[], + __carType?: string[], gearbox?: string[], mileage?: string[], deposit?: number, @@ -125,7 +125,7 @@ const CarList = ({ const payload: bookcarsTypes.GetCarsPayload = { suppliers: suppliers ?? [], - fuel, + carType: __carType, gearbox, mileage, deposit, @@ -174,7 +174,7 @@ const CarList = ({ page, carSuppliers, carKeyword, - carFuel, + _carType, carGearbox, carMileage, carDeposit || 0, @@ -194,7 +194,7 @@ const CarList = ({ page, carSuppliers, carKeyword, - carFuel, + _carType, carGearbox, carMileage, carDeposit, @@ -218,7 +218,7 @@ const CarList = ({ }, [ carSuppliers, carKeyword, - carFuel, + _carType, carGearbox, carMileage, carDeposit, @@ -232,7 +232,7 @@ const CarList = ({ 1, carSuppliers, carKeyword, - carFuel, + _carType, carGearbox, carMileage, carDeposit, @@ -243,7 +243,7 @@ const CarList = ({ reload, carSuppliers, carKeyword, - carFuel, + _carType, carGearbox, carMileage, carDeposit, @@ -393,7 +393,7 @@ const CarList = ({
  • - + {helper.getCarTypeShort(car.type)}
    @@ -442,7 +442,7 @@ const CarList = ({
  • - + {`${strings.FUEL_POLICY}${fr ? ' : ' : ': '}${helper.getFuelPolicy(car.fuelPolicy)}`}
    diff --git a/backend/src/components/CarTypeFilter.tsx b/backend/src/components/CarTypeFilter.tsx new file mode 100644 index 000000000..b3de938df --- /dev/null +++ b/backend/src/components/CarTypeFilter.tsx @@ -0,0 +1,319 @@ +import React, { useState, useEffect, useRef } from 'react' +import * as bookcarsTypes from ':bookcars-types' +import * as bookcarsHelper from ':bookcars-helper' +import { strings as commonStrings } from '../lang/common' +import { strings } from '../lang/cars' +import Accordion from './Accordion' + +import '../assets/css/car-type-filter.css' + +interface CarTypeProps { + className?: string + onChange?: (values: bookcarsTypes.CarType[]) => void +} + +const allTypes = bookcarsHelper.getAllCarTypes() + +const CarType = ({ + className, + onChange +}: CarTypeProps) => { + const [allChecked, setAllChecked] = useState(true) + const [values, setValues] = useState(allTypes) + + const dieselRef = useRef(null) + const gasolineRef = useRef(null) + const electricRef = useRef(null) + const hybridRef = useRef(null) + const plugInHybridRef = useRef(null) + + useEffect(() => { + if (allChecked + && dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = true + gasolineRef.current.checked = true + electricRef.current.checked = true + hybridRef.current.checked = true + plugInHybridRef.current.checked = true + } + }, [allChecked]) + + const handleCheckDieselChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Diesel) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Diesel), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleDieselClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckDieselChange(event) + } + + const handleCheckGasolineChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Gasoline) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Gasoline), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleGasolineClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckGasolineChange(event) + } + + const handleCheckElectricChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Electric) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Electric), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleElectricClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckElectricChange(event) + } + + const handleCheckHybridChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Hybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Hybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleHybridClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckHybridChange(event) + } + + const handleCheckPlugInHybridChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.PlugInHybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.PlugInHybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handlePlugInHybridClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckPlugInHybridChange(event) + } + + const handleUncheckAllChange = () => { + if (allChecked) { + // uncheck all + if (dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = false + gasolineRef.current.checked = false + electricRef.current.checked = false + hybridRef.current.checked = false + plugInHybridRef.current.checked = false + } + setAllChecked(false) + setValues([]) + } else { + // check all + if (dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = true + gasolineRef.current.checked = true + electricRef.current.checked = true + hybridRef.current.checked = true + plugInHybridRef.current.checked = true + } + const _values = allTypes + + setAllChecked(true) + setValues(_values) + + if (onChange) { + onChange(bookcarsHelper.clone(_values)) + } + } + } + + return ( + +
    +
    + + + {strings.DIESEL} + +
    +
    + + + {strings.GASOLINE} + +
    + +
    + + + {strings.ELECTRIC} + +
    +
    + + + {strings.HYBRID} + +
    +
    + + + {strings.PLUG_IN_HYBRID} + +
    +
    +
    + + {allChecked ? commonStrings.UNCHECK_ALL : commonStrings.CHECK_ALL} + +
    +
    + ) +} + +export default CarType diff --git a/backend/src/components/CarTypeList.tsx b/backend/src/components/CarTypeList.tsx index a2b1dce30..af0a49776 100644 --- a/backend/src/components/CarTypeList.tsx +++ b/backend/src/components/CarTypeList.tsx @@ -44,6 +44,9 @@ const CarTypeList = ({ ) diff --git a/backend/src/components/FuelFilter.tsx b/backend/src/components/FuelFilter.tsx deleted file mode 100644 index 72233e136..000000000 --- a/backend/src/components/FuelFilter.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react' -import * as bookcarsTypes from ':bookcars-types' -import * as bookcarsHelper from ':bookcars-helper' -import { strings as commonStrings } from '../lang/common' -import { strings } from '../lang/cars' -import Accordion from './Accordion' - -import '../assets/css/fuel-filter.css' - -interface FuelFilterProps { - className?: string - onChange?: (values: bookcarsTypes.CarType[]) => void -} - -const FuelFilter = ({ - className, - onChange -}: FuelFilterProps) => { - const [allChecked, setAllChecked] = useState(true) - const [values, setValues] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) - - const dieselRef = useRef(null) - const gasolineRef = useRef(null) - - useEffect(() => { - if (allChecked && dieselRef.current && gasolineRef.current) { - dieselRef.current.checked = true - gasolineRef.current.checked = true - } - }, [allChecked]) - - const handleCheckDieselChange = (e: React.ChangeEvent | React.MouseEvent) => { - if ('checked' in e.currentTarget && e.currentTarget.checked) { - values.push(bookcarsTypes.CarType.Diesel) - - if (values.length === 2) { - setAllChecked(true) - } - } else { - values.splice( - values.findIndex((v) => v === bookcarsTypes.CarType.Diesel), - 1, - ) - - if (values.length === 0) { - setAllChecked(false) - } - } - - setValues(values) - - if (onChange) { - onChange(bookcarsHelper.clone(values)) - } - } - - const handleDieselClick = (e: React.MouseEvent) => { - const checkbox = e.currentTarget.previousSibling as HTMLInputElement - checkbox.checked = !checkbox.checked - const event = e - event.currentTarget = checkbox - handleCheckDieselChange(event) - } - - const handleCheckGasolineChange = (e: React.ChangeEvent | React.MouseEvent) => { - if ('checked' in e.currentTarget && e.currentTarget.checked) { - values.push(bookcarsTypes.CarType.Gasoline) - - if (values.length === 2) { - setAllChecked(true) - } - } else { - values.splice( - values.findIndex((v) => v === bookcarsTypes.CarType.Gasoline), - 1, - ) - - if (values.length === 0) { - setAllChecked(false) - } - } - - setValues(values) - - if (onChange) { - onChange(bookcarsHelper.clone(values)) - } - } - - const handleGasolineClick = (e: React.MouseEvent) => { - const checkbox = e.currentTarget.previousSibling as HTMLInputElement - checkbox.checked = !checkbox.checked - const event = e - event.currentTarget = checkbox - handleCheckGasolineChange(event) - } - - const handleUncheckAllChange = () => { - if (allChecked) { - // uncheck all - if (dieselRef.current) { - dieselRef.current.checked = false - } - if (gasolineRef.current) { - gasolineRef.current.checked = false - } - setAllChecked(false) - setValues([]) - } else { - // check all - if (dieselRef.current) { - dieselRef.current.checked = true - } - if (gasolineRef.current) { - gasolineRef.current.checked = true - } - const _values = [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline] - - setAllChecked(true) - setValues(_values) - - if (onChange) { - onChange(bookcarsHelper.clone(_values)) - } - } - } - - return ( - -
    -
    - - {strings.DIESEL} -
    -
    - - {strings.GASOLINE} -
    -
    -
    - - {allChecked ? commonStrings.UNCHECK_ALL : commonStrings.CHECK_ALL} - -
    -
    - ) -} - -export default FuelFilter diff --git a/backend/src/lang/cars.ts b/backend/src/lang/cars.ts index c0b8b9cbf..351b086d0 100644 --- a/backend/src/lang/cars.ts +++ b/backend/src/lang/cars.ts @@ -10,8 +10,14 @@ const strings = new LocalizedStrings({ FUEL_POLICY: 'Politique carburant', DIESEL: 'Diesel', GASOLINE: 'Essence', + ELECTRIC: 'Électrique', + HYBRID: 'Hybride', + PLUG_IN_HYBRID: 'Hybride rechargeable', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'E', + ELECTRIC_SHORT: 'ELEC', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'HR', GEARBOX_MANUAL: 'Manuelle', GEARBOX_AUTOMATIC: 'Automatique', GEARBOX_MANUAL_SHORT: 'M', @@ -20,6 +26,9 @@ const strings = new LocalizedStrings({ FUEL_POLICY_FREE_TANK: 'Plein inclus', DIESEL_TOOLTIP: 'Cette voiture a un moteur diesel', GASOLINE_TOOLTIP: 'Cette voiture a un moteur essence', + ELECTRIC_TOOLTIP: 'Cette voiture est électrique', + HYBRID_TOOLTIP: 'Cette voiture est hybride', + PLUG_IN_HYBRID_TOOLTIP: 'Cette voiture est hybride rechargeable', GEARBOX_MANUAL_TOOLTIP: 'Cette voiture a une transmission manuelle', GEARBOX_AUTOMATIC_TOOLTIP: 'Cette voiture a une transmission automatique', SEATS_TOOLTIP_1: 'Cette voiture a ', @@ -72,8 +81,14 @@ const strings = new LocalizedStrings({ FUEL_POLICY: 'Fuel policy', DIESEL: 'Diesel', GASOLINE: 'Gasoline', + ELECTRIC: 'Electric', + HYBRID: 'Hybrid', + PLUG_IN_HYBRID: 'Plug-in hybrid', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'G', + ELECTRIC_SHORT: 'E', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'PH', GEARBOX_MANUAL: 'Manual', GEARBOX_AUTOMATIC: 'Automatic', GEARBOX_MANUAL_SHORT: 'M', @@ -82,6 +97,9 @@ const strings = new LocalizedStrings({ FUEL_POLICY_FREE_TANK: 'Free tank', DIESEL_TOOLTIP: 'This car has a diesel engine', GASOLINE_TOOLTIP: 'This car has a gasoline engine', + ELECTRIC_TOOLTIP: 'This car is electric', + HYBRID_TOOLTIP: 'This car is hybrid', + PLUG_IN_HYBRID_TOOLTIP: 'This car is plug-in hybrid', GEARBOX_MANUAL_TOOLTIP: 'This car has a manual gearbox', GEARBOX_AUTOMATIC_TOOLTIP: 'This car has an automatic gearbox', SEATS_TOOLTIP_1: 'This car has ', diff --git a/backend/src/pages/Cars.tsx b/backend/src/pages/Cars.tsx index 0379efad0..6b5967ecf 100644 --- a/backend/src/pages/Cars.tsx +++ b/backend/src/pages/Cars.tsx @@ -10,7 +10,7 @@ import Layout from '../components/Layout' import SupplierFilter from '../components/SupplierFilter' import Search from '../components/Search' import InfoBox from '../components/InfoBox' -import FuelFilter from '../components/FuelFilter' +import CarTypeFilter from '../components/CarTypeFilter' import GearboxFilter from '../components/GearboxFilter' import MileageFilter from '../components/MileageFilter' import DepositFilter from '../components/DepositFilter' @@ -29,7 +29,7 @@ const Cars = () => { const [rowCount, setRowCount] = useState(0) const [loading, setLoading] = useState(true) const [gearbox, setGearbox] = useState([bookcarsTypes.GearboxType.Automatic, bookcarsTypes.GearboxType.Manual]) - const [fuel, setFuel] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) + const [carType, setCarType] = useState(bookcarsHelper.getAllCarTypes()) const [mileage, setMileage] = useState([bookcarsTypes.Mileage.Limited, bookcarsTypes.Mileage.Unlimited]) const [availability, setAvailability] = useState([bookcarsTypes.Availablity.Available, bookcarsTypes.Availablity.Unavailable]) const [deposit, setDeposit] = useState(-1) @@ -53,8 +53,9 @@ const Cars = () => { setRowCount(_rowCount) } - const handleFuelFilterChange = (values: string[]) => { - setFuel(values) + const handleCarTypeFilterChange = (values: string[]) => { + console.log(values) + setCarType(values) } const handleGearboxFilterChange = (values: string[]) => { @@ -102,7 +103,7 @@ const Cars = () => { {rowCount > -1 && ( <> - + @@ -115,7 +116,7 @@ const Cars = () => { =14.0.0" } @@ -5030,9 +5030,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "20.12.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", - "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dependencies": { "undici-types": "~5.26.4" } @@ -5068,9 +5068,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", + "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5170,9 +5170,9 @@ "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==" }, "node_modules/@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + "version": "13.11.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", + "integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg==" }, "node_modules/@types/ws": { "version": "8.5.5", @@ -7250,9 +7250,9 @@ } }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } @@ -18338,11 +18338,11 @@ } }, "node_modules/react-router": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", - "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", "dependencies": { - "@remix-run/router": "1.16.0" + "@remix-run/router": "1.16.1" }, "engines": { "node": ">=14.0.0" @@ -18352,12 +18352,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", - "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", "dependencies": { - "@remix-run/router": "1.16.0", - "react-router": "6.23.0" + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" }, "engines": { "node": ">=14.0.0" diff --git a/frontend/package.json b/frontend/package.json index 79ee36ad5..e03fc643f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,17 +6,17 @@ "@craco/craco": "^7.1.0", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.15.17", - "@mui/material": "^5.15.17", - "@mui/x-data-grid": "^7.3.2", - "@mui/x-date-pickers": "^7.3.2", + "@mui/icons-material": "^5.15.18", + "@mui/material": "^5.15.18", + "@mui/x-data-grid": "^7.5.0", + "@mui/x-date-pickers": "^7.5.0", "@stripe/react-stripe-js": "^2.7.1", "@stripe/stripe-js": "^3.4.0", - "@types/node": "^20.12.11", - "@types/react": "^18.3.1", + "@types/node": "^20.12.12", + "@types/react": "^18.3.2", "@types/react-dom": "^18.3.0", "@types/react-google-recaptcha": "^2.1.9", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "axios": "^1.6.8", "date-fns": "^2.29.3", "react": "^18.3.1", @@ -24,7 +24,7 @@ "react-dom": "^18.3.1", "react-google-recaptcha-v3": "^1.10.1", "react-localization": "^1.0.19", - "react-router-dom": "^6.23.0", + "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", "react-toastify": "^10.0.5", "typescript": "^4.9.5", diff --git a/frontend/src/assets/css/car-type-filter.css b/frontend/src/assets/css/car-type-filter.css new file mode 100644 index 000000000..d6fbabe3d --- /dev/null +++ b/frontend/src/assets/css/car-type-filter.css @@ -0,0 +1,26 @@ +div.car-type-filter div.filter-elements { + padding: 7px 5px; +} + +div.car-type-filter div.filter-elements div.filter-element input[type='checkbox'].car-type-checkbox { + cursor: pointer; + margin-left: 5px; +} + +div.car-type-filter div.filter-elements div.filter-element span { + margin-left: 5px; + cursor: pointer; + font-size: 12px; + font-weight: 400; +} + +div.car-type-filter div.filter-actions { + text-align: center; + padding-bottom: 10px; +} + +div.car-type-filter div.filter-actions span.uncheckall { + text-decoration: underline; + cursor: pointer; + color: #0064c8; +} diff --git a/frontend/src/assets/css/fuel-filter.css b/frontend/src/assets/css/fuel-filter.css deleted file mode 100644 index ffec99901..000000000 --- a/frontend/src/assets/css/fuel-filter.css +++ /dev/null @@ -1,26 +0,0 @@ -div.fuel-filter div.filter-elements { - padding: 7px 5px; -} - -div.fuel-filter div.filter-elements div.filter-element input[type='checkbox'].fuel-checkbox { - cursor: pointer; - margin-left: 5px; -} - -div.fuel-filter div.filter-elements div.filter-element span { - margin-left: 5px; - cursor: pointer; - font-size: 12px; - font-weight: 400; -} - -div.fuel-filter div.filter-actions { - text-align: center; - padding-bottom: 10px; -} - -div.fuel-filter div.filter-actions span.uncheckall { - text-decoration: underline; - cursor: pointer; - color: #0064c8; -} diff --git a/frontend/src/common/helper.ts b/frontend/src/common/helper.ts index 24fa2f75d..95cdcfdb1 100644 --- a/frontend/src/common/helper.ts +++ b/frontend/src/common/helper.ts @@ -72,6 +72,15 @@ export const getCarTypeShort = (type: string) => { case bookcarsTypes.CarType.Gasoline: return strings.GASOLINE_SHORT + case bookcarsTypes.CarType.Electric: + return strings.ELECTRIC_SHORT + + case bookcarsTypes.CarType.Hybrid: + return strings.HYBRID_SHORT + + case bookcarsTypes.CarType.PlugInHybrid: + return strings.PLUG_IN_HYBRID_SHORT + default: return '' } @@ -148,6 +157,15 @@ export const getCarTypeTooltip = (type: string) => { case bookcarsTypes.CarType.Gasoline: return strings.GASOLINE_TOOLTIP + case bookcarsTypes.CarType.Electric: + return strings.ELECTRIC_TOOLTIP + + case bookcarsTypes.CarType.Hybrid: + return strings.HYBRID_TOOLTIP + + case bookcarsTypes.CarType.PlugInHybrid: + return strings.PLUG_IN_HYBRID_TOOLTIP + default: return '' } diff --git a/frontend/src/components/CarList.tsx b/frontend/src/components/CarList.tsx index 3a7abce3c..487d24ba4 100644 --- a/frontend/src/components/CarList.tsx +++ b/frontend/src/components/CarList.tsx @@ -8,7 +8,7 @@ import { Typography } from '@mui/material' import { - LocalGasStation as FuelIcon, + LocalGasStation as CarTypeIcon, AccountTree as GearboxIcon, Person as SeatsIcon, AcUnit as AirconIcon, @@ -38,7 +38,7 @@ interface CarListProps { suppliers?: string[] pickupLocation?: string dropOffLocation?: string - fuel?: string[] + carType?: string[] gearbox?: string[] mileage?: string[] deposit?: number @@ -58,7 +58,7 @@ const CarList = ({ suppliers, pickupLocation, dropOffLocation, - fuel, + carType: _carType, gearbox, mileage, deposit, @@ -115,7 +115,7 @@ const CarList = ({ _page: number, _suppliers?: string[], _pickupLocation?: string, - _fuel?: string[], + __carType?: string[], _gearbox?: string[], _mileage?: string[], _deposit?: number @@ -125,7 +125,7 @@ const CarList = ({ const payload: bookcarsTypes.GetCarsPayload = { suppliers: _suppliers ?? [], pickupLocation: _pickupLocation, - fuel: _fuel, + carType: __carType, gearbox: _gearbox, mileage: _mileage, deposit: _deposit, @@ -170,7 +170,7 @@ const CarList = ({ useEffect(() => { if (suppliers) { if (suppliers.length > 0) { - fetchData(page, suppliers, pickupLocation, fuel, gearbox, mileage, deposit) + fetchData(page, suppliers, pickupLocation, _carType, gearbox, mileage, deposit) } else { setRows([]) setFetch(false) @@ -181,7 +181,7 @@ const CarList = ({ } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [page, suppliers, pickupLocation, fuel, gearbox, mileage, deposit, from, to]) + }, [page, suppliers, pickupLocation, _carType, gearbox, mileage, deposit, from, to]) useEffect(() => { if (cars) { @@ -196,14 +196,14 @@ const CarList = ({ useEffect(() => { setPage(1) - }, [suppliers, pickupLocation, fuel, gearbox, mileage, deposit, from, to]) + }, [suppliers, pickupLocation, _carType, gearbox, mileage, deposit, from, to]) useEffect(() => { if (reload) { setPage(1) - fetchData(1, suppliers, pickupLocation, fuel, gearbox, mileage, deposit) + fetchData(1, suppliers, pickupLocation, _carType, gearbox, mileage, deposit) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [reload, suppliers, pickupLocation, fuel, gearbox, mileage, deposit]) + }, [reload, suppliers, pickupLocation, _carType, gearbox, mileage, deposit]) const getExtraIcon = (option: string, extra: number) => { let available = false @@ -273,7 +273,7 @@ const CarList = ({
  • - + {helper.getCarTypeShort(car.type)}
    @@ -322,7 +322,7 @@ const CarList = ({
  • - + {`${strings.FUEL_POLICY}${fr ? ' : ' : ': '}${helper.getFuelPolicy(car.fuelPolicy)}`}
    diff --git a/frontend/src/components/CarTypeFilter.tsx b/frontend/src/components/CarTypeFilter.tsx new file mode 100644 index 000000000..b3de938df --- /dev/null +++ b/frontend/src/components/CarTypeFilter.tsx @@ -0,0 +1,319 @@ +import React, { useState, useEffect, useRef } from 'react' +import * as bookcarsTypes from ':bookcars-types' +import * as bookcarsHelper from ':bookcars-helper' +import { strings as commonStrings } from '../lang/common' +import { strings } from '../lang/cars' +import Accordion from './Accordion' + +import '../assets/css/car-type-filter.css' + +interface CarTypeProps { + className?: string + onChange?: (values: bookcarsTypes.CarType[]) => void +} + +const allTypes = bookcarsHelper.getAllCarTypes() + +const CarType = ({ + className, + onChange +}: CarTypeProps) => { + const [allChecked, setAllChecked] = useState(true) + const [values, setValues] = useState(allTypes) + + const dieselRef = useRef(null) + const gasolineRef = useRef(null) + const electricRef = useRef(null) + const hybridRef = useRef(null) + const plugInHybridRef = useRef(null) + + useEffect(() => { + if (allChecked + && dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = true + gasolineRef.current.checked = true + electricRef.current.checked = true + hybridRef.current.checked = true + plugInHybridRef.current.checked = true + } + }, [allChecked]) + + const handleCheckDieselChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Diesel) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Diesel), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleDieselClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckDieselChange(event) + } + + const handleCheckGasolineChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Gasoline) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Gasoline), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleGasolineClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckGasolineChange(event) + } + + const handleCheckElectricChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Electric) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Electric), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleElectricClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckElectricChange(event) + } + + const handleCheckHybridChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.Hybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Hybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handleHybridClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckHybridChange(event) + } + + const handleCheckPlugInHybridChange = (e: React.ChangeEvent | React.MouseEvent) => { + if ('checked' in e.currentTarget && e.currentTarget.checked) { + values.push(bookcarsTypes.CarType.PlugInHybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.PlugInHybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setValues(values) + + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const handlePlugInHybridClick = (e: React.MouseEvent) => { + const checkbox = e.currentTarget.previousSibling as HTMLInputElement + checkbox.checked = !checkbox.checked + const event = e + event.currentTarget = checkbox + handleCheckPlugInHybridChange(event) + } + + const handleUncheckAllChange = () => { + if (allChecked) { + // uncheck all + if (dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = false + gasolineRef.current.checked = false + electricRef.current.checked = false + hybridRef.current.checked = false + plugInHybridRef.current.checked = false + } + setAllChecked(false) + setValues([]) + } else { + // check all + if (dieselRef.current + && gasolineRef.current + && electricRef.current + && hybridRef.current + && plugInHybridRef.current) { + dieselRef.current.checked = true + gasolineRef.current.checked = true + electricRef.current.checked = true + hybridRef.current.checked = true + plugInHybridRef.current.checked = true + } + const _values = allTypes + + setAllChecked(true) + setValues(_values) + + if (onChange) { + onChange(bookcarsHelper.clone(_values)) + } + } + } + + return ( + +
    +
    + + + {strings.DIESEL} + +
    +
    + + + {strings.GASOLINE} + +
    + +
    + + + {strings.ELECTRIC} + +
    +
    + + + {strings.HYBRID} + +
    +
    + + + {strings.PLUG_IN_HYBRID} + +
    +
    +
    + + {allChecked ? commonStrings.UNCHECK_ALL : commonStrings.CHECK_ALL} + +
    +
    + ) +} + +export default CarType diff --git a/frontend/src/components/FuelFilter.tsx b/frontend/src/components/FuelFilter.tsx deleted file mode 100644 index 6983c34ae..000000000 --- a/frontend/src/components/FuelFilter.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react' -import * as bookcarsTypes from ':bookcars-types' -import * as bookcarsHelper from ':bookcars-helper' -import { strings as commonStrings } from '../lang/common' -import { strings } from '../lang/cars' -import Accordion from './Accordion' - -import '../assets/css/fuel-filter.css' - -interface FuelFilterProps { - className?: string - onChange?: (values: bookcarsTypes.CarType[]) => void -} - -const FuelFilter = ({ - className, - onChange -}: FuelFilterProps) => { - const [allChecked, setAllChecked] = useState(true) - const [values, setValues] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) - - const dieselRef = useRef(null) - const gasolineRef = useRef(null) - - useEffect(() => { - if (allChecked && dieselRef.current && gasolineRef.current) { - dieselRef.current.checked = true - gasolineRef.current.checked = true - } - }, [allChecked]) - - const handleCheckDieselChange = (e: React.ChangeEvent | React.MouseEvent) => { - if ('checked' in e.currentTarget && e.currentTarget.checked) { - values.push(bookcarsTypes.CarType.Diesel) - - if (values.length === 2) { - setAllChecked(true) - } - } else { - values.splice( - values.findIndex((v) => v === bookcarsTypes.CarType.Diesel), - 1, - ) - - if (values.length === 0) { - setAllChecked(false) - } - } - - setValues(values) - - if (onChange) { - onChange(bookcarsHelper.clone(values)) - } - } - - const handleDieselClick = (e: React.MouseEvent) => { - const checkbox = e.currentTarget.previousSibling as HTMLInputElement - checkbox.checked = !checkbox.checked - const event = e - event.currentTarget = checkbox - handleCheckDieselChange(event) - } - - const handleCheckGasolineChange = (e: React.ChangeEvent | React.MouseEvent) => { - if ('checked' in e.currentTarget && e.currentTarget.checked) { - values.push(bookcarsTypes.CarType.Gasoline) - - if (values.length === 2) { - setAllChecked(true) - } - } else { - values.splice( - values.findIndex((v) => v === bookcarsTypes.CarType.Gasoline), - 1, - ) - - if (values.length === 0) { - setAllChecked(false) - } - } - - setValues(values) - - if (onChange) { - onChange(bookcarsHelper.clone(values)) - } - } - - const handleGasolineClick = (e: React.MouseEvent) => { - const checkbox = e.currentTarget.previousSibling as HTMLInputElement - checkbox.checked = !checkbox.checked - const event = e - event.currentTarget = checkbox - handleCheckGasolineChange(event) - } - - const handleUncheckAllChange = () => { - if (allChecked) { - // uncheck all - if (dieselRef.current) { - dieselRef.current.checked = false - } - if (gasolineRef.current) { - gasolineRef.current.checked = false - } - setAllChecked(false) - setValues([]) - } else { - // check all - if (dieselRef.current) { - dieselRef.current.checked = true - } - if (gasolineRef.current) { - gasolineRef.current.checked = true - } - const _values = [bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline] - - setAllChecked(true) - setValues(_values) - - if (onChange) { - onChange(bookcarsHelper.clone(_values)) - } - } - } - - return ( - -
    -
    - - - {strings.DIESEL} - -
    -
    - - - {strings.GASOLINE} - -
    -
    -
    - - {allChecked ? commonStrings.UNCHECK_ALL : commonStrings.CHECK_ALL} - -
    -
    - ) -} - -export default FuelFilter diff --git a/frontend/src/lang/cars.ts b/frontend/src/lang/cars.ts index 42ea6840c..ff907df85 100644 --- a/frontend/src/lang/cars.ts +++ b/frontend/src/lang/cars.ts @@ -8,8 +8,14 @@ const strings = new LocalizedStrings({ FUEL_POLICY: 'Politique carburant', DIESEL: 'Diesel', GASOLINE: 'Essence', + ELECTRIC: 'Électrique', + HYBRID: 'Hybride', + PLUG_IN_HYBRID: 'Hybride rechargeable', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'E', + ELECTRIC_SHORT: 'ELEC', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'HR', GEARBOX_MANUAL: 'Manuelle', GEARBOX_AUTOMATIC: 'Automatique', GEARBOX_MANUAL_SHORT: 'M', @@ -18,6 +24,9 @@ const strings = new LocalizedStrings({ FUEL_POLICY_FREE_TANK: 'Plein inclus', DIESEL_TOOLTIP: 'Cette voiture a un moteur diesel', GASOLINE_TOOLTIP: 'Cette voiture a un moteur essence', + ELECTRIC_TOOLTIP: 'Cette voiture est électrique', + HYBRID_TOOLTIP: 'Cette voiture est hybride', + PLUG_IN_HYBRID_TOOLTIP: 'Cette voiture est hybride rechargeable', GEARBOX_MANUAL_TOOLTIP: 'Cette voiture a une transmission manuelle', GEARBOX_AUTOMATIC_TOOLTIP: 'Cette voiture a une transmission automatique', SEATS_TOOLTIP_1: 'Cette voiture a ', @@ -67,8 +76,14 @@ const strings = new LocalizedStrings({ FUEL_POLICY: 'Fuel policy', DIESEL: 'Diesel', GASOLINE: 'Gasoline', + ELECTRIC: 'Electric', + HYBRID: 'Hybrid', + PLUG_IN_HYBRID: 'Plug-in hybrid', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'G', + ELECTRIC_SHORT: 'E', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'PH', GEARBOX_MANUAL: 'Manual', GEARBOX_AUTOMATIC: 'Automatic', GEARBOX_MANUAL_SHORT: 'M', @@ -77,6 +92,9 @@ const strings = new LocalizedStrings({ FUEL_POLICY_FREE_TANK: 'Free tank', DIESEL_TOOLTIP: 'This car has a diesel engine', GASOLINE_TOOLTIP: 'This car has a gasoline engine', + ELECTRIC_TOOLTIP: 'This car is electric', + HYBRID_TOOLTIP: 'This car is hybrid', + PLUG_IN_HYBRID_TOOLTIP: 'This car is plug-in hybrid', GEARBOX_MANUAL_TOOLTIP: 'This car has a manual gearbox', GEARBOX_AUTOMATIC_TOOLTIP: 'This car has an automatic gearbox', SEATS_TOOLTIP_1: 'This car has ', diff --git a/frontend/src/pages/Search.tsx b/frontend/src/pages/Search.tsx index 42da6665f..051426426 100644 --- a/frontend/src/pages/Search.tsx +++ b/frontend/src/pages/Search.tsx @@ -10,7 +10,7 @@ import Layout from '../components/Layout' import NoMatch from './NoMatch' import CarFilter from '../components/CarFilter' import SupplierFilter from '../components/SupplierFilter' -import FuelFilter from '../components/FuelFilter' +import CarType from '../components/CarTypeFilter' import GearboxFilter from '../components/GearboxFilter' import MileageFilter from '../components/MileageFilter' import DepositFilter from '../components/DepositFilter' @@ -30,7 +30,7 @@ const Search = () => { const [allSuppliers, setAllSuppliers] = useState([]) const [suppliers, setSuppliers] = useState() const [loading, setLoading] = useState(true) - const [fuel, setFuel] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) + const [carType, setCarType] = useState(bookcarsHelper.getAllCarTypes()) const [gearbox, setGearbox] = useState([bookcarsTypes.GearboxType.Automatic, bookcarsTypes.GearboxType.Manual]) const [mileage, setMileage] = useState([bookcarsTypes.Mileage.Limited, bookcarsTypes.Mileage.Unlimited]) const [deposit, setDeposit] = useState(-1) @@ -46,8 +46,8 @@ const Search = () => { setTo(filter.to) } - const handleFuelFilterChange = (values: bookcarsTypes.CarType[]) => { - setFuel(values) + const handleCarTypeFilterChange = (values: bookcarsTypes.CarType[]) => { + setCarType(values) } const handleGearboxFilterChange = (values: bookcarsTypes.GearboxType[]) => { @@ -130,7 +130,7 @@ const Search = () => { <> - + @@ -140,7 +140,7 @@ const Search = () => {
    { case bookcarsTypes.CarType.Gasoline: return i18n.t('GASOLINE_SHORT') + case bookcarsTypes.CarType.Electric: + return i18n.t('ELECTRIC_SHORT') + + case bookcarsTypes.CarType.Hybrid: + return i18n.t('HYBRID_SHORT') + + case bookcarsTypes.CarType.PlugInHybrid: + return i18n.t('PLUG_IN_HYBRID_SHORT') + default: return '' } diff --git a/mobile/components/Car.tsx b/mobile/components/Car.tsx index 0ad134dd9..4644159ef 100644 --- a/mobile/components/Car.tsx +++ b/mobile/components/Car.tsx @@ -186,6 +186,8 @@ const styles = StyleSheet.create({ img: { width: env.CAR_IMAGE_WIDTH, height: env.CAR_IMAGE_HEIGHT, + flex: 1, + resizeMode: 'contain', }, infos: { flexDirection: 'row', @@ -234,6 +236,8 @@ const styles = StyleSheet.create({ supplierImg: { width: env.SUPPLIER_IMAGE_WIDTH, height: env.SUPPLIER_IMAGE_HEIGHT, + flex: 1, + resizeMode: 'contain', }, supplierText: { color: '#a1a1a1', diff --git a/mobile/components/CarList.tsx b/mobile/components/CarList.tsx index 4d5f29c36..372945c7f 100644 --- a/mobile/components/CarList.tsx +++ b/mobile/components/CarList.tsx @@ -17,7 +17,7 @@ interface CarListProps { suppliers?: string[] pickupLocation?: string dropOffLocation?: string - fuel?: string[] + carType?: string[] gearbox?: string[] mileage?: string[] deposit?: number @@ -32,7 +32,7 @@ const CarList = ({ suppliers, pickupLocation, dropOffLocation, - fuel, + carType: _carType, gearbox, mileage, deposit, @@ -64,7 +64,7 @@ const CarList = ({ _page: number, _suppliers?: string[], _pickupLocation?: string, - _fuel?: string[], + __carType?: string[], _gearbox?: string[], _mileage?: string[], _deposit?: number @@ -74,10 +74,10 @@ const CarList = ({ setLoading(true) setFetch(true) - const payload = { + const payload: bookcarsTypes.GetCarsPayload = { suppliers: _suppliers, pickupLocation: _pickupLocation, - fuel: _fuel, + carType: __carType, gearbox: _gearbox, mileage: _mileage, deposit: _deposit, @@ -111,7 +111,7 @@ const CarList = ({ useEffect(() => { if (suppliers) { if (suppliers.length > 0) { - fetchData(page, suppliers, pickupLocation, fuel, gearbox, mileage, deposit) + fetchData(page, suppliers, pickupLocation, _carType, gearbox, mileage, deposit) } else { setRows([]) setFetch(false) @@ -120,11 +120,11 @@ const CarList = ({ } } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [page, suppliers, pickupLocation, fuel, gearbox, mileage, deposit]) + }, [page, suppliers, pickupLocation, _carType, gearbox, mileage, deposit]) useEffect(() => { setPage(1) - }, [suppliers, pickupLocation, fuel, gearbox, mileage, deposit]) + }, [suppliers, pickupLocation, _carType, gearbox, mileage, deposit]) const numToRender = Math.floor(env.CARS_PAGE_SIZE / 2) diff --git a/mobile/components/FuelFilter.tsx b/mobile/components/CarTypeFilter.tsx similarity index 54% rename from mobile/components/FuelFilter.tsx rename to mobile/components/CarTypeFilter.tsx index fb678f4e2..f92dce9ae 100644 --- a/mobile/components/FuelFilter.tsx +++ b/mobile/components/CarTypeFilter.tsx @@ -8,27 +8,32 @@ import Accordion from './Accordion' import Link from './Link' import Switch from './Switch' -interface FuelFilterProps { +interface CarTypeFilterProps { visible?: boolean style?: object onChange?: (values: bookcarsTypes.CarType[]) => void } -const FuelFilter = ({ +const allTypes = bookcarsHelper.getAllCarTypes() + +const CarTypeFilter = ({ visible, style, onChange -}: FuelFilterProps) => { +}: CarTypeFilterProps) => { const [diesel, setDiesel] = useState(true) const [gasoline, setGasoline] = useState(true) - const [values, setValues] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) + const [electric, setElectric] = useState(true) + const [hybrid, setHybrid] = useState(true) + const [plugInHybrid, setPlugInHybrid] = useState(true) + const [values, setValues] = useState(allTypes) const [allChecked, setAllChecked] = useState(true) const onValueChangeDiesel = (checked: boolean) => { if (checked) { values.push(bookcarsTypes.CarType.Diesel) - if (values.length === 2) { + if (values.length === allTypes.length) { setAllChecked(true) } } else { @@ -53,7 +58,7 @@ const FuelFilter = ({ if (checked) { values.push(bookcarsTypes.CarType.Gasoline) - if (values.length === 2) { + if (values.length === allTypes.length) { setAllChecked(true) } } else { @@ -74,6 +79,81 @@ const FuelFilter = ({ } } + const onValueChangeElectric = (checked: boolean) => { + if (checked) { + values.push(bookcarsTypes.CarType.Electric) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Electric), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setElectric(checked) + setValues(values) + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const onValueChangeHybrid = (checked: boolean) => { + if (checked) { + values.push(bookcarsTypes.CarType.Hybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.Hybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setHybrid(checked) + setValues(values) + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + + const onValueChangePlugInHybrid = (checked: boolean) => { + if (checked) { + values.push(bookcarsTypes.CarType.PlugInHybrid) + + if (values.length === allTypes.length) { + setAllChecked(true) + } + } else { + values.splice( + values.findIndex((v) => v === bookcarsTypes.CarType.PlugInHybrid), + 1, + ) + + if (values.length === 0) { + setAllChecked(false) + } + } + + setPlugInHybrid(checked) + setValues(values) + if (onChange) { + onChange(bookcarsHelper.clone(values)) + } + } + return ( visible && ( @@ -81,6 +161,9 @@ const FuelFilter = ({ + + + 1 && ( + visible && (suppliers.length > 1 && suppliers.length < 17) && ( @@ -158,6 +158,8 @@ const styles = StyleSheet.create({ image: { width: env.SUPPLIER_IMAGE_WIDTH, height: env.SUPPLIER_IMAGE_HEIGHT, + flex: 1, + resizeMode: 'contain', }, link: { marginTop: 10, diff --git a/mobile/lang/en.ts b/mobile/lang/en.ts index fc59bd65d..760d5d64d 100644 --- a/mobile/lang/en.ts +++ b/mobile/lang/en.ts @@ -116,6 +116,9 @@ export const en = { DAILY: '/day', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'G', + ELECTRIC_SHORT: 'E', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'PH', GEARBOX_MANUAL_SHORT: 'M', GEARBOX_AUTOMATIC_SHORT: 'A', FUEL_POLICY: 'Fuel policy', @@ -166,6 +169,9 @@ export const en = { ENGINE: 'Engine', DIESEL: 'Diesel', GASOLINE: 'Gasoline', + ELECTRIC: 'Electric', + HYBRID: 'Hybrid', + PLUG_IN_HYBRID: 'Plug-in hybrid', GEARBOX: 'Gearbox', GEARBOX_AUTOMATIC: 'Automatic', GEARBOX_MANUAL: 'Manual', diff --git a/mobile/lang/fr.ts b/mobile/lang/fr.ts index 42026852d..0bcd7e821 100644 --- a/mobile/lang/fr.ts +++ b/mobile/lang/fr.ts @@ -115,6 +115,9 @@ export const fr = { DAILY: '/jour', DIESEL_SHORT: 'D', GASOLINE_SHORT: 'E', + ELECTRIC_SHORT: 'ELEC', + HYBRID_SHORT: 'H', + PLUG_IN_HYBRID_SHORT: 'HR', GEARBOX_MANUAL_SHORT: 'M', GEARBOX_AUTOMATIC_SHORT: 'A', FUEL_POLICY: 'Politique carburant', @@ -166,6 +169,9 @@ export const fr = { ENGINE: 'Moteur', DIESEL: 'Diesel', GASOLINE: 'Essence', + ELECTRIC: 'Électrique', + HYBRID: 'Hybride', + PLUG_IN_HYBRID: 'Hybride rechargeable', GEARBOX: 'Transmission', GEARBOX_AUTOMATIC: 'Automatique', GEARBOX_MANUAL: 'Manuelle', diff --git a/mobile/package-lock.json b/mobile/package-lock.json index 61d548735..8974a3922 100644 --- a/mobile/package-lock.json +++ b/mobile/package-lock.json @@ -9,7 +9,7 @@ "version": "4.0.0", "dependencies": { "@react-native-async-storage/async-storage": "1.23.1", - "@react-native-community/datetimepicker": "7.7.0", + "@react-native-community/datetimepicker": "8.0.1", "@react-navigation/drawer": "^6.6.15", "@react-navigation/native": "^6.1.17", "@react-navigation/native-stack": "^6.9.26", @@ -19,21 +19,21 @@ "@types/mime": "^3.0.4", "@types/react-native-dotenv": "^0.2.2", "@types/react-native-vector-icons": "^6.4.18", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "axios": "^1.6.8", - "axios-retry": "^4.1.0", + "axios-retry": "^4.2.0", "babel-plugin-module-resolver": "^5.0.2", "date-fns": "^3.6.0", - "expo": "~51.0.2", + "expo": "~51.0.8", "expo-asset": "~10.0.6", "expo-constants": "~16.0.1", "expo-device": "~6.0.2", - "expo-image-picker": "~15.0.4", + "expo-image-picker": "~15.0.5", "expo-localization": "~15.0.3", - "expo-notifications": "~0.28.1", + "expo-notifications": "~0.28.3", "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", - "expo-updates": "~0.25.11", + "expo-updates": "~0.25.14", "i18n-js": "^4.4.3", "lodash.debounce": "^4.0.8", "mime": "^4.0.3", @@ -44,7 +44,7 @@ "react-native-gesture-handler": "~2.16.2", "react-native-paper": "^5.12.3", "react-native-reanimated": "~3.10.1", - "react-native-root-toast": "^3.5.1", + "react-native-root-toast": "^3.6.0", "react-native-safe-area-context": "4.10.1", "react-native-screens": "~3.31.1", "react-native-size-matters": "^0.4.2", @@ -54,8 +54,8 @@ "devDependencies": { "@babel/core": "^7.24.5", "@types/react": "~18.2.79", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-airbnb-base": "^15.0.0", @@ -2258,15 +2258,15 @@ } }, "node_modules/@expo/cli": { - "version": "0.18.10", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.10.tgz", - "integrity": "sha512-cuAE060tcX4Mn+sF+tGAchGDsTNzwCUB7ioFGB3OrvxoU3idsqZJPs6xMt5Utuuy7QDGPnOn68H0vC4kDsXkUQ==", + "version": "0.18.13", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.13.tgz", + "integrity": "sha512-ZO1fpDK8z6mLeQGuFP6e3cZyCHV55ohZY7/tEyhpft3bwysS680eyFg5SFe+tWNFesnziFrbtI8JaUyhyjqovA==", "dependencies": { "@babel/runtime": "^7.20.0", "@expo/code-signing-certificates": "0.0.5", - "@expo/config": "~9.0.0-beta.0", - "@expo/config-plugins": "~8.0.0-beta.0", - "@expo/devcert": "^1.0.0", + "@expo/config": "~9.0.0", + "@expo/config-plugins": "~8.0.0", + "@expo/devcert": "^1.1.2", "@expo/env": "~0.3.0", "@expo/image-utils": "^0.5.0", "@expo/json-file": "^8.3.0", @@ -2274,7 +2274,7 @@ "@expo/osascript": "^2.0.31", "@expo/package-manager": "^1.5.0", "@expo/plist": "^0.1.0", - "@expo/prebuild-config": "7.0.3", + "@expo/prebuild-config": "7.0.4", "@expo/rudder-sdk-node": "1.1.1", "@expo/spawn-async": "^1.7.2", "@expo/xcpretty": "^4.3.0", @@ -2285,7 +2285,7 @@ "arg": "5.0.2", "better-opn": "~3.0.2", "bplist-parser": "^0.3.1", - "cacache": "^15.3.0", + "cacache": "^18.0.2", "chalk": "^4.0.0", "ci-info": "^3.3.0", "connect": "^3.7.0", @@ -2343,6 +2343,41 @@ "expo-internal": "build/bin/cli" } }, + "node_modules/@expo/cli/node_modules/@expo/prebuild-config": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.4.tgz", + "integrity": "sha512-E2n3QbwgV8Qa0CBw7BHrWBDWD7l8yw+N/yjvXpSPFFtoZLMSKyegdkJFACh2u+UIRKUSZm8zQwHeZR0rqAxV9g==", + "dependencies": { + "@expo/config": "~9.0.0", + "@expo/config-plugins": "~8.0.0", + "@expo/config-types": "^51.0.0-unreleased", + "@expo/image-utils": "^0.5.0", + "@expo/json-file": "^8.3.0", + "@react-native/normalize-colors": "~0.74.83", + "debug": "^4.3.1", + "fs-extra": "^9.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" + }, + "peerDependencies": { + "expo-modules-autolinking": ">=0.8.1" + } + }, + "node_modules/@expo/cli/node_modules/@expo/prebuild-config/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/cli/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2453,6 +2488,17 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@expo/cli/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/@expo/cli/node_modules/picomatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", @@ -2486,6 +2532,14 @@ "node": ">=8" } }, + "node_modules/@expo/cli/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@expo/code-signing-certificates": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz", @@ -2496,12 +2550,12 @@ } }, "node_modules/@expo/config": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-9.0.1.tgz", - "integrity": "sha512-0tjaXBstTbXmD4z+UMFBkh2SZFwilizSQhW6DlaTMnPG5ezuw93zSFEWAuEC3YzkpVtNQTmYzxAYjxwh6seOGg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-9.0.2.tgz", + "integrity": "sha512-BKQ4/qBf3OLT8hHp5kjObk2vxwoRQ1yYQBbG/OM9Jdz32yYtrU8opTbKRAxfZEWH5i3ZHdLrPdC1rO0I6WxtTw==", "dependencies": { "@babel/code-frame": "~7.10.4", - "@expo/config-plugins": "~8.0.0-beta.0", + "@expo/config-plugins": "~8.0.0", "@expo/config-types": "^51.0.0-unreleased", "@expo/json-file": "^8.3.0", "getenv": "^1.0.0", @@ -2635,9 +2689,9 @@ } }, "node_modules/@expo/devcert": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.0.tgz", - "integrity": "sha512-ghUVhNJQOCTdQckSGTHctNp/0jzvVoMMkVh+6SHn+TZj8sU15U/npXIDt8NtQp0HedlPaCgkVdMu8Sacne0aEA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.2.tgz", + "integrity": "sha512-FyWghLu7rUaZEZSTLt/XNRukm0c9GFfwP0iFaswoDWpV6alvVg+zRAfCLdIVQEz1SVcQ3zo1hMZFDrnKGvkCuQ==", "dependencies": { "application-config-path": "^0.1.0", "command-exists": "^1.2.4", @@ -2645,7 +2699,7 @@ "eol": "^0.9.1", "get-port": "^3.2.0", "glob": "^7.1.2", - "lodash": "^4.17.4", + "lodash": "^4.17.21", "mkdirp": "^0.5.1", "password-prompt": "^1.0.4", "rimraf": "^2.6.2", @@ -2739,9 +2793,9 @@ } }, "node_modules/@expo/fingerprint": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.7.1.tgz", - "integrity": "sha512-lbTwFiIk0lOm9zzPRvnC45GfPqXqPB3w4hDDKVma+8FDAbPCWhNN42ltLhx/ekwcHFQxURmg0fHm59k0Vy+jtw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.8.0.tgz", + "integrity": "sha512-LBNweJnpG16p7SbvFGINF5Q44bDErIcm1li9SuvYQgrrSey3ErIPmZsiMsNBxlvVie6eTp4wmFO6IFmeaqEhbg==", "dependencies": { "@expo/spawn-async": "^1.7.2", "chalk": "^4.1.2", @@ -3031,15 +3085,15 @@ } }, "node_modules/@expo/metro-config": { - "version": "0.18.3", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.3.tgz", - "integrity": "sha512-E4iW+VT/xHPPv+t68dViOsW7egtGIr+sRElcym0iGpC4goLz9WBux/xGzWgxvgvvHEWa21uSZQPM0jWla0OZXg==", + "version": "0.18.4", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.4.tgz", + "integrity": "sha512-vh9WDf/SzE+NYCn6gqbzLKiXtENFlFZdAqyj9nI38RvQ4jw6TJIQ8+ExcdLDT3MOG36Ytg44XX9Zb3OWF6LVxw==", "dependencies": { "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@babel/parser": "^7.20.0", "@babel/types": "^7.20.0", - "@expo/config": "~9.0.0-beta.0", + "@expo/config": "~9.0.0", "@expo/env": "~0.3.0", "@expo/json-file": "~8.3.0", "@expo/spawn-async": "^1.7.2", @@ -3493,7 +3547,8 @@ "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", @@ -3558,7 +3613,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -3575,7 +3629,6 @@ "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" }, @@ -3587,7 +3640,6 @@ "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" }, @@ -3598,14 +3650,12 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -3622,7 +3672,6 @@ "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" }, @@ -3637,7 +3686,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -3875,12 +3923,14 @@ } }, "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dependencies": { - "@gar/promisify": "^1.0.1", "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@npmcli/fs/node_modules/semver": { @@ -3986,44 +4036,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@npmcli/node-gyp": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", @@ -4095,7 +4107,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -5646,11 +5657,21 @@ } }, "node_modules/@react-native-community/datetimepicker": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.7.0.tgz", - "integrity": "sha512-nYzZy4DQLRFUzKJShWzRleCaebmCJfZ1lIcFmZgMXJoiVuGJNw3OIGHSWmHhPETh3OhP1RO3to882d7WmDIyrA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.0.1.tgz", + "integrity": "sha512-4BO0t3geMNNw9cIIm9p9FNUzwMXexdzD4pAH0AaUAycs3BS71HLrX8jHbrI7nzq/+8O7cLAXn5Gudte+YpTV8Q==", "dependencies": { "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "react-native-windows": { + "optional": true + } } }, "node_modules/@react-native/assets-registry": { @@ -6417,12 +6438,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -6496,12 +6511,6 @@ "@types/react-native": "^0.70" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/semver-utils": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/semver-utils/-/semver-utils-1.1.3.tgz", @@ -6514,9 +6523,9 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "node_modules/@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + "version": "13.11.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", + "integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg==" }, "node_modules/@types/yargs": { "version": "17.0.32", @@ -6532,21 +6541,19 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -6566,49 +6573,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { @@ -6628,13 +6602,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -6645,13 +6619,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -6672,9 +6646,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -6685,13 +6659,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6721,18 +6695,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -6749,13 +6711,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -6763,25 +6722,16 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -6794,46 +6744,13 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -7350,9 +7267,9 @@ } }, "node_modules/axios-retry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.1.0.tgz", - "integrity": "sha512-svdth4H00yhlsjBbjfLQ/sMLkXqeLxhiFC1nE1JtkN/CIssGxqk0UwTEdrVjwA2gr3yJkAulwvDSIm4z4HyPvg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.2.0.tgz", + "integrity": "sha512-zcVGX7NrRe+nadNFsSlf+KUT8ZFWRd8lf5f2QDqZCvWX6n3KTfPWErpTRxD7Nd7pPzQlnpvoEUq1ZrkhCwj/cA==", "dependencies": { "is-retry-allowed": "^2.2.0" }, @@ -7477,9 +7394,9 @@ } }, "node_modules/babel-preset-expo": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-11.0.5.tgz", - "integrity": "sha512-IjqR4B7wnBU55pofLeLGjwUGrWJE1buamgzE9CYpYCNicZmJcNjXUcinQiurXCMuClF2hOff3QfZsLxnGj1UaA==", + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-11.0.6.tgz", + "integrity": "sha512-jRi9I5/jT+dnIiNJDjDg+I/pV+AlxrIW/DNbdqYoRWPZA/LHDqD6IJnJXLxbuTcQ+llp+0LWcU7f/kC/PgGpkw==", "dependencies": { "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-transform-export-namespace-from": "^7.22.11", @@ -7847,73 +7764,107 @@ } }, "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "version": "18.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.3.tgz", + "integrity": "sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==", "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", + "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dependencies": { - "yallist": "^4.0.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dependencies": { + "minipass": "^7.0.3" }, "engines": { - "node": ">=10" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/cacache/node_modules/glob": { + "version": "10.3.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", + "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.11.0" + }, "bin": { - "mkdirp": "bin/cmd.js" + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dependencies": { - "glob": "^7.1.3" + "brace-expansion": "^2.0.1" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/cacache/node_modules/minipass": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/cacache/node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } }, "node_modules/cacheable-lookup": { "version": "7.0.0", @@ -8992,8 +8943,7 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ee-first": { "version": "1.1.1", @@ -9854,23 +9804,23 @@ } }, "node_modules/expo": { - "version": "51.0.2", - "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.2.tgz", - "integrity": "sha512-aRKrheMMQBcNDg2SBjW5kcSN5G58bdIpsxeSQ65Bx18DFLXjPv5UaU9kzIWRAcxaPtgictn9ut9IJQVZKChNxQ==", + "version": "51.0.8", + "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.8.tgz", + "integrity": "sha512-bdTOiMb1f3PChtuqEZ9czUm2gMTmS0r1+H+Pkm2O3PsuLnOgxfIBzL6S37+J4cUocLBaENrmx9SOGKpzhBqXpg==", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.18.10", - "@expo/config": "9.0.1", + "@expo/cli": "0.18.13", + "@expo/config": "9.0.2", "@expo/config-plugins": "8.0.4", - "@expo/metro-config": "0.18.3", + "@expo/metro-config": "0.18.4", "@expo/vector-icons": "^14.0.0", - "babel-preset-expo": "~11.0.5", + "babel-preset-expo": "~11.0.6", "expo-asset": "~10.0.6", "expo-file-system": "~17.0.1", - "expo-font": "~12.0.4", - "expo-keep-awake": "~13.0.1", + "expo-font": "~12.0.5", + "expo-keep-awake": "~13.0.2", "expo-modules-autolinking": "1.11.1", - "expo-modules-core": "1.12.10", + "expo-modules-core": "1.12.11", "fbemitter": "^3.0.0", "whatwg-url-without-unicode": "8.0.0-3" }, @@ -9936,9 +9886,9 @@ } }, "node_modules/expo-font": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-12.0.4.tgz", - "integrity": "sha512-VtOQB7MEeFMVwo46/9/ntqzrgraTE7gAsnfi2NukFcCpDmyAU3G1R7m287LUXltE46SmGkMgAvM6+fflXFjaJA==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-12.0.5.tgz", + "integrity": "sha512-h/VkN4jlHYDJ6T6pPgOYTVoDEfBY0CTKQe4pxnPDGQiE6H+DFdDgk+qWVABGpRMH0+zXoHB+AEi3OoQjXIynFA==", "dependencies": { "fontfaceobserver": "^2.1.0" }, @@ -9955,9 +9905,9 @@ } }, "node_modules/expo-image-picker": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-15.0.4.tgz", - "integrity": "sha512-Jo78o3DQfqpYC4fsnayxTEVGDFSbaNMwx5gQ2PPlEYMK5AmD5qexQjxhlxM1mZ0e1xkJKJfN7XEdcf53jW9vIg==", + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-15.0.5.tgz", + "integrity": "sha512-Qqp16udsadx/YpNcNaWzfbmO0tbMxyX9bS1aFiDVC+Zffh8LY8S4HJJcnWqSC2TeuAl+9SxUwTloJagvPeMBBw==", "dependencies": { "expo-image-loader": "~4.7.0" }, @@ -9971,9 +9921,9 @@ "integrity": "sha512-mlfaSArGVb+oJmUcR22jEONlgPp0wj4iNIHfQ2je9Q8WTOqMc0Ws9tUciz3JdJnhffdHqo/k8fpvf0IRmN5HPA==" }, "node_modules/expo-keep-awake": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.1.tgz", - "integrity": "sha512-Kqv8Bf1f5Jp7YMUgTTyKR9GatgHJuAcC8vVWDEkgVhB3O7L3pgBy5MMSMUhkTmRRV6L8TZe/rDmjiBoVS/soFA==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz", + "integrity": "sha512-kKiwkVg/bY0AJ5q1Pxnm/GvpeB6hbNJhcFsoOWDh2NlpibhCLaHL826KHUM+WsnJRbVRxJ+K9vbPRHEMvFpVyw==", "peerDependencies": { "expo": "*" } @@ -10114,17 +10064,17 @@ } }, "node_modules/expo-modules-core": { - "version": "1.12.10", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.10.tgz", - "integrity": "sha512-aS4imfr7fuUtcx+j/CHuG6ohNSThyCzGRh1kKjQTDcO0/CqDO2cSFnxf7n2vpiRFgyoMFJvFFtW/zIzVXiC2Tw==", + "version": "1.12.11", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.11.tgz", + "integrity": "sha512-CF5G6hZo/6uIUz6tj4dNRlvE5L4lakYukXPqz5ZHQ+6fLk1NQVZbRdpHjMkxO/QSBQcKUzG/ngeytpoJus7poQ==", "dependencies": { "invariant": "^2.2.4" } }, "node_modules/expo-notifications": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.1.tgz", - "integrity": "sha512-qBVcq3lc+FIvcYt/8M+JB1c60g0hVuyGY4MVGTY56ciU6nMOCiBiz4XPc3DeiZA16jVtfriooWA26wqBkQfkHg==", + "version": "0.28.3", + "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.28.3.tgz", + "integrity": "sha512-Xaj82eQUJzJXa8+giZr708ih86GGtkGS8N01epoiDkTKC8Z9783UJ8Pf8+PSFSfHsY3Sd8TJpQrD9n7QnGHwGQ==", "dependencies": { "@expo/image-utils": "^0.5.0", "@ide/backoff": "^1.0.0", @@ -10194,14 +10144,14 @@ "integrity": "sha512-R+gFGn0x5CWl4OVlk2j1bJTJIz4KO8mPoCHpRHmfqMjmrMvrOM0qQSY3V5NHXwp1yT/L2v8aUmFQsBRIdvi1XA==" }, "node_modules/expo-updates": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.11.tgz", - "integrity": "sha512-ZO+e6bLsEBMz+JdEOlJXGf+3w606si7zKKEEzkwDQWJWP20W0WQAG+MDYgTEgxQboc+jTC+T0MvvOvkVb8cFIQ==", + "version": "0.25.14", + "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-0.25.14.tgz", + "integrity": "sha512-taYa6Q/882MxPaMZEoU0Tr4Ivtq0B0XUmCgj7GcKv0pDDhB7vuQ4uxXhWYn5udX+nJM0KH+dtEVFNVyeucVArg==", "dependencies": { "@expo/code-signing-certificates": "0.0.5", - "@expo/config": "~9.0.0-beta.0", - "@expo/config-plugins": "~8.0.0-beta.0", - "@expo/fingerprint": "^0.7.0", + "@expo/config": "~9.0.0", + "@expo/config-plugins": "~8.0.0", + "@expo/fingerprint": "^0.8.0", "@expo/spawn-async": "^1.7.2", "arg": "4.1.0", "chalk": "^4.1.2", @@ -10614,7 +10564,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -10630,7 +10579,6 @@ "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" }, @@ -11444,7 +11392,8 @@ "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true }, "node_modules/inflight": { "version": "1.0.6", @@ -12151,7 +12100,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -13383,18 +13331,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", - "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/make-fetch-happen/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -13521,84 +13457,6 @@ "node": ">=8" } }, - "node_modules/make-fetch-happen/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/make-plural": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz", @@ -14228,6 +14086,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -15898,18 +15757,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/pacote/node_modules/@npmcli/fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", - "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/pacote/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -16099,51 +15946,6 @@ "node": ">=10" } }, - "node_modules/pacote/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/pacote/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/pacote/node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/pacote/node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/pacote/node_modules/validate-npm-package-name": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", @@ -16256,15 +16058,15 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -16691,7 +16493,8 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true }, "node_modules/promise-retry": { "version": "2.0.1", @@ -17101,9 +16904,9 @@ "integrity": "sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA==" }, "node_modules/react-native-root-toast": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/react-native-root-toast/-/react-native-root-toast-3.5.1.tgz", - "integrity": "sha512-zqsuec7Ugx2/9hR9BHqcmb3WWC/WBouqn2RYIpeTG+OpVvVfvr2UhWK4kLPJLk5/icZWl3xJrqiktPpbRpEA2A==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/react-native-root-toast/-/react-native-root-toast-3.6.0.tgz", + "integrity": "sha512-HgZ2OS84ZbInJGuejGghBCPmBwoSBuJFO/bAJoR/NS6rCl9eiXSRegIG/gLEo7lH9BijeA63is1noUqR8Y1DpQ==", "dependencies": { "deprecated-react-native-prop-types": "^2.3.0", "prop-types": "^15.5.10", @@ -18318,14 +18121,22 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dependencies": { - "minipass": "^3.1.1" + "minipass": "^7.0.3" }, "engines": { - "node": ">= 8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/stack-utils": { @@ -18421,7 +18232,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -18435,7 +18245,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -18444,7 +18253,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -18550,7 +18358,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -19229,19 +19036,25 @@ } }, "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dependencies": { - "unique-slug": "^2.0.0" + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dependencies": { "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/unique-string": { @@ -19738,7 +19551,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -19755,7 +19567,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -19770,7 +19581,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -19781,14 +19591,12 @@ "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/mobile/package.json b/mobile/package.json index f08159490..e99fbbfd2 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@react-native-async-storage/async-storage": "1.23.1", - "@react-native-community/datetimepicker": "7.7.0", + "@react-native-community/datetimepicker": "8.0.1", "@react-navigation/drawer": "^6.6.15", "@react-navigation/native": "^6.1.17", "@react-navigation/native-stack": "^6.9.26", @@ -29,21 +29,21 @@ "@types/mime": "^3.0.4", "@types/react-native-dotenv": "^0.2.2", "@types/react-native-vector-icons": "^6.4.18", - "@types/validator": "^13.11.9", + "@types/validator": "^13.11.10", "axios": "^1.6.8", - "axios-retry": "^4.1.0", + "axios-retry": "^4.2.0", "babel-plugin-module-resolver": "^5.0.2", "date-fns": "^3.6.0", - "expo": "~51.0.2", + "expo": "~51.0.8", "expo-asset": "~10.0.6", "expo-constants": "~16.0.1", "expo-device": "~6.0.2", - "expo-image-picker": "~15.0.4", + "expo-image-picker": "~15.0.5", "expo-localization": "~15.0.3", - "expo-notifications": "~0.28.1", + "expo-notifications": "~0.28.3", "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", - "expo-updates": "~0.25.11", + "expo-updates": "~0.25.14", "i18n-js": "^4.4.3", "lodash.debounce": "^4.0.8", "mime": "^4.0.3", @@ -54,7 +54,7 @@ "react-native-gesture-handler": "~2.16.2", "react-native-paper": "^5.12.3", "react-native-reanimated": "~3.10.1", - "react-native-root-toast": "^3.5.1", + "react-native-root-toast": "^3.6.0", "react-native-safe-area-context": "4.10.1", "react-native-screens": "~3.31.1", "react-native-size-matters": "^0.4.2", @@ -65,8 +65,8 @@ "devDependencies": { "@babel/core": "^7.24.5", "@types/react": "~18.2.79", - "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-airbnb-base": "^15.0.0", diff --git a/mobile/screens/CarsScreen.tsx b/mobile/screens/CarsScreen.tsx index 10b2323ec..c24a9c1d6 100644 --- a/mobile/screens/CarsScreen.tsx +++ b/mobile/screens/CarsScreen.tsx @@ -3,13 +3,14 @@ import { StyleSheet, View } from 'react-native' import { useIsFocused } from '@react-navigation/native' import { NativeStackScreenProps } from '@react-navigation/native-stack' import * as bookcarsTypes from ':bookcars-types' +import * as bookcarsHelper from ':bookcars-helper' import Layout from '../components/Layout' import i18n from '../lang/i18n' import * as UserService from '../services/UserService' import CarList from '../components/CarList' import SupplierFilter from '../components/SupplierFilter' -import FuelFilter from '../components/FuelFilter' +import CarTypeFilter from '../components/CarTypeFilter' import GearboxFilter from '../components/GearboxFilter' import MileageFilter from '../components/MileageFilter' import DepositFilter from '../components/DepositFilter' @@ -20,7 +21,7 @@ const CarsScreen = ({ navigation, route }: NativeStackScreenProps([]) - const [fuel, setFuel] = useState([bookcarsTypes.CarType.Diesel, bookcarsTypes.CarType.Gasoline]) + const [carType, setCarType] = useState(bookcarsHelper.getAllCarTypes()) const [gearbox, setGearbox] = useState([bookcarsTypes.GearboxType.Automatic, bookcarsTypes.GearboxType.Manual]) const [mileage, setMileage] = useState([bookcarsTypes.Mileage.Limited, bookcarsTypes.Mileage.Unlimited]) const [deposit, setDeposit] = useState(-1) @@ -53,8 +54,8 @@ const CarsScreen = ({ navigation, route }: NativeStackScreenProps { - setFuel(_fuel) + const onChangeFuel = (_carType: bookcarsTypes.CarType[]) => { + setCarType(_carType) } const onChangeGearbox = (_gearbox: bookcarsTypes.GearboxType[]) => { @@ -75,7 +76,7 @@ const CarsScreen = ({ navigation, route }: NativeStackScreenProps - + diff --git a/packages/bookcars-helper/index.ts b/packages/bookcars-helper/index.ts index 375514aa6..40891875c 100644 --- a/packages/bookcars-helper/index.ts +++ b/packages/bookcars-helper/index.ts @@ -241,3 +241,16 @@ export const formatPrice = (price: number, currency: string, language: string) = * @returns {boolean} */ export const isFrench = (language?: string) => language === 'fr' + +/** + * Return all car types. + * + * @returns {bookcarsTypes.CarType[]} + */ +export const getAllCarTypes = () => [ + bookcarsTypes.CarType.Diesel, + bookcarsTypes.CarType.Gasoline, + bookcarsTypes.CarType.Electric, + bookcarsTypes.CarType.Hybrid, + bookcarsTypes.CarType.PlugInHybrid +] diff --git a/packages/bookcars-helper/package.json b/packages/bookcars-helper/package.json index e96e29a72..30a933694 100644 --- a/packages/bookcars-helper/package.json +++ b/packages/bookcars-helper/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "type": "module", "scripts": { "build": "rimraf ./index.js ./index.d.ts && tsc" }, diff --git a/packages/bookcars-types/index.ts b/packages/bookcars-types/index.ts index 5195b3fb3..9c7975582 100644 --- a/packages/bookcars-types/index.ts +++ b/packages/bookcars-types/index.ts @@ -11,7 +11,10 @@ export enum AppType { export enum CarType { Diesel = 'diesel', - Gasoline = 'gasoline' + Gasoline = 'gasoline', + Electric = 'Electric', + Hybrid = 'Hybrid', + PlugInHybrid = 'PlugInHybrid' } export enum GearboxType { @@ -159,7 +162,7 @@ export interface UpdateCarPayload extends CreateCarPayload { export interface GetCarsPayload { suppliers: string[] - fuel?: string[] + carType?: string[] gearbox?: string[] mileage?: string[] deposit?: number