Index: backend/models/orderModel.js
===================================================================
--- backend/models/orderModel.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ backend/models/orderModel.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,49 @@
+import mongoose from "mongoose";
+
+const orderSchema = new mongoose.Schema(
+  {
+    orderItems: [
+      {
+        slug: { type: String, required: true },
+        name: { type: String, required: true },
+        quantity: { type: Number, required: true },
+        image: { type: String, required: true },
+        price: { type: Number, required: true },
+        product: {
+          type: mongoose.Schema.Types.ObjectId,
+          ref: "Product",
+          required: true,
+        },
+      },
+    ],
+    shippingAddress: {
+      fullName: { type: String, required: true },
+      address: { type: String, required: true },
+      city: { type: String, required: true },
+      postalCode: { type: String, required: true },
+      country: { type: String, required: true },
+    },
+    paymentMethod: { type: String, required: true },
+    paymentResult: {
+      id: String,
+      status: String,
+      update_time: String,
+      email_address: String,
+    },
+    itemsPrice: { type: Number, required: true },
+    shippingPrice: { type: Number, required: true },
+    totalPrice: { type: Number, required: true },
+    user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
+    isPaid: { type: Boolean, default: false },
+    paidAt: { type: Date },
+    paidAtFormat: { type: String },
+    isDelivered: { type: Boolean, default: false },
+    deliveredAt: { type: Date },
+  },
+  {
+    timestamps: true,
+  }
+);
+
+const Order = mongoose.model("Order", orderSchema);
+export default Order;
Index: backend/models/userModel.js
===================================================================
--- backend/models/userModel.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ backend/models/userModel.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -4,4 +4,5 @@
   {
     name: { type: String, required: true },
+    contact: { type: String, required: true },
     email: { type: String, required: true, unique: true },
     password: { type: String, required: true },
Index: backend/package-lock.json
===================================================================
--- backend/package-lock.json	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ backend/package-lock.json	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -13,4 +13,6 @@
         "dotenv": "^16.0.1",
         "express": "^4.18.1",
+        "express-async-handler": "^1.2.0",
+        "jsonwebtoken": "^8.5.1",
         "mongoose": "^6.5.3"
       },
@@ -192,4 +194,9 @@
       }
     },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
     "node_modules/bytes": {
       "version": "3.1.2",
@@ -316,4 +323,12 @@
       "engines": {
         "node": ">=12"
+      }
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
       }
     },
@@ -385,4 +400,9 @@
       }
     },
+    "node_modules/express-async-handler": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz",
+      "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w=="
+    },
     "node_modules/fill-range": {
       "version": "7.0.1",
@@ -616,8 +636,88 @@
       }
     },
+    "node_modules/jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=4",
+        "npm": ">=1.4.28"
+      }
+    },
+    "node_modules/jsonwebtoken/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
+    "node_modules/jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "dependencies": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "node_modules/kareem": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz",
       "integrity": "sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA=="
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
     },
     "node_modules/media-typer": {
@@ -1021,5 +1121,4 @@
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
       "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
       "bin": {
         "semver": "bin/semver"
@@ -1396,4 +1495,9 @@
       }
     },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
     "bytes": {
       "version": "3.1.2",
@@ -1482,4 +1586,12 @@
       "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
       "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ=="
+    },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
     },
     "ee-first": {
@@ -1541,4 +1653,9 @@
       }
     },
+    "express-async-handler": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/express-async-handler/-/express-async-handler-1.2.0.tgz",
+      "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w=="
+    },
     "fill-range": {
       "version": "7.0.1",
@@ -1700,8 +1817,86 @@
       "dev": true
     },
+    "jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "requires": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+        }
+      }
+    },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "kareem": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz",
       "integrity": "sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA=="
+    },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
     },
     "media-typer": {
@@ -1987,6 +2182,5 @@
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
     },
     "send": {
Index: backend/package.json
===================================================================
--- backend/package.json	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ backend/package.json	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -15,4 +15,6 @@
     "dotenv": "^16.0.1",
     "express": "^4.18.1",
+    "express-async-handler": "^1.2.0",
+    "jsonwebtoken": "^8.5.1",
     "mongoose": "^6.5.3"
   },
Index: backend/routes/orderRoutes.js
===================================================================
--- backend/routes/orderRoutes.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ backend/routes/orderRoutes.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,51 @@
+import express from "express";
+import expressAsyncHandler from "express-async-handler";
+import Order from "../models/orderModel.js";
+import bcrypt from "bcryptjs";
+import { isAuth } from "../utils.js";
+
+const orderRouter = express.Router();
+
+orderRouter.post(
+  "/",
+  isAuth,
+  expressAsyncHandler(async (req, res) => {
+    const newOrder = new Order({
+      orderItems: req.body.orderItems.map((x) => ({ ...x, product: x._id })),
+      shippingAddress: req.body.shippingAddress,
+      paymentMethod: req.body.paymentMethod,
+      itemsPrice: req.body.itemsPrice,
+      shippingPrice: req.body.shippingPrice,
+      totalPrice: req.body.totalPrice,
+      user: req.user._id,
+      isPaid: req.body.isPaid,
+      paidAt: req.body.paidAt,
+    });
+    const order = await newOrder.save();
+    res.status(201).send({ message: "New Order Created", order });
+  })
+);
+
+orderRouter.get(
+  "/mine",
+  isAuth,
+  expressAsyncHandler(async (req, res) => {
+    const orders = await Order.find({ user: req.user._id });
+    res.send(orders);
+  })
+);
+
+orderRouter.get(
+  "/:id",
+  isAuth,
+  expressAsyncHandler(async (req, res) => {
+    const order = await Order.findById(req.params.id);
+    if (order) {
+      res.send(order);
+    } else {
+      res.status(404).send({ message: "Order Not Found" });
+    }
+  })
+);
+
+export default orderRouter;
Index: backend/routes/userRoutes.js
===================================================================
--- backend/routes/userRoutes.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ backend/routes/userRoutes.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,51 @@
+import express from "express";
+import expressAsyncHandler from "express-async-handler";
+import User from "../models/userModel.js";
+import bcrypt from "bcryptjs";
+import { generateToken } from "../utils.js";
+
+const userRouter = express.Router();
+
+userRouter.post(
+  "/signin",
+  expressAsyncHandler(async (req, res) => {
+    const user = await User.findOne({ email: req.body.email });
+    if (user) {
+      if (bcrypt.compareSync(req.body.password, user.password)) {
+        res.send({
+          _id: user.id,
+          name: user.name,
+          contact: user.contact,
+          email: user.email,
+          isAdmin: user.isAdmin,
+          token: generateToken(user),
+        });
+        return;
+      }
+    }
+    res.status(401).send({ message: "Invalid email or password" });
+  })
+);
+
+userRouter.post(
+  "/signup",
+  expressAsyncHandler(async (req, res) => {
+    const newUser = new User({
+      name: req.body.name,
+      contact: req.body.contact,
+      email: req.body.email,
+      password: bcrypt.hashSync(req.body.password),
+    });
+    const user = await newUser.save();
+    res.send({
+      _id: user.id,
+      name: user.name,
+      contact: user.contact,
+      email: user.email,
+      isAdmin: user.isAdmin,
+      token: generateToken(user),
+    });
+  })
+);
+
+export default userRouter;
Index: backend/server.js
===================================================================
--- backend/server.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ backend/server.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -5,4 +5,6 @@
 import seedRouter from "./routes/seedRoutes.js";
 import productRouter from "./routes/productRoutes.js";
+import userRouter from "./routes/userRoutes.js";
+import orderRouter from "./routes/orderRoutes.js";
 
 dotenv.config();
@@ -18,6 +20,16 @@
 
 const app = express();
+
+app.use(express.json());
+app.use(express.urlencoded({ extended: true }));
+
 app.use("/api/seed", seedRouter);
 app.use("/api/products", productRouter);
+app.use("/api/users", userRouter);
+app.use("/api/orders", orderRouter);
+
+app.use((err, req, res, next) => {
+  res.status(500).send({ message: err.message });
+});
 
 const port = process.env.PORT || 5000;
Index: backend/utils.js
===================================================================
--- backend/utils.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ backend/utils.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,25 @@
+import jwt from "jsonwebtoken";
+export const generateToken = (user) => {
+  return jwt.sign(
+    { _id: user.id, name: user.name, email: user.email, isAdmin: user.isAdmin },
+    process.env.JWT_SECRET,
+    { expiresIn: "30d" }
+  );
+};
+
+export const isAuth = (req, res, next) => {
+  const authorization = req.headers.authorization;
+  if (authorization) {
+    const token = authorization.slice(7, authorization.length);
+    jwt.verify(token, process.env.JWT_SECRET, (err, decode) => {
+      if (err) {
+        res.status(401).send({ message: "Invalid Token" });
+      } else {
+        req.user = decode;
+        next();
+      }
+    });
+  } else {
+    res.status(401).send({ message: "No Token" });
+  }
+};
Index: frontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/package-lock.json	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -28,4 +28,5 @@
         "react-router-dom": "^6.3.0",
         "react-scripts": "5.0.1",
+        "react-toastify": "^9.0.8",
         "web-vitals": "^2.1.4"
       }
@@ -14659,4 +14660,16 @@
       }
     },
+    "node_modules/react-toastify": {
+      "version": "9.0.8",
+      "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz",
+      "integrity": "sha512-EwM+teWt49HSHx+67qI08yLAW1zAsBxCXLCsUfxHYv1W7/R3ZLhrqKalh7j+kjgPna1h5LQMSMwns4tB4ww2yQ==",
+      "dependencies": {
+        "clsx": "^1.1.1"
+      },
+      "peerDependencies": {
+        "react": ">=16",
+        "react-dom": ">=16"
+      }
+    },
     "node_modules/react-transition-group": {
       "version": "4.4.5",
@@ -27673,4 +27686,12 @@
       }
     },
+    "react-toastify": {
+      "version": "9.0.8",
+      "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz",
+      "integrity": "sha512-EwM+teWt49HSHx+67qI08yLAW1zAsBxCXLCsUfxHYv1W7/R3ZLhrqKalh7j+kjgPna1h5LQMSMwns4tB4ww2yQ==",
+      "requires": {
+        "clsx": "^1.1.1"
+      }
+    },
     "react-transition-group": {
       "version": "4.4.5",
Index: frontend/package.json
===================================================================
--- frontend/package.json	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/package.json	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -24,4 +24,5 @@
     "react-router-dom": "^6.3.0",
     "react-scripts": "5.0.1",
+    "react-toastify": "^9.0.8",
     "web-vitals": "^2.1.4"
   },
Index: frontend/src/App.js
===================================================================
--- frontend/src/App.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/App.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -11,4 +11,13 @@
 import CategoryScreen from "./screens/CategoryScreen";
 import SigninScreen from "./screens/SigninScreen";
