From f103de19564ae2701a94fdd3fd24b54c511349c4 Mon Sep 17 00:00:00 2001 From: hemanthkumar-syncfusion Date: Thu, 13 Mar 2025 23:19:58 +0530 Subject: [PATCH 1/2] 946605: Need to implement UI team suggested changes in hotel booking application --- Hotel-booking-App/.gitignore | 30 +- Hotel-booking-App/.npmignore | 9 + Hotel-booking-App/Jenkinsfile | 39 ++ Hotel-booking-App/README.md | 71 +--- Hotel-booking-App/config.json | 3 + Hotel-booking-App/favicon.ico | Bin 0 -> 6574 bytes Hotel-booking-App/gulpfile.js | 1 + .../{img => images}/hotel-app.gif | Bin Hotel-booking-App/index.html | 22 + Hotel-booking-App/license | 10 + Hotel-booking-App/package.json | 99 ++--- Hotel-booking-App/public/favicon.ico | Bin 3150 -> 0 bytes Hotel-booking-App/public/index.html | 17 - Hotel-booking-App/public/logo192.png | Bin 5347 -> 0 bytes Hotel-booking-App/public/logo512.png | Bin 9664 -> 0 bytes Hotel-booking-App/public/manifest.json | 25 -- Hotel-booking-App/public/robots.txt | 3 - Hotel-booking-App/src/common/index.tsx | 9 + .../HotelBook/HotelBook.css} | 107 ++++- .../HotelBook/HotelBook.tsx} | 393 ++++++++++-------- .../HotelBook/HotelData.ts} | 171 +++++--- .../src/{ => components/HotelBook}/usa.json | 0 Hotel-booking-App/src/index.css | 13 - Hotel-booking-App/src/index.js | 15 - Hotel-booking-App/src/logo.svg | 7 - Hotel-booking-App/src/sample-base.js | 15 - Hotel-booking-App/src/serviceWorker.js | 141 ------- Hotel-booking-App/src/setupTests.js | 5 - Hotel-booking-App/styles/index.css | 0 Hotel-booking-App/tsconfig.json | 10 + Hotel-booking-App/webpack.config.js | 61 +++ 31 files changed, 625 insertions(+), 651 deletions(-) create mode 100644 Hotel-booking-App/.npmignore create mode 100644 Hotel-booking-App/Jenkinsfile create mode 100644 Hotel-booking-App/config.json create mode 100644 Hotel-booking-App/favicon.ico create mode 100644 Hotel-booking-App/gulpfile.js rename Hotel-booking-App/{img => images}/hotel-app.gif (100%) create mode 100644 Hotel-booking-App/index.html create mode 100644 Hotel-booking-App/license delete mode 100644 Hotel-booking-App/public/favicon.ico delete mode 100644 Hotel-booking-App/public/index.html delete mode 100644 Hotel-booking-App/public/logo192.png delete mode 100644 Hotel-booking-App/public/logo512.png delete mode 100644 Hotel-booking-App/public/manifest.json delete mode 100644 Hotel-booking-App/public/robots.txt create mode 100644 Hotel-booking-App/src/common/index.tsx rename Hotel-booking-App/src/{HotelBookApp.css => components/HotelBook/HotelBook.css} (81%) rename Hotel-booking-App/src/{HotelBookApp.js => components/HotelBook/HotelBook.tsx} (74%) rename Hotel-booking-App/src/{DataCreation.js => components/HotelBook/HotelData.ts} (80%) rename Hotel-booking-App/src/{ => components/HotelBook}/usa.json (100%) delete mode 100644 Hotel-booking-App/src/index.css delete mode 100644 Hotel-booking-App/src/index.js delete mode 100644 Hotel-booking-App/src/logo.svg delete mode 100644 Hotel-booking-App/src/sample-base.js delete mode 100644 Hotel-booking-App/src/serviceWorker.js delete mode 100644 Hotel-booking-App/src/setupTests.js create mode 100644 Hotel-booking-App/styles/index.css create mode 100644 Hotel-booking-App/tsconfig.json create mode 100644 Hotel-booking-App/webpack.config.js diff --git a/Hotel-booking-App/.gitignore b/Hotel-booking-App/.gitignore index 4d29575..e08aebc 100644 --- a/Hotel-booking-App/.gitignore +++ b/Hotel-booking-App/.gitignore @@ -1,23 +1,7 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* +.npmrc +.vscode/ +node_modules/ +src/**/*.js +dist/ +styles/*.* +!styles/index.css \ No newline at end of file diff --git a/Hotel-booking-App/.npmignore b/Hotel-booking-App/.npmignore new file mode 100644 index 0000000..389afd2 --- /dev/null +++ b/Hotel-booking-App/.npmignore @@ -0,0 +1,9 @@ +.npmrc +.vscode/ +.npmignore +config.json +gulpfile.js +tsconfig.json +node-modules/ +Jenkinsfile +src/**/*.js \ No newline at end of file diff --git a/Hotel-booking-App/Jenkinsfile b/Hotel-booking-App/Jenkinsfile new file mode 100644 index 0000000..ac9c95a --- /dev/null +++ b/Hotel-booking-App/Jenkinsfile @@ -0,0 +1,39 @@ +#!groovy + +node('EJ2Angularlatest') { + try { + deleteDir() + + stage('Import') { + git url: 'http://github.com/essential-studio/ej2-groovy-scripts.git', branch: 'master', credentialsId: env.GithubCredentialID; + shared = load 'src/shared.groovy' + } + + stage('Checkout') { + checkout scm + shared.getProjectDetails() + shared.gitlabCommitStatus('running') + } + + stage('Install') { + sh 'npm install' + } + + stage('Build') { + sh 'gulp hide-license && npm run build && gulp finished' + } + + stage('Publish') { + shared.publish() + } + + shared.gitlabCommitStatus('success') + + deleteDir() + } + catch(Exception e) { + shared.throwError(e) + deleteDir() + error('Build Failed') + } +} \ No newline at end of file diff --git a/Hotel-booking-App/README.md b/Hotel-booking-App/README.md index f1f26a2..4ae1e2b 100644 --- a/Hotel-booking-App/README.md +++ b/Hotel-booking-App/README.md @@ -1,53 +1,26 @@ -# Hotel booking application using Syncfusion React Grid +# Hotel booking application using Syncfusion React DataGrid While looking for a secure and comfortable hotel stay that fits your budget, preferred amenities, desired location, and high user reviews, this article explores how Syncfusion React Grid can display a comprehensive list of hotels and their rooms, along with facilities, user reviews, and costs. Additionally, Syncfusion React Grid offers filtering options based on budget, amenities, location, and user reviews, making the booking process more efficient and user-friendly. -This demo will show you how to utilize the Syncfusion Data Grid to display the lists of hotels and it facility and cost and locations and user reviews. Also, how to provide the option to select the hostel based on available hotel rooms on the selected check and checkout date with budget-wise and facilities and user review. With our step-by-step guide, you'll be able to easily set up and configure the data grid to meet your specific needs. - - -![Hotelbooking App](img/hotel-app.gif) - -## Target Audience -- Accountants and Bookkeepers -- Construction Companies -- Property Management Companies -- Medical Practice -- Educational Institutions -- Event Management Companies -- Software Development Firms -- Transportation and Logistics Companies -- Manufacturing Companies -- Travel Agencies -- Insurance Agencies -- Real Estate Agencies -- Hospitality Businesses -- Fitness Centers and Gyms -- Consulting Firms -- Photography Studios - -## Prerequisites -- We have developed this app by using the [node.js 16.0](https://legacy.reactjs.org/blog/2017/09/26/react-v16.0.html). -- If you have not previously installed the React packages or if you have installed a version of node.js older than Node 16 on your machine, you can run the following command to install them. - ```sh - npm install -g create-react-app - - ``` -## Run the sample -To execute the following command in your command prompt. - ```sh -npm start - ``` -## Common errors - -| Error | Try to solution | -|----------|----------| -| Module not found: Can't resolve 'module' | This indicates that the required module is either not installed properly or is missing. Therefore, we recommend ensuring that all dependency modules are installed correctly by executing either the npm install or yarn install command after deleting the package.lock.json file. | -| npm ERR! ENOENT: no such file or directory | This error suggests that the specified directory or file is not available on your machine, or permission for execution was denied. To resolve this, ensure that the file exists and that proper permissions are enabled for accessing the file or directory. | -|npm ERR! Failed at the project-name@0.1.0 start script| This error occurred due to a problem with the start script defined in your package.json file. It's important to validate the start script and execute it correctly set up to run your application. Additionally, ensure that all dependencies are installed properly or not. | -|npm ERR! EADDRINUSE: Address already in use | This error indicates the port number already used. So, you can choose another port or stop the existing running application. | -|npm ERR! Invalid package.json| This error indicates any syntax issue occurred in your package.json. to ensure all the syntax properly. | - -## Reference of Syncfusion Grid -[Demo](https://ej2.syncfusion.com/react/demos/#/material3/grid/overview),
-[Documentation](https://ej2.syncfusion.com/react/documentation/grid/getting-started). +This demo will show you how to utilize the Syncfusion Data Grid to display the lists of hotels, facilities, costs, locations, and user reviews. Also, how to provide the option to select the hostel based on available hotel rooms on the selected check and checkout date with budget-wise and facilities and user review. With our step-by-step guide, you can easily set up and configure the data grid to meet your specific needs. +![Hotelbooking App](images/hotel-app.gif) + +* To install all dependent packages, use the below command. + +``` +npm install +``` +* If Angular CLI is not installed into your machine, please use the below command to install Angular CLI. + +``` +npm install -g @angular/cli@15.1.5 +``` + +### Run + +To run the sample, use the below command + +``` +ng serve +``` diff --git a/Hotel-booking-App/config.json b/Hotel-booking-App/config.json new file mode 100644 index 0000000..ce7ea71 --- /dev/null +++ b/Hotel-booking-App/config.json @@ -0,0 +1,3 @@ +{ + "productOwner": "Maithiliy Karthikeyan " +} diff --git a/Hotel-booking-App/favicon.ico b/Hotel-booking-App/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d8d5c152e7353a07c3e519c9e53ac9328e515fa8 GIT binary patch literal 6574 zcmeHLZ)jUp6o1J}(=>U>YhL@3w0TL>C8MsL+H`gkEVxdkmO9tb;jBuvbG9p5I^2g+ zoQ_RobEu4M#mx^QI7C|n@y`&)zU<3BbPQB*vVCzdnHEGebfLH<{!U+RdizYC2_~~j z1HasR&O7J+&b{}%bKiS{U=c*2x>`UR5q8-GVZ9(Mk>7TV@$vY-_rFZ=hz7$<%I*YLf(BcUQQv$12qd1n5&7W;6a-9p|6b zEhm49g@-KH`gmCjM%xIyj%eKs>3FcY z7n(o3J#i>co_LArxZI=s%9(%6R(@pPpgxCWiu%Ry6DQk0y}gm7yr6rAVRyV~hT>x~ zwUqzFqjN9j0FA-VgT-jp@-Yrp@Q=->eJHEXYL9=tkj!kdk!e*gDhmYScQgOFnb;OE~-vz&&w zQajg1Pn+N~)SZTV{K{q%o6~)<&}%H8s9lI*l^4D+KY9dvo5Ozg=*(Ki>YA>-a|SZ~p!SYpRMR literal 0 HcmV?d00001 diff --git a/Hotel-booking-App/gulpfile.js b/Hotel-booking-App/gulpfile.js new file mode 100644 index 0000000..d936c5d --- /dev/null +++ b/Hotel-booking-App/gulpfile.js @@ -0,0 +1 @@ +require('@syncfusion/ej2-showcase-helper'); \ No newline at end of file diff --git a/Hotel-booking-App/img/hotel-app.gif b/Hotel-booking-App/images/hotel-app.gif similarity index 100% rename from Hotel-booking-App/img/hotel-app.gif rename to Hotel-booking-App/images/hotel-app.gif diff --git a/Hotel-booking-App/index.html b/Hotel-booking-App/index.html new file mode 100644 index 0000000..6db6435 --- /dev/null +++ b/Hotel-booking-App/index.html @@ -0,0 +1,22 @@ + + + + + + + + + Essential JS 2 for React - Hotel room booking application + + + + + + + +
+ + + \ No newline at end of file diff --git a/Hotel-booking-App/license b/Hotel-booking-App/license new file mode 100644 index 0000000..4e57cc0 --- /dev/null +++ b/Hotel-booking-App/license @@ -0,0 +1,10 @@ +Essential JS 2 library is available under the Syncfusion Essential Studio program, and can be licensed either under the Syncfusion Community License Program or the Syncfusion commercial license. + +To be qualified for the Syncfusion Community License Program you must have a gross revenue of less than one (1) million U.S. dollars ($1,000,000.00 USD) per year and have less than five (5) developers in your organization, and agree to be bound by Syncfusion’s terms and conditions. + +Customers who do not qualify for the community license can contact sales@syncfusion.com for commercial licensing options. + +Under no circumstances can you use this product without (1) either a Community License or a commercial license and (2) without agreeing and abiding by Syncfusion’s license containing all terms and conditions. + +The Syncfusion license that contains the terms and conditions can be found at +https://www.syncfusion.com/content/downloads/syncfusion_license.pdf \ No newline at end of file diff --git a/Hotel-booking-App/package.json b/Hotel-booking-App/package.json index ca1a270..f96fe5f 100644 --- a/Hotel-booking-App/package.json +++ b/Hotel-booking-App/package.json @@ -1,15 +1,34 @@ { - "name": "react-app", - "version": "0.1.0", - "private": true, - "homepage": ".", + "name": "@syncfusion/ej2-react-hotel-room-reserve", + "version": "1.0.0", + "description": "Essential JS 2 - Hotel room booking application", + "author": "Syncfusion Inc.", + "license": "SEE LICENSE IN license", + "scripts": { + "start": "webpack-dev-server --open --mode development", + "build": "webpack --mode production", + "ci-publish": "gulp publish-sample" + }, + "devDependencies": { + "@types/node": "^20.4.1", + "@types/react": "^18.2.14", + "@types/react-dom": "^18.2.6", + "@types/react-router-dom": "^5.3.3", + "css-loader": "^6.8.1", + "html-webpack-plugin": "^5.5.3", + "mini-css-extract-plugin": "^2.7.6", + "terser-webpack-plugin": "^5.3.9", + "ts-loader": "^9.4.4", + "typescript": "^5.1.6", + "webpack": "^5.88.1", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1", + "copy-webpack-plugin": "^12.0.2" + }, "dependencies": { - "@babel/plugin-transform-runtime": "^7.23.4", - "@babel/preset-env": "^7.23.3", - "@babel/preset-react": "^7.23.3", - "@babel/preset-typescript": "^7.23.3", - "@headlessui/react": "^1.7.15", - "@heroicons/react": "^2.0.18", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.14.1", "@syncfusion/ej2-react-grids": "*", "@syncfusion/ej2-react-calendars": "*", "@syncfusion/ej2-react-buttons": "*", @@ -17,64 +36,6 @@ "@syncfusion/ej2-react-inputs": "*", "@syncfusion/ej2-react-dropdowns": "*", "@syncfusion/ej2-react-navigations": "*", - "@syncfusion/ej2-react-maps": "*", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.23", - "@types/numeral": "^2.0.2", - "@types/react": "^18.0.37", - "@types/react-dom": "^18.0.11", - "axios": "^1.4.0", - "babel-plugin-inline-react-svg": "^2.0.2", - "babel-plugin-transform-decorators": "^6.24.1", - "buffer": "^6.0.3", - "formik": "^2.4.2", - "moment": "^2.29.4", - "numeral": "^2.0.6", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-inject-env": "^2.1.0", - "react-number-format": "^5.3.1", - "react-router-dom": "^6.11.1", - "react-scripts": "5.0.1", - "typescript": "^4.9.5", - "web-vitals": "^2.1.4", - "yup": "^1.2.0" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", - "format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"", - "prepare": "husky install" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "devDependencies": { - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "autoprefixer": "^10.4.14", - "husky": "^8.0.3", - "postcss": "^8.4.22", - "prettier": "2.8.8", - "tailwindcss": "^3.3.1" + "@syncfusion/ej2-react-maps": "*" } } diff --git a/Hotel-booking-App/public/favicon.ico b/Hotel-booking-App/public/favicon.ico deleted file mode 100644 index bcd5dfd67cd0361b78123e95c2dd96031f27f743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3150 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 MDeX2GIKR{Qf5okjU;qFB diff --git a/Hotel-booking-App/public/index.html b/Hotel-booking-App/public/index.html deleted file mode 100644 index f471986..0000000 --- a/Hotel-booking-App/public/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - -
- - - \ No newline at end of file diff --git a/Hotel-booking-App/public/logo192.png b/Hotel-booking-App/public/logo192.png deleted file mode 100644 index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/Hotel-booking-App/public/manifest.json b/Hotel-booking-App/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/Hotel-booking-App/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/Hotel-booking-App/public/robots.txt b/Hotel-booking-App/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/Hotel-booking-App/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/Hotel-booking-App/src/common/index.tsx b/Hotel-booking-App/src/common/index.tsx new file mode 100644 index 0000000..e4b6bed --- /dev/null +++ b/Hotel-booking-App/src/common/index.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; +import { createRoot } from 'react-dom/client'; +import HotelBook from "../components/HotelBook/HotelBook"; +import "../../styles/index.css"; + +const root = createRoot(document.getElementById("content-area") as HTMLElement); +root.render( + +); diff --git a/Hotel-booking-App/src/HotelBookApp.css b/Hotel-booking-App/src/components/HotelBook/HotelBook.css similarity index 81% rename from Hotel-booking-App/src/HotelBookApp.css rename to Hotel-booking-App/src/components/HotelBook/HotelBook.css index bbc5cfe..a358d86 100644 --- a/Hotel-booking-App/src/HotelBookApp.css +++ b/Hotel-booking-App/src/components/HotelBook/HotelBook.css @@ -187,7 +187,7 @@ .e-semi-bold-header-text { font-weight: 700; color: #ec4899; - font-size: 24px; + font-size: 22px; font-family: "Josefin Sans", serif; } @@ -223,7 +223,7 @@ .e-rowtemplate-border-applier { box-shadow: none; - border: 1px solid #a5b4fc !important; + border-top: 1px solid #a5b4fc !important; } .e-room-not-available-cover { @@ -254,10 +254,6 @@ width: 17px; } -.e-grid .e-dialog-map { - max-height: none !important; -} - .e-info-container { padding: 5px; margin-top: 15px; @@ -296,6 +292,11 @@ .e-map-text-spacer { margin-left: 10px; + margin-top: 1px; +} + +.e-margin-top-10 { + margin-top: 10px; } .e-map-text-styler { @@ -382,7 +383,11 @@ } .e-book-details-button { - padding-right: 13px; + padding-right: 65px; +} + +.e-padding-right { + padding-right: 50px; } .emptyRecordTemplate { @@ -400,7 +405,7 @@ } .e-carousel-image-holder-height { - height: 280px; + height: 380px; } .e-back-button-carousel-container { @@ -443,7 +448,7 @@ .e-carouselcomponent-container, .e-carousel-img-container img { - height: 240px; + height: 340px; width: 520px; } @@ -454,6 +459,7 @@ .e-details-info-container { display: flex; + flex-direction: row-reverse; background-color: #ffffff; margin-top: 30px; } @@ -493,6 +499,15 @@ .e-print-info-separator { margin-top: 10px; + padding-bottom: 10px; + font-weight: 600; + color: #14b8a6; + font-family: "Josefin Sans", serif; + font-size: 20px; +} + +.e-print-info-separator.e-print-info-separator-margin-top { + margin-top: 20px; } .e-chip-list { @@ -512,18 +527,64 @@ color: #15803d !important; } -@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-calendars/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css'; -@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css'; -@import "../node_modules/@syncfusion/ej2-react-grids/styles/tailwind3.css"; -@import "../node_modules/@syncfusion/ej2-icons/styles/tailwind3.css"; -@import "../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css"; -@import '../node_modules/@syncfusion/ej2-notifications/styles/tailwind3.css'; +#hotelamenities, +#roomamenities { + border: 0px; +} + +.e-dialog.e-dialog-print-info .e-dlg-header { + text-align: center !important; + width: auto !important; +} + +.e-dialog .e-footer-content .e-btn { + margin-right: 10px; +} + +.e-dialog.e-dlg-modal.e-popup.e-popup-open.e-dialog-map { + max-width: 800px !important; + max-height: 530px !important; +} + +.e-dialog.e-dlg-modal.e-popup.e-popup-open.e-dialog-print-info { + max-width: 950px !important; + max-height: 500px !important; +} + +.e-dialog.e-dlg-modal.e-popup.e-popup-open.e-dialog-print-info .e-dlg-header-content { + padding-top: 16px; +} + +.e-dialog.e-dlg-modal.e-popup.e-popup-open.e-dialog-print-info .e-footer-content { + padding-bottom: 16px; +} + +.e-treeview .e-level-1>.e-text-content .e-list-text { + font-size: 16px; + font-weight: 600; +} + +.e-slidercomponent-container { + width: 95%; + margin-left: 6px; +} + +.e-upload { + width: 96%; +} + +@import '../../../node_modules/@syncfusion/ej2-base/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-calendars/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css'; +@import '../../../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css'; +@import "../../../node_modules/@syncfusion/ej2-react-grids/styles/tailwind3.css"; +@import "../../../node_modules/@syncfusion/ej2-icons/styles/tailwind3.css"; +@import "../../../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css"; +@import '../../../node_modules/@syncfusion/ej2-notifications/styles/tailwind3.css'; @media only screen and (max-width: 1120px) { @@ -634,7 +695,7 @@ .e-carouselcomponent-container, .e-carousel-img-container img { - height: 240px; + height: 340px; width: 420px; } } @@ -656,7 +717,7 @@ .e-carouselcomponent-container, .e-carousel-img-container img { - height: 240px; + height: 340px; width: 320px; } } \ No newline at end of file diff --git a/Hotel-booking-App/src/HotelBookApp.js b/Hotel-booking-App/src/components/HotelBook/HotelBook.tsx similarity index 74% rename from Hotel-booking-App/src/HotelBookApp.js rename to Hotel-booking-App/src/components/HotelBook/HotelBook.tsx index 79cadd6..ad9c920 100644 --- a/Hotel-booking-App/src/HotelBookApp.js +++ b/Hotel-booking-App/src/components/HotelBook/HotelBook.tsx @@ -4,72 +4,75 @@ import { ColumnsDirective, ColumnDirective, Inject, - Page, Print + Page, Print, + DataResult, + Column, + PrintEventArgs } from '@syncfusion/ej2-react-grids'; import { closest, isNullOrUndefined } from '@syncfusion/ej2-base'; -import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars'; +import { DateRangePickerComponent, RangeEventArgs, RenderDayCellEventArgs } from '@syncfusion/ej2-react-calendars'; import { ButtonComponent, ChipListComponent, ChipsDirective, ChipDirective } from '@syncfusion/ej2-react-buttons'; import { DialogComponent } from '@syncfusion/ej2-react-popups'; -import { NumericTextBoxComponent, TextBoxComponent, RatingComponent, SliderComponent, UploaderComponent, MaskedTextBoxComponent } from '@syncfusion/ej2-react-inputs'; +import { NumericTextBoxComponent, TextBoxComponent, RatingComponent, SliderComponent, UploaderComponent, MaskedTextBoxComponent, SliderChangeEventArgs, FormValidatorModel } from '@syncfusion/ej2-react-inputs'; import { FormValidator } from '@syncfusion/ej2-react-inputs'; -import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns'; -import { TreeViewComponent, CarouselComponent } from '@syncfusion/ej2-react-navigations'; +import { ChangeEventArgs, DropDownListComponent } from '@syncfusion/ej2-react-dropdowns'; +import { TreeViewComponent, CarouselComponent, SlideChangingEventArgs, FieldsSettingsModel } from '@syncfusion/ej2-react-navigations'; import { MapsComponent, LayersDirective, LayerDirective, MarkersDirective, MarkerDirective, Marker, MapsTooltip, DataLabel } from '@syncfusion/ej2-react-maps'; import * as USA from './usa.json'; import { DataManager, Query, Predicate } from '@syncfusion/ej2-data'; -import { data } from './DataCreation'; -import './HotelBookApp.css'; +import { CheckInOut, data, Hotel, Location } from './HotelData'; +import './HotelBook.css'; -function HotelBookApp() { +function HotelBook() { // Hotel grid which render the hotel list using grid component - let hotelGrid; - let filterDataPredicate; - const hotelData = React.useRef(data); - const [showHotels, setShowHotels] = React.useState(true); - const [hotelGridData, setHotelGridData] = React.useState([]); + let hotelGrid: GridComponent; + let filterDataPredicate: Predicate; + const hotelData: React.MutableRefObject = React.useRef(data); + const [showHotels, setShowHotels]: [boolean, React.Dispatch>] = React.useState(true); + const [hotelGridData, setHotelGridData]: [Hotel[], React.Dispatch>] = React.useState([]); // Menu ref property for opening and closing the menu when clicking menu button - let menu = React.useRef(null); + let menu: React.MutableRefObject = React.useRef(null); // Check in and check out information for rendering the hotel list according to user specified date - let checkInOutDate = React.useRef(null); - let defaultCheckInDate = new Date(); + let checkInOutDate: React.MutableRefObject = React.useRef(null); + let defaultCheckInDate: Date = new Date(); defaultCheckInDate = new Date( defaultCheckInDate.getFullYear(), defaultCheckInDate.getMonth(), defaultCheckInDate.getDate() ); - const defaultCheckOutDate = new Date(defaultCheckInDate); + const defaultCheckOutDate: Date = new Date(defaultCheckInDate); defaultCheckOutDate.setDate(defaultCheckInDate.getDate() + 2); - const checkInDate = React.useRef(defaultCheckInDate); - const checkOutDate = React.useRef(defaultCheckOutDate); + const checkInDate: React.MutableRefObject = React.useRef(defaultCheckInDate); + const checkOutDate: React.MutableRefObject = React.useRef(defaultCheckOutDate); // Price range information for rendering the hotel list according to user expecting price - let priceRange = React.useRef(null); - let minPriceText = React.useRef(null); - let maxPriceText = React.useRef(null); - const defaultMinPrice = 50; - const defaultMaxPrice = 1000; + let priceRange: React.MutableRefObject = React.useRef(null); + let minPriceText: React.MutableRefObject = React.useRef(null); + let maxPriceText: React.MutableRefObject = React.useRef(null); + const defaultMinPrice: number = 50; + const defaultMaxPrice: number = 1000; // Map information for hotel location - let map = React.useRef(null); - const [showMapDialog, setShowMapDialog] = React.useState(false); - const [mapDataSource, setMapDataSource] = React.useState([]); + let map: React.MutableRefObject = React.useRef(null); + const [showMapDialog, setShowMapDialog]: [boolean, React.Dispatch>] = React.useState(false); + const [mapDataSource, setMapDataSource]: [Location[], React.Dispatch>] = React.useState([]); // Sorting the hotels according to user specific choice - let sortOptionContainer = React.useRef(null); - const sortOption = [ + let sortOptionContainer: React.MutableRefObject = React.useRef(null); + const sortOption: KeyData[] = [ { key: 1, value: 'Top rating' }, { key: 2, value: 'Price (low to high)' }, { key: 3, value: 'Price (high to low)' }, ]; - let sortOptionValue = React.useRef(1); + let sortOptionValue: React.MutableRefObject = React.useRef(1); // Hotel amenities infromation for rendering the hotel list according to user requirement that present in the hotel - let hotelAmenities = React.useRef(null); - let hotelAmenitiesData = [ + let hotelAmenities: React.MutableRefObject = React.useRef(null); + let hotelAmenitiesData: KeyData[] = [ { id: 1001, name: 'Amenities', hasChild: true, expanded: true, fieldValue: 'HotelFacility' }, { id: 1002, pid: 1001, name: 'Parking' }, { id: 1003, pid: 1001, name: 'Pet allowed' }, @@ -77,11 +80,11 @@ function HotelBookApp() { { id: 1005, pid: 1001, name: 'Restaurant' }, { id: 1006, pid: 1001, name: 'Spa' }, ]; - const hotelAmenitiesField = { dataSource: hotelAmenitiesData, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' }; + const hotelAmenitiesField: FieldsSettingsModel = { dataSource: hotelAmenitiesData, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' }; // Room amenities infromation for rendering the hotel list according to user requirement that present in the room - let roomAmenities = React.useRef(null); - let roomAmenitiesData = [ + let roomAmenities: React.MutableRefObject = React.useRef(null); + let roomAmenitiesData: KeyData[] = [ { id: 2001, name: 'Room Amenities', hasChild: true, expanded: true, fieldValue: 'RoomFacility' }, { id: 2002, pid: 2001, name: 'Television' }, { id: 2003, pid: 2001, name: 'Projector' }, @@ -92,39 +95,39 @@ function HotelBookApp() { { id: 2008, pid: 2001, name: 'Shower' }, ]; - const roomAmenitiesField = { dataSource: roomAmenitiesData, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' }; + const roomAmenitiesField: FieldsSettingsModel = { dataSource: roomAmenitiesData, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' }; // Hotel images for user booking room - let backgroundBlurImage = React.useRef(null); - const [hotelImages, setHotelImages] = React.useState([]); + let backgroundBlurImage: React.MutableRefObject = React.useRef(null); + const [hotelImages, setHotelImages]: [Record[], React.Dispatch[]>>] = React.useState([]); // Obtaining user information via input field with validator while booking room in hotel - const [selectedRoom, setSelectedRoom] = React.useState({}); - let formValidator = React.useRef(null); - let firstName = React.useRef(null); - let lastName = React.useRef(null); - let email = React.useRef(null); - let phno = React.useRef(null); - let address = React.useRef(null); - let city = React.useRef(null); - let code = React.useRef(null); - let country = React.useRef(null); - let person = React.useRef(null); - let extraBed = React.useRef(null); + const [selectedRoom, setSelectedRoom]: [Hotel, React.Dispatch>] = React.useState({} as Hotel); + let formValidator: React.MutableRefObject = React.useRef(null); + let firstName: React.MutableRefObject = React.useRef(null); + let lastName: React.MutableRefObject = React.useRef(null); + let email: React.MutableRefObject = React.useRef(null); + let phno: React.MutableRefObject = React.useRef(null); + let address: React.MutableRefObject = React.useRef(null); + let city: React.MutableRefObject = React.useRef(null); + let code: React.MutableRefObject = React.useRef(null); + let country: React.MutableRefObject = React.useRef(null); + let person: React.MutableRefObject = React.useRef(null); + let extraBed: React.MutableRefObject = React.useRef(null); let lineThroughPriceText = React.useRef(null); let taxedPriceText = React.useRef(null); let priceStatementText = React.useRef(null); - let priceCollectionData = React.useRef({}); + let priceCollectionData: React.MutableRefObject = React.useRef({} as PriceDetails); // Printing the booked room infromation - let printInfo = React.useRef({}); - let personalInfoGrid = React.useRef(null); - let hotelInfoGrid = React.useRef(null); - const [showPrintInfo, setShowPrintInfo] = React.useState(false); + let printInfo: React.MutableRefObject = React.useRef({} as BookingDetails); + let personalInfoGrid: React.MutableRefObject = React.useRef(null); + let hotelInfoGrid: React.MutableRefObject = React.useRef(null); + const [showPrintInfo, setShowPrintInfo]: [boolean, React.Dispatch>] = React.useState(false); // This method calls for checking the selected sorting option for generating hotel list - const checkSortOptions = (query) => { - const value = sortOptionContainer.current.value; + const checkSortOptions = (query: Query): void => { + const value: number = sortOptionContainer.current.value as number; switch (value) { case 1: query.sortBy('Rating', 'descending'); @@ -139,22 +142,22 @@ function HotelBookApp() { } // This method calls for checking the selected hotel and room amenities options for generating hotel list - const checkAmenities = (ref) => { - const checkedNodes = ref.checkedNodes; + const checkAmenities = (ref: TreeViewComponent): void => { + const checkedNodes: string[] = ref.checkedNodes; for (let i = 0; i < checkedNodes.length; i++) { - const childInfo = ref.treeData.find((data) => { + const childInfo: KeyData = (ref.fields.dataSource as { [key: string]: Object; }[]).find((data) => { return data.id.toString() === checkedNodes[i] && data.pid; }); if (childInfo) { - const parentInfo = ref.treeData.find(data => data.id === childInfo.pid); - filterDataPredicate = filterDataPredicate.and(parentInfo.fieldValue, 'contains', childInfo.name); + const parentInfo: KeyData = (ref.fields.dataSource as { [key: string]: Object; }[]).find(data => data.id === childInfo.pid); + filterDataPredicate = filterDataPredicate.and(parentInfo.fieldValue as string, 'contains', childInfo.name as string); } } } // This method calls for checking both user expecting price and amenities for generating hotel list - const checkPriceRangeAndAmenities = (query) => { - const value = priceRange.current.value; + const checkPriceRangeAndAmenities = (query: Query): void => { + const value: number[] = priceRange.current.value as number[]; filterDataPredicate = new Predicate('Price', 'greaterthanorequal', value[0]); filterDataPredicate = filterDataPredicate.and('Price', 'lessthanorequal', value[1]); checkAmenities(hotelAmenities.current); @@ -163,32 +166,32 @@ function HotelBookApp() { } // This method will generate and assign data for hotel grid - const generateHotelData = () => { + const generateHotelData = (): void => { // Generating query here - let query = new Query(); + let query: Query = new Query(); checkPriceRangeAndAmenities(query); checkSortOptions(query); // Generating data according to query new DataManager(hotelData.current).executeQuery(query).then((e) => { // Assigning data to hotel grid - setHotelGridData(e.result); + setHotelGridData((e as unknown as DataResult).result as Hotel[]); }); } // This method calls for generating hotel list when hotel grid is created - const hotelGridCreated = () => { + const hotelGridCreated = (): void => { generateHotelData(); } // This method calls for generating hotel list when sort options is changed - const sortOptionsChange = (args) => { - sortOptionValue.current = args.value; + const sortOptionsChange = (args: ChangeEventArgs): void => { + sortOptionValue.current = args.value as number; generateHotelData(); } // This method calls for generating hotel list when check in and check out date is changed - const checkInOutDateChange = (args) => { + const checkInOutDateChange = (args: RangeEventArgs): void => { if (args.startDate && args.endDate) { checkInDate.current = args.startDate; checkOutDate.current = args.endDate; @@ -197,23 +200,24 @@ function HotelBookApp() { } // This method calls for generating hotel list when price range is changed - const priceRangeChanged = (args) => { - minPriceText.current.innerText = args.value[0]; - maxPriceText.current.innerText = args.value[1]; + const priceRangeChanged = (args: SliderChangeEventArgs): void => { + const value: number[] = args.value as number[]; + minPriceText.current.innerText = value[0].toString(); + maxPriceText.current.innerText = value[1].toString(); generateHotelData(); } // This method calls for generating hotel list when amenities is changed - const amenitiesNodeChecked = (args) => { + const amenitiesNodeChecked = (): void => { generateHotelData(); } // This method calls for showing hotel location in map - const showMap = (args) => { - const rowIndex = closest(args.target, 'tr').rowIndex; - const rowObject = hotelGrid.currentViewData[rowIndex]; + const showMap = (args: React.MouseEvent): void => { + const rowIndex: number = (closest(args.target as Element, 'tr') as HTMLTableRowElement).rowIndex; + const rowObject: Hotel = hotelGrid.currentViewData[rowIndex] as Hotel; setMapDataSource([rowObject.Location]); - const mapInst = map.current; + const mapInst: MapsComponent = map.current; setTimeout(() => { mapInst.refresh(); }, 10); @@ -221,18 +225,18 @@ function HotelBookApp() { } // This method calls for closing the map - const closeMap = () => { + const closeMap = (): void => { setShowMapDialog(false); } // This method calls for validating the input field in a custom way - const customValidation = (args) => { - const argsLength = args.element.ej2_instances[0].value.length; + const customValidation = (args: { [key: string]: string }): boolean => { + const argsLength: number = ((args.element as unknown as { ej2_instances: object[]; }).ej2_instances[0] as MaskedTextBoxComponent).value.length; return argsLength >= 10; }; // This method calls for validating the first and last name input field in a custom way - const nameValidation = (args) => { + const nameValidation = (args: { [key: string]: string }): boolean => { // Regex to allow only letters and spaces if (/^[A-Za-z\s]*$/.test(args.value)) { return true; @@ -241,14 +245,14 @@ function HotelBookApp() { }; // This method calls for validating the proof input field in a custom way - const proofValidation = (args) => { - return args.element.ej2_instances[0].filesData.length ? true : false; + const proofValidation = (args: { [key: string]: string }): boolean => { + return ((args.element as unknown as { ej2_instances: object[]; }).ej2_instances[0] as UploaderComponent).filesData.length ? true : false; }; // This method calls for rendering the room price with discount and tax - const renderRoomPrice = (selectedRoom) => { - const price = selectedRoom.Price + (extraBed.current.value * selectedRoom.ExtraBedCost); - const priceCollection = calculatePrice(price, selectedRoom.DiscountPercentage, selectedRoom.TaxPercentage); + const renderRoomPrice = (selectedRoom: Hotel): void => { + const price: number = selectedRoom.Price + (extraBed.current.value * selectedRoom.ExtraBedCost); + const priceCollection: PriceDetails = calculatePrice(price, selectedRoom.DiscountPercentage, selectedRoom.TaxPercentage); priceCollectionData.current = priceCollection; lineThroughPriceText.current.innerText = '$' + price.toFixed(2); taxedPriceText.current.innerText = '$' + priceCollection.TaxedPrice; @@ -256,9 +260,9 @@ function HotelBookApp() { } // This method calls for navigate the user to booking page and rendering the input field with form validator - const goToRoomBookingPage = (args) => { - const rowIndex = closest(args.target, 'tr').rowIndex; - const rowObject = hotelGrid.currentViewData[rowIndex]; + const goToRoomBookingPage = (args: React.MouseEvent): void => { + const rowIndex: number = (closest(args.target as Element, 'tr') as HTMLTableRowElement).rowIndex; + const rowObject: Hotel = hotelGrid.currentViewData[rowIndex] as Hotel; setSelectedRoom(rowObject); setHotelImages([ { ID: 1, Name: rowObject.HotelImgID, imageName: rowObject.HotelImgID }, @@ -266,7 +270,7 @@ function HotelBookApp() { ]); setShowHotels(false); setTimeout(() => { - const options = { + const options: FormValidatorModel = { rules: { firstname: { required: [nameValidation, '* Please enter your first name (only letters accept)'], @@ -309,24 +313,24 @@ function HotelBookApp() { } // This method calls for revisting the hotel list page - const backToHotels = () => { + const backToHotels = (): void => { checkInDate.current = defaultCheckInDate; checkOutDate.current = defaultCheckOutDate; setShowHotels(true); } - const getDate = (date) => { + const getDate = (date: Date): Date => { return new Date(date.getFullYear(), date.getMonth(), date.getDate()); } // This method calls for checking the room whether it is available or not for the user choosed check in and check out date - const checkRoomAvailable = (checkInOut) => { - let isRoomAvailable = true; - const startDate = getDate(checkInDate.current); - const endDate = getDate(checkOutDate.current); + const checkRoomAvailable = (checkInOut: CheckInOut[]): boolean => { + let isRoomAvailable: boolean = true; + const startDate: Date = getDate(checkInDate.current); + const endDate: Date = getDate(checkOutDate.current); for (let i = 0; i < checkInOut.length; i++) { - const checkIn = getDate(checkInOut[i].CheckIn); - const checkOut = getDate(checkInOut[i].CheckOut); + const checkIn: Date = getDate(checkInOut[i].CheckIn); + const checkOut: Date = getDate(checkInOut[i].CheckOut); if ((checkIn <= startDate && startDate <= checkOut) || (checkIn <= endDate && endDate <= checkOut)) { isRoomAvailable = false; break; @@ -336,26 +340,25 @@ function HotelBookApp() { } // This method calculate and return the price with discount and tax - const calculatePrice = (price, discount, tax) => { - const discountAmount = price * (discount * 0.01); - const discountedPrice = price - discountAmount; - const taxAmount = discountedPrice * (tax * 0.01); - const taxedPrice = discountedPrice + taxAmount; + const calculatePrice = (price: number, discount: number, tax: number): PriceDetails => { + const discountAmount: number = price * (discount * 0.01); + const discountedPrice: number = price - discountAmount; + const taxAmount: number = discountedPrice * (tax * 0.01); + const taxedPrice: number = discountedPrice + taxAmount; return { OriginalCost: price.toFixed(2), DiscountAmount: discountAmount.toFixed(2), DiscountedPrice: discountedPrice.toFixed(2), TaxAmount: taxAmount.toFixed(2), TaxedPrice: taxedPrice.toFixed(2) }; } // This method calls for rendering hotel grid row in a custom way using rowTemplate feature - const renderHotelGridRow = (props) => { - const src = '/images/' + props.RoomImgID + '.jpg'; - const hotelFacilityList = props.HotelFacility.split(', '); - const roomFacilityList = props.RoomFacility.split(', '); - const extrasList = props.Extras.split(', '); - const isRoomAvailable = checkRoomAvailable(props.CheckInOut); - const priceCollection = calculatePrice(props.Price, props.DiscountPercentage, props.TaxPercentage); + const renderHotelGridRow = (props: Hotel): React.JSX.Element => { + const src: string = './images/' + props.RoomImgID + '.jpg'; + const hotelFacilityList: string[] = props.HotelFacility.split(', '); + const roomFacilityList: string[] = props.RoomFacility.split(', '); + const extrasList: string[] = props.Extras.split(', '); + const isRoomAvailable: boolean = checkRoomAvailable(props.CheckInOut); + const priceCollection: PriceDetails = calculatePrice(props.Price, props.DiscountPercentage, props.TaxPercentage); return ( - {!isRoomAvailable &&
}
{props.RoomImgID} @@ -367,16 +370,16 @@ function HotelBookApp() {
{props.HotelName}
-
- {props.Address} - Map +
+ Map + {props.Address}
Rating:
-
+
@@ -453,7 +456,7 @@ function HotelBookApp() {
-
+
{!isRoomAvailable ? "Room's not available" : "Book Room"}
@@ -463,10 +466,10 @@ function HotelBookApp() { }; // This method calls for rendering the empty record template in the hotel grid when there is no hotel is available according to user specification - const renderHotelGridEmptyRecordRow = () => { + const renderHotelGridEmptyRecordRow = (): React.JSX.Element => { return (
- No record + No record
There is no hotel available to display at the moment.
@@ -475,22 +478,22 @@ function HotelBookApp() { } // This method calls for rendering the hotel grid header in custom way using headerTemplate feature - const renderHotelGridHeader = (args) => { + const renderHotelGridHeader = (args: Column): React.JSX.Element => { return (
{args.headerText}
- sortOptionContainer.current = dd} width={160} dataSource={sortOption} fields={{ text: 'value', value: 'key' }} value={sortOptionValue.current} change={sortOptionsChange} /> + sortOptionContainer.current = dd} width={160} dataSource={sortOption} fields={{ text: 'value', value: 'key' }} value={sortOptionValue.current} change={sortOptionsChange} />
); } // Memoized the hotel grid to prevent unnecessary rerenders - const memoizedHotelGrid = React.useMemo(() => { + const memoizedHotelGrid: React.JSX.Element = React.useMemo((): React.JSX.Element => { return ( hotelGrid = g} + ref={(g: GridComponent) => hotelGrid = g} dataSource={hotelGridData} height={'100%'} allowPaging={true} @@ -499,22 +502,22 @@ function HotelBookApp() { emptyRecordTemplate={renderHotelGridEmptyRecordRow} > - + ); }, [hotelGridData]); - const renderDayCell = (args) => { + const renderDayCell = (args: RenderDayCellEventArgs): void => { if (!isNullOrUndefined(args.isOutOfRange) && !args.isOutOfRange) { - const bookedDate = []; - hotelGridData.map((data) => { - data.CheckInOut.map((date) => { + const bookedDate: CheckInOut[] = []; + hotelGridData.map((data: Hotel) => { + data.CheckInOut.map((date: CheckInOut) => { bookedDate.push(date); }); }); - const roomBooked = bookedDate.find(({ CheckIn, CheckOut }) => { + const roomBooked = bookedDate.find(({ CheckIn, CheckOut }: CheckInOut) => { CheckIn.setHours(0, 0, 0, 0); CheckOut.setHours(0, 0, 0, 0); if (args.date >= CheckIn && args.date <= CheckOut) { @@ -531,32 +534,32 @@ function HotelBookApp() { } // Memoized the check in, check out data picker to prevent unnecessary rerenders - const memoizedCheckInOutDate = React.useMemo(() => { + const memoizedCheckInOutDate: React.JSX.Element = React.useMemo((): React.JSX.Element => { return ( - checkInOutDate.current = dr} min={defaultCheckInDate} startDate={defaultCheckInDate} endDate={defaultCheckOutDate} change={checkInOutDateChange} + checkInOutDate.current = dr} min={defaultCheckInDate} startDate={defaultCheckInDate} endDate={defaultCheckOutDate} change={checkInOutDateChange} renderDayCell={renderDayCell} /> ); }, [hotelGridData]); // This method calls for rendering the hotel images in a custom way in carousel using itemTemplate feature - const hotelImagesItemTemplate = (props) => { - return (
{props.imageName}
); + const hotelImagesItemTemplate = (props: Record): React.JSX.Element => { + return (
{props.imageName
); } // This method calls for rendering the room price when extra bed value change - const extraBedChange = (args) => { + const extraBedChange = (): void => { renderRoomPrice(selectedRoom); } - const getRandomNumber = (min, max) => { + const getRandomNumber = (min: number, max: number): number => { return Math.floor(Math.random() * (max - min + 1)) + min; } // The method calls for storing the user entered infromation for booking the room and display the receipt dialog to user - const bookRoom = (args) => { + const bookRoom = (): void => { if (formValidator.current.validate()) { - const dataIndex = hotelData.current.findIndex(data => data.HotelID === selectedRoom.HotelID && data.RoomID === selectedRoom.RoomID); + const dataIndex: number = hotelData.current.findIndex(data => data.HotelID === selectedRoom.HotelID && data.RoomID === selectedRoom.RoomID); hotelData.current[dataIndex].CheckInOut.push({ CheckIn: checkInDate.current, CheckOut: checkOutDate.current }); checkInDate.current = defaultCheckInDate; checkOutDate.current = defaultCheckOutDate; @@ -569,7 +572,7 @@ function HotelBookApp() { Address: address.current.value, City: city.current.value, Code: code.current.value, - Country: country.current.value, + Country: country.current.value as string, Person: person.current.value, ExtraBed: extraBed.current.value, HotelData: hotelData.current[dataIndex], @@ -585,7 +588,7 @@ function HotelBookApp() { } // This method calls for opening the menu - const menuClick = (args) => { + const menuClick = (): void => { menu.current.style.display = 'block'; setTimeout(() => { priceRange.current.refresh(); @@ -593,36 +596,36 @@ function HotelBookApp() { } // This method calls for closing the menu - const menuCloseClick = (args) => { + const menuCloseClick = (): void => { menu.current.style.display = 'none'; } // This method calls for closing the print information dialog - const closePrintInfo = (args) => { + const closePrintInfo = (): void => { setShowPrintInfo(false); } // This method calls for printing the receipt using print method of grid - const printInformation = (args) => { + const printInformation = (): void => { personalInfoGrid.current.print(); } // This method calls for printing the receipt in a custom way - const beforePrint = (args) => { + const beforePrint = (args: PrintEventArgs): void => { args.cancel = true; // formating the booked date - const bookedDate = printInfo.current.BookedDate; - const formattedDate = bookedDate.toLocaleDateString(); - const formattedTime = bookedDate.toLocaleTimeString([], { + const bookedDate: Date = printInfo.current.BookedDate; + const formattedDate: string = bookedDate.toLocaleDateString(); + const formattedTime: string = bookedDate.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", }); - const formattedDateTime = formattedDate + " " + formattedTime; + const formattedDateTime: string = formattedDate + " " + formattedTime; // Creating the print window - let printWindow = window.open( + let printWindow: Window = window.open( "", "_blank", "width=" + window.outerWidth + ",height=" + window.outerHeight @@ -788,9 +791,9 @@ function HotelBookApp() { } } - const onSlideChanging = (args) => { - backgroundBlurImage.current.src = "/images/" + hotelImages[args.nextIndex].imageName + ".jpg"; - backgroundBlurImage.current.alt = hotelImages[args.nextIndex].imageName; + const onSlideChanging = (args: SlideChangingEventArgs): void => { + backgroundBlurImage.current.src = "./images/" + hotelImages[args.nextIndex].imageName + ".jpg"; + backgroundBlurImage.current.alt = hotelImages[args.nextIndex].imageName as string; } return ( @@ -834,16 +837,17 @@ function HotelBookApp() { Price Range: $ minPriceText.current = e}>{defaultMinPrice} to $ maxPriceText.current = e}>{defaultMaxPrice}
- priceRange.current = p} type='Range' value={[defaultMinPrice, defaultMaxPrice]} min={defaultMinPrice} max={defaultMaxPrice} tooltip={{ placement: 'After', isVisible: true, showOn: 'Focus' }} changed={priceRangeChanged} /> + priceRange.current = p} type='Range' value={[defaultMinPrice, defaultMaxPrice]} min={defaultMinPrice} max={defaultMaxPrice} tooltip={{ placement: 'After', isVisible: true, format: 'C2' }} + ticks={{ placement: 'After', format: 'C2', largeStep: 400, smallStep: 100, showSmallTicks: true }} changed={priceRangeChanged} />
- hotelAmenities.current = a} fields={hotelAmenitiesField} showCheckBox={true} nodeChecked={amenitiesNodeChecked} /> + hotelAmenities.current = a} id="hotelamenities" fields={hotelAmenitiesField} showCheckBox={true} nodeChecked={amenitiesNodeChecked} />
- roomAmenities.current = r} fields={roomAmenitiesField} showCheckBox={true} nodeChecked={amenitiesNodeChecked} /> + roomAmenities.current = r} id="roomamenities" fields={roomAmenitiesField} showCheckBox={true} nodeChecked={amenitiesNodeChecked} />
@@ -852,7 +856,7 @@ function HotelBookApp() { {memoizedHotelGrid}
- map.current = m} background='#ffffff' mapsArea={{ background: '#ffffff' }}> + map.current = m} background='#ffffff' mapsArea={{ background: '#ffffff' }} height='100%'> @@ -880,7 +884,7 @@ function HotelBookApp() {
- backgroundBlurImage.current = e} className='e-background-blur-image' src={"./images/" + hotelImages[0].imageName + ".jpg"} alt={hotelImages[0].imageName} /> + backgroundBlurImage.current = e} className='e-background-blur-image' src={"./images/" + hotelImages[0].imageName + ".jpg"} alt={hotelImages[0].imageName as string} />
@@ -897,21 +901,21 @@ function HotelBookApp() {
Personal information
- firstName.current = f} width='75%' placeholder="First name *" name='firstname' floatLabelType="Always" type="text" data-msg-containerid="errorForFirstName" /> + firstName.current = f} width='95%' placeholder="First name *" name='firstname' floatLabelType="Always" type="text" data-msg-containerid="errorForFirstName" />
- lastName.current = l} width='75%' placeholder="Last name *" name='lastname' floatLabelType="Always" type="text" data-msg-containerid="errorForLastName" /> + lastName.current = l} width='95%' placeholder="Last name *" name='lastname' floatLabelType="Always" type="text" data-msg-containerid="errorForLastName" />
- email.current = e} width='75%' placeholder="Email *" name='email' floatLabelType="Always" type='email' data-msg-containerid="errorForEmail" /> + email.current = e} width='95%' placeholder="Email *" name='email' floatLabelType="Always" type='email' data-msg-containerid="errorForEmail" />
- phno.current = p} width='75%' mask="(999) 999-9999" placeholder="Phone number *" name='phno' floatLabelType='Always' /> + phno.current = p} width='95%' mask="(999) 999-9999" placeholder="Phone number *" name='phno' floatLabelType='Always' />
@@ -921,21 +925,21 @@ function HotelBookApp() {
Current address
- address.current = a} width='75%' placeholder="Address *" name='address' floatLabelType="Always" type="text" data-msg-containerid="errorForAddress" /> + address.current = a} width='95%' placeholder="Address *" name='address' floatLabelType="Always" type="text" data-msg-containerid="errorForAddress" />
- city.current = c} width='75%' placeholder="City *" name='city' floatLabelType="Always" type="text" data-msg-containerid="errorForCity" /> + city.current = c} width='95%' placeholder="City *" name='city' floatLabelType="Always" type="text" data-msg-containerid="errorForCity" />
- code.current = c} width='75%' placeholder="Zip/Post code *" name='code' floatLabelType="Always" type="number" data-msg-containerid="errorForCode" /> + code.current = c} width='95%' placeholder="Zip/Post code *" name='code' floatLabelType="Always" type="number" data-msg-containerid="errorForCode" />
- country.current = c} width='75%' placeholder='Country/Region *' name='country' floatLabelType="Always" dataSource={['USA']} value="USA" data-msg-containerid="errorForCountry" /> + country.current = c} width='95%' placeholder='Country/Region *' name='country' floatLabelType="Always" dataSource={['USA']} value="USA" data-msg-containerid="errorForCountry" />
@@ -957,10 +961,10 @@ function HotelBookApp() {
Room details
- person.current = c} width='75%' placeholder={'No of person (capacity: ' + selectedRoom.Capacity + ')'} floatLabelType='Always' value={1} min={1} max={selectedRoom.Capacity} /> + person.current = c} width='95%' placeholder={'No of person (capacity: ' + selectedRoom.Capacity + ')'} floatLabelType='Always' value={1} min={1} max={selectedRoom.Capacity} />
- extraBed.current = e} width='75%' placeholder={'No of extra bed (capacity: ' + selectedRoom.ExtraBed + ' and per bed cost: $' + selectedRoom.ExtraBedCost + ')'} floatLabelType='Always' value={0} min={0} max={selectedRoom.ExtraBed} change={extraBedChange} /> + extraBed.current = e} width='95%' placeholder={'No of extra bed (capacity: ' + selectedRoom.ExtraBed + ' and per bed cost: $' + selectedRoom.ExtraBedCost + ')'} floatLabelType='Always' value={0} min={0} max={selectedRoom.ExtraBed} change={extraBedChange} />
@@ -1013,15 +1017,18 @@ function HotelBookApp() {
}
- + { + return ( +
+
+ Print +
+ ) + }}>
{showPrintInfo &&
-
-
- Print -
-
Personal Information
- personalInfoGrid.current = g} +
Personal Information
+ personalInfoGrid.current = g} width={'100%'} dataSource={[printInfo.current]} allowTextWrap={true} @@ -1035,8 +1042,8 @@ function HotelBookApp() { -
Room Information
- hotelInfoGrid.current = g} width={'100%'} dataSource={[printInfo.current]} allowTextWrap={true} enableHover={false} allowSelection={false}> +
Room Information
+ hotelInfoGrid.current = g} width={'100%'} dataSource={[printInfo.current]} allowTextWrap={true} enableHover={false} allowSelection={false}> @@ -1054,4 +1061,36 @@ function HotelBookApp() {
); } -export default HotelBookApp; +export default HotelBook; + +interface PriceDetails { + OriginalCost: string; + DiscountAmount: string; + DiscountedPrice: string; + TaxAmount: string; + TaxedPrice: string; +} + +interface BookingDetails { + FirstName: string; + LastName: string; + Email: string; + Phno: string; + Address: string; + City: string; + Code: string; + Country: string; + Person: number; + ExtraBed: number; + HotelData: Hotel; + PriceCollection: PriceDetails; + FinalPrice: number; + ReceiptID: number; + BookedDate: Date; + CheckIn: Date; + CheckOut: Date; +} + +interface KeyData { + [key: string]: Object; +} diff --git a/Hotel-booking-App/src/DataCreation.js b/Hotel-booking-App/src/components/HotelBook/HotelData.ts similarity index 80% rename from Hotel-booking-App/src/DataCreation.js rename to Hotel-booking-App/src/components/HotelBook/HotelData.ts index c0699d9..592d7f6 100644 --- a/Hotel-booking-App/src/DataCreation.js +++ b/Hotel-booking-App/src/components/HotelBook/HotelData.ts @@ -1,35 +1,33 @@ -Object.defineProperty(exports, "__esModule", { value: true }); - -const startDate1 = new Date(); -const endDate1 = new Date(startDate1); +const startDate1: Date = new Date(); +const endDate1: Date = new Date(startDate1); endDate1.setDate(startDate1.getDate() + 2); -const startDate2 = new Date(endDate1); +const startDate2: Date = new Date(endDate1); startDate2.setDate(endDate1.getDate() + 1); -const endDate2 = new Date(startDate2); +const endDate2: Date = new Date(startDate2); endDate2.setDate(startDate2.getDate() + 2); -const startDate3 = new Date(endDate2); +const startDate3: Date = new Date(endDate2); startDate3.setDate(endDate2.getDate() + 5); -const endDate3 = new Date(startDate3); +const endDate3: Date = new Date(startDate3); endDate3.setDate(startDate3.getDate() + 5); -const startDate4 = new Date(endDate3); +const startDate4: Date = new Date(endDate3); startDate4.setDate(endDate3.getDate() + 5); -const endDate4 = new Date(startDate4); +const endDate4: Date = new Date(startDate4); endDate4.setDate(startDate4.getDate() + 5); -const startDate5 = new Date(endDate4); +const startDate5: Date = new Date(endDate4); startDate5.setDate(endDate4.getDate() + 2); -const endDate5 = new Date(startDate5); +const endDate5: Date = new Date(startDate5); endDate5.setDate(startDate5.getDate() + 2); -var hotelData = [ +const hotelData: Hotel[] = [ { HotelID: 102278, HotelName: 'Benor Hotel', Address: "59 rue de l'Abbaye", - Description: 'We are the king of the hotel in the vast beautiful world.', + Description: 'We are a top hotel, providing comfort and luxury. Our warm hospitality makes every stay special. Enjoy a memorable experience with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 20, @@ -52,7 +50,7 @@ var hotelData = [ HotelID: 102278, HotelName: 'Benor Hotel', Address: "59 rue de l'Abbaye", - Description: 'We are the king of the hotel in the vast beautiful world.', + Description: 'We are a top hotel, providing comfort and luxury. Our warm hospitality makes every stay special. Enjoy a memorable experience with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 20, @@ -75,7 +73,7 @@ var hotelData = [ HotelID: 102278, HotelName: 'Benor Hotel', Address: "59 rue de l'Abbaye", - Description: 'We are the king of the hotel in the vast beautiful world.', + Description: 'We are a top hotel, providing comfort and luxury. Our warm hospitality makes every stay special. Enjoy a memorable experience with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 20, @@ -98,7 +96,7 @@ var hotelData = [ HotelID: 117823, HotelName: 'Zabator Hotel', Address: "Luisenstr. 48", - Description: 'Pleasent hotel for pleasent people.', + Description: 'A pleasant hotel for pleasant people. We offer comfort, warmth, and great service. Stay with us for a relaxing experience.', HotelImgID: 'hotel_2', Rating: 4, ReviewCount: 30, @@ -121,7 +119,7 @@ var hotelData = [ HotelID: 117823, HotelName: 'Zabator Hotel', Address: "Luisenstr. 48", - Description: 'Pleasent hotel for pleasent people.', + Description: 'A pleasant hotel for pleasant people. We offer comfort, warmth, and great service. Stay with us for a relaxing experience.', HotelImgID: 'hotel_2', Rating: 4, ReviewCount: 30, @@ -144,7 +142,7 @@ var hotelData = [ HotelID: 117823, HotelName: 'Zabator Hotel', Address: "Luisenstr. 48", - Description: 'Pleasent hotel for pleasent people.', + Description: 'A pleasant hotel for pleasant people. We offer comfort, warmth, and great service. Stay with us for a relaxing experience.', HotelImgID: 'hotel_2', Rating: 4, ReviewCount: 30, @@ -167,7 +165,7 @@ var hotelData = [ HotelID: 322211, HotelName: 'Ben Swikator', Address: "Rua do Paço, 67", - Description: 'Want to explore wave silent see in marvelous hotel.', + Description: 'Want to explore the peaceful waves and a marvelous hotel? Experience serenity and luxury with us. Enjoy a stay like no other.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 18, @@ -190,7 +188,7 @@ var hotelData = [ HotelID: 322211, HotelName: 'Ben Swikator', Address: "Rua do Paço, 67", - Description: 'Want to explore wave silent see in marvelous hotel.', + Description: 'Want to explore the peaceful waves and a marvelous hotel? Experience serenity and luxury with us. Enjoy a stay like no other.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 18, @@ -213,7 +211,7 @@ var hotelData = [ HotelID: 322211, HotelName: 'Ben Swikator', Address: "Rua do Paço, 67", - Description: 'Want to explore wave silent see in marvelous hotel.', + Description: 'Want to explore the peaceful waves and a marvelous hotel? Experience serenity and luxury with us. Enjoy a stay like no other.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 18, @@ -236,7 +234,7 @@ var hotelData = [ HotelID: 112278, HotelName: 'Zentor Hotel', Address: "2, rue du Commerce", - Description: 'We are the queen of the hotel.', + Description: 'We are the queen of hospitality, offering elegance and comfort. Our hotel provides a royal experience for every guest. Stay with us and feel the luxury.', HotelImgID: 'hotel_4', Rating: 4, ReviewCount: 35, @@ -259,7 +257,7 @@ var hotelData = [ HotelID: 112278, HotelName: 'Zentor Hotel', Address: "2, rue du Commerce", - Description: 'We are the queen of the hotel.', + Description: 'We are the queen of hospitality, offering elegance and comfort. Our hotel provides a royal experience for every guest. Stay with us and feel the luxury.', HotelImgID: 'hotel_4', Rating: 4, ReviewCount: 35, @@ -282,7 +280,7 @@ var hotelData = [ HotelID: 112278, HotelName: 'Zentor Hotel', Address: "2, rue du Commerce", - Description: 'We are the queen of the hotel.', + Description: 'We are the queen of hospitality, offering elegance and comfort. Our hotel provides a royal experience for every guest. Stay with us and feel the luxury.', HotelImgID: 'hotel_4', Rating: 4, ReviewCount: 35, @@ -305,7 +303,7 @@ var hotelData = [ HotelID: 127823, HotelName: 'Bakator Hotel', Address: "Boulevard Tirou, 255", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_5', Rating: 2, ReviewCount: 15, @@ -328,7 +326,7 @@ var hotelData = [ HotelID: 127823, HotelName: 'Bakator Hotel', Address: "Boulevard Tirou, 255", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_5', Rating: 2, ReviewCount: 15, @@ -351,7 +349,7 @@ var hotelData = [ HotelID: 127823, HotelName: 'Bakator Hotel', Address: "Boulevard Tirou, 255", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_5', Rating: 2, ReviewCount: 15, @@ -374,7 +372,7 @@ var hotelData = [ HotelID: 332211, HotelName: 'Zen Swikator', Address: "Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_6', Rating: 5, ReviewCount: 22, @@ -397,7 +395,7 @@ var hotelData = [ HotelID: 332211, HotelName: 'Zen Swikator', Address: "Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_6', Rating: 5, ReviewCount: 22, @@ -420,7 +418,7 @@ var hotelData = [ HotelID: 332211, HotelName: 'Zen Swikator', Address: "Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_6', Rating: 5, ReviewCount: 22, @@ -443,7 +441,7 @@ var hotelData = [ HotelID: 342211, HotelName: 'Cen Zwikator', Address: "Hauptstr. 31", - Description: 'Want to explore a marvelous hotel.', + Description: 'Want to explore a marvelous hotel? Experience luxury, comfort, and exceptional service. Stay with us for an unforgettable journey.', HotelImgID: 'hotel_7', Rating: 5, ReviewCount: 25, @@ -466,7 +464,7 @@ var hotelData = [ HotelID: 342211, HotelName: 'Cen Zwikator', Address: "Hauptstr. 31", - Description: 'Want to explore a marvelous hotel.', + Description: 'Want to explore a marvelous hotel? Experience luxury, comfort, and exceptional service. Stay with us for an unforgettable journey.', HotelImgID: 'hotel_7', Rating: 5, ReviewCount: 25, @@ -489,7 +487,7 @@ var hotelData = [ HotelID: 342211, HotelName: 'Cen Zwikator', Address: "Hauptstr. 31", - Description: 'Want to explore a marvelous hotel.', + Description: 'Want to explore a marvelous hotel? Experience luxury, comfort, and exceptional service. Stay with us for an unforgettable journey.', HotelImgID: 'hotel_7', Rating: 5, ReviewCount: 25, @@ -512,7 +510,7 @@ var hotelData = [ HotelID: 132278, HotelName: 'Bekaor Hotel', Address: "68 rue de l'Abbaye", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_8', Rating: 3, ReviewCount: 30, @@ -535,7 +533,7 @@ var hotelData = [ HotelID: 132278, HotelName: 'Bekaor Hotel', Address: "68 rue de l'Abbaye", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_8', Rating: 3, ReviewCount: 30, @@ -558,7 +556,7 @@ var hotelData = [ HotelID: 132278, HotelName: 'Bekaor Hotel', Address: "68 rue de l'Abbaye", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_8', Rating: 3, ReviewCount: 30, @@ -581,7 +579,7 @@ var hotelData = [ HotelID: 137823, HotelName: 'Zanator Hotel', Address: "Luisenstr. 56", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_9', Rating: 5, ReviewCount: 50, @@ -604,7 +602,7 @@ var hotelData = [ HotelID: 137823, HotelName: 'Zanator Hotel', Address: "Luisenstr. 56", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_9', Rating: 5, ReviewCount: 50, @@ -627,7 +625,7 @@ var hotelData = [ HotelID: 137823, HotelName: 'Zanator Hotel', Address: "Luisenstr. 56", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_9', Rating: 5, ReviewCount: 50, @@ -650,7 +648,7 @@ var hotelData = [ HotelID: 343211, HotelName: 'Bentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_10', Rating: 2, ReviewCount: 50, @@ -673,7 +671,7 @@ var hotelData = [ HotelID: 343211, HotelName: 'Bentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_10', Rating: 2, ReviewCount: 50, @@ -696,7 +694,7 @@ var hotelData = [ HotelID: 343211, HotelName: 'Bentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_10', Rating: 2, ReviewCount: 50, @@ -719,7 +717,7 @@ var hotelData = [ HotelID: 142278, HotelName: 'ZZntor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_11', Rating: 4, ReviewCount: 35, @@ -742,7 +740,7 @@ var hotelData = [ HotelID: 142278, HotelName: 'ZZntor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_11', Rating: 4, ReviewCount: 35, @@ -765,7 +763,7 @@ var hotelData = [ HotelID: 142278, HotelName: 'ZZntor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_11', Rating: 4, ReviewCount: 35, @@ -788,7 +786,7 @@ var hotelData = [ HotelID: 129823, HotelName: 'Oakator Hotel', Address: "255, RU Boulevard Tirou", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 50, @@ -811,7 +809,7 @@ var hotelData = [ HotelID: 129823, HotelName: 'Oakator Hotel', Address: "255, RU Boulevard Tirou", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 50, @@ -834,7 +832,7 @@ var hotelData = [ HotelID: 129823, HotelName: 'Oakator Hotel', Address: "255, RU Boulevard Tirou", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_1', Rating: 5, ReviewCount: 50, @@ -857,7 +855,7 @@ var hotelData = [ HotelID: 332221, HotelName: 'ZenZen Swikator', Address: "66, Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_2', Rating: 3, ReviewCount: 22, @@ -880,7 +878,7 @@ var hotelData = [ HotelID: 332221, HotelName: 'ZenZen Swikator', Address: "66, Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_2', Rating: 3, ReviewCount: 22, @@ -903,7 +901,7 @@ var hotelData = [ HotelID: 332221, HotelName: 'ZenZen Swikator', Address: "66, Rua do Paço, GG", - Description: 'Want to explore stunning silent see in a marvelous hotel.', + Description: 'Want to explore a stunning, silent sea in a marvelous hotel? Experience tranquility and luxury with us. Enjoy a peaceful and unforgettable stay.', HotelImgID: 'hotel_2', Rating: 3, ReviewCount: 22, @@ -926,7 +924,7 @@ var hotelData = [ HotelID: 342311, HotelName: 'CenCake Owikator', Address: "Hauptstr. 31 Mt GG", - Description: 'Want to explore a marvelous hotel in marvelous Ocean.', + Description: 'Want to explore a marvelous hotel by the marvelous ocean? Experience luxury, tranquility, and breathtaking views. Enjoy an unforgettable stay with us.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 30, @@ -949,7 +947,7 @@ var hotelData = [ HotelID: 342311, HotelName: 'CenCake Owikator', Address: "Hauptstr. 31 Mt GG", - Description: 'Want to explore a marvelous hotel in marvelous Ocean.', + Description: 'Want to explore a marvelous hotel by the marvelous ocean? Experience luxury, tranquility, and breathtaking views. Enjoy an unforgettable stay with us.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 30, @@ -972,7 +970,7 @@ var hotelData = [ HotelID: 342311, HotelName: 'CenCake Owikator', Address: "Hauptstr. 31 Mt GG", - Description: 'Want to explore a marvelous hotel in marvelous Ocean.', + Description: 'Want to explore a marvelous hotel by the marvelous ocean? Experience luxury, tranquility, and breathtaking views. Enjoy an unforgettable stay with us.', HotelImgID: 'hotel_3', Rating: 3, ReviewCount: 30, @@ -995,7 +993,7 @@ var hotelData = [ HotelID: 192278, HotelName: 'Zekaorza Hotel', Address: "68 rue de l'Abbaye GG", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_4', Rating: 1, ReviewCount: 30, @@ -1018,7 +1016,7 @@ var hotelData = [ HotelID: 192278, HotelName: 'Zekaorza Hotel', Address: "68 rue de l'Abbaye GG", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_4', Rating: 1, ReviewCount: 30, @@ -1041,7 +1039,7 @@ var hotelData = [ HotelID: 192278, HotelName: 'Zekaorza Hotel', Address: "68 rue de l'Abbaye GG", - Description: 'We have different theme hotel.', + Description: 'We have a variety of themed hotels, each offering a unique experience. Enjoy a stay that matches your style and preferences. Discover comfort with a creative touch.', HotelImgID: 'hotel_4', Rating: 1, ReviewCount: 30, @@ -1064,7 +1062,7 @@ var hotelData = [ HotelID: 197823, HotelName: 'Zabatorza Hotel', Address: "Luisenstr. 56 GG", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_5', Rating: 3, ReviewCount: 10, @@ -1087,7 +1085,7 @@ var hotelData = [ HotelID: 197823, HotelName: 'Zabatorza Hotel', Address: "Luisenstr. 56 GG", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_5', Rating: 3, ReviewCount: 10, @@ -1110,7 +1108,7 @@ var hotelData = [ HotelID: 197823, HotelName: 'Zabatorza Hotel', Address: "Luisenstr. 56 GG", - Description: 'Pleasent hotel for polite people.', + Description: 'A pleasant hotel for polite people. We offer comfort, warmth, and excellent service. Enjoy a relaxing and memorable stay with us.', HotelImgID: 'hotel_5', Rating: 3, ReviewCount: 10, @@ -1133,7 +1131,7 @@ var hotelData = [ HotelID: 393211, HotelName: 'Saentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_6', Rating: 3, ReviewCount: 10, @@ -1156,7 +1154,7 @@ var hotelData = [ HotelID: 393211, HotelName: 'Saentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_6', Rating: 3, ReviewCount: 10, @@ -1179,7 +1177,7 @@ var hotelData = [ HotelID: 393211, HotelName: 'Saentoo Swikator', Address: "66,RuRua do Paço", - Description: 'Want to explore shift silent water wave in ocean.', + Description: 'Want to experience the gentle, shifting waves of the silent ocean? Embrace tranquility and beauty as you explore the serene waters. Let the oceans calmness refresh your soul.', HotelImgID: 'hotel_6', Rating: 3, ReviewCount: 10, @@ -1202,7 +1200,7 @@ var hotelData = [ HotelID: 199278, HotelName: 'Zoontor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_7', Rating: 1, ReviewCount: 35, @@ -1225,7 +1223,7 @@ var hotelData = [ HotelID: 199278, HotelName: 'Zoontor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_7', Rating: 1, ReviewCount: 35, @@ -1248,7 +1246,7 @@ var hotelData = [ HotelID: 199278, HotelName: 'Zoontor Hotel', Address: "333, rue du Commerce", - Description: 'We are the winner hotel.', + Description: 'We are an award-winning hotel, offering exceptional service and luxury. Experience the best in hospitality with us. Your perfect stay starts here.', HotelImgID: 'hotel_7', Rating: 1, ReviewCount: 35, @@ -1271,7 +1269,7 @@ var hotelData = [ HotelID: 199923, HotelName: 'Sasktor Hotel', Address: "255, RU Boulevard Tirou GG", - Description: 'Pleasent hotel for sweet people.', + Description: 'A pleasant hotel for sweet people. We offer warmth, comfort, and great service. Enjoy a delightful stay with us.', HotelImgID: 'hotel_8', Rating: 2, ReviewCount: 50, @@ -1293,4 +1291,39 @@ var hotelData = [ ]; -exports.data = hotelData; \ No newline at end of file +export const data: Hotel[] = hotelData; + +export interface Location { + latitude: number; + longitude: number; + TooltipContent: string; +} + +export interface CheckInOut { + CheckIn: Date; + CheckOut: Date; +} + +export interface Hotel { + HotelID: number; + HotelName: string; + Address: string; + Description: string; + HotelImgID: string; + Rating: number; + ReviewCount: number; + Location: Location; + HotelFacility: string; + RoomID: number; + RoomImgID: string; + RoomName: string; + Capacity: number; + ExtraBed: number; + ExtraBedCost: number; + DiscountPercentage: number; + TaxPercentage: number; + Extras: string; + RoomFacility: string; + Price: number; + CheckInOut: CheckInOut[]; +} \ No newline at end of file diff --git a/Hotel-booking-App/src/usa.json b/Hotel-booking-App/src/components/HotelBook/usa.json similarity index 100% rename from Hotel-booking-App/src/usa.json rename to Hotel-booking-App/src/components/HotelBook/usa.json diff --git a/Hotel-booking-App/src/index.css b/Hotel-booking-App/src/index.css deleted file mode 100644 index ec2585e..0000000 --- a/Hotel-booking-App/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/Hotel-booking-App/src/index.js b/Hotel-booking-App/src/index.js deleted file mode 100644 index efe9103..0000000 --- a/Hotel-booking-App/src/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import HotelBookApp from './HotelBookApp'; -import * as serviceWorker from './serviceWorker'; -import React, { StrictMode } from "react"; -import { createRoot } from "react-dom/client"; - -const rootElement = document.getElementById("App"); -const root = createRoot(rootElement); - -root.render( - - - -); - -serviceWorker.unregister(); diff --git a/Hotel-booking-App/src/logo.svg b/Hotel-booking-App/src/logo.svg deleted file mode 100644 index 6b60c10..0000000 --- a/Hotel-booking-App/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Hotel-booking-App/src/sample-base.js b/Hotel-booking-App/src/sample-base.js deleted file mode 100644 index 706ad12..0000000 --- a/Hotel-booking-App/src/sample-base.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - import { enableRipple } from '@syncfusion/ej2-base'; -enableRipple(true); - - export class SampleBase extends React.PureComponent { - rendereComplete() { - /**custom render complete function */ - } - componentDidMount() { - setTimeout(() => { - this.rendereComplete(); - }); - } - } - \ No newline at end of file diff --git a/Hotel-booking-App/src/serviceWorker.js b/Hotel-booking-App/src/serviceWorker.js deleted file mode 100644 index b04b771..0000000 --- a/Hotel-booking-App/src/serviceWorker.js +++ /dev/null @@ -1,141 +0,0 @@ -// This optional code is used to register a service worker. -// register() is not called by default. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on subsequent visits to a page, after all the -// existing tabs open on the page have been closed, since previously cached -// resources are updated in the background. - -// To learn more about the benefits of this model and instructions on how to -// opt-in, read https://bit.ly/CRA-PWA - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' - ); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - -function registerValidSW(swUrl, config) { - navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' - ); - - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl, config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl, { - headers: { 'Service-Worker': 'script' }, - }) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready - .then(registration => { - registration.unregister(); - }) - .catch(error => { - console.error(error.message); - }); - } -} diff --git a/Hotel-booking-App/src/setupTests.js b/Hotel-booking-App/src/setupTests.js deleted file mode 100644 index 74b1a27..0000000 --- a/Hotel-booking-App/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; diff --git a/Hotel-booking-App/styles/index.css b/Hotel-booking-App/styles/index.css new file mode 100644 index 0000000..e69de29 diff --git a/Hotel-booking-App/tsconfig.json b/Hotel-booking-App/tsconfig.json new file mode 100644 index 0000000..a60771d --- /dev/null +++ b/Hotel-booking-App/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "commonjs", + "target": "es5", + "jsx": "react", + "resolveJsonModule": true, + } +} \ No newline at end of file diff --git a/Hotel-booking-App/webpack.config.js b/Hotel-booking-App/webpack.config.js new file mode 100644 index 0000000..3310062 --- /dev/null +++ b/Hotel-booking-App/webpack.config.js @@ -0,0 +1,61 @@ +var glob = require("glob"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const TerserPlugin = require("terser-webpack-plugin"); +const CopyWebpackPlugin = require("copy-webpack-plugin"); +const path = require("path"); + +module.exports = { + entry: { + index: glob.sync("./src/**/**/*.tsx") + }, + target: "web", + module: { + rules: [ + { + test: /\.tsx$/, + exclude: /node_modules/, + use: "ts-loader", + }, + { + test: /\.css$/, + use: [ + MiniCssExtractPlugin.loader, + "css-loader" + ], + }, + { + test: /\.ts$/, + exclude: /node_modules/, + use: "ts-loader", + }, + ], + }, + plugins: [ + new HtmlWebpackPlugin({ + template: "index.html", + favicon: "favicon.ico" + }), + new MiniCssExtractPlugin({ + filename: "index.css", + }), + new CopyWebpackPlugin({ + patterns: [ + { from: "public/images", to: "images" }, + ], + }), + ], + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: "[name].js", + path: path.resolve(__dirname, "dist"), + }, + optimization: { + minimize: true, + minimizer: [new TerserPlugin({ + extractComments: false, + })], + }, +}; \ No newline at end of file From b0fd72b97778f150c67f5465e9788019c1a5718c Mon Sep 17 00:00:00 2001 From: hemanthkumar-syncfusion Date: Fri, 14 Mar 2025 10:26:36 +0530 Subject: [PATCH 2/2] 946605: Need to implement UI team suggested changes in hotel booking application --- Hotel-booking-App/.gitignore | 30 ++++++-- Hotel-booking-App/.npmignore | 9 --- Hotel-booking-App/Jenkinsfile | 39 ---------- Hotel-booking-App/README.md | 71 ++++++++++++------ Hotel-booking-App/config.json | 3 - .../{images => demo-img}/hotel-app.gif | Bin Hotel-booking-App/favicon.ico | Bin 6574 -> 0 bytes Hotel-booking-App/gulpfile.js | 1 - Hotel-booking-App/license | 10 --- Hotel-booking-App/webpack.config.js | 3 +- 10 files changed, 73 insertions(+), 93 deletions(-) delete mode 100644 Hotel-booking-App/.npmignore delete mode 100644 Hotel-booking-App/Jenkinsfile delete mode 100644 Hotel-booking-App/config.json rename Hotel-booking-App/{images => demo-img}/hotel-app.gif (100%) delete mode 100644 Hotel-booking-App/favicon.ico delete mode 100644 Hotel-booking-App/gulpfile.js delete mode 100644 Hotel-booking-App/license diff --git a/Hotel-booking-App/.gitignore b/Hotel-booking-App/.gitignore index e08aebc..4d29575 100644 --- a/Hotel-booking-App/.gitignore +++ b/Hotel-booking-App/.gitignore @@ -1,7 +1,23 @@ -.npmrc -.vscode/ -node_modules/ -src/**/*.js -dist/ -styles/*.* -!styles/index.css \ No newline at end of file +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/Hotel-booking-App/.npmignore b/Hotel-booking-App/.npmignore deleted file mode 100644 index 389afd2..0000000 --- a/Hotel-booking-App/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -.npmrc -.vscode/ -.npmignore -config.json -gulpfile.js -tsconfig.json -node-modules/ -Jenkinsfile -src/**/*.js \ No newline at end of file diff --git a/Hotel-booking-App/Jenkinsfile b/Hotel-booking-App/Jenkinsfile deleted file mode 100644 index ac9c95a..0000000 --- a/Hotel-booking-App/Jenkinsfile +++ /dev/null @@ -1,39 +0,0 @@ -#!groovy - -node('EJ2Angularlatest') { - try { - deleteDir() - - stage('Import') { - git url: 'http://github.com/essential-studio/ej2-groovy-scripts.git', branch: 'master', credentialsId: env.GithubCredentialID; - shared = load 'src/shared.groovy' - } - - stage('Checkout') { - checkout scm - shared.getProjectDetails() - shared.gitlabCommitStatus('running') - } - - stage('Install') { - sh 'npm install' - } - - stage('Build') { - sh 'gulp hide-license && npm run build && gulp finished' - } - - stage('Publish') { - shared.publish() - } - - shared.gitlabCommitStatus('success') - - deleteDir() - } - catch(Exception e) { - shared.throwError(e) - deleteDir() - error('Build Failed') - } -} \ No newline at end of file diff --git a/Hotel-booking-App/README.md b/Hotel-booking-App/README.md index 4ae1e2b..f1f26a2 100644 --- a/Hotel-booking-App/README.md +++ b/Hotel-booking-App/README.md @@ -1,26 +1,53 @@ -# Hotel booking application using Syncfusion React DataGrid +# Hotel booking application using Syncfusion React Grid While looking for a secure and comfortable hotel stay that fits your budget, preferred amenities, desired location, and high user reviews, this article explores how Syncfusion React Grid can display a comprehensive list of hotels and their rooms, along with facilities, user reviews, and costs. Additionally, Syncfusion React Grid offers filtering options based on budget, amenities, location, and user reviews, making the booking process more efficient and user-friendly. -This demo will show you how to utilize the Syncfusion Data Grid to display the lists of hotels, facilities, costs, locations, and user reviews. Also, how to provide the option to select the hostel based on available hotel rooms on the selected check and checkout date with budget-wise and facilities and user review. With our step-by-step guide, you can easily set up and configure the data grid to meet your specific needs. +This demo will show you how to utilize the Syncfusion Data Grid to display the lists of hotels and it facility and cost and locations and user reviews. Also, how to provide the option to select the hostel based on available hotel rooms on the selected check and checkout date with budget-wise and facilities and user review. With our step-by-step guide, you'll be able to easily set up and configure the data grid to meet your specific needs. + + +![Hotelbooking App](img/hotel-app.gif) + +## Target Audience +- Accountants and Bookkeepers +- Construction Companies +- Property Management Companies +- Medical Practice +- Educational Institutions +- Event Management Companies +- Software Development Firms +- Transportation and Logistics Companies +- Manufacturing Companies +- Travel Agencies +- Insurance Agencies +- Real Estate Agencies +- Hospitality Businesses +- Fitness Centers and Gyms +- Consulting Firms +- Photography Studios + +## Prerequisites +- We have developed this app by using the [node.js 16.0](https://legacy.reactjs.org/blog/2017/09/26/react-v16.0.html). +- If you have not previously installed the React packages or if you have installed a version of node.js older than Node 16 on your machine, you can run the following command to install them. + ```sh + npm install -g create-react-app + + ``` +## Run the sample +To execute the following command in your command prompt. + ```sh +npm start + ``` +## Common errors + +| Error | Try to solution | +|----------|----------| +| Module not found: Can't resolve 'module' | This indicates that the required module is either not installed properly or is missing. Therefore, we recommend ensuring that all dependency modules are installed correctly by executing either the npm install or yarn install command after deleting the package.lock.json file. | +| npm ERR! ENOENT: no such file or directory | This error suggests that the specified directory or file is not available on your machine, or permission for execution was denied. To resolve this, ensure that the file exists and that proper permissions are enabled for accessing the file or directory. | +|npm ERR! Failed at the project-name@0.1.0 start script| This error occurred due to a problem with the start script defined in your package.json file. It's important to validate the start script and execute it correctly set up to run your application. Additionally, ensure that all dependencies are installed properly or not. | +|npm ERR! EADDRINUSE: Address already in use | This error indicates the port number already used. So, you can choose another port or stop the existing running application. | +|npm ERR! Invalid package.json| This error indicates any syntax issue occurred in your package.json. to ensure all the syntax properly. | + +## Reference of Syncfusion Grid +[Demo](https://ej2.syncfusion.com/react/demos/#/material3/grid/overview),
+[Documentation](https://ej2.syncfusion.com/react/documentation/grid/getting-started). -![Hotelbooking App](images/hotel-app.gif) - -* To install all dependent packages, use the below command. - -``` -npm install -``` -* If Angular CLI is not installed into your machine, please use the below command to install Angular CLI. - -``` -npm install -g @angular/cli@15.1.5 -``` - -### Run - -To run the sample, use the below command - -``` -ng serve -``` diff --git a/Hotel-booking-App/config.json b/Hotel-booking-App/config.json deleted file mode 100644 index ce7ea71..0000000 --- a/Hotel-booking-App/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "productOwner": "Maithiliy Karthikeyan " -} diff --git a/Hotel-booking-App/images/hotel-app.gif b/Hotel-booking-App/demo-img/hotel-app.gif similarity index 100% rename from Hotel-booking-App/images/hotel-app.gif rename to Hotel-booking-App/demo-img/hotel-app.gif diff --git a/Hotel-booking-App/favicon.ico b/Hotel-booking-App/favicon.ico deleted file mode 100644 index d8d5c152e7353a07c3e519c9e53ac9328e515fa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6574 zcmeHLZ)jUp6o1J}(=>U>YhL@3w0TL>C8MsL+H`gkEVxdkmO9tb;jBuvbG9p5I^2g+ zoQ_RobEu4M#mx^QI7C|n@y`&)zU<3BbPQB*vVCzdnHEGebfLH<{!U+RdizYC2_~~j z1HasR&O7J+&b{}%bKiS{U=c*2x>`UR5q8-GVZ9(Mk>7TV@$vY-_rFZ=hz7$<%I*YLf(BcUQQv$12qd1n5&7W;6a-9p|6b zEhm49g@-KH`gmCjM%xIyj%eKs>3FcY z7n(o3J#i>co_LArxZI=s%9(%6R(@pPpgxCWiu%Ry6DQk0y}gm7yr6rAVRyV~hT>x~ zwUqzFqjN9j0FA-VgT-jp@-Yrp@Q=->eJHEXYL9=tkj!kdk!e*gDhmYScQgOFnb;OE~-vz&&w zQajg1Pn+N~)SZTV{K{q%o6~)<&}%H8s9lI*l^4D+KY9dvo5Ozg=*(Ki>YA>-a|SZ~p!SYpRMR diff --git a/Hotel-booking-App/gulpfile.js b/Hotel-booking-App/gulpfile.js deleted file mode 100644 index d936c5d..0000000 --- a/Hotel-booking-App/gulpfile.js +++ /dev/null @@ -1 +0,0 @@ -require('@syncfusion/ej2-showcase-helper'); \ No newline at end of file diff --git a/Hotel-booking-App/license b/Hotel-booking-App/license deleted file mode 100644 index 4e57cc0..0000000 --- a/Hotel-booking-App/license +++ /dev/null @@ -1,10 +0,0 @@ -Essential JS 2 library is available under the Syncfusion Essential Studio program, and can be licensed either under the Syncfusion Community License Program or the Syncfusion commercial license. - -To be qualified for the Syncfusion Community License Program you must have a gross revenue of less than one (1) million U.S. dollars ($1,000,000.00 USD) per year and have less than five (5) developers in your organization, and agree to be bound by Syncfusion’s terms and conditions. - -Customers who do not qualify for the community license can contact sales@syncfusion.com for commercial licensing options. - -Under no circumstances can you use this product without (1) either a Community License or a commercial license and (2) without agreeing and abiding by Syncfusion’s license containing all terms and conditions. - -The Syncfusion license that contains the terms and conditions can be found at -https://www.syncfusion.com/content/downloads/syncfusion_license.pdf \ No newline at end of file diff --git a/Hotel-booking-App/webpack.config.js b/Hotel-booking-App/webpack.config.js index 3310062..41d6c9a 100644 --- a/Hotel-booking-App/webpack.config.js +++ b/Hotel-booking-App/webpack.config.js @@ -33,8 +33,7 @@ module.exports = { }, plugins: [ new HtmlWebpackPlugin({ - template: "index.html", - favicon: "favicon.ico" + template: "index.html" }), new MiniCssExtractPlugin({ filename: "index.css",