la-flowerita 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. package/README.md +70 -0
  2. package/package.json +78 -0
  3. package/public/favicon.ico +0 -0
  4. package/public/images/1.jpg +0 -0
  5. package/public/images/2.jpg +0 -0
  6. package/public/images/3.jpg +0 -0
  7. package/public/images/Logo.png +0 -0
  8. package/public/images/add-user.png +0 -0
  9. package/public/images/contact-us.png +0 -0
  10. package/public/images/flower.png +0 -0
  11. package/public/images/flower_shop.png +0 -0
  12. package/public/images/flower_shop1.png +0 -0
  13. package/public/images/flowers/buttercup.png +0 -0
  14. package/public/images/flowers/daffodil.png +0 -0
  15. package/public/images/flowers/daisy.png +0 -0
  16. package/public/images/flowers/jasmine.png +0 -0
  17. package/public/images/flowers/lily.png +0 -0
  18. package/public/images/flowers/marigold.png +0 -0
  19. package/public/images/flowers/orchid.png +0 -0
  20. package/public/images/flowers/rose.png +0 -0
  21. package/public/images/flowers/sunflower.png +0 -0
  22. package/public/images/flowers/tulip.png +0 -0
  23. package/public/images/garbage.png +0 -0
  24. package/public/images/icon1.jpg +0 -0
  25. package/public/images/login.png +0 -0
  26. package/public/images/refresh.png +0 -0
  27. package/public/images/transaction.png +0 -0
  28. package/public/index.html +41 -0
  29. package/public/logo192.png +0 -0
  30. package/public/logo512.png +0 -0
  31. package/public/manifest.json +26 -0
  32. package/public/offline.html +44 -0
  33. package/public/robots.txt +3 -0
  34. package/public/serviceworker.js +44 -0
  35. package/server.js +97 -0
  36. package/src/App.css +38 -0
  37. package/src/App.js +25 -0
  38. package/src/App.test.js +8 -0
  39. package/src/Config/db.js +5 -0
  40. package/src/Config/mail.js +7 -0
  41. package/src/Config/passport.js +34 -0
  42. package/src/Controllers/catalog.controller.js +78 -0
  43. package/src/Controllers/shoppinglist.controller.js +186 -0
  44. package/src/Controllers/user.controller.js +214 -0
  45. package/src/Controllers/wishlist.controller.js +150 -0
  46. package/src/Middleware/sendMail.js +29 -0
  47. package/src/Middleware/uploadImage.js +26 -0
  48. package/src/Models/orderProducts.js +10 -0
  49. package/src/Models/products.js +17 -0
  50. package/src/Models/shoppinglists.js +12 -0
  51. package/src/Models/userShoppinglists.js +9 -0
  52. package/src/Models/users.js +57 -0
  53. package/src/Models/wishlists.js +9 -0
  54. package/src/Routes/auth.js +21 -0
  55. package/src/Routes/indexRouter.js +40 -0
  56. package/src/Services/ProductService.js +76 -0
  57. package/src/Services/ShoppinglistService.js +135 -0
  58. package/src/Services/UserService.js +63 -0
  59. package/src/Services/WishlistService.js +105 -0
  60. package/src/components/About.js +45 -0
  61. package/src/components/Auth.js +15 -0
  62. package/src/components/Catalog.js +118 -0
  63. package/src/components/Chat.js +77 -0
  64. package/src/components/Contact.js +48 -0
  65. package/src/components/Dashboard.js +13 -0
  66. package/src/components/DetailsProductModal.js +362 -0
  67. package/src/components/LoginModal.js +173 -0
  68. package/src/components/NewProductModal.js +271 -0
  69. package/src/components/NoPermission.js +10 -0
  70. package/src/components/OrderedProduct.js +104 -0
  71. package/src/components/PreChat.js +51 -0
  72. package/src/components/Product.js +158 -0
  73. package/src/components/ResetPassword.js +211 -0
  74. package/src/components/ShoppingCart.js +198 -0
  75. package/src/components/SideNav.js +76 -0
  76. package/src/components/SignupModal.js +306 -0
  77. package/src/components/Spinner.js +22 -0
  78. package/src/components/Wishlist.js +195 -0
  79. package/src/components/social-config.js +17 -0
  80. package/src/css/about.css +12 -0
  81. package/src/css/catalog.css +218 -0
  82. package/src/css/chat.css +191 -0
  83. package/src/css/contact.css +404 -0
  84. package/src/css/index.css +129 -0
  85. package/src/css/newProductModal.css +69 -0
  86. package/src/css/noPermission.css +89 -0
  87. package/src/css/orderedProduct.css +0 -0
  88. package/src/css/resetPassword.css +44 -0
  89. package/src/css/shoppingCart.css +10 -0
  90. package/src/css/sideNav.css +68 -0
  91. package/src/css/spinner.css +23 -0
  92. package/src/images/1.jpg +0 -0
  93. package/src/images/2.jpg +0 -0
  94. package/src/images/3.jpg +0 -0
  95. package/src/images/Logo.png +0 -0
  96. package/src/images/add-user.png +0 -0
  97. package/src/images/buttercup.png +0 -0
  98. package/src/images/contact-us.png +0 -0
  99. package/src/images/daffodil.png +0 -0
  100. package/src/images/daisy.png +0 -0
  101. package/src/images/flower.png +0 -0
  102. package/src/images/flower_shop.png +0 -0
  103. package/src/images/flower_shop1.png +0 -0
  104. package/src/images/flowers/buttercup.png +0 -0
  105. package/src/images/flowers/daffodil.png +0 -0
  106. package/src/images/flowers/daisy.png +0 -0
  107. package/src/images/flowers/jasmine.png +0 -0
  108. package/src/images/flowers/lily.png +0 -0
  109. package/src/images/flowers/marigold.png +0 -0
  110. package/src/images/flowers/orchid.png +0 -0
  111. package/src/images/flowers/rose.png +0 -0
  112. package/src/images/flowers/sunflower.png +0 -0
  113. package/src/images/flowers/tulip.png +0 -0
  114. package/src/images/garbage.png +0 -0
  115. package/src/images/icon1.jpg +0 -0
  116. package/src/images/jasmine.png +0 -0
  117. package/src/images/lily.png +0 -0
  118. package/src/images/login.png +0 -0
  119. package/src/images/marigold.png +0 -0
  120. package/src/images/orchid.png +0 -0
  121. package/src/images/refresh.png +0 -0
  122. package/src/images/rose.png +0 -0
  123. package/src/images/sunflower.png +0 -0
  124. package/src/images/transaction.png +0 -0
  125. package/src/images/tulip.png +0 -0
  126. package/src/index.js +371 -0
  127. package/src/logo.svg +1 -0
  128. package/src/reportWebVitals.js +13 -0
  129. package/src/setupTests.js +5 -0
@@ -0,0 +1,158 @@
1
+ import { React, Component } from "react";
2
+ import sampleImage from "../logo.svg";
3
+ import "../css/catalog.css";
4
+ // import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
5
+ import { FaHeart, FaRegHeart, FaShoppingCart, FaEye } from "react-icons/fa";
6
+ import DetailsProductModal from "./DetailsProductModal.js";
7
+ import swal from "sweetalert";
8
+ import LoadingIndicator from "./Spinner";
9
+ import { usePromiseTracker, trackPromise } from "react-promise-tracker";
10
+ class Product extends Component {
11
+ constructor(props) {
12
+ super(props);
13
+ console.log(props);
14
+ this.state = {
15
+ isInWishList: props.isInWishList,
16
+ id: props.id,
17
+ name: props.name,
18
+ image: props.image,
19
+ color: props.color,
20
+ price: props.price,
21
+ description: props.description,
22
+ type: props.type,
23
+ maxAmount: props.maxAmount,
24
+ onUpdateCart: props.onUpdateCart,
25
+ onUpdateWishlist: props.onUpdateWishlist,
26
+ showModal:false
27
+ };
28
+ }
29
+
30
+ async intoCart(props) {
31
+ console.log(this.state);
32
+ var options = {
33
+ method: "POST",
34
+ headers: { "Content-Type": "application/json" },
35
+ body: JSON.stringify({ productId: this.state.id }),
36
+ };
37
+ await fetch("/addNewProductToCart", options).then(res => res.json()).then(
38
+ (result) => {
39
+ if (result.status == 200) {
40
+ this.state.onUpdateCart(result.cart.products.length);
41
+ swal("Success!", "Product Added To Cart!", "success");
42
+ }
43
+ },
44
+ (error) => {
45
+ console.log(error);
46
+ }
47
+ );
48
+ }
49
+ async intoWishList() {
50
+ console.log(this.state);
51
+ var options = {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/json" },
54
+ body: JSON.stringify({ productId: this.state.id }),
55
+ };
56
+ await fetch("/addNewProductToWishlist", options).then(res => res.json()).then(
57
+ (result) => {
58
+ if (result.status == 200) {
59
+ this.state.onUpdateWishlist(result.wishlist.products.length);
60
+ this.setState({ isInWishList: true });
61
+ swal("Success!", "Product Added To Wish List!", "success");
62
+ }
63
+ },
64
+ (error) => {
65
+ console.log(error);
66
+ }
67
+ );
68
+ }
69
+ async outOfWishList() {
70
+ console.log(this.state);
71
+ var options = {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify({ productId: this.state.id }),
75
+ };
76
+ await fetch("/deleteProductFromWishlist", options).then(res => res.json()).then(
77
+ (result) => {
78
+ if (result.status == 200) {
79
+ this.state.onUpdateWishlist(result.wishlist.products.length);
80
+ this.setState({ isInWishList: false });
81
+ swal("Success!", "Product Removed From Wish List!", "success");
82
+ }
83
+ },
84
+ (error) => {
85
+ console.log(error);
86
+ }
87
+ ); }
88
+ arrayBufferToBase64(buffer) {
89
+ var binary = "";
90
+ var bytes = [].slice.call(new Uint8Array(buffer.data));
91
+ bytes.forEach((b) => (binary += String.fromCharCode(b)));
92
+ return window.btoa(binary);
93
+ }
94
+ render() {
95
+ var path =
96
+ "data:/" +
97
+ this.props.image.contentType +
98
+ ";base64," +
99
+ this.arrayBufferToBase64(this.props.image.data);
100
+ return (<div class="column">
101
+ <div class="product-img">
102
+ <img src={path} onError={(e) => {
103
+ e.target.src =
104
+ "https://www.freeiconspng.com/uploads/no-image-icon-11.PNG";
105
+ e.target.onerror = null; // prevents looping
106
+ }}/>
107
+ </div>
108
+ <div class="product-info">
109
+ <div class="product-text">
110
+ <h1>{this.props.name}</h1>
111
+ <h2>Seller {this.props.sellerName}</h2>
112
+ <p>{this.props.description}</p>
113
+ </div>
114
+ <div class="product-price-btn">
115
+ <p><span className=".product-span">{this.props.price}</span>$</p>
116
+ {this.state.isInWishList ? (
117
+ <button type="button" onClick={() => this.outOfWishList()}>
118
+ <FaHeart
119
+ id="inWishList"
120
+ style={{ cursor: "pointer" }}
121
+ />
122
+ </button>
123
+ ) : (
124
+ <button type="button" onClick={() => this.intoWishList()} >
125
+ <FaRegHeart
126
+ id="outWishList"
127
+ style={{ cursor: "pointer" }}
128
+ />
129
+ </button>
130
+ )}
131
+ <button type="button" onClick={() => this.intoCart(this.props)}>
132
+ <FaShoppingCart
133
+ style={{ cursor: "pointer" }}
134
+ />
135
+ </button>
136
+ <button type="button" onClick={() => this.setState({showModal:true})}>
137
+ <FaEye/>
138
+ {this.state.showModal? <DetailsProductModal id={this.props.id}
139
+ image={this.props.image}
140
+ path={path}
141
+ name={this.props.name}
142
+ color={this.props.color}
143
+ price={this.props.price}
144
+ description={this.props.description}
145
+ type={this.props.type}
146
+ maxAmount={this.state.maxAmount}
147
+ sellerName={this.state.sellerName}
148
+ showModal={true}
149
+ />: ""}
150
+ </button>
151
+ </div>
152
+ </div>
153
+ </div>);
154
+
155
+ }
156
+ }
157
+
158
+ export default Product;
@@ -0,0 +1,211 @@
1
+ import React, { Component } from "react";
2
+ import Button from "react-bootstrap/Button";
3
+ import { Route, NavLink, HashRouter, Routes } from "react-router-dom";
4
+ import "../css/resetPassword.css"
5
+ import LoadingIndicator from "./Spinner";
6
+ import { usePromiseTracker, trackPromise } from "react-promise-tracker";
7
+ import swal from 'sweetalert';
8
+
9
+ class ResetPassword extends Component {
10
+ constructor() {
11
+ super();
12
+ this.state = {
13
+ emailSent: false,
14
+ emailReceived: false,
15
+ tokenChecked: false,
16
+ id: null,
17
+ ERROR: ""
18
+ };
19
+ }
20
+
21
+ resetPassword = async () => {
22
+ // this.setState({ [e.target.name]: e.target.value });
23
+ let email = document.getElementById("email").value;
24
+ var options = {
25
+ method: "POST",
26
+ headers: { "Content-Type": "application/json" },
27
+ body: JSON.stringify({email:email}),
28
+ };
29
+ trackPromise(
30
+ fetch("/emailForResetPassword", options)
31
+ .then(
32
+ (res) => {
33
+ console.log(res);
34
+ if (res.status == 200) {
35
+ console.log("email was sent successfully!");
36
+ this.setState({ emailSent: true });
37
+ }
38
+ else if (res.status == 404){
39
+ console.log("email was not sent!");
40
+ this.setState({ ERROR: "This email is not one of our users" });
41
+ }
42
+ },
43
+ // Note: it's important to handle errors here
44
+ // instead of a catch() block so that we don't swallow
45
+ // exceptions from actual bugs in components.
46
+ (error) => {
47
+ this.setState({
48
+ ERROR: error
49
+ });
50
+ }
51
+ ))
52
+ };
53
+
54
+ checkToken = async () => {
55
+ let token = document.getElementById("token").value;
56
+ var options = {
57
+ method: "POST",
58
+ headers: { "Content-Type": "application/json" },
59
+ body: JSON.stringify({token:token}),
60
+ };
61
+ trackPromise(
62
+ fetch("/checkToken", options).then(res => res.json())
63
+ .then(
64
+ (res ) => {
65
+ console.log(res);
66
+ if (res.status == 200) {
67
+ console.log("token is good!");
68
+ this.setState({id:res.id, tokenChecked: true });
69
+ }
70
+ else if (res.status == 404){
71
+ console.log("token not good!");
72
+ this.setState({ ERROR: "This is not correct. Please try again" });
73
+ }
74
+ },
75
+ // Note: it's important to handle errors here
76
+ // instead of a catch() block so that we don't swallow
77
+ // exceptions from actual bugs in components.
78
+ (error) => {
79
+ this.setState({
80
+ ERROR: error
81
+ });
82
+ }
83
+ ))
84
+ };
85
+
86
+ updatePassword = async () => {
87
+ // this.setState({ [e.target.name]: e.target.value });
88
+ let password = document.getElementById("password").value;
89
+ let repass = document.getElementById("repass").value;
90
+ if(password != repass){
91
+ this.setState({ ERROR: "This passwords are not the same" });
92
+ return;
93
+ }
94
+ var options = {
95
+ method: "POST",
96
+ headers: { "Content-Type": "application/json" },
97
+ body: JSON.stringify({password:password, id: this.state.id}),
98
+ };
99
+ trackPromise(
100
+ fetch("/updatePassword", options)
101
+ .then(
102
+ (res) => {
103
+ console.log(res);
104
+ if (res.status == 200) {
105
+ console.log("update password was successful!");
106
+ swal("Successful!","update password was successful! Please login.", "success")
107
+ document.location.href = "/";
108
+ }
109
+ },
110
+ // Note: it's important to handle errors here
111
+ // instead of a catch() block so that we don't swallow
112
+ // exceptions from actual bugs in components.
113
+ (error) => {
114
+ this.setState({
115
+ ERROR: error
116
+ });
117
+ }
118
+ ))
119
+ };
120
+ render() {
121
+ if(!this.state.emailSent){
122
+ return (<GetEmailForReset resetPasswordFunction={this.resetPassword} ERROR={this.state.ERROR}></GetEmailForReset>
123
+ );
124
+ }
125
+ else if (!this.state.emailReceived && !this.state.tokenChecked){
126
+ return (<GetToken checkTokenFunction={this.checkToken} ERROR={this.state.ERROR}></GetToken>);
127
+
128
+ }
129
+ else if(this.state.tokenChecked){
130
+ return (<UpdatePassword updatePasswordfunction={this.updatePassword} ERROR={this.state.ERROR}></UpdatePassword>);
131
+
132
+ }
133
+ }
134
+ }
135
+
136
+ class GetEmailForReset extends Component{
137
+
138
+ render(){
139
+ return (
140
+ <div id="divForResetPassword" className="container d-flex justify-content-center align-items-center vh-100">
141
+ <LoadingIndicator/>
142
+ <div className="bg-white text-center p-5 mt-3 center">
143
+ <h3>Forgot Password </h3>
144
+ <p>Please enter your email and we will send you a link to reset your password.</p>
145
+ <form className="pb-3" action="#">
146
+ <div className="form-group">
147
+ <input name="email" id="email" type="email" className="form-control" placeholder="Your Username*" required/>
148
+ </div>
149
+ <h5>{this.props.ERROR}</h5>
150
+ </form>
151
+ <button onClick={() => this.props.resetPasswordFunction()} type="button" className="btn">Reset Password</button>
152
+ </div>
153
+ </div>);
154
+ }
155
+ }
156
+
157
+ class GetToken extends Component{
158
+
159
+ render(){
160
+ return(
161
+ <div className="container d-flex justify-content-center align-items-center vh-100">
162
+ <LoadingIndicator/>
163
+ <div className="bg-white text-center p-5 mt-3 center">
164
+ <h3>Forgot Password </h3>
165
+ <p>Please enter the token you got to your mail.</p>
166
+ <form className="pb-3" action="#">
167
+ <div className="form-group">
168
+ <input name="token" id="token" type="text" className="form-control" required/>
169
+ </div>
170
+ <h5>{this.props.ERROR}</h5>
171
+ </form>
172
+ <button onClick={() => this.props.checkTokenFunction()} type="button" className="btn">Submit</button>
173
+ {/* <NavLink
174
+ style={{cursor:"pointer"}}
175
+ onClick={() => this.checkToken()}
176
+ to="/updatePassword"
177
+ >
178
+ Submit
179
+ </NavLink> */}
180
+ </div>
181
+ </div>);
182
+ }
183
+ }
184
+
185
+
186
+ class UpdatePassword extends Component{
187
+
188
+ render() {
189
+ return (
190
+ <div className="container d-flex justify-content-center align-items-center vh-100">
191
+ <LoadingIndicator/>
192
+ <div className="bg-white text-center p-5 mt-3 center">
193
+ <h3>Change Password </h3>
194
+ <p>Please enter a new paswword.</p>
195
+ <form className="pb-3" action="#">
196
+ <div className="form-group">
197
+ <input name="password" id="password" type="password" className="form-control" placeholder="Your Password*" required/>
198
+ </div>
199
+ <div className="form-group">
200
+ <input name="repass" id="repass" type="password" className="form-control" placeholder="Write It Again*" required/>
201
+ </div>
202
+ <h5>{this.props.ERROR}</h5>
203
+ </form>
204
+ <button onClick={() => this.props.updatePasswordfunction()} type="button" className="btn">Save</button>
205
+ </div>
206
+ </div>
207
+ );
208
+ }
209
+ }
210
+
211
+ export default ResetPassword;
@@ -0,0 +1,198 @@
1
+ import {React, Component} from 'react';
2
+ import sampleImage from '../logo.svg';
3
+ import '../css/shoppingCart.css';
4
+ import { FaHeart, FaRegHeart, FaShoppingCart, FaEye } from "react-icons/fa";
5
+ import OrderedProduct from "./OrderedProduct.js"
6
+ import swal from "sweetalert";
7
+ import { Container, Table, Row, Button } from "react-bootstrap";
8
+ import LoadingIndicator from "./Spinner";
9
+ import { usePromiseTracker, trackPromise } from "react-promise-tracker";
10
+ class ShoppingCart extends Component {
11
+ constructor(props) {
12
+ super(props);
13
+ this.state = {
14
+ totalPrice: 0,
15
+ products: [],
16
+ loggedIn: false,
17
+ onUpdateCart: props.onUpdateCart,
18
+ };
19
+ }
20
+ componentDidMount = async () => {
21
+ var options = {
22
+ method: "GET",
23
+ headers: { "Content-Type": "application/json" },
24
+ };
25
+ trackPromise(
26
+ fetch("/getCurrentCart", options).then(res => res.json()).then(
27
+ (result) => {
28
+ console.log(result)
29
+ if (result.status == 200) {
30
+ this.setState({
31
+ products: result.cart.products,
32
+ totalPrice: result.cart.products.reduce(
33
+ (acc, item) => acc + item.price * item.quantity,
34
+ 0
35
+ ),
36
+ });
37
+ }
38
+ },
39
+ (error) => {
40
+ console.log(error);
41
+ }
42
+ ));
43
+ }
44
+
45
+ componentDidUpdate(prevProps, prevState) {
46
+ if (this.state.products.length != prevState.products.length) {
47
+ this.state.onUpdateCart(this.state.products.length);
48
+ }
49
+ }
50
+
51
+ async intoWishList() {}
52
+ async deleteFromCart(id) {
53
+ swal({
54
+ title: "Are you sure?",
55
+ text: "Do you want to delete this product from cart?",
56
+ icon: "warning",
57
+ buttons: true,
58
+ dangerMode: true,
59
+ }).then((willDelete) => {
60
+ if (willDelete) {
61
+ var options = {
62
+ method: "POST",
63
+ headers: { "Content-Type": "application/json" },
64
+ body: JSON.stringify({productId: id})
65
+ };
66
+ trackPromise(
67
+ fetch("/deleteProductFromCart", options).then(res => res.json()).then(
68
+ (result) => {
69
+ console.log(result)
70
+ if (result.status == 200) {
71
+ this.setState({
72
+ products: result.cart.products,
73
+ totalPrice: result.cart.products.reduce(
74
+ (acc, item) => acc + item.price * item.quantity,
75
+ 0
76
+ ),
77
+ });
78
+ swal("Success","Product Deleted Successfully From Cart", "success")
79
+ }
80
+ },
81
+ (error) => {
82
+ console.log(error);
83
+ }
84
+ ));
85
+ }
86
+ })
87
+ }
88
+ async payNow(){
89
+ if(this.state.products.length < 1){
90
+ swal("Error", "Please add atleast one product to the cart","error")
91
+ return;
92
+ }
93
+ var options = {
94
+ method: "GET",
95
+ headers: { "Content-Type": "application/json" },
96
+ };
97
+ trackPromise(
98
+ await fetch("/payNow", options).then(res => {
99
+ if(res.status == 200){
100
+ swal("Success","Payment is successful","success");
101
+ this.setState({products:[], totalPrice: 0});
102
+ this.onUpdateCart(this.state.products.length);
103
+ }
104
+ else{
105
+ swal("Error","There was an error","error");
106
+ }
107
+ }))
108
+
109
+ }
110
+ async updateQuantity(e, id) {
111
+ var quantity = Number(e.target.value);
112
+ var product = this.state.products.filter(p => p.id == id);
113
+ product = product[0]
114
+ product.quantity = quantity;
115
+ var products = this.state.products;
116
+ products.map((p) => {if(p.id == id) p = product})
117
+ var options = {
118
+ method: "POST",
119
+ headers: { "Content-Type": "application/json" },
120
+ body:JSON.stringify({product:{productId: product.id, price: product.price, quantity: product.quantity}})
121
+ };
122
+ fetch("/updateProductInCart", options).then(res => res.json()).then(
123
+ (result) => {
124
+ console.log(result)
125
+ if (result.status == 200) {
126
+ this.setState({
127
+ products: result.cart.products,
128
+ totalPrice: result.cart.products.reduce(
129
+ (acc, item) => acc + item.price * item.quantity,
130
+ 0
131
+ ),
132
+ });
133
+ }
134
+ },
135
+ (error) => {
136
+ console.log(error);
137
+ }
138
+ );
139
+ }
140
+
141
+ render() {
142
+ return (
143
+ <div className="productSlider mb-5 mt-5">
144
+ <Container>
145
+ <h5 className="text-left mb-4 ps-2">Cart List</h5>
146
+ <Row>
147
+ <div className="col-9 cartShow">
148
+ <Table bordered hover responsive="sm">
149
+ <thead>
150
+ <tr>
151
+ <th>Product Img</th>
152
+ <th>Name</th>
153
+ <th>Price</th>
154
+ <th>Quantity</th>
155
+ <th>Sub Total</th>
156
+ <th>Delete</th>
157
+ </tr>
158
+ </thead>
159
+ <tbody>
160
+ <LoadingIndicator/>
161
+ {this.state.products.map((product, idx) => (
162
+ <OrderedProduct
163
+ key={product.id}
164
+ isCart={true}
165
+ product={product}
166
+ onDelete={(id) => this.deleteFromCart(id)}
167
+ onUpdate={(e, id) => this.updateQuantity(e, id)}
168
+ />
169
+ ))}
170
+ </tbody>
171
+ </Table>
172
+ </div>
173
+ <div className="col-3 cartSum boxShadaw bg-light p-4">
174
+ <h5 className="text-left mb-4 pb-2">Cart Price</h5>
175
+ <div className="d-flex justify-content-between mb-3">
176
+ <h6 className="fw-normal">Tax :</h6>
177
+ <span>{(this.state.totalPrice * (17 / 117)).toFixed(2)}$</span>
178
+ </div>
179
+ <div className="d-flex justify-content-between mb-4">
180
+ <h6 className="fw-normal">SubTotal Price :</h6>
181
+ <span>{(this.state.totalPrice * (100 / 117)).toFixed(2)}$</span>
182
+ </div>
183
+ <div className="d-flex justify-content-between fw-bold">
184
+ <h6>Total Price :</h6>
185
+ <span>{this.state.totalPrice}$</span>
186
+ </div>
187
+ <Button onClick={() => this.payNow()} variant="dark" size="md" className="mt-4 w-100">
188
+ pay now
189
+ </Button>
190
+ </div>
191
+ </Row>
192
+ </Container>
193
+ </div>
194
+ );
195
+ }
196
+ }
197
+
198
+ export default ShoppingCart;
@@ -0,0 +1,76 @@
1
+ //import useState hook to create menu collapse state
2
+ import React, { useState } from "react";
3
+
4
+ //import react pro sidebar components
5
+ import {
6
+ ProSidebar,
7
+ Menu,
8
+ MenuItem,
9
+ SidebarHeader,
10
+ SidebarFooter,
11
+ SidebarContent
12
+ } from "react-pro-sidebar";
13
+
14
+ //import icons from react icons
15
+ import { FaList, FaRegHeart } from "react-icons/fa";
16
+ import {
17
+ FiHome,
18
+ FiLogOut,
19
+ FiArrowLeftCircle,
20
+ FiArrowRightCircle
21
+ } from "react-icons/fi";
22
+ import { RiPencilLine } from "react-icons/ri";
23
+ import { BiCog } from "react-icons/bi";
24
+
25
+ //import sidebar css from react-pro-sidebar module and our custom css
26
+ import "react-pro-sidebar/dist/css/styles.css";
27
+ import "../css/sideNav.css";
28
+
29
+ const Header = () => {
30
+ //create initial menuCollapse state using useState hook
31
+ const [menuCollapse, setMenuCollapse] = useState(false);
32
+
33
+ //create a custom function that will change menucollapse state from false to true and true to false
34
+ const menuIconClick = () => {
35
+ //condition checking to change state from true to false and vice versa
36
+ menuCollapse ? setMenuCollapse(false) : setMenuCollapse(true);
37
+ };
38
+
39
+ return (
40
+ <>
41
+ <div id="header">
42
+ {/* collapsed props to change menu size using menucollapse state */}
43
+ <ProSidebar collapsed={menuCollapse}>
44
+ <SidebarHeader>
45
+ {/* <div className="logotext"> */}
46
+ {/* small and big change using menucollapse state */}
47
+ {/* <p>{menuCollapse ? "Logo" : "Big Logo"}</p> */}
48
+ {/* </div> */}
49
+ <div className="closemenu" onClick={menuIconClick}>
50
+ {/* changing menu collapse icon on click */}
51
+ {menuCollapse ? <FiArrowRightCircle /> : <FiArrowLeftCircle />}
52
+ </div>
53
+ </SidebarHeader>
54
+ <SidebarContent>
55
+ <Menu iconShape="square">
56
+ <MenuItem active={true} icon={<FiHome />}>
57
+ Home
58
+ </MenuItem>
59
+ <MenuItem icon={<FaList />}>Category</MenuItem>
60
+ <MenuItem icon={<FaRegHeart />}>Favourite</MenuItem>
61
+ <MenuItem icon={<RiPencilLine />}>Author</MenuItem>
62
+ <MenuItem icon={<BiCog />}>Settings</MenuItem>
63
+ </Menu>
64
+ </SidebarContent>
65
+ {/* <SidebarFooter>
66
+ <Menu iconShape="square">
67
+ <MenuItem icon={<FiLogOut />}>Logout</MenuItem>
68
+ </Menu>
69
+ </SidebarFooter> */}
70
+ </ProSidebar>
71
+ </div>
72
+ </>
73
+ );
74
+ };
75
+
76
+ export default Header;