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,173 @@
1
+ import React, { Component } from "react";
2
+ import Button from "react-bootstrap/Button";
3
+ import Modal from "react-bootstrap/Modal";
4
+ import { NavLink } from "react-router-dom";
5
+ import swal from 'sweetalert';
6
+ import {
7
+ FiLogIn,
8
+ } from "react-icons/fi";
9
+ class LoginModal extends Component {
10
+ constructor(props) {
11
+ super(props);
12
+ this.state = {
13
+ showModal: false,
14
+ email: "",
15
+ password: "",
16
+ ERROR: "",
17
+ reloadNavbar: props.reloadNavbar,
18
+ };
19
+ }
20
+
21
+ handleClose = () => {
22
+ this.setState({ showModal: false });
23
+ };
24
+ handleShow = () => {
25
+ this.setState({ showModal: true });
26
+ };
27
+ async dofetch() {
28
+ // check inputs
29
+ var email = this.state.email;
30
+ var password = this.state.password;
31
+ if (email == "" || password == "") {
32
+ this.setState({ ERROR: "Please fill all the fields" });
33
+ return;
34
+ }
35
+ if (!email.includes("@")) {
36
+ this.setState({ ERROR: "Please fill all the fields correctly" });
37
+ return;
38
+ }
39
+
40
+ // pass inputs to server
41
+ let user = { email, password };
42
+ var options = {
43
+ method: "POST",
44
+ headers: { "Content-Type": "application/json" },
45
+ body: JSON.stringify(user),
46
+ };
47
+
48
+ await fetch("/auth", options)
49
+ .then(
50
+ (res) => {
51
+ console.log(res);
52
+ if (res.status == 200) {
53
+ swal("Success!", "You Logged In!", "success");
54
+ document.location.href = "/";
55
+ }
56
+ else if(res.status == 404){
57
+ this.setState({ ERROR: "Email or password is not correct." });
58
+ return;
59
+ }
60
+ else if(res.status == 400){
61
+ this.setState({ ERROR: "There was an error. Please try again" });
62
+ return;
63
+ }
64
+ },
65
+ // Note: it's important to handle errors here
66
+ // instead of a catch() block so that we don't swallow
67
+ // exceptions from actual bugs in components.
68
+ (error) => {
69
+ this.setState({
70
+ ERROR: error
71
+ });
72
+ return;
73
+ }
74
+ )
75
+ // options = {
76
+ // method: "GET",
77
+ // headers: { "Content-Type": "application/json" }
78
+ // };
79
+ // await fetch("/getCurrentUser", options).then(res => res.json()).then((res) => {
80
+ // sessionStorage.setItem("profileImage", JSON.stringify(res.profileImage));
81
+ // sessionStorage.setItem("email", JSON.stringify(res.user.email));
82
+ // // alert(res.profileImage);
83
+ // this.state.reloadNavbar();
84
+ // // document.location.href = "/";
85
+ // })
86
+ }
87
+
88
+
89
+ inputsHandler = (e) => {
90
+ this.setState({ [e.target.name]: e.target.value });
91
+ };
92
+ render() {
93
+ return (
94
+ <div>
95
+ <Button
96
+ title="Log In"
97
+ class="btn btn-primary btn-lg btn-floating"
98
+ style={{display: this.props.showButton,"background-color": "#17c0eb"}}
99
+ onClick={() => this.handleShow()}
100
+ >
101
+ {this.props.menuCollapse ? "" :"Login"}<FiLogIn/>
102
+ </Button>
103
+ {/* <button style={{"float":"right"}} type="button" id="login" data-bs-toggle="modal" data-bs-target="#myModal">
104
+ Login */}
105
+
106
+ <Modal
107
+ style={{ opacity: 1 }}
108
+ show={this.state.showModal}
109
+ onHide={() => this.handleClose()}
110
+ >
111
+ <Modal.Header>
112
+ <Modal.Title>
113
+ <div className="modal-header">
114
+ <img src="images\login.png" width="72" height="72" />
115
+ <h5 className="modal-title" id="exampleModalLabel">
116
+ Please sign in
117
+ </h5>
118
+ </div>
119
+ </Modal.Title>
120
+ </Modal.Header>
121
+ <Modal.Body>
122
+ <form>
123
+ <div className="mb-3">
124
+ <input
125
+ type="email"
126
+ name="email"
127
+ id="email"
128
+ className="form-control"
129
+ placeholder="Email address"
130
+ onChange={this.inputsHandler}
131
+ required
132
+ autoFocus
133
+ />
134
+ </div>
135
+ <div className="mb-3">
136
+ <input
137
+ type="password"
138
+ name="password"
139
+ id="password"
140
+ className="form-control"
141
+ placeholder="Password"
142
+ onChange={this.inputsHandler}
143
+ required
144
+ />
145
+ </div>
146
+ </form>
147
+ </Modal.Body>
148
+ <Modal.Footer>
149
+ <h5>{this.state.ERROR}</h5>
150
+ <div className="modal-footer">
151
+ <button
152
+ className="btn btn-lg btn-primary btn-block"
153
+ onClick={() => this.dofetch()}
154
+ type="submit"
155
+ >
156
+ Sign in
157
+ </button>
158
+ <NavLink
159
+ style={{cursor:"pointer"}}
160
+ onClick={() => this.handleClose()}
161
+ to="/resetPassword"
162
+ >
163
+ forgot pasword ? click here
164
+ </NavLink>
165
+ </div>
166
+ </Modal.Footer>
167
+ </Modal>
168
+ </div>
169
+ );
170
+ }
171
+ }
172
+
173
+ export default LoginModal;
@@ -0,0 +1,271 @@
1
+ import React, { Component } from "react";
2
+ import Button from "react-bootstrap/Button";
3
+ import Modal from "react-bootstrap/Modal";
4
+ import { NavLink } from "react-router-dom";
5
+ import { FaPlus } from "react-icons/fa";
6
+ import '../css/newProductModal.css';
7
+ import withAuth from "./Auth.js"
8
+ import swal from 'sweetalert';
9
+ import LoadingIndicator from "./Spinner";
10
+ import { usePromiseTracker, trackPromise } from "react-promise-tracker";
11
+ class NewProductModal extends Component {
12
+ constructor(props) {
13
+ super(props);
14
+ this.state = {
15
+ showModal: props.showModal,
16
+ name: "",
17
+ price: 0,
18
+ description: "",
19
+ color: "#000000",
20
+ type: "",
21
+ picture: false,
22
+ src: false,
23
+ id: 0,
24
+ maxAmount:"",
25
+ ERROR: "",
26
+ };
27
+ }
28
+
29
+ handleClose = () => {
30
+ this.setState({ showModal: false });
31
+ };
32
+ handleShow = () => {
33
+ this.setState({ showModal: true });
34
+ };
35
+
36
+ async addProduct() {
37
+ var name = this.state.name;
38
+ var price = this.state.price;
39
+ var description = this.state.description;
40
+ var color = this.state.color;
41
+ var type = this.state.type;
42
+ var picture = this.state.picture;
43
+ var maxAmount = this.state.maxAmount;
44
+ if (
45
+ name == "" ||
46
+ price == "" ||
47
+ description == "" ||
48
+ color == "" ||
49
+ type == "" ||
50
+ maxAmount == "" ||
51
+ !picture
52
+ ) {
53
+ this.setState({ ERROR: "Please fill all the fields." });
54
+ return;
55
+ }
56
+ var product = {
57
+ name: name,
58
+ color: color,
59
+ description: description,
60
+ price: price,
61
+ type: type,
62
+ maxAmount: maxAmount
63
+ };
64
+
65
+ var options = {
66
+ method: "POST",
67
+ headers: { "Content-Type": "application/json" },
68
+ body: JSON.stringify({product: product}),
69
+ };
70
+ var id = 0;
71
+ trackPromise(
72
+ fetch("/addNewProduct", options).then(res => res.json()).then(
73
+ (res) => {
74
+ console.log(res);
75
+ if(res.status == 403){
76
+ swal("No permission","You don't have permission for this option","error");
77
+ return;
78
+ }
79
+ if (res.status == 200) {
80
+ id = res.id;
81
+ } else if (res.status == 400) {
82
+ this.setState({ ERROR: "There was an error. Please try again" });
83
+ } else if (res.status == 500) {
84
+ this.setState({ ERROR: "There was an error on our side" });
85
+ }
86
+ },
87
+ (error) => {
88
+ this.setState({
89
+ ERROR: error,
90
+ });
91
+ }
92
+ ));
93
+
94
+ if(id != 0){
95
+ var myFormData = new FormData();
96
+ myFormData.append('file', this.state.picture);
97
+ myFormData.append('id', id);
98
+
99
+ const response = await fetch("/addProductPicture", {
100
+ method: "POST",
101
+ body: myFormData,
102
+ });
103
+ if (response.status == 200) {
104
+ swal("Success!", "Product added successfully!", "success");
105
+ }
106
+ }else{
107
+ swal("Error!", "There was an error in uploading image", "error"); }
108
+ }
109
+ renderPreview() {
110
+ if(this.state.src) {
111
+ return (
112
+ <img src={this.state.src} style={{"maxWidth": "inherit", "maxHeight": "inherit"}}/>
113
+ );
114
+ } else {
115
+ return (
116
+ <p>
117
+ No Preview
118
+ </p>
119
+ );
120
+ }
121
+ }
122
+
123
+ handlePictureSelected(event) {
124
+ var picture = event.target.files[0];
125
+ var src = URL.createObjectURL(picture);
126
+
127
+ this.setState({
128
+ picture: picture,
129
+ src: src
130
+ });
131
+ }
132
+
133
+ inputsHandler = (e) => {
134
+ this.setState({ [e.target.name]: e.target.value });
135
+ };
136
+ radioHandler = (e) => {
137
+ this.setState({
138
+ [e.target.name]: document.querySelector(
139
+ `input[name=${e.target.name}]:checked`
140
+ ).id,
141
+ });
142
+ };
143
+ colorSelected = (e) => {
144
+ this.setState({
145
+ color : e.target.value});
146
+ };
147
+ render() {
148
+ return (
149
+ <div>
150
+ <br/>
151
+ <Modal
152
+ style={{ opacity: 1 }}
153
+ show={this.state.showModal}
154
+ onHide={() => this.handleClose()}
155
+ >
156
+ <Modal.Header>
157
+ <Modal.Title>
158
+ <div className="modal-header">
159
+ {/* <img src="images\login.png" width="72" height="72" /> */}
160
+ <h5 className="modal-title" id="exampleModalLabel">
161
+ Add new Flower
162
+ </h5>
163
+ </div>
164
+ </Modal.Title>
165
+ </Modal.Header>
166
+ <Modal.Body>
167
+ <LoadingIndicator/>
168
+ <form>
169
+ <div className="mb-3">
170
+ <input
171
+ type="text"
172
+ name="name"
173
+ id="name"
174
+ className="form-control"
175
+ placeholder="Name of the flower"
176
+ onChange={this.inputsHandler}
177
+ required
178
+ autoFocus
179
+ />
180
+ </div>
181
+ <div className="mb-3">
182
+ Pick a color
183
+ <input onChange={this.colorSelected} type="color" />
184
+ </div>
185
+ <div className="mb-3">
186
+ <input
187
+ type="text"
188
+ name="description"
189
+ id="description"
190
+ className="form-control"
191
+ placeholder="Description"
192
+ onChange={this.inputsHandler}
193
+ required
194
+ />
195
+ </div>
196
+ <div className="mb-3">
197
+ <input
198
+ type="number"
199
+ step="0.01"
200
+ name="price"
201
+ id="price"
202
+ className="form-control"
203
+ placeholder="Price"
204
+ onChange={this.inputsHandler}
205
+ required
206
+ />
207
+ </div>
208
+ <div className="mb-3">
209
+ <input
210
+ type="number"
211
+ name="maxAmount"
212
+ id="maxAmount"
213
+ className="form-control"
214
+ placeholder="Max Amount"
215
+ onChange={this.inputsHandler}
216
+ required
217
+ />
218
+ </div>
219
+ <div className="mb-3">
220
+ <input
221
+ type="radio"
222
+ name="type"
223
+ id="Bouquest"
224
+ onChange={this.radioHandler}
225
+ />
226
+ <label for="rd1">Bouquest</label>
227
+ <input
228
+ type="radio"
229
+ name="type"
230
+ id="Flower"
231
+ onChange={this.radioHandler}
232
+ />
233
+ <label for="rd2">Flower</label>
234
+ </div>
235
+ <div className="mb-3">
236
+ <h2>Upload Product Image</h2>
237
+ <input
238
+ name="file"
239
+ id="file"
240
+ type="file"
241
+ onChange={this.handlePictureSelected.bind(this)}
242
+ />
243
+ <br/>
244
+ <div style={{"maxWidth": "80%", "maxHeight": "80%"}}>
245
+ {this.renderPreview()}
246
+ </div>
247
+ <hr/>
248
+ </div>
249
+ </form>
250
+ </Modal.Body>
251
+ <Modal.Footer>
252
+ <h5>{this.state.ERROR}</h5>
253
+ <div className="modal-footer">
254
+ <button
255
+ className="button-17"
256
+ role="button"
257
+ onClick={() => this.addProduct()}
258
+ type="submit"
259
+ >
260
+ Add
261
+ </button>
262
+ </div>
263
+ </Modal.Footer>
264
+ </Modal>
265
+ </div>
266
+ );
267
+ }
268
+ }
269
+
270
+ // export default withAuth(NewProductModal);
271
+ export default NewProductModal;
@@ -0,0 +1,10 @@
1
+ import '../css/noPermission.css';
2
+ export default function NoPermission() {
3
+ return(<div className="center">
4
+ {/* <div className="lock"></div> */}
5
+ <div className="message">
6
+ <h1>Access to this page is restricted</h1>
7
+ <p>Please check with the site admin if you believe this is a mistake.</p>
8
+ </div>
9
+ </div>)
10
+ }
@@ -0,0 +1,104 @@
1
+ import { React, Component } from "react";
2
+ import sampleImage from "../logo.svg";
3
+ import "../css/catalog.css";
4
+ import "../css/orderedProduct.css";
5
+
6
+ import { FaHeart, FaRegHeart, FaShoppingCart, FaEye } from "react-icons/fa";
7
+
8
+ import Card from "react-bootstrap/Card";
9
+ import Button from "react-bootstrap/Button";
10
+ import { ButtonGroup, Container } from "react-bootstrap";
11
+ import * as Icon from "react-bootstrap-icons";
12
+ import ReactStars from "react-rating-stars-component";
13
+
14
+ class OrderedProduct extends Component {
15
+ constructor(props) {
16
+ super(props);
17
+ console.log(props.product);
18
+ this.state = {
19
+ isInCart: true,
20
+ id: props.product.id,
21
+ name: props.product.name,
22
+ price: props.product.price,
23
+ quantity: props.product.quantity,
24
+ image: props.product.image,
25
+ subTotal: props.product.price * props.product.quantity,
26
+ };
27
+ }
28
+
29
+ componentDidUpdate(prevProps, prevState) {
30
+ if (this.state.quantity !== prevState.quantity) {
31
+ this.setState({ subTotal: this.state.quantity * this.state.price });
32
+ }
33
+ }
34
+
35
+ arrayBufferToBase64(buffer) {
36
+ var binary = "";
37
+ var bytes = [].slice.call(new Uint8Array(buffer.data));
38
+ bytes.forEach((b) => (binary += String.fromCharCode(b)));
39
+ return window.btoa(binary);
40
+ }
41
+ render() {
42
+ var path = "";
43
+ try {
44
+ path =
45
+ "data:/" +
46
+ this.state.image.contentType +
47
+ ";base64," +
48
+ this.arrayBufferToBase64(this.state.image.data);
49
+ } catch (e) {
50
+ console.log("couldn't find path of profile image");
51
+ }
52
+ var currentItem = this.props.product;
53
+ return (
54
+ <tr key={currentItem.id}>
55
+ <td>
56
+ <img src={path} alt="productImg" />
57
+ </td>
58
+ <td>{currentItem.name}</td>
59
+ <td className="price-new">{currentItem.price}$</td>
60
+ {this.props.isCart ? (
61
+ <td>
62
+ <input
63
+ type="number"
64
+ id="quantity"
65
+ name="quantity"
66
+ min="1"
67
+ // max={props.product.maxQuantity}
68
+ step="1"
69
+ defaultValue={currentItem.quantity}
70
+ onChange={(e) => {
71
+ this.setState({ quantity: Number(e.target.value) });
72
+ this.props.onUpdate(e, currentItem.id);
73
+ }}
74
+ />
75
+ </td>
76
+ ) : (
77
+ <td>
78
+ <FaShoppingCart
79
+ onClick={() => this.props.onAdd(currentItem.id)}
80
+ style={{ cursor: "pointer" }}
81
+ />
82
+ </td>
83
+ )}
84
+ {this.props.isCart ? (
85
+ <td className="subTotalShow">{this.state.subTotal}</td>
86
+ ) : (
87
+ ""
88
+ )}
89
+ <td>
90
+ <Button
91
+ variant="dark"
92
+ size="sm"
93
+ className="ms-2"
94
+ onClick={() => this.props.onDelete(currentItem.id)}
95
+ >
96
+ <Icon.Trash></Icon.Trash>
97
+ </Button>
98
+ </td>
99
+ </tr>
100
+ );
101
+ }
102
+ }
103
+
104
+ export default OrderedProduct;
@@ -0,0 +1,51 @@
1
+ import "../css/chat.css";
2
+ import io from "socket.io-client";
3
+ import { useState } from "react";
4
+ import Chat from "./Chat";
5
+
6
+
7
+ const socket = io.connect("http://localhost:5000");
8
+
9
+
10
+ function PreChat() {
11
+ const [username, setUsername] = useState("");
12
+ const [room, setRoom] = useState("");
13
+ const [showChat, setShowChat] = useState(false);
14
+
15
+ const joinRoom = () => {
16
+ if (username !== "" && room !== "") {
17
+ socket.emit("join_room", room);
18
+ setShowChat(true);
19
+ }
20
+ };
21
+
22
+ return (
23
+ <div className="PreChat">
24
+
25
+ {!showChat ? (
26
+ <div className="joinChatContainer">
27
+ <h3>Join A Chat</h3>
28
+ <input
29
+ type="text"
30
+ placeholder="user name..."
31
+ onChange={(event) => {
32
+ setUsername(event.target.value);
33
+ }}
34
+ />
35
+ <input
36
+ type="text"
37
+ placeholder="Room ID..."
38
+ onChange={(event) => {
39
+ setRoom(event.target.value);
40
+ }}
41
+ />
42
+ <button onClick={joinRoom}>Join A Room</button>
43
+ </div>
44
+ ) : (
45
+ <Chat socket={socket} username={username} room={room} />
46
+ )}
47
+ </div>
48
+ );
49
+ }
50
+
51
+ export default PreChat;