+import { ToastContainer } from "react-toastify";
+import "react-toastify/dist/ReactToastify.css";
+import ShippingAddressScreen from "./screens/ShippingAddressScreen";
+import SignupScreen from "./screens/SignupScreen";
+import PaymentMethodScreen from "./screens/PaymentMethodScreen";
+import PlaceOrderScreen from "./screens/PlaceOrderScreen";
+import OrderScreen from "./screens/OrderScreen";
+import CardPaymentScreen from "./screens/CardPaymentScreen";
+import OrderHistoryScreen from "./screens/OrderHistoryScreen";
 
 function App() {
@@ -17,4 +26,5 @@
   return (
     <BrowserRouter>
+      <ToastContainer position="bottom-center" limit={1} />
       <Header />
 
@@ -24,4 +34,11 @@
         <Route path="/cart" element={<CartScreen />} />
         <Route path="/signin" element={<SigninScreen />} />
+        <Route path="/signup" element={<SignupScreen />} />
+        <Route path="/shipping" element={<ShippingAddressScreen />} />
+        <Route path="/payment" element={<PaymentMethodScreen />} />
+        <Route path="/placeorder" element={<PlaceOrderScreen />} />
+        <Route path="placeorder/payment" element={<CardPaymentScreen />} />
+        <Route path="/orderhistory" element={<OrderHistoryScreen />} />
+        <Route path="/order/:id" element={<OrderScreen />} />
         <Route path="/products" element={<CategoryScreen />} />
       </Routes>
Index: frontend/src/Store.js
===================================================================
--- frontend/src/Store.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/Store.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -4,5 +4,14 @@
 
 const initialState = {
+  userInfo: localStorage.getItem("userInfo")
+    ? JSON.parse(localStorage.getItem("userInfo"))
+    : null,
   cart: {
+    shippingAddress: localStorage.getItem("shippingAddress")
+      ? JSON.parse(localStorage.getItem("shippingAddress"))
+      : {},
+    paymentMethod: localStorage.getItem("paymentMethod")
+      ? localStorage.getItem("paymentMethod")
+      : "",
     cartItems: localStorage.getItem("cartItems")
       ? JSON.parse(localStorage.getItem("cartItems"))
@@ -32,4 +41,24 @@
       return { ...state, cart: { ...state.cart, cartItems } };
     }
+    case "CART_CLEAR":
+      return { ...state, cart: { ...state.cart, cartItems: [] } };
+    case "USER_SIGNIN":
+      return { ...state, userInfo: action.payload };
+    case "USER_SIGNOUT":
+      return {
+        ...state,
+        userInfo: null,
+        cart: { cartItems: [], shippingAddress: {}, paymentMethod: "" },
+      };
+    case "SAVE_SHIPPING_ADDRESS":
+      return {
+        ...state,
+        cart: { ...state.cart, shippingAddress: action.payload },
+      };
+    case "SAVE_PAYMENT_METHOD":
+      return {
+        ...state,
+        cart: { ...state.cart, paymentMethod: action.payload },
+      };
     default:
       return state;
Index: frontend/src/components/CheckoutSteps.js
===================================================================
--- frontend/src/components/CheckoutSteps.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/components/CheckoutSteps.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,16 @@
+import React from "react";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+
+function CheckoutSteps(props) {
+  return (
+    <Row className="checkout-steps">
+      <Col className={props.step1 ? "active" : ""}>Најава</Col>
+      <Col className={props.step2 ? "active" : ""}>Адреса</Col>
+      <Col className={props.step3 ? "active" : ""}>Плаќање</Col>
+      <Col className={props.step4 ? "active" : ""}>Потврди</Col>
+    </Row>
+  );
+}
+
+export default CheckoutSteps;
Index: frontend/src/components/Header.js
===================================================================
--- frontend/src/components/Header.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/components/Header.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -16,5 +16,5 @@
 import ShoppingBasketIcon from "@mui/icons-material/ShoppingCart";
 import MenuIcon from "@mui/icons-material/Menu";
-import { Link } from "react-router-dom";
+import { Link, NavLink, useNavigate } from "react-router-dom";
 import logo2 from "../Images/logo2.png";
 import Badge from "react-bootstrap/Badge";
@@ -22,6 +22,8 @@
 import { Store } from "../Store";
 import { useContext } from "react";
+import NavDropdown from "react-bootstrap/NavDropdown";
 
 const toggleMenu = (event) => {
+  event.stopPropagation();
   let menu = document.querySelector(".mobile-menu-container");
   menu.classList.remove("hidden");
@@ -30,4 +32,5 @@
 
 const toggleSubMenu = (event) => {
+  event.stopPropagation();
   let menu = document.querySelector(".subDropdown");
   menu.classList.remove("hidden");
@@ -68,6 +71,15 @@
 
 function Header() {
-  const { state } = useContext(Store);
-  const { cart } = state;
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const { cart, userInfo } = state;
+  const navigate = useNavigate();
+
+  const signoutHandler = () => {
+    ctxDispatch({ type: "USER_SIGNOUT" });
+    localStorage.removeItem("userInfo");
+    localStorage.removeItem("shippingAddress");
+    localStorage.removeItem("paymentMethod");
+  };
+
   return (
     <div className="header">
@@ -78,5 +90,12 @@
           onClick={toggleMenu}
         />
-        <img className="header__icon" src={logo2} alt="logo"></img>
+        <img
+          className="header__icon"
+          src={logo2}
+          alt="logo"
+          onClick={() => {
+            navigate("/");
+          }}
+        ></img>
       </div>
       <div className="mobile-menu-container hidden">
@@ -85,5 +104,11 @@
         </div>
         <ul className="mobile-menu">
-          <li>Почетна</li>
+          <Link
+            to="/"
+            style={{ textDecoration: "none", color: "black" }}
+            onClick={closeMenu}
+          >
+            <li>Почетна</li>
+          </Link>
           <li onClick={toggleSubMenu} className="subMenu">
             Производи <ArrowDropDownIcon />
@@ -492,8 +517,57 @@
       <div className="header__right">
         <div className="header__buttons">
-          <span>
-            <AccountCircleIcon className="header__login" fontSize="large" />
-            <p>Најави се</p>
-          </span>
+          {userInfo ? (
+            <NavDropdown
+              title={
+                <span>
+                  <AccountCircleIcon
+                    className="header__login"
+                    fontSize="large"
+                  />
+                  <p>{userInfo.name}</p>
+                </span>
+              }
+              id="basic-nav-dropdown"
+            >
+              <NavDropdown.Item
+                onClick={() => {
+                  navigate("/profile");
+                }}
+              >
+                Профил
+              </NavDropdown.Item>
+
+              <NavDropdown.Item
+                onClick={() => {
+                  navigate("/orderhistory");
+                }}
+              >
+                Нарачки
+              </NavDropdown.Item>
+
+              <NavDropdown.Divider />
+              <Link
+                className="drowdown-item"
+                to="#signout"
+                onClick={signoutHandler}
+              >
+                Одјави се
+              </Link>
+            </NavDropdown>
+          ) : (
+            <Link
+              to={"/signin"}
+              className="link"
+              onClick={() => {
+                navigate("/orderhistory");
+              }}
+            >
+              <span>
+                <AccountCircleIcon className="header__login" fontSize="large" />
+                <p>Најави се</p>
+              </span>
+            </Link>
+          )}
+
           <Link to="/cart" className="badgee">
             <span>
Index: frontend/src/index.css
===================================================================
--- frontend/src/index.css	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/index.css	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,9 @@
+.checkout-steps > div {
+  border-bottom: 0.2rem solid #a0a0a0;
+  color: #a0a0a0;
+}
+
+.checkout-steps > div.active {
+  border-bottom: 0.2rem solid #f08000;
+  color: #f08000;
+}
Index: frontend/src/screens/CardPaymentScreen.js
===================================================================
--- frontend/src/screens/CardPaymentScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/CardPaymentScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,160 @@
+import React, { useContext, useEffect, useReducer, useState } from "react";
+import Container from "react-bootstrap/Container";
+import { Helmet } from "react-helmet-async";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/Button";
+import { useNavigate, useParams } from "react-router-dom";
+import { Store } from "../Store";
+import axios from "axios";
+import { getError } from "../components/utils";
+import { toast } from "react-toastify";
+
+const reducer = (state, action) => {
+  switch (action.type) {
+    case "CREATE_REQUEST":
+      return { ...state, loading: true };
+    case "CREATE_SUCCESS":
+      return { ...state, loading: false };
+    case "CREATE_FAIL":
+      return { ...state, loading: false };
+    default:
+      return state;
+  }
+};
+
+function CardPaymentScreen() {
+  const [validated, setValidated] = useState(false);
+  const navigate = useNavigate();
+
+  const [{ loading }, dispatch] = useReducer(reducer, {
+    loading: false,
+  });
+
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const { cart, userInfo } = state;
+
+  const round2 = (num) => Math.round(num * 100 + Number.EPSILON) / 100;
+  cart.itemsPrice = round2(
+    cart.cartItems.reduce((a, c) => a + c.quantity * c.price, 0)
+  );
+  cart.shippingPrice = cart.itemsPrice > 1500 ? round2(0) : round2(150);
+  cart.totalPrice = cart.itemsPrice + cart.shippingPrice;
+
+  const paymentHandler = async (event) => {
+    event.preventDefault();
+    const form = event.currentTarget;
+    if (form.checkValidity() === false) {
+      event.preventDefault();
+      event.stopPropagation();
+    }
+    setValidated(true);
+    if (form.checkValidity() === true) {
+      try {
+        dispatch({ type: "CREATE_REQUEST" });
+        const { data } = await axios.post(
+          "/api/orders",
+          {
+            orderItems: cart.cartItems,
+            shippingAddress: cart.shippingAddress,
+            paymentMethod: cart.paymentMethod,
+            itemsPrice: cart.itemsPrice,
+            shippingPrice: cart.shippingPrice,
+            totalPrice: cart.totalPrice,
+            isPaid: true,
+            paidAt: Date.now(),
+          },
+          {
+            headers: {
+              authorization: `Bearer ${userInfo.token}`,
+            },
+          }
+        );
+        ctxDispatch({ type: "CART_CLEAR" });
+        dispatch({ type: "CREATE_SUCCESS" });
+        localStorage.removeItem("cartItems");
+        navigate(`/order/${data.order._id}`);
+      } catch (err) {
+        dispatch({ type: "CREATE_FAIL" });
+        toast.error(getError(err));
+      }
+    }
+  };
+
+  return (
+    <div className="pageContainer">
+      <Container className="pageContainer shipPC">
+        <Helmet>
+          <title>Плати нарачка</title>
+        </Helmet>
+        <Form
+          noValidate
+          validated={validated}
+          onSubmit={paymentHandler}
+          className="formCointainer"
+        >
+          <Form.Group id="nameInput">
+            <Form.Label>Име и Презиме</Form.Label>
+            <Form.Control
+              type="text"
+              //value={holderName}
+              // onChange={(e) => setHolderName(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Број на картичка</Form.Label>
+            <Form.Control
+              type="text"
+              //value={cardNumber}
+              //onChange={(e) => setCardNumber(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>CVV2/CVC2</Form.Label>
+            <Form.Control
+              type="text"
+              //value={cvv}
+              //onChange={(e) => setCvv(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Рок на важност</Form.Label>
+            <div style={{ display: "flex" }}>
+              <Form.Select style={{ width: "47%", margin: "auto" }}>
+                <option value="01">01</option>
+                <option value="02">02</option>
+                <option value="03">03</option>
+                <option value="04">04</option>
+                <option value="05">05</option>
+                <option value="06">06</option>
+                <option value="07">07</option>
+                <option value="08">08</option>
+                <option value="09">09</option>
+                <option value="10">10</option>
+                <option value="11">11</option>
+                <option value="12">12</option>
+              </Form.Select>
+              <Form.Select style={{ width: "47%", margin: "auto" }}>
+                <option value="01">22</option>
+                <option value="02">23</option>
+                <option value="03">24</option>
+                <option value="04">25</option>
+                <option value="05">26</option>
+              </Form.Select>
+            </div>
+          </Form.Group>
+
+          <div className="submitBtnContainer">
+            <Button variant="danger" size="lg" type="submit">
+              Плати
+            </Button>
+          </div>
+        </Form>
+      </Container>
+    </div>
+  );
+}
+
+export default CardPaymentScreen;
Index: frontend/src/screens/OrderHistoryScreen.js
===================================================================
--- frontend/src/screens/OrderHistoryScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/OrderHistoryScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,108 @@
+import axios from "axios";
+import React, { useContext, useEffect, useReducer } from "react";
+import { Helmet } from "react-helmet-async";
+import { useNavigate } from "react-router-dom";
+import LoadingBox from "../components/LoadingBox";
+import MessageBox from "../components/MessageBox";
+import { getError } from "../components/utils";
+import { Store } from "../Store";
+import Button from "react-bootstrap/Button";
+import CheckIcon from "@mui/icons-material/Check";
+import ClearIcon from "@mui/icons-material/Clear";
+const reducer = (state, action) => {
+  switch (action.type) {
+    case "FETCH_REQUEST":
+      return { ...state, loading: true };
+    case "FETCH_SUCCESS":
+      return { ...state, orders: action.payload, loading: false };
+    case "FETCH_FAIL":
+      return { ...state, loading: false, error: action.payload };
+    default:
+      return state;
+  }
+};
+
+function OrderHistoryScreen() {
+  const { state } = useContext(Store);
+  const { userInfo } = state;
+  const navigate = useNavigate();
+
+  const [{ loading, error, orders }, dispatch] = useReducer(reducer, {
+    loading: true,
+    error: "",
+  });
+
+  useEffect(() => {
+    const fetchData = async () => {
+      dispatch({ type: "FETCH_REQUEST" });
+      try {
+        const { data } = await axios.get("/api/orders/mine", {
+          headers: { Authorization: `Bearer ${userInfo.token}` },
+        });
+        dispatch({ type: "FETCH_SUCCESS", payload: data });
+      } catch (error) {
+        dispatch({ type: "FETCH_FAIL", payload: getError(error) });
+      }
+    };
+    fetchData();
+  }, [userInfo]);
+
+  return (
+    <div className="pageContainer shipPC">
+      <Helmet>
+        <title>Историја на нарачки</title>
+      </Helmet>
+      <h1 style={{ marginTop: "20px" }}>Историја на нарачки</h1>
+      {loading ? (
+        <LoadingBox></LoadingBox>
+      ) : error ? (
+        <MessageBox variant="danger">{error}</MessageBox>
+      ) : (
+        <table
+          className="table"
+          style={{ marginTop: "20px", width: "90%", textAlign: "center" }}
+        >
+          <thead>
+            <tr>
+              <th>ID</th>
+              <th>Дата</th>
+              <th>Вкупно</th>
+              <th>Статус</th>
+              <th>Акции</th>
+            </tr>
+          </thead>
+          <tbody>
+            {orders.map((order) => (
+              <tr key={order._id}>
+                <td>{order._id.substring(0, 6)}</td>
+                <td>{order.createdAt.substring(0, 10)}</td>
+                <td>{order.totalPrice.toFixed(2)}</td>
+
+                <td>
+                  {order.isDelivered ? (
+                    <CheckIcon></CheckIcon>
+                  ) : (
+                    <ClearIcon></ClearIcon>
+                  )}
+                </td>
+                <td>
+                  <Button
+                    type="button"
+                    variant="primary"
+                    onClick={() => {
+                      navigate(`/order/${order._id}`);
+                    }}
+                  >
+                    Детали
+                  </Button>
+                </td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
+      )}
+    </div>
+  );
+}
+
+export default OrderHistoryScreen;
Index: frontend/src/screens/OrderScreen.js
===================================================================
--- frontend/src/screens/OrderScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/OrderScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,176 @@
+import axios from "axios";
+import React, { useContext, useEffect, useReducer } from "react";
+import { Link, useNavigate, useParams } from "react-router-dom";
+import LoadingBox from "../components/LoadingBox";
+import MessageBox from "../components/MessageBox";
+import { Store } from "../Store";
+import { getError } from "../components/utils";
+import { Helmet } from "react-helmet-async";
+import Row from "react-bootstrap/Row";
+import Card from "react-bootstrap/Card";
+import Col from "react-bootstrap/Col";
+import ListGroup from "react-bootstrap/ListGroup";
+
+function reducer(state, action) {
+  switch (action.type) {
+    case "FETCH_REQUEST":
+      return { ...state, loading: true, error: "" };
+    case "FETCH_SUCCESS":
+      return { ...state, loading: false, order: action.payload, error: "" };
+    case "FETCH_FAIL":
+      return { ...state, loading: false, error: action.payload };
+    default:
+      return state;
+  }
+}
+
+export default function OrderScreen() {
+  const { state } = useContext(Store);
+  const { userInfo } = state;
+  const params = useParams();
+  const { id: orderId } = params;
+  const navigate = useNavigate();
+
+  const [{ loading, error, order }, dispatch] = useReducer(reducer, {
+    loading: true,
+    order: {},
+    error: "",
+  });
+
+  useEffect(() => {
+    const fetchOrder = async () => {
+      try {
+        dispatch({ type: "FETCH_REQUEST" });
+        const { data } = await axios.get(`/api/orders/${orderId}`, {
+          headers: { authorization: `Bearer ${userInfo.token}` },
+        });
+        dispatch({ type: "FETCH_SUCCESS", payload: data });
+      } catch (err) {
+        dispatch({ type: "FETCH_FAIL", payload: getError(err) });
+      }
+    };
+    if (!userInfo) {
+      return navigate("/login");
+    }
+    if (!order._id || (order._id && order._id !== orderId)) {
+      fetchOrder();
+    }
+  }, [order, userInfo, orderId, navigate]);
+
+  return loading ? (
+    <LoadingBox></LoadingBox>
+  ) : error ? (
+    <MessageBox variant="danger">{error}</MessageBox>
+  ) : (
+    <div className="pageContainer shipPC">
+      <Helmet>
+        <title>Нарачка {orderId}</title>
+      </Helmet>
+      <h1 style={{ marginTop: "20px" }}>Нарачка {orderId}</h1>
+      <Row style={{ width: "90%" }}>
+        <Col md={8}>
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Испорака</Card.Title>
+              <Card.Text>
+                <strong>Име:</strong> {order.shippingAddress.fullName}
+                <br />
+                <strong>Адреса:</strong> {order.shippingAddress.address},
+                {order.shippingAddress.city},{order.shippingAddress.postalCode},
+                {order.shippingAddress.country}
+              </Card.Text>
+              {order.isDelivered ? (
+                <MessageBox variant="success">
+                  Доставено на {order.deliveredAt}
+                </MessageBox>
+              ) : (
+                <MessageBox variant="danger">Не е доставено</MessageBox>
+              )}
+            </Card.Body>
+          </Card>
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Плаќање</Card.Title>
+              <Card.Text>
+                <strong>Начин:</strong>{" "}
+                {order.paymentMethod === "Karticka"
+                  ? "Со платежна картичка"
+                  : "Во готово при достава"}
+              </Card.Text>
+              {order.isPaid ? (
+                <MessageBox variant="success">
+                  Платено на {order.paidAt}
+                </MessageBox>
+              ) : (
+                <MessageBox variant="danger">Не е платено</MessageBox>
+              )}
+            </Card.Body>
+          </Card>
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Продукти</Card.Title>
+              <ListGroup variant="flush">
+                {order.orderItems.map((item) => (
+                  <ListGroup.Item key={item._id}>
+                    <div
+                      style={{
+                        display: "flex",
+                        justifyContent: "space-between",
+                      }}
+                    >
+                      <div style={{ display: "flex", alignItems: "center" }}>
+                        <img
+                          src={item.image}
+                          alt={item.name}
+                          className="img-fluid rounded img-thumbnail"
+                          style={{ margin: "0px" }}
+                        ></img>
+                        <Link to={`/product/${item.slug}`}>{item.name}</Link>
+                      </div>
+
+                      <span>{item.quantity}</span>
+
+                      <span>{item.price} ден</span>
+                    </div>
+                  </ListGroup.Item>
+                ))}
+              </ListGroup>
+            </Card.Body>
+          </Card>
+        </Col>
+        <Col md={4}>
+          <Card>
+            <Card.Body>
+              <Card.Title>Нарачка</Card.Title>
+              <ListGroup variant="flush">
+                <ListGroup.Item>
+                  <Row>
+                    <Col>Продукти:</Col>
+                    <Col>{order.itemsPrice.toFixed(2)} ден</Col>
+                  </Row>
+                </ListGroup.Item>
+                <ListGroup.Item>
+                  <Row>
+                    <Col>Испорака:</Col>
+                    <Col>{order.shippingPrice.toFixed(2)} ден</Col>
+                  </Row>
+                </ListGroup.Item>
+
+                <ListGroup.Item>
+                  <Row>
+                    <Col>
+                      <strong>Вкупно</strong>
+                    </Col>
+                    <Col>
+                      <strong>{order.totalPrice.toFixed(2)} ден</strong>
+                    </Col>
+                  </Row>
+                </ListGroup.Item>
+              </ListGroup>
+            </Card.Body>
+          </Card>
+        </Col>
+      </Row>
+    </div>
+  );
+}
Index: frontend/src/screens/PaymentMethodScreen.js
===================================================================
--- frontend/src/screens/PaymentMethodScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/PaymentMethodScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,79 @@
+import React, { useContext, useEffect, useState } from "react";
+import { Helmet } from "react-helmet-async";
+import CheckoutSteps from "../components/CheckoutSteps";
+import Container from "react-bootstrap/Container";
+import Button from "react-bootstrap/Button";
+import Form from "react-bootstrap/Form";
+import { Store } from "../Store";
+import { useNavigate } from "react-router-dom";
+import CreditCardIcon from "@mui/icons-material/CreditCard";
+
+function PaymentMethodScreen() {
+  const navigate = useNavigate();
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const {
+    cart: { shippingAddress, paymentMethod },
+  } = state;
+  const [paymentMethodName, setPaymentMethod] = useState(
+    paymentMethod || "Karticka"
+  );
+
+  useEffect(() => {
+    if (!shippingAddress.address) {
+      navigate("/shipping");
+    }
+  }, [shippingAddress, navigate]);
+  const submitHandler = (e) => {
+    e.preventDefault();
+    ctxDispatch({ type: "SAVE_PAYMENT_METHOD", payload: paymentMethodName });
+    localStorage.setItem("paymentMethod", paymentMethodName);
+    navigate("/placeorder");
+  };
+  return (
+    <div className="pageContainer shipPC">
+      <CheckoutSteps step1 step2 step3 />
+      <Container className="main">
+        <Helmet>
+          <title>Начин на наплата</title>
+        </Helmet>
+        <h1 style={{ marginTop: "10px" }}>Начин на наплата</h1>
+        <Form
+          onSubmit={submitHandler}
+          style={{
+            display: "flex",
+            flexDirection: "column",
+            alignItems: "center",
+          }}
+        >
+          <div className="radioContainer" style={{ marginTop: "10px" }}>
+            <Form.Check
+              type="radio"
+              id="Karticka"
+              label="Со платежна картичка"
+              value="Karticka"
+              checked={paymentMethodName === "Karticka"}
+              onChange={(e) => setPaymentMethod(e.target.value)}
+            />
+          </div>
+          <div className="radioContainer" style={{ marginTop: "10px" }}>
+            <Form.Check
+              type="radio"
+              id="voGotovo"
+              label="Во готово при достава"
+              value="voGotovo"
+              checked={paymentMethodName === "voGotovo"}
+              onChange={(e) => setPaymentMethod(e.target.value)}
+            />
+          </div>
+          <div style={{ marginTop: "20px" }}>
+            <Button variant="danger" type="submit">
+              Продолжи
+            </Button>
+          </div>
+        </Form>
+      </Container>
+    </div>
+  );
+}
+
+export default PaymentMethodScreen;
Index: frontend/src/screens/PlaceOrderScreen.js
===================================================================
--- frontend/src/screens/PlaceOrderScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/PlaceOrderScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,216 @@
+import React, { useContext, useEffect, useReducer } from "react";
+import Axios from "axios";
+import { Helmet } from "react-helmet-async";
+import CheckoutSteps from "../components/CheckoutSteps";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
+import Card from "react-bootstrap/Card";
+import Button from "react-bootstrap/Button";
+import ListGroup from "react-bootstrap/ListGroup";
+import { getError } from "../components/utils";
+import { toast } from "react-toastify";
+import { Store } from "../Store";
+import { Link, useNavigate } from "react-router-dom";
+import LoadingBox from "../components/LoadingBox";
+
+const reducer = (state, action) => {
+  switch (action.type) {
+    case "CREATE_REQUEST":
+      return { ...state, loading: true };
+    case "CREATE_SUCCESS":
+      return { ...state, loading: false };
+    case "CREATE_FAIL":
+      return { ...state, loading: false };
+    default:
+      return state;
+  }
+};
+
+function PlaceOrderScreen() {
+  const navigate = useNavigate();
+
+  const [{ loading }, dispatch] = useReducer(reducer, {
+    loading: false,
+  });
+
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const { cart, userInfo } = state;
+
+  const round2 = (num) => Math.round(num * 100 + Number.EPSILON) / 100;
+  cart.itemsPrice = round2(
+    cart.cartItems.reduce((a, c) => a + c.quantity * c.price, 0)
+  );
+  cart.shippingPrice = cart.itemsPrice > 1500 ? round2(0) : round2(150);
+  cart.totalPrice = cart.itemsPrice + cart.shippingPrice;
+
+  const paymentHandler = async () => {
+    navigate(`/placeorder/payment`);
+  };
+
+  const placeOrderHandler = async () => {
+    try {
+      dispatch({ type: "CREATE_REQUEST" });
+      const { data } = await Axios.post(
+        "/api/orders",
+        {
+          orderItems: cart.cartItems,
+          shippingAddress: cart.shippingAddress,
+          paymentMethod: cart.paymentMethod,
+          itemsPrice: cart.itemsPrice,
+          shippingPrice: cart.shippingPrice,
+          totalPrice: cart.totalPrice,
+        },
+        {
+          headers: {
+            authorization: `Bearer ${userInfo.token}`,
+          },
+        }
+      );
+      ctxDispatch({ type: "CART_CLEAR" });
+      dispatch({ type: "CREATE_SUCCESS" });
+      localStorage.removeItem("cartItems");
+      navigate(`/order/${data.order._id}`);
+    } catch (err) {
+      dispatch({ type: "CREATE_FAIL" });
+      toast.error(getError(err));
+    }
+  };
+
+  useEffect(() => {
+    if (!cart.paymentMethod) {
+      navigate("/payment");
+    }
+  }, [cart, navigate]);
+
+  return (
+    <div className="pageContainer shipPC">
+      <CheckoutSteps step1 step2 step3 step4 />
+
+      <Helmet>
+        <title>Потврди нарачка</title>
+      </Helmet>
+      <h1 style={{ marginTop: "20px" }}>Потврди нарачка</h1>
+      <Row style={{ width: "90%" }}>
+        <Col md={8}>
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Испорака</Card.Title>
+              <Card.Text>
+                <strong>Име:</strong> {cart.shippingAddress.fullName}
+                <br />
+                <strong>Адреса:</strong> {cart.shippingAddress.address},
+                {cart.shippingAddress.city},{cart.shippingAddress.postalCode},
+                {cart.shippingAddress.country}
+                <br />
+              </Card.Text>
+              <Link to="/shipping">Измени</Link>
+            </Card.Body>
+          </Card>
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Плаќање</Card.Title>
+              <Card.Text>
+                <strong>Начин:</strong>{" "}
+                {cart.paymentMethod === "Karticka"
+                  ? "Со платежна картичка"
+                  : "Во готово при достава"}
+              </Card.Text>
+              <Link to="/payment">Измени</Link>
+            </Card.Body>
+          </Card>
+
+          <Card className="mb-3">
+            <Card.Body>
+              <Card.Title>Продукти</Card.Title>
+              <ListGroup variant="flush">
+                {cart.cartItems.map((item) => (
+                  <ListGroup.Item key={item._id}>
+                    <div
+                      style={{
+                        display: "flex",
+                        justifyContent: "space-between",
+                      }}
+                    >
+                      <div style={{ display: "flex", alignItems: "center" }}>
+                        <img
+                          src={item.image}
+                          alt={item.name}
+                          className="img-fluid rounded img-thumbnail"
+                          style={{ margin: "0px" }}
+                        ></img>
+                        <Link to={`/product/${item.slug}`}>{item.name}</Link>
+                      </div>
+
+                      <span>{item.quantity}</span>
+
+                      <span>{item.price} ден</span>
+                    </div>
+                  </ListGroup.Item>
+                ))}
+              </ListGroup>
+              <Link to="/cart">Измени</Link>
+            </Card.Body>
+          </Card>
+        </Col>
+        <Col md={4}>
+          <Card>
+            <Card.Body>
+              <Card.Title>Нарачка</Card.Title>
+              <ListGroup variant="flush">
+                <ListGroup.Item>
+                  <Row>
+                    <Col>Продукти:</Col>
+                    <Col>{cart.itemsPrice.toFixed(2)} ден</Col>
+                  </Row>
+                </ListGroup.Item>
+                <ListGroup.Item>
+                  <Row>
+                    <Col>Испорака:</Col>
+                    <Col>{cart.shippingPrice.toFixed(2)} ден</Col>
+                  </Row>
+                </ListGroup.Item>
+
+                <ListGroup.Item>
+                  <Row>
+                    <Col>
+                      <strong>Вкупно</strong>
+                    </Col>
+                    <Col>
+                      <strong>{cart.totalPrice.toFixed(2)} ден</strong>
+                    </Col>
+                  </Row>
+                </ListGroup.Item>
+                <ListGroup.Item>
+                  <div className="d-grid">
+                    {cart.paymentMethod === "Karticka" ? (
+                      <Button
+                        type="button"
+                        onClick={paymentHandler}
+                        disabled={cart.cartItems.length === 0}
+                        variant="danger"
+                      >
+                        Плати
+                      </Button>
+                    ) : (
+                      <Button
+                        type="button"
+                        onClick={placeOrderHandler}
+                        disabled={cart.cartItems.length === 0}
+                        variant="danger"
+                      >
+                        Потврди нарачка
+                      </Button>
+                    )}
+                  </div>
+                  {loading && <LoadingBox></LoadingBox>}
+                </ListGroup.Item>
+              </ListGroup>
+            </Card.Body>
+          </Card>
+        </Col>
+      </Row>
+    </div>
+  );
+}
+
+export default PlaceOrderScreen;
Index: frontend/src/screens/ShippingAddressScreen.js
===================================================================
--- frontend/src/screens/ShippingAddressScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/ShippingAddressScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,118 @@
+import React, { useContext, useEffect, useState } from "react";
+import { Helmet } from "react-helmet-async";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/Button";
+import Container from "react-bootstrap/Container";
+import { useNavigate } from "react-router-dom";
+import { Store } from "../Store";
+import CheckoutSteps from "../components/CheckoutSteps";
+
+function ShippingAddressScreen() {
+  const navigate = useNavigate();
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const {
+    userInfo,
+    cart: { shippingAddress },
+  } = state;
+  const [fullName, setFullName] = useState(shippingAddress.fullName || "");
+  const [address, setAddress] = useState(shippingAddress.address || "");
+  const [city, setCity] = useState(shippingAddress.city || "");
+  const [postalCode, setPostalCode] = useState(
+    shippingAddress.postalCode || ""
+  );
+  const [country, setCountry] = useState(shippingAddress.country || "");
+
+  useEffect(() => {
+    if (!userInfo) {
+      navigate("/signin");
+    }
+  }, [userInfo, navigate]);
+
+  const submitHandler = (e) => {
+    e.preventDefault();
+    ctxDispatch({
+      type: "SAVE_SHIPPING_ADDRESS",
+      payload: {
+        fullName,
+        address,
+        city,
+        postalCode,
+        country,
+      },
+    });
+    localStorage.setItem(
+      "shippingAddress",
+      JSON.stringify({
+        fullName,
+        address,
+        city,
+        postalCode,
+        country,
+      })
+    );
+    navigate("/payment");
+  };
+
+  return (
+    <div className="pageContainer shipPC">
+      <CheckoutSteps step1 step2 />
+      <Container className="main">
+        <Helmet>
+          <title>Адреса</title>
+        </Helmet>
+
+        <h1 className="my-3">Адреса</h1>
+
+        <Form onSubmit={submitHandler} className="formCointainer">
+          <Form.Group>
+            <Form.Label>Име и Презиме</Form.Label>
+            <Form.Control
+              value={fullName}
+              onChange={(e) => setFullName(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Адреса</Form.Label>
+            <Form.Control
+              value={address}
+              onChange={(e) => setAddress(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Град</Form.Label>
+            <Form.Control
+              value={city}
+              onChange={(e) => setCity(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Поштенски код</Form.Label>
+            <Form.Control
+              value={postalCode}
+              onChange={(e) => setPostalCode(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <Form.Group>
+            <Form.Label>Држава</Form.Label>
+            <Form.Control
+              value={country}
+              onChange={(e) => setCountry(e.target.value)}
+              required
+            ></Form.Control>
+          </Form.Group>
+          <div className="submitBtnContainer">
+            <Button variant="danger" size="lg" type="submit">
+              Продолжи
+            </Button>
+          </div>
+        </Form>
+      </Container>
+    </div>
+  );
+}
+
+export default ShippingAddressScreen;
Index: frontend/src/screens/SigninScreen.js
===================================================================
--- frontend/src/screens/SigninScreen.js	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/screens/SigninScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -1,2 +1,3 @@
+import Axios from "axios";
 import Container from "react-bootstrap/Container";
 import Form from "react-bootstrap/Form";
@@ -4,11 +5,43 @@
 import Button from "react-bootstrap/Button";
 import "../styles/SigninScreen.css";
-import React from "react";
-import { Link, useLocation } from "react-router-dom";
+import React, { useContext, useEffect, useState } from "react";
+import { Link, useLocation, useNavigate } from "react-router-dom";
+import { Store } from "../Store";
+import { toast } from "react-toastify";
+import { getError } from "../components/utils";
 
 function SigninScreen() {
+  const navigate = useNavigate();
   const { search } = useLocation();
   const redirectInUrl = new URLSearchParams(search).get("redirect");
   const redirect = redirectInUrl ? redirectInUrl : "/";
+
+  const [email, setEmail] = useState("");
+  const [password, setPassword] = useState("");
+
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const { userInfo } = state;
+
+  const submitHandler = async (e) => {
+    e.preventDefault();
+    try {
+      const { data } = await Axios.post("/api/users/signin", {
+        email,
+        password,
+      });
+      ctxDispatch({ type: "USER_SIGNIN", payload: data });
+      localStorage.setItem("userInfo", JSON.stringify(data));
+      navigate(redirect || "/");
+    } catch (err) {
+      toast.error(getError(err));
+    }
+  };
+
+  useEffect(() => {
+    if (userInfo) {
+      navigate(redirect);
+    }
+  }, [navigate, redirect, userInfo]);
+
   return (
     <div className="pageContainer">
@@ -18,12 +51,20 @@
         </Helmet>
         <h1>Најави се</h1>
-        <Form className="formCointainer">
+        <Form className="formCointainer" onSubmit={submitHandler}>
           <Form.Group controlId="email">
             <Form.Label>Email</Form.Label>
-            <Form.Control type="email" required />
+            <Form.Control
+              type="email"
+              required
+              onChange={(e) => setEmail(e.target.value)}
+            />
           </Form.Group>
           <Form.Group controlId="password">
             <Form.Label>Лозинка</Form.Label>
-            <Form.Control type="email" required />
+            <Form.Control
+              type="password"
+              required
+              onChange={(e) => setPassword(e.target.value)}
+            />
           </Form.Group>
           <div className="submitBtnContainer">
Index: frontend/src/screens/SignupScreen.js
===================================================================
--- frontend/src/screens/SignupScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
+++ frontend/src/screens/SignupScreen.js	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -0,0 +1,118 @@
+import Axios from "axios";
+import Container from "react-bootstrap/Container";
+import Form from "react-bootstrap/Form";
+import { Helmet } from "react-helmet-async";
+import Button from "react-bootstrap/Button";
+import "../styles/SigninScreen.css";
+import React, { useContext, useEffect, useState } from "react";
+import { Link, useLocation, useNavigate } from "react-router-dom";
+import { Store } from "../Store";
+import { toast } from "react-toastify";
+import { getError } from "../components/utils";
+
+function SignupScreen() {
+  const navigate = useNavigate();
+  const { search } = useLocation();
+  const redirectInUrl = new URLSearchParams(search).get("redirect");
+  const redirect = redirectInUrl ? redirectInUrl : "/";
+
+  const [name, setName] = useState("");
+  const [contact, setContact] = useState("");
+  const [email, setEmail] = useState("");
+  const [password, setPassword] = useState("");
+  const [confirmPassword, setConfirmPassword] = useState("");
+
+  const { state, dispatch: ctxDispatch } = useContext(Store);
+  const { userInfo } = state;
+
+  const submitHandler = async (e) => {
+    e.preventDefault();
+    if (password !== confirmPassword) {
+      toast.error("Лозинките не се совпаѓаат");
+      return;
+    }
+    try {
+      const { data } = await Axios.post("/api/users/signup", {
+        name,
+        contact,
+        email,
+        password,
+      });
+      ctxDispatch({ type: "USER_SIGNIN", payload: data });
+      localStorage.setItem("userInfo", JSON.stringify(data));
+      navigate(redirect || "/");
+    } catch (err) {
+      toast.error(getError(err));
+    }
+  };
+
+  useEffect(() => {
+    if (userInfo) {
+      navigate(redirect);
+    }
+  }, [navigate, redirect, userInfo]);
+
+  return (
+    <div className="pageContainer">
+      <Container className="main">
+        <Helmet>
+          <title>Регистрирај се</title>
+        </Helmet>
+        <h1>Регистрирај се</h1>
+        <Form className="formCointainer" onSubmit={submitHandler}>
+          <Form.Group controlId="name">
+            <Form.Label>Име и Презиме</Form.Label>
+            <Form.Control
+              style={{ textAlign: "left" }}
+              required
+              onChange={(e) => setName(e.target.value)}
+            />
+          </Form.Group>
+          <Form.Group controlId="contact">
+            <Form.Label>Телефон</Form.Label>
+            <Form.Control
+              type="text"
+              required
+              onChange={(e) => setContact(e.target.value)}
+            />
+          </Form.Group>
+          <Form.Group controlId="email">
+            <Form.Label>Email</Form.Label>
+            <Form.Control
+              type="email"
+              required
+              onChange={(e) => setEmail(e.target.value)}
+            />
+          </Form.Group>
+          <Form.Group controlId="password">
+            <Form.Label>Лозинка</Form.Label>
+            <Form.Control
+              type="password"
+              required
+              onChange={(e) => setPassword(e.target.value)}
+            />
+          </Form.Group>
+          <Form.Group controlId="confirmPassword">
+            <Form.Label>Потврди Лозинка</Form.Label>
+            <Form.Control
+              type="password"
+              required
+              onChange={(e) => setConfirmPassword(e.target.value)}
+            />
+          </Form.Group>
+          <div className="submitBtnContainer">
+            <Button variant="danger" size="lg" type="submit">
+              Регистрирај се
+            </Button>
+          </div>
+          <div className="registerParagraph">
+            Имате профил?{" "}
+            <Link to={`/signin?redirect=${redirect}`}>Најави се</Link>
+          </div>
+        </Form>
+      </Container>
+    </div>
+  );
+}
+
+export default SignupScreen;
Index: frontend/src/styles/Header.css
===================================================================
--- frontend/src/styles/Header.css	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/styles/Header.css	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -6,4 +6,5 @@
   margin: 0;
   padding: 0;
+  margin-top: 10px;
   height: 70px;
   width: 100%;
@@ -200,4 +201,10 @@
 }
 
+#basic-nav-dropdown {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
 @media only screen and (max-width: 1015px) {
   .header__dropdown {
Index: frontend/src/styles/SigninScreen.css
===================================================================
--- frontend/src/styles/SigninScreen.css	(revision 717ceae0194e473720ee8817b1deb266a288a17f)
+++ frontend/src/styles/SigninScreen.css	(revision 16237c49c48dec4a9921c2dd8bd19ccf9e9fb846)
@@ -13,4 +13,15 @@
 .formCointainer {
   width: 400px;
+}
+
+.shipPC {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.shipPC .checkout-steps {
+  width: 70%;
 }
 
@@ -32,2 +43,14 @@
   }
 }
+
+@media only screen and (max-width: 559px) {
+  .shipPC .checkout-steps {
+    width: 100%;
+  }
+}
+
+@media only screen and (max-width: 331px) {
+  .shipPC .checkout-steps {
+    display: none;
+  }
+}
