Browse Source

feat: Added somewhat complete study page 2

master
Denis Thiessen 5 months ago
parent
commit
ff6a2481de
  1. 135
      package-lock.json
  2. 6
      package.json
  3. BIN
      public/images/lodgingluxe_logo.png
  4. 6
      public/index.html
  5. 16
      src/components/ScrollableTab.jsx
  6. 6
      src/index.css
  7. 68
      src/pages/study_site_2/StartPage2.jsx
  8. 1
      src/pages/study_site_2/TourOperators.jsx
  9. 16
      src/pages/study_site_2/tab_content/HotelCatering.jsx
  10. 20
      src/pages/study_site_2/tab_content/HotelFacilities.jsx
  11. 21
      src/pages/study_site_2/tab_content/HotelFeatures.jsx
  12. 14
      src/pages/study_site_2/tab_content/HotelFlights.jsx
  13. 18
      src/pages/study_site_2/tab_content/HotelInformation.jsx
  14. 45
      src/pages/study_site_2/tab_content/HotelLocation.jsx
  15. 33
      src/pages/study_site_2/tab_content/HotelMap.jsx
  16. 75
      src/pages/study_site_2/tab_content/HotelRatings.jsx
  17. 40
      src/pages/study_site_2/tab_content/HotelRooms.jsx

135
package-lock.json

