From c8773536689229b839a1afa913d5d041a401c911 Mon Sep 17 00:00:00 2001 From: TristanBrault Date: Sun, 19 Feb 2023 18:05:01 -0500 Subject: [PATCH] moved to cupertino --- api/.dockerignore | 2 +- api/assets/foodapp.drawio | 1 + api/package-lock.json | 82 ++++++++----- api/package.json | 32 ++--- api/src/modules/app.module.ts | 16 ++- .../database/accounts/models/home.model.ts | 7 +- .../models/grocery-products.model.ts | 9 +- .../models/ingredient-categories.model.ts | 13 +- .../ingredients/models/ingredients.model.ts | 29 +++-- .../services/ingredients.service.ts | 6 +- .../pantry/controllers/pantry.controller.ts | 10 +- .../pantry/models/pantry-items.model.ts | 40 +++--- .../pantry/services/pantry.service.ts | 17 ++- .../modules/translations/languages.enum.ts | 4 +- .../translations/models/translation.model.ts | 5 - api/tsconfig.build.json | 7 +- api/tsconfig.json | 5 +- api/tsconfig.migrations.json | 2 +- app/analysis_options.yaml | 4 + app/android/app/build.gradle | 4 +- app/lib/api/base_api.dart | 5 +- .../common/models/database-entity.model.dart | 55 ++++----- .../apis/grocery-product.api.dart | 10 +- .../models/grocery-products.model.dart | 98 +++++---------- .../api/pantry/models/pantry_item.model.dart | 62 ++++------ app/lib/api/pantry/pantry.api.dart | 9 +- app/lib/app.widget.dart | 46 +++++-- app/lib/environment.dart | 6 +- app/lib/interceptors/lang.interceptor.dart | 15 +++ app/lib/main.delegate.dart | 31 +++-- app/lib/main_dev.dart | 4 +- .../pages/add_pantry_item/add_item.page.dart | 87 +++++++------ app/lib/pages/app/app.page.dart | 1 - .../ingredient_not_found.page.dart | 28 +++-- app/lib/pages/pantry/cubit/pantry.cubit.dart | 21 ++++ app/lib/pages/pantry/cubit/pantry.state.dart | 42 +++++++ app/lib/pages/pantry/pantry.page.dart | 114 +++++++++++------- .../pantry_item_card.widget.dart | 77 ++++++++++-- app/lib/repositories/pantry.repository.dart | 11 +- app/lib/routing/main.router.dart | 23 ++-- .../widgets/base_list/base_list.widget.dart | 8 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 +- app/pubspec.lock | 112 ++++++----------- app/pubspec.yaml | 6 +- 44 files changed, 660 insertions(+), 508 deletions(-) create mode 100644 api/assets/foodapp.drawio delete mode 100644 api/src/modules/translations/models/translation.model.ts create mode 100644 app/lib/interceptors/lang.interceptor.dart create mode 100644 app/lib/pages/pantry/cubit/pantry.cubit.dart create mode 100644 app/lib/pages/pantry/cubit/pantry.state.dart diff --git a/api/.dockerignore b/api/.dockerignore index 36f06c9..74a312d 100644 --- a/api/.dockerignore +++ b/api/.dockerignore @@ -145,7 +145,7 @@ bower_components build/Release # Dependency directories -test-backend/api/node_modules/ +foodapp/api/node_modules/ jspm_packages/ # TypeScript v1 declaration files diff --git a/api/assets/foodapp.drawio b/api/assets/foodapp.drawio new file mode 100644 index 0000000..acf7958 --- /dev/null +++ b/api/assets/foodapp.drawio @@ -0,0 +1 @@ +7VzZcuI4FP0aHkl5NzySbZYkVZlO1fT0EyVsAZoYi8hygP76ucL70uAEgsyY6qqOfSRZV/fI9x7JNj39ZrH+jaHl/Im62Otpirvu6bc9TdMUTYU/AtlEiK0bETBjxI0gNQNeyE8cg0qMhsTFQaEip9TjZFkEHer72OEFDDFGV8VqU+oVe12iGa4ALw7yquh34vJ5hA40O8N/x2Q2T3pWrWFUskBJ5XgkwRy5dJWD9LuefsMo5dHRYn2DPeG8xC9Ru/tflKaGMezzJg3+XvVHf177d1aA1NG3b+OnKR30VT26zDvywnjEPc16C4VR14+I8OwsHgXfJK7heC3wOV94AKhwGHBGX/EN9SgDxKc+1LyeEs8rQcgjMx9OHTAdA379jhkn4PRRXLAgriu6uV7NCccvS+SIPlcwxQBjNPRdLEalpGaJC+D1Lz2jpv6GiYrpAnO2gSpJg4SieI6mlK0yxq0YmufI1mMMxXNsll45owEOYiY+woqxgxXtUdxOGP7ztvwoUGbCn7/C3o3eGw0n1O8Cabq5n7TBSUkzDyVN2R6DfYpxNYQwYoi4Nsc/4c8TWpMusGoOW8Zq0n8tq8+MuuGWTsEqAf91gKK+rpQ4UiSHy2QMtRxdMxy+iyTfSWpMydTotZnME+52yXuBhoSeCV33A/KT+LOePppQ5mLWB0z4MBrESBWjNEVV5LzOtl4EtKfp2BD/oGCJXDe6gLZcb32bkW/NxF8oZdgl4NixgzieUUZAZsamwVC31kVVE5SjiYdrTa4YNqU+F4PAAsSLkgWKA55LTcxdR6vUCmDGlGsp1dGkJk4oCO0yyCqImyDPD7kxZ3C1InF3VhRgtZsdHd8/qA17nlIGM9V/wJvjWtCwex8t8Mc7FmAdFwKPplGCl2JROYBwuszFGQ9PRSsKtabedjEhglIxdh0ljtilODKsxhG1Lg8PvyyQ1KqrVgWSS/hoY/jIBfp3xAjihPrjY5vziVgySS/n4sBhZCkMqxaSRaRdOhV/Bp+MPqr6VeHHUCuewu4Mv8SnlPE5nVEfeXcZWtJ3WZ1HKpy6dda/mPNNvOuFQk6LrsRrwv+Jm4vjH+L4yozPbte5ottNcuLDeEUj9UpRBgkQtVRtKwGyxtuzQutnzAi4TQjanDIV493NJ7iHhszBu8K4FVXkiM0w3xvvqzOEYQ9u4feiJcfPNlZLsw00czDbjJdi5elcUo6clJOF5/sHrak5WR7KLMslgXDpEbESGdPpueSm4DUcO9StaYYg/EPegmlKnB3FHplimC/70l4Gw92NXMRR1xKirn42Iw6+LCMOzzEjqkYxIyp2CsjKiHbTjGhJzYj2eWTEMeF4cUmLUtLinp4jpgjOqJKzCovsGNcnvLhwhScBzKRqeSGjdSX9mOVnbY3Tj/Zl+0GDlsYj5DjQ7qLMd9yAoU/eQvxHV3eUpwR7bje3la1iHLFV2dvKSWCTo2KT4x952bpbwypXqqr2cho2PZGlX4dnoV9NQwbRMvxsHrpztm06YgxtchWWlGyTWnrlZwFk93ZpgWoOzDxl+6obtlliOOo/4zsdyAGSYdhSybBE4h69rFzOa0Nvx3Imu9wcZq2sdc4b31QNIsFYZPiOKY/S42zTaLp+Mb5MeMh9oHSlJXtmH9IeFsTQFmmPhJ22aw9NLtd2c66lkGNLJUc/c2HY2M9yhKFRknq2WfpMoVS/Pzis/kmkZOLz1knJZDfcI8FlK7xtgjIP6sdUmdVKwHzr9Gj9hnutSvUpL7yN2wmRWo6UZs3L26d+yGtJUS6J4Owr1Se2qpICslSn0VTYSH2HybClqs685PzIK2tWie7zYduQynb7P7QIxpePLtotUA57ha2OXVlao2pd19REXy0/tB9U5UT66d5p3qI22/oRh5DFl0AkJRDt6ZmufMzG8UsVsqIJkMVwkE6Q3Drl8hQf1i0132if+Cn+QKrULW6wJkV7N9OjVqnU7e3WuUeUtGbjjzAGMiVtMs1awerJts0bk3Pwdu5ht1xbv5DZpvLx5S28c1tcVFP8iXYtGy4Rco6D6eUuiP9xc/5nid+0ZSd+q/aXP1oQhaId+Uv4aeOSokU/KJHFntIHB12JKaZeWkt8XUSB0+zH9qIHwdlPFup3/wE= \ No newline at end of file diff --git a/api/package-lock.json b/api/package-lock.json index 5ece812..be12f79 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -1303,6 +1303,19 @@ "xlsx": "^0.17.2" } }, + "@recursyve/nestjs-rosetta-core": { + "version": "9.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@recursyve/nestjs-rosetta-core/-/nestjs-rosetta-core-9.0.0-beta.19.tgz", + "integrity": "sha512-vHLzZg25aZAFXiskUaiI4KRZYLKjTL58tdP27VuvdKePg4/aL1DWfoTR4KV211szsQGgIDmaKBfL6MNevBXS7g==", + "requires": { + "accept-language-parser": "^1.5.0" + } + }, + "@recursyve/nestjs-rosetta-sequelize": { + "version": "9.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@recursyve/nestjs-rosetta-sequelize/-/nestjs-rosetta-sequelize-9.0.0-beta.19.tgz", + "integrity": "sha512-G5w+sPhDRC3A5YALR6RdAaqPhKTDBKJmhu6ITrfEhoJAHD6zpt8rODtcYAxUl5NeGHLoz3SzG42JrYf+DhOeZA==" + }, "@recursyve/nestjs-sequelize-utils": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/@recursyve/nestjs-sequelize-utils/-/nestjs-sequelize-utils-8.0.4.tgz", @@ -1968,6 +1981,11 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "accept-language-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==" + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2116,7 +2134,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-union": { "version": "2.1.0", @@ -2489,12 +2507,20 @@ "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" }, "class-validator": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz", - "integrity": "sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.0.tgz", + "integrity": "sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==", "requires": { - "libphonenumber-js": "^1.9.43", + "@types/validator": "^13.7.10", + "libphonenumber-js": "^1.10.14", "validator": "^13.7.0" + }, + "dependencies": { + "@types/validator": { + "version": "13.7.12", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.12.tgz", + "integrity": "sha512-YVtyAPqpefU+Mm/qqnOANW6IkqKpCSrarcyV269C8MA8Ux0dbkEuQwM/4CjL47kVEM2LgBef/ETfkH+c6+moFA==" + } } }, "cli-cursor": { @@ -2627,7 +2653,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", @@ -2682,7 +2708,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "cookiejar": { "version": "2.1.3", @@ -2881,7 +2907,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { "version": "1.4.4", @@ -2926,7 +2952,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", @@ -3148,7 +3174,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "events": { "version": "3.3.0", @@ -3471,7 +3497,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fs-extra": { "version": "10.1.0", @@ -3493,7 +3519,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -3730,7 +3756,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3856,7 +3882,7 @@ "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" }, "is-stream": { "version": "2.0.1", @@ -4610,9 +4636,9 @@ } }, "libphonenumber-js": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.7.tgz", - "integrity": "sha512-jZXLCCWMe1b/HXkjiLeYt2JsytZMcqH26jLFIdzFDFF0xvSUWrYKyvPlyPG+XJzEyKUFbcZxLdWGMwQsWaHDxQ==" + "version": "1.10.20", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.20.tgz", + "integrity": "sha512-kQovlKNdLcVzerbTPmJ+Fx4R+7/pYXmPDIllHjg7IxL4X6MsMG7jaT5opfYrBok0uqkByVif//JUR8e11l/V7w==" }, "lines-and-columns": { "version": "1.2.4", @@ -4725,7 +4751,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "memfs": { "version": "3.4.7", @@ -4739,7 +4765,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "merge-stream": { "version": "2.0.0", @@ -4756,7 +4782,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { "version": "4.0.5", @@ -4915,7 +4941,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, @@ -5032,7 +5058,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -5152,7 +5178,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -5288,7 +5314,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "pump": { "version": "3.0.0", @@ -5565,7 +5591,7 @@ "seq-queue": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" }, "sequelize": { "version": "6.21.2", @@ -6234,7 +6260,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "update-browserslist-db": { "version": "1.0.4", @@ -6263,7 +6289,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "8.3.2", @@ -6431,7 +6457,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "4.0.1", diff --git a/api/package.json b/api/package.json index f16148b..efb0cac 100644 --- a/api/package.json +++ b/api/package.json @@ -5,21 +5,21 @@ "author": "", "license": "MIT", "scripts": { - "prebuild": "test-backend/api/node_modules/.bin/rimraf dist", - "build": "test-backend/api/node_modules/.bin/nest build", - "build:data-migrations": "test-backend/api/node_modules/.bin/rimraf data-migrations-dist && tsc --build tsconfig.migrations.json", - "format": "test-backend/api/node_modules/.bin/prettier --write \\\"src/**/*.ts\\\" \\\"test/**/*.ts\\\"", - "start": "test-backend/api/node_modules/.bin/nest start", - "start:dev": "test-backend/api/node_modules/.bin/nest start --watch", - "start:debug": "test-backend/api/node_modules/.bin/nest start --debug --watch", + "prebuild": "rimraf dist", + "build": "nest build", + "build:data-migrations": "rimraf data-migrations-dist && tsc --build tsconfig.migrations.json", + "format": "prettier --write \\\"src/**/*.ts\\\" \\\"test/**/*.ts\\\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", - "lint": "test-backend/api/node_modules/.bin/eslint . --fix --ext .ts", - "test": "test-backend/api/node_modules/.bin/jest", - "test:watch": "test-backend/api/node_modules/.bin/jest --watch", - "test:cov": "test-backend/api/node_modules/.bin/jest --coverage", - "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register test-backend/api/node_modules/.bin/jest --runInBand", - "test:e2e": "test-backend/api/node_modules/.bin/jest --config ./test/jest-e2e.json", - "install": "(ls test-backend/pre-commit-setup.sh >> /dev/null 2>&1 && echo 'pre-commit setup' && chmod +x ../pre-commit-setup.sh && bash -c ../pre-commit-setup.sh) || echo 'pre-commit setup skipped'", + "lint": "eslint . --fix --ext .ts", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json", + "install": "(ls foodapp/pre-commit-setup.sh >> /dev/null 2>&1 && echo 'pre-commit setup' && chmod +x ../pre-commit-setup.sh && bash -c ../pre-commit-setup.sh) || echo 'pre-commit setup skipped'", "data-migrations": "node data-migrations-dist/data-migrations/index.js" }, "dependencies": { @@ -34,8 +34,10 @@ "@recursyve/nestjs-config": "^8.0.1", "@recursyve/nestjs-data-filter": "^8.4.4", "@recursyve/nestjs-sequelize-utils": "^8.0.4", + "@recursyve/nestjs-rosetta-core": "^9.0.0-beta.19", + "@recursyve/nestjs-rosetta-sequelize": "^9.0.0-beta.19", "class-transformer": "^0.5.1", - "class-validator": "^0.13.2", + "class-validator": "^0.14.0", "compression": "^1.7.4", "dotenv": "^16.0.1", "helmet": "^5.1.0", diff --git a/api/src/modules/app.module.ts b/api/src/modules/app.module.ts index fcea8a5..1237a35 100644 --- a/api/src/modules/app.module.ts +++ b/api/src/modules/app.module.ts @@ -3,8 +3,22 @@ import { GlobalConfigModule } from "./config/config.module"; import { RootModule } from "./root/root.module"; import { DatabaseModule } from "./database/database.module"; import { HealthModule } from "./health/health.module"; +import { NestjsRosettaModule } from "@recursyve/nestjs-rosetta-core"; +import { NestjsRosettaSequelizeModule, SequelizeTranslationObjectProcessor } from "@recursyve/nestjs-rosetta-sequelize"; +import { languagesValues, Languages } from "./translations/languages.enum"; @Module({ - imports: [GlobalConfigModule, RootModule, DatabaseModule, HealthModule] + imports: [ + GlobalConfigModule, + RootModule, + DatabaseModule, + HealthModule, + NestjsRosettaModule.forRoot({ + processors: [new SequelizeTranslationObjectProcessor()], + supportedLanguages: languagesValues, + fallbackLanguage: Languages.EN + }), + NestjsRosettaSequelizeModule + ] }) export class ApplicationModule {} diff --git a/api/src/modules/database/accounts/models/home.model.ts b/api/src/modules/database/accounts/models/home.model.ts index a38f807..8d72e7f 100644 --- a/api/src/modules/database/accounts/models/home.model.ts +++ b/api/src/modules/database/accounts/models/home.model.ts @@ -1,8 +1,9 @@ import { DatabaseEntities } from "../../common/models/database-entities.model"; import { AllowNull, BelongsTo, Column, ForeignKey, Table } from "sequelize-typescript"; import { Accounts } from "./accounts.model"; -import { Translation } from "../../../translations/models/translation.model"; import { DataTypes } from "sequelize"; +import { TranslationObject } from "@recursyve/nestjs-rosetta-core"; +import { TranslationColumn } from "@recursyve/nestjs-rosetta-sequelize"; @Table export class Homes extends DatabaseEntities { @@ -12,7 +13,9 @@ export class Homes extends DatabaseEntities { @AllowNull(false) @Column(DataTypes.JSON) - public name: Translation; + @TranslationColumn() + // TODO should be a string + public name: TranslationObject; @BelongsTo(() => Accounts) public ownerAccount: Accounts; diff --git a/api/src/modules/database/grocery_products/models/grocery-products.model.ts b/api/src/modules/database/grocery_products/models/grocery-products.model.ts index 7add403..9b040ee 100644 --- a/api/src/modules/database/grocery_products/models/grocery-products.model.ts +++ b/api/src/modules/database/grocery_products/models/grocery-products.model.ts @@ -1,8 +1,9 @@ import { DatabaseEntities } from "../../common/models/database-entities.model"; import { AllowNull, BelongsTo, Column, ForeignKey, Table } from "sequelize-typescript"; import { Ingredients } from "../../ingredients/models/ingredients.model"; -import { Translation } from "../../../translations/models/translation.model"; import { DataTypes } from "sequelize"; +import { TranslationColumn } from "@recursyve/nestjs-rosetta-sequelize"; +import { TranslationObject } from "@recursyve/nestjs-rosetta-core"; @Table export class GroceryProducts extends DatabaseEntities { @@ -16,10 +17,12 @@ export class GroceryProducts extends DatabaseEntities { @AllowNull(false) @Column(DataTypes.JSON) - public name: Translation; + @TranslationColumn() + public name: TranslationObject; @Column(DataTypes.JSON) - public description: Translation; + @TranslationColumn() + public description: TranslationObject; @Column public skuCode: string; diff --git a/api/src/modules/database/ingredients/models/ingredient-categories.model.ts b/api/src/modules/database/ingredients/models/ingredient-categories.model.ts index 7e54ef2..c83978f 100644 --- a/api/src/modules/database/ingredients/models/ingredient-categories.model.ts +++ b/api/src/modules/database/ingredients/models/ingredient-categories.model.ts @@ -1,13 +1,16 @@ import { DatabaseEntities } from "../../common/models/database-entities.model"; import { Column, Table } from "sequelize-typescript"; -import { Translation } from "../../../translations/models/translation.model"; import { DataTypes } from "sequelize"; +import { TranslationObject } from "@recursyve/nestjs-rosetta-core"; +import { TranslationColumn } from "@recursyve/nestjs-rosetta-sequelize"; @Table export class IngredientCategories extends DatabaseEntities { - @Column(DataTypes.JSON) - public name: Translation; + @Column(DataTypes.JSON) + @TranslationColumn() + public name: TranslationObject; - @Column(DataTypes.JSON) - public description: Translation; + @Column(DataTypes.JSON) + @TranslationColumn() + public description: TranslationObject; } diff --git a/api/src/modules/database/ingredients/models/ingredients.model.ts b/api/src/modules/database/ingredients/models/ingredients.model.ts index d849dd6..1253109 100644 --- a/api/src/modules/database/ingredients/models/ingredients.model.ts +++ b/api/src/modules/database/ingredients/models/ingredients.model.ts @@ -1,24 +1,27 @@ import { DatabaseEntities } from "../../common/models/database-entities.model"; import { AllowNull, BelongsTo, Column, ForeignKey, Table } from "sequelize-typescript"; -import { Translation } from "../../../translations/models/translation.model"; import { DataTypes } from "sequelize"; +import { TranslationObject } from "@recursyve/nestjs-rosetta-core"; +import { TranslationColumn } from "@recursyve/nestjs-rosetta-sequelize"; @Table export class Ingredients extends DatabaseEntities { - @Column - @ForeignKey(() => Ingredients) - public variationOfIngredientId: number; + @Column + @ForeignKey(() => Ingredients) + public variationOfIngredientId: number; - @AllowNull(false) - @Column(DataTypes.JSON) - public name: Translation; + @AllowNull(false) + @Column(DataTypes.JSON) + @TranslationColumn() + public name: TranslationObject; - @Column(DataTypes.JSON) - public description: Translation; + @Column(DataTypes.JSON) + @TranslationColumn() + public description: TranslationObject; - @Column - public imagePath: string; + @Column + public imagePath: string; - @BelongsTo(() => Ingredients) - public variationOfIngredient: Ingredients; + @BelongsTo(() => Ingredients) + public variationOfIngredient: Ingredients; } diff --git a/api/src/modules/database/ingredients/services/ingredients.service.ts b/api/src/modules/database/ingredients/services/ingredients.service.ts index 51ce1b5..3c412f7 100644 --- a/api/src/modules/database/ingredients/services/ingredients.service.ts +++ b/api/src/modules/database/ingredients/services/ingredients.service.ts @@ -2,7 +2,7 @@ import { DatabaseRepository } from "../../common/repositories/database.repositor import { Ingredients } from "../models/ingredients.model"; export class IngredientsService extends DatabaseRepository { - constructor() { - super(Ingredients); - } + constructor() { + super(Ingredients); + } } diff --git a/api/src/modules/database/pantry/controllers/pantry.controller.ts b/api/src/modules/database/pantry/controllers/pantry.controller.ts index 36a1631..76bd7f7 100644 --- a/api/src/modules/database/pantry/controllers/pantry.controller.ts +++ b/api/src/modules/database/pantry/controllers/pantry.controller.ts @@ -4,10 +4,10 @@ import { PantryItems } from "../models/pantry-items.model"; @Controller("pantry") export class PantryController { - constructor(private service: PantryService) {} + constructor(private service: PantryService) {} - @Get() - public async getPantryItems(): Promise { - return this.service.getAllItems(); - } + @Get() + public async getPantryItems(): Promise { + return this.service.findAllItems(); + } } diff --git a/api/src/modules/database/pantry/models/pantry-items.model.ts b/api/src/modules/database/pantry/models/pantry-items.model.ts index 4520d19..471955a 100644 --- a/api/src/modules/database/pantry/models/pantry-items.model.ts +++ b/api/src/modules/database/pantry/models/pantry-items.model.ts @@ -5,30 +5,30 @@ import { GroceryProducts } from "../../grocery_products/models/grocery-products. @Table export class PantryItems extends DatabaseEntities { - @Column - @ForeignKey(() => GroceryProducts) - public groceryProductId: number; + @Column + @ForeignKey(() => GroceryProducts) + public groceryProductId: number; - @Column - @ForeignKey(() => Homes) - public homeId: number; + @Column + @ForeignKey(() => Homes) + public homeId: number; - @Column - public itemCount: number; + @Column + public itemCount: number; - @Default(false) - @Column - public isLow: boolean; + @Default(false) + @Column + public isLow: boolean; - // @Column - // public oldestEntry: Date; - // - // @Column - // public newestEntry: Date; + // @Column + // public oldestEntry: Date; + // + // @Column + // public newestEntry: Date; - @BelongsTo(() => GroceryProducts) - public groceryProduct: GroceryProducts; + @BelongsTo(() => GroceryProducts) + public groceryProduct: GroceryProducts; - @BelongsTo(() => Homes) - public home: Homes; + @BelongsTo(() => Homes) + public home: Homes; } diff --git a/api/src/modules/database/pantry/services/pantry.service.ts b/api/src/modules/database/pantry/services/pantry.service.ts index b5fd692..ee6217d 100644 --- a/api/src/modules/database/pantry/services/pantry.service.ts +++ b/api/src/modules/database/pantry/services/pantry.service.ts @@ -4,11 +4,16 @@ import { Injectable } from "@nestjs/common"; @Injectable() export class PantryService extends DatabaseRepository { - constructor() { - super(PantryItems); - } + constructor() { + super(PantryItems); + } - public async getAllItems(): Promise { - return this.findAll(); - } + public async findAllItems(): Promise { + const pantryItems = await this.findAll({ + include: ["groceryProduct", "home"] + }); + + pantryItems.forEach((p) => console.log(p.toJSON())); + return pantryItems; + } } diff --git a/api/src/modules/translations/languages.enum.ts b/api/src/modules/translations/languages.enum.ts index 7b9cdb2..ad40883 100644 --- a/api/src/modules/translations/languages.enum.ts +++ b/api/src/modules/translations/languages.enum.ts @@ -1,4 +1,6 @@ export enum Languages { FR = "fr", EN = "en" -} \ No newline at end of file +} + +export const languagesValues = Object.values(Languages); diff --git a/api/src/modules/translations/models/translation.model.ts b/api/src/modules/translations/models/translation.model.ts deleted file mode 100644 index f7c8a00..0000000 --- a/api/src/modules/translations/models/translation.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Languages } from "../languages.enum"; - -export type Translation = { - [key in Languages]?: string; -} \ No newline at end of file diff --git a/api/tsconfig.build.json b/api/tsconfig.build.json index 9054e73..5e705a7 100644 --- a/api/tsconfig.build.json +++ b/api/tsconfig.build.json @@ -1,10 +1,11 @@ { "extends": "./tsconfig.json", "exclude": [ - "test-backend/api/node_modules", + "foodapp/api/node_modules", "test", - "dist", + "dist", + "ceto", "data-migrations", - "**/*spec.ts" + "**/*spec.ts" ] } diff --git a/api/tsconfig.json b/api/tsconfig.json index 4e111cb..3ec0b7d 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -7,12 +7,13 @@ "experimentalDecorators": true, "target": "es2017", "sourceMap": true, - "outDir": "./test-backend/api/dist", + "outDir": "./dist", "baseUrl": "./", "incremental": true }, "exclude": [ - "test-backend/api/node_modules", + "foodapp/api/node_modules", + "ceto", "dist" ] } diff --git a/api/tsconfig.migrations.json b/api/tsconfig.migrations.json index 5f103a6..0b07309 100644 --- a/api/tsconfig.migrations.json +++ b/api/tsconfig.migrations.json @@ -18,5 +18,5 @@ "src" ], "exclude": [ - "test-backend/api/node_modules", "dist"] + "foodapp/api/node_modules", "dist"] } diff --git a/app/analysis_options.yaml b/app/analysis_options.yaml index 61b6c4d..0c9e8a3 100644 --- a/app/analysis_options.yaml +++ b/app/analysis_options.yaml @@ -24,6 +24,10 @@ linter: rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + always_declare_return_types: true + always_use_package_imports: true + eol_at_end_of_file: true + require_trailing_commas: true # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/app/android/app/build.gradle b/app/android/app/build.gradle index 2e3901b..4bc2741 100644 --- a/app/android/app/build.gradle +++ b/app/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion 33 ndkVersion flutter.ndkVersion compileOptions { @@ -47,7 +47,7 @@ android { applicationId "com.example.foodapp" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/app/lib/api/base_api.dart b/app/lib/api/base_api.dart index fef2adb..7646708 100644 --- a/app/lib/api/base_api.dart +++ b/app/lib/api/base_api.dart @@ -2,13 +2,12 @@ import 'package:dio/dio.dart'; import 'package:foodapp/environment.dart'; class BaseApi { - late Dio http; - late String baseUrl; + final Dio http; + late final String baseUrl; BaseApi(this.http, String path) { String apiUrl = Environment.apiUrl; baseUrl = "$apiUrl/$path"; - http = Dio(); } String url([String? path]) { diff --git a/app/lib/api/common/models/database-entity.model.dart b/app/lib/api/common/models/database-entity.model.dart index d3437d1..82a57f4 100644 --- a/app/lib/api/common/models/database-entity.model.dart +++ b/app/lib/api/common/models/database-entity.model.dart @@ -1,39 +1,30 @@ -import 'dart:collection'; +import 'package:foodapp/api/common/types/json.type.dart'; +import 'package:foodapp/utils/json.utils.dart'; class DatabaseEntityModel { - int? id; - DateTime? createdAt; - DateTime? updatedAt; - DateTime? deletedAt; + final int id; + final DateTime? createdAt; + final DateTime? updatedAt; + final DateTime? deletedAt; - DatabaseEntityModel(this.id, this.createdAt, this.updatedAt, this.deletedAt); + DatabaseEntityModel({required this.id, this.createdAt, this.updatedAt, this.deletedAt}); - DatabaseEntityModel.fromJson(LinkedHashMap? json) { - if (json == null) return; + DatabaseEntityModel.fromJson(Json json) + : id = json["id"], + createdAt = JsonUtils.parseIfNotNull(json["createdAt"], DateTime.parse)?.toLocal(), + updatedAt = JsonUtils.parseIfNotNull(json["updatedAt"], DateTime.parse)?.toLocal(), + deletedAt = JsonUtils.parseIfNotNull(json["deletedAt"], DateTime.parse)?.toLocal(); - id = json["id"]; - if (json["createdAt"] != null) { - createdAt = DateTime.tryParse(json["createdAt"])?.toLocal(); - } - if (json["updatedAt"] != null) { - updatedAt = DateTime.tryParse(json["updatedAt"])?.toLocal(); - } - if (json["deletedAt"] != null) { - deletedAt = DateTime.tryParse(json["deletedAt"])?.toLocal(); - } - } - - DatabaseEntityModel.merge(DatabaseEntityModel target, DatabaseEntityModel source) { - id = source.id ?? target.id; - createdAt = source.createdAt ?? target.createdAt; - updatedAt = source.updatedAt ?? target.updatedAt; - deletedAt = source.deletedAt ?? target.deletedAt; - } + DatabaseEntityModel.merge(DatabaseEntityModel target, DatabaseEntityModel source) + : id = source.id, + createdAt = source.createdAt ?? target.createdAt, + updatedAt = source.updatedAt ?? target.updatedAt, + deletedAt = source.deletedAt ?? target.deletedAt; Map toJson() => { - if (id != null) "id": id, - if (createdAt != null) "createdAt": createdAt?.toIso8601String(), - if (updatedAt != null) "updatedAt": updatedAt?.toIso8601String(), - if (deletedAt != null) "deletedAt": deletedAt?.toIso8601String(), - }; -} \ No newline at end of file + "id": id, + if (createdAt != null) "createdAt": createdAt?.toIso8601String(), + if (updatedAt != null) "updatedAt": updatedAt?.toIso8601String(), + if (deletedAt != null) "deletedAt": deletedAt?.toIso8601String(), + }; +} diff --git a/app/lib/api/grocery-products/apis/grocery-product.api.dart b/app/lib/api/grocery-products/apis/grocery-product.api.dart index 9be99fe..ab821f9 100644 --- a/app/lib/api/grocery-products/apis/grocery-product.api.dart +++ b/app/lib/api/grocery-products/apis/grocery-product.api.dart @@ -1,21 +1,19 @@ -import 'dart:collection'; - import 'package:dio/dio.dart'; import 'package:foodapp/api/base_api.dart'; import 'package:foodapp/api/common/types/json.type.dart'; import 'package:foodapp/api/grocery-products/models/grocery-products.model.dart'; class GroceryProductApi extends BaseApi { - GroceryProductApi(Dio http): super(http, "grocery-product"); + GroceryProductApi(Dio http) : super(http, "grocery-product"); Future getGroceryProductBySku(String skuCode) async { try { - final Response response = await http.get(url(), queryParameters: { "sku": skuCode }); + final Response response = await http.get(url(), queryParameters: {"sku": skuCode}); return GroceryProductsModel.fromJson(Json.from(response.data)); - } catch(e) { + } catch (e) { if (e is DioError && e.response?.statusCode == 400) return null; print(e); return null; } } -} \ No newline at end of file +} diff --git a/app/lib/api/grocery-products/models/grocery-products.model.dart b/app/lib/api/grocery-products/models/grocery-products.model.dart index ac56746..1386ed0 100644 --- a/app/lib/api/grocery-products/models/grocery-products.model.dart +++ b/app/lib/api/grocery-products/models/grocery-products.model.dart @@ -1,21 +1,19 @@ -import 'dart:collection'; - -import 'package:equatable/equatable.dart'; import 'package:foodapp/api/common/models/database-entity.model.dart'; +import 'package:foodapp/api/common/types/json.type.dart'; -class GroceryProductsModel extends DatabaseEntityModel with EquatableMixin { - int? ingredientId; - int? duplicateOfGroceryProductId; - String? name; - String? description; - String? skuCode; - double? averagePrice; - int? averageLifeSpanDays; - String? imagePath; +class GroceryProductsModel extends DatabaseEntityModel { + final int? ingredientId; + final int? duplicateOfGroceryProductId; + final String? name; + final String? description; + final String? skuCode; + final double? averagePrice; + final int? averageLifeSpanDays; + final String? imagePath; dynamic productMetadata; GroceryProductsModel({ - int? id, + required super.id, this.ingredientId, this.duplicateOfGroceryProductId, this.name, @@ -25,44 +23,22 @@ class GroceryProductsModel extends DatabaseEntityModel with EquatableMixin { this.averageLifeSpanDays, this.imagePath, this.productMetadata, - DateTime? createdAt, - DateTime? updatedAt, - DateTime? deletedAt -}) : super(id, createdAt, updatedAt, deletedAt); - - GroceryProductsModel.fromJson(LinkedHashMap? json) : super.fromJson(json) { - if (json == null) return; - - name = json["name"]; - - if (json["ingredientId"] != null) { - ingredientId = json["ingredientId"]; - } - - if (json["duplicateOfGroceryProductId"] != null) { - duplicateOfGroceryProductId = json["duplicateOfGroceryProductId"]; - } - - if (json["description"] != null) { - description = json["description"]; - } + super.createdAt, + super.updatedAt, + super.deletedAt, + }); - if (json["skuCode"] != null) { - skuCode = json["skuCode"]; - } - - if (json["averagePrice"] != null) { - averagePrice = json["averagePrice"]; - } - - if (json["averageLifeSpanDays"] != null) { - averageLifeSpanDays = json["averageLifeSpanDays"]; - } - - if (json["productMetadata"] != null) { - productMetadata = json["productMetadata"]; - } - } + GroceryProductsModel.fromJson(Json json) + : name = json["name"], + ingredientId = json["ingredientId"], + duplicateOfGroceryProductId = json["duplicateOfGroceryProductId"], + description = json["description"], + skuCode = json["skuCode"], + averagePrice = json["averagePrice"], + averageLifeSpanDays = json["averageLifeSpanDays"], + productMetadata = json["productMetadata"], + imagePath = json["imagePath"], + super.fromJson(json); GroceryProductsModel copyWith({ int? ingredientId, @@ -74,7 +50,7 @@ class GroceryProductsModel extends DatabaseEntityModel with EquatableMixin { int? averageLifeSpanDays, String? imagePath, dynamic productMetadata, -}) { + }) { return GroceryProductsModel( id: id, ingredientId: ingredientId ?? this.ingredientId, @@ -91,22 +67,4 @@ class GroceryProductsModel extends DatabaseEntityModel with EquatableMixin { deletedAt: deletedAt, ); } - - @override - List get props => [ - id, - createdAt, - updatedAt, - deletedAt, - ingredientId, - duplicateOfGroceryProductId, - name, - description, - skuCode, - averagePrice, - averageLifeSpanDays, - imagePath, - productMetadata - ]; - -} \ No newline at end of file +} diff --git a/app/lib/api/pantry/models/pantry_item.model.dart b/app/lib/api/pantry/models/pantry_item.model.dart index 3b47f23..e43c008 100644 --- a/app/lib/api/pantry/models/pantry_item.model.dart +++ b/app/lib/api/pantry/models/pantry_item.model.dart @@ -1,41 +1,37 @@ -import 'package:equatable/equatable.dart'; import 'package:foodapp/api/common/models/database-entity.model.dart'; import 'package:foodapp/api/common/types/json.type.dart'; +import 'package:foodapp/api/grocery-products/models/grocery-products.model.dart'; +import 'package:foodapp/utils/json.utils.dart'; - -class PantryItemsModel extends DatabaseEntityModel with EquatableMixin { +class PantryItemsModel extends DatabaseEntityModel { int? groceryProductId; int? homeId; int? itemCount; bool? isLow; + GroceryProductsModel? groceryProduct; PantryItemsModel({ - int? id, + required super.id, this.groceryProductId, this.homeId, this.itemCount, this.isLow, - DateTime? createdAt, - DateTime? updatedAt, - DateTime? deletedAt - }) : super(id, createdAt, updatedAt, deletedAt); - - PantryItemsModel.fromJson(Json? json) : super.fromJson(json) { - if (json == null) return; - - groceryProductId = json["groceryProductId"]; - - if (json["homeId"] != null) { - homeId = json["homeId"]; - } - - if (json["itemCount"] != null) { - itemCount = json["itemCount"]; - } - - if (json["isLow"] != null) { - isLow = json["isLow"]; - } + this.groceryProduct, + super.createdAt, + super.updatedAt, + super.deletedAt, + }); + + PantryItemsModel.fromJson(Json json) + : groceryProductId = json["groceryProductId"], + homeId = json["homeId"], + itemCount = json["itemCount"], + isLow = json["isLow"], + groceryProduct = JsonUtils.parseIfNotNull(json["groceryProduct"], GroceryProductsModel.fromJson), + super.fromJson(json); + + static List fromJsonList(JsonArray json) { + return json.map((pantryItem) => PantryItemsModel.fromJson(pantryItem)).toList(); } PantryItemsModel copyWith({ @@ -43,6 +39,7 @@ class PantryItemsModel extends DatabaseEntityModel with EquatableMixin { int? homeId, int? itemCount, bool? isLow, + GroceryProductsModel? groceryProduct, }) { return PantryItemsModel( id: id, @@ -50,23 +47,10 @@ class PantryItemsModel extends DatabaseEntityModel with EquatableMixin { homeId: homeId ?? this.homeId, itemCount: itemCount ?? this.itemCount, isLow: isLow ?? this.isLow, + groceryProduct: groceryProduct ?? this.groceryProduct, createdAt: createdAt, updatedAt: updatedAt, deletedAt: deletedAt, ); } - - @override - List get props => [ - id, - createdAt, - updatedAt, - deletedAt, - groceryProductId, - homeId, - itemCount, - isLow - ]; - - } diff --git a/app/lib/api/pantry/pantry.api.dart b/app/lib/api/pantry/pantry.api.dart index 058285a..7ca5638 100644 --- a/app/lib/api/pantry/pantry.api.dart +++ b/app/lib/api/pantry/pantry.api.dart @@ -1,20 +1,15 @@ -import 'dart:ffi'; - import 'package:dio/dio.dart'; import 'package:foodapp/api/base_api.dart'; import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; -import 'package:foodapp/api/common/types/json.type.dart'; - class PantryApi extends BaseApi { PantryApi(Dio http) : super(http, "pantry"); Future> getPantryItems() async { try { final Response response = await http.get(url()); - final thing = response.data as List; - return List.from(thing.map((e) => PantryItemsModel.fromJson(Json.from(e)))); - } catch(e) { + return PantryItemsModel.fromJsonList(response.data); + } catch (e) { if (e is DioError && e.response?.statusCode == 400) return []; print(e); return []; diff --git a/app/lib/app.widget.dart b/app/lib/app.widget.dart index f10d1d7..f5298ab 100644 --- a/app/lib/app.widget.dart +++ b/app/lib/app.widget.dart @@ -1,8 +1,9 @@ import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:foodapp/pages/app/home/home.page.dart'; +import 'package:foodapp/pages/pantry/pantry.page.dart'; import 'package:foodapp/routing/main.router.dart'; -import 'package:foodapp/theme/app.theme.dart'; -import 'package:nice_flutter_kit/nice_flutter_kit.dart'; class FoodApp extends StatelessWidget { final _router = MainRouter(); @@ -13,17 +14,38 @@ class FoodApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: Setup NiceAuth - - return MaterialApp.router( - routerDelegate: _router.delegate(), - routeInformationParser: _router.defaultRouteParser(), - routeInformationProvider: _router.routeInfoProvider(), + return CupertinoApp( debugShowCheckedModeBanner: false, - title: "Base", - // supportedLocales: NiceLocalizations.supportedLocales, - // localizationsDelegates: NiceLocalizations.delegates, - // localeResolutionCallback: NiceLocalizations.localResolutionCallback, - theme: AppTheme.generateTheme(), + theme: CupertinoTheme.of(context).copyWith(primaryColor: Colors.lightGreen), + home: CupertinoTabScaffold( + tabBar: CupertinoTabBar( + items: const [ + BottomNavigationBarItem(icon: Icon(CupertinoIcons.house_fill), label: "Pantry"), + BottomNavigationBarItem(icon: Icon(CupertinoIcons.square_list_fill), label: "Groceries"), + ], + ), + tabBuilder: (BuildContext context, int index) { + return CupertinoTabView( + builder: (context) { + if (index == 0) { + return const PantryPage(); + } + return HomePage(); + }, + ); + }, + ), ); + + // return CupertinoApp.router( + // routerDelegate: _router.delegate(), + // routeInformationParser: _router.defaultRouteParser(), + // routeInformationProvider: _router.routeInfoProvider(), + // debugShowCheckedModeBanner: false, + // title: "Base", + // // supportedLocales: NiceLocalizations.supportedLocales, + // // localizationsDelegates: NiceLocalizations.delegates, + // // localeResolutionCallback: NiceLocalizations.localResolutionCallback, + // ); } } diff --git a/app/lib/environment.dart b/app/lib/environment.dart index e6b383a..0e875a1 100644 --- a/app/lib/environment.dart +++ b/app/lib/environment.dart @@ -5,13 +5,13 @@ class Environment { Environment._config = environmentConfig; } - static get apiUrl => _config.apiUrl; + static String get apiUrl => _config.apiUrl; } class EnvironmentConfig { final String apiUrl; const EnvironmentConfig({ - required this.apiUrl + required this.apiUrl, }); -} \ No newline at end of file +} diff --git a/app/lib/interceptors/lang.interceptor.dart b/app/lib/interceptors/lang.interceptor.dart new file mode 100644 index 0000000..a903501 --- /dev/null +++ b/app/lib/interceptors/lang.interceptor.dart @@ -0,0 +1,15 @@ +import "package:dio/dio.dart"; + +class LangInterceptor extends InterceptorsWrapper { + @override + Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async { + return handler.next( + options.copyWith( + headers: { + ...options.headers, + "Accept-Language": "fr", + }, + ), + ); + } +} diff --git a/app/lib/main.delegate.dart b/app/lib/main.delegate.dart index 3d94d7d..96ba6c8 100644 --- a/app/lib/main.delegate.dart +++ b/app/lib/main.delegate.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -5,14 +7,19 @@ import 'package:foodapp/api/grocery-products/apis/grocery-product.api.dart'; import 'package:foodapp/api/ingredients/ingredients.api.dart'; import 'package:foodapp/api/pantry/pantry.api.dart'; import 'package:foodapp/app.widget.dart'; +import 'package:foodapp/interceptors/lang.interceptor.dart'; import 'package:foodapp/repositories/grocery-products.repository.dart'; import 'package:foodapp/repositories/ingredients.repository.dart'; import 'package:foodapp/repositories/pantry.repository.dart'; -import 'package:hydrated_bloc/hydrated_bloc.dart'; - void mainDelegate() async { + WidgetsFlutterBinding.ensureInitialized(); + await _run(); +} + +Future _run() async { final dio = Dio(); + dio.interceptors.add(LangInterceptor()); // Setup APIs final ingredientsApi = IngredientApi(dio); @@ -25,15 +32,21 @@ void mainDelegate() async { final groceryProductRepository = GroceryProductsRepository(groceryProductApi); // Add interceptors - // Config onboarding // Request permissions // Run app with multiprovider - HydratedBlocOverrides.runZoned(() async => runApp(MultiRepositoryProvider(providers: [ - RepositoryProvider(create: (_) => ingredientsRepository), - RepositoryProvider(create: (_) => pantryRepository), - RepositoryProvider(create: (_) => groceryProductRepository) - ], child: FoodApp(dio: dio)))); -} \ No newline at end of file + runZoned( + () => runApp( + MultiRepositoryProvider( + providers: [ + RepositoryProvider.value(value: ingredientsRepository), + RepositoryProvider.value(value: pantryRepository), + RepositoryProvider.value(value: groceryProductRepository), + ], + child: FoodApp(dio: dio), + ), + ), + ); +} diff --git a/app/lib/main_dev.dart b/app/lib/main_dev.dart index 6528924..3310156 100644 --- a/app/lib/main_dev.dart +++ b/app/lib/main_dev.dart @@ -2,6 +2,6 @@ import 'package:foodapp/environment.dart'; import 'package:foodapp/main.delegate.dart'; void main() { - Environment.setEnvironment(const EnvironmentConfig(apiUrl: "http://192.168.1.142:3000")); + Environment.setEnvironment(const EnvironmentConfig(apiUrl: "http://10.0.2.2:8080")); mainDelegate(); -} \ No newline at end of file +} diff --git a/app/lib/pages/add_pantry_item/add_item.page.dart b/app/lib/pages/add_pantry_item/add_item.page.dart index 1e839b5..e77f8fa 100644 --- a/app/lib/pages/add_pantry_item/add_item.page.dart +++ b/app/lib/pages/add_pantry_item/add_item.page.dart @@ -1,11 +1,6 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart'; -import 'package:foodapp/api/api.service.dart'; -import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; -import 'package:foodapp/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart'; -import 'package:foodapp/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart'; import 'package:foodapp/repositories/grocery-products.repository.dart'; -import 'package:foodapp/widgets/base_list/base_list.widget.dart'; class AddItemPage extends StatefulWidget { const AddItemPage({super.key}); @@ -22,8 +17,7 @@ class _AddItemPageState extends State { void submit() async { if (_formKey.currentState!.validate()) { - final grocery = - await groceryRepository.groceryProductApi.getGroceryProductBySku(skuController.text); + final grocery = await groceryRepository.groceryProductApi.getGroceryProductBySku(skuController.text); if (grocery == null) { Navigator.pushNamed(context, "/ingredient/notfound"); } else { @@ -50,44 +44,45 @@ class _AddItemPageState extends State { @override Widget build(BuildContext context) { groceryRepository = GroceryProductsRepository.of(context); - return Scaffold( - appBar: AppBar( - title: const Text("Add item"), - ), - body: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ + return CupertinoPageScaffold( + navigationBar: const CupertinoNavigationBar( + middle: Text("Add item"), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ Expanded( - child: Container( - width: 1000, - child: Form( - key: _formKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TextFormField( - decoration: const InputDecoration(labelText: 'SKU'), - controller: skuController, - keyboardType: TextInputType.text, - validator: (value) { - return (value?.length ?? 0) > 0 - ? null - : "Min length 1"; - }, - ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: tryScan, - child: const Text('Scan')), - ElevatedButton( - onPressed: submit, - child: const Text('Search')), - Text(content) - ], - ) - ], - )))) - ])); + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CupertinoSearchTextField( + controller: skuController, + placeholder: "Search with sku code", + onSubmitted: (text) => submit(), + ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CupertinoButton( + onPressed: tryScan, + child: const Text('Scan'), + ), + CupertinoButton( + onPressed: submit, + child: const Text('Search'), + ), + Text(content) + ], + ) + ], + ), + ), + ) + ], + ), + ); } } diff --git a/app/lib/pages/app/app.page.dart b/app/lib/pages/app/app.page.dart index 1415d17..bf85d5e 100644 --- a/app/lib/pages/app/app.page.dart +++ b/app/lib/pages/app/app.page.dart @@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; class AppPage extends StatelessWidget { - const AppPage(); @override Widget build(BuildContext context) { diff --git a/app/lib/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart b/app/lib/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart index b4ead3f..efda5f4 100644 --- a/app/lib/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart +++ b/app/lib/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart @@ -1,9 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:foodapp/api/api.service.dart'; -import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; -import 'package:foodapp/pages/ingredients/ingredient_not_foud/ingredient_not_found.page.dart'; -import 'package:foodapp/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart'; -import 'package:foodapp/widgets/base_list/base_list.widget.dart'; class IngredientNotFoundPage extends StatefulWidget { const IngredientNotFoundPage({super.key}); @@ -24,13 +19,22 @@ class _IngredientNotFoundPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text("Add item"), - ), - body: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ + appBar: AppBar( + title: const Text("Add item"), + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ ElevatedButton( - onPressed: _addItem, child: const Text("Add the item")), - ElevatedButton(onPressed: _retry, child: const Text("Retry")), - ])); + onPressed: _addItem, + child: const Text("Add the item"), + ), + ElevatedButton( + onPressed: _retry, + child: const Text("Retry"), + ), + ], + ), + ); } } diff --git a/app/lib/pages/pantry/cubit/pantry.cubit.dart b/app/lib/pages/pantry/cubit/pantry.cubit.dart new file mode 100644 index 0000000..2219c02 --- /dev/null +++ b/app/lib/pages/pantry/cubit/pantry.cubit.dart @@ -0,0 +1,21 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:foodapp/pages/pantry/cubit/pantry.state.dart'; +import 'package:foodapp/repositories/pantry.repository.dart'; +import 'package:nice_flutter_kit/nice_flutter_kit.dart'; + +class PantryCubit extends NiceBaseCubit { + final PantryRepository _pantryRepository; + static PantryCubit of(BuildContext context) => BlocProvider.of(context); + + PantryCubit(this._pantryRepository) : super(const PantryState.initialState()); + + Future init() async { + loadPantryItems(); + } + + Future loadPantryItems() async { + final items = await _pantryRepository.getPantryItems(); + emit(state.copyWith(pantryItems: items)); + } +} diff --git a/app/lib/pages/pantry/cubit/pantry.state.dart b/app/lib/pages/pantry/cubit/pantry.state.dart new file mode 100644 index 0000000..e48e29e --- /dev/null +++ b/app/lib/pages/pantry/cubit/pantry.state.dart @@ -0,0 +1,42 @@ +import 'package:flutter/cupertino.dart'; +import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; +import 'package:nice_flutter_kit/nice_flutter_kit.dart'; + +@immutable +class PantryState extends NiceBaseState { + final List? pantryItems; + + const PantryState({ + required super.loading, + required super.error, + required this.pantryItems, + }); + + const PantryState.initialState() + : pantryItems = null, + super.initialState(); + + PantryState copyWith({ + bool? loading, + bool? error, + List? pantryItems, + }) { + return PantryState( + loading: loading ?? this.loading, + error: error ?? this.error, + pantryItems: pantryItems ?? this.pantryItems, + ); + } + + @override + NiceBaseState copyWithLoadingAndError({bool? loading, bool? error}) { + return copyWith(loading: loading, error: error); + } + + @override + List get props => [ + loading, + error, + pantryItems, + ]; +} diff --git a/app/lib/pages/pantry/pantry.page.dart b/app/lib/pages/pantry/pantry.page.dart index 10865c6..38e551f 100644 --- a/app/lib/pages/pantry/pantry.page.dart +++ b/app/lib/pages/pantry/pantry.page.dart @@ -1,11 +1,10 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; -import 'package:foodapp/api/api.service.dart'; -import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:foodapp/pages/add_pantry_item/add_item.page.dart'; +import 'package:foodapp/pages/pantry/cubit/pantry.cubit.dart'; +import 'package:foodapp/pages/pantry/cubit/pantry.state.dart'; import 'package:foodapp/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart'; -import 'package:foodapp/routing/main.router.dart'; -import 'package:foodapp/widgets/base_list/base_list.widget.dart'; +import 'package:foodapp/repositories/pantry.repository.dart'; class PantryPage extends StatefulWidget { const PantryPage({super.key, this.title}); @@ -16,48 +15,81 @@ class PantryPage extends StatefulWidget { } class _PantryPageState extends State { - final ApiService apiService = ApiService.instance; - List? data = []; - - @override - void initState() { - super.initState(); - loadItems(); - } - - void loadItems() async { - final response = await apiService.pantry.getPantryItems(); - print(response); - setState(() { - data = response; - }); - } - void _addItem() async { setState(() { - // Navigator.of(context) - // .push(MaterialPageRoute(builder: ((context) => const AddItemPage()))); - AutoRouter.of(context).push(const AddItemPageRoute()); + Navigator.of(context).push(CupertinoPageRoute(builder: ((context) => const AddItemPage()))); + //AutoRouter.of(context).push(const AddItemPageRoute()); }); } @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title ?? "FoodApp"), - ), - body: Center( - child: BaseList( - emptyState: const Text("Empty"), - data: data, - itemBuilder: (BuildContext context, int index) { - return PantryItemCard(data![index]); - })), - floatingActionButton: FloatingActionButton( - onPressed: _addItem, - tooltip: 'Add item', - child: const Icon(Icons.add), + return BlocProvider( + create: (context) => PantryCubit( + PantryRepository.of(context), + )..init(), + child: SafeArea( + child: CupertinoPageScaffold( + child: BlocBuilder( + buildWhen: (prev, curr) => prev.pantryItems != curr.pantryItems, + builder: (context, state) { + return CustomScrollView( + slivers: [ + CupertinoSliverNavigationBar( + leading: CupertinoButton( + onPressed: () => {}, + child: const Icon(CupertinoIcons.person_crop_circle), + ), + largeTitle: const Text('Pantry'), + trailing: CupertinoButton( + onPressed: _addItem, + child: const Icon(CupertinoIcons.add), + ), + ), + // This widget fills the remaining space in the viewport. + // Drag the scrollable area to collapse the CupertinoSliverNavigationBar. + CupertinoSliverRefreshControl( + onRefresh: () => PantryCubit.of(context).loadPantryItems(), + ), + + if (state.pantryItems != null) + SliverPadding( + padding: const EdgeInsets.only(top: 10), + sliver: SliverGrid( + delegate: SliverChildBuilderDelegate( + (context, index) { + return PantryItemCard(state.pantryItems![index]); + }, + childCount: state.pantryItems!.length, + ), + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 1.5), + ), + ), + + // SliverFillRemaining( + // child: Column( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // BlocBuilder( + // builder: (context, state) { + // return BaseList( + // emptyState: const Text("Empty"), + // data: state.pantryItems, + // itemBuilder: (BuildContext context, int index) { + // return PantryItemCard(state.pantryItems![index]); + // }, + // ); + // }, + // ), + // ], + // ), + // ), + ], + ); + }, + ), + ), ), ); } diff --git a/app/lib/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart b/app/lib/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart index 98391ef..79b9793 100644 --- a/app/lib/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart +++ b/app/lib/pages/pantry/widgets/ingredient-card/pantry_item_card.widget.dart @@ -8,13 +8,76 @@ class PantryItemCard extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - color: Colors.amberAccent, - child: Column( - children: [ - Text(item.groceryProductId.toString()), - Text(item.itemCount.toString()) - ], + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), + child: DecoratedBox( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + blurRadius: 6, + color: Colors.grey.withOpacity(0.2), + ), + ], + ), + child: Card( + child: Stack( + children: [ + Center( + child: Image.network(item.groceryProduct?.imagePath ?? ""), + ), + Positioned( + right: 10, + top: 5, + child: SizedBox( + width: 25, + height: 25, + child: ClipOval( + child: ColoredBox( + color: const Color.fromRGBO(238, 238, 240, 1), + child: Center( + child: Text( + item.itemCount.toString(), + textAlign: TextAlign.center, + style: TextStyle( + color: + item.isLow == true ? Colors.red : CupertinoTheme.of(context).textTheme.textStyle.color, + ), + ), + ), + ), + ), + ), + ), + Column( + children: [ + const Spacer(), + SizedBox( + height: 28, + child: DecoratedBox( + decoration: BoxDecoration( + color: CupertinoTheme.of(context).primaryContrastingColor.withOpacity(0.9), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(4), + bottomRight: Radius.circular(4), + ), + ), + child: Center( + child: Text( + item.groceryProduct?.name ?? "", + overflow: TextOverflow.ellipsis, + style: CupertinoTheme.of(context) + .textTheme + .textStyle + .copyWith(fontWeight: FontWeight.w500, fontSize: 14), + ), + ), + ), + ), + ], + ) + ], + ), + ), ), ); } diff --git a/app/lib/repositories/pantry.repository.dart b/app/lib/repositories/pantry.repository.dart index 08a4eee..7c997c4 100644 --- a/app/lib/repositories/pantry.repository.dart +++ b/app/lib/repositories/pantry.repository.dart @@ -1,7 +1,16 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:foodapp/api/pantry/models/pantry_item.model.dart'; import 'package:foodapp/api/pantry/pantry.api.dart'; class PantryRepository { + factory PantryRepository.of(BuildContext context) => RepositoryProvider.of(context); + final PantryApi _pantryApi; PantryRepository(this._pantryApi); -} \ No newline at end of file + + Future> getPantryItems() { + return _pantryApi.getPantryItems(); + } +} diff --git a/app/lib/routing/main.router.dart b/app/lib/routing/main.router.dart index 7f1eab6..5a4f718 100644 --- a/app/lib/routing/main.router.dart +++ b/app/lib/routing/main.router.dart @@ -3,9 +3,6 @@ import 'package:flutter/widgets.dart'; import 'package:foodapp/pages/add_pantry_item/add_item.page.dart'; import 'package:foodapp/pages/app/app.page.dart'; import 'package:foodapp/pages/app/home/home.page.dart'; -import 'package:foodapp/pages/auth/auth.page.dart'; -import 'package:foodapp/pages/auth/sign-in/sign-in.page.dart'; - import 'package:foodapp/pages/pantry/pantry.page.dart'; part 'main.router.gr.dart'; @@ -22,9 +19,7 @@ part 'main.router.gr.dart'; path: "/", initial: true, page: PantryPage, - meta: { - "title": "Foodapp" - }, + meta: {"title": "Foodapp"}, children: [ RedirectRoute( path: "*", @@ -32,16 +27,12 @@ part 'main.router.gr.dart'; ), ], ), - AutoRoute( - path: "/add-item", - page: AddItemPage, - children: [ - RedirectRoute( - path: "*", - redirectTo: "", - ), - ] - ), + AutoRoute(path: "/add-item", page: AddItemPage, children: [ + RedirectRoute( + path: "*", + redirectTo: "", + ), + ]), AutoRoute( path: "/app", page: AppPage, diff --git a/app/lib/widgets/base_list/base_list.widget.dart b/app/lib/widgets/base_list/base_list.widget.dart index f12b0b1..4e17ba2 100644 --- a/app/lib/widgets/base_list/base_list.widget.dart +++ b/app/lib/widgets/base_list/base_list.widget.dart @@ -17,9 +17,11 @@ class BaseList extends StatelessWidget { if ((data == null || data!.isEmpty) && emptyState != null) { return emptyState!; } else if (data != null && data!.isNotEmpty) { - return ListView.builder( - itemCount: data!.length, - itemBuilder: itemBuilder, + return Flexible( + child: ListView.builder( + itemCount: data!.length, + itemBuilder: itemBuilder, + ), ); } else { return Container(); diff --git a/app/macos/Flutter/GeneratedPluginRegistrant.swift b/app/macos/Flutter/GeneratedPluginRegistrant.swift index e2fdeee..4d189e6 100644 --- a/app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,7 +8,7 @@ import Foundation import firebase_core import firebase_messaging import geolocator_apple -import shared_preferences_macos +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) diff --git a/app/pubspec.lock b/app/pubspec.lock index 2d49b88..203b52f 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -14,7 +14,7 @@ packages: name: _flutterfire_internals url: "https://pub.dartlang.org" source: hosted - version: "1.0.12" + version: "1.0.15" analyzer: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: args url: "https://pub.dartlang.org" source: hosted - version: "2.3.1" + version: "2.4.0" async: dependency: transitive description: @@ -50,20 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.3" - auto_size_text_pk: - dependency: transitive - description: - name: auto_size_text_pk - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" bloc: dependency: "direct main" description: name: bloc url: "https://pub.dartlang.org" source: hosted - version: "8.1.0" + version: "8.1.1" boolean_selector: dependency: transitive description: @@ -126,7 +119,7 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.4.2" + version: "8.4.3" characters: dependency: transitive description: @@ -245,42 +238,42 @@ packages: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.6.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.5.2" + version: "4.5.3" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.1" firebase_messaging: dependency: transitive description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "14.2.1" + version: "14.2.4" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.2.10" + version: "4.2.13" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web url: "https://pub.dartlang.org" source: hosted - version: "3.2.11" + version: "3.2.14" fixnum: dependency: transitive description: @@ -412,14 +405,14 @@ packages: name: geolocator_android url: "https://pub.dartlang.org" source: hosted - version: "4.1.4" + version: "4.1.7" geolocator_apple: dependency: transitive description: name: geolocator_apple url: "https://pub.dartlang.org" source: hosted - version: "2.2.3" + version: "2.2.5" geolocator_platform_interface: dependency: transitive description: @@ -496,14 +489,14 @@ packages: name: introduction_screen url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "3.1.4" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" js: dependency: transitive description: @@ -517,14 +510,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.7.0" - lint: - dependency: transitive - description: - name: lint - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" + version: "4.8.0" lints: dependency: transitive description: @@ -538,7 +524,7 @@ packages: name: logging url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" matcher: dependency: transitive description: @@ -552,7 +538,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: @@ -566,7 +552,7 @@ packages: name: mime url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" nested: dependency: transitive description: @@ -580,7 +566,7 @@ packages: name: nice_flutter_kit url: "https://pub.dartlang.org" source: hosted - version: "1.4.15" + version: "1.4.18" notification_permissions: dependency: transitive description: @@ -622,7 +608,7 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.7" + version: "2.1.8" path_provider_platform_interface: dependency: transitive description: @@ -713,35 +699,28 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.15" + version: "2.0.17" shared_preferences_android: dependency: transitive description: name: shared_preferences_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.14" - shared_preferences_ios: + version: "2.0.15" + shared_preferences_foundation: dependency: transitive description: - name: shared_preferences_ios + name: shared_preferences_foundation url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.3" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" + version: "2.1.3" shared_preferences_platform_interface: dependency: transitive description: @@ -762,7 +741,7 @@ packages: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.3" shelf: dependency: transitive description: @@ -788,14 +767,14 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "1.2.6" + version: "1.2.7" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.9.1" stack_trace: dependency: transitive description: @@ -824,20 +803,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" - styled_widget: - dependency: "direct main" - description: - name: styled_widget - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.1" synchronized: dependency: transitive description: name: synchronized url: "https://pub.dartlang.org" source: hosted - version: "3.0.0+3" + version: "3.0.1" term_glyph: dependency: transitive description: @@ -851,7 +823,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.12" + version: "0.4.13" timeago: dependency: transitive description: @@ -865,7 +837,7 @@ packages: name: timing url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" tuple: dependency: transitive description: @@ -886,21 +858,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" - velocity_x: - dependency: "direct main" - description: - name: velocity_x - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.0" - vxstate: - dependency: transitive - description: - name: vxstate - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.0" + version: "2.1.3" watcher: dependency: transitive description: @@ -914,7 +872,7 @@ packages: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.3.0" win32: dependency: transitive description: @@ -928,7 +886,7 @@ packages: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+2" + version: "1.0.0" xml: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index f3aa47e..6a57301 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -35,9 +35,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - velocity_x: ^3.5.1 - styled_widget: ^0.4.0+3 + cupertino_icons: ^1.0.5 flutter_barcode_scanner: ^2.0.0 flutter_bloc: 8.0.1 dio: ^4.0.6 @@ -45,7 +43,7 @@ dependencies: hydrated_bloc: ^8.1.0 equatable: ^2.0.5 auto_route: ^5.0.4 - nice_flutter_kit: ^1.4.15 + nice_flutter_kit: ^1.4.17 dev_dependencies: flutter_test: