Professional Documents
Culture Documents
A Project Report
submitted in partial fulfillment of the requirementsfor the award of
the degree of
ROBIN
19015041023
Ms. Kirti
Assistant Professor
(CSE)
(June 2022)
CANDIDATE DECLARATION
We hereby certify that the work which is being presented in this project entitled“Restaurant
Portfolio Website” is authentic record of our work carried out under the guidance of Ms. Kirti,
Assistant Professor (CSE). The matter embodied in this report has not been submitted to any
other University/ Institute for the award of any degree or diploma. I have followed all the guidelines
provided to me by the Institute in writing this thesis. I have also conformed to the norms and
guidelines given in the Ethical Codeof Conduct of the Institute.
ii
CERTIFICATE
This is to certify that the work in this project undertaking entitled “Restaurant Portfolio
Website” submitted by Robin in partial fulfillment of the requirements for the award of degree of
Bachelor of Computer Application in the academic during 2019-2022 is an authentic work
completed out by them under guidance and supervision of Ms. Kirti at the Department of
Computer Science and Engineering, IITM Group of Institutions, Murthal, Sonipat.
iii
ACKNOWLEDGEMENT
Before we get into thick of things, we would like to add few words of appreciation for the people
who have been a part of this project right from its inception. This project has been one of the
significant academic challenges we have faced and without the support, patience and guidance of
the people involved, this task would not have been completed.It is to owe our deepest gratitude.
It has been our privilege to have Ms. Kirti, Assistant Professor (CSE) as our mentorwho has
assisted us for the commencement of the project. The success of this project is a result of sheer
hard work and determination put in by us with the help of our mentor.
We are extremely grateful and indebted to all our teachers, our parents and our siblings for being
pillars of strength, for their unfailing moral and encouragement. We treasure their blessings and
good wishes and dedicated this study to them.
iv
ABSTRACT
This project presents an overview of what a Restaurant Portfolio Website and how it works.
This Project is made in HTML, CSS and Javascript language with the help of React.
In this project we have created a Restaurant Portfolio Website with implementing HTML, CSS and
Javascript.The Project “Restaurant Portfolio Website” is a web application that lets us to know
the information related to the dishes. This app will be helpful to find our famous dishes and customers
can directly contact with us by given address and also we providing location on map. People can also
give their feedback, which item they like the most.
In this project, we have used the “Mr. Tandoor” API to show the list of the dishes. On the home
page, we have a menu section in which all the dishes came from the backend i.e. Mr. Tandoor
website through Mr. Tandoor API. It also contains top rated dishes, unique and popular dishes for
the customers.
v
TABLE OF CONTENT
Chapter 1 Introduction
Introduction ....................................................................................................... 7
Chapter 2 Tools & Techniques
HTML............................................................................................................... 9
CSS (Cascading Style Sheets) ........................................................................ 10
JavaScript ....................................................................................................... 11
React.js ........................................................................................................... 12
Chapter 5 Coding
Coding ............................................................................................................. 18
Chapter 6 Conclusions
Conclusion.......................................................................................................42
Chapter 7 References
References .....................................................................................................43
6
Chapter 1
Project Introduction
Summary
Restaurant Portfolio website is a famous restaurant webpage for
foods items. In this web application user can view the featured
foods, chef and details about the food with single page application
and, the clear navigation that will enable users to quickly get the
food and review details.
Features
• Featured dish, promotion and leaders display in homepage.
• Nice UI interaction between the pages like on data request loading
the spinner and ease in/out for view pages.
• Comment review in action.
• Rating slider for users.
• User friendly error reporting.
• Storing the feedback details web services
7
Chapter 2
Tools & Techniques
There are several tools and platforms (wordpress, magento etc..) available that can be used to
develop the front end of a website, and understanding which tools are best fit for specific tasks
marks the difference between developing a hacked site and a well designed, scalable site.
• HTML
• CSS
• JavaScript
• React.js
8
HTML
9
Cascading Style Sheets (CSS)
• Cascading Style Sheets (CSS) controls the presentation aspect of the site and
allows your site to have its own unique look.
• It does this by maintaining style sheets which sit on top of other style rules and
are triggered based on other inputs, such as device screen size and resolution.
10
JavaScript
11
React.js
• React React (also known as React.js or ReactJS) is a JavaScript library for building user
interfaces.
• It is maintained by Facebook and a community of individual developers and companies.
• React can be used as a base in the development of single-page or mobile applications, as it is
optimal for fetching rapidly changing data that needs to be recorded.
• However, fetching data is only the beginning of what happens on a web page, which is why
complex React applications usually require the use of additional libraries for state
management, routing, and interaction with an API: Redux, React Router and axios are
examples of such libraries.
12
Chapter 3
Design and Implementation
Giving the UI design diagram below for a better understanding of the flow.
App component consist of Header , Main and footer component. Main component
content will load based on the router. This is basically separation of concerns and gives
more clarity and modularity for the design.
13
These are the list of libraries/ modules used in
the project.
“dependencies”:{
"bootstrap": "^4.0.0", —> for
UI styling "bootstrap-social":
"^5.1.1",
"prop-types": "^15.6.0",
"react": "^16.11.0", —> React
support "react-animation-
components": "^3.0.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0", —> Intercepting the
dispatch
},
14
Chapter 4
Project Screenshot
15
16
PROJECT STRUCTURE FRONTEND PART
17
Chapter 5
Coding
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/f
undamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build
.
Only files inside the `public` folder can be referenced from the HTML.
18
AboutComponent.js
function About(props) {
let leaders = <div></div>
if (props.leaders.isLoading) {
leaders = <Loading />;
}
else if (props.leaders.errMess) {
leaders = <h4>{props.leaders.errMess}</h4>;
}
else if(props.leaders) {
leaders = props.leaders.leaders.map((leader) => {
return (
<Fade in key={leader.id}>
<RenderLeader key={leader.id} leader={leader} />
</Fade>
);
});
}
19
</Media>
</Media>
);
}
return(
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/home">Home</Link></BreadcrumbIt
em>
<BreadcrumbItem active>About Us</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>About Us</h3>
<hr />
</div>
</div>
<div className="row row-content">
<div className="col-12 col-md-6">
<h2>Our History</h2>
<p>Started in 2010, Ristorante con Fusion quickly establis
hed itself as a culinary icon par excellence in Hong Kong. With its unique bra
nd of world fusion cuisine that can be found nowhere else, it enjoys patronage
from the A-list clientele in Hong Kong. Featuring four of the best three-
star Michelin chefs in the world, you never know what will arrive on your plat
e the next time you visit us.</p>
<p>The restaurant traces its humble beginnings to <em>The
Frying Pan</em>, a successful chain started by our CEO, Mr. Peter Pan, that fe
atured for the first time the world's best cuisines in a pan.</p>
</div>
<div className="col-12 col-md-5">
<Card>
<CardHeader className="bg-primary text-
white">Facts At a Glance</CardHeader>
<CardBody>
<dl className="row p-1">
<dt className="col-6">Started</dt>
<dd className="col-6">3 Feb. 2013</dd>
<dt className="col-6">Major Stake Holder</dt>
<dd className="col-6">HK Fine Foods Inc.</dd>
<dt className="col-
6">Last Year's Turnover</dt>
<dd className="col-6">$1,250,375</dd>
<dt className="col-6">Employees</dt>
<dd className="col-6">40</dd>
</dl>
</CardBody>
20
</Card>
</div>
<div className="col-12">
<Card>
<CardBody className="bg-faded">
<blockquote className="blockquote">
<p className="mb-
0">You better cut the pizza in four pieces because
I'm not hungry enough to eat six.</p>
<footer className="blockquote-
footer">Yogi Berra,
<cite title="Source Title">The Wit and Wisdom
of Yogi Berra,
P. Pepe, Diversion Books, 2014</cite>
</footer>
</blockquote>
</CardBody>
</Card>
</div>
</div>
<div className="row row-content">
<div className="col-12">
<h2>Corporate Leadership</h2>
</div>
<div className="col-12">
<Media list>
<Stagger in>
{leaders}
</Stagger>
</Media>
</div>
</div>
</div>
);
21
CommentForm.js
constructor(props) {
super(props);
this.state = {
isModalOpen: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.toggleModal = this.toggleModal.bind(this);
}
handleSubmit(values) {
this.toggleModal();
this.props.postComment(this.props.dishId, values.rating, values.yourna
me, values.comment)
}
toggleModal() {
this.setState({
isModalOpen: !this.state.isModalOpen
});
}
render() {
return(
<>
<Button type="button" className="fa fa-
pencil" outline color="secondary" size="lg"
onClick={this.toggleModal}>
<span className="ml-1">Submit Comment</span>
</Button>
<Modal isOpen={this.state.isModalOpen} toggle={this.toggleModa
l}>
<ModalHeader toggle={this.toggleModal}>Submit Comment</ModalHe
ader>
22
<ModalBody>
<LocalForm className="container" onSubmit={(values) => this.ha
ndleSubmit(values)}>
<Row className="form-group">
<Label htmlFor="rating">Rating</Label>
<Control.select model=".rating" id="rating" name="rati
ng"
className="form-control" defaultValue="1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="3">4</option>
<option value="3">5</option>
</Control.select>
</Row>
<Row className="form-group">
<Label htmlFor="yourname">Your Name</Label>
<Control.text type="text" model=".yourname" id="yourna
me" name="yourname"
className="form-control"
validators={{
required, minLength: minLength(2), maxLength: maxL
ength(15)
}} />
<Errors
className="text-danger"
model=".yourname"
show="touched"
messages={{
required: 'Required',
minLength: 'Must be greater than 2 characters'
,
maxLength: 'Must be 15 characters or less'
}} />
</Row>
<Row className="form-group">
<Label htmlFor="comment">Comment</Label>
<Control.textarea model=".comment" type="text" id="com
ment" name="comment"
rows="6" className="form-control"/>
</Row>
<Button type="submit" value="submit" color="primary">Submi
t</Button>
</LocalForm>
</ModalBody>
</Modal>
</>
);
23
}
}
ContactComponent.js
import React, { Component } from 'react';
import { Breadcrumb, BreadcrumbItem,
Button, Row, Label, Col } from 'reactstrap';
import { Link } from 'react-router-dom';
import { Control, Form, Errors } from 'react-redux-form';
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
async handleSubmit(values) {
const feedback = await this.props.postFeedback(values);
console.log('Current State is: ' + JSON.stringify(feedback));
alert('Current State is: ' + JSON.stringify(feedback));
this.props.resetFeedbackForm();
}
render() {
return(
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/home">Home</Link></Breadcru
mbItem>
<BreadcrumbItem active>Contact Us</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>Contact Us</h3>
24
<hr />
</div>
</div>
<div className="row row-content">
<div className="col-12">
<h3>Location Information</h3>
</div>
<div className="col-12 col-sm-4 offset-sm-1">
<h5>Our Address</h5>
<address>
121, Clear Water Bay Road<br />
Clear Water Bay, Kowloon<br />
HONG KONG<br />
<i className="fa fa-
phone"></i>: +852 1234 5678<br />
<i className="fa fa-
fax"></i>: +852 8765 4321<br />
<i className="fa fa-
envelope"></i>: <a href="mailto:confusion@food.net">confusion@food.net</a>
</address>
</div>
<div className="col-12 col-sm-6 offset-sm-1">
<h5>Map of our Location</h5>
</div>
<div className="col-12 col-sm-11 offset-sm-1">
<div className="btn-group" role="group">
<a role="button" className="btn btn-
primary" href="tel:+85212345678"><i className="fa fa-phone"></i> Call</a>
<a role="button" className="btn btn-
info"><i className="fa fa-skype"></i> Skype</a>
<a role="button" className="btn btn-
success" href="mailto:confusion@food.net"><i className="fa fa-envelope-
o"></i> Email</a>
</div>
</div>
</div>
<div className="row row-content">
<div className="col-12">
<h3>Send us your Feedback</h3>
</div>
<div className="col-12 col-md-9">
<Form model="feedback" onSubmit={(values) => this.hand
leSubmit(values)}>
<Row className="form-group">
<Label htmlFor="firstname" md={2}>First Name</
Label>
<Col md={10}>
<Control.text model=".firstname" id="firstname" name="firstname"
25
placeholder="First Name"
className="form-control"
validators={{
required, minLength: minLength(3), maxLength: maxLength(15)
}} />
<Errors
className="text-danger"
model=".firstname"
show="touched"
messages={{
required: 'Required',
minLength: 'Must be greater than 2 characters',
maxLength: 'Must be 15 characters or less'
}}
/>
</Col>
</Row>
<Row className="form-group">
<Label htmlFor="lastname" md={2}>Last Name</Label>
<Col md={10}>
<Control.text model=".lastname" type="text" id="lastname" name="lastname"
placeholder="Last Name"
className="form-control"
validators={{
required, minLength: minLength(3), maxLength: maxLength(15)
}}/>
<Errors
className="text-danger"
model=".lastname"
show="touched"
messages={{
required: 'Required',
minLength: 'Must be greater than 2 characters',
maxLength: 'Must be 15 characters or less'
}}
/>
</Col>
</Row>
<Row className="form-group">
<Label htmlFor="telnum" md={2}>Contact Tel.</Label>
<Col md={10}>
<Control.text model=".telnum" type="tel" id="telnum" name="telnum"
placeholder="Tel. number"
className="form-control"
validators={{
required, minLength: minLength(3), maxLength: maxLength(15), isNumber
}}/>
<Errors
26
className="text-danger"
model=".telnum"
show="touched"
messages={{
required: 'Required',
minLength: 'Must be greater than 2 numbers',
maxLength: 'Must be 15 numbers or less',
isNumber: 'Must be a number'
}}
/>
</Col>
</Row>
<Row className="form-group">
<Label htmlFor="email" md={2}>Email</Label>
<Col md={10}>
<Control.text model=".email" type="email" id="email" name="email"
placeholder="Email"
className="form-control"
validators={{
required, validEmail
}}
/>
<Errors
className="text-danger"
model=".email"
show="touched"
messages={{
required: 'Required',
validEmail: 'Invalid Email Address'
}}
/>
</Col>
</Row>
<Row className="form-group">
<Col md={{size: 6, offset: 2}}>
<div className="form-check">
<Label check>
<Control.checkbox model=".agree" type="checkbox"
name="agree"
className="form-check-input" /> {' '}
<strong>May we contact you?</strong>
</Label>
</div>
</Col>
<Col md={{size: 3, offset: 1}}>
<Control.select model=".contactType" type="select" name="contactType"
className="form-control">
<option>Tel.</option>
27
<option>Email</option>
</Control.select>
</Col>
</Row>
<Row className="form-group">
<Label htmlFor="message" md={2}>Your Feedback</Label>
<Col md={10}>
<Control.textarea model=".message" type="textarea" id="message" name="message"
rows="12"
className="form-control" />
</Col>
</Row>
<Row className="form-group">
<Col md={{size: 10, offset: 2}}>
<Button type="submit" color="primary">
Send Feedback
</Button>
</Col>
</Row>
</Form>
</div>
</div>
</div>
);
}
}
DishDetail.js
if (props.isLoading) {
return(
28
<div className="container">
<div className="row">
<Loading />
</div>
</div>
);
}
else if (props.errMess) {
return(
<div className="container">
<div className="row">
<h4>{props.errMess}</h4>
</div>
</div>
);
}
else if(props.dish != null)
return(
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/menu">Menu</Link></BreadcrumbItem>
<BreadcrumbItem active>{props.dish.name}</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>{props.dish.name}</h3>
<hr />
</div>
</div>
<div className="row">
<div className="col-12 col-md-5 m-1">
<RenderDish dish={props.dish}/>
</div>
<div className="col-12 col-md-5 m-1">
<h4>Comments</h4>
<RenderComments comments={props.comments}
postComment={props.postComment}
dishId={props.dish.id}/>
</div>
</div>
</div>
);
else
return(
<div></div>
);
29
}
function RenderDish({dish}) {
return (
<FadeTransform
in
transformProps={{
exitTransform: 'scale(0.5) translateY(-50%)'
}}>
<Card>
<CardImg top src={baseUrl + dish.image} alt={dish.name} />
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
</FadeTransform>)
}
return (
<ul className="list-unstyled mb-4">
<Stagger in>
{ comments.map( comment => {
const date = new Date(comment.date);
return (
<Fade in key={comment.id}>
<li key={comment.id}>
<p className="mb-3">{comment.comment}</p>
<p className="mb-3">-- {comment.author}, {date.toLocaleDateString('en-US', {
day: 'numeric', month: 'short', year: 'numeric'
})}
</p>
</li>
</Fade>
)
})
}
</Stagger>
<li><CommentForm dishId={dishId} postComment={postComment}/></li>
</ul>
)
}
else {
return (<div></div>)
}
30
}
FooterComponent.js
function Footer(props) {
return(
<div className="footer">
<div className="container">
<div className="row justify-content-center">
<div className="col-4 offset-1 col-sm-2">
<h5>Links</h5>
<ul className="list-unstyled">
<li><Link to='/home'>Home</Link></li>
<li><Link to='/aboutus'>About Us</Link></li>
<li><Link to='/menu'>Menu</Link></li>
<li><Link to='/contactus'>Contact Us</Link></li>
</ul>
</div>
<div className="col-7 col-sm-5">
<h5>Our Address</h5>
<address>
121, Clear Water Bay Road<br />
Clear Water Bay, Kowloon<br />
HONG KONG<br />
<i className="fa fa-phone fa-lg"></i>: +852 1234 5678<br />
<i className="fa fa-fax fa-lg"></i>: +852 8765 4321<br />
<i className="fa fa-envelope fa-lg"></i>: <a href="mailto:confusion@food.net">
confusion@food.net</a>
</address>
</div>
<div className="col-12 col-sm-4 align-self-center">
<div className="text-center">
<a className="btn btn-social-icon btn-
google" href="http://google.com/+"><i className="fa fa-google-plus"></i></a>
<a className="btn btn-social-icon btn-
facebook" href="http://www.facebook.com/profile.php?id="><i className="fa fa-
facebook"></i></a>
31
<a className="btn btn-social-icon btn-
linkedin" href="http://www.linkedin.com/in/"><i className="fa fa-
linkedin"></i></a>
<a className="btn btn-social-icon btn-
twitter" href="http://twitter.com/"><i className="fa fa-twitter"></i></a>
<a className="btn btn-social-icon btn-
google" href="http://youtube.com/"><i className="fa fa-youtube"></i></a>
<a className="btn btn-social-icon" href="mailto:"><i className="fa fa-
envelope-o"></i></a>
</div>
</div>
</div>
<div className="row justify-content-center">
<div className="col-auto">
<p>© Copyright 2018 Ristorante Con Fusion</p>
</div>
</div>
</div>
</div>
)
}
HeaderComponent.js
constructor(props) {
super(props);
this.toggleNav = this.toggleNav.bind(this);
this.state = {
isNavOpen: false,
isModalOpen: false
};
this.toggleModal = this.toggleModal.bind(this);
32
this.handleLogin = this.handleLogin.bind(this);
}
toggleNav() {
this.setState({
isNavOpen: !this.state.isNavOpen
});
}
toggleModal() {
this.setState({
isModalOpen: !this.state.isModalOpen
});
}
handleLogin(event) {
this.toggleModal();
alert("Username: " + this.username.value + " Password: " + this.password.value
+ " Remember: " + this.remember.checked);
event.preventDefault();
render() {
return(
<div>
<Navbar dark expand="md">
<div className="container">
<NavbarToggler onClick={this.toggleNav} />
<NavbarBrand className="mr-
auto" href="/"><img src='assets/images/logo.png' height="30" width="41" alt='R
istorante Con Fusion' /></NavbarBrand>
<Collapse isOpen={this.state.isNavOpen} navbar>
<Nav navbar>
<NavItem>
<NavLink className="nav-link" to='/home'><span className="fa fa-home fa-
lg"></span> Home</NavLink>
</NavItem>
<NavItem>
<NavLink className="nav-link" to='/aboutus'><span className="fa fa-info fa-
lg"></span> About Us</NavLink>
</NavItem>
<NavItem>
<NavLink className="nav-link" to='/menu'><span className="fa fa-list fa-
lg"></span> Menu</NavLink>
</NavItem>
<NavItem>
33
<NavLink className="nav-link" to='/contactus'><span className="fa fa-address-
card fa-lg"></span> Contact Us</NavLink>
</NavItem>
</Nav>
<Nav className="ml-auto" navbar>
<NavItem>
<Button outline onClick={this.toggleModal}><span className="fa fa-sign-in fa-
lg"></span> Login</Button>
</NavItem>
</Nav>
</Collapse>
</div>
</Navbar>
<Jumbotron>
<div className="container">
<div className="row row-header">
<div className="col-12 col-sm-6">
<h1>Ristorante con Fusion</h1>
<p>We take inspiration from the World's best cuisines, and create a unique fus
ion experience. Our lipsmacking creations will tickle your culinary senses!</p
>
</div>
</div>
</div>
</Jumbotron>
<Modal isOpen={this.state.isModalOpen} toggle={this.toggleModal}>
<ModalHeader toggle={this.toggleModal}>Login</ModalHeader>
<ModalBody>
<Form onSubmit={this.handleLogin}>
<FormGroup>
<Label htmlFor="username">Username</Label>
<Input type="text" id="username" name="username"
innerRef={(input) => this.username = input} />
</FormGroup>
<FormGroup>
<Label htmlFor="password">Password</Label>
<Input type="password" id="password" name="password"
innerRef={(input) => this.password = input} />
</FormGroup>
<FormGroup check>
<Label check>
<Input type="checkbox" name="remember"
innerRef={(input) => this.remember = input} />
Remember me
</Label>
</FormGroup>
<Button type="submit" value="submit" color="primary">Login</Button>
</Form>
34
</ModalBody>
</Modal>
</div>
);
}
}
HomeComponent.js
if (isLoading) {
return(
<Loading />
);
}
else if (errMess) {
return(
<h4>{errMess}</h4>
);
}
else
return(
<FadeTransform
in
transformProps={{
exitTransform: 'scale(0.5) translateY(-50%)'
}}>
<Card>
<CardImg src={baseUrl + item.image} alt={item.name} />
35
<CardBody>
<CardTitle>{item.name}</CardTitle>
{item.designation ? <CardSubtitle>{item.designation}</
CardSubtitle> : null }
<CardText>{item.description}</CardText>
</CardBody>
</Card>
</FadeTransform>
);
function Home(props) {
return(
<div className="container">
<div className="row align-items-start">
<div className="col-12 col-md m-1">
<RenderCard item={props.dish} isLoading={props.dishesLoading}
errMess={props.dishesErrMess} />
</div>
<div className="col-12 col-md m-1">
<RenderCard item={props.promotion} isLoading={props.promoLoadi
ng} errMess={props.promoErrMess} />
</div>
<div className="col-12 col-md m-1">
<RenderCard item={props.leader} isLoading={props.leadersLoadin
g} errMess={props.leadersErrMess} />
</div>
</div>
</div>
);
}
LoadingComponent.js
import React from 'react';
36
};
MainComponent.js
import React, { Component } from 'react';
import { Switch, Route, Redirect, withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { actions } from 'react-redux-form';
import Home from './HomeComponent';
import Menu from './MenuComponent';
import About from './AboutComponent';
import Header from './HeaderComponent';
import Footer from './FooterComponent';
import Contact from './ContactComponent';
import DishDetail from './DishdetailComponent';
import { postComment, postFeedback, fetchDishes, fetchComments, fetchPromos, f
etchLeaders } from '../redux/ActionCreators';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
constructor(props) {
super(props);
}
componentDidMount() {
37
this.props.fetchDishes();
this.props.fetchComments();
this.props.fetchPromos();
this.props.fetchLeaders();
}
onDishSelect(dishId) {
this.setState({ selectedDish: dishId});
}
render() {
const HomePage = () => {
return(
<Home
dish={this.props.dishes.dishes.filter((dish) => dish.featured)[0]}
dishesLoading={this.props.dishes.isLoading}
dishesErrMess={this.props.dishes.errMess}
promotion={this.props.promotions.promotions.filter((promo) => promo.
featured)[0]}
promoLoading={this.props.promotions.isLoading}
promoErrMess={this.props.promotions.errMess}
leader={this.props.leaders.leaders.filter((leader) => leader.feature
d)[0]}
leadersLoading={this.props.leaders.isLoading}
leadersErrMess={this.props.leaders.errMess}
/>
);
}
return (
<div>
<Header />
<TransitionGroup>
38
<CSSTransition key={this.props.location.key} classNames="page" tim
eout={300}>
<Switch>
<Route path='/home' component={HomePage} />
<Route exact path='/menu' component={() => <Menu dishes={thi
s.props.dishes} />} />
<Route path='/aboutus' component={() => <About leaders={this
.props.leaders} />} />
<Route exact path='/contactus' component={() => <Contact pos
tFeedback={this.props.postFeedback} resetFeedbackForm={this.props.resetFeedbac
kForm} />} />
<Route path='/menu/:dishId' component={DishWithId} />
<Redirect to="/home" />
</Switch>
</CSSTransition>
</TransitionGroup>
<Footer />
</div>
);
}
}
MenuComponent.js
import React from 'react';
import { Card, CardImg, CardImgOverlay,
CardTitle, Breadcrumb, BreadcrumbItem } from 'reactstrap';
import { Link } from 'react-router-dom';
import { Loading } from './LoadingComponent';
import { baseUrl } from '../shared/baseUrl';
39
const Menu = (props) => {
if (props.dishes.isLoading) {
return(
<div className="container">
<div className="row">
<Loading />
</div>
</div>
);
}
else if (props.dishes.errMess) {
return(
<div className="container">
<div className="row">
<div className="col-12">
<h4>{props.dishes.errMess}</h4>
</div>
</div>
</div>
);
}
else
return (
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/home">Home</Link></Brea
dcrumbItem>
<BreadcrumbItem active>Menu</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>Menu</h3>
<hr />
</div>
</div>
<div className="row">
{menu}
</div>
40
</div>
);
}
41
Chapter 6
Conclusions
42
Chapter 7
Bibliography & References
• React Router and the DOM
• Create React App
• React Official documentation.
43