├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── client
├── .env
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── homeArt.png
│ ├── index.html
│ ├── logo.png
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ │ ├── Loader.js
│ │ ├── Modal.js
│ │ ├── Navbar.js
│ │ ├── ReciptModal.js
│ │ ├── Search.js
│ │ ├── Styles.js
│ │ ├── Theme.js
│ │ └── map.js
│ ├── context
│ │ └── RoleDataContext.js
│ ├── getWeb3.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ │ ├── Customer
│ │ │ ├── PurchaseCustomer.js
│ │ │ ├── ReceiveCustomer.js
│ │ │ └── ReceivedByCustomer.js
│ │ ├── DeliveryHub
│ │ │ ├── ReceiveDeliveryHub.js
│ │ │ └── ShipDeliveryHub.js
│ │ ├── Explorer.js
│ │ ├── Home.js
│ │ ├── Manufacturer
│ │ │ ├── AllManufacture.js
│ │ │ ├── Manufacture.js
│ │ │ └── ShipManufacture.js
│ │ ├── RoleAdmin.js
│ │ └── ThirdParty
│ │ │ ├── PurshaseThirdParty.js
│ │ │ ├── ReceiveThirdParty.js
│ │ │ └── ShipThirdParty.js
│ ├── server.js
│ └── serviceWorker.js
└── yarn.lock
├── contracts
├── Migrations.sol
├── Structure.sol
├── SupplyChain.sol
└── rolesUtils[deprecated]
│ ├── Customer.sol
│ ├── DeliveryHub.sol
│ ├── Manufacturer.sol
│ ├── Roles.sol
│ ├── SortationHub.sol
│ └── Thirdparty.sol
├── images
├── Solidity.svg
├── activitydiagram.png
├── architecture.png
├── architecturefinal.png
├── dataflow.png
├── express.jpg
├── express.svg
├── flow.png
├── ganachetrans.png
├── logo.png
├── mat.png
├── nginx.png
├── react.png
├── sequencediagram.png
├── truffle.png
├── trufflenew.png
└── web3.jpg
├── migrations
├── 1_initial_migration.js
└── 2_deploy_contracts.js
├── package-lock.json
├── package.json
├── test
├── TestSimpleStorage.sol
└── simplestorage.js
└── truffle-config.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Truffle
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Supply-Chain-Dapp
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | A simple Supply Chain setup with Solidity .
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | Description •
54 | Architecture •
55 | Flow •
56 | Working •
57 | Contract Diagrams •
58 | Installation and Setup •
59 | License
60 |
61 |
62 | ## Description
63 | Supply chain is always hard to manage and requires a lot of admistrative machinery. However, when managed with smart contracts using blockchain, a lot of the paperwork is reduced.
64 | Also it leads to an increase in transparency and helps to build an efficient Root of Trust. Spply-chain-dapp is such an implementation of a supply chian management system wich uses blockchain to ensure a transparent and secure transfer of product from the manufacturer to the customer via the online e-commerce websites.
65 | ## Architecture
66 | The smart contract is being written with Solidity which is then compiled, migrated and deployed using Truffle.js on the local blockchain network created using Ganache-cli.The frontend uses Web3.js to communicate with the smart contract and local blockchain network and is written using React.js framework for better component and state lifecycle management.The requests from user are forwarded to frontend through Nginx(load balancer) and Express.js for dynamic routing.
67 |
68 |
69 |
70 |
71 | ## Flow
72 |
73 |
74 |
75 |
76 | ## Working
77 |
78 | The lifecycle of a product starts when manufactureProduct() is called(while making an entry) after the final product is manufactured and the product and manufacturer details are entered in the blockchain. The productHistory[] gets initialized and the current product data is stored with the current owner(manufacturer).
79 |
80 |
81 | Now this product shall be available to the Third Party for purchase. On being purchased by a third party seller, the purchasedByThirdParty() gets called where the owner is set to thirdParty and the present data gets pushed to the productHistory[] (which helps us to track the origin and handling of the product). Simultaneously, the product is shipped by the manufacturer (shipToThirdParty() ) and is received by the Third Party where receivedByThirdParty() is called and the details of the Third Party seller are entered. Each of these checkpoint's data is stored in product history with the state being updated at each step.
82 |
83 |
84 | The online purchase of the product takes place from the Third Party. When the customer orders the product, it is shipped by the Third Party (shipByThirdParty() ) and received by the delivery hub where the receivedByDeliveryHub() is called. Here the customer address is stored, owner is set to Delivery Hub, details of the Delivery Hub are fed and the current data state gets pushed to the productHistory[].
85 |
86 |
87 | Finally the product is shipped by the Delivery Hub (shipByDeliveryHub() ) and received by the customer where the receivedByCustomer() is called and the current and final state gets pushed to the productHistory[] .
88 |
89 |
90 | All of these juncture functions shall be called only after complete verification of product and productHistory[] while entering a checkpoint. (eg:- Customer accepts and confirms the product by clicking the receive button from his account only after it verifies the product).
91 |
92 |
93 | fetchProductPart1() , fetchProductPart2() , fetchProductPart3() , fetchProductHistoryLength() , fetchProductCount() , fetchProductState() are the functions to retreive data of a product queried with UID and data type as product(current state) or history.
94 |
95 |
96 | The hashes(read certificates) are generated using the Solidity cryptographic function keccak256() which implements a SHA-3 hash in the blockchain setup. keccak256() generates a secure 256-bit hash which is the main basis of security in the entire mainnet apart from the smart contracts being immutable. In our supply chain setup certificates are generated at every stage of shipping of the product.
97 |
98 |
99 | ## Contract Diagrams
100 | ### Activity Diagram
101 | The overall flow of the project is described as follows.
102 |
103 |
104 |
105 |
106 |
107 | Sequence Diagram
108 | The flow of the functions in the smart contracts.
109 |
110 |
111 |
112 |
113 |
114 | Data Flow Diagram
115 | The entire structure of the code.
116 |
117 |
118 |
119 |
120 |
121 |
122 | ## Installation and Setup
123 | Prerequisites : `npm, git, docker(optional)`
124 |
125 | Clone the repository
126 | ```Bash
127 | git clone https://github.com/rishav4101/eth-supplychain-dapp.git && cd eth-supplychain-dapp
128 | ```
129 | Install dependencies
130 | ```Bash
131 | npm i
132 | ```
133 | Install ganache-cli
134 | ```Bash
135 | npm i -g ganache-cli
136 | ```
137 | Configure ganache-cli for 10 accounts and extend gasLimit to 6721975000 and beyond, so as to have enough gas for migrating the smart contracts and a data flow for the prototype.
138 | ```Bash
139 | ganache-cli --accounts 10 --gasLimit 6721975000
140 | ```
141 | If you want to run the ganache-cli on docker then use the following command
142 | ```Bash
143 | sudo docker run -d -p 8545:8545 trufflesuite/ganache-cli:latest -h 0.0.0.0 --accounts 10 --gasLimit 6721975000
144 | ```
145 | Open a second terminal and enter the client folder
146 | ```Bash
147 | cd client
148 | ```
149 | Install all packages in the package.json file
150 | ```Bash
151 | npm i
152 | ```
153 | Setup an .env file using the `nano .env` command and enter the google maps api key and set the react rpc port to 8545 since the ganache-cli runs on the same port by default.
154 | The final .env file must look like this
155 | ```Bash
156 | REACT_APP_GOOGLE_MAP_API_KEY=*************************
157 | REACT_APP_RPC=http://127.0.0.1:8545/
158 |
159 | ```
160 | Run the app
161 | ```Bash
162 | npm start
163 | ```
164 | The app gets hosted by default at port 3000.
165 |
166 |
167 |
168 | ## License
169 | This project uses an [MIT](https://opensource.org/licenses/MIT) license.
170 | ## Documentation to help with Solidity
171 | https://docs.soliditylang.org/en/v0.8.4/
172 | ## Documentation to help with React
173 | https://reactjs.org/docs/getting-started.html
174 | ## Documentation to help with Truffle
175 | https://www.trufflesuite.com/docs/truffle/reference/configuration
176 | ## Documentation to help with Ganache-cli
177 | https://www.trufflesuite.com/docs/ganache/overview
178 |
--------------------------------------------------------------------------------
/client/.env:
--------------------------------------------------------------------------------
1 | REACT_APP_GOOGLE_MAP_API_KEY=AIzaSyA6WqMeNU1cT5SdPi5MhmUrAqKTjUaZNGY
2 | REACT_APP_RPC=http://127.0.0.1:7545/
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | /src/contracts
8 |
9 | # testing
10 | /coverage
11 |
12 | # production
13 | /build
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | .env
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `yarn start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `yarn test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `yarn build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `yarn eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `yarn build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.11.4",
7 | "@material-ui/icons": "^4.11.2",
8 | "clsx": "^1.1.1",
9 | "express": "^4.17.1",
10 | "ganache-cli": "^6.12.2",
11 | "ganache-core": "^2.13.2",
12 | "google-maps-react": "^2.0.6",
13 | "react": "16.11.0",
14 | "react-dom": "16.11.0",
15 | "react-router-dom": "^5.2.0",
16 | "react-scripts": "^3.2.0",
17 | "web3": "1.2.2"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": "react-app"
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/homeArt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/homeArt.png
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
20 |
29 | Supplychain-dapp
30 |
31 |
32 | You need to enable JavaScript to run this app.
33 |
34 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/client/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo.png
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | font-family: 'Poppins', sans-serif;
3 | }
4 |
5 | .App {
6 | text-align: center;
7 | }
8 |
9 | .App-logo {
10 | height: 40vmin;
11 | }
12 |
13 | .App-header {
14 | background-color: #282c34;
15 | min-height: 100vh;
16 | display: flex;
17 | flex-direction: column;
18 | align-items: center;
19 | justify-content: center;
20 | font-size: calc(10px + 2vmin);
21 | color: white;
22 | }
23 |
24 | .App-link {
25 | color: #09d3ac;
26 | }
27 |
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import SupplyChainContract from "./contracts/SupplyChain.json";
3 | import { Router, Switch, Route } from "react-router-dom";
4 | import { RoleDataContextProvider } from "./context/RoleDataContext";
5 | // import history from "./history";
6 | import {createBrowserHistory} from 'history';
7 | import getWeb3 from "./getWeb3";
8 |
9 | import Manufacture from "./pages/Manufacturer/Manufacture";
10 | import AllManufacture from "./pages/Manufacturer/AllManufacture";
11 | import ShipManufacture from "./pages/Manufacturer/ShipManufacture";
12 |
13 | import "./App.css";
14 | import ReceiveThirdParty from "./pages/ThirdParty/ReceiveThirdParty";
15 | import PurchaseCustomer from "./pages/Customer/PurchaseCustomer";
16 | import ShipThirdParty from "./pages/ThirdParty/ShipThirdParty";
17 | import ReceiveDeliveryHub from "./pages/DeliveryHub/ReceiveDeliveryHub";
18 | import ShipDeliveryHub from "./pages/DeliveryHub/ShipDeliveryHub";
19 | import ReceiveCustomer from "./pages/Customer/ReceiveCustomer";
20 | import ReceivedByCustomer from "./pages/Customer/ReceivedByCustomer";
21 | import PurchaseThirdParty from "./pages/ThirdParty/PurshaseThirdParty";
22 | import RoleAdmin from "./pages/RoleAdmin";
23 |
24 | import { ThemeProvider } from "@material-ui/core/styles";
25 | import theme from "./components/Theme";
26 |
27 | import Explorer from './pages/Explorer';
28 | import Home from "./pages/Home";
29 |
30 | class App extends Component {
31 | state = { web3: null, accounts: null, contract: null, mRole: null, tpRole: null, dhRole: null, cRole: null };
32 |
33 | componentDidMount = async () => {
34 | try {
35 | const web3 = await getWeb3();
36 | const accounts = await web3.eth.getAccounts();
37 |
38 | const networkId = await web3.eth.net.getId();
39 | const deployedNetwork = SupplyChainContract.networks[networkId];
40 | const instance = new web3.eth.Contract(
41 | SupplyChainContract.abi,
42 | deployedNetwork && deployedNetwork.address,
43 | );
44 |
45 | const mRole = localStorage.getItem("mRole");
46 | const tpRole = localStorage.getItem("tpRole");
47 | const dhRole = localStorage.getItem("dhRole");
48 | const cRole = localStorage.getItem("cRole");
49 |
50 | this.setState({ web3, accounts, contract: instance, mRole: mRole, tpRole: tpRole, dhRole: dhRole, cRole: cRole }, this.runExample);
51 | } catch (error) {
52 | alert(
53 | `Failed to load web3, accounts, or contract. Check console for details.`,
54 | );
55 | console.error(error);
56 | }
57 | };
58 |
59 | runExample = async () => {
60 | const { contract } = this.state;
61 | console.log(contract);
62 | };
63 |
64 | render() {
65 | if (!this.state.web3) {
66 | return Loading Web3, accounts, and contract...
;
67 | }
68 | return (
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | {this.state.mRole !== "" ?
88 |
89 | : Assign Manufacturer Role at /RoleAdmin }
90 |
91 |
92 | {this.state.mRole !== "" ?
93 |
94 | : Assign Manufacturer Role at /RoleAdmin }
95 |
96 |
97 | {this.state.mRole !== "" ?
98 |
99 | : Assign Manufacturer Role at /RoleAdmin }
100 |
101 |
102 | {this.state.tpRole !== "" ?
103 |
104 | : Assign Third Party Role at /RoleAdmin }
105 |
106 |
107 | {this.state.tpRole !== "" ?
108 |
109 | : Assign Third Party Role at /RoleAdmin }
110 |
111 |
112 | {this.state.cRole !== "" ?
113 |
114 | : Assign Customer Role at /RoleAdmin }
115 |
116 |
117 | {this.state.tpRole !== "" ?
118 |
119 | : Assign Third Party Role at /RoleAdmin }
120 |
121 |
122 | {this.state.dhRole !== "" ?
123 |
124 | : Assign Delivery Hub Role at /RoleAdmin }
125 |
126 |
127 | {this.state.dhRole !== "" ?
128 |
129 | : Assign Delivery Hub Role at /RoleAdmin }
130 |
131 |
132 | {this.state.cRole !== "" ?
133 |
134 | : Assign Customer Role at /RoleAdmin }
135 |
136 |
137 | {this.state.cRole !== "" ?
138 |
139 | : Assign Customer Role at /RoleAdmin }
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | );
149 | }
150 | }
151 |
152 | export default App;
153 |
--------------------------------------------------------------------------------
/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render( , div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/client/src/components/Loader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { makeStyles } from "@material-ui/core/styles";
3 | import CircularProgress from "@material-ui/core/CircularProgress";
4 |
5 | const useStyles = makeStyles(() => ({
6 | root: {
7 | display: "flex",
8 | justifyContent: "center",
9 | alignItems: "center",
10 | verticalAlign: "middle",
11 | paddingTop: "300px",
12 | },
13 | }));
14 |
15 | export default function Loader() {
16 | const classes = useStyles();
17 |
18 | return (
19 |
20 |
21 |
22 | );
23 | }
--------------------------------------------------------------------------------
/client/src/components/Modal.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Modal from "@material-ui/core/Modal";
3 | import Backdrop from "@material-ui/core/Backdrop";
4 | import Fade from "@material-ui/core/Fade";
5 | import Button from "@material-ui/core/Button";
6 | import TextField from "@material-ui/core/TextField";
7 | import { useStyles } from "./Styles";
8 |
9 | export default function ProductModal({
10 | prod,
11 | open,
12 | handleClose,
13 | handleReceiveButton,
14 | aText
15 | }) {
16 | const [rdata, setRdata] = React.useState({
17 | long: "",
18 | lat: "",
19 | });
20 |
21 | const handleChangeForm = async (e) => {
22 | setRdata({
23 | ...rdata,
24 | [e.target.name]: e.target.value,
25 | });
26 | };
27 |
28 | const classes = useStyles();
29 | return (
30 |
31 |
43 |
44 |
45 | {prod.length === 0 ? (
46 | <>>
47 | ) : (
48 | <>
49 |
Details
50 |
51 |
52 |
Universal ID:
53 |
{prod[0][0]}
54 |
55 |
56 |
SKU:
{" "}
57 |
{prod[0][1]}
58 |
59 |
60 |
Owner:
{" "}
61 |
{prod[0][2]}
62 |
63 |
64 |
65 |
Manufacturer:
{" "}
66 |
{prod[0][3]}
67 |
68 |
69 |
70 |
Name of Manufacturer:
{" "}
71 |
{prod[0][4]}
72 |
73 |
74 |
75 |
Manufactured date:
{" "}
76 |
77 | {new Date(parseInt(prod[1][0] * 1000)).toDateString() +
78 | " " +
79 | new Date(parseInt(prod[1][0] * 1000)).toTimeString()}
80 |
81 |
82 |
83 |
84 |
85 | Details of Manufacturer:
86 |
{" "}
87 |
{prod[0][5]}
88 |
89 |
90 |
91 |
92 | Longitude of Manufature:{" "}
93 |
{" "}
94 |
{prod[0][6]}
95 |
96 |
97 |
Latitude of Manufature:
{" "}
98 |
{prod[0][7]}
99 |
100 |
101 |
102 |
Product Name:
{" "}
103 |
{prod[1][1]}
104 |
105 |
106 |
Product Code:
{" "}
107 |
{prod[1][2]}
108 |
109 |
110 |
111 |
Product Price:
{" "}
112 |
{prod[1][3]}
113 |
114 |
115 |
116 |
Product Category:
117 |
{prod[1][4]}
118 |
119 |
120 |
Product State:
{" "}
121 |
{prod[1][5]}
122 |
123 |
124 |
Third Party Address:
{" "}
125 |
{prod[1][6]}
126 |
127 |
128 |
Third Party Longitude:
{" "}
129 |
{prod[1][7]}
130 |
131 |
132 |
Third Party Latitude:
{" "}
133 |
{prod[2][0]}
134 |
135 |
136 |
137 |
Delivery Hub Address:
{" "}
138 |
{prod[2][1]}
139 |
140 |
141 |
142 | Delivery Hub Longitude:{" "}
143 |
{" "}
144 |
{prod[2][2]}
145 |
146 |
147 |
Delivery Hub Latitude:
{" "}
148 |
{prod[2][3]}
149 |
150 |
151 |
Customer Address:
{" "}
152 |
{prod[2][4]}
153 |
154 |
155 |
Tx Hash:
{" "}
156 |
157 | {/* {prod[2][5]} */}
158 | {prod[2][5].length > 40
159 | ? prod[2][5].substring(0, 40) + "..."
160 | : prod[2][5]}
161 |
162 |
163 |
164 | {console.log(handleReceiveButton)}
165 | {handleReceiveButton ? (
166 | prod[1][5] === "2" || prod[1][5] === "5" ? (
167 | <>
168 |
175 |
176 |
183 | >
184 | ) : (
185 | <> >
186 | )
187 | ) : (
188 | <> >
189 | )}
190 | {handleReceiveButton ? (
191 | prod[1][5] === "2" ||
192 | prod[1][5] === "5" ||
193 | prod[1][5] === "7" ? (
194 | <>
195 |
201 | handleReceiveButton(
202 | prod[0][0],
203 | rdata.long,
204 | rdata.lat
205 | )
206 | }
207 | >
208 | Recieve
209 |
210 |
{aText.length !== 0 ? aText : ""}
211 | >
212 | ) : (
213 | <> >
214 | )
215 | ) : (
216 | <>>
217 | )}
218 |
219 | >
220 | )}
221 |
222 |
223 |
224 |
225 | );
226 | }
227 |
--------------------------------------------------------------------------------
/client/src/components/Navbar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import clsx from "clsx";
3 | import { makeStyles, useTheme } from "@material-ui/core/styles";
4 | import Drawer from "@material-ui/core/Drawer";
5 | import CssBaseline from "@material-ui/core/CssBaseline";
6 | import AppBar from "@material-ui/core/AppBar";
7 | import Toolbar from "@material-ui/core/Toolbar";
8 | import List from "@material-ui/core/List";
9 | import Typography from "@material-ui/core/Typography";
10 | import IconButton from "@material-ui/core/IconButton";
11 | import MenuIcon from "@material-ui/icons/Menu";
12 | import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
13 | import ChevronRightIcon from "@material-ui/icons/ChevronRight";
14 | import ListItem from "@material-ui/core/ListItem";
15 | import ListItemText from "@material-ui/core/ListItemText";
16 | import { Link } from "react-router-dom";
17 | import GitHubIcon from "@material-ui/icons/GitHub";
18 |
19 | const drawerWidth = 240;
20 |
21 | const useStyles = makeStyles((theme) => ({
22 | root: {
23 | display: "flex",
24 | },
25 | appBar: {
26 | transition: theme.transitions.create(["margin", "width"], {
27 | easing: theme.transitions.easing.sharp,
28 | duration: theme.transitions.duration.leavingScreen,
29 | }),
30 | },
31 | appBarShift: {
32 | width: `calc(100% - ${drawerWidth}px)`,
33 | marginLeft: drawerWidth,
34 | transition: theme.transitions.create(["margin", "width"], {
35 | easing: theme.transitions.easing.easeOut,
36 | duration: theme.transitions.duration.enteringScreen,
37 | }),
38 | },
39 | menuButton: {
40 | marginRight: theme.spacing(2),
41 | },
42 | hide: {
43 | display: "none",
44 | },
45 | drawer: {
46 | width: drawerWidth,
47 | flexShrink: 0,
48 | },
49 | drawerPaper: {
50 | width: drawerWidth,
51 | backgroundColor: "#09126d",
52 | color: "#fff",
53 | },
54 | drawerHeader: {
55 | display: "flex",
56 | alignItems: "center",
57 | padding: theme.spacing(0, 1),
58 | // necessary for content to be below app bar
59 | ...theme.mixins.toolbar,
60 | justifyContent: "flex-end",
61 | },
62 | content: {
63 | flexGrow: 1,
64 | padding: theme.spacing(3),
65 | transition: theme.transitions.create("margin", {
66 | easing: theme.transitions.easing.sharp,
67 | duration: theme.transitions.duration.leavingScreen,
68 | }),
69 | marginLeft: -drawerWidth,
70 | },
71 | contentShift: {
72 | transition: theme.transitions.create("margin", {
73 | easing: theme.transitions.easing.easeOut,
74 | duration: theme.transitions.duration.enteringScreen,
75 | }),
76 | marginLeft: 0,
77 | },
78 | }));
79 |
80 | export default function PersistentDrawerLeft({ pageTitle,navItems, children }) {
81 | const classes = useStyles();
82 | const theme = useTheme();
83 | const [open, setOpen] = React.useState(true);
84 |
85 | const handleDrawerOpen = () => {
86 | setOpen(true);
87 | };
88 |
89 | const handleDrawerClose = () => {
90 | setOpen(false);
91 | };
92 |
93 | return (
94 |
95 |
96 |
102 |
103 |
110 |
111 |
112 |
117 |
122 | SupplyChain-Dapp
123 |
124 |
125 |
126 |
135 |
136 | {pageTitle}
137 |
138 | {theme.direction === "ltr" ? (
139 |
140 | ) : (
141 |
142 | )}
143 |
144 |
145 |
146 |
147 |
148 | Home
149 |
150 |
151 |
155 |
156 | Explorer
157 |
158 |
159 |
160 |
161 | {navItems.length !== 0 ? (
162 | navItems.map((item) => (
163 |
167 |
168 |
169 |
170 |
171 | ))
172 | ) : (
173 | <> >
174 | )}
175 |
176 |
200 |
201 |
206 |
207 | {children}
208 |
209 |
210 | );
211 | }
212 |
--------------------------------------------------------------------------------
/client/src/components/ReciptModal.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Modal from "@material-ui/core/Modal";
3 | import Backdrop from "@material-ui/core/Backdrop";
4 | import Fade from "@material-ui/core/Fade";
5 | import { useStyles } from "./Styles";
6 |
7 | export default function ReciptModal({ recipt, openRecipt, handleCloseRecipt }) {
8 | const classes = useStyles();
9 | return (
10 |
22 |
23 |
24 |
Recipt
25 |
26 | {recipt !== null ? (
27 | <>
28 |
29 |
Tx hash:
30 |
{recipt.hash}
31 |
32 |
33 |
Block hash:
34 |
{recipt.blockHash}
35 |
36 |
37 |
Block Number:
38 |
{recipt.blockNumber}
39 |
40 |
41 |
From:
42 |
{recipt.from}
43 |
44 |
45 |
To:
46 |
{recipt.to}
47 |
48 |
49 |
Nonce:
50 |
{recipt.nonce}
51 |
52 |
53 |
Input:
54 |
{recipt.input}
55 |
56 |
57 |
Gas:
58 |
{recipt.gas}
59 |
60 |
61 |
Value:
62 |
{recipt.value}
63 |
64 | >
65 | ) : (
66 | <> >
67 | )}
68 |
69 |
70 |
71 |
72 | );
73 | }
74 |
--------------------------------------------------------------------------------
/client/src/components/Search.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { makeStyles } from '@material-ui/core/styles';
3 | import Paper from '@material-ui/core/Paper';
4 | import IconButton from '@material-ui/core/IconButton';
5 | import SearchIcon from '@material-ui/icons/Search';
6 |
7 | const useStyles = makeStyles((theme) => ({
8 | root: {
9 | padding: '2px 10px',
10 | display: 'flex',
11 | margin:'20px auto',
12 | width: '40%',
13 | border:"2px solid #1a237e",
14 | borderRadius:50,
15 | boxShadow:"2px 2px 10px #9fa8da"
16 |
17 | },
18 | input: {
19 | justifyContent:'center',
20 | flex: 1,
21 | outline:"none",
22 | border:"none",
23 | padding:0,
24 | borderRadius:40,
25 | fontSize: 17
26 | },
27 | iconButton: {
28 | padding: 10,
29 | },
30 | divider: {
31 | height: 28,
32 | margin: 4,
33 | },
34 | }));
35 |
36 | export default function CustomizedInputBase(props) {
37 | const classes = useStyles();
38 | const [search , setSearch] = React.useState("");
39 | const onTextChage = async (e) =>{
40 | setSearch(e.target.value);
41 | }
42 |
43 | return (
44 | <>
45 |
46 | e.key === 'Enter' ? props.findProduct(search): onTextChage}
52 | />
53 | props.findProduct(search)}>
54 |
55 |
56 |
57 | >
58 | );
59 | }
--------------------------------------------------------------------------------
/client/src/components/Styles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@material-ui/core/styles";
2 |
3 | export const useStyles = makeStyles({
4 | pageWrap: {
5 | textAlign: "center",
6 | color: "#1a237e",
7 | },
8 | pageHeading: {
9 | textAlign: "center",
10 | margin: "10px auto",
11 | padding: 0,
12 | color: "#1a237e",
13 | },
14 |
15 | TableRoot: {
16 | width: "100%",
17 | maxWidth: 1200,
18 | margin: "5px auto",
19 | border: "2px solid #1a237e",
20 | borderRadius: 10,
21 | boxShadow: "2px 2px 10px #9fa8da",
22 | },
23 | TableContainer: {
24 | maxHeight: 600,
25 | borderRadius: 7,
26 | },
27 | AddressCell: {
28 | maxWidth: 150,
29 | overflow: "hidden",
30 | textOverflow: "ellipsis",
31 | },
32 | tableCount: {
33 | textAlign: "center",
34 | margin: "10px auto",
35 | padding: 0,
36 | color: "#1a237e",
37 | },
38 | TableHead: {
39 | backgroundColor: "#1a237e !important",
40 | color: "#fff !important",
41 | },
42 | TableCell: {
43 | color: "#1a237e !important",
44 | },
45 |
46 | FormWrap: {
47 | maxWidth: 900,
48 | margin: "30px auto",
49 | padding: 20,
50 | borderRadius: 10,
51 | boxShadow: "2px 2px 10px #9fa8da",
52 | },
53 |
54 | RoleForm: {
55 | display: "flex",
56 | alignItems: "center",
57 | margin: "20px auto",
58 | },
59 |
60 | //Explorer
61 | Explorerroot: {
62 | padding: "2px 4px",
63 | margin: "10px",
64 | width: "100%",
65 | },
66 | ProductPaper: {
67 | padding: 10,
68 | borderRadius: 10,
69 | boxShadow: "2px 2px 10px #9fa8da",
70 | border: "2px solid #1a237e",
71 | },
72 | ExplorerdRow: {
73 | width: "100%",
74 | borderBottom: `0px solid #222`,
75 | display: "flex",
76 | justifyContent: "center",
77 | alignItems: "center",
78 | padding: 5,
79 | margin: "0 auto",
80 | fontWeight: 600,
81 | color: "#1a237e",
82 | },
83 | TableRoot2: {
84 | width: "100%",
85 | maxWidth: 1300,
86 | margin: "5px auto",
87 | border: "2px solid #1a237e",
88 | borderRadius: 10,
89 | boxShadow: "2px 2px 10px #9fa8da",
90 | },
91 |
92 | //Modal
93 | modal: {
94 | display: "flex",
95 | alignItems: "center",
96 | justifyContent: "center",
97 | },
98 | paper: {
99 | backgroundColor: "#fff",
100 | padding: 15,
101 | outline: "none",
102 | width: "min(90%, 650px)",
103 | height: "80%",
104 | border: "2px solid #1a237e",
105 | borderRadius: 10,
106 | boxShadow: "2px 2px 10px #9fa8da",
107 | overflow: "scroll",
108 | },
109 | Reciptpaper: {
110 | backgroundColor: "#fff",
111 | border: "0px solid #000",
112 | padding: 15,
113 | outline: "none",
114 | width: "min(95%, 950px)",
115 | height: "500px",
116 | border: "2px solid #1a237e",
117 | borderRadius: 10,
118 | boxShadow: "2px 2px 10px #9fa8da",
119 | overflow: "scroll",
120 | },
121 | dRow: {
122 | width: "100%",
123 | borderBottom: `1px solid #222`,
124 | display: "flex",
125 | justifyContent: "center",
126 | alignItems: "center",
127 | padding: 10,
128 | margin: "0 auto",
129 | },
130 |
131 | dCol1: {
132 | width: "30%",
133 | textAlign: "left",
134 | fontWeight: 600,
135 | color: "#1a237e",
136 | },
137 | dCol2: {
138 | width: "70%",
139 | textAlign: "left",
140 | fontWeight: 600,
141 | color: "#1a237e",
142 | overflow: "hidden",
143 | textOverflow: "ellipsis",
144 | },
145 |
146 | //Home
147 | HomeBtn: {
148 | margin: 10,
149 | },
150 | HomeCardWrap: {
151 | maxWidth: 500,
152 | width: "90%",
153 | padding: 20,
154 | borderRadius: 10,
155 | boxShadow: "2px 2px 10px #9fa8da",
156 | border: "2px solid #1a237e",
157 | margin: "10px auto",
158 | },
159 | });
160 |
--------------------------------------------------------------------------------
/client/src/components/Theme.js:
--------------------------------------------------------------------------------
1 | import createMuiTheme from "@material-ui/core/styles/createMuiTheme";
2 |
3 | const theme = createMuiTheme({
4 | palette: {
5 | primary: {
6 | main: "#1a237e",
7 | },
8 | secondary: {
9 | main: "#1a237e",
10 | },
11 |
12 | },
13 | });
14 |
15 | export default theme;
16 |
--------------------------------------------------------------------------------
/client/src/components/map.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Map, GoogleApiWrapper, Marker } from 'google-maps-react';
3 | const mapStyles = {
4 | width: '95%',
5 | // height: '50%',
6 |
7 | borderRadius:"10px",
8 | // maxWidth:"400px",
9 | height: "350px",
10 | zIndex: "10 !important",
11 | border:"2px solid #1a237e",
12 | };
13 |
14 | export class MapContainer extends Component {
15 | constructor(props) {
16 | super(props);
17 | // var point = [];
18 | // prodData.map((data) =>{
19 | // point.push({latitude:data[0][7],longitude: data[0][7]});
20 |
21 | // });
22 | var points =[];
23 | if(props.prodData[0][7].length !== 0) { points.push({latitude: props.prodData[0][7], longitude: props.prodData[0][6]})};
24 | if(props.prodData[2][0].length !== 0) {points.push( {latitude: props.prodData[2][0], longitude: props.prodData[1][7]})};
25 | if(props.prodData[2][3].length !== 0) {points.push({latitude: props.prodData[2][3], longitude: props.prodData[2][2]})};
26 |
27 | this.state = {
28 | stores: points
29 | }
30 | }
31 |
32 | displayMarkers = () => {
33 | return this.state.stores.map((store, index) => {
34 | return console.log("You clicked me!")} />
39 | })
40 | }
41 |
42 | render() {
43 | return (
44 |
50 | {this.displayMarkers()}
51 |
52 | );
53 | }
54 | }
55 |
56 | MapContainer = GoogleApiWrapper({
57 | apiKey: process.env.REACT_APP_GOOGLE_MAP_API_KEY
58 | })(MapContainer);
--------------------------------------------------------------------------------
/client/src/context/RoleDataContext.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createContext, useState } from "react";
3 |
4 | const RoleDataContext = createContext(null);
5 |
6 | export const RoleDataContextProvider = ({ mRole, tpRole, dhRole, cRole, children }) => {
7 |
8 | const [roles, setRoles] = useState({
9 | manufacturer : mRole,
10 | thirdparty : tpRole,
11 | deliveryhub : dhRole,
12 | customer : cRole
13 | });
14 |
15 | return (
16 |
17 | {children}
18 |
19 | );
20 | };
21 |
22 | export const useRole = () => React.useContext(RoleDataContext);
23 |
--------------------------------------------------------------------------------
/client/src/getWeb3.js:
--------------------------------------------------------------------------------
1 | import Web3 from "web3";
2 |
3 |
4 | const getWeb3 = () =>
5 | new Promise((resolve, reject) => {
6 | // Wait for loading completion to avoid race conditions with web3 injection timing.
7 | window.addEventListener("load", async () => {
8 | // Modern dapp browsers...
9 | if (window.ethereum) {
10 | const web3 = new Web3(window.ethereum);
11 | try {
12 | // Request account access if needed
13 | await window.ethereum.enable();
14 | // Acccounts now exposed
15 | resolve(web3);
16 | } catch (error) {
17 | reject(error);
18 | }
19 | }
20 | // Legacy dapp browsers...
21 | else if (window.web3) {
22 | // Use Mist/MetaMask's provider.
23 | const web3 = window.web3;
24 | console.log("Injected web3 detected.");
25 | resolve(web3);
26 | }
27 | // Fallback to localhost; use dev console port by default...
28 | else {
29 | const provider = new Web3.providers.HttpProvider(
30 | process.env.REACT_APP_RPC
31 | );
32 | const web3 = new Web3(provider);
33 |
34 | console.log("No web3 instance injected, using Local web3.");
35 | resolve(web3);
36 | }
37 | });
38 | });
39 |
40 | export default getWeb3;
41 |
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render( , document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/pages/Customer/PurchaseCustomer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Table from "@material-ui/core/Table";
6 | import TableBody from "@material-ui/core/TableBody";
7 | import TableCell from "@material-ui/core/TableCell";
8 | import TableContainer from "@material-ui/core/TableContainer";
9 | import TableHead from "@material-ui/core/TableHead";
10 | import TableRow from "@material-ui/core/TableRow";
11 | import Paper from "@material-ui/core/Paper";
12 | import TablePagination from "@material-ui/core/TablePagination";
13 | import { useStyles } from "../../components/Styles";
14 | import ProductModal from "../../components/Modal";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function PurchaseCustomer(props) {
19 | const classes = useStyles();
20 | const supplyChainContract = props.supplyChainContract;
21 | const { roles } = useRole();
22 | const [count, setCount] = React.useState(0);
23 | const [allProducts, setAllProducts] = React.useState([]);
24 | const [loading, setLoading] = React.useState(false);
25 | const navItem = [
26 | ["Purchase Product", "/Customer/buy"],
27 | ["Receive Product", "/Customer/receive"],
28 | ["Your Products", "/Customer/allReceived"],
29 | ];
30 | React.useEffect(() => {
31 | (async () => {
32 | setLoading(true);
33 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
34 | setCount(cnt);
35 | })();
36 |
37 | (async () => {
38 | const arr = [];
39 | for (var i = 1; i < count; i++) {
40 | const prodState = await supplyChainContract.methods
41 | .fetchProductState(i)
42 | .call();
43 |
44 | if (prodState === "3") {
45 | const prodData = [];
46 | const a = await supplyChainContract.methods
47 | .fetchProductPart1(i, "product", 0)
48 | .call();
49 | const b = await supplyChainContract.methods
50 | .fetchProductPart2(i, "product", 0)
51 | .call();
52 | const c = await supplyChainContract.methods
53 | .fetchProductPart3(i, "product", 0)
54 | .call();
55 | prodData.push(a);
56 | prodData.push(b);
57 | prodData.push(c);
58 | arr.push(prodData);
59 | }
60 | }
61 | setAllProducts(arr);
62 | setLoading(false);
63 | })();
64 | }, [count]);
65 | const [page, setPage] = React.useState(0);
66 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
67 |
68 | const handleChangePage = (event, newPage) => {
69 | setPage(newPage);
70 | };
71 |
72 | const handleChangeRowsPerPage = (event) => {
73 | setRowsPerPage(+event.target.value);
74 | setPage(0);
75 | };
76 |
77 | const [open, setOpen] = React.useState(false);
78 | const [modalData, setModalData] = React.useState([]);
79 |
80 | const handleClose = () => setOpen(false);
81 |
82 | const handleClick = async (prod) => {
83 | await setModalData(prod);
84 | setOpen(true);
85 | };
86 |
87 | const handleBuyButton = async (id) => {
88 | await supplyChainContract.methods
89 | .purchaseByCustomer(id)
90 | .send({ from: roles.customer, gas: 1000000 })
91 | .on("transactionHash", function (hash) {
92 | handleSetTxhash(id, hash);
93 | });
94 | setCount(0);
95 | };
96 |
97 | const handleSetTxhash = async (id, hash) => {
98 | await supplyChainContract.methods
99 | .setTransactionHash(id, hash)
100 | .send({ from: roles.manufacturer, gas: 900000 });
101 | };
102 |
103 | return (
104 | <>
105 |
106 |
107 | {loading ? (
108 |
109 | ) : (
110 | <>
111 |
116 |
117 | Purchase Products
118 |
119 | Total : {allProducts.length}
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | Universal ID
130 |
131 |
135 | Product Code
136 |
137 |
141 | Manufacturer
142 |
143 |
147 | Manufacture Date
148 |
149 |
153 | Product Name
154 |
155 |
162 | Owner
163 |
164 |
168 | Buy
169 |
170 |
171 |
172 |
173 | {allProducts.length !== 0 ? (
174 | allProducts
175 | .slice(
176 | page * rowsPerPage,
177 | page * rowsPerPage + rowsPerPage
178 | )
179 | .map((prod) => {
180 | const d = new Date(parseInt(prod[1][0] * 1000));
181 | return (
182 | <>
183 |
189 | handleClick(prod)}
195 | >
196 | {prod[0][0]}
197 |
198 | handleClick(prod)}
202 | >
203 | {prod[1][2]}
204 |
205 | handleClick(prod)}
209 | >
210 | {prod[0][4]}
211 |
212 | handleClick(prod)}
215 | >
216 | {d.toDateString() +
217 | " " +
218 | d.toTimeString()}
219 |
220 | handleClick(prod)}
224 | >
225 | {prod[1][1]}
226 |
227 | handleClick(prod)}
234 | >
235 | {prod[0][2]}
236 |
237 |
241 |
246 | handleBuyButton(prod[0][0])
247 | }
248 | >
249 | BUY
250 |
251 |
252 |
253 | >
254 | );
255 | })
256 | ) : (
257 | <> >
258 | )}
259 |
260 |
261 |
262 |
271 |
272 |
273 | >
274 | )}
275 |
276 |
277 | >
278 | );
279 | }
280 |
--------------------------------------------------------------------------------
/client/src/pages/Customer/ReceiveCustomer.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import ProductModal from "../../components/Modal";
5 | import { useRole } from "../../context/RoleDataContext";
6 | import Table from "@material-ui/core/Table";
7 | import TableBody from "@material-ui/core/TableBody";
8 | import TableCell from "@material-ui/core/TableCell";
9 | import TableContainer from "@material-ui/core/TableContainer";
10 | import TableHead from "@material-ui/core/TableHead";
11 | import TableRow from "@material-ui/core/TableRow";
12 | import Paper from "@material-ui/core/Paper";
13 | import TablePagination from "@material-ui/core/TablePagination";
14 | import { useStyles } from "../../components/Styles";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function ReceiveCustomer(props) {
19 | const supplyChainContract = props.supplyChainContract;
20 | const { roles } = useRole();
21 | const [count, setCount] = React.useState(0);
22 | const [allReceiveProducts, setAllReceiveProducts] = React.useState([]);
23 | const [modalData, setModalData] = useState([]);
24 | const [open, setOpen] = useState(false);
25 | const classes = useStyles();
26 | const [loading, setLoading] = React.useState(false);
27 | const navItem = [
28 | ["Purchase Product", "/Customer/buy"],
29 | ["Receive Product", "/Customer/receive"],
30 | ["Your Products", "/Customer/allReceived"],
31 | ];
32 | const [alertText, setalertText] = React.useState("");
33 | React.useEffect(() => {
34 | (async () => {
35 | setLoading(true);
36 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
37 | setCount(cnt);
38 | })();
39 |
40 | (async () => {
41 | const arr = [];
42 | for (var i = 1; i < count; i++) {
43 | const prodState = await supplyChainContract.methods
44 | .fetchProductState(i)
45 | .call();
46 |
47 | if (prodState === "7") {
48 | const prodData = [];
49 | const a = await supplyChainContract.methods
50 | .fetchProductPart1(i, "product", 0)
51 | .call();
52 | const b = await supplyChainContract.methods
53 | .fetchProductPart2(i, "product", 0)
54 | .call();
55 | const c = await supplyChainContract.methods
56 | .fetchProductPart3(i, "product", 0)
57 | .call();
58 | prodData.push(a);
59 | prodData.push(b);
60 | prodData.push(c);
61 | arr.push(prodData);
62 | }
63 | }
64 | setAllReceiveProducts(arr);
65 | setLoading(false);
66 | })();
67 | }, [count]);
68 |
69 | const handleReceiveButton = async (id) => {
70 | try{
71 | await supplyChainContract.methods
72 | .receiveByCustomer(parseInt(id))
73 | .send({ from: roles.customer, gas: 1000000 })
74 | .on("transactionHash", function (hash) {
75 | handleSetTxhash(id, hash);
76 | });
77 | setCount(0);
78 | setOpen(false);
79 | }catch{
80 | setalertText("You are not the owner of the Product");
81 | }
82 |
83 | };
84 |
85 | const handleSetTxhash = async (id, hash) => {
86 | await supplyChainContract.methods
87 | .setTransactionHash(id, hash)
88 | .send({ from: roles.manufacturer, gas: 900000 });
89 | };
90 |
91 | const [page, setPage] = React.useState(0);
92 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
93 |
94 | const handleChangePage = (event, newPage) => {
95 | setPage(newPage);
96 | };
97 |
98 | const handleChangeRowsPerPage = (event) => {
99 | setRowsPerPage(+event.target.value);
100 | setPage(0);
101 | };
102 |
103 | const handleClose = () => setOpen(false);
104 |
105 | const handleClick = async (prod) => {
106 | await setModalData(prod);
107 | setOpen(true);
108 | };
109 |
110 | return (
111 |
112 |
113 | {loading ? (
114 |
115 | ) : (
116 | <>
117 |
124 |
125 | Products to be Received
126 |
127 | Total : {allReceiveProducts.length}
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | Universal ID
138 |
139 |
140 | Product Code
141 |
142 |
143 | Manufacturer
144 |
145 |
146 | Manufacture Date
147 |
148 |
149 | Product Name
150 |
151 |
158 | Owner
159 |
160 |
164 | RECEIVE
165 |
166 |
167 |
168 |
169 | {allReceiveProducts.length !== 0 ? (
170 | allReceiveProducts
171 | .slice(
172 | page * rowsPerPage,
173 | page * rowsPerPage + rowsPerPage
174 | )
175 | .map((prod) => {
176 | const d = new Date(parseInt(prod[1][0] * 1000));
177 | return (
178 | <>
179 |
185 | handleClick(prod)}
191 | >
192 | {prod[0][0]}
193 |
194 | handleClick(prod)}
198 | >
199 | {prod[1][2]}
200 |
201 | handleClick(prod)}
205 | >
206 | {prod[0][4]}
207 |
208 | handleClick(prod)}
211 | >
212 | {d.toDateString() + " " + d.toTimeString()}
213 |
214 | handleClick(prod)}
218 | >
219 | {prod[1][1]}
220 |
221 | handleClick(prod)}
228 | >
229 | {prod[0][2]}
230 |
231 |
235 | handleClick(prod)}
240 | >
241 | RECEIVE
242 |
243 |
244 |
245 | >
246 | );
247 | })
248 | ) : (
249 | <> >
250 | )}
251 |
252 |
253 |
254 |
263 |
264 |
265 |
266 | {/* {allReceiveProducts.length !== 0 ? (allReceiveProducts.map((prod) => (
267 | <>
268 |
269 |
Universal ID : {prod[0][0]}
270 |
SKU : {prod[0][1]}
271 |
Owner : {prod[0][2]}
272 |
Manufacturer : {prod[0][3]}
273 |
Name of Manufacturer : {prod[0][4]}
274 |
Details of Manufacturer : {prod[0][5]}
275 |
Longitude of Manufature : {prod[0][6]}
276 |
Latitude of Manufature : {prod[0][7]}
277 |
278 |
Manufactured date : {prod[1][0]}
279 |
handleClick(prod)}
284 | >
285 | Recieve
286 |
287 |
288 |
289 | >
290 | ))) : <> >} */}
291 | >
292 | )}
293 |
294 |
295 | );
296 | }
297 |
--------------------------------------------------------------------------------
/client/src/pages/Customer/ReceivedByCustomer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Table from "@material-ui/core/Table";
4 | import TableBody from "@material-ui/core/TableBody";
5 | import TableCell from "@material-ui/core/TableCell";
6 | import TableContainer from "@material-ui/core/TableContainer";
7 | import TableHead from "@material-ui/core/TableHead";
8 | import TableRow from "@material-ui/core/TableRow";
9 | import Paper from "@material-ui/core/Paper";
10 | import TablePagination from "@material-ui/core/TablePagination";
11 | import { useStyles } from "../../components/Styles";
12 | import ProductModal from "../../components/Modal";
13 | import clsx from "clsx";
14 | import Loader from "../../components/Loader";
15 |
16 | export default function ReceivedByCustomer(props) {
17 | const classes = useStyles();
18 | const supplyChainContract = props.supplyChainContract;
19 | const [count, setCount] = React.useState(0);
20 | const [allReceived, setAllReceived] = React.useState([]);
21 | const [loading, setLoading] = React.useState(false);
22 | const navItem = [
23 | ["Purchase Product", "/Customer/buy"],
24 | ["Receive Product", "/Customer/receive"],
25 | ["Your Products", "/Customer/allReceived"],
26 | ];
27 | React.useEffect(() => {
28 | (async () => {
29 | setLoading(true);
30 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
31 | setCount(cnt);
32 | })();
33 |
34 | (async () => {
35 | const arr = [];
36 | for (var i = 1; i < count; i++) {
37 | const prodState = await supplyChainContract.methods
38 | .fetchProductState(i)
39 | .call();
40 |
41 | if (prodState === "8") {
42 | const prodData = [];
43 | const a = await supplyChainContract.methods
44 | .fetchProductPart1(i, "product", 0)
45 | .call();
46 | const b = await supplyChainContract.methods
47 | .fetchProductPart2(i, "product", 0)
48 | .call();
49 | const c = await supplyChainContract.methods
50 | .fetchProductPart3(i, "product", 0)
51 | .call();
52 | prodData.push(a);
53 | prodData.push(b);
54 | prodData.push(c);
55 | arr.push(prodData);
56 | }
57 | }
58 | setAllReceived(arr);
59 | setLoading(false);
60 | })();
61 | }, [count]);
62 |
63 | const [page, setPage] = React.useState(0);
64 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
65 |
66 | const handleChangePage = (event, newPage) => {
67 | setPage(newPage);
68 | };
69 |
70 | const handleChangeRowsPerPage = (event) => {
71 | setRowsPerPage(+event.target.value);
72 | setPage(0);
73 | };
74 |
75 | const [open, setOpen] = React.useState(false);
76 | const [modalData, setModalData] = React.useState([]);
77 |
78 | const handleClose = () => setOpen(false);
79 |
80 | const handleClick = async (prod) => {
81 | await setModalData(prod);
82 | setOpen(true);
83 | };
84 |
85 | return (
86 | <>
87 |
88 |
89 | {loading ? (
90 |
91 | ) : (
92 | <>
93 |
98 | Your Products
99 |
100 | Total : {allReceived.length}
101 |
102 | <>
103 |
104 |
105 |
106 |
107 |
108 |
109 |
113 | Universal ID
114 |
115 |
119 | Product Code
120 |
121 |
125 | Manufacturer
126 |
127 |
131 | Manufacture Date
132 |
133 |
137 | Product Name
138 |
139 |
146 | Owner
147 |
148 |
149 |
150 |
151 | {allReceived.length !== 0 ? (
152 | allReceived
153 | .slice(
154 | page * rowsPerPage,
155 | page * rowsPerPage + rowsPerPage
156 | )
157 | .map((prod) => {
158 | const d = new Date(parseInt(prod[1][0] * 1000));
159 | return (
160 | handleClick(prod)}
166 | >
167 |
173 | {prod[0][0]}
174 |
175 |
179 | {prod[1][2]}
180 |
181 |
185 | {prod[0][4]}
186 |
187 |
188 | {d.toDateString() +
189 | " " +
190 | d.toTimeString()}
191 |
192 |
196 | {prod[1][1]}
197 |
198 |
205 | {prod[0][2]}
206 |
207 |
208 | );
209 | })
210 | ) : (
211 | <> >
212 | )}
213 |
214 |
215 |
216 |
225 |
226 |
227 | >
228 | >
229 | )}
230 |
231 |
232 | >
233 | );
234 | }
235 |
--------------------------------------------------------------------------------
/client/src/pages/DeliveryHub/ReceiveDeliveryHub.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import ProductModal from "../../components/Modal";
5 | import { useRole } from "../../context/RoleDataContext";
6 | import Table from "@material-ui/core/Table";
7 | import TableBody from "@material-ui/core/TableBody";
8 | import TableCell from "@material-ui/core/TableCell";
9 | import TableContainer from "@material-ui/core/TableContainer";
10 | import TableHead from "@material-ui/core/TableHead";
11 | import TableRow from "@material-ui/core/TableRow";
12 | import Paper from "@material-ui/core/Paper";
13 | import TablePagination from "@material-ui/core/TablePagination";
14 | import { useStyles } from "../../components/Styles";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function ReceiveDeliveryHub(props) {
19 | const supplyChainContract = props.supplyChainContract;
20 | const { roles } = useRole();
21 | const [count, setCount] = React.useState(0);
22 | const [allReceiveProducts, setAllReceiveProducts] = React.useState([]);
23 | const [modalData, setModalData] = useState([]);
24 | const [open, setOpen] = useState(false);
25 | const classes = useStyles();
26 | const [loading, setLoading] = React.useState(false);
27 | const navItem = [
28 | ["Receive Product", "/DeliveryHub/receive"],
29 | ["Ship Product", "/DeliveryHub/ship"],
30 | ];
31 | const [alertText, setalertText] = React.useState("");
32 | React.useEffect(() => {
33 | (async () => {
34 | setLoading(true);
35 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
36 | setCount(cnt);
37 | })();
38 |
39 | (async () => {
40 | const arr = [];
41 | for (var i = 1; i < count; i++) {
42 | const prodState = await supplyChainContract.methods
43 | .fetchProductState(i)
44 | .call();
45 |
46 | if (prodState === "5") {
47 | const prodData = [];
48 | const a = await supplyChainContract.methods
49 | .fetchProductPart1(i, "product", 0)
50 | .call();
51 | const b = await supplyChainContract.methods
52 | .fetchProductPart2(i, "product", 0)
53 | .call();
54 | const c = await supplyChainContract.methods
55 | .fetchProductPart3(i, "product", 0)
56 | .call();
57 | prodData.push(a);
58 | prodData.push(b);
59 | prodData.push(c);
60 | arr.push(prodData);
61 | }
62 | }
63 | setAllReceiveProducts(arr);
64 | setLoading(false);
65 | })();
66 | }, [count]);
67 |
68 | const handleSetTxhash = async (id, hash) => {
69 | await supplyChainContract.methods
70 | .setTransactionHash(id, hash)
71 | .send({ from: roles.manufacturer, gas: 900000 });
72 | };
73 |
74 | const handleReceiveButton = async (id, long, lat) => {
75 | try{
76 | await supplyChainContract.methods
77 | .receiveByDeliveryHub(parseInt(id), long, lat)
78 | .send({ from: roles.deliveryhub, gas: 1000000 })
79 | .on("transactionHash", function (hash) {
80 | handleSetTxhash(id, hash);
81 | });
82 | setCount(0);
83 | setOpen(false);
84 | }catch{
85 | setalertText("You are not the owner of the Product");
86 | }
87 |
88 | };
89 |
90 | const [page, setPage] = React.useState(0);
91 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
92 |
93 | const handleChangePage = (event, newPage) => {
94 | setPage(newPage);
95 | };
96 |
97 | const handleChangeRowsPerPage = (event) => {
98 | setRowsPerPage(+event.target.value);
99 | setPage(0);
100 | };
101 |
102 | const handleClose = () => setOpen(false);
103 |
104 | const handleClick = async (prod) => {
105 | await setModalData(prod);
106 |
107 | setOpen(true);
108 | };
109 |
110 | return (
111 |
112 |
113 | {loading ? (
114 |
115 | ) : (
116 | <>
117 |
124 |
125 | Products To be Received
126 |
127 | Total : {allReceiveProducts.length}
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | Universal ID
138 |
139 |
140 | Product Code
141 |
142 |
143 | Manufacturer
144 |
145 |
146 | Manufacture Date
147 |
148 |
149 | Product Name
150 |
151 |
158 | Owner
159 |
160 |
164 | RECEIVE
165 |
166 |
167 |
168 |
169 | {allReceiveProducts.length !== 0 ? (
170 | allReceiveProducts
171 | .slice(
172 | page * rowsPerPage,
173 | page * rowsPerPage + rowsPerPage
174 | )
175 | .map((prod) => {
176 | const d = new Date(parseInt(prod[1][0] * 1000));
177 | return (
178 | <>
179 |
185 | handleClick(prod)}
191 | >
192 | {prod[0][0]}
193 |
194 | handleClick(prod)}
198 | >
199 | {prod[1][2]}
200 |
201 | handleClick(prod)}
205 | >
206 | {prod[0][4]}
207 |
208 | handleClick(prod)}
211 | >
212 | {d.toDateString() + " " + d.toTimeString()}
213 |
214 | handleClick(prod)}
218 | >
219 | {prod[1][1]}
220 |
221 | handleClick(prod)}
228 | >
229 | {prod[0][2]}
230 |
231 |
235 | handleClick(prod)}
240 | >
241 | RECEIVE
242 |
243 |
244 |
245 | >
246 | );
247 | })
248 | ) : (
249 | <> >
250 | )}
251 |
252 |
253 |
254 |
263 |
264 |
265 |
266 | {/* {allReceiveProducts.length !== 0 ? (allReceiveProducts.map((prod) => (
267 | <>
268 |
269 |
Universal ID : {prod[0][0]}
270 |
SKU : {prod[0][1]}
271 |
Owner : {prod[0][2]}
272 |
Manufacturer : {prod[0][3]}
273 |
Name of Manufacturer : {prod[0][4]}
274 |
Details of Manufacturer : {prod[0][5]}
275 |
Longitude of Manufature : {prod[0][6]}
276 |
Latitude of Manufature : {prod[0][7]}
277 |
278 |
Manufactured date : {prod[1][0]}
279 |
handleClick(prod)}
284 | >
285 | Recieve
286 |
287 |
288 |
289 | >
290 | ))) : <> >} */}
291 | >
292 | )}
293 |
294 |
295 | );
296 | }
297 |
--------------------------------------------------------------------------------
/client/src/pages/DeliveryHub/ShipDeliveryHub.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Table from "@material-ui/core/Table";
6 | import TableBody from "@material-ui/core/TableBody";
7 | import TableCell from "@material-ui/core/TableCell";
8 | import TableContainer from "@material-ui/core/TableContainer";
9 | import TableHead from "@material-ui/core/TableHead";
10 | import TableRow from "@material-ui/core/TableRow";
11 | import Paper from "@material-ui/core/Paper";
12 | import TablePagination from "@material-ui/core/TablePagination";
13 | import { useStyles } from "../../components/Styles";
14 | import ProductModal from "../../components/Modal";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function ShipDeliveryHub(props) {
19 | const classes = useStyles();
20 | const supplyChainContract = props.supplyChainContract;
21 | const { roles } = useRole();
22 | const [count, setCount] = React.useState(0);
23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]);
24 | const [loading, setLoading] = React.useState(false);
25 | const navItem = [
26 | ["Receive Product", "/DeliveryHub/receive"],
27 | ["Ship Product", "/DeliveryHub/ship"],
28 | ];
29 | const [alertText, setalertText] = React.useState("");
30 | React.useEffect(() => {
31 | (async () => {
32 | setLoading(true);
33 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
34 | setCount(cnt);
35 | })();
36 |
37 | (async () => {
38 | const arr = [];
39 | for (var i = 1; i < count; i++) {
40 | const prodState = await supplyChainContract.methods
41 | .fetchProductState(i)
42 | .call();
43 |
44 | if (prodState === "6") {
45 | const prodData = [];
46 | const a = await supplyChainContract.methods
47 | .fetchProductPart1(i, "product", 0)
48 | .call();
49 | const b = await supplyChainContract.methods
50 | .fetchProductPart2(i, "product", 0)
51 | .call();
52 | const c = await supplyChainContract.methods
53 | .fetchProductPart3(i, "product", 0)
54 | .call();
55 | prodData.push(a);
56 | prodData.push(b);
57 | prodData.push(c);
58 | arr.push(prodData);
59 | }
60 | }
61 | setAllSoldProducts(arr);
62 | setLoading(false);
63 | })();
64 | }, [count]);
65 |
66 | const handleSetTxhash = async (id, hash) => {
67 | await supplyChainContract.methods
68 | .setTransactionHash(id, hash)
69 | .send({ from: roles.manufacturer, gas: 900000 });
70 | };
71 |
72 | const handleShipButton = async (id) => {
73 | try{
74 | await supplyChainContract.methods
75 | .shipByDeliveryHub(id)
76 | .send({ from: roles.deliveryhub, gas: 1000000 })
77 | .on("transactionHash", function (hash) {
78 | handleSetTxhash(id, hash);
79 | });
80 | setCount(0);
81 | }catch{
82 | setalertText("You are not the owner of the Product");
83 | }
84 | };
85 | const [page, setPage] = React.useState(0);
86 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
87 |
88 | const handleChangePage = (event, newPage) => {
89 | setPage(newPage);
90 | };
91 |
92 | const handleChangeRowsPerPage = (event) => {
93 | setRowsPerPage(+event.target.value);
94 | setPage(0);
95 | };
96 |
97 | const [open, setOpen] = React.useState(false);
98 | const [modalData, setModalData] = React.useState([]);
99 |
100 | const handleClose = () => setOpen(false);
101 |
102 | const handleClick = async (prod) => {
103 | await setModalData(prod);
104 | setOpen(true);
105 | };
106 |
107 | return (
108 | <>
109 |
110 |
111 | {loading ? (
112 |
113 | ) : (
114 | <>
115 |
120 | Products To be Shipped
121 |
122 | Total : {allSoldProducts.length}
123 |
124 |
125 |
126 |
{alertText.length !== 0 ? alertText : ""}
127 |
128 |
129 |
130 |
131 |
132 |
133 | Universal ID
134 |
135 |
139 | Product Code
140 |
141 |
145 | Manufacturer
146 |
147 |
151 | Manufacture Date
152 |
153 |
157 | Product Name
158 |
159 |
166 | Owner
167 |
168 |
172 | Ship
173 |
174 |
175 |
176 |
177 | {allSoldProducts.length !== 0 ? (
178 | allSoldProducts
179 | .slice(
180 | page * rowsPerPage,
181 | page * rowsPerPage + rowsPerPage
182 | )
183 | .map((prod) => {
184 | const d = new Date(parseInt(prod[1][0] * 1000));
185 | return (
186 | <>
187 |
193 | handleClick(prod)}
199 | >
200 | {prod[0][0]}
201 |
202 | handleClick(prod)}
206 | >
207 | {prod[1][2]}
208 |
209 | handleClick(prod)}
213 | >
214 | {prod[0][4]}
215 |
216 | handleClick(prod)}
219 | >
220 | {d.toDateString() +
221 | " " +
222 | d.toTimeString()}
223 |
224 | handleClick(prod)}
228 | >
229 | {prod[1][1]}
230 |
231 | handleClick(prod)}
238 | >
239 | {prod[0][2]}
240 |
241 |
245 |
250 | handleShipButton(prod[0][0])
251 | }
252 | >
253 | SHIP
254 |
255 |
256 |
257 | >
258 | );
259 | })
260 | ) : (
261 | <> >
262 | )}
263 |
264 |
265 |
266 |
275 |
276 |
277 | >
278 | )}
279 |
280 |
281 | >
282 | );
283 | }
284 |
--------------------------------------------------------------------------------
/client/src/pages/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useStyles } from "../components/Styles";
5 | import Grid from "@material-ui/core/Grid";
6 | import { Link } from "react-router-dom";
7 |
8 | export default function Home() {
9 | const classes = useStyles();
10 | const navItem = [];
11 |
12 | return (
13 | <>
14 |
15 |
16 |
21 |
34 |
39 |
40 |
41 |
55 |
56 |
Assign Roles
57 |
61 |
67 | Assign
68 |
69 |
70 |
71 |
72 | Visit As
73 |
77 |
83 | Manufacturer
84 |
85 |
86 |
90 |
96 | Third party
97 |
98 |
99 |
103 |
109 | delivery hub
110 |
111 |
112 |
116 |
122 | customer
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | >
131 | );
132 | }
133 |
--------------------------------------------------------------------------------
/client/src/pages/Manufacturer/AllManufacture.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Table from "@material-ui/core/Table";
4 | import TableBody from "@material-ui/core/TableBody";
5 | import TableCell from "@material-ui/core/TableCell";
6 | import TableContainer from "@material-ui/core/TableContainer";
7 | import TableHead from "@material-ui/core/TableHead";
8 | import TableRow from "@material-ui/core/TableRow";
9 | import Paper from "@material-ui/core/Paper";
10 | import TablePagination from "@material-ui/core/TablePagination";
11 | import { useStyles } from "../../components/Styles";
12 | import ProductModal from "../../components/Modal";
13 | import clsx from "clsx";
14 | import Loader from "../../components/Loader";
15 |
16 | export default function AllManufacture(props) {
17 | const supplyChainContract = props.supplyChainContract;
18 | const classes = useStyles();
19 | const [count, setCount] = React.useState(0);
20 | const [allManufacture, setAllManufacture] = React.useState([]);
21 | const [loading, setLoading] = React.useState(false);
22 | const navItem = [
23 | ["Add Product", "/manufacturer/manufacture"],
24 | ["Ship Product", "/manufacturer/ship"],
25 | ["All Products", "/manufacturer/allManufacture"],
26 | ];
27 | React.useEffect(() => {
28 | setLoading(true);
29 | (async () => {
30 | setLoading(true);
31 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
32 | setCount(cnt);
33 | })();
34 |
35 | (async () => {
36 | const arr = [];
37 | for (var i = 1; i < count; i++) {
38 | const prodState = await supplyChainContract.methods
39 | .fetchProductState(i)
40 | .call();
41 |
42 | if (prodState === "0") {
43 | const prodData = [];
44 | const a = await supplyChainContract.methods
45 | .fetchProductPart1(i, "product", 0)
46 | .call();
47 | const b = await supplyChainContract.methods
48 | .fetchProductPart2(i, "product", 0)
49 | .call();
50 | const c = await supplyChainContract.methods
51 | .fetchProductPart3(i, "product", 0)
52 | .call();
53 | prodData.push(a);
54 | prodData.push(b);
55 | prodData.push(c);
56 | arr.push(prodData);
57 | }
58 | }
59 | setAllManufacture(arr);
60 | setLoading(false);
61 | })();
62 | }, [count]);
63 |
64 | const [page, setPage] = React.useState(0);
65 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
66 |
67 | const handleChangePage = (event, newPage) => {
68 | setPage(newPage);
69 | };
70 |
71 | const handleChangeRowsPerPage = (event) => {
72 | setRowsPerPage(+event.target.value);
73 | setPage(0);
74 | };
75 |
76 | const [open, setOpen] = React.useState(false);
77 | const [modalData, setModalData] = React.useState([]);
78 |
79 | const handleClose = () => setOpen(false);
80 |
81 | const handleClick = async (prod) => {
82 | await setModalData(prod);
83 | setOpen(true);
84 | };
85 |
86 | return (
87 |
88 |
89 | {loading ? (
90 |
91 | ) : (
92 |
93 |
98 |
Manufactured Products
99 |
100 | Total : {allManufacture.length}
101 |
102 | <>
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | Universal ID
111 |
112 |
116 | Product Code
117 |
118 |
122 | Manufacturer
123 |
124 |
128 | Manufacture Date
129 |
130 |
134 | Product Name
135 |
136 |
143 | Owner
144 |
145 |
146 |
147 |
148 | {allManufacture.length !== 0 ? (
149 | allManufacture
150 | .slice(
151 | page * rowsPerPage,
152 | page * rowsPerPage + rowsPerPage
153 | )
154 | .map((prod) => {
155 | const d = new Date(parseInt(prod[1][0] * 1000));
156 | return (
157 | handleClick(prod)}
163 | >
164 |
170 | {prod[0][0]}
171 |
172 |
176 | {prod[1][2]}
177 |
178 |
182 | {prod[0][4]}
183 |
184 |
185 | {d.toDateString() + " " + d.toTimeString()}
186 |
187 |
191 | {prod[1][1]}
192 |
193 |
200 | {prod[0][2]}
201 |
202 |
203 | );
204 | })
205 | ) : (
206 | <> >
207 | )}
208 |
209 |
210 |
211 |
220 |
221 |
222 | >
223 |
224 | )}
225 |
226 |
227 | );
228 | }
229 |
--------------------------------------------------------------------------------
/client/src/pages/Manufacturer/Manufacture.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import TextField from "@material-ui/core/TextField";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Navbar from "../../components/Navbar";
6 | import { useStyles } from "../../components/Styles";
7 | import Grid from "@material-ui/core/Grid";
8 | import Loader from "../../components/Loader";
9 |
10 | export default function Manufacture(props) {
11 | const supplyChainContract = props.supplyChainContract;
12 | const classes = useStyles();
13 | const { roles } = useRole();
14 | const [loading, setLoading] = React.useState(false);
15 | const [fvalid, setfvalid] = React.useState(false);
16 | const navItem = [
17 | ["Add Product", "/manufacturer/manufacture"],
18 | ["Ship Product", "/manufacturer/ship"],
19 | ["All Products", "/manufacturer/allManufacture"],
20 | ];
21 | const [manuForm, setManuForm] = React.useState({
22 | id: 0,
23 | manufacturerName: "",
24 | manufacturerDetails: "",
25 | manufacturerLongitude: "",
26 | manufacturerLatitude: "",
27 | productName: "",
28 | productCode: 0,
29 | productPrice: 0,
30 | productCategory: "",
31 | });
32 |
33 | const handleChangeManufacturerForm = async (e) => {
34 | setManuForm({
35 | ...manuForm,
36 | [e.target.name]: e.target.value,
37 | });
38 | };
39 |
40 | const handleSubmitManufacturerForm = async () => {
41 | setLoading(true);
42 |
43 | if (manuForm.manufacturerName !== "" && manuForm.manufacturerDetails !== "" && manuForm.manufacturerLongitude !== "" && manuForm.manufacturerLatitude !== "" && manuForm.productName !== "" && manuForm.productCode !== 0 && manuForm.productPrice !== 0 && manuForm.productCategory !== "") {
44 | setfvalid(false);
45 | await supplyChainContract.methods.manufactureProduct(manuForm.manufacturerName, manuForm.manufacturerDetails, manuForm.manufacturerLongitude, manuForm.manufacturerLatitude, manuForm.productName, parseInt(manuForm.productCode), parseInt(manuForm.productPrice), manuForm.productCategory).send({ from: roles.manufacturer, gas: 999999 })
46 | // .then(console.log)
47 | .on('transactionHash', function (hash) {
48 | handleSetTxhash(hash);
49 | });
50 | setManuForm({
51 | id: 0,
52 | manufacturerName: "",
53 | manufacturerDetails: "",
54 | manufacturerLongitude: "",
55 | manufacturerLatitude: "",
56 | productName: "",
57 | productCode: 0,
58 | productPrice: 0,
59 | productCategory: "",
60 | })
61 | } else {
62 | setfvalid(true);
63 | }
64 | setLoading(false);
65 | };
66 |
67 | const handleSetTxhash = async (hash) => {
68 | await supplyChainContract.methods
69 | .setTransactionHashOnManufacture(hash)
70 | .send({ from: roles.manufacturer, gas: 900000 });
71 | };
72 |
73 | const createProduct = async () => {
74 | setLoading(true);
75 | for (var i = 0; i < 5; i++) {
76 | await supplyChainContract.methods
77 | .manufactureProduct(
78 | "product" + i,
79 | "manufacturer" + 1,
80 | "98",
81 | "89",
82 | "mi" + i,
83 | 99 + i,
84 | 12000,
85 | "electronics"
86 | )
87 | .send({ from: roles.manufacturer, gas: 999999 })
88 | .on("transactionHash", function (hash) {
89 | handleSetTxhash(hash);
90 | });
91 | }
92 | setLoading(false);
93 | };
94 |
95 | return (
96 | <>
97 |
98 | {loading ? (
99 |
100 | ) : (
101 | <>
102 |
103 |
Add Product
104 |
105 |
106 |
115 |
116 |
117 |
126 |
127 |
128 |
137 |
138 |
139 |
148 |
149 |
150 |
159 |
160 |
161 |
170 |
171 |
172 |
181 |
182 |
183 |
192 |
193 |
194 |
195 |
{fvalid ? "Please enter all data" : ""}
196 |
202 | SUBMIT
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | >
211 | )}
212 |
213 | >
214 | );
215 | }
216 |
--------------------------------------------------------------------------------
/client/src/pages/Manufacturer/ShipManufacture.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Table from "@material-ui/core/Table";
6 | import TableBody from "@material-ui/core/TableBody";
7 | import TableCell from "@material-ui/core/TableCell";
8 | import TableContainer from "@material-ui/core/TableContainer";
9 | import TableHead from "@material-ui/core/TableHead";
10 | import TableRow from "@material-ui/core/TableRow";
11 | import Paper from "@material-ui/core/Paper";
12 | import TablePagination from "@material-ui/core/TablePagination";
13 | import { useStyles } from "../../components/Styles";
14 | import ProductModal from "../../components/Modal";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function ShipManufacture(props) {
19 | const supplyChainContract = props.supplyChainContract;
20 | const { roles } = useRole();
21 | const classes = useStyles();
22 | const [count, setCount] = React.useState(0);
23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]);
24 | const [loading, setLoading] = React.useState(false);
25 | const navItem = [
26 | ["Add Product", "/manufacturer/manufacture"],
27 | ["Ship Product", "/manufacturer/ship"],
28 | ["All Products", "/manufacturer/allManufacture"],
29 | ];
30 | const [alertText, setalertText] = React.useState("");
31 | React.useEffect(() => {
32 | (async () => {
33 | setLoading(true);
34 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
35 | setCount(cnt);
36 |
37 | })();
38 |
39 | (async () => {
40 | const arr = [];
41 | for (var i = 1; i < count; i++) {
42 | const prodState = await supplyChainContract.methods
43 | .fetchProductState(i)
44 | .call();
45 |
46 | if (prodState === "1") {
47 | const prodData = [];
48 | const a = await supplyChainContract.methods
49 | .fetchProductPart1(i, "product", 0)
50 | .call();
51 | const b = await supplyChainContract.methods
52 | .fetchProductPart2(i, "product", 0)
53 | .call();
54 | const c = await supplyChainContract.methods
55 | .fetchProductPart3(i, "product", 0)
56 | .call();
57 | prodData.push(a);
58 | prodData.push(b);
59 | prodData.push(c);
60 | arr.push(prodData);
61 | }
62 | }
63 | setAllSoldProducts(arr);
64 | setLoading(false);
65 | })();
66 | }, [count]);
67 |
68 | const [page, setPage] = React.useState(0);
69 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
70 |
71 | const handleChangePage = (event, newPage) => {
72 | setPage(newPage);
73 | };
74 |
75 | const handleChangeRowsPerPage = (event) => {
76 | setRowsPerPage(+event.target.value);
77 | setPage(0);
78 | };
79 |
80 | const [open, setOpen] = React.useState(false);
81 | const [modalData, setModalData] = React.useState([]);
82 |
83 | const handleClose = () => setOpen(false);
84 |
85 | const handleClick = async (prod) => {
86 | await setModalData(prod);
87 | setOpen(true);
88 | };
89 |
90 | const handleSetTxhash = async (id, hash) => {
91 | await supplyChainContract.methods
92 | .setTransactionHash(id, hash)
93 | .send({ from: roles.manufacturer, gas: 900000 });
94 | };
95 |
96 | const handleShipButton = async (id) => {
97 | try{
98 | await supplyChainContract.methods
99 | .shipToThirdParty(id)
100 | .send({ from: roles.manufacturer, gas: 1000000 })
101 | .on("transactionHash", function (hash) {
102 | handleSetTxhash(id, hash);
103 | });
104 | setCount(0);
105 | }catch{
106 | setalertText("You are not the owner of the Product");
107 | }
108 |
109 | };
110 |
111 | return (
112 |
113 |
114 | {loading ? (
115 |
116 | ) : (
117 | <>
118 |
123 | Products To be Shipped
124 |
125 | Total : {allSoldProducts.length}
126 |
127 |
128 |
129 |
{alertText.length !== 0 ? alertText : ""}
130 |
131 |
132 |
133 |
134 |
135 |
136 | Universal ID
137 |
138 |
139 | Product Code
140 |
141 |
142 | Manufacturer
143 |
144 |
145 | Manufacture Date
146 |
147 |
148 | Product Name
149 |
150 |
157 | Owner
158 |
159 |
163 | Ship
164 |
165 |
166 |
167 |
168 | {allSoldProducts.length !== 0 ? (
169 | allSoldProducts
170 | .slice(
171 | page * rowsPerPage,
172 | page * rowsPerPage + rowsPerPage
173 | )
174 | .map((prod) => {
175 | const d = new Date(parseInt(prod[1][0] * 1000));
176 | return (
177 | <>
178 |
184 | handleClick(prod)}
190 | >
191 | {prod[0][0]}
192 |
193 | handleClick(prod)}
197 | >
198 | {prod[1][2]}
199 |
200 | handleClick(prod)}
204 | >
205 | {prod[0][4]}
206 |
207 | handleClick(prod)}
210 | >
211 | {d.toDateString() + " " + d.toTimeString()}
212 |
213 | handleClick(prod)}
217 | >
218 | {prod[1][1]}
219 |
220 | handleClick(prod)}
227 | >
228 | {prod[0][2]}
229 |
230 |
234 |
239 | handleShipButton(prod[0][0])
240 | }
241 | >
242 | SHIP
243 |
244 |
245 |
246 | >
247 | );
248 | })
249 | ) : (
250 | <> >
251 | )}
252 |
253 |
254 |
255 |
264 |
265 |
266 |
267 | {/* {allSoldProducts.length !== 0 ? (
268 | allSoldProducts.map((prod) => (
269 | <>
270 |
271 |
Universal ID : {prod[0][0]}
272 |
SKU : {prod[0][1]}
273 |
Owner : {prod[0][2]}
274 |
Manufacturer : {prod[0][3]}
275 |
Name of Manufacturer : {prod[0][4]}
276 |
Details of Manufacturer : {prod[0][5]}
277 |
Longitude of Manufature : {prod[0][6]}
278 |
Latitude of Manufature : {prod[0][7]}
279 |
280 |
Manufactured date : {prod[1][0]}
281 |
handleShipButton(prod[0][0])}
286 | >
287 | SHIP
288 |
289 |
290 | >
291 | ))
292 | ) : (
293 | <> >
294 | )} */}
295 | >
296 | )}
297 |
298 |
299 | );
300 | }
301 |
--------------------------------------------------------------------------------
/client/src/pages/RoleAdmin.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ResponsiveDrawer from "../components/Navbar";
3 | import TextField from "@material-ui/core/TextField";
4 | import Button from "@material-ui/core/Button";
5 | import { useRole } from "../context/RoleDataContext";
6 | import { useStyles } from "../components/Styles";
7 |
8 | function RoleAdmin(props) {
9 | const accounts = props.accounts;
10 | const supplyChainContract = props.supplyChainContract;
11 | const { roles, setRoles } = useRole();
12 |
13 | const classes = useStyles();
14 | const [manufacturerRole, setManufacturerRole] = React.useState("");
15 | const [thirdPartyRole, setThirdPartyRole] = React.useState("");
16 | const [deliveryHubRole, setDeliveryHubRole] = React.useState("");
17 | const [customerRole, setCustomerRole] = React.useState("");
18 | const navItem = [];
19 |
20 | const handleAddManufacturerRole = async () => {
21 | await setRoles({
22 | ...roles,
23 | manufacturer : manufacturerRole
24 | })
25 |
26 | localStorage.setItem("mRole", manufacturerRole);
27 | await supplyChainContract.methods.addManufacturerRole(manufacturerRole).send({ from: accounts[0], gas:100000 })
28 | .then(console.log);
29 |
30 |
31 |
32 | setManufacturerRole("");
33 | }
34 |
35 | const handleAddThirdPartyRole = async () => {
36 | await setRoles({
37 | ...roles,
38 | thirdparty : thirdPartyRole
39 | })
40 |
41 | localStorage.setItem("tpRole", thirdPartyRole);
42 | await supplyChainContract.methods.addThirdPartyRole(thirdPartyRole).send({ from: accounts[0], gas:100000 })
43 | .then(console.log);
44 |
45 |
46 |
47 | setThirdPartyRole("");
48 | }
49 |
50 | const handleAddDeliveryHubRole = async () => {
51 | await setRoles({
52 | ...roles,
53 | deliveryhub : deliveryHubRole
54 | })
55 |
56 | localStorage.setItem("dhRole", deliveryHubRole);
57 | await supplyChainContract.methods.addDeliveryHubRole(deliveryHubRole).send({ from: accounts[0], gas:100000 })
58 | .then(console.log);
59 |
60 |
61 |
62 | setDeliveryHubRole("");
63 | }
64 |
65 | const handleAddCustomerRole = async () => {
66 | await setRoles({
67 | ...roles,
68 | customer : customerRole
69 | })
70 |
71 | localStorage.setItem("cRole", customerRole);
72 | await supplyChainContract.methods.addCustomerRole(customerRole).send({ from: accounts[0], gas:100000 })
73 | .then(console.log);
74 |
75 |
76 |
77 | setCustomerRole("");
78 | }
79 |
80 |
81 | return (
82 |
83 |
84 |
85 |
Add Roles
86 | {console.log(roles)}
87 |
88 |
108 |
109 |
129 |
130 |
150 |
151 |
171 |
172 |
173 |
Local Accounts
174 | {accounts.slice(1).map((acc) => (
175 | {acc}
176 | ))}
177 |
178 |
179 |
180 |
181 |
182 | );
183 | }
184 |
185 | export default RoleAdmin;
186 |
--------------------------------------------------------------------------------
/client/src/pages/ThirdParty/PurshaseThirdParty.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Table from "@material-ui/core/Table";
6 | import TableBody from "@material-ui/core/TableBody";
7 | import TableCell from "@material-ui/core/TableCell";
8 | import TableContainer from "@material-ui/core/TableContainer";
9 | import TableHead from "@material-ui/core/TableHead";
10 | import TableRow from "@material-ui/core/TableRow";
11 | import Paper from "@material-ui/core/Paper";
12 | import TablePagination from "@material-ui/core/TablePagination";
13 | import { useStyles } from "../../components/Styles";
14 | import ProductModal from "../../components/Modal";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function PurchaseThirdParty(props) {
19 | const classes = useStyles();
20 | const supplyChainContract = props.supplyChainContract;
21 | const { roles } = useRole();
22 | const [count, setCount] = React.useState(0);
23 | const [allProducts, setAllProducts] = React.useState([]);
24 | const [loading, setLoading] = React.useState(false);
25 | const navItem = [
26 | ["Buy Product", "/ThirdParty/allProducts"],
27 | ["Receive Product", "/ThirdParty/receive"],
28 | ["Ship Products", "/ThirdParty/ship"],
29 | ];
30 | React.useEffect(() => {
31 | (async () => {
32 | setLoading(true);
33 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
34 | setCount(cnt);
35 |
36 | })();
37 |
38 | (async () => {
39 | const arr = [];
40 | for (var i = 1; i < count; i++) {
41 | const prodState = await supplyChainContract.methods
42 | .fetchProductState(i)
43 | .call();
44 |
45 | if (prodState === "0") {
46 | const prodData = [];
47 | const a = await supplyChainContract.methods
48 | .fetchProductPart1(i, "product", 0)
49 | .call();
50 | const b = await supplyChainContract.methods
51 | .fetchProductPart2(i, "product", 0)
52 | .call();
53 | const c = await supplyChainContract.methods
54 | .fetchProductPart3(i, "product", 0)
55 | .call();
56 | prodData.push(a);
57 | prodData.push(b);
58 | prodData.push(c);
59 | arr.push(prodData);
60 | }
61 | }
62 | setAllProducts(arr);
63 | setLoading(false);
64 | })();
65 | }, [count]);
66 |
67 | const [page, setPage] = React.useState(0);
68 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
69 |
70 | const handleChangePage = (event, newPage) => {
71 | setPage(newPage);
72 | };
73 |
74 | const handleChangeRowsPerPage = (event) => {
75 | setRowsPerPage(+event.target.value);
76 | setPage(0);
77 | };
78 |
79 | const [open, setOpen] = React.useState(false);
80 | const [modalData, setModalData] = React.useState([]);
81 |
82 | const handleClose = () => setOpen(false);
83 |
84 | const handleClick = async (prod) => {
85 | await setModalData(prod);
86 | setOpen(true);
87 | };
88 |
89 | const handleSetTxhash = async (id, hash) => {
90 | await supplyChainContract.methods
91 | .setTransactionHash(id, hash)
92 | .send({ from: roles.manufacturer, gas: 900000 });
93 | };
94 |
95 | const handleBuyButton = async (id) => {
96 | await supplyChainContract.methods
97 | .purchaseByThirdParty(id)
98 | .send({ from: roles.thirdparty, gas: 1000000 })
99 | .on("transactionHash", function (hash) {
100 | handleSetTxhash(id, hash);
101 | });
102 | setCount(0);
103 | };
104 |
105 | return (
106 |
107 |
108 | {loading ? (
109 |
110 | ) : (
111 | <>
112 |
117 |
118 | All Products
119 | Total : {allProducts.length}
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | Universal ID
129 |
130 |
131 | Product Code
132 |
133 |
134 | Manufacturer
135 |
136 |
137 | Manufacture Date
138 |
139 |
140 | Product Name
141 |
142 |
149 | Owner
150 |
151 |
155 | Buy
156 |
157 |
158 |
159 |
160 | {allProducts.length !== 0 ? (
161 | allProducts
162 | .slice(
163 | page * rowsPerPage,
164 | page * rowsPerPage + rowsPerPage
165 | )
166 | .map((prod) => {
167 | const d = new Date(parseInt(prod[1][0] * 1000));
168 | return (
169 | <>
170 |
176 | handleClick(prod)}
182 | >
183 | {prod[0][0]}
184 |
185 | handleClick(prod)}
189 | >
190 | {prod[1][2]}
191 |
192 | handleClick(prod)}
196 | >
197 | {prod[0][4]}
198 |
199 | handleClick(prod)}
202 | >
203 | {d.toDateString() + " " + d.toTimeString()}
204 |
205 | handleClick(prod)}
209 | >
210 | {prod[1][1]}
211 |
212 | handleClick(prod)}
219 | >
220 | {prod[0][2]}
221 |
222 |
226 |
231 | handleBuyButton(prod[0][0])
232 | }
233 | >
234 | BUY
235 |
236 |
237 |
238 | >
239 | );
240 | })
241 | ) : (
242 | <> >
243 | )}
244 |
245 |
246 |
247 |
256 |
257 |
258 |
259 | {/* {allProducts.length !== 0 ? (allProducts.map((prod) => (
260 | <>
261 |
262 |
Universal ID : {prod[0][0]}
263 |
SKU : {prod[0][1]}
264 |
Owner : {prod[0][2]}
265 |
Manufacturer : {prod[0][3]}
266 |
Name of Manufacturer : {prod[0][4]}
267 |
Details of Manufacturer : {prod[0][5]}
268 |
Longitude of Manufature : {prod[0][6]}
269 |
Latitude of Manufature : {prod[0][7]}
270 |
271 |
Manufactured date : {prod[1][0]}
272 |
handleBuyButton(prod[0][0])}
277 | >
278 | BUY
279 |
280 |
281 |
282 | >
283 | ))) : <> >} */}
284 | >
285 | )}
286 |
287 |
288 | );
289 | }
290 |
--------------------------------------------------------------------------------
/client/src/pages/ThirdParty/ShipThirdParty.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Navbar from "../../components/Navbar";
3 | import Button from "@material-ui/core/Button";
4 | import { useRole } from "../../context/RoleDataContext";
5 | import Table from "@material-ui/core/Table";
6 | import TableBody from "@material-ui/core/TableBody";
7 | import TableCell from "@material-ui/core/TableCell";
8 | import TableContainer from "@material-ui/core/TableContainer";
9 | import TableHead from "@material-ui/core/TableHead";
10 | import TableRow from "@material-ui/core/TableRow";
11 | import Paper from "@material-ui/core/Paper";
12 | import TablePagination from "@material-ui/core/TablePagination";
13 | import { useStyles } from "../../components/Styles";
14 | import ProductModal from "../../components/Modal";
15 | import clsx from "clsx";
16 | import Loader from "../../components/Loader";
17 |
18 | export default function ShipThirdParty(props) {
19 | const classes = useStyles();
20 | const supplyChainContract = props.supplyChainContract;
21 | const { roles } = useRole();
22 | const [count, setCount] = React.useState(0);
23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]);
24 | const [loading, setLoading] = React.useState(false);
25 | const navItem = [
26 | ["Buy Product", "/ThirdParty/allProducts"],
27 | ["Receive Product", "/ThirdParty/receive"],
28 | ["Ship Products", "/ThirdParty/ship"],
29 | ];
30 | const [alertText, setalertText] = React.useState("");
31 | React.useEffect(() => {
32 | (async () => {
33 | setLoading(true);
34 | const cnt = await supplyChainContract.methods.fetchProductCount().call();
35 | setCount(cnt);
36 |
37 | })();
38 |
39 | (async () => {
40 | const arr = [];
41 | for (var i = 1; i < count; i++) {
42 | const prodState = await supplyChainContract.methods
43 | .fetchProductState(i)
44 | .call();
45 |
46 | if (prodState === "4") {
47 | const prodData = [];
48 | const a = await supplyChainContract.methods
49 | .fetchProductPart1(i, "product", 0)
50 | .call();
51 | const b = await supplyChainContract.methods
52 | .fetchProductPart2(i, "product", 0)
53 | .call();
54 | const c = await supplyChainContract.methods
55 | .fetchProductPart3(i, "product", 0)
56 | .call();
57 | prodData.push(a);
58 | prodData.push(b);
59 | prodData.push(c);
60 | arr.push(prodData);
61 | }
62 | }
63 | setAllSoldProducts(arr);
64 | setLoading(false);
65 | })();
66 | }, [count]);
67 |
68 | const handleSetTxhash = async (id, hash) => {
69 | await supplyChainContract.methods
70 | .setTransactionHash(id, hash)
71 | .send({ from: roles.manufacturer, gas: 900000 });
72 | };
73 |
74 | const handleShipButton = async (id) => {
75 | try{
76 | await supplyChainContract.methods
77 | .shipByThirdParty(id)
78 | .send({ from: roles.thirdparty, gas: 1000000 })
79 | .on("transactionHash", function (hash) {
80 | handleSetTxhash(id, hash);
81 | });
82 | setCount(0);
83 | }catch{
84 | setalertText("You are not the owner of the Product")
85 | }
86 |
87 | };
88 | const [page, setPage] = React.useState(0);
89 | const [rowsPerPage, setRowsPerPage] = React.useState(10);
90 |
91 | const handleChangePage = (event, newPage) => {
92 | setPage(newPage);
93 | };
94 |
95 | const handleChangeRowsPerPage = (event) => {
96 | setRowsPerPage(+event.target.value);
97 | setPage(0);
98 | };
99 |
100 | const [open, setOpen] = React.useState(false);
101 | const [modalData, setModalData] = React.useState([]);
102 |
103 | const handleClose = () => setOpen(false);
104 |
105 | const handleClick = async (prod) => {
106 | await setModalData(prod);
107 | setOpen(true);
108 | };
109 |
110 | return (
111 | <>
112 |
113 |
114 | {loading ? (
115 |
116 | ) : (
117 | <>
118 |
123 | Products To be Shipped
124 |
125 | Total : {allSoldProducts.length}
126 |
127 |
128 |
129 |
{alertText.length !== 0 ? alertText : ""}
130 |
131 |
132 |
133 |
134 |
135 |
136 | Universal ID
137 |
138 |
142 | Product Code
143 |
144 |
148 | Manufacturer
149 |
150 |
154 | Manufacture Date
155 |
156 |
160 | Product Name
161 |
162 |
169 | Owner
170 |
171 |
175 | Ship
176 |
177 |
178 |
179 |
180 | {allSoldProducts.length !== 0 ? (
181 | allSoldProducts
182 | .slice(
183 | page * rowsPerPage,
184 | page * rowsPerPage + rowsPerPage
185 | )
186 | .map((prod) => {
187 | const d = new Date(parseInt(prod[1][0] * 1000));
188 | return (
189 | <>
190 |
196 | handleClick(prod)}
202 | >
203 | {prod[0][0]}
204 |
205 | handleClick(prod)}
209 | >
210 | {prod[1][2]}
211 |
212 | handleClick(prod)}
216 | >
217 | {prod[0][4]}
218 |
219 | handleClick(prod)}
222 | >
223 | {d.toDateString() +
224 | " " +
225 | d.toTimeString()}
226 |
227 | handleClick(prod)}
231 | >
232 | {prod[1][1]}
233 |
234 | handleClick(prod)}
241 | >
242 | {prod[0][2]}
243 |
244 |
248 |
253 | handleShipButton(prod[0][0])
254 | }
255 | >
256 | SHIP
257 |
258 |
259 |
260 | >
261 | );
262 | })
263 | ) : (
264 | <> >
265 | )}
266 |
267 |
268 |
269 |
278 |
279 |
280 | >
281 | )}
282 |
283 |
284 | >
285 | );
286 | }
287 |
--------------------------------------------------------------------------------
/client/src/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const http = require('http');
3 | const path = require('path');
4 | const app = express();
5 | app.use(express.static(path.join(__dirname,'..', 'build')));
6 | app.user(express.static("public"));
7 | app.get('/*', function (req, res) {
8 | res.sendFile(path.join(__dirname,'..', 'build', 'index.html'));
9 | });
10 |
11 |
12 | // const server = http.createServer(app);
13 |
14 | const port = 3000;
15 |
16 | app.listen(port, () => {
17 | console.log('Server is up on port ' + port);
18 | });
--------------------------------------------------------------------------------
/client/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl)
104 | .then(response => {
105 | // Ensure service worker exists, and that we really are getting a JS file.
106 | const contentType = response.headers.get('content-type');
107 | if (
108 | response.status === 404 ||
109 | (contentType != null && contentType.indexOf('javascript') === -1)
110 | ) {
111 | // No service worker found. Probably a different app. Reload the page.
112 | navigator.serviceWorker.ready.then(registration => {
113 | registration.unregister().then(() => {
114 | window.location.reload();
115 | });
116 | });
117 | } else {
118 | // Service worker found. Proceed as normal.
119 | registerValidSW(swUrl, config);
120 | }
121 | })
122 | .catch(() => {
123 | console.log(
124 | 'No internet connection found. App is running in offline mode.'
125 | );
126 | });
127 | }
128 |
129 | export function unregister() {
130 | if ('serviceWorker' in navigator) {
131 | navigator.serviceWorker.ready.then(registration => {
132 | registration.unregister();
133 | });
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/contracts/Migrations.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | contract Migrations {
5 | address public owner;
6 | uint public last_completed_migration;
7 |
8 | modifier restricted() {
9 | if (msg.sender == owner) _;
10 | }
11 |
12 | constructor() public {
13 | owner = msg.sender;
14 | }
15 |
16 | function setCompleted(uint completed) public restricted {
17 | last_completed_migration = completed;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/contracts/Structure.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | library Structure {
5 | enum State {
6 | Manufactured,
7 | PurchasedByThirdParty,
8 | ShippedByManufacturer,
9 | ReceivedByThirdParty,
10 | PurchasedByCustomer,
11 | ShippedByThirdParty,
12 | ReceivedByDeliveryHub,
13 | ShippedByDeliveryHub,
14 | ReceivedByCustomer
15 | }
16 | struct ManufactureDetails {
17 | address manufacturer;
18 | string manufacturerName;
19 | string manufacturerDetails;
20 | string manufacturerLongitude;
21 | string manufacturerLatitude;
22 | uint256 manufacturedDate;
23 | }
24 | struct ProductDetails {
25 | string productName;
26 | uint256 productCode;
27 | uint256 productPrice;
28 | string productCategory;
29 | }
30 | struct ThirdPartyDetails {
31 | address thirdParty;
32 | string thirdPartyLongitude;
33 | string thirdPartyLatitude;
34 | }
35 | struct DeliveryHubDetails {
36 | address deliveryHub;
37 | string deliveryHubLongitude;
38 | string deliveryHubLatitude;
39 | }
40 | struct Product {
41 | uint256 uid;
42 | uint256 sku;
43 | address owner;
44 | State productState;
45 | ManufactureDetails manufacturer;
46 | ThirdPartyDetails thirdparty;
47 | ProductDetails productdet;
48 | DeliveryHubDetails deliveryhub;
49 | address customer;
50 | string transaction;
51 | }
52 |
53 | struct ProductHistory {
54 | Product[] history;
55 | }
56 |
57 | struct Roles {
58 | bool Manufacturer;
59 | bool ThirdParty;
60 | bool DeliveryHub;
61 | bool Customer;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/Customer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | import "./Roles.sol";
5 |
6 | contract Customer {
7 | using Roles for Roles.Role;
8 |
9 | event CustomerAdded(address indexed _account);
10 | event CustomerRemoved(address indexed _account);
11 |
12 | Roles.Role private customersList;
13 |
14 | constructor() public {
15 | customersList.addRole(msg.sender);
16 | emit CustomerAdded(msg.sender);
17 | }
18 |
19 | ///@dev Modifiers for Customer.
20 | modifier onlyCustomer() {
21 | require(isCustomer(msg.sender));
22 | _;
23 | }
24 | /*-----------------------------*/
25 |
26 | ///@dev Customer Utility functions.
27 | function isCustomer(address _account) public view returns (bool) {
28 | return customersList.hasRole(_account);
29 | }
30 |
31 | function addCustomer(address _account) public onlyCustomer {
32 | customersList.addRole(_account);
33 | emit CustomerAdded(_account);
34 | }
35 |
36 | function removeCustomer() public {
37 | customersList.removeRole(msg.sender);
38 | emit CustomerRemoved(msg.sender);
39 | }
40 | /*-----------------------------*/
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/DeliveryHub.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | import "./Roles.sol";
5 |
6 | contract DeliveryHub {
7 | using Roles for Roles.Role;
8 |
9 | event DeliveryHubAdded(address indexed _account);
10 | event DeliveryHubRemoved(address indexed _account);
11 |
12 | Roles.Role private deliveryHubsList;
13 |
14 | constructor() public {
15 | deliveryHubsList.addRole(msg.sender);
16 | emit DeliveryHubAdded(msg.sender);
17 | }
18 |
19 | ///@dev Modifiers for DeliveryHub.
20 | modifier onlyDeliveryHub() {
21 | require(isDeliveryHub(msg.sender));
22 | _;
23 | }
24 | /*-----------------------------*/
25 |
26 | ///@dev DeliveryHub Utility functions.
27 | function isDeliveryHub(address _account) public view returns (bool) {
28 | return deliveryHubsList.hasRole(_account);
29 | }
30 |
31 | function addDeliveryHub(address _account) public onlyDeliveryHub {
32 | deliveryHubsList.addRole(_account);
33 | emit DeliveryHubAdded(_account);
34 | }
35 |
36 | function removeDeliveryHub() public {
37 | deliveryHubsList.removeRole(msg.sender);
38 | emit DeliveryHubRemoved(msg.sender);
39 | }
40 | /*-----------------------------*/
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/Manufacturer.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | import "./Roles.sol";
5 |
6 | contract Manufacturer {
7 | using Roles for Roles.Role;
8 |
9 | event ManufacturerAdded(address indexed _account);
10 | event ManufacturerRemoved(address indexed _account);
11 |
12 | Roles.Role manufacturersList;
13 |
14 | constructor() public {
15 | manufacturersList.addRole(msg.sender);
16 | emit ManufacturerAdded(msg.sender);
17 | }
18 |
19 | ///@dev Modifiers for Manufacturer.
20 | modifier onlyManufacturer() {
21 | require(isManufacturer(msg.sender));
22 | _;
23 | }
24 | /*-----------------------------*/
25 |
26 | ///@dev Manufacturer Utility functions.
27 | function isManufacturer(address _account) public view returns (bool) {
28 | return manufacturersList.hasRole(_account);
29 | }
30 |
31 | function addManufacturer(address _account ) public {
32 | manufacturersList.addRole(_account);
33 | emit ManufacturerAdded(_account);
34 | }
35 |
36 | function removeManufacturer() public {
37 | manufacturersList.removeRole(msg.sender);
38 | emit ManufacturerRemoved(msg.sender);
39 | }
40 | /*-----------------------------*/
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/Roles.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | ///@title Library to add, remove and verify role.
5 | ///@author Rishav Raj Kumar, Ramiz Mollah.
6 | ///@notice You can use this as helper functions for contracts making use of Roles.
7 | ///@dev All internal functions from use by contracts internally only.
8 | library Roles{
9 | struct Role {
10 | mapping (address => bool) list;
11 | }
12 |
13 | ///@notice Checks is the given account has the given role.
14 | function hasRole(Role storage role, address _account)
15 | internal
16 | view
17 | returns (bool)
18 | {
19 | require(_account != address(0));
20 | return role.list[_account];
21 | }
22 |
23 | ///@notice Adds the given role to the given account.
24 | function addRole(Role storage role, address _account)
25 | internal
26 | {
27 | require(_account != address(0));
28 | require(!hasRole(role, _account));
29 |
30 | role.list[_account] = true;
31 | }
32 |
33 | ///@notice Removes the given role from the given account.
34 | function removeRole(Role storage role, address _account)
35 | internal
36 | {
37 | require(_account != address(0));
38 | require(hasRole(role, _account));
39 |
40 | role.list[_account] = false;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/SortationHub.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | import "./Roles.sol";
5 |
6 | contract SortationHub {
7 | using Roles for Roles.Role;
8 |
9 | event SortationHubAdded(address indexed _account);
10 | event SortationHubRemoved(address indexed _account);
11 |
12 | Roles.Role private sortationHubsList;
13 |
14 | constructor() public {
15 | sortationHubsList.addRole(msg.sender);
16 | emit SortationHubAdded(msg.sender);
17 | }
18 |
19 | ///@dev Modifiers for SortationHub.
20 | modifier onlySortationHub() {
21 | require(isSortationHub(msg.sender));
22 | _;
23 | }
24 | /*-----------------------------*/
25 |
26 | ///@dev SortationHub Utility functions.
27 | function isSortationHub(address _account) public view returns (bool) {
28 | return sortationHubsList.hasRole(_account);
29 | }
30 |
31 | function addSortationHub(address _account) public onlySortationHub {
32 | sortationHubsList.addRole(_account);
33 | emit SortationHubAdded(_account);
34 | }
35 |
36 | function removeSortationHub() public {
37 | sortationHubsList.removeRole(msg.sender);
38 | emit SortationHubRemoved(msg.sender);
39 | }
40 | /*-----------------------------*/
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/rolesUtils[deprecated]/Thirdparty.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.4.21 <0.9.0;
3 |
4 | import "./Roles.sol";
5 |
6 | contract Thirdparty {
7 | using Roles for Roles.Role;
8 |
9 | event ThirdpartyAdded(address indexed _account);
10 | event ThirdpartyRemoved(address indexed _account);
11 |
12 | Roles.Role private thirdpartysList;
13 |
14 | constructor() public {
15 | thirdpartysList.addRole(msg.sender);
16 | emit ThirdpartyAdded(msg.sender);
17 | }
18 |
19 | ///@dev Modifiers for Thirdparty.
20 | modifier onlyThirdparty() {
21 | require(isThirdparty(msg.sender));
22 | _;
23 | }
24 | /*-----------------------------*/
25 |
26 | ///@dev Thirdparty Utility functions.
27 | function isThirdparty(address _account) public view returns (bool) {
28 | return thirdpartysList.hasRole(_account);
29 | }
30 |
31 | function addThirdparty(address _account) public onlyThirdparty {
32 | thirdpartysList.addRole(_account);
33 | emit ThirdpartyAdded(_account);
34 | }
35 |
36 | function removeThirdparty() public {
37 | thirdpartysList.removeRole(msg.sender);
38 | emit ThirdpartyRemoved(msg.sender);
39 | }
40 | /*-----------------------------*/
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/images/Solidity.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/activitydiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/activitydiagram.png
--------------------------------------------------------------------------------
/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/architecture.png
--------------------------------------------------------------------------------
/images/architecturefinal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/architecturefinal.png
--------------------------------------------------------------------------------
/images/dataflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/dataflow.png
--------------------------------------------------------------------------------
/images/express.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/express.jpg
--------------------------------------------------------------------------------
/images/express.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/flow.png
--------------------------------------------------------------------------------
/images/ganachetrans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/ganachetrans.png
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/logo.png
--------------------------------------------------------------------------------
/images/mat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/mat.png
--------------------------------------------------------------------------------
/images/nginx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/nginx.png
--------------------------------------------------------------------------------
/images/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/react.png
--------------------------------------------------------------------------------
/images/sequencediagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/sequencediagram.png
--------------------------------------------------------------------------------
/images/truffle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/truffle.png
--------------------------------------------------------------------------------
/images/trufflenew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/trufflenew.png
--------------------------------------------------------------------------------
/images/web3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/web3.jpg
--------------------------------------------------------------------------------
/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | var Migrations = artifacts.require("./Migrations.sol");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/migrations/2_deploy_contracts.js:
--------------------------------------------------------------------------------
1 | var SupplyChainContract = artifacts.require("./SupplyChain.sol");
2 | var RolesContract = artifacts.require("./rolesUtils/Roles.sol")
3 | var ManufacturerContract = artifacts.require("./rolesUtils/Manufacturer.sol");
4 |
5 | module.exports = function(deployer) {
6 | deployer.deploy(ManufacturerContract);
7 | deployer.deploy(RolesContract);
8 | deployer.deploy(SupplyChainContract, {gas: 15555555});
9 | // deployer.deploy(FetchContract, {gas: 15555555});
10 | };
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eth-supplychain-dapp",
3 | "version": "0.1.0",
4 | "dependencies": {
5 | "solc": "^0.8.4",
6 | "truffle": "^5.3.7"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/TestSimpleStorage.sol:
--------------------------------------------------------------------------------
1 | pragma solidity >=0.4.21 <0.7.0;
2 |
3 | import "truffle/Assert.sol";
4 | import "truffle/DeployedAddresses.sol";
5 | import "../contracts/SimpleStorage.sol";
6 |
7 | contract TestSimpleStorage {
8 |
9 | function testItStoresAValue() public {
10 | SimpleStorage simpleStorage = SimpleStorage(DeployedAddresses.SimpleStorage());
11 |
12 | simpleStorage.set(89);
13 |
14 | uint expected = 89;
15 |
16 | Assert.equal(simpleStorage.get(), expected, "It should store the value 89.");
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/test/simplestorage.js:
--------------------------------------------------------------------------------
1 | const SimpleStorage = artifacts.require("./SimpleStorage.sol");
2 |
3 | contract("SimpleStorage", accounts => {
4 | it("...should store the value 89.", async () => {
5 | const simpleStorageInstance = await SimpleStorage.deployed();
6 |
7 | // Set value of 89
8 | await simpleStorageInstance.set(89, { from: accounts[0] });
9 |
10 | // Get stored value
11 | const storedData = await simpleStorageInstance.get.call();
12 |
13 | assert.equal(storedData, 89, "The value 89 was not stored.");
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/truffle-config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | module.exports = {
4 | compilers: {
5 | solc: {
6 | settings: {
7 | optimizer: {
8 | enabled: true,
9 | runs: 200
10 | }
11 | }
12 | }
13 | },
14 | // See
15 | // to customize your Truffle configuration!
16 | contracts_build_directory: path.join(__dirname, "client/src/contracts"),
17 | networks: {
18 | develop: {
19 | host: "127.0.0.1",
20 | port: 8545,
21 | network_id: "*", // match any network
22 | websockets: true
23 | }
24 | }
25 |
26 | };
27 |
--------------------------------------------------------------------------------