| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
# SEG3125-LAB8
 | 
			
		||||
 | 
			
		||||
The Real Estate Website using React made by Ruchira Perrera, Sam Oyediran, Batuhan Basoglu, and Kene Ojukwu
 | 
			
		||||
The Real Estate Website using React made by Ruchira Perrera, Sam Oyediran, Batuhan Basoglu, and Kene Ojukwu.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
After npm start execute the command "node src/shared-components/contact-us/index.js" in order to set up the backend of the contact form.
 | 
			
		||||
 | 
			
		||||
# Authors
 | 
			
		||||
 | 
			
		||||
- Batuhan Basoglu, 300001274 - ArcticHawk1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20791
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										28
									
								
								package.json
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -6,14 +6,27 @@
 | 
			
		|||
    "@testing-library/jest-dom": "^5.11.10",
 | 
			
		||||
    "@testing-library/react": "^11.2.5",
 | 
			
		||||
    "@testing-library/user-event": "^12.8.3",
 | 
			
		||||
    "axios": "^0.21.1",
 | 
			
		||||
    "bootstrap": "^4.6.0",
 | 
			
		||||
    "cors": "^2.8.5",
 | 
			
		||||
    "express": "^4.17.1",
 | 
			
		||||
    "joi-browser": "^13.4.0",
 | 
			
		||||
    "nodemailer": "^6.5.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-alert": "^7.0.2",
 | 
			
		||||
    "react-alert-template-basic": "^1.0.0",
 | 
			
		||||
    "react-bootstrap": "^1.5.2",
 | 
			
		||||
    "react-bootstrap-carousel": "^4.1.1",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
    "react-fa": "^5.0.0",
 | 
			
		||||
    "react-form-with-constraints": "^0.16.0",
 | 
			
		||||
    "react-form-with-constraints-bootstrap4": "^0.16.0",
 | 
			
		||||
    "react-google-maps": "^9.4.5",
 | 
			
		||||
    "react-hook-form": "^7.0.0",
 | 
			
		||||
    "react-router-dom": "^5.2.0",
 | 
			
		||||
    "react-scripts": "4.0.3",
 | 
			
		||||
    "react-select": "^4.3.0",
 | 
			
		||||
    "reactstrap": "^8.9.0",
 | 
			
		||||
    "spectre.css": "^0.5.9",
 | 
			
		||||
    "web-vitals": "^1.1.1"
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			@ -43,5 +56,18 @@
 | 
			
		|||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "create-react-component-folder": "^0.3.7"
 | 
			
		||||
  }
 | 
			
		||||
  },
 | 
			
		||||
  "description": "The Real Estate Website using React made by Ruchira Perrera, Sam Oyediran, Batuhan Basoglu, and Kene Ojukwu.",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git+https://github.com/ArcticHawk1/SEG3125-LAB8.git"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [],
 | 
			
		||||
  "author": "",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/ArcticHawk1/SEG3125-LAB8/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": ""
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import { BrowserRouter, Route } from "react-router-dom";
 | 
			
		|||
import HomePage from "./homePage/Homepage";
 | 
			
		||||
import ListingsPage from "./listings-page/ListingsPage";
 | 
			
		||||
import AgentPage from "./agent-page/AgentPage";
 | 
			
		||||
// import ContactUs from "./shared-components/Contact-us/Contact-us";
 | 
			
		||||
import ContactUs from "./shared-components/contact-us/contact-us";
 | 
			
		||||
 | 
			
		||||
class App extends Component {
 | 
			
