Skip to content
Snippets Groups Projects
Commit 13e423a8 authored by Sebastian Kuzniarz's avatar Sebastian Kuzniarz
Browse files

Staff Overview Changes and New Boat Type Overview

- Fixed tile layout for rented boat tiles
- Added several design changes on overview
- Added status dependant tile color dependence on status
- Added new Boat Type Overview UI
parent 27f5dedc
No related branches found
No related tags found
No related merge requests found
......@@ -10,31 +10,9 @@
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
\ No newline at end of file
......@@ -47,6 +47,10 @@
"invalidEmail" : "Bitte trage eine gültige Email ein"
}
},
"staffModal": {
"Cancel": "Abbrechen",
"Done": "Fertig"
},
"staffNav": {
"buttonBoatOverview": "Bootsübersicht",
"buttonManageBoats": "Boote verwalten",
......@@ -55,10 +59,16 @@
},
"boatOverview": {
"labelOverdue": "Ausgeliehene Boote - Überfällig",
"labelCurrentlyRented": "Momentan augeliehende Boote",
"labelCurrentlyRented": "Momentan augeliehene Boote",
"buttonShowAll": "Alle anzeigen"
},
"routes": {
"/staff/overview": "Bootsübersicht"
"/": "Wassersport",
"/book": "Boot buchen",
"/book/success": "Buchung Erfolgreich",
"/signout": "Bootrückgabe",
"/login": "Login",
"/staff/overview": "Bootsübersicht",
"/staff/boattypes" : "Bootstypen"
}
}
\ No newline at end of file
......@@ -47,6 +47,10 @@
"invalidEmail" : "Bitte trage eine gültige Email ein"
}
},
"staffModal": {
"Cancel": "Cancel",
"Done": "Done"
},
"staffNav": {
"buttonBoatOverview": "Boat Overview",
"buttonManageBoats": "Manage Boats",
......@@ -59,6 +63,12 @@
"buttonShowAll": "Show all"
},
"routes": {
"/staff/overview": "Boat Overview"
"/": "Water Sports",
"/book": "Book a Boat",
"/book/success": "Booked Successfully",
"/signout": "Sign Out",
"/login": "Login",
"/staff/overview": "Boat Overview",
"/staff/boattypes" : "Boat Types"
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ import { BrowserRouter, Route, Routes } from "react-router-dom";
import StaffLayout from "./components/StaffLayout";
import UserLayout from "./components/UserLayout";
import BoatOverview from "./pages/BoatOverview";
import BoatTypeOverview from "./pages/BoatTypeOverview";
import BookingForm from "./pages/BookingForm";
import BookingSignOut from "./pages/BookingSignOut";
import BookingSignOutSuccess from "./pages/BookingSignOutSuccess";
......@@ -35,6 +36,7 @@ function Router() {
</Route>
<Route path="staff" element={<StaffLayout />}>
<Route path="overview" element={<BoatOverview />} />
<Route path="boattypes" element={<BoatTypeOverview />} />
</Route>
</Routes>
</BrowserRouter>
......
import React from "react";
import { Col } from "react-bootstrap";
// import { Image } from "react-bootstrap";
// import { Link } from "react-router-dom";
function RentedBoatTile(props: any) {
return(
<div className="rented-boat-tile mb-1 col-sm rounded-2 bg-danger" style={{height: "5rem", minWidth: "17rem", maxWidth: "100%)", margin: "10px"}}>
<div className="tile-body position-relative w-100 h-100">
<h3 className="tile-label-boatName position-absolute top-0 start-0 text-white fw-bold">{props.boatName}</h3>
<h4 className="tile-label-time position-absolute top-0 end-0 text-white">{props.time}</h4>
<h4 className="tile-label-persons position-absolute bottom-0 start-0 text-white">{props.persons}</h4>
<h3 className="tile-label-overdue position-absolute bottom-0 end-0 text-white fw-bold">{props.overdue}</h3>
<Col>
<div className={`card-body shadow position-relative mb-1 rounded-2 ${props.overdue ? 'bg-danger' : 'bg-secondary'}` } style={{height : "80px"}}>
<div className="text-uppercase fs-4 tile-label-boatName position-absolute ms-2 mt-1 top-0 start-0 text-white fw-bold">{props.boatName}</div>
<div className="tile-label-time position-absolute me-2 mt-2 top-0 end-0 text-white">{props.time}</div>
<div className="tile-label-persons position-absolute ms-2 mb-2 bottom-0 start-0 text-white">{props.persons}</div>
{/* Conditonally render the overdue text if it is set*/}
{props.overdue &&
<div className="tile-label-overdue position-absolute me-2 mb-2 bottom-0 end-0 text-white fw-bold">{props.overdue}</div>
}
</div>
</div>
</Col>
);
}
......
import { Modal, Button } from "react-bootstrap";
import { useTranslation } from "react-i18next";
function StaffModal(props: {
children?: any;
......@@ -11,6 +12,7 @@ function StaffModal(props: {
hideText?: string;
show: boolean;
}) {
const {t} = useTranslation();
return (
<Modal
{...props}
......@@ -29,16 +31,16 @@ function StaffModal(props: {
<Modal.Footer className="justify-content-between">
<Button
className="float-left"
variant={props.hideColor || "danger"}
variant={props.hideColor || "secondary"}
onClick={props.onHide}
>
{props.hideText || "Close"}
{props.hideText || t("staffModal.Close")}
</Button>
<Button
variant={props.successColor || "primary"}
onClick={props.onSuccess}
>
{props.successText || "Done"}
{props.successText || t("staffModal.Done")}
</Button>
</Modal.Footer>
</Modal>
......
import React from "react";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Outlet } from "react-router";
import { useLocation } from "react-router-dom";
import bg from "../assets/bg_mobile.png";
function UserLayout() {
const location = useLocation();
const {t} = useTranslation();
//TODO: Find out how to change continously
useEffect(() => {
console.log(location.pathname);
document.title=t(`routes.${location.pathname}`);
}, []);
return (
<div>
<div
......
import { Button } from "react-bootstrap";
import { Button, Container, Row } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import Divider from "../components/Divider";
import RentedBoatTile from "../components/RentedBoatTile";
......@@ -9,19 +9,38 @@ function BoatOverview() {
return (
<div className="text-center">
{/*TODO: Make dynamic*/}
<h1 className="mt-3">{t("boatOverview.labelOverdue")}</h1>
<div className="row mx-auto w-100 justify-content-center">
<RentedBoatTile boatName="Canoe 13" time="13:15-15:14" persons="1 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 15" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 15" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 15" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 15" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 15" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<h2 className="my-3">{t("boatOverview.labelOverdue")}</h2>
<div className="py-3 bg-light border">
<Container>
<div className="overdue-tiles text-center">
<Row xs={1} md={2} xxl={3}>
<RentedBoatTile boatName="Canoe 1" time="13:15-15:14" persons="1 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 7" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 13" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 16" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
<RentedBoatTile boatName="Canoe 22" time="13:15-15:14" persons="3 Person" overdue="Overdue!"></RentedBoatTile>
</Row>
</div>
<Button variant="light" className="mt-3 shadow-sm bg-white border w-50 text-uppercase rounded-pill">{t("boatOverview.buttonShowAll")}</Button>
</Container>
</div>
<h2 className="my-3">{t("boatOverview.labelCurrentlyRented")}</h2>
<div className="py-3 bg-light border">
<Container>
<div className="overdue-tiles text-center">
<Row xs={1} md={2} xxl={3}>
<RentedBoatTile boatName="Canoe 2" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
<RentedBoatTile boatName="Canoe 5" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
<RentedBoatTile boatName="Canoe 6" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
<RentedBoatTile boatName="Canoe 9" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
<RentedBoatTile boatName="Canoe 18" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
<RentedBoatTile boatName="Canoe 20" time="13:15-15:14" persons="3 Person" overdue={false}></RentedBoatTile>
</Row>
</div>
<Button variant="light" className="mt-3 shadow-sm bg-white border w-50 text-uppercase rounded-pill">{t("boatOverview.buttonShowAll")}</Button>
</Container>
</div>
<Button variant="light" className="color-secondary border w-50 text-uppercase rounded-pill">{t("boatOverview.buttonShowAll")}</Button>
<Divider />
<h1 className="mt-3">{t("boatOverview.labelCurrentlyRented")}</h1>
<Button variant="light" className="color-secondary border w-50 text-uppercase rounded-pill">{t("boatOverview.buttonShowAll")}</Button>
</div>
);
}
......
import React, { useEffect, useState } from "react";
import { Table, Button } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import { faEdit, faTrashAlt } from "@fortawesome/free-regular-svg-icons";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import StaffModal from "../components/StaffModal"
function BoatOverview() {
const { t } = useTranslation();
const [editElement, setEditElement] = useState<any>(undefined);
const [deleteElement, setDeleteElement] = useState<any>(undefined);
const [addElement, setAddElement] = useState<any>(false);
return (
<div className="m-1 h-100">
<div className="my-2 d-flex justify-content-end mx-2">
<Button onClick={()=>{setAddElement(true)}} variant="secondary"><FontAwesomeIcon icon={faPlus} className="text-white" /> Add</Button>
</div>
<Table responsive striped bordered hover>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Seats</th>
<th>Sport</th>
<th></th>
</tr>
</thead>
<tbody>
{
[{ id: 1, name: "Das Boot 1", seats: 1, sport: 1 }, { id: 2, name: "Das Boot 2", seats: 1, sport: 1 }, { id: 3, name: "Das Boot 3", seats: 1, sport: 1 }].map(x => (
<tr key={x.id}>
<td>{x.id}</td>
<td>{x.name}</td>
<td>{x.seats}</td>
<td>{x.sport}</td>
<td>
<div className="d-flex">
<div className="mx-2" onClick={() => { setEditElement(x) }}><FontAwesomeIcon
icon={faEdit}
className="text-secondary clickableIcon"
size="1x" />
</div>
<div className="mx-2" onClick={() => { setDeleteElement(x) }}><FontAwesomeIcon
icon={faTrashAlt}
className="text-danger clickableIcon"
size="1x" />
</div>
</div>
</td>
</tr>
))
}
</tbody>
</Table>
<StaffModal header={"Add BoatType"} show={addElement} successText="Add" onHide={() => { setAddElement(false) }}>
</StaffModal>
<StaffModal header={"Edit BoatType"} show={editElement} onHide={() => { setEditElement(undefined) }}>
</StaffModal>
<StaffModal header={"Delete BoatType?"} hideColor="secondary" successText="Delete" successColor="danger" show={deleteElement} onHide={() => { setDeleteElement(undefined) }} onSuccess={() => { setDeleteElement(undefined) }}>
<span>Do you really want to delete "{deleteElement?.name}"?</span>
</StaffModal>
</div>
);
}
export default BoatOverview;
\ No newline at end of file
......@@ -15,4 +15,11 @@ $body-color: $secondary;
.nav-link.active {
text-decoration: underline;
}
.clickableIcon {
&:hover {
cursor: pointer;
transform: scale(1.2);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment