From 202a6c9e2324362e4aed1649416a48640549b28b Mon Sep 17 00:00:00 2001 From: Jethrolopwus Date: Thu, 28 Nov 2024 14:09:23 +0100 Subject: [PATCH 01/12] feat: implement manufacturer dashboard design --- frontend/package-lock.json | 526 ++++++++++++++++++++++++++-- frontend/package.json | 4 + frontend/src/app/dashboard/page.tsx | 346 ++++++++++++++++++ frontend/src/assets/girl1.png | Bin 0 -> 6394 bytes frontend/src/assets/icon1.png | Bin 0 -> 1234 bytes 5 files changed, 852 insertions(+), 24 deletions(-) create mode 100644 frontend/src/app/dashboard/page.tsx create mode 100644 frontend/src/assets/girl1.png create mode 100644 frontend/src/assets/icon1.png diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 775ecf0..12fff04 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,7 +16,11 @@ "next": "14.0.2", "react": "^18", "react-blockies": "^1.4.1", + "react-datepicker": "^7.5.0", "react-dom": "^18", + "react-icons": "^5.3.0", + "react-toastify": "^10.0.6", + "sharp": "^0.33.5", "starknet": "^6.11.0" }, "devDependencies": { @@ -62,6 +66,15 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -119,29 +132,29 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz", - "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", "dependencies": { - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", - "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/react": { - "version": "0.26.17", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.17.tgz", - "integrity": "sha512-ESD+jYWwqwVzaIgIhExrArdsCL1rOAzryG/Sjlu8yaD3Mtqi3uVyhbE2V7jD58Mo52qbzKz2eUY/Xgh5I86FCQ==", + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", "dependencies": { - "@floating-ui/react-dom": "^2.1.0", - "@floating-ui/utils": "^0.2.0", + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -150,9 +163,9 @@ } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", - "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -162,9 +175,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", - "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" }, "node_modules/@headlessui/react": { "version": "2.0.4", @@ -227,6 +240,348 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1691,6 +2046,18 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1707,6 +2074,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1822,6 +2198,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -1896,6 +2281,14 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -3176,6 +3569,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -4624,6 +5022,21 @@ "react": ">=15.0.0" } }, + "node_modules/react-datepicker": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.5.0.tgz", + "integrity": "sha512-6MzeamV8cWSOcduwePHfGqY40acuGlS1cG//ePHT6bVbLxWyqngaStenfH03n1wbzOibFggF66kWaBTb1SbTtQ==", + "dependencies": { + "@floating-ui/react": "^0.26.23", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -4636,11 +5049,31 @@ "react": "^18.3.1" } }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-toastify": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", + "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -4859,10 +5292,9 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -4908,6 +5340,44 @@ "node": ">= 0.4" } }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4959,6 +5429,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 4fa885b..7a73245 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,7 +21,11 @@ "next": "14.0.2", "react": "^18", "react-blockies": "^1.4.1", + "react-datepicker": "^7.5.0", "react-dom": "^18", + "react-icons": "^5.3.0", + "react-toastify": "^10.0.6", + "sharp": "^0.33.5", "starknet": "^6.11.0" }, "devDependencies": { diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx new file mode 100644 index 0000000..268af85 --- /dev/null +++ b/frontend/src/app/dashboard/page.tsx @@ -0,0 +1,346 @@ +'use client'; +import Image from 'next/image'; +import React, { useState } from 'react'; +import { BsFillXDiamondFill } from 'react-icons/bs'; +import { HiMenuAlt3 } from 'react-icons/hi'; +import { IoSearchOutline, IoSettingsOutline } from 'react-icons/io5'; +import { IoMdMenu, IoMdClose } from 'react-icons/io'; +import { FaPlus } from 'react-icons/fa'; +import girl from '@/assets/girl1.png'; +import boy from '@/assets/girl1.png'; +import icon from '@/assets/icon1.png'; +import { toast } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; + +const AddEventModal = ({ + isOpen, + onClose, +}: { + isOpen: boolean; + onClose: () => void; +}) => { + const [formData, setFormData] = useState({ + title: '', + verification: '', + date: null, + role: '', + }); + + const [errors, setErrors] = useState({ + title: false, + verification: false, + date: false, + role: false, + }); + + const handleInputChange = (field: string, value: string | Date | null) => { + setFormData({ ...formData, [field]: value }); + setErrors({ ...errors, [field]: false }); + }; + + const validateForm = () => { + const newErrors = { + title: formData.title.trim() === '', + verification: formData.verification.trim() === '', + date: !formData.date, + role: formData.role === '', + }; + setErrors(newErrors); + return !Object.values(newErrors).some((error) => error); + }; + + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + if (validateForm()) { + toast.success('Event added successfully!', { + position: 'top-right', + }); + + setFormData({ + title: '', + verification: '', + date: null, + role: '', + }); + onClose(); + } else { + toast.error('Please fill in all the required fields!', { + position: 'top-right', + }); + } + }; + + if (!isOpen) return null; + + return ( +
+
+
+

+ + Add Events +

+ +
+ +
+
+ + handleInputChange('title', e.target.value)} + className={`w-full px-3 py-2 border ${ + errors.title ? 'border-red-500' : 'border-gray-300' + } rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-600`} + /> + {errors.title && ( +

Title is required.

+ )} +
+ +
+ + + handleInputChange('verification', e.target.value) + } + className={`w-full px-3 py-2 border ${ + errors.verification ? 'border-red-500' : 'border-gray-300' + } rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-600`} + /> + {errors.verification && ( +

Verification is required.

+ )} +
+
+
+ + handleInputChange('date', date)} + className={`w-full px-3 py-2 border ${ + errors.date ? 'border-red-500' : 'border-gray-300' + } rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-600`} + placeholderText="Select Date" + /> + {errors.date && ( +

Date is required.

+ )} +
+ +
+ + + {errors.role && ( +

Role is required.

+ )} +
+
+
+ +
+
+
+
+ ); +}; + +const Dashboard = () => { + const [isModalOpen, setModalOpen] = useState(false); + const [activePage, setActivePage] = useState(1); + + const handlePageClick = (page: React.SetStateAction) => { + setActivePage(page); + }; + + const [activeMenu, setActiveMenu] = useState('menu'); + + const handleMenuClick = (menu: React.SetStateAction) => { + setActiveMenu(menu); + }; + + return ( +
+ + + + +
+
+

Inspection List

+
+ Avatar +
+ Joy Daniel +

Owner

+
+
+
+
+
+ + +
+
+
+ + +
+
+
+ +
+
+ setModalOpen(false)} + /> + +
+ + + + + + + + + + + {Array.from({ length: 10 }).map((_, idx) => ( + + + + + + + ))} + +
ChecksDatesRoleDescription
+ + Avatar + Take recent orders on Jumia + + August 23, 2023 + + Avatar + Doris K. John + +

. Required to look up items on Jumia

+

. Select required item and place

+
+
+ +
+ + {[1, 2, 3, 4, 5].map((page) => ( + + ))} + + +
+
+
+ ); +}; + +export default Dashboard; diff --git a/frontend/src/assets/girl1.png b/frontend/src/assets/girl1.png new file mode 100644 index 0000000000000000000000000000000000000000..b76fae258cdefe50c819c619eb6e40ec45843ad5 GIT binary patch literal 6394 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 IM6N<$g3SqFdjJ3c literal 0 HcmV?d00001 diff --git a/frontend/src/assets/icon1.png b/frontend/src/assets/icon1.png new file mode 100644 index 0000000000000000000000000000000000000000..338979f3843278a0fe1de9ba19faf2d904ae4d5f GIT binary patch literal 1234 zcmV;@1TFiCP)3Bnm!7}ENu}HYd6iu?#}Ma?KyX6+H7_yQ zTlW&0{dA`&lGP`-v-*~nrl+4E!I#k;!O-`i`>AU6_*RYDidOYHcQm$eoQ{@+9E3Qp z@85<{_s~yDC!*IhT&1vicZ+D>huI~%ZQ(FVB>doJA8!@yI2A|1!KHlwAB<#?*yg^q8$NAWk%v&`!deCIMik7Py|spOD`g}`%4z;;SlS?Bl*xx5z5XAr z*Ik&9l>*oHJ&2r4WbYEW$cWVWutCK5Vcjtn%&d3{pD(W?Avv|WIxckrZ@~BK6~yJY zii5=1_JkyVK4NmtpH3Zdx$2s~p%!R{WK&XPG+bA=Yw+rOjDL7mt+W0uRuGyiET45`7;K zZ5}F}0?xc{8aY6N;j&Pb$}9!!Pthq3y$1Y$J6hX)W5Aam0;9u-jOV>6xweL0aqS=A z>z|BHLA_p(elakXUw4E{f0(o`ilL#!hQlfK8G1#=XjW6;kA`T^TR^Wk_DuA)RH)=H zE!v+j7SL^;KLi|)oMbKp6WemR;AcQ**hjn`K{iiK(!^Dw8RlQhbCc6`M)46dzl wsY*Y95Zqyd_3?lrg7tCFyTbV}r Date: Thu, 28 Nov 2024 16:34:07 +0000 Subject: [PATCH 02/12] feat: add branding toolkit --- frontend/design/branding.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 frontend/design/branding.md diff --git a/frontend/design/branding.md b/frontend/design/branding.md new file mode 100644 index 0000000..f71d68c --- /dev/null +++ b/frontend/design/branding.md @@ -0,0 +1,3 @@ +## Brand toolkit for ScanGuard + +[Link to google drive](https://drive.google.com/drive/folders/1tpg9cHSTW-oZyaiq1mzFbUtVeHsVTC4d) \ No newline at end of file From cfe52df2766597781f2a80741b9969b09842bd08 Mon Sep 17 00:00:00 2001 From: Starknet Bro <100969340+starknetbrother@users.noreply.github.com> Date: Fri, 29 Nov 2024 03:35:32 +0000 Subject: [PATCH 03/12] chore: fix video on homepage --- frontend/src/components/ContentSection.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/ContentSection.tsx b/frontend/src/components/ContentSection.tsx index 4e5ce20..714e437 100644 --- a/frontend/src/components/ContentSection.tsx +++ b/frontend/src/components/ContentSection.tsx @@ -117,9 +117,14 @@ const ContentCTAMobile = () => ( const VideoComponent = () => (
- +
); From 09f0b1f720167a9fbcae5621ec137437bc580d63 Mon Sep 17 00:00:00 2001 From: Starknet Bro <100969340+starknetbrother@users.noreply.github.com> Date: Fri, 29 Nov 2024 03:39:16 +0000 Subject: [PATCH 04/12] chore: fix video on homepage --- frontend/src/components/ContentSection.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/ContentSection.tsx b/frontend/src/components/ContentSection.tsx index 714e437..d519d11 100644 --- a/frontend/src/components/ContentSection.tsx +++ b/frontend/src/components/ContentSection.tsx @@ -121,7 +121,6 @@ const VideoComponent = () => ( className="w-full h-full rounded-2xl" src="https://www.youtube.com/embed/j99jT-Ljusg" title="YouTube video player" - frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen > From 81943e4a76bf8b1c0918195f4487c90c29e2c0bd Mon Sep 17 00:00:00 2001 From: Jethrolopwus Date: Fri, 29 Nov 2024 08:03:18 +0100 Subject: [PATCH 05/12] style: responsiveness and style modification --- frontend/src/app/dashboard/page.tsx | 93 +++++++++++++++------------- frontend/src/assets/icon1.ico | Bin 0 -> 7886 bytes frontend/src/assets/icon1.png | Bin 1234 -> 0 bytes 3 files changed, 50 insertions(+), 43 deletions(-) create mode 100644 frontend/src/assets/icon1.ico delete mode 100644 frontend/src/assets/icon1.png diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index 268af85..020bad7 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -8,13 +8,13 @@ import { IoMdMenu, IoMdClose } from 'react-icons/io'; import { FaPlus } from 'react-icons/fa'; import girl from '@/assets/girl1.png'; import boy from '@/assets/girl1.png'; -import icon from '@/assets/icon1.png'; +import icon from '@/assets/icon1.ico'; import { toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; -const AddEventModal = ({ +const AddProductModal = ({ isOpen, onClose, }: { @@ -77,11 +77,11 @@ const AddEventModal = ({ return (
-
+

- Add Events + Add Product

-
+
@@ -181,19 +181,18 @@ const AddEventModal = ({ const Dashboard = () => { const [isModalOpen, setModalOpen] = useState(false); const [activePage, setActivePage] = useState(1); + const [activeMenu, setActiveMenu] = useState('menu'); const handlePageClick = (page: React.SetStateAction) => { setActivePage(page); }; - const [activeMenu, setActiveMenu] = useState('menu'); - const handleMenuClick = (menu: React.SetStateAction) => { setActiveMenu(menu); }; return ( -
+
- -
-
+

Inspection List

Avatar @@ -239,12 +242,12 @@ const Dashboard = () => { -
-
-
+
+
{ />
-
+
- setModalOpen(false)} /> -
- +
+
- - - - - + + + + + {Array.from({ length: 10 }).map((_, idx) => ( - - - - ))} @@ -319,7 +324,7 @@ const Dashboard = () => {
ChecksDatesRoleDescription
ChecksDatesRoleDescription
+ Avatar - Take recent orders on Jumia + + Take recent orders on Jumia + + August 23, 2023 + Avatar - Doris K. John + Doris K. John +

. Required to look up items on Jumia

-

. Select required item and place

+

. Select required item and place

-
+
@@ -327,13 +332,15 @@ const Dashboard = () => { ))} - diff --git a/frontend/src/assets/icon1.ico b/frontend/src/assets/icon1.ico new file mode 100644 index 0000000000000000000000000000000000000000..7e45ca2ad4d494501cbd7bb44ac92d229cb3921d GIT binary patch literal 7886 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 literal 0 HcmV?d00001 diff --git a/frontend/src/assets/icon1.png b/frontend/src/assets/icon1.png deleted file mode 100644 index 338979f3843278a0fe1de9ba19faf2d904ae4d5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1234 zcmV;@1TFiCP)3Bnm!7}ENu}HYd6iu?#}Ma?KyX6+H7_yQ zTlW&0{dA`&lGP`-v-*~nrl+4E!I#k;!O-`i`>AU6_*RYDidOYHcQm$eoQ{@+9E3Qp z@85<{_s~yDC!*IhT&1vicZ+D>huI~%ZQ(FVB>doJA8!@yI2A|1!KHlwAB<#?*yg^q8$NAWk%v&`!deCIMik7Py|spOD`g}`%4z;;SlS?Bl*xx5z5XAr z*Ik&9l>*oHJ&2r4WbYEW$cWVWutCK5Vcjtn%&d3{pD(W?Avv|WIxckrZ@~BK6~yJY zii5=1_JkyVK4NmtpH3Zdx$2s~p%!R{WK&XPG+bA=Yw+rOjDL7mt+W0uRuGyiET45`7;K zZ5}F}0?xc{8aY6N;j&Pb$}9!!Pthq3y$1Y$J6hX)W5Aam0;9u-jOV>6xweL0aqS=A z>z|BHLA_p(elakXUw4E{f0(o`ilL#!hQlfK8G1#=XjW6;kA`T^TR^Wk_DuA)RH)=H zE!v+j7SL^;KLi|)oMbKp6WemR;AcQ**hjn`K{iiK(!^Dw8RlQhbCc6`M)46dzl wsY*Y95Zqyd_3?lrg7tCFyTbV}r Date: Fri, 29 Nov 2024 10:47:09 +0100 Subject: [PATCH 06/12] feat: manufacturer account creation backend integration --- .../src/app/manufacturer/account/page.tsx | 2 + .../manufacturer/ManufacturerForm.tsx | 63 ++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/manufacturer/account/page.tsx b/frontend/src/app/manufacturer/account/page.tsx index 0f7eac4..c6cec5e 100644 --- a/frontend/src/app/manufacturer/account/page.tsx +++ b/frontend/src/app/manufacturer/account/page.tsx @@ -1,3 +1,5 @@ +'use client'; + import ManufacturerForm from '@/components/manufacturer/ManufacturerForm'; export default function ManufacturerPage() { diff --git a/frontend/src/components/manufacturer/ManufacturerForm.tsx b/frontend/src/components/manufacturer/ManufacturerForm.tsx index d466d2e..870b02a 100644 --- a/frontend/src/components/manufacturer/ManufacturerForm.tsx +++ b/frontend/src/components/manufacturer/ManufacturerForm.tsx @@ -7,8 +7,51 @@ import { MapIcon, PhotoIcon, } from '@heroicons/react/24/outline'; +import { useState, FormEvent } from 'react'; +import axios from 'axios'; export default function ManufacturerForm() { + const [companyName, setCompanyName] = useState(''); + const [manufacturerName, setManufacturerName] = useState(''); + const [address, setAddress] = useState(''); + const [email, setEmail] = useState(''); + const [registrationCode, setRegistrationCode] = useState(''); + const [phone, setPhone] = useState(''); + const [registrationImage, setRegistrationImage] = useState(null); + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + + const formData = new FormData(); + formData.append('name', companyName); + formData.append('manufacturerName', manufacturerName); + formData.append('address', address); + formData.append('email', email); + formData.append('rc', registrationCode); + formData.append('phone', phone); + if (registrationImage) { + formData.append('registrationImage', registrationImage); + } + + try { + // Todo manufacturer api endpoint would change + const response = await axios.post('/api/manufacturers', formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); + + if (response.status !== 200) { + // Todo handle error + throw new Error('Failed to create manufacturer'); + } + // Todo handle success + } catch (error) { + // Todo handle error + console.error('Error creating manufacturer:', error); + } + }; + return (
@@ -19,7 +62,10 @@ export default function ManufacturerForm() { Enter your Manufacturer details to get started!

-
+
From f39a3004a7824ca12d7d7be47f285713941d38d7 Mon Sep 17 00:00:00 2001 From: Jethrolopwus Date: Sat, 30 Nov 2024 08:17:57 +0100 Subject: [PATCH 07/12] UPDATE: create a layout file for proper file and folder structure --- frontend/src/app/Home/layout.tsx | 18 ++++++++++++++++++ frontend/src/app/Home/page.tsx | 17 +++++++++++++++++ frontend/src/app/Home/scan/page.tsx | 13 +++++++++++++ frontend/src/app/dashboard/layout.tsx | 11 +++++++++++ frontend/src/app/layout.tsx | 4 ---- frontend/src/app/page.tsx | 21 +++++++++------------ 6 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 frontend/src/app/Home/layout.tsx create mode 100644 frontend/src/app/Home/page.tsx create mode 100644 frontend/src/app/Home/scan/page.tsx create mode 100644 frontend/src/app/dashboard/layout.tsx diff --git a/frontend/src/app/Home/layout.tsx b/frontend/src/app/Home/layout.tsx new file mode 100644 index 0000000..29142e6 --- /dev/null +++ b/frontend/src/app/Home/layout.tsx @@ -0,0 +1,18 @@ +import Footer from '@/components/Footer'; +import NavBar from '@/components/Navbar'; +import { ReactNode } from 'react'; + +interface LayoutProps { + children: ReactNode; +} +const Layout = ({ children }: LayoutProps) => { + return ( +
+ + <>{children} +
+
+ ); +}; + +export default Layout; diff --git a/frontend/src/app/Home/page.tsx b/frontend/src/app/Home/page.tsx new file mode 100644 index 0000000..8f7b429 --- /dev/null +++ b/frontend/src/app/Home/page.tsx @@ -0,0 +1,17 @@ +import Footer from '@/components/Footer'; +import NavBar from '@/components/Navbar'; +import React from 'react'; +import ManufacturerPage from '../manufacturer/account/page'; +import HeroSection from '@/components/HeroSection'; +import ContentSection from '@/components/ContentSection'; + +const page = () => { + return ( +
+ + +
+ ); +}; + +export default page; diff --git a/frontend/src/app/Home/scan/page.tsx b/frontend/src/app/Home/scan/page.tsx new file mode 100644 index 0000000..159ee63 --- /dev/null +++ b/frontend/src/app/Home/scan/page.tsx @@ -0,0 +1,13 @@ +import ScanPage from '@/app/scan/[product]/page'; +import ScanButton from '@/components/ScanButton'; +import React from 'react'; + +const page = () => { + return ( +
+ +
+ ); +}; + +export default page; diff --git a/frontend/src/app/dashboard/layout.tsx b/frontend/src/app/dashboard/layout.tsx new file mode 100644 index 0000000..7c604e8 --- /dev/null +++ b/frontend/src/app/dashboard/layout.tsx @@ -0,0 +1,11 @@ +import { ReactNode } from 'react'; + +interface LayoutProps { + children: ReactNode; +} + +const layout = ({ children }: LayoutProps) => { + return
{children}
; +}; + +export default layout; diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 8e809aa..976b1b7 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -3,8 +3,6 @@ import { Inter } from 'next/font/google'; import './globals.css'; import { StarknetProvider } from '@/components/StarknetProvider'; import { bowlby_one, poppins, roboto } from './fonts'; -import Footer from '@/components/Footer'; -import NavBar from '@/components/Navbar'; import Alert from '@/components/Alert'; import { AlertProvider } from '@/hooks/useAlert'; @@ -28,11 +26,9 @@ export default function RootLayout({ > - {children} -
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 41c1e34..48c7017 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,19 +1,16 @@ 'use client'; import ContentSection from '@/components/ContentSection'; +import Footer from '@/components/Footer'; import HeroSection from '@/components/HeroSection'; +import NavBar from '@/components/Navbar'; +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; export default function Home() { - return ( -
-
-
- -
-
-
- -
-
- ); + const router = useRouter(); + useEffect(() => { + router.push('/Home'); + }); + return
; } From c5af19fb80c9df7a7afde5facaac6c2d2e6379f6 Mon Sep 17 00:00:00 2001 From: Zintarh Date: Sat, 30 Nov 2024 14:58:54 +0100 Subject: [PATCH 08/12] chore: fix layout --- frontend/src/app/Home/page.tsx | 10 +++------- frontend/src/app/Home/scan/page.tsx | 13 ------------- frontend/src/app/page.tsx | 13 ++++++------- frontend/src/app/scan/[product]/page.tsx | 5 ++++- 4 files changed, 13 insertions(+), 28 deletions(-) delete mode 100644 frontend/src/app/Home/scan/page.tsx diff --git a/frontend/src/app/Home/page.tsx b/frontend/src/app/Home/page.tsx index 8f7b429..1f4172b 100644 --- a/frontend/src/app/Home/page.tsx +++ b/frontend/src/app/Home/page.tsx @@ -1,15 +1,11 @@ -import Footer from '@/components/Footer'; -import NavBar from '@/components/Navbar'; import React from 'react'; -import ManufacturerPage from '../manufacturer/account/page'; -import HeroSection from '@/components/HeroSection'; -import ContentSection from '@/components/ContentSection'; + const page = () => { return (
- - + {/* + */}
); }; diff --git a/frontend/src/app/Home/scan/page.tsx b/frontend/src/app/Home/scan/page.tsx deleted file mode 100644 index 159ee63..0000000 --- a/frontend/src/app/Home/scan/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import ScanPage from '@/app/scan/[product]/page'; -import ScanButton from '@/components/ScanButton'; -import React from 'react'; - -const page = () => { - return ( -
- -
- ); -}; - -export default page; diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 48c7017..740f47f 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,16 +1,15 @@ 'use client'; import ContentSection from '@/components/ContentSection'; -import Footer from '@/components/Footer'; import HeroSection from '@/components/HeroSection'; -import NavBar from '@/components/Navbar'; import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; +import Layout from './Home/layout'; export default function Home() { const router = useRouter(); - useEffect(() => { - router.push('/Home'); - }); - return
; + + return + + + } diff --git a/frontend/src/app/scan/[product]/page.tsx b/frontend/src/app/scan/[product]/page.tsx index 6c90bab..e1fe7f0 100644 --- a/frontend/src/app/scan/[product]/page.tsx +++ b/frontend/src/app/scan/[product]/page.tsx @@ -5,6 +5,7 @@ import ScanProduct from '@/components/Scan'; import ConnectModal from '@/components/ConnectModal'; import { useParams } from 'next/navigation'; import ProductPreview from '@/components/ProductPreview'; +import Layout from '@/app/Home/layout'; export default function ScanPage() { const { address } = useAccount(); @@ -25,11 +26,13 @@ export default function ScanPage() { }, [product]); return ( -
+ +
{open && }
+
); } From 30d1d9ff9ab8d46f7160c7539d9e7ce9c9fb855b Mon Sep 17 00:00:00 2001 From: Zintarh Date: Sat, 30 Nov 2024 14:59:56 +0100 Subject: [PATCH 09/12] chore: fix layout --- frontend/src/app/Home/page.tsx | 1 - frontend/src/app/page.tsx | 10 ++++++---- frontend/src/app/scan/[product]/page.tsx | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/Home/page.tsx b/frontend/src/app/Home/page.tsx index 1f4172b..a2fd322 100644 --- a/frontend/src/app/Home/page.tsx +++ b/frontend/src/app/Home/page.tsx @@ -1,6 +1,5 @@ import React from 'react'; - const page = () => { return (
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 740f47f..d886d32 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -8,8 +8,10 @@ import Layout from './Home/layout'; export default function Home() { const router = useRouter(); - return - - - + return ( + + + + + ); } diff --git a/frontend/src/app/scan/[product]/page.tsx b/frontend/src/app/scan/[product]/page.tsx index e1fe7f0..be83c67 100644 --- a/frontend/src/app/scan/[product]/page.tsx +++ b/frontend/src/app/scan/[product]/page.tsx @@ -28,11 +28,11 @@ export default function ScanPage() { return (
- - {open && } + + {open && } - -
+ +
); } From 3eb4dc4bbabb093ca9fb1bef4f45d0b13bd9a139 Mon Sep 17 00:00:00 2001 From: Joseph Gimba <86230531+Joewizy@users.noreply.github.com> Date: Sat, 30 Nov 2024 14:02:11 +0000 Subject: [PATCH 10/12] feat: implement product verification --- frontend/.env.example | 3 ++ frontend/src/app/api/product/[productId].ts | 46 +++++++++++++++++++++ frontend/src/components/Scan.tsx | 20 ++++++++- frontend/src/services/apiService.ts | 13 ++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 frontend/src/app/api/product/[productId].ts diff --git a/frontend/.env.example b/frontend/.env.example index 2939b25..4c6aa57 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -4,3 +4,6 @@ RPC_URL= DATABASE_URL= +BACKEND_BASE_URL=http://localhost:3000/api + + diff --git a/frontend/src/app/api/product/[productId].ts b/frontend/src/app/api/product/[productId].ts new file mode 100644 index 0000000..e923280 --- /dev/null +++ b/frontend/src/app/api/product/[productId].ts @@ -0,0 +1,46 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; + +type ProductDetails = { + product_id: string; + name: string; + image: string; + manufacturer: string; + manufactureDate: string; + expiryDate: string; +}; + +type ErrorResponse = { + error: string; +}; + +const BASE_URL = process.env.BACKEND_BASE_URL || 'http://localhost:3000'; // Update to match your backend URL + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + const { productId } = req.query; + + if (req.method !== 'GET') { + return res.status(405).json({ error: 'Method Not Allowed' }); + } + + if (!productId || typeof productId !== 'string') { + return res.status(400).json({ error: 'Invalid or missing productId' }); + } + + try { + const response = await fetch(`${BASE_URL}/products/${productId}`); + + if (!response.ok) { + const errorBody = await response.json(); + return res.status(response.status).json({ error: errorBody.error || 'Failed to fetch product details' }); + } + + const productDetails: ProductDetails = await response.json(); + return res.status(200).json(productDetails); + } catch (error: any) { + console.error('Error fetching product details:', error.message); + return res.status(500).json({ error: 'Internal Server Error' }); + } +} diff --git a/frontend/src/components/Scan.tsx b/frontend/src/components/Scan.tsx index 7c0c2ff..ee28176 100644 --- a/frontend/src/components/Scan.tsx +++ b/frontend/src/components/Scan.tsx @@ -6,7 +6,7 @@ import { StarIcon2, } from '@/assets/icons'; import { CONTRACT_ADDR, formatDate, formatIpfsHash } from '@/lib/config'; -import { fetchIpfsFile } from '@/services/apiService'; +import { fetchIpfsFile, fetchProductDetails } from '@/services/apiService'; import { useAccount, useReadContract } from '@starknet-react/core'; import React, { useEffect, useMemo, useState } from 'react'; import { useParams } from 'next/navigation'; @@ -22,6 +22,7 @@ type ProductProps = { }; export default function ScanProduct() { + const [productId, setProductId] = useState(""); const [product, setProduct] = useState(); const [contractData, setContractData] = useState<{ product_id: string; @@ -34,13 +35,28 @@ export default function ScanProduct() { const { address } = useAccount(); let payload = params?.product; + useEffect(() => { + const fetchData = async () => { + try { + if (payload) { + const product = await fetchProductDetails(payload.productId); + setProductId(product.productId); + } + } catch (e) { + console.error('Error fetching from Product:', e); + } + }; + + fetchData(); + }, [payload]); + const toggleUserModal = () => { setOpenWallet((prev) => !prev); }; const { data } = useReadContract({ functionName: 'verify', - args: [payload.toString()], + args: [productId], abi, address: CONTRACT_ADDR, watch: true, diff --git a/frontend/src/services/apiService.ts b/frontend/src/services/apiService.ts index fc7afca..2f729bd 100644 --- a/frontend/src/services/apiService.ts +++ b/frontend/src/services/apiService.ts @@ -42,3 +42,16 @@ export const handleFlagProduct = async function ( return await response.json(); }; + +export const fetchProductDetails = async (productId: string) => { + try { + const response = await fetch(`/api/product/${productId}`); + if (!response.ok) { + throw new Error(await response.text()); + } + return await response.json(); + } catch (error) { + console.error('Error fetching product details:', error.message); + throw error; + } +}; From d6431452bb710425e2334afa666a1ecd830b79d1 Mon Sep 17 00:00:00 2001 From: Joseph Gimba <86230531+Joewizy@users.noreply.github.com> Date: Sat, 30 Nov 2024 14:07:16 +0000 Subject: [PATCH 11/12] chore: run prettier fix --- frontend/src/app/api/product/[productId].ts | 16 +++++++++------- frontend/src/components/Scan.tsx | 4 ++-- frontend/src/services/apiService.ts | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/api/product/[productId].ts b/frontend/src/app/api/product/[productId].ts index e923280..f383984 100644 --- a/frontend/src/app/api/product/[productId].ts +++ b/frontend/src/app/api/product/[productId].ts @@ -1,12 +1,12 @@ import type { NextApiRequest, NextApiResponse } from 'next'; type ProductDetails = { - product_id: string; - name: string; - image: string; - manufacturer: string; - manufactureDate: string; - expiryDate: string; + product_id: string; + name: string; + image: string; + manufacturer: string; + manufactureDate: string; + expiryDate: string; }; type ErrorResponse = { @@ -34,7 +34,9 @@ export default async function handler( if (!response.ok) { const errorBody = await response.json(); - return res.status(response.status).json({ error: errorBody.error || 'Failed to fetch product details' }); + return res + .status(response.status) + .json({ error: errorBody.error || 'Failed to fetch product details' }); } const productDetails: ProductDetails = await response.json(); diff --git a/frontend/src/components/Scan.tsx b/frontend/src/components/Scan.tsx index ee28176..ff38ba3 100644 --- a/frontend/src/components/Scan.tsx +++ b/frontend/src/components/Scan.tsx @@ -22,7 +22,7 @@ type ProductProps = { }; export default function ScanProduct() { - const [productId, setProductId] = useState(""); + const [productId, setProductId] = useState(''); const [product, setProduct] = useState(); const [contractData, setContractData] = useState<{ product_id: string; @@ -39,7 +39,7 @@ export default function ScanProduct() { const fetchData = async () => { try { if (payload) { - const product = await fetchProductDetails(payload.productId); + const product = await fetchProductDetails(payload[0]); setProductId(product.productId); } } catch (e) { diff --git a/frontend/src/services/apiService.ts b/frontend/src/services/apiService.ts index 2f729bd..a61b39e 100644 --- a/frontend/src/services/apiService.ts +++ b/frontend/src/services/apiService.ts @@ -51,7 +51,7 @@ export const fetchProductDetails = async (productId: string) => { } return await response.json(); } catch (error) { - console.error('Error fetching product details:', error.message); + console.error('Error fetching product details:', error); throw error; } }; From f481c45e9a07aa37068aa3cc6d76c09c57431458 Mon Sep 17 00:00:00 2001 From: Joy-Adah Date: Sun, 1 Dec 2024 10:04:24 +0100 Subject: [PATCH 12/12] feat: add api logic and use alert hook --- .../app/manufacturer/account/api_service.tsx | 35 +++++++++++++++ .../manufacturer/ManufacturerForm.tsx | 45 +++++++------------ 2 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 frontend/src/app/manufacturer/account/api_service.tsx diff --git a/frontend/src/app/manufacturer/account/api_service.tsx b/frontend/src/app/manufacturer/account/api_service.tsx new file mode 100644 index 0000000..b9b4dad --- /dev/null +++ b/frontend/src/app/manufacturer/account/api_service.tsx @@ -0,0 +1,35 @@ +import { FormEvent } from 'react'; + +interface ManufacturerFormData { + name: string; + address: string; + email: string; + rc: string; + phone: string; + registrationImage?: File; +} + +export const handleSubmit = async ( + e: FormEvent, + data: ManufacturerFormData +) => { + e.preventDefault(); + try { + const formData = new FormData(); + Object.entries(data).forEach(([key, value]) => { + if (value !== undefined) { + formData.append(key, value); + } + }); + + const response = await fetch('/api/manufacturers', { + method: 'POST', + body: formData, + }); + if (!response.ok) throw new Error('Registration failed'); + return response.json(); + } catch (error) { + console.error('Error:', error); + throw error; + } +}; diff --git a/frontend/src/components/manufacturer/ManufacturerForm.tsx b/frontend/src/components/manufacturer/ManufacturerForm.tsx index 870b02a..7713e58 100644 --- a/frontend/src/components/manufacturer/ManufacturerForm.tsx +++ b/frontend/src/components/manufacturer/ManufacturerForm.tsx @@ -7,8 +7,9 @@ import { MapIcon, PhotoIcon, } from '@heroicons/react/24/outline'; -import { useState, FormEvent } from 'react'; -import axios from 'axios'; +import { useState } from 'react'; +import { handleSubmit } from '../../app/manufacturer/account/api_service'; +import { useAlert } from '../../hooks/useAlert'; export default function ManufacturerForm() { const [companyName, setCompanyName] = useState(''); @@ -18,37 +19,21 @@ export default function ManufacturerForm() { const [registrationCode, setRegistrationCode] = useState(''); const [phone, setPhone] = useState(''); const [registrationImage, setRegistrationImage] = useState(null); + const { showAlert } = useAlert(); - const handleSubmit = async (e: FormEvent) => { - e.preventDefault(); - - const formData = new FormData(); - formData.append('name', companyName); - formData.append('manufacturerName', manufacturerName); - formData.append('address', address); - formData.append('email', email); - formData.append('rc', registrationCode); - formData.append('phone', phone); - if (registrationImage) { - formData.append('registrationImage', registrationImage); - } - + const onSubmit = async (e: React.FormEvent) => { try { - // Todo manufacturer api endpoint would change - const response = await axios.post('/api/manufacturers', formData, { - headers: { - 'Content-Type': 'multipart/form-data', - }, + await handleSubmit(e, { + name: companyName, + address: address, + email: email, + rc: registrationCode, + phone: phone, + registrationImage: registrationImage || undefined, }); - - if (response.status !== 200) { - // Todo handle error - throw new Error('Failed to create manufacturer'); - } - // Todo handle success + showAlert('success', 'Manufacturer registered successfully!'); } catch (error) { - // Todo handle error - console.error('Error creating manufacturer:', error); + showAlert('error', 'Failed to register manufacturer. Please try again.'); } }; @@ -63,7 +48,7 @@ export default function ManufacturerForm() {