		||||
  render() {
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ class App extends Component {
 | 
			
		|||
          <Route exact path="/" component={HomePage}></Route>
 | 
			
		||||
          <Route path="/listings" component={ListingsPage}></Route>
 | 
			
		||||
          <Route path="/agents" component={AgentPage}></Route>
 | 
			
		||||
          <Route path="/contact-us" component={ContactUs}></Route>
 | 
			
		||||
        </BrowserRouter>
 | 
			
		||||
        <Footer></Footer>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,25 +4,30 @@
 | 
			
		|||
    white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.white-section {
 | 
			
		||||
    background-color: #ffffff;
 | 
			
		||||
    padding-top: 10rem;
 | 
			
		||||
    padding-bottom: 5rem;
 | 
			
		||||
    padding-left: 18%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#title .container-fluid {
 | 
			
		||||
    padding: 4% 34% 6%;
 | 
			
		||||
    padding: 5% 34% 6%;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    font-family: "Georgia";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#features .container-fluid {
 | 
			
		||||
    padding: 2% 48% 2%;
 | 
			
		||||
    padding: 2% 14% 4%;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    font-family: "Georgia";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.housesIntro{
 | 
			
		||||
    padding: 4% 5%;
 | 
			
		||||
    width: 1200px;
 | 
			
		||||
    height: 800px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.contactIntro{
 | 
			
		||||
| 
						 | 
				
			
			@ -31,23 +36,9 @@
 | 
			
		|||
    padding-bottom: 80px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.carouselSection {
 | 
			
		||||
    margin: 2% 8%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.headerImg{
 | 
			
		||||
    width: 2000px;
 | 
			
		||||
    height: 600px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.heading-1{
 | 
			
		||||
    padding-left: 40%;
 | 
			
		||||
    padding-top: 10%;
 | 
			
		||||
    padding-bottom: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.formhelper{
 | 
			
		||||
    padding-bottom: 15px;
 | 
			
		||||
    width: 1200px;
 | 
			
		||||
    height: 800px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.button-1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -67,3 +58,69 @@
 | 
			
		|||
    padding-left: 45%;
 | 
			
		||||
    padding-top: 15px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.buttonka{
 | 
			
		||||
    padding-top: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.prev-icon,
 | 
			
		||||
.next-icon {
 | 
			
		||||
  height: 210px;
 | 
			
		||||
  width: 100px;
 | 
			
		||||
  outline: black;
 | 
			
		||||
  background-size: 100%, 100%;
 | 
			
		||||
  border-radius: 50%;
 | 
			
		||||
  background-image: none;
 | 
			
		||||
  text-shadow: 2px 2px 5px black;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.next-icon:after
 | 
			
		||||
{
 | 
			
		||||
  content: '>';
 | 
			
		||||
  font-size: 140px;
 | 
			
		||||
  color: rgb(255, 255, 255);
 | 
			
		||||
  text-shadow: 2px 2px 5px black;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.prev-icon:after {
 | 
			
		||||
  content: '<';
 | 
			
		||||
  font-size: 140px;
 | 
			
		||||
  color: rgb(255, 255, 255);
 | 
			
		||||
  text-shadow: 2px 2px 5px black;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ol.carousel-indicators {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    bottom: 5px;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    width: auto;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 ol.carousel-indicators li,
 | 
			
		||||
 ol.carousel-indicators li.active {
 | 
			
		||||
    width: 1rem;
 | 
			
		||||
    height: 1rem;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    border-radius: 50%;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    background: transparent;
 | 
			
		||||
    box-shadow: 0 0 1px 1px black;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 ol.carousel-indicators li {
 | 
			
		||||
    background: rgb(255, 255, 255);
 | 
			
		||||
    margin-left: .5rem;
 | 
			
		||||
    margin-right: .5rem;
 | 
			
		||||
    box-shadow: 0 0 1px 1px black;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 ol.carousel-indicators li.active {
 | 
			
		||||
    background: #17a2b8;
 | 
			
		||||
    box-shadow: 0 0 1px 1px black;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
.homePage{
 | 
			
		||||
    padding-bottom: 15%;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,20 +3,23 @@ import "./Homepage.css";
 | 
			
		|||
import house1 from "../images/house1.jpg";
 | 
			
		||||
import house2 from "../images/house2.jpg";
 | 
			
		||||
import house3 from "../images/house3.jpg";
 | 
			
		||||
import house4 from "../images/house4.jpg";
 | 
			
		||||
import Carousel from "react-bootstrap/Carousel";
 | 
			
		||||
import Button from "react-bootstrap/Button";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Homepage extends Component {
 | 
			
		||||
  constructor(props) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.state = {
 | 
			
		||||
      firstname: "",
 | 
			
		||||
      lastname: "",
 | 
			
		||||
      email: "",
 | 
			
		||||
      message: "",
 | 
			
		||||
      nextIcon: <span className="next-icon"></span>,
 | 
			
		||||
      prevIcon: <span className="prev-icon"></span>,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { nextIcon, prevIcon } = this.state;
 | 
			
		||||
    return (
 | 
			
		||||
      <div className="homePage">
 | 
			
		||||
        <section className="colored-section" id="title">
 | 
			
		||||
| 
						 | 
				
			
			@ -29,98 +32,70 @@ class Homepage extends Component {
 | 
			
		|||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </section>
 | 
			
		||||
        <section className="white-section" id="white-section">
 | 
			
		||||
        <section className="white-section">
 | 
			
		||||
          <div className="housesIntro">
 | 
			
		||||
            <Carousel>
 | 
			
		||||
            <Carousel nextIcon={nextIcon} prevIcon={prevIcon}>
 | 
			
		||||
              <Carousel.Item>
 | 
			
		||||
                <img className="headerImg" src={house1} alt="First House" />
 | 
			
		||||
                <Carousel.Caption>
 | 
			
		||||
                  <h3 style={{ fontSize: "250%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>100 Charlie Rogers, Kanata, ON K2V 1A7</h3>
 | 
			
		||||
                  <h2 style={{ fontSize: "150%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>1 Bedroom, 2 Bathroom</h2>
 | 
			
		||||
                  <div className="buttonka">
 | 
			
		||||
                    <Button href="/listings" variant="info">Click for Details</Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </Carousel.Caption>
 | 
			
		||||
              </Carousel.Item>
 | 
			
		||||
              <Carousel.Item>
 | 
			
		||||
                <img className="headerImg" src={house2} alt="Second House" />
 | 
			
		||||
                <Carousel.Caption>
 | 
			
		||||
                  <h3 style={{ fontSize: "250%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>1490 Youville Drive, Orléans, ON K1C 2X8</h3>
 | 
			
		||||
                  <h2 style={{ fontSize: "150%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>1 Bedroom, 2 Bathroom</h2>
 | 
			
		||||
                  <div className="buttonka">
 | 
			
		||||
                    <Button href="/listings" variant="info">Click for Details</Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </Carousel.Caption>
 | 
			
		||||
              </Carousel.Item>
 | 
			
		||||
              <Carousel.Item>
 | 
			
		||||
                <img className="headerImg" src={house3} alt="Third House" />
 | 
			
		||||
                <Carousel.Caption>
 | 
			
		||||
                  <h3 style={{ fontSize: "250%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>8720 Russell Road, Navan, ON K4B 1J1</h3>
 | 
			
		||||
                  <h2 style={{ fontSize: "150%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>1 Bedroom, 2 Bathroom</h2>
 | 
			
		||||
                  <div className="buttonka">
 | 
			
		||||
                    <Button href="/listings" variant="info">Click for Details</Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </Carousel.Caption>
 | 
			
		||||
              </Carousel.Item>
 | 
			
		||||
              <Carousel.Item>
 | 
			
		||||
                <img className="headerImg" src={house4} alt="Fourth House" />
 | 
			
		||||
                <Carousel.Caption>
 | 
			
		||||
                  <h3 style={{ fontSize: "250%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>2785 8th Line Road, Metcalfe, ON K0A 2P0</h3>
 | 
			
		||||
                  <h2 style={{ fontSize: "150%", textShadow: "-2px 0 black, 0 2px black, 2px 0 black, 0 -2px black" }}>1 Bedroom, 2 Bathroom</h2>
 | 
			
		||||
                  <div className="buttonka">
 | 
			
		||||
                    <Button href="/listings" variant="info">Click for Details</Button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </Carousel.Caption>
 | 
			
		||||
              </Carousel.Item>
 | 
			
		||||
            </Carousel>
 | 
			
		||||
          </div>
 | 
			
		||||
        </section>
 | 
			
		||||
        <section class="colored-section" id="contact">
 | 
			
		||||
          <div className="container-fluid">
 | 
			
		||||
            <div className="contactIntro">
 | 
			
		||||
              <h2 className="heading-1">Contact Us</h2>
 | 
			
		||||
              <form
 | 
			
		||||
                id="contact-form"
 | 
			
		||||
                onSubmit={this.handleSubmit.bind(this)}
 | 
			
		||||
                method="POST"
 | 
			
		||||
              >
 | 
			
		||||
                <div className="formhelper row">
 | 
			
		||||
                  <div className="col-6">
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="text"
 | 
			
		||||
                      className="form-control"
 | 
			
		||||
                      placeholder="First Name"
 | 
			
		||||
                      value={this.state.firstname}
 | 
			
		||||
                      onChange={this.onFirstNameChange.bind(this)}
 | 
			
		||||
                    />
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div className="col-6">
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="text"
 | 
			
		||||
                      className="form-control"
 | 
			
		||||
                      placeholder="Last Name"
 | 
			
		||||
                      value={this.state.lastname}
 | 
			
		||||
                      onChange={this.onLastNameChange.bind(this)}
 | 
			
		||||
                    />
 | 
			
		||||
            <section className="colored-section" id="features">
 | 
			
		||||
              <div className="container-fluid">
 | 
			
		||||
                <div className="row">
 | 
			
		||||
                  <div className="col-12">
 | 
			
		||||
                    <h2 style={{ paddingLeft: "22rem", paddingBottom: "1rem", fontFamily: "Trebuchet MS" }}>Description </h2>
 | 
			
		||||
                    <p style={{ fontSize: "110%" }}> Welcome to Kene's Cribs. Kene's Cribs is a real estator company which provides the clients with the houses. <br></br>
 | 
			
		||||
                  	 The houses limited to the clients are only limited to the clients' dreams. In order to further navigate the<br></br>
 | 
			
		||||
                     website, use the navigation bar to switch between pages. Listings page is for browsing houses, Agents page<br></br>
 | 
			
		||||
                     is for browsing the estators, the Contact Us page is for the contacting us and the login page is for our<br></br>
 | 
			
		||||
                     members who want to benefit from our deals. Above are some houses which can interest you. Feel free to<br></br>
 | 
			
		||||
                     click the buttons above to explore the houses you want. </p>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div className="form-group">
 | 
			
		||||
                  <input
 | 
			
		||||
                    type="email"
 | 
			
		||||
                    className="form-control"
 | 
			
		||||
                    placeholder="Email Address"
 | 
			
		||||
                    aria-describedby="emailHelp"
 | 
			
		||||
                    value={this.state.email}
 | 
			
		||||
                    onChange={this.onEmailChange.bind(this)}
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
                <div className="form-group">
 | 
			
		||||
                  <textarea
 | 
			
		||||
                    className="form-control"
 | 
			
		||||
                    placeholder="Message"
 | 
			
		||||
                    rows="5"
 | 
			
		||||
                    value={this.state.message}
 | 
			
		||||
                    onChange={this.onMessageChange.bind(this)}
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
                <div className="buttonhelper">
 | 
			
		||||
                  <button type="submit" className="button-1">
 | 
			
		||||
                    Submit
 | 
			
		||||
                  </button>
 | 
			
		||||
                </div>
 | 
			
		||||
              </form>
 | 
			
		||||
            </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </section>
 | 
			
		||||
          </div>
 | 
			
		||||
        </section>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  onFirstNameChange(event) {
 | 
			
		||||
    this.setState({ firstname: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onLastNameChange(event) {
 | 
			
		||||
    this.setState({ lastname: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onEmailChange(event) {
 | 
			
		||||
    this.setState({ email: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onMessageChange(event) {
 | 
			
		||||
    this.setState({ message: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleSubmit(event) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Homepage;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
export { default } from "./homePage";
 | 
			
		||||
export { default } from "./homePage";
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 253 KiB  | 
| 
		 Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 245 KiB  | 
| 
		 Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 288 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/images/house4.jpg
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 114 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
.colored-section {
 | 
			
		||||
    background-color: #e7dec8;
 | 
			
		||||
    color: #000000;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#contact .container-fluid {
 | 
			
		||||
    padding-top: 50px;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    font-family: "Georgia";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.contactIntro{
 | 
			
		||||
    padding-left: 10%;
 | 
			
		||||
    padding-right: 10%;
 | 
			
		||||
    padding-bottom: 80px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.heading-1{
 | 
			
		||||
    padding-left: 38%;
 | 
			
		||||
    padding-top: 10px;
 | 
			
		||||
    padding-bottom: 20%;
 | 
			
		||||
    font-size: 40px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.formhelper{
 | 
			
		||||
    padding-bottom: 15px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#dropdown{
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 40px;   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
input, textarea {
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
[data-feedback] {
 | 
			
		||||
    margin-bottom: 10px;  
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
[data-feedback].error {
 | 
			
		||||
    color: red;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
							
								
								
									
										4
									
								
								src/shared-components/contact-us/config.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
module.exports = {
 | 
			
		||||
    USER: 'a0f17fd29c4ac0', 
 | 
			
		||||
    PASS: '671f8cbe2bd5e2'
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,220 @@
 | 
			
		|||
import React, { Component } from "react";
 | 
			
		||||
import "./Contact-us.css";
 | 
			
		||||
import axios from 'axios'
 | 
			
		||||
import {
 | 
			
		||||
  FieldFeedback,
 | 
			
		||||
  FieldFeedbacks,
 | 
			
		||||
  FormWithConstraints
 | 
			
		||||
} from 'react-form-with-constraints';
 | 
			
		||||
import Alert from 'react-bootstrap/Alert';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ContactUs extends Component {
 | 
			
		||||
  constructor(props) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.state = {
 | 
			
		||||
      firstname: "",
 | 
			
		||||
      lastname: "",
 | 
			
		||||
      email: "",
 | 
			
		||||
      message: "",
 | 
			
		||||
      agent: "",
 | 
			
		||||
      house: "",
 | 
			
		||||
      alertBad: false,
 | 
			
		||||
      alertSucess: false,
 | 
			
		||||
      time: false
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    return <div>ContactUs</div>;
 | 
			
		||||
    return (
 | 
			
		||||
      <div className="contact-us">
 | 
			
		||||
        <Alert variant="danger" style={{ display: this.state.alertBad ? "block" : "none" }} onClose={() => this.setState({ alertBad: false })} dismissible>
 | 
			
		||||
          <Alert.Heading>Message could not send.</Alert.Heading>
 | 
			
		||||
          <p>
 | 
			
		||||
            There are some errors in your contact form.
 | 
			
		||||
        </p>
 | 
			
		||||
        </Alert>
 | 
			
		||||
        <Alert variant="success" style={{ display: this.state.alertSucess ? "block" : "none" }} onClose={() => this.setState({ alertSucess: false })} dismissible>
 | 
			
		||||
          <Alert.Heading>The message is successfully sent.</Alert.Heading>
 | 
			
		||||
          <p>
 | 
			
		||||
            You contact form will be delivered to our support team.
 | 
			
		||||
        </p>
 | 
			
		||||
        </Alert>
 | 
			
		||||
        <div className="container">
 | 
			
		||||
          <section class="colored-section" id="contact">
 | 
			
		||||
            <div className="container-fluid">
 | 
			
		||||
              <div className="contactIntro">
 | 
			
		||||
                <h2 className="heading-1">Contact Us</h2>
 | 
			
		||||
                <FormWithConstraints ref={form => this.form = form}
 | 
			
		||||
                  id="contact-form"
 | 
			
		||||
                  onSubmit={this.handleSubmit.bind(this)}
 | 
			
		||||
                  method="POST"
 | 
			
		||||
                  noValidate
 | 
			
		||||
                >
 | 
			
		||||
 | 
			
		||||
                  <div className="row">
 | 
			
		||||
                    <div className="col-6">
 | 
			
		||||
                      <select className="form-group" name="agent" id="dropdown" required onChange={this.onAgentChange.bind(this)} value={this.state.agent}>
 | 
			
		||||
                        <option value="">Select an Agent</option>
 | 
			
		||||
                        <option value="Michael">Michael</option>
 | 
			
		||||
                        <option value="Jin">Jin </option>
 | 
			
		||||
                        <option value="Anita">Anita</option>
 | 
			
		||||
                        <option value="Alex">Alex</option>
 | 
			
		||||
                        <option value="Xuan">Xuan</option>
 | 
			
		||||
                        <option value="Walter">Walter</option>
 | 
			
		||||
                        <option value="No preference">No preference</option>
 | 
			
		||||
                      </select>
 | 
			
		||||
                      <FieldFeedbacks for="agent">
 | 
			
		||||
                        <FieldFeedback when="*" />
 | 
			
		||||
                      </FieldFeedbacks>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div className="col-6">
 | 
			
		||||
                      <select className="form-group" name="house" id="dropdown" required onChange={this.onHouseChange.bind(this)} value={this.state.house}>
 | 
			
		||||
                        <option value="">Select a House</option>
 | 
			
		||||
                        <option value="100 Charlie Rogers">100 Charlie Rogers</option>
 | 
			
		||||
                        <option value="1490 Youville Drive">1490 Youville Drive </option>
 | 
			
		||||
                        <option value="8720 Russell Road">8720 Russell Road</option>
 | 
			
		||||
                        <option value="2785 8th Line Road">2785 8th Line Road</option>
 | 
			
		||||
                        <option value="No preference">No preference</option>
 | 
			
		||||
                      </select>
 | 
			
		||||
                      <FieldFeedbacks for="house">
 | 
			
		||||
                        <FieldFeedback when="*" />
 | 
			
		||||
                      </FieldFeedbacks>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
 | 
			
		||||
                  <div className="formhelper row">
 | 
			
		||||
                    <div className="col-6">
 | 
			
		||||
                      <input name="firstname"
 | 
			
		||||
                        type="text"
 | 
			
		||||
                        className="form-control"
 | 
			
		||||
                        placeholder="First Name"
 | 
			
		||||
                        value={this.state.firstname}
 | 
			
		||||
                        required onChange={this.onFirstNameChange.bind(this)}
 | 
			
		||||
                      />
 | 
			
		||||
                      <FieldFeedbacks for="firstname">
 | 
			
		||||
                        <FieldFeedback when="*" />
 | 
			
		||||
                      </FieldFeedbacks>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div className="col-6">
 | 
			
		||||
                      <input name="lastname"
 | 
			
		||||
                        type="text"
 | 
			
		||||
                        className="form-control"
 | 
			
		||||
                        placeholder="Last Name"
 | 
			
		||||
                        value={this.state.lastname}
 | 
			
		||||
                        required onChange={this.onLastNameChange.bind(this)}
 | 
			
		||||
                      />
 | 
			
		||||
                      <FieldFeedbacks for="lastname">
 | 
			
		||||
                        <FieldFeedback when="*" />
 | 
			
		||||
                      </FieldFeedbacks>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div className="form-group">
 | 
			
		||||
                    <input name="email"
 | 
			
		||||
                      type="email"
 | 
			
		||||
                      className="form-control"
 | 
			
		||||
                      placeholder="Email Address"
 | 
			
		||||
                      aria-describedby="emailHelp"
 | 
			
		||||
                      value={this.state.email}
 | 
			
		||||
                      required onChange={this.onEmailChange.bind(this)}
 | 
			
		||||
                    />
 | 
			
		||||
                    <FieldFeedbacks for="email">
 | 
			
		||||
                      <FieldFeedback when="*" />
 | 
			
		||||
                    </FieldFeedbacks>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div className="form-group">
 | 
			
		||||
                    <textarea name="message"
 | 
			
		||||
                      className="form-control"
 | 
			
		||||
                      placeholder="Message"
 | 
			
		||||
                      rows="5"
 | 
			
		||||
                      value={this.state.message}
 | 
			
		||||
                      required onChange={this.onMessageChange.bind(this)}
 | 
			
		||||
                    />
 | 
			
		||||
                    <FieldFeedbacks for="message">
 | 
			
		||||
                      <FieldFeedback when="*" />
 | 
			
		||||
                    </FieldFeedbacks>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div className="buttonhelper">
 | 
			
		||||
                    <button type="submit" className="button-1">
 | 
			
		||||
                      Submit
 | 
			
		||||
                  </button>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </FormWithConstraints>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </section>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onAgentChange(event) {
 | 
			
		||||
    this.setState({ agent: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onHouseChange(event) {
 | 
			
		||||
    this.setState({ house: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onFirstNameChange(event) {
 | 
			
		||||
    this.setState({ firstname: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onLastNameChange(event) {
 | 
			
		||||
    this.setState({ lastname: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onEmailChange(event) {
 | 
			
		||||
    this.setState({ email: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onMessageChange(event) {
 | 
			
		||||
    this.setState({ message: event.target.value });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleChange = e => {
 | 
			
		||||
    this.form.validateFields(e.target);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleSubmit(event) {
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
 | 
			
		||||
    this.form.validateFields();
 | 
			
		||||
 | 
			
		||||
    if (!this.form.isValid()) {
 | 
			
		||||
      this.alertBad();
 | 
			
		||||
      return;
 | 
			
		||||
    } else {
 | 
			
		||||
      this.alertSuccess();
 | 
			
		||||
      axios({
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        url: "http://localhost:3002/send",
 | 
			
		||||
        data: this.state
 | 
			
		||||
      }).then((response) => {
 | 
			
		||||
        if (response.data.status === 'success') {
 | 
			
		||||
          this.resetForm();
 | 
			
		||||
        } else if (response.data.status === 'fail') {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  alertSuccess(){
 | 
			
		||||
    this.setState({ alertBad: false, alertSucess: true })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  alertBad(){
 | 
			
		||||
    this.setState({ alertSucess: false, alertBad: true  })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  resetForm() {
 | 
			
		||||
    this.setState({ firstname: '', lastname: '', email: '', message: '', agent: '', house: '' })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default ContactUs;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1,60 @@
 | 
			
		|||
export { default } from "./Contact-us";
 | 
			
		||||
var express = require('express');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var nodemailer = require('nodemailer');
 | 
			
		||||
var cors = require('cors');
 | 
			
		||||
const creds = require('./config');
 | 
			
		||||
 | 
			
		||||
var transport = {
 | 
			
		||||
    host: 'smtp.mailtrap.io', // Don’t forget to replace with the SMTP host of your provider
 | 
			
		||||
    port: 2525,
 | 
			
		||||
    auth: {
 | 
			
		||||
        user: creds.USER,
 | 
			
		||||
        pass: creds.PASS
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var transporter = nodemailer.createTransport(transport)
 | 
			
		||||
 | 
			
		||||
transporter.verify((error, success) => {
 | 
			
		||||
    if (error) {
 | 
			
		||||
        console.log(error);
 | 
			
		||||
    } else {
 | 
			
		||||
        console.log('Server is ready to take messages');
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.post('/send', (req, res, next) => {
 | 
			
		||||
    var firstname = req.body.firstname
 | 
			
		||||
    var lastname = req.body.lastname
 | 
			
		||||
    var email = req.body.email
 | 
			
		||||
    var agent = req.body.agent
 | 
			
		||||
    var house = req.body.house
 | 
			
		||||
    var message = req.body.message
 | 
			
		||||
    var content = `First Name: ${firstname} \n Last Name: ${lastname} \n E-mail: ${email} \n Agent: ${agent} \n House: ${house} \n Message: ${message} `
 | 
			
		||||
 | 
			
		||||
    var mail = {
 | 
			
		||||
        from: email,
 | 
			
		||||
        to: 'kenes@cribs.com',  // Change to email address that you want to receive messages on
 | 
			
		||||
        subject: 'New Message from Contact Form',
 | 
			
		||||
        text: content
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    transporter.sendMail(mail, (err, data) => {
 | 
			
		||||
        if (err) {
 | 
			
		||||
            res.json({
 | 
			
		||||
                status: 'fail'
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            res.json({
 | 
			
		||||
                status: 'success'
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const app = express()
 | 
			
		||||
app.use(cors())
 | 
			
		||||
app.use(express.json())
 | 
			
		||||
app.use('/', router)
 | 
			
		||||
app.listen(3002)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ const Navbar = () => {
 | 
			
		|||
            </li>
 | 
			
		||||
 | 
			
		||||
            <li className="nav-item">
 | 
			
		||||
              <Link className="nav-link" to="/">
 | 
			
		||||
              <Link className="nav-link" to="/contact-us">
 | 
			
		||||
                Contact Us
 | 
			
		||||
              </Link>
 | 
			
		||||
            </li>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||