@ -8,26 +8,37 @@
"name": "sonification-study-framework",
"version": "0.1.0",
"dependencies": {
"-": "^0.0.1",
"@geist-ui/core": "^2.3.8",
"@geist-ui/icons": "^1.0.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/leaflet": "^1.9.12",
"heatmap.js": "^2.0.5",
"i18next": "^23.11.3",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-http-backend": "^2.5.1",
"leaflet": "^1.9.4",
"leaflet-gesture-handling": "^1.2.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.1",
"react-leaflet": "^4.2.1",
"react-router-dom": "^6.23.0",
"react-scripts": "5.0.1",
"react-tabs-scrollable": "^2.0.6",
"save": "^2.9.0",
"tone": "^15.0.4",
"web-vitals": "^2.1.4",
"zustand": "^4.5.2"
}
},
"node_modules/-": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/-/-/--0.0.1.tgz",
"integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ=="
},
"node_modules/@adobe/css-tools": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz",
@ -3342,6 +3353,16 @@
}
}
},
"node_modules/@react-leaflet/core": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz",
"integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==",
"peerDependencies": {
"leaflet": "^1.9.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@remix-run/router": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
@ -4098,6 +4119,11 @@
"@types/send": "*"
}
},
"node_modules/@types/geojson": {
"version": "7946.0.14",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg=="
},
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@ -4391,6 +4417,14 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
},
"node_modules/@types/leaflet": {
"version": "1.9.12",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.12.tgz",
"integrity": "sha512-BK7XS+NyRI291HIo0HCfE18Lp8oA30H1gpi1tf0mF3TgiCEzanQjOqNZ4x126SXzzi2oNSZhZ5axJp1k0iM6jg==",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@ -8287,6 +8321,20 @@
"node": ">= 0.6"
}
},
"node_modules/event-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
"integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
"dependencies": {
"duplexer": "^0.1.1",
"from": "^0.1.7",
"map-stream": "0.0.7",
"pause-stream": "^0.0.11",
"split": "^1.0.1",
"stream-combiner": "^0.2.2",
"through": "^2.3.8"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -8868,6 +8916,11 @@
"node": ">= 0.6"
}
},
"node_modules/from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g=="
},
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@ -12487,6 +12540,16 @@
"shell-quote": "^1.8.1"
}
},
"node_modules/leaflet": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
},
"node_modules/leaflet-gesture-handling": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/leaflet-gesture-handling/-/leaflet-gesture-handling-1.2.2.tgz",
"integrity": "sha512-Blf5V4PoNphWkzL7Y1qge+Spkd4OCQ2atjwUNhMhLIcjKzPcBH++x/lwOinaR9jSqLWqJ6oKYO8d0XdTffy4hQ=="
},
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -12557,6 +12620,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
"integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@ -12655,6 +12723,11 @@
"tmpl": "1.0.5"
}
},
"node_modules/map-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
"integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ=="
},
"node_modules/mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@ -12763,6 +12836,11 @@
"node": ">=4"
}
},
"node_modules/mingo": {
"version": "6.4.15",
"resolved": "https://registry.npmjs.org/mingo/-/mingo-6.4.15.tgz",
"integrity": "sha512-fKUCGr7fUxrb7YBK6whm5O5VouXfKAVtxnb+6g3Xuwsj9Jt9u8hhMOgiUoKO4kp3DmuiN0qgpYX2H/nP3zD1Hw=="
},
"node_modules/mini-css-extract-plugin": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz",
@ -13466,6 +13544,14 @@
"node": ">=8"
}
},
"node_modules/pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
"dependencies": {
"through": "~2.3"
}
},
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@ -15252,6 +15338,19 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-leaflet": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz",
"integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==",
"dependencies": {
"@react-leaflet/core": "^2.1.0"
},
"peerDependencies": {
"leaflet": "^1.9.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@ -15901,6 +16000,17 @@
}
}
},
"node_modules/save": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/save/-/save-2.9.0.tgz",
"integrity": "sha512-eg8+g8CjvehE/2C6EbLdtK1pINVD27pcJLj4M9PjWWhoeha/y5bWf4dp/0RF+OzbKTcG1bae9qi3PAqiR8CJTg==",
"dependencies": {
"async": "^3.2.2",
"event-stream": "^4.0.1",
"lodash.assign": "^4.2.0",
"mingo": "^6.1.0"
}
},
"node_modules/sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
@ -16321,6 +16431,17 @@
"wbuf": "^1.7.3"
}
},
"node_modules/split": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"dependencies": {
"through": "2"
},
"engines": {
"node": "*"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -16478,6 +16599,15 @@
"node": ">= 0.4"
}
},
"node_modules/stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==",
"dependencies": {
"duplexer": "~0.1.1",
"through": "~2.3.4"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -17130,6 +17260,11 @@
"resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz",
"integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ=="
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"node_modules/thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",

6
package.json

@ -3,21 +3,27 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"-": "^0.0.1",
"@geist-ui/core": "^2.3.8",
"@geist-ui/icons": "^1.0.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/leaflet": "^1.9.12",
"heatmap.js": "^2.0.5",
"i18next": "^23.11.3",
"i18next-browser-languagedetector": "^7.2.1",
"i18next-http-backend": "^2.5.1",
"leaflet": "^1.9.4",
"leaflet-gesture-handling": "^1.2.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^14.1.1",
"react-leaflet": "^4.2.1",
"react-router-dom": "^6.23.0",
"react-scripts": "5.0.1",
"react-tabs-scrollable": "^2.0.6",
"save": "^2.9.0",
"tone": "^15.0.4",
"web-vitals": "^2.1.4",
"zustand": "^4.5.2"

BIN
public/images/lodgingluxe_logo.png

After

Width: 500  |  Height: 500  |  Size: 29 KiB

6
public/index.html

@ -25,6 +25,12 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""
/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

16
src/components/ScrollableTab.jsx

@ -1,18 +1,14 @@
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Tabs, Tab } from "react-tabs-scrollable";
import "react-tabs-scrollable/dist/rts.css";
import { Modal } from "@geist-ui/core";
import PopupModal from "./PopupModal";
var amountTabs = 0;
var reachedEndValue = false;
var rightSideEnd = true;
var endElement = amountTabs;
function ScrollableTab({ children }) {
const [activeTab, setActiveTab] = useState(1);
const [modalVisible, setModalVisible] = useState(false);
function ScrollableTab({ onActiveTabChange, children }) {
const [activeTab, setActiveTab] = useState(0);
// define a onClick function to bind the value on tab click
const onTabClick = (e, index) => {
@ -27,10 +23,9 @@ function ScrollableTab({ children }) {
if (actionType === "button") {
window.location.href = redirectLoc;
} else if (actionType === "modal") {
setModalVisible(true);
}
setActiveTab(index);
onActiveTabChange(index);
};
/*
@ -44,10 +39,6 @@ function ScrollableTab({ children }) {
};
*/
const closeModal = () => {
setModalVisible(false);
};
const onHoverElement = () => {};
const onHoverTab = (key) => {
@ -112,7 +103,6 @@ function ScrollableTab({ children }) {
redirectLoc={k.props.redirectLoc}
>
{k.props.children}
<PopupModal visible={modalVisible} closeHandler={closeModal} />
</Tab>
);
});

6
src/index.css

@ -34,4 +34,10 @@ canvas {
.centeredLogo {
display: block;
margin: 0 auto;
}
.leaflet-container {
height: 75vh;
width: 95%;
margin: 10px auto;
}

68
src/pages/study_site_2/StartPage2.jsx

@ -1,13 +1,12 @@
import React from "react";
import { getTranslation } from "../../core/i18n/I18NHandler";
import React, { useState } from "react";
import WebpageBanner from "../../components/webpage_container/WebpageBanner";
import { Tab } from "react-tabs-scrollable";
import {
StudySite,
getHeatmapData,
} from "../../components/webpage_container/StudySite";
import { pushToMouseLog, getSensorLog } from "../../core/log/SensorLogger";
import { Collapse, Text, Spacer } from "@geist-ui/core";
import { pushToMouseLog } from "../../core/log/SensorLogger";
import { Spacer } from "@geist-ui/core";
import ScrollableTab from "../../components/ScrollableTab";
import {
Emoji,
@ -21,11 +20,38 @@ import {
User,
ArrowUpRight,
} from "@geist-ui/icons";
import HotelInformation from "./tab_content/HotelInformation";
import HotelRatings from "./tab_content/HotelRatings";
import HotelFeatures from "./tab_content/HotelFeatures";
import HotelRooms from "./tab_content/HotelRooms";
import HotelFacilities from "./tab_content/HotelFacilities";
import HotelLocation from "./tab_content/HotelLocation";
import HotelFlights from "./tab_content/HotelFlights";
import HotelCatering from "./tab_content/HotelCatering";
const tabContent = [
(<HotelFeatures />),
(<HotelFacilities />),
(<HotelLocation />),
(<HotelFlights />),
(<HotelRooms />),
(<HotelCatering />),
"",
"",
(<HotelRatings />),
(<HotelInformation />),
];
function StartPage2({ redirectLoc }) {
const [activeTabIndex, setActiveTabIndex] = useState(0);
var saveMouseLog = function () {
pushToMouseLog(getHeatmapData());
//window.location.href = "./" + redirectLoc;
};
var onActiveTabChange = (index) => {
setActiveTabIndex(index);
};
// TODO THINK IF I WANT TO JUST USE AN OVERLAY FOR OTHER DUMMY LINKS, WHICH ARENT CORRECT???
@ -36,60 +62,62 @@ function StartPage2({ redirectLoc }) {
<WebpageBanner translationKey="task_2_info" />
<Spacer h={2} />
<img
src="/images/budget_bird_logo.png"
src="/images/lodgingluxe_logo.png"
width="150px"
alt="BudgetBird Airlines Logo"
alt="LodgingLuxe Logo"
class="centeredLogo"
/>
<Spacer h={1} />
<Spacer h={3} />
<h4>Hotel Le Laboratoire</h4>
<Spacer h={2} />
<ScrollableTab>
<Tab actionType="modal">
<Spacer h={3} />
{tabContent[activeTabIndex]}
<ScrollableTab onActiveTabChange={onActiveTabChange}>
<Tab actionType="text">
<Flag viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Features
</Tab>
<Tab actionType="button" redirectLoc={redirectLoc}>
<Tab actionType="text">
<Home viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Facilities
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<MapPin viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Location
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<ArrowUpRight viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Flights
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<Key viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Rooms
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<Emoji viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Catering
</Tab>
<Tab actionType="modal">
<Tab actionType="button" redirectLoc={redirectLoc}>
<User viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Tour Operators
</Tab>
<Tab actionType="modal">
<Tab actionType="button" redirectLoc="./hotel_map">
<Map viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Map
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<Star viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Ratings
</Tab>
<Tab actionType="modal">
<Tab actionType="text">
<HelpCircle viewBox="0 -8 24 32" size={18} />
<Spacer inline w={0.35} />
Useful Information

1
src/pages/study_site_2/TourOperators.jsx

@ -1,5 +1,4 @@
import React from "react";
import { getTranslation } from "../../core/i18n/I18NHandler";
import WebpageBanner from "../../components/webpage_container/WebpageBanner";
import { Tab } from "react-tabs-scrollable";
import {

16
src/pages/study_site_2/tab_content/HotelCatering.jsx

@ -0,0 +1,16 @@
import { Text } from "@geist-ui/core";
function HotelCatering() {
return (
<Text>
Our on-site restaurant, The Alchemist, serves a menu inspired by molecular
gastronomy and scientific innovation. Guests can enjoy a range of dishes
that combine traditional flavors with modern techniques, creating a dining
experience that is both delicious and visually stunning. The rooftop bar,
The Observatory, offers a selection of cocktails and snacks with a
panoramic view of the city.
</Text>
);
}
export default HotelCatering;

20
src/pages/study_site_2/tab_content/HotelFacilities.jsx

@ -0,0 +1,20 @@
import { Text } from "@geist-ui/core";
function HotelFacilities() {
return (
<div>
<Text>
The hotel boasts state-of-the-art facilities designed to enhance your
stay:
</Text>
<ul>
<li>Fully equipped fitness center</li>
<li>Indoor swimming pool</li>
<li>Spa and wellness center</li>
<li>Conference rooms and event spaces</li>
</ul>
</div>
);
}
export default HotelFacilities;

21
src/pages/study_site_2/tab_content/HotelFeatures.jsx

@ -0,0 +1,21 @@
import { Text } from "@geist-ui/core";
function HotelFeatures() {
return (
<div>
<Text>
Hotel Le Laboratoire offers a unique experience inspired by scientific
research and laboratories. Enjoy cutting-edge technology, interactive
exhibits, and a futuristic ambiance. Features include:
</Text>
<ul>
<li>Modern, science-themed rooms</li>
<li>On-site science museum</li>
<li>Interactive lab experiences</li>
<li>Rooftop observatory</li>
</ul>
</div>
);
}
export default HotelFeatures;

14
src/pages/study_site_2/tab_content/HotelFlights.jsx

@ -0,0 +1,14 @@
import { Text } from "@geist-ui/core";
function HotelFlights() {
return (
<Text>
Amsterdam Schiphol Airport is the main international gateway to the city.
It offers numerous direct flights to major cities worldwide. Our concierge
service can assist you with booking flights and arranging airport
transfers.
</Text>
);
}
export default HotelFlights;

18
src/pages/study_site_2/tab_content/HotelInformation.jsx

@ -0,0 +1,18 @@
import { Description, Spacer } from "@geist-ui/core";
function HotelInformation() {
return (
<div>
<Description title="Check-in" content="From 3:00 PM" />
<Spacer h={2} />
<Description title="Check-out" content="Until 12:00 PM" />
<Spacer h={2} />
<Description title="Wi-Fi" content="Free high-speed internet" />
<Spacer h={2} />
<Description title="Parking" content="Available on-site" />
<Spacer h={3} />
</div>
);
}
export default HotelInformation;

45
src/pages/study_site_2/tab_content/HotelLocation.jsx

@ -0,0 +1,45 @@
import { Text, Image } from "@geist-ui/core";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
function HotelLocation() {
const positionCenter = [52.368, 4.88];
const rijksmuseumCoordinates = [52.36, 4.885];
const anneFrankCoordinates = [52.3749, 4.8839];
const vondelparkCoordinates = [52.3577, 4.8665];
const leidsepleinCoordinates = [52.3641, 4.883];
return (
<div>
<Text>
Located in the heart of Amsterdam, Hotel Le Laboratoire is conveniently
situated near popular attractions such as:
</Text>
<ul>
<li>Rijksmuseum</li>
<li>Anne Frank House</li>
<li>Vondelpark</li>
<li>Leidseplein</li>
</ul>
<MapContainer center={positionCenter} zoom={13}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<Marker position={rijksmuseumCoordinates}>
<Popup>Rijksmuseum</Popup>
</Marker>
<Marker position={anneFrankCoordinates}>
<Popup>Anne Frank House</Popup>
</Marker>
<Marker position={vondelparkCoordinates}>
<Popup>Vondelpark</Popup>
</Marker>
<Marker position={leidsepleinCoordinates}>
<Popup>Leidseplein</Popup>
</Marker>
</MapContainer>
</div>
);
}
export default HotelLocation;

33
src/pages/study_site_2/tab_content/HotelMap.jsx

@ -0,0 +1,33 @@
import React from "react";
import WebpageBanner from "../../../components/webpage_container/WebpageBanner";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { StudySite } from "../../../components/webpage_container/StudySite";
const MapSection = () => {
const position = [52.366, 4.8794];
return (
<MapContainer center={position} zoom={13}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<Marker position={position}>
<Popup>
Hotel Le Laboratoire <br /> Amsterdam City Center.
</Popup>
</Marker>
</MapContainer>
);
};
function HotelMap() {
return (
<StudySite>
<WebpageBanner translationKey="task_2_info" />
<MapSection />
</StudySite>
);
}
export default HotelMap;

75
src/pages/study_site_2/tab_content/HotelRatings.jsx

@ -0,0 +1,75 @@
import React from "react";
import { Card, Text, Grid, Avatar, Divider } from "@geist-ui/core";
import { Star } from "@geist-ui/icons";
const RatingCard = ({ name, avatar, rating, review }) => {
return (
<Card shadow style={{ marginBottom: "20px" }}>
<Grid.Container gap={2} justify="center" direction="column">
<Grid
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Avatar src={avatar} width="50px" height="50px" />
</Grid>
<Grid style={{ textAlign: "center" }}>
<Text h4>{name}</Text>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
marginBottom: "10px",
}}
>
{[...Array(rating)].map((_, i) => (
<Star key={i} color="#f5a623" size={20} />
))}
</div>
<Text>{review}</Text>
</Grid>
</Grid.Container>
</Card>
);
};
function HotelRatings() {
const ratings = [
{
name: "John Doe",
avatar: "https://i.pravatar.cc/150?img=3",
rating: 5,
review:
"An amazing experience! The scientific theme is fascinating and the service was excellent. Highly recommend.",
},
{
name: "Jane Smith",
avatar: "https://i.pravatar.cc/150?img=5",
rating: 4,
review:
"Loved the unique theme and the amenities were top-notch. Would love to stay here again.",
},
{
name: "Alex Johnson",
avatar: "https://i.pravatar.cc/150?img=7",
rating: 3,
review:
"Interesting concept, but the rooms were a bit small. Overall, a decent stay.",
},
];
return (
<Grid.Container gap={2} justify="center">
<Grid>
{ratings.map((rating, index) => (
<RatingCard key={index} {...rating} />
))}
</Grid>
</Grid.Container>
);
}
export default HotelRatings;

40
src/pages/study_site_2/tab_content/HotelRooms.jsx

@ -0,0 +1,40 @@
import { Grid, Text, Card, Image } from "@geist-ui/core";
function HotelRooms() {
return (
<Grid.Container gap={2}>
<Grid xs={24} sm={12}>
<Card shadow>
<Text h4>Standard Room</Text>
<Image
src="https://via.placeholder.com/300x200"
alt="Standard Room"
/>
<Text>
Comfortable room with modern amenities and a scientific theme.
</Text>
</Card>
</Grid>
<Grid xs={24} sm={12}>
<Card shadow>
<Text h4>Deluxe Room</Text>
<Image src="https://via.placeholder.com/300x200" alt="Deluxe Room" />
<Text>
Spacious room with enhanced features and a stylish design.
</Text>
</Card>
</Grid>
<Grid xs={24} sm={12}>
<Card shadow>
<Text h4>Suite</Text>
<Image src="https://via.placeholder.com/300x200" alt="Suite" />
<Text>
Luxurious suite with separate living area and premium amenities.
</Text>
</Card>
</Grid>
</Grid.Container>
);
}
export default HotelRooms;
Loading…
Cancel
Save