You are on page 1of 43

Restaurant Portfolio Website

A Project Report
submitted in partial fulfillment of the requirementsfor the award of
the degree of

BACHELOR OF COMPUTER APPLICATION


(BCA)
By

ROBIN
19015041023

Under the guidance of

Ms. Kirti

Assistant Professor

(CSE)

Department of Computer Science and Engineering

IITM Group of Institutions, Murthal

(Affiliated to Deenbandhu Chotu Ram University of Science &Technology)

(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.

RAMANDEEP ROBIN SACHIN


(19015041020) (19015041023) (19015041024)

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.

Signature of Supervisor External Examiner


Ms. Kirti
(IITM Group of
Institutions, MURTHAL)

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.

This is the overall structure of project.

v
TABLE OF CONTENT

Candidate Declaration ...................................................................................................... ii


Certificate .......................................................................................................................... iii
Acknowledgement ............................................................................................................ iv
Abstract .............................................................................................................................. v
Table of Content ............................................................................................................... vi

Chapter 1 Introduction
Introduction ....................................................................................................... 7
Chapter 2 Tools & Techniques
HTML............................................................................................................... 9
CSS (Cascading Style Sheets) ........................................................................ 10
JavaScript ....................................................................................................... 11
React.js ........................................................................................................... 12

Chapter 3 Design and Implementation

Design and Implementation ............................................................................ 13

List of libraries/ modules ................................................................................ 14


Chapter 4 Screenshots
Project Screenshots ........................................................................................ 15
Project Structure Frontend Part ...................................................................... 17

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

• Hyper Text Markup Language (HTML) Hyper Text Markup Language


(HTML) is the backbone of any website development process, without
which a web page doesn't exist.
• Hypertext means that text has links, termed hyperlinks, embedded in it.
• When a user clicks on a word or a phrase that has a hyperlink, it will
bring another web-page.
• A markup language indicates text can be turned into images, tables,
links, and other representations.
• It is the HTML code that provides an overall framework of how the site
will look. HTML was developed by Tim Berners-Lee.
• The latest version of HTML is called HTML5 and was published on
October 28, 2014 by the W3 recommendation.
• This version contains new and efficient ways of handling elements such
as video and audio files.

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

• JavaScript is an event-based imperative programming language (as opposed to HTML's


declarative language model) that is used to transform a static HTML page into a dynamic
interface.
• JavaScript code can use the [Document Object Model] (DOM), provided by the HTML
standard, to manipulate a web page in response to events, like user input.
• Using a technique called AJAX, JavaScript code can also actively retrieve content from the
web (independent of the original HTML page retrieval).
• And also react to server-side events as well, adding a truly dynamic nature to the web page
experience.

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.

● For the actual code implementation, need a proper understanding of different


flows in the application and using that i have divided the application into different
components within a page itself. For example

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",

"cross-fetch": "^2.1.0", —> Server


Communication "font-awesome": "^4.7.0",

"prop-types": "^15.6.0",
"react": "^16.11.0", —> React
support "react-animation-
components": "^3.0.0",

"react-dom": "^16.11.0", —> Provides React


Virtual DOM "react-popper": "^0.9.2",

"react-redux": "^5.0.7", —> State


Management "react-redux-form": "^1.16.8",
—> Redux Form "react-router-dom": "^5.1.2",
—> For React Routing "react-scripts":
"3.2.0", —> For Bundling "reactstrap":
"^5.0.0", —> for UI styling "redux":
"^3.7.2", —> Redux Support

"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.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will


work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>ConFusion App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.


The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.


To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

18
AboutComponent.js

import React from 'react';


import { Breadcrumb, BreadcrumbItem, Card, CardBody, CardHeader, Media } from
'reactstrap';
import {Fade, Stagger } from 'react-animation-components';
import { Link } from 'react-router-dom';
import { Loading } from './LoadingComponent';
import { baseUrl } from '../shared/baseUrl';

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>
);
});
}

function RenderLeader ({leader}) {


return (
<Media className="mb-5">
<Media left className="mr-5 mt-5">
<Media object style={{maxHeight: 160,maxWidth: 150 }} src=
{baseUrl + leader.image} alt={leader.name} />
</Media>
<Media body>
<Media heading>
{leader.name}
</Media>
<div className="mb-3">{leader.designation}</div>
<div>{leader.description}</div>

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>
);

export default About;

21
CommentForm.js

import React, { Component } from 'react';


import {Modal, ModalHeader, ModalBody, Button, Row, Label} from 'reactstrap';
import { Control, LocalForm, Errors } from 'react-redux-form';

const required = (val) => val && val.length;


const maxLength = (len) => (val) => !(val) || (val.length <= len);
const minLength = (len) => (val) => val && (val.length > len);

class CommentForm extends Component {

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
}
}

