├── Backend
├── .gitignore
├── controller
│ ├── product.js
│ ├── purchase.js
│ ├── purchaseStock.js
│ ├── sales.js
│ ├── soldStock.js
│ └── store.js
├── models
│ ├── index.js
│ ├── product.js
│ ├── purchase.js
│ ├── sales.js
│ ├── store.js
│ └── users.js
├── package-lock.json
├── package.json
├── router
│ ├── product.js
│ ├── purchase.js
│ ├── sales.js
│ └── store.js
└── server.js
├── Frontend
├── .gitignore
├── README.md
├── README.md~
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── AuthContext.js
│ ├── ProtectedWrapper.js
│ ├── assets
│ │ ├── 20943629.eps
│ │ ├── License free.txt
│ │ ├── License premium.txt
│ │ ├── Login.png
│ │ ├── add-product.png
│ │ ├── dashboard-icon.png
│ │ ├── download.png
│ │ ├── filter-icon.png
│ │ ├── inventory-icon.png
│ │ ├── location-icon.png
│ │ ├── logo.png
│ │ ├── mi-logo (2).jpg
│ │ ├── mi-logo.png
│ │ ├── order-icon.png
│ │ ├── reports-icon.png
│ │ ├── search-icon.png
│ │ ├── signup-img.zip
│ │ ├── signup.jpg
│ │ ├── store-image.jpg
│ │ └── supplier-icon.png
│ ├── components
│ │ ├── AddProduct.js
│ │ ├── AddPurchaseDetails.js
│ │ ├── AddSale.js
│ │ ├── AddStore.js
│ │ ├── Header.js
│ │ ├── Layout.js
│ │ ├── SideMenu.js
│ │ ├── UpdateProduct.js
│ │ └── UploadImage.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ │ ├── Dashboard.js
│ │ ├── Inventory.js
│ │ ├── Login.js
│ │ ├── NoPageFound.js
│ │ ├── PurchaseDetails.js
│ │ ├── Register.js
│ │ ├── Sales.js
│ │ └── Store.js
│ ├── reportWebVitals.js
│ └── setupTests.js
└── tailwind.config.js
└── README.md
/Backend/.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 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
--------------------------------------------------------------------------------
/Backend/controller/product.js:
--------------------------------------------------------------------------------
1 | const Product = require("../models/Product");
2 | const Purchase = require("../models/purchase");
3 | const Sales = require("../models/sales");
4 |
5 | // Add Post
6 | const addProduct = (req, res) => {
7 | console.log("req: ", req.body.userId);
8 | const addProduct = new Product({
9 | userID: req.body.userId,
10 | name: req.body.name,
11 | manufacturer: req.body.manufacturer,
12 | stock: 0,
13 | description: req.body.description,
14 | });
15 |
16 | addProduct
17 | .save()
18 | .then((result) => {
19 | res.status(200).send(result);
20 | })
21 | .catch((err) => {
22 | res.status(402).send(err);
23 | });
24 | };
25 |
26 | // Get All Products
27 | const getAllProducts = async (req, res) => {
28 | const findAllProducts = await Product.find({
29 | userID: req.params.userId,
30 | }).sort({ _id: -1 }); // -1 for descending;
31 | res.json(findAllProducts);
32 | };
33 |
34 | // Delete Selected Product
35 | const deleteSelectedProduct = async (req, res) => {
36 | const deleteProduct = await Product.deleteOne(
37 | { _id: req.params.id }
38 | );
39 | const deletePurchaseProduct = await Purchase.deleteOne(
40 | { ProductID: req.params.id }
41 | );
42 |
43 | const deleteSaleProduct = await Sales.deleteOne(
44 | { ProductID: req.params.id }
45 | );
46 | res.json({ deleteProduct, deletePurchaseProduct, deleteSaleProduct });
47 | };
48 |
49 | // Update Selected Product
50 | const updateSelectedProduct = async (req, res) => {
51 | try {
52 | const updatedResult = await Product.findByIdAndUpdate(
53 | { _id: req.body.productID },
54 | {
55 | name: req.body.name,
56 | manufacturer: req.body.manufacturer,
57 | description: req.body.description,
58 | },
59 | { new: true }
60 | );
61 | console.log(updatedResult);
62 | res.json(updatedResult);
63 | } catch (error) {
64 | console.log(error);
65 | res.status(402).send("Error");
66 | }
67 | };
68 |
69 | // Search Products
70 | const searchProduct = async (req, res) => {
71 | const searchTerm = req.query.searchTerm;
72 | const products = await Product.find({
73 | name: { $regex: searchTerm, $options: "i" },
74 | });
75 | res.json(products);
76 | };
77 |
78 | module.exports = {
79 | addProduct,
80 | getAllProducts,
81 | deleteSelectedProduct,
82 | updateSelectedProduct,
83 | searchProduct,
84 | };
85 |
--------------------------------------------------------------------------------
/Backend/controller/purchase.js:
--------------------------------------------------------------------------------
1 | const Purchase = require("../models/purchase");
2 | const purchaseStock = require("./purchaseStock");
3 |
4 | // Add Purchase Details
5 | const addPurchase = (req, res) => {
6 | const addPurchaseDetails = new Purchase({
7 | userID: req.body.userID,
8 | ProductID: req.body.productID,
9 | QuantityPurchased: req.body.quantityPurchased,
10 | PurchaseDate: req.body.purchaseDate,
11 | TotalPurchaseAmount: req.body.totalPurchaseAmount,
12 | });
13 |
14 | addPurchaseDetails
15 | .save()
16 | .then((result) => {
17 | purchaseStock(req.body.productID, req.body.quantityPurchased);
18 | res.status(200).send(result);
19 | })
20 | .catch((err) => {
21 | res.status(402).send(err);
22 | });
23 | };
24 |
25 | // Get All Purchase Data
26 | const getPurchaseData = async (req, res) => {
27 | const findAllPurchaseData = await Purchase.find({"userID": req.params.userID})
28 | .sort({ _id: -1 })
29 | .populate("ProductID"); // -1 for descending order
30 | res.json(findAllPurchaseData);
31 | };
32 |
33 | // Get total purchase amount
34 | const getTotalPurchaseAmount = async (req, res) => {
35 | let totalPurchaseAmount = 0;
36 | const purchaseData = await Purchase.find({"userID": req.params.userID});
37 | purchaseData.forEach((purchase) => {
38 | totalPurchaseAmount += purchase.TotalPurchaseAmount;
39 | });
40 | res.json({ totalPurchaseAmount });
41 | };
42 |
43 | module.exports = { addPurchase, getPurchaseData, getTotalPurchaseAmount };
44 |
--------------------------------------------------------------------------------
/Backend/controller/purchaseStock.js:
--------------------------------------------------------------------------------
1 | const Purchase = require("../models/purchase");
2 | const Product = require("../models/Product");
3 |
4 | const purchaseStock = async (productID, purchaseStockData) => {
5 | // Updating Purchase stock
6 | try {
7 | const myProductData = await Product.findOne({ _id: productID });
8 | let myUpdatedStock = parseInt(myProductData.stock) + purchaseStockData;
9 |
10 | const PurchaseStock = await Product.findByIdAndUpdate(
11 | { _id: productID },
12 | {
13 | stock: myUpdatedStock,
14 | },
15 | { new: true }
16 | );
17 | console.log(PurchaseStock);
18 | } catch (error) {
19 | console.error("Error updating Purchase stock ", error);
20 | }
21 | };
22 |
23 | module.exports = purchaseStock;
24 |
--------------------------------------------------------------------------------
/Backend/controller/sales.js:
--------------------------------------------------------------------------------
1 | const Sales = require("../models/sales");
2 | const soldStock = require("../controller/soldStock");
3 |
4 | // Add Sales
5 | const addSales = (req, res) => {
6 | const addSale = new Sales({
7 | userID: req.body.userID,
8 | ProductID: req.body.productID,
9 | StoreID: req.body.storeID,
10 | StockSold: req.body.stockSold,
11 | SaleDate: req.body.saleDate,
12 | TotalSaleAmount: req.body.totalSaleAmount,
13 | });
14 |
15 | addSale
16 | .save()
17 | .then((result) => {
18 | soldStock(req.body.productID, req.body.stockSold);
19 | res.status(200).send(result);
20 | })
21 | .catch((err) => {
22 | res.status(402).send(err);
23 | });
24 | };
25 |
26 | // Get All Sales Data
27 | const getSalesData = async (req, res) => {
28 | const findAllSalesData = await Sales.find({"userID": req.params.userID})
29 | .sort({ _id: -1 })
30 | .populate("ProductID")
31 | .populate("StoreID"); // -1 for descending order
32 | res.json(findAllSalesData);
33 | };
34 |
35 | // Get total sales amount
36 | const getTotalSalesAmount = async(req,res) => {
37 | let totalSaleAmount = 0;
38 | const salesData = await Sales.find({"userID": req.params.userID});
39 | salesData.forEach((sale)=>{
40 | totalSaleAmount += sale.TotalSaleAmount;
41 | })
42 | res.json({totalSaleAmount});
43 |
44 | }
45 |
46 | const getMonthlySales = async (req, res) => {
47 | try {
48 | const sales = await Sales.find();
49 |
50 | // Initialize array with 12 zeros
51 | const salesAmount = [];
52 | salesAmount.length = 12;
53 | salesAmount.fill(0)
54 |
55 | sales.forEach((sale) => {
56 | const monthIndex = parseInt(sale.SaleDate.split("-")[1]) - 1;
57 |
58 | salesAmount[monthIndex] += sale.TotalSaleAmount;
59 | });
60 |
61 | res.status(200).json({ salesAmount });
62 | } catch (err) {
63 | console.error(err);
64 | res.status(500).json({ error: "Server error" });
65 | }
66 | };
67 |
68 |
69 |
70 | module.exports = { addSales, getMonthlySales, getSalesData, getTotalSalesAmount};
71 |
--------------------------------------------------------------------------------
/Backend/controller/soldStock.js:
--------------------------------------------------------------------------------
1 | const Sales = require("../models/sales");
2 | const Product = require("../models/Product");
3 |
4 |
5 | const soldStock = async (productID, stockSoldData) => {
6 |
7 | // Updating sold stock
8 | try {
9 |
10 | const myProductData = await Product.findOne({ _id: productID });
11 | let myUpdatedStock = myProductData.stock - stockSoldData;
12 | console.log("MY SOLD STOCK: ", myUpdatedStock);
13 |
14 | const SoldStock = await Product.findByIdAndUpdate(
15 | { _id: productID },
16 | {
17 | stock: myUpdatedStock,
18 | },
19 | { new: true }
20 | );
21 | console.log(SoldStock);
22 |
23 | } catch (error) {
24 | console.error("Error updating sold stock ", error);
25 | }
26 | };
27 |
28 | module.exports = soldStock;
29 |
--------------------------------------------------------------------------------
/Backend/controller/store.js:
--------------------------------------------------------------------------------
1 | const Store = require("../models/store");
2 |
3 | // Add Store
4 | const addStore = async (req, res) => {
5 | console.log(req.body)
6 | const addStore = await new Store({
7 | userID : req.body.userId,
8 | name: req.body.name,
9 | category: req.body.category,
10 | address: req.body.address,
11 | city: req.body.city,
12 | image: req.body.image
13 | });
14 |
15 | addStore.save().then((result) => {
16 | res.status(200).send(result);
17 | })
18 | .catch((err) => {
19 | res.status(402).send(err);
20 | });
21 | };
22 |
23 | // Get All Stores
24 | const getAllStores = async (req, res) => {
25 | const findAllStores = await Store.find({"userID": req.params.userID}).sort({ _id: -1 }); // -1 for descending;
26 | res.json(findAllStores);
27 | };
28 |
29 | module.exports = { addStore, getAllStores };
30 |
--------------------------------------------------------------------------------
/Backend/models/index.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const uri = "mongodb+srv://adminhamza:adminhamza123&@cluster0.pzcviot.mongodb.net/InventoryManagementApp?retryWrites=true&w=majority";
3 |
4 |
5 | function main() {
6 | mongoose.connect(uri).then(() => {
7 | console.log("Succesfull")
8 |
9 | }).catch((err) => {
10 | console.log("Error: ", err)
11 | })
12 | }
13 |
14 | module.exports = { main };
--------------------------------------------------------------------------------
/Backend/models/product.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const ProductSchema = new mongoose.Schema(
4 | {
5 | userID: {
6 | type: mongoose.Schema.Types.ObjectId,
7 | ref: 'users',
8 | required: true,
9 | },
10 | name: {
11 | type: String,
12 | required: true,
13 | },
14 | manufacturer: {
15 | type: String,
16 | required: true,
17 | },
18 | stock: {
19 | type: Number,
20 | required: true,
21 | },
22 | description: String,
23 | },
24 | { timestamps: true }
25 | );
26 |
27 |
28 | const Product = mongoose.model("product", ProductSchema);
29 | module.exports = Product;
30 |
--------------------------------------------------------------------------------
/Backend/models/purchase.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const PurchaseSchema = new mongoose.Schema(
4 | {
5 | userID: {
6 | type: mongoose.Schema.Types.ObjectId,
7 | ref: "users",
8 | required: true,
9 | },
10 | ProductID: {
11 | type: mongoose.Schema.Types.ObjectId,
12 | ref: "product",
13 | required: true,
14 | },
15 | QuantityPurchased: {
16 | type: Number,
17 | required: true,
18 | },
19 | PurchaseDate: {
20 | type: String,
21 | required: true,
22 | },
23 | TotalPurchaseAmount: {
24 | type: Number,
25 | required: true,
26 | },
27 | },
28 | { timestamps: true }
29 | );
30 |
31 | const Purchase = mongoose.model("purchase", PurchaseSchema);
32 | module.exports = Purchase;
33 |
--------------------------------------------------------------------------------
/Backend/models/sales.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const SaleSchema = new mongoose.Schema(
4 | {
5 | userID: {
6 | type: mongoose.Schema.Types.ObjectId,
7 | ref: "users",
8 | required: true,
9 | },
10 | ProductID: {
11 | type: mongoose.Schema.Types.ObjectId,
12 | ref: "product",
13 | required: true,
14 | },
15 | StoreID: {
16 | type: mongoose.Schema.Types.ObjectId,
17 | ref: "store",
18 | required: true,
19 | },
20 | StockSold: {
21 | type: Number,
22 | required: true,
23 | },
24 | SaleDate: {
25 | type: String,
26 | required: true,
27 | },
28 | TotalSaleAmount: {
29 | type: Number,
30 | required: true,
31 | },
32 | },
33 | { timestamps: true }
34 | );
35 |
36 | const Sales = mongoose.model("sales", SaleSchema);
37 | module.exports = Sales;
38 |
--------------------------------------------------------------------------------
/Backend/models/store.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const StoreSchema = new mongoose.Schema(
4 | {
5 | userID: {
6 | type: mongoose.Schema.Types.ObjectId,
7 | ref: 'users',
8 | required: true,
9 | },
10 | name: {
11 | type: String,
12 | required: true,
13 | },
14 | category: {
15 | type: String,
16 | required: true,
17 | },
18 | address: {
19 | type: String,
20 | required: true,
21 | },
22 | city: {
23 | type: String,
24 | required: true,
25 | },
26 | image: {
27 | type: String,
28 | required: true,
29 | },
30 | },
31 | { timestamps: true }
32 | );
33 |
34 | const Store = mongoose.model("store", StoreSchema);
35 | module.exports = Store;
36 |
--------------------------------------------------------------------------------
/Backend/models/users.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const UserSchema = new mongoose.Schema({
4 | firstName: 'String',
5 | lastName : 'String',
6 | email: 'String',
7 | password: 'String',
8 | phoneNumber: 'Number',
9 | imageUrl: 'String',
10 | });
11 |
12 | const User = mongoose.model("users", UserSchema);
13 | module.exports = User;
--------------------------------------------------------------------------------
/Backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "serverStart": "nodemon server.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "cors": "^2.8.5",
14 | "express": "^4.18.2",
15 | "mongoose": "^7.0.2",
16 | "multer": "^1.4.5-lts.1",
17 | "nodemon": "^2.0.21"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Backend/router/product.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const product = require("../controller/product");
4 |
5 | // Add Product
6 | app.post("/add", product.addProduct);
7 |
8 | // Get All Products
9 | app.get("/get/:userId", product.getAllProducts);
10 |
11 | // Delete Selected Product Item
12 | app.get("/delete/:id", product.deleteSelectedProduct);
13 |
14 | // Update Selected Product
15 | app.post("/update", product.updateSelectedProduct);
16 |
17 | // Search Product
18 | app.get("/search", product.searchProduct);
19 |
20 | // http://localhost:4000/api/product/search?searchTerm=fa
21 |
22 | module.exports = app;
23 |
--------------------------------------------------------------------------------
/Backend/router/purchase.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const purchase = require("../controller/purchase");
4 |
5 | // Add Purchase
6 | app.post("/add", purchase.addPurchase);
7 |
8 | // Get All Purchase Data
9 | app.get("/get/:userID", purchase.getPurchaseData);
10 |
11 | app.get("/get/:userID/totalpurchaseamount", purchase.getTotalPurchaseAmount);
12 |
13 | module.exports = app;
14 |
15 | // http://localhost:4000/api/purchase/add POST
16 | // http://localhost:4000/api/purchase/get GET
17 |
--------------------------------------------------------------------------------
/Backend/router/sales.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const sales = require("../controller/sales");
4 |
5 | // Add Sales
6 | app.post("/add", sales.addSales);
7 |
8 | // Get All Sales
9 | app.get("/get/:userID", sales.getSalesData);
10 | app.get("/getmonthly", sales.getMonthlySales);
11 |
12 |
13 | app.get("/get/:userID/totalsaleamount", sales.getTotalSalesAmount);
14 |
15 | module.exports = app;
16 |
17 |
18 |
19 | // http://localhost:4000/api/sales/add POST
20 | // http://localhost:4000/api/sales/get GET
21 |
--------------------------------------------------------------------------------
/Backend/router/store.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const app = express();
3 | const store = require("../controller/store");
4 |
5 | // Add Store
6 | app.post("/add", store.addStore);
7 |
8 | // Get All Store
9 | app.get("/get/:userID", store.getAllStores)
10 |
11 | module.exports = app;
12 |
--------------------------------------------------------------------------------
/Backend/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const { main } = require("./models/index");
3 | const productRoute = require("./router/product");
4 | const storeRoute = require("./router/store");
5 | const purchaseRoute = require("./router/purchase");
6 | const salesRoute = require("./router/sales");
7 | const cors = require("cors");
8 | const User = require("./models/users");
9 | const Product = require("./models/Product");
10 |
11 |
12 | const app = express();
13 | const PORT = 4000;
14 | main();
15 | app.use(express.json());
16 | app.use(cors());
17 |
18 | // Store API
19 | app.use("/api/store", storeRoute);
20 |
21 | // Products API
22 | app.use("/api/product", productRoute);
23 |
24 | // Purchase API
25 | app.use("/api/purchase", purchaseRoute);
26 |
27 | // Sales API
28 | app.use("/api/sales", salesRoute);
29 |
30 | // ------------- Signin --------------
31 | let userAuthCheck;
32 | app.post("/api/login", async (req, res) => {
33 | console.log(req.body);
34 | // res.send("hi");
35 | try {
36 | const user = await User.findOne({
37 | email: req.body.email,
38 | password: req.body.password,
39 | });
40 | console.log("USER: ", user);
41 | if (user) {
42 | res.send(user);
43 | userAuthCheck = user;
44 | } else {
45 | res.status(401).send("Invalid Credentials");
46 | userAuthCheck = null;
47 | }
48 | } catch (error) {
49 | console.log(error);
50 | res.send(error);
51 | }
52 | });
53 |
54 | // Getting User Details of login user
55 | app.get("/api/login", (req, res) => {
56 | res.send(userAuthCheck);
57 | });
58 | // ------------------------------------
59 |
60 | // Registration API
61 | app.post("/api/register", (req, res) => {
62 | let registerUser = new User({
63 | firstName: req.body.firstName,
64 | lastName: req.body.lastName,
65 | email: req.body.email,
66 | password: req.body.password,
67 | phoneNumber: req.body.phoneNumber,
68 | imageUrl: req.body.imageUrl,
69 | });
70 |
71 | registerUser
72 | .save()
73 | .then((result) => {
74 | res.status(200).send(result);
75 | alert("Signup Successfull");
76 | })
77 | .catch((err) => console.log("Signup: ", err));
78 | console.log("request: ", req.body);
79 | });
80 |
81 |
82 | app.get("/testget", async (req,res)=>{
83 | const result = await Product.findOne({ _id: '6429979b2e5434138eda1564'})
84 | res.json(result)
85 |
86 | })
87 |
88 | // Here we are listening to the server
89 | app.listen(PORT, () => {
90 | console.log("I am live again");
91 | });
92 |
--------------------------------------------------------------------------------
/Frontend/.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 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/Frontend/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | 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.
37 |
38 | 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.
39 |
40 | 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.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 | # React-Inventory-Management-System
72 |
--------------------------------------------------------------------------------
/Frontend/README.md~:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/README.md~
--------------------------------------------------------------------------------
/Frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "inventory-management-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@headlessui/react": "^1.7.13",
7 | "@heroicons/react": "^2.0.16",
8 | "@tailwindcss/forms": "^0.5.3",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.4.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "apexcharts": "^3.37.2",
13 | "chart.js": "^4.2.1",
14 | "react": "^18.2.0",
15 | "react-apexcharts": "^1.4.0",
16 | "react-chartjs-2": "^5.2.0",
17 | "react-dom": "^18.2.0",
18 | "react-router-dom": "^6.9.0",
19 | "react-scripts": "5.0.1",
20 | "web-vitals": "^2.1.4"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": [
30 | "react-app",
31 | "react-app/jest"
32 | ]
33 | },
34 | "browserslist": {
35 | "production": [
36 | ">0.2%",
37 | "not dead",
38 | "not op_mini all"
39 | ],
40 | "development": [
41 | "last 1 chrome version",
42 | "last 1 firefox version",
43 | "last 1 safari version"
44 | ]
45 | },
46 | "devDependencies": {
47 | "tailwindcss": "^3.2.7"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/public/favicon.ico
--------------------------------------------------------------------------------
/Frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Frontend/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/public/logo192.png
--------------------------------------------------------------------------------
/Frontend/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/public/logo512.png
--------------------------------------------------------------------------------
/Frontend/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 |
--------------------------------------------------------------------------------
/Frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/Frontend/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Frontend/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Login from "./pages/Login";
3 | import Register from "./pages/Register";
4 | import Dashboard from "./pages/Dashboard";
5 | import "./index.css";
6 | import { BrowserRouter, Routes, Route } from "react-router-dom";
7 | import Layout from "./components/Layout";
8 | import Inventory from "./pages/Inventory";
9 | import NoPageFound from "./pages/NoPageFound";
10 | import AuthContext from "./AuthContext";
11 | import ProtectedWrapper from "./ProtectedWrapper";
12 | import { useEffect, useState } from "react";
13 | import Store from "./pages/Store";
14 | import Sales from "./pages/Sales";
15 | import PurchaseDetails from "./pages/PurchaseDetails";
16 |
17 | const App = () => {
18 | const [user, setUser] = useState("");
19 | const [loader, setLoader] = useState(true);
20 | let myLoginUser = JSON.parse(localStorage.getItem("user"));
21 | // console.log("USER: ",user)
22 |
23 | useEffect(() => {
24 | if (myLoginUser) {
25 | setUser(myLoginUser._id);
26 | setLoader(false);
27 | // console.log("inside effect", myLoginUser)
28 | } else {
29 | setUser("");
30 | setLoader(false);
31 | }
32 | }, [myLoginUser]);
33 |
34 | const signin = (newUser, callback) => {
35 | setUser(newUser);
36 | callback();
37 | };
38 |
39 | const signout = () => {
40 | setUser(null);
41 | localStorage.removeItem("user");
42 | };
43 |
44 | let value = { user, signin, signout };
45 |
46 | if (loader)
47 | return (
48 |
56 |
LOADING...
57 |
58 | );
59 |
60 | return (
61 |
62 |
63 |
64 | } />
65 | } />
66 |
70 |
71 |
72 | }
73 | >
74 | } />
75 | } />
76 | } />
77 | } />
78 | } />
79 |
80 | } />
81 |
82 |
83 |
84 | );
85 | };
86 |
87 | export default App;
88 |
--------------------------------------------------------------------------------
/Frontend/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/Frontend/src/AuthContext.js:
--------------------------------------------------------------------------------
1 | import { createContext } from "react";
2 |
3 | let AuthContext = createContext(null);
4 |
5 | export default AuthContext;
6 |
--------------------------------------------------------------------------------
/Frontend/src/ProtectedWrapper.js:
--------------------------------------------------------------------------------
1 | import AuthContext from "./AuthContext";
2 | import { useContext } from "react";
3 | import { Navigate } from "react-router-dom";
4 |
5 | function ProtectedWrapper(props) {
6 | const auth = useContext(AuthContext);
7 | // console.log("====================================");
8 | // console.log(auth);
9 | // console.log("====================================");
10 |
11 | if (!auth.user) {
12 | return ;
13 | }
14 |
15 | return props.children;
16 | }
17 | export default ProtectedWrapper;
18 |
--------------------------------------------------------------------------------
/Frontend/src/assets/20943629.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/20943629.eps
--------------------------------------------------------------------------------
/Frontend/src/assets/License free.txt:
--------------------------------------------------------------------------------
1 | IMPORTANT NOTICE: This license only applies if you downloaded this content as
2 | an unsubscribed user. If you are a premium user (ie, you pay a subscription)
3 | you are bound to the license terms described in the accompanying file
4 | "License premium.txt".
5 |
6 | ---------------------
7 |
8 | You must attribute the image to its author:
9 |
10 | In order to use a content or a part of it, you must attribute it to vectorjuice / Freepik,
11 | so we will be able to continue creating new graphic resources every day.
12 |
13 |
14 | How to attribute it?
15 |
16 | For websites:
17 |
18 | Please, copy this code on your website to accredit the author:
19 | Designed by vectorjuice / Freepik
20 |
21 | For printing:
22 |
23 | Paste this text on the final work so the authorship is known.
24 | - For example, in the acknowledgements chapter of a book:
25 | "Designed by vectorjuice / Freepik"
26 |
27 |
28 | You are free to use this image:
29 |
30 | - For both personal and commercial projects and to modify it.
31 | - In a website or presentation template or application or as part of your design.
32 |
33 | You are not allowed to:
34 |
35 | - Sub-license, resell or rent it.
36 | - Include it in any online or offline archive or database.
37 |
38 | The full terms of the license are described in section 7 of the Freepik
39 | terms of use, available online in the following link:
40 |
41 | http://www.freepik.com/terms_of_use
42 |
43 | The terms described in the above link have precedence over the terms described
44 | in the present document. In case of disagreement, the Freepik Terms of Use
45 | will prevail.
46 |
--------------------------------------------------------------------------------
/Frontend/src/assets/License premium.txt:
--------------------------------------------------------------------------------
1 | IMPORTANT NOTICE: This license only applies if you downloaded this content as
2 | a subscribed (or "premium") user. If you are an unsubscribed user (or "free"
3 | user) you are bound to the license terms described in the accompanying file
4 | "License free.txt".
5 |
6 | ---------------------
7 |
8 | You can download from your profile in Freepik a personalized license stating
9 | your right to use this content as a "premium" user:
10 |
11 | https://profile.freepik.com/my_downloads
12 |
13 | You are free to use this image:
14 |
15 | - For both personal and commercial projects and to modify it.
16 | - In a website or presentation template or application or as part of your design.
17 |
18 | You are not allowed to:
19 |
20 | - Sub-license, resell or rent it.
21 | - Include it in any online or offline archive or database.
22 |
23 | The full terms of the license are described in sections 7 and 8 of the Freepik
24 | terms of use, available online in the following link:
25 |
26 | http://www.freepik.com/terms_of_use
27 |
28 | The terms described in the above link have precedence over the terms described
29 | in the present document. In case of disagreement, the Freepik Terms of Use
30 | will prevail.
31 |
--------------------------------------------------------------------------------
/Frontend/src/assets/Login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/Login.png
--------------------------------------------------------------------------------
/Frontend/src/assets/add-product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/add-product.png
--------------------------------------------------------------------------------
/Frontend/src/assets/dashboard-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/dashboard-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/download.png
--------------------------------------------------------------------------------
/Frontend/src/assets/filter-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/filter-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/inventory-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/inventory-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/location-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/location-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/logo.png
--------------------------------------------------------------------------------
/Frontend/src/assets/mi-logo (2).jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/mi-logo (2).jpg
--------------------------------------------------------------------------------
/Frontend/src/assets/mi-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/mi-logo.png
--------------------------------------------------------------------------------
/Frontend/src/assets/order-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/order-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/reports-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/reports-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/search-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/search-icon.png
--------------------------------------------------------------------------------
/Frontend/src/assets/signup-img.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/signup-img.zip
--------------------------------------------------------------------------------
/Frontend/src/assets/signup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/signup.jpg
--------------------------------------------------------------------------------
/Frontend/src/assets/store-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/store-image.jpg
--------------------------------------------------------------------------------
/Frontend/src/assets/supplier-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mhamzashaikh/React-Inventory-Management-System/6bfe18edb0fc097653ca0b45d7a9d6ebd0bdac56/Frontend/src/assets/supplier-icon.png
--------------------------------------------------------------------------------
/Frontend/src/components/AddProduct.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useContext, useRef, useState } from "react";
2 | import { Dialog, Transition } from "@headlessui/react";
3 | import { PlusIcon } from "@heroicons/react/24/outline";
4 | import AuthContext from "../AuthContext";
5 |
6 | export default function AddProduct({
7 | addProductModalSetting,
8 | handlePageUpdate,
9 | }) {
10 | const authContext = useContext(AuthContext);
11 | const [product, setProduct] = useState({
12 | userId: authContext.user,
13 | name: "",
14 | manufacturer: "",
15 | description: "",
16 | });
17 | console.log("----",product)
18 | const [open, setOpen] = useState(true);
19 | const cancelButtonRef = useRef(null);
20 |
21 | const handleInputChange = (key, value) => {
22 | setProduct({ ...product, [key]: value });
23 | };
24 |
25 | const addProduct = () => {
26 | fetch("http://localhost:4000/api/product/add", {
27 | method: "POST",
28 | headers: {
29 | "Content-type": "application/json",
30 | },
31 | body: JSON.stringify(product),
32 | })
33 | .then((result) => {
34 | alert("Product ADDED");
35 | handlePageUpdate();
36 | addProductModalSetting();
37 | })
38 | .catch((err) => console.log(err));
39 | };
40 |
41 | return (
42 | // Modal
43 |
44 |
246 |
247 | );
248 | }
249 |
--------------------------------------------------------------------------------
/Frontend/src/components/AddPurchaseDetails.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useRef, useState } from "react";
2 | import { Dialog, Transition } from "@headlessui/react";
3 | import { PlusIcon } from "@heroicons/react/24/outline";
4 |
5 | export default function AddPurchaseDetails({
6 | addSaleModalSetting,
7 | products,
8 | handlePageUpdate,
9 | authContext
10 | }) {
11 | const [purchase, setPurchase] = useState({
12 | userID: authContext.user,
13 | productID: "",
14 | quantityPurchased: "",
15 | purchaseDate: "",
16 | totalPurchaseAmount: "",
17 | });
18 | const [open, setOpen] = useState(true);
19 | const cancelButtonRef = useRef(null);
20 |
21 | console.log("PPu: ", purchase);
22 |
23 | // Handling Input Change for input fields
24 | const handleInputChange = (key, value) => {
25 | setPurchase({ ...purchase, [key]: value });
26 | };
27 |
28 | // POST Data
29 | const addSale = () => {
30 | fetch("http://localhost:4000/api/purchase/add", {
31 | method: "POST",
32 | headers: {
33 | "Content-type": "application/json",
34 | },
35 | body: JSON.stringify(purchase),
36 | })
37 | .then((result) => {
38 | alert("Purchase ADDED");
39 | handlePageUpdate();
40 | addSaleModalSetting();
41 | })
42 | .catch((err) => console.log(err));
43 | };
44 |
45 | return (
46 | // Modal
47 |
48 |
234 |
235 | );
236 | }
237 |
--------------------------------------------------------------------------------
/Frontend/src/components/AddSale.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useRef, useState } from "react";
2 | import { Dialog, Transition } from "@headlessui/react";
3 | import { PlusIcon } from "@heroicons/react/24/outline";
4 |
5 | export default function AddSale({
6 | addSaleModalSetting,
7 | products,
8 | stores,
9 | handlePageUpdate,
10 | authContext
11 | }) {
12 | const [sale, setSale] = useState({
13 | userID: authContext.user,
14 | productID: "",
15 | storeID: "",
16 | stockSold: "",
17 | saleDate: "",
18 | totalSaleAmount: "",
19 | });
20 | const [open, setOpen] = useState(true);
21 | const cancelButtonRef = useRef(null);
22 |
23 |
24 | // Handling Input Change for input fields
25 | const handleInputChange = (key, value) => {
26 | setSale({ ...sale, [key]: value });
27 | };
28 |
29 | // POST Data
30 | const addSale = () => {
31 | fetch("http://localhost:4000/api/sales/add", {
32 | method: "POST",
33 | headers: {
34 | "Content-type": "application/json",
35 | },
36 | body: JSON.stringify(sale),
37 | })
38 | .then((result) => {
39 | alert("Sale ADDED");
40 | handlePageUpdate();
41 | addSaleModalSetting();
42 | })
43 | .catch((err) => console.log(err));
44 | };
45 |
46 | return (
47 | // Modal
48 |
49 |
261 |
262 | );
263 | }
264 |
--------------------------------------------------------------------------------
/Frontend/src/components/AddStore.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useRef, useState, useContext } from "react";
2 | import { Dialog, Transition } from "@headlessui/react";
3 | import { PlusIcon } from "@heroicons/react/24/outline";
4 | import UploadImage from "./UploadImage";
5 | import AuthContext from "../AuthContext";
6 |
7 | export default function AddStore() {
8 | const authContext = useContext(AuthContext);
9 | const [form, setForm] = useState({
10 | userId: authContext.user,
11 | name: "",
12 | category: "",
13 | address: "",
14 | city: "",
15 | image: "",
16 | });
17 |
18 | const handleInputChange = (e) => {
19 | setForm({ ...form, [e.target.name]: e.target.value });
20 | };
21 |
22 | const [open, setOpen] = useState(true);
23 | const cancelButtonRef = useRef(null);
24 |
25 | const addProduct = () => {
26 | fetch("http://localhost:4000/api/store/add", {
27 | method: "POST",
28 | headers: {
29 | "Content-type": "application/json",
30 | },
31 | body: JSON.stringify(form),
32 | })
33 | .then((result) => {
34 | alert("STORE ADDED");
35 | setOpen(false);
36 | })
37 | .catch((err) => console.log(err));
38 | };
39 |
40 | // Uploading image to cloudinary
41 | const uploadImage = async (image) => {
42 | const data = new FormData();
43 | data.append("file", image);
44 | data.append("upload_preset", "inventoryapp");
45 |
46 | await fetch("https://api.cloudinary.com/v1_1/ddhayhptm/image/upload", {
47 | method: "POST",
48 | body: data,
49 | })
50 | .then((res) => res.json())
51 | .then((data) => {
52 | setForm({ ...form, image: data.url });
53 | alert("Store Image Successfully Uploaded");
54 | })
55 | .catch((error) => console.log(error));
56 | };
57 |
58 | return (
59 | // Modal
60 |
61 |
253 |
254 | );
255 | }
256 |
--------------------------------------------------------------------------------
/Frontend/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useContext } from "react";
2 | import { Disclosure, Menu, Transition } from "@headlessui/react";
3 | import { Bars3Icon, BellIcon, XMarkIcon } from "@heroicons/react/24/outline";
4 | import AuthContext from "../AuthContext";
5 | import { Link } from "react-router-dom";
6 |
7 | const navigation = [
8 | { name: "Dashboard", href: "/", current: true },
9 | { name: "Inventory", href: "/inventory", current: false },
10 | { name: "Purchase Details", href: "/purchase-details", current: false },
11 | { name: "Sales", href: "/sales", current: false },
12 | { name: "Manage Store", href: "/manage-store", current: false },
13 | ];
14 |
15 | const userNavigation = [{ name: "Sign out", href: "./login" }];
16 |
17 | function classNames(...classes) {
18 | return classes.filter(Boolean).join(" ");
19 | }
20 |
21 | export default function Header() {
22 | const authContext = useContext(AuthContext);
23 | const localStorageData = JSON.parse(localStorage.getItem("user"));
24 | return (
25 | <>
26 |
27 |
28 | {({ open }) => (
29 | <>
30 |
31 |
32 |
33 |
34 |
35 |
})
40 |
41 | Inventory Management
42 |
43 |
44 |
45 |
46 |
47 |
48 |
55 |
56 | {/* Profile dropdown */}
57 |
98 |
99 |
100 |
101 | {/* Mobile menu button */}
102 |
103 | Open main menu
104 | {open ? (
105 |
109 | ) : (
110 |
114 | )}
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | {navigation.map((item) => (
123 |
124 |
136 | {item.name}
137 |
138 |
139 | ))}
140 |
141 |
142 |
143 |
144 |

149 |
150 |
151 |
152 | {localStorageData.firstName +
153 | " " +
154 | localStorageData.lastName}
155 |
156 |
157 | {localStorageData.email}
158 |
159 |
160 |
167 |
168 |
169 | {userNavigation.map((item) => (
170 |
176 | authContext.signout()}>
177 | {item.name}{" "}
178 |
179 |
180 | ))}
181 |
182 |
183 |
184 | >
185 | )}
186 |
187 |
188 | >
189 | );
190 | }
191 |
--------------------------------------------------------------------------------
/Frontend/src/components/Layout.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Outlet } from "react-router-dom";
3 | import Header from "./Header";
4 | import SideMenu from "./SideMenu";
5 |
6 | function Layout() {
7 | return (
8 | <>
9 |
10 |
11 |
12 |
18 | >
19 | );
20 | }
21 |
22 | export default Layout;
23 |
--------------------------------------------------------------------------------
/Frontend/src/components/SideMenu.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | function SideMenu() {
5 | const localStorageData = JSON.parse(localStorage.getItem("user"));
6 |
7 | return (
8 |
9 |
10 |
68 |
69 |
70 |
71 |
72 |

77 |
78 |
79 |
80 |
81 | {localStorageData.firstName + " " + localStorageData.lastName}
82 |
83 |
84 | {localStorageData.email}
85 |
86 |
87 |
88 |
89 |
90 | );
91 | }
92 |
93 | export default SideMenu;
94 |
--------------------------------------------------------------------------------
/Frontend/src/components/UpdateProduct.js:
--------------------------------------------------------------------------------
1 | import { Fragment, useRef, useState } from "react";
2 | import { Dialog, Transition } from "@headlessui/react";
3 | import { PlusIcon } from "@heroicons/react/24/outline";
4 |
5 | export default function UpdateProduct({
6 | updateProductData,
7 | updateModalSetting,
8 | }) {
9 | const { _id, name, manufacturer, description } = updateProductData;
10 | const [product, setProduct] = useState({
11 | productID: _id,
12 | name: name,
13 | manufacturer: manufacturer,
14 | description: description,
15 | });
16 | const [open, setOpen] = useState(true);
17 | const cancelButtonRef = useRef(null);
18 |
19 | const handleInputChange = (key, value) => {
20 | console.log(key);
21 | setProduct({ ...product, [key]: value });
22 | };
23 |
24 | const updateProduct = () => {
25 | fetch("http://localhost:4000/api/product/update", {
26 | method: "POST",
27 | headers: {
28 | "Content-type": "application/json",
29 | },
30 | body: JSON.stringify(product),
31 | })
32 | .then((result) => {
33 | alert("Product Updated");
34 | setOpen(false);
35 | })
36 | .catch((err) => console.log(err));
37 | };
38 |
39 | return (
40 | // Modal
41 |
42 |
205 |
206 | );
207 | }
208 |
--------------------------------------------------------------------------------
/Frontend/src/components/UploadImage.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 |
3 | function UploadImage({ uploadImage }) {
4 | const [fileName, setFileName] = useState("");
5 |
6 | const handleFileInputChange = (event) => {
7 | setFileName(event.target.files[0]);
8 | uploadImage(event.target.files[0]);
9 | };
10 |
11 | return (
12 |
13 |
33 |
41 |
42 | );
43 | }
44 |
45 | export default UploadImage;
46 |
--------------------------------------------------------------------------------
/Frontend/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 |
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
10 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
11 | sans-serif;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | code {
17 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
18 | monospace;
19 | }
20 |
--------------------------------------------------------------------------------
/Frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/Frontend/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Dashboard.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect, useState } from "react";
2 | import Chart from "react-apexcharts";
3 | import AuthContext from "../AuthContext";
4 | import { Doughnut } from "react-chartjs-2";
5 | import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
6 |
7 | ChartJS.register(ArcElement, Tooltip, Legend);
8 | export const data = {
9 | labels: ["Apple", "Knorr", "Shoop", "Green", "Purple", "Orange"],
10 | datasets: [
11 | {
12 | label: "# of Votes",
13 | data: [0, 1, 5, 8, 9, 15],
14 | backgroundColor: [
15 | "rgba(255, 99, 132, 0.2)",
16 | "rgba(54, 162, 235, 0.2)",
17 | "rgba(255, 206, 86, 0.2)",
18 | "rgba(75, 192, 192, 0.2)",
19 | "rgba(153, 102, 255, 0.2)",
20 | "rgba(255, 159, 64, 0.2)",
21 | ],
22 | borderColor: [
23 | "rgba(255, 99, 132, 1)",
24 | "rgba(54, 162, 235, 1)",
25 | "rgba(255, 206, 86, 1)",
26 | "rgba(75, 192, 192, 1)",
27 | "rgba(153, 102, 255, 1)",
28 | "rgba(255, 159, 64, 1)",
29 | ],
30 | borderWidth: 1,
31 | },
32 | ],
33 | };
34 |
35 | function Dashboard() {
36 | const [saleAmount, setSaleAmount] = useState("");
37 | const [purchaseAmount, setPurchaseAmount] = useState("");
38 | const [stores, setStores] = useState([]);
39 | const [products, setProducts] = useState([]);
40 |
41 | const [chart, setChart] = useState({
42 | options: {
43 | chart: {
44 | id: "basic-bar",
45 | },
46 | xaxis: {
47 | categories: [
48 | "Jan",
49 | "Feb",
50 | "Mar",
51 | "Apr",
52 | "May",
53 | "Jun",
54 | "Jul",
55 | "Aug",
56 | "Sep",
57 | "Oct",
58 | "Nov",
59 | "Dec",
60 | ],
61 | },
62 | },
63 | series: [
64 | {
65 | name: "series",
66 | data: [10, 20, 40, 50, 60, 20, 10, 35, 45, 70, 25, 70],
67 | },
68 | ],
69 | });
70 |
71 | // Update Chart Data
72 | const updateChartData = (salesData) => {
73 | setChart({
74 | ...chart,
75 | series: [
76 | {
77 | name: "Monthly Sales Amount",
78 | data: [...salesData],
79 | },
80 | ],
81 | });
82 | };
83 |
84 | const authContext = useContext(AuthContext);
85 |
86 | useEffect(() => {
87 | fetchTotalSaleAmount();
88 | fetchTotalPurchaseAmount();
89 | fetchStoresData();
90 | fetchProductsData();
91 | fetchMonthlySalesData();
92 | }, []);
93 |
94 | // Fetching total sales amount
95 | const fetchTotalSaleAmount = () => {
96 | fetch(
97 | `http://localhost:4000/api/sales/get/${authContext.user}/totalsaleamount`
98 | )
99 | .then((response) => response.json())
100 | .then((datas) => setSaleAmount(datas.totalSaleAmount));
101 | };
102 |
103 | // Fetching total purchase amount
104 | const fetchTotalPurchaseAmount = () => {
105 | fetch(
106 | `http://localhost:4000/api/purchase/get/${authContext.user}/totalpurchaseamount`
107 | )
108 | .then((response) => response.json())
109 | .then((datas) => setPurchaseAmount(datas.totalPurchaseAmount));
110 | };
111 |
112 | // Fetching all stores data
113 | const fetchStoresData = () => {
114 | fetch(`http://localhost:4000/api/store/get/${authContext.user}`)
115 | .then((response) => response.json())
116 | .then((datas) => setStores(datas));
117 | };
118 |
119 | // Fetching Data of All Products
120 | const fetchProductsData = () => {
121 | fetch(`http://localhost:4000/api/product/get/${authContext.user}`)
122 | .then((response) => response.json())
123 | .then((datas) => setProducts(datas))
124 | .catch((err) => console.log(err));
125 | };
126 |
127 | // Fetching Monthly Sales
128 | const fetchMonthlySalesData = () => {
129 | fetch(`http://localhost:4000/api/sales/getmonthly`)
130 | .then((response) => response.json())
131 | .then((datas) => updateChartData(datas.salesAmount))
132 | .catch((err) => console.log(err));
133 | };
134 |
135 | return (
136 | <>
137 |
138 |
139 |
140 |
154 |
155 |
67.81%
156 |
157 |
158 |
159 |
160 | Sales
161 |
162 |
163 |
164 |
165 | ${saleAmount}
166 |
167 |
168 | from $240.94
169 |
170 |
171 |
172 |
173 |
174 |
175 |
189 |
190 |
67.81%
191 |
192 |
193 |
194 |
195 | Purchase
196 |
197 |
198 |
199 |
200 | {" "}
201 | ${purchaseAmount}{" "}
202 |
203 |
204 | from $404.32
205 |
206 |
207 |
208 |
209 |
210 |
224 |
225 |
67.81%
226 |
227 |
228 |
229 |
230 | Total Products
231 |
232 |
233 |
234 |
235 | {" "}
236 | {products.length}{" "}
237 |
238 |
239 | {/* from $404.32 */}
240 |
241 |
242 |
243 |
244 |
245 |
259 |
260 |
67.81%
261 |
262 |
263 |
264 |
265 | Total Stores
266 |
267 |
268 |
269 |
270 | {" "}
271 | {stores.length}{" "}
272 |
273 |
274 | {/* from 0 */}
275 |
276 |
277 |
278 |
279 |
280 |
286 |
287 |
288 |
289 |
290 |
291 |
292 | >
293 | );
294 | }
295 |
296 | export default Dashboard;
297 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Inventory.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useContext } from "react";
2 | import AddProduct from "../components/AddProduct";
3 | import UpdateProduct from "../components/UpdateProduct";
4 | import AuthContext from "../AuthContext";
5 |
6 | function Inventory() {
7 | const [showProductModal, setShowProductModal] = useState(false);
8 | const [showUpdateModal, setShowUpdateModal] = useState(false);
9 | const [updateProduct, setUpdateProduct] = useState([]);
10 | const [products, setAllProducts] = useState([]);
11 | const [searchTerm, setSearchTerm] = useState();
12 | const [updatePage, setUpdatePage] = useState(true);
13 | const [stores, setAllStores] = useState([]);
14 |
15 | const authContext = useContext(AuthContext);
16 | console.log('====================================');
17 | console.log(authContext);
18 | console.log('====================================');
19 |
20 | useEffect(() => {
21 | fetchProductsData();
22 | fetchSalesData();
23 | }, [updatePage]);
24 |
25 | // Fetching Data of All Products
26 | const fetchProductsData = () => {
27 | fetch(`http://localhost:4000/api/product/get/${authContext.user}`)
28 | .then((response) => response.json())
29 | .then((data) => {
30 | setAllProducts(data);
31 | })
32 | .catch((err) => console.log(err));
33 | };
34 |
35 | // Fetching Data of Search Products
36 | const fetchSearchData = () => {
37 | fetch(`http://localhost:4000/api/product/search?searchTerm=${searchTerm}`)
38 | .then((response) => response.json())
39 | .then((data) => {
40 | setAllProducts(data);
41 | })
42 | .catch((err) => console.log(err));
43 | };
44 |
45 | // Fetching all stores data
46 | const fetchSalesData = () => {
47 | fetch(`http://localhost:4000/api/store/get/${authContext.user}`)
48 | .then((response) => response.json())
49 | .then((data) => {
50 | setAllStores(data);
51 | });
52 | };
53 |
54 | // Modal for Product ADD
55 | const addProductModalSetting = () => {
56 | setShowProductModal(!showProductModal);
57 | };
58 |
59 | // Modal for Product UPDATE
60 | const updateProductModalSetting = (selectedProductData) => {
61 | console.log("Clicked: edit");
62 | setUpdateProduct(selectedProductData);
63 | setShowUpdateModal(!showUpdateModal);
64 | };
65 |
66 |
67 | // Delete item
68 | const deleteItem = (id) => {
69 | console.log("Product ID: ", id);
70 | console.log(`http://localhost:4000/api/product/delete/${id}`);
71 | fetch(`http://localhost:4000/api/product/delete/${id}`)
72 | .then((response) => response.json())
73 | .then((data) => {
74 | setUpdatePage(!updatePage);
75 | });
76 | };
77 |
78 | // Handle Page Update
79 | const handlePageUpdate = () => {
80 | setUpdatePage(!updatePage);
81 | };
82 |
83 | // Handle Search Term
84 | const handleSearchTerm = (e) => {
85 | setSearchTerm(e.target.value);
86 | fetchSearchData();
87 | };
88 |
89 | return (
90 |
91 |
92 |
93 |
Overall Inventory
94 |
95 |
96 |
97 | Total Products
98 |
99 |
100 | {products.length}
101 |
102 |
103 | Last 7 days
104 |
105 |
106 |
107 |
108 | Stores
109 |
110 |
111 |
112 |
113 | {stores.length}
114 |
115 |
116 | Last 7 days
117 |
118 |
119 |
120 |
121 | $2000
122 |
123 |
124 | Revenue
125 |
126 |
127 |
128 |
129 |
130 |
131 | Top Selling
132 |
133 |
134 |
135 |
136 | 5
137 |
138 |
139 | Last 7 days
140 |
141 |
142 |
143 |
144 | $1500
145 |
146 | Cost
147 |
148 |
149 |
150 |
151 |
152 | Low Stocks
153 |
154 |
155 |
156 |
157 | 12
158 |
159 |
160 | Ordered
161 |
162 |
163 |
164 |
165 | 2
166 |
167 |
168 | Not in Stock
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 | {showProductModal && (
177 |
181 | )}
182 | {showUpdateModal && (
183 |
187 | )}
188 |
189 | {/* Table */}
190 |
191 |
192 |
193 |
Products
194 |
195 |
})
200 |
207 |
208 |
209 |
210 |
217 |
218 |
219 |
220 |
221 |
222 |
223 | Products
224 | |
225 |
226 | Manufacturer
227 | |
228 |
229 | Stock
230 | |
231 |
232 | Description
233 | |
234 |
235 | Availibility
236 | |
237 |
238 | More
239 | |
240 |
241 |
242 |
243 |
244 | {products.map((element, index) => {
245 | return (
246 |
247 |
248 | {element.name}
249 | |
250 |
251 | {element.manufacturer}
252 | |
253 |
254 | {element.stock}
255 | |
256 |
257 | {element.description}
258 | |
259 |
260 | {element.stock > 0 ? "In Stock" : "Not in Stock"}
261 | |
262 |
263 | updateProductModalSetting(element)}
266 | >
267 | Edit{" "}
268 |
269 | deleteItem(element._id)}
272 | >
273 | Delete
274 |
275 | |
276 |
277 | );
278 | })}
279 |
280 |
281 |
282 |
283 |
284 | );
285 | }
286 |
287 | export default Inventory;
288 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Login.js:
--------------------------------------------------------------------------------
1 | // import { LockClosedIcon } from "@heroicons/react/20/solid";
2 | import { useContext, useState } from "react";
3 | import { Link, useNavigate } from "react-router-dom";
4 | import AuthContext from "../AuthContext";
5 |
6 | function Login() {
7 | const [form, setForm] = useState({
8 | email: "",
9 | password: "",
10 | });
11 |
12 | const authContext = useContext(AuthContext);
13 | const navigate = useNavigate();
14 |
15 |
16 | const handleInputChange = (e) => {
17 | setForm({ ...form, [e.target.name]: e.target.value });
18 | };
19 |
20 | const authCheck = () => {
21 | setTimeout(() => {
22 | fetch("http://localhost:4000/api/login")
23 | .then((response) => response.json())
24 | .then((data) => {
25 | alert("Successfully Login");
26 | localStorage.setItem("user", JSON.stringify(data));
27 | authContext.signin(data._id, () => {
28 | navigate("/");
29 | });
30 | })
31 | .catch((err) => {
32 | alert("Wrong credentials, Try again")
33 | console.log(err);
34 | });
35 | }, 3000);
36 | };
37 |
38 | const loginUser = (e) => {
39 | // Cannot send empty data
40 | if (form.email === "" || form.password === "") {
41 | alert("To login user, enter details to proceed...");
42 | } else {
43 | fetch("http://localhost:4000/api/login", {
44 | method: "POST",
45 | headers: {
46 | "Content-type": "application/json",
47 | },
48 | body: JSON.stringify(form),
49 | })
50 | .then((result) => {
51 | console.log("User login", result);
52 | })
53 | .catch((error) => {
54 | console.log("Something went wrong ", error);
55 | });
56 | }
57 | authCheck();
58 | };
59 |
60 |
61 | const handleSubmit = (e) => {
62 | e.preventDefault();
63 | };
64 |
65 |
66 | return (
67 | <>
68 |
69 |
70 |
})
71 |
72 |
73 |
74 |
})
79 |
80 | Signin to your account
81 |
82 |
83 | Or
84 |
87 | start your 14-day free trial
88 |
89 |
90 |
91 |
178 |
179 |
180 | >
181 | );
182 | }
183 |
184 | export default Login;
185 |
--------------------------------------------------------------------------------
/Frontend/src/pages/PurchaseDetails.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useContext } from "react";
2 | import AddPurchaseDetails from "../components/AddPurchaseDetails";
3 | import AuthContext from "../AuthContext";
4 |
5 | function PurchaseDetails() {
6 | const [showPurchaseModal, setPurchaseModal] = useState(false);
7 | const [purchase, setAllPurchaseData] = useState([]);
8 | const [products, setAllProducts] = useState([]);
9 | const [updatePage, setUpdatePage] = useState(true);
10 |
11 | const authContext = useContext(AuthContext);
12 |
13 | useEffect(() => {
14 | fetchPurchaseData();
15 | fetchProductsData();
16 | }, [updatePage]);
17 |
18 | // Fetching Data of All Purchase items
19 | const fetchPurchaseData = () => {
20 | fetch(`http://localhost:4000/api/purchase/get/${authContext.user}`)
21 | .then((response) => response.json())
22 | .then((data) => {
23 | setAllPurchaseData(data);
24 | })
25 | .catch((err) => console.log(err));
26 | };
27 |
28 | // Fetching Data of All Products
29 | const fetchProductsData = () => {
30 | fetch(`http://localhost:4000/api/product/get/${authContext.user}`)
31 | .then((response) => response.json())
32 | .then((data) => {
33 | setAllProducts(data);
34 | })
35 | .catch((err) => console.log(err));
36 | };
37 |
38 | // Modal for Sale Add
39 | const addSaleModalSetting = () => {
40 | setPurchaseModal(!showPurchaseModal);
41 | };
42 |
43 |
44 | // Handle Page Update
45 | const handlePageUpdate = () => {
46 | setUpdatePage(!updatePage);
47 | };
48 |
49 | return (
50 |
51 |
52 | {showPurchaseModal && (
53 |
59 | )}
60 | {/* Table */}
61 |
62 |
63 |
64 | Purchase Details
65 |
66 |
67 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | Product Name
81 | |
82 |
83 | Quantity Purchased
84 | |
85 |
86 | Purchase Date
87 | |
88 |
89 | Total Purchase Amount
90 | |
91 |
92 |
93 |
94 |
95 | {purchase.map((element, index) => {
96 | return (
97 |
98 |
99 | {element.ProductID?.name}
100 | |
101 |
102 | {element.QuantityPurchased}
103 | |
104 |
105 | {new Date(element.PurchaseDate).toLocaleDateString() ==
106 | new Date().toLocaleDateString()
107 | ? "Today"
108 | : element.PurchaseDate}
109 | |
110 |
111 | ${element.TotalPurchaseAmount}
112 | |
113 |
114 | );
115 | })}
116 |
117 |
118 |
119 |
120 |
121 | );
122 | }
123 |
124 | export default PurchaseDetails;
125 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Register.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 | import UploadImage from "../components/UploadImage";
4 |
5 | function Register() {
6 | const [form, setForm] = useState({
7 | firstName: "",
8 | lastName: "",
9 | email: "",
10 | password: "",
11 | phoneNumber: "",
12 | imageUrl: "",
13 | });
14 |
15 | const navigate = useNavigate();
16 |
17 | // Handling Input change for registration form.
18 | const handleInputChange = (e) => {
19 | setForm({ ...form, [e.target.name]: e.target.value });
20 | };
21 |
22 | // Register User
23 | const registerUser = () => {
24 | fetch("http://localhost:4000/api/register", {
25 | method: "POST",
26 | headers: {
27 | "Content-type": "application/json",
28 | },
29 | body: JSON.stringify(form),
30 | })
31 | .then((result) => {
32 | alert("Successfully Registered, Now Login with your details");
33 | navigate('/login')
34 |
35 | })
36 | .catch((err) => console.log(err));
37 | };
38 | // ------------------
39 |
40 | // Uploading image to cloudinary
41 | const uploadImage = async (image) => {
42 | const data = new FormData();
43 | data.append("file", image);
44 | data.append("upload_preset", "inventoryapp");
45 |
46 | await fetch("https://api.cloudinary.com/v1_1/ddhayhptm/image/upload", {
47 | method: "POST",
48 | body: data,
49 | })
50 | .then((res) => res.json())
51 | .then((data) => {
52 | setForm({ ...form, imageUrl: data.url });
53 | alert("Image Successfully Uploaded");
54 | })
55 | .catch((error) => console.log(error));
56 | };
57 |
58 |
59 | const handleSubmit = (e) => {
60 | e.preventDefault();
61 | }
62 |
63 | return (
64 | <>
65 |
66 |
67 |
68 |
})
73 |
74 | Register your account
75 |
76 |
77 |
193 |
194 |
195 |
})
196 |
197 |
198 | >
199 | );
200 | }
201 |
202 | export default Register;
203 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Sales.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useContext } from "react";
2 | import AddSale from "../components/AddSale";
3 | import AuthContext from "../AuthContext";
4 |
5 | function Sales() {
6 | const [showSaleModal, setShowSaleModal] = useState(false);
7 | const [sales, setAllSalesData] = useState([]);
8 | const [products, setAllProducts] = useState([]);
9 | const [stores, setAllStores] = useState([]);
10 | const [updatePage, setUpdatePage] = useState(true);
11 |
12 | const authContext = useContext(AuthContext);
13 |
14 | useEffect(() => {
15 | fetchSalesData();
16 | fetchProductsData();
17 | fetchStoresData();
18 | }, [updatePage]);
19 |
20 | // Fetching Data of All Sales
21 | const fetchSalesData = () => {
22 | fetch(`http://localhost:4000/api/sales/get/${authContext.user}`)
23 | .then((response) => response.json())
24 | .then((data) => {
25 | setAllSalesData(data);
26 | })
27 | .catch((err) => console.log(err));
28 | };
29 |
30 | // Fetching Data of All Products
31 | const fetchProductsData = () => {
32 | fetch(`http://localhost:4000/api/product/get/${authContext.user}`)
33 | .then((response) => response.json())
34 | .then((data) => {
35 | setAllProducts(data);
36 | })
37 | .catch((err) => console.log(err));
38 | };
39 |
40 | // Fetching Data of All Stores
41 | const fetchStoresData = () => {
42 | fetch(`http://localhost:4000/api/store/get/${authContext.user}`)
43 | .then((response) => response.json())
44 | .then((data) => {
45 | setAllStores(data);
46 | });
47 | };
48 |
49 | // Modal for Sale Add
50 | const addSaleModalSetting = () => {
51 | setShowSaleModal(!showSaleModal);
52 | };
53 |
54 | // Handle Page Update
55 | const handlePageUpdate = () => {
56 | setUpdatePage(!updatePage);
57 | };
58 |
59 | return (
60 |
61 |
62 | {showSaleModal && (
63 |
70 | )}
71 | {/* Table */}
72 |
73 |
74 |
75 | Sales
76 |
77 |
78 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Product Name
92 | |
93 |
94 | Store Name
95 | |
96 |
97 | Stock Sold
98 | |
99 |
100 | Sales Date
101 | |
102 |
103 | Total Sale Amount
104 | |
105 |
106 |
107 |
108 |
109 | {sales.map((element, index) => {
110 | return (
111 |
112 |
113 | {element.ProductID?.name}
114 | |
115 |
116 | {element.StoreID?.name}
117 | |
118 |
119 | {element.StockSold}
120 | |
121 |
122 | {element.SaleDate}
123 | |
124 |
125 | ${element.TotalSaleAmount}
126 | |
127 |
128 | );
129 | })}
130 |
131 |
132 |
133 |
134 |
135 | );
136 | }
137 |
138 | export default Sales;
139 |
--------------------------------------------------------------------------------
/Frontend/src/pages/Store.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useContext } from "react";
2 | import AddStore from "../components/AddStore";
3 | import AuthContext from "../AuthContext";
4 |
5 | function Store() {
6 | const [showModal, setShowModal] = useState(false);
7 | const [stores, setAllStores] = useState([]);
8 |
9 | const authContext = useContext(AuthContext);
10 |
11 | useEffect(() => {
12 | fetchData();
13 | }, []);
14 |
15 | // Fetching all stores data
16 | const fetchData = () => {
17 | fetch(`http://localhost:4000/api/store/get/${authContext.user}`)
18 | .then((response) => response.json())
19 | .then((data) => {
20 | setAllStores(data);
21 | });
22 | };
23 |
24 | const modalSetting = () => {
25 | setShowModal(!showModal);
26 | };
27 |
28 | return (
29 |
30 |
31 |
32 | Manage Store
33 |
39 |
40 | {showModal &&
}
41 | {stores.map((element, index) => {
42 | return (
43 |
47 |
48 |

53 |
54 |
55 |
{element.name}
56 |
57 |
})
62 |
{element.address + ", " + element.city}
63 |
64 |
65 |
66 | );
67 | })}
68 |
69 |
70 | );
71 | }
72 |
73 | export default Store;
74 |
--------------------------------------------------------------------------------
/Frontend/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/Frontend/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/Frontend/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/**/*.{js,jsx,ts,tsx}",
5 | ],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [
10 | // ...
11 | require("@tailwindcss/forms"),
12 | ],
13 | };
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React-Inventory-Management-System
2 | Inventory Management System Built with React JS, Node JS, Express JS, MongoDB and Tailwind CSS.
3 |
4 | ### Show Some Support!
5 | [](https://www.buymeacoffee.com/hamzashaikh)
6 |
7 |
8 | # [View Live Preview from here.](https://inventory-management-rosy.vercel.app)
9 |
--------------------------------------------------------------------------------