export default CommentForm;

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';

const required = (val) => val && val.length;


const maxLength = (len) => (val) => !(val) || (val.length <= len);
const minLength = (len) => (val) => val && (val.length >= len);
const isNumber = (val) => !isNaN(Number(val));
const validEmail = (val) => /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-
Z]{2,4}$/i.test(val);

class Contact extends Component {

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>
);
}
}

export default Contact;

DishDetail.js

import React from 'react';


import { Card, CardImg, CardText, CardBody,
CardTitle, Breadcrumb, BreadcrumbItem } from 'reactstrap';
import { FadeTransform, Fade, Stagger } from 'react-animation-components';
import { Link } from 'react-router-dom';
import CommentForm from './CommentForm'
import { Loading } from './LoadingComponent';
import { baseUrl } from '../shared/baseUrl';

const DishDetail = (props) => {

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>)
}

function RenderComments({comments, postComment, dishId}) {


if(comments && comments.length > 0) {

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
}

export default DishDetail;

FooterComponent.js

import React from 'react';


import { Link } from 'react-router-dom';

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>
)
}

export default Footer;

HeaderComponent.js

import React, { Component } from 'react';


import { Nav, Navbar, NavbarBrand, NavbarToggler, Collapse, NavItem, Jumbotron
,
Button, Modal, ModalHeader, ModalBody,
Form, FormGroup, Input, Label } from 'reactstrap';
import { NavLink } from 'react-router-dom';

class Header extends Component {

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>
);
}
}

export default Header;

HomeComponent.js

import React from 'react';


import { Card, CardImg, CardText, CardBody,
CardTitle, CardSubtitle} from 'reactstrap';
import { FadeTransform } from 'react-animation-components';
import { Loading } from './LoadingComponent';
import { baseUrl } from '../shared/baseUrl';

function RenderCard({item, isLoading, errMess}) {

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>
);
}

export default Home;

LoadingComponent.js
import React from 'react';

export const Loading = () => {


return(
<div className="col-12">
<span className="fa fa-spinner fa-pulse fa-3x fa-fw text-
primary"></span>
<p>Loading . . .</p>
</div>
);

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';

const mapStateToProps = state => {


return {
dishes: state.dishes,
comments: state.comments,
promotions: state.promotions,
leaders: state.leaders
}
}

const mapDispatchToProps = dispatch => ({


postComment: (dishId, rating, author, comment) => dispatch(postComment(dishI
d, rating, author, comment)),
postFeedback: (values) => dispatch(postFeedback(values) ),
fetchDishes: () => { dispatch(fetchDishes())},
resetFeedbackForm: () => { dispatch(actions.reset('feedback'))},
fetchComments: () => dispatch(fetchComments()),
fetchPromos: () => dispatch(fetchPromos()),
fetchLeaders: () => dispatch(fetchLeaders())
});

class Main extends Component {

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}
/>
);
}

const DishWithId = ({match}) => {


return (
<DishDetail
dish={this.props.dishes.dishes.filter((dish) => +dish.id === parseIn
t(match.params.dishId,10))[0]}
isLoading={this.props.dishes.isLoading}
errMess={this.props.dishes.errMess}
comments={this.props.comments.comments.filter((comment) => +comment.
dishId === parseInt(match.params.dishId,10))}
commentsErrMess={this.props.comments.errMess}
postComment={this.props.postComment}
/>
);
};

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>
);
}
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Main)


);

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';

function RenderMenuItem ({dish, onClick}) {


return (
<Card>
<Link to={`/menu/${dish.id}`} >
<CardImg width="100%" src={baseUrl + dish.image} alt={dish
.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Link>
</Card>
);
}

39
const Menu = (props) => {

const menu = props.dishes.dishes.map((dish) => {


return (
<div className="col-12 col-md-5 m-1" key={dish.id}>
<RenderMenuItem dish={dish} />
</div>
);
});

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>
);
}

export default Menu;

41
Chapter 6
Conclusions

• This Restaurant App really helpful for the


users to access the dishes menu in the
restaurant and to access the details of the
dishes.
• In the future we will be adding a cart page and
a payment process flows so that all the users
can easily buy the items online.
• This app will support in all the devices and
doesn’t matter the size and with the good
animations.

42
Chapter 7
Bibliography & References
• React Router and the DOM
• Create React App
• React Official documentation.

Books and Internet Sites

• E. Balaguruswami, Programming with Java,


second edition, Tata McGraw Hill.
• Herbert Schildt, The Complete Reference Java
2, fifth edition, Tata McGraw Hill.
• https://www.javatpoint.com
• https://www.w3schools.com
• https://www.guru99.com
• https://www.udemy.com
• https://www.geeksforgeeks.org

43

You might also like