diff --git a/client/public/locales/de/translation.json b/client/public/locales/de/translation.json index cc26312bbc1d0b3131a4b3a93c044ff5df934de5..604e37db15469d0192c66143af3c0b55d617206f 100644 --- a/client/public/locales/de/translation.json +++ b/client/public/locales/de/translation.json @@ -124,6 +124,7 @@ "LastName": "Nachname", "Email": "Email", "Password": "Password", + "Role": "Role", "AddAccount": "Account hinzufügen", "EditAccount": "Account editieren", "DeleteAccount": "Account löschen?", diff --git a/client/public/locales/en/translation.json b/client/public/locales/en/translation.json index 6bc6dbf22b614b2f7ecf24910baae35c2d1d967c..cf36ec8d2766732d15430b7aabc705f775350a5d 100644 --- a/client/public/locales/en/translation.json +++ b/client/public/locales/en/translation.json @@ -124,6 +124,7 @@ "LastName": "Last Name", "Email": "Email", "Password": "Password", + "Role": "Role", "AddAccount": "Add Account", "EditAccount": "Edit Account", "DeleteAccount": "Delete Account?", diff --git a/client/src/api/auth.ts b/client/src/api/auth.ts index f57da51c1743cb5cabe129344f6ac8289c3e51d6..1da75772a7de95560defe6a09e57bbb6614a877a 100644 --- a/client/src/api/auth.ts +++ b/client/src/api/auth.ts @@ -11,6 +11,8 @@ export async function staffLogin({ email, password }: StaffLoginParameters) { "Content-Type": "application/json", }, }); - + if (!response.ok){ + throw new Error("Couldn't Login") + } return response.json(); } diff --git a/client/src/components/StaffLayout.tsx b/client/src/components/StaffLayout.tsx index 7e5187ce993b6c9603efd7ee5c7c82c6fd63e2c4..22eaab2807734c4ab5fbc807205828c7838c5a44 100644 --- a/client/src/components/StaffLayout.tsx +++ b/client/src/components/StaffLayout.tsx @@ -42,7 +42,7 @@ function StaffLayout() { }, []); return ( - <div className="h-100 w-100"> + <div className="h-100 w-100" style={{ "overflow": "none" }}> <Helmet> <title>{t(`routes.${pathname}`)}</title> </Helmet> @@ -89,7 +89,9 @@ function StaffLayout() { </Navbar.Collapse> </Container> </Navbar> - <Outlet /> + <div style={{"overflow": "auto", "maxHeight": "calc(100vh - 56px)"}}> + <Outlet /> + </div> </div> ); } diff --git a/client/src/pages/staff/Accounts.tsx b/client/src/pages/staff/Accounts.tsx index 90af69cc2d45c5662254c457ef14a23a802cda25..b02e90959d3d611bb3d183563102d3d038a1601b 100644 --- a/client/src/pages/staff/Accounts.tsx +++ b/client/src/pages/staff/Accounts.tsx @@ -142,8 +142,7 @@ function Accounts() { setLoading(false); }); } - }, (err) => { console.log(err) })() - + })() }} > <Form> diff --git a/client/src/pages/staff/BoatOverview.tsx b/client/src/pages/staff/BoatOverview.tsx index 540cb943ac80078fe538ea8d3a0dc560fa914454..9913cfe9e0069bf315d5e19fbf1d4e819f58a594 100644 --- a/client/src/pages/staff/BoatOverview.tsx +++ b/client/src/pages/staff/BoatOverview.tsx @@ -18,7 +18,7 @@ function BoatOverview() { { id: 10, boatName: "Canoe 1", time: "13:15-15:14", seats: 2, overdue: false }, { id: 11, boatName: "Canoe 1", time: "13:15-15:14", seats: 2, overdue: false }, { id: 12, boatName: "Canoe 1", time: "13:15-15:14", seats: 2, overdue: false },] return ( - <div className="text-center bg-light" style={{ height: "calc(100vh - 56px)" }}> + <div className="text-center bg-light"> {/*TODO: Make dynamic*/} <div className="boatViews text-center"> diff --git a/client/src/pages/staff/Sports.tsx b/client/src/pages/staff/Sports.tsx index 409b774eaf71964ed4a02694db2c239f8460a88a..f2c552b71ef70ece312e7595d76c9af162aab409 100644 --- a/client/src/pages/staff/Sports.tsx +++ b/client/src/pages/staff/Sports.tsx @@ -51,7 +51,12 @@ function Sports() { {sports.sort((a, b) => a.name.localeCompare(b.name)).map((x, i) => ( <tr key={x.id}> <td>{x.name}</td> - <td>{x.color}</td> + <td> + <div className="d-flex" style={{ "alignItems": "center" }}> + <div style={{ "borderRadius": "50%", "height": "20px", "width": "20px", "marginRight": "10px", "background": x.color }}></div> + {x.color} + </div> + </td> <td> <div className="d-flex"> <div @@ -94,10 +99,10 @@ function Sports() { <Button onClick={() => { setAdding(true); - setEditElement({ name: "", color: "#000000" } as Sport); + setEditElement({ name: "", color: "#003366" } as Sport); setValue('id', undefined as any); setValue('name', ""); - setValue('color', "#000000"); + setValue('color', "#003366"); }} variant="secondary" > @@ -180,7 +185,7 @@ function Sports() { render={({ field }) => ( <div className="mb-2"> <Form.Label>{t("sports.Color")}</Form.Label> - <Form.Control type="text" {...field} isInvalid={!!errors.color} /> + <Form.Control type="color" {...field} isInvalid={!!errors.color} /> <Form.Control.Feedback type="invalid"> {errors.color?.message} </Form.Control.Feedback> diff --git a/client/src/pages/staff/StaffLogin.tsx b/client/src/pages/staff/StaffLogin.tsx index 9c42711754621f01f1b48e1edeedfa85fd0d1835..0dc7c69d14f277ce73a7245677fdbe85226adef3 100644 --- a/client/src/pages/staff/StaffLogin.tsx +++ b/client/src/pages/staff/StaffLogin.tsx @@ -1,5 +1,5 @@ -import { useEffect } from "react"; -import { Button, Col, Container, Form, Row } from "react-bootstrap"; +import { useEffect, useState } from "react"; +import { Button, Col, Container, Form, Row, Alert } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; @@ -24,6 +24,7 @@ function Login() { }); const { t } = useTranslation(); const navigate = useNavigate(); + const [showLoginError, setShowLoginError] = useState(false); const onSubmit = async (data: FormData) => { try { @@ -32,6 +33,7 @@ function Login() { navigate("/staff", { replace: true }); } } catch (e) { + setShowLoginError(true) // TODO: Error handling } }; @@ -42,7 +44,7 @@ function Login() { if (response.status === 200) { navigate("/staff"); } - } catch (e) {} + } catch (e) { } } useEffect(() => { @@ -53,6 +55,12 @@ function Login() { <Container className="position-absolute top-50 start-50 translate-middle"> <Row> <Col xs={{ span: 10, offset: 1 }}> + {showLoginError && <Alert variant="danger" onClose={() => setShowLoginError(false)} dismissible> + <Alert.Heading>{t("staffLogin.LoginError")}</Alert.Heading> + <p> + {t("staffLogin.LoginErrorText")} + </p> + </Alert>} <Modal> <h1 className="text-center p-1">{t("staffLogin.title")}</h1> <p className="text-center">{t("staffLogin.subtitle")}</p> diff --git a/server/package-lock.json b/server/package-lock.json index fbb1652124acbf7f3b45c47d0845f45184f5cfe3..7d3bc18e7fd5b75dabc1faf45c598148f205de41 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,9 +10,7 @@ "license": "ISC", "dependencies": { "bcrypt": "^5.0.1", - "body-parser": "^1.19.1", "cookie-parser": "^1.4.6", - "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", "express-validator": "^6.14.0", @@ -24,9 +22,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", - "@types/body-parser": "^1.19.2", "@types/cookie-parser": "^1.4.2", - "@types/cors": "^2.8.12", "@types/express": "^4.17.13", "@types/jest": "^27.0.3", "@types/jsonwebtoken": "^8.5.6", @@ -1147,12 +1143,6 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, - "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true - }, "node_modules/@types/express": { "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", @@ -1704,70 +1694,6 @@ "node": ">=8" } }, - "node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "dependencies": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/body-parser/node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/body-parser/node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -1880,14 +1806,6 @@ "node": ">=4" } }, - "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -2247,18 +2165,6 @@ "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", "dev": true }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -4976,14 +4882,6 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz", @@ -5446,53 +5344,6 @@ "node": ">= 0.6" } }, - "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "dependencies": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/raw-body/node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/raw-body/node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -7751,12 +7602,6 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, - "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true - }, "@types/express": { "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", @@ -8223,57 +8068,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "requires": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - }, - "dependencies": { - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } - } - }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -8361,11 +8155,6 @@ "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" }, - "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" - }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -8643,15 +8432,6 @@ "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", "dev": true }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -10753,11 +10533,6 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, "object-inspect": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.1.tgz", @@ -11100,46 +10875,6 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, - "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } - } - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", diff --git a/server/package.json b/server/package.json index 7994f48d0f8903c6340c1aec27feecb3749cac21..05815ab3f7f5f69429ef4ecddf82d503a96aa931 100644 --- a/server/package.json +++ b/server/package.json @@ -14,9 +14,7 @@ "license": "ISC", "dependencies": { "bcrypt": "^5.0.1", - "body-parser": "^1.19.1", "cookie-parser": "^1.4.6", - "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", "express-validator": "^6.14.0", @@ -28,9 +26,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", - "@types/body-parser": "^1.19.2", "@types/cookie-parser": "^1.4.2", - "@types/cors": "^2.8.12", "@types/express": "^4.17.13", "@types/jest": "^27.0.3", "@types/jsonwebtoken": "^8.5.6", diff --git a/server/src/controllers/accounts.controllers.ts b/server/src/controllers/accounts.controllers.ts index 210d508eacc982c606ac7d98a95cf19e1c52f53c..3d709456af4865b35b926dfd4c50f863724658b7 100644 --- a/server/src/controllers/accounts.controllers.ts +++ b/server/src/controllers/accounts.controllers.ts @@ -60,7 +60,6 @@ const showAllAccounts = async (req: Request, res: Response) => { }), }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -84,7 +83,6 @@ const showAccountById = async (req: Request, res: Response) => { } return res.status(404).json({ success: false, error: "accountIdNotFound" }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -142,7 +140,6 @@ const updateAccount = async (req: Request, res: Response) => { }, }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -168,7 +165,6 @@ const deleteAccountById = async (req: Request, res: Response) => { return res.status(200).json({ success: true }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; diff --git a/server/src/controllers/auth.controllers.ts b/server/src/controllers/auth.controllers.ts index baadebbdb17f4d863246c5321ce93dbe26fccd0e..f14c3cb14eaca76de817722b876c36ce0e372f59 100644 --- a/server/src/controllers/auth.controllers.ts +++ b/server/src/controllers/auth.controllers.ts @@ -41,7 +41,6 @@ const authLoginController = async (req: Request, res: Response) => { return res.status(401).json({ success: false, error: "invalidPassword" }); } } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; diff --git a/server/src/controllers/boat.controllers.ts b/server/src/controllers/boat.controllers.ts index 33f73c7873584fa1153e1e812e4a73188161500f..7917425637200cf1392b81a86410fb08ad28c241 100644 --- a/server/src/controllers/boat.controllers.ts +++ b/server/src/controllers/boat.controllers.ts @@ -6,12 +6,6 @@ import Sport from "../db/models/Sport"; //create boat const createBoat = async (req: Request, res: Response) => { try { - if (!(res.locals.user.role == "coordinator")) { - return res - .status(403) - .json({ success: false, error: "MustBeCoordinator" }); - } - const newBoatInput = req.body; //check if boattype exists @@ -22,71 +16,9 @@ const createBoat = async (req: Request, res: Response) => { .json({ success: false, error: "boattypeNotFound" }); } - //check if name of boat already exists - - const checkBoatName = await Boat.findOne({ - where: { - name: newBoatInput.name, - }, - }); - - if (!(checkBoatName === null)) { - return res - .status(409) - .json({ success: false, error: "boatNameAlreadyExists" }); - } - - //check if given sport-ids can be found - const sportsArray = newBoatInput.sports; - var check = true; - - //if sports provided in the request body - if (!(sportsArray === undefined)) { - //define empty array, where we store founded/not founded names of sports assigned to boat's id - var listIfNotFound = new Array(); - var listIfFound = new Array(); - - //check wether each new given id exists or not - for (let i = 0; i < sportsArray.length; i++) { - const found = await Sport.findByPk(sportsArray[i]); - if (!found) { - listIfNotFound.push(sportsArray[i]); - var check = false; - } - if (found) { - const showSportName = await ( - await Sport.findByPk(sportsArray[i]) - ).name; - listIfFound.push(showSportName); - } - } - } - - //if there is a sport, which isn't in the database, we return an array with the names of the missing sports - if (check === false) { - return res.status(404).json({ success: false, sports: listIfNotFound }); - } - //create the boat const newBoat = await Boat.create(newBoatInput); - //another check if sports array was provided and it's with valid sport ids => create entry in BoatHasSport table with the new created boat id and corresponding sport is - if (!(sportsArray == undefined)) { - if (listIfFound.length === sportsArray.length) { - const boatid = newBoat.id; - - //create entry (boatid, each id of given sportIds) - for (let i = 0; i < sportsArray.length; i++) { - const sportid = sportsArray[i]; - const entry = { boatid, sportid }; - - //create new entry in boatHasBoatType - //TODO: Replace - //await BoatTypeHasSport.create(entry); - } - } - } - //return created boat + the assigned sports if (newBoat) { return res.status(201).json({ @@ -94,13 +26,11 @@ const createBoat = async (req: Request, res: Response) => { result: { id: newBoat.id, name: newBoat.name, - status: newBoat.status, - sports: listIfFound, + status: newBoat.status }, }); } } catch (error) { - console.error(error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -120,7 +50,6 @@ const showAllBoatsController = async (req: Request, res: Response) => { }), }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -142,7 +71,6 @@ const showBoatById = async (req: Request, res: Response) => { } return res.status(404).json({ success: false, error: "boatIdNotFound" }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -150,8 +78,6 @@ const showBoatById = async (req: Request, res: Response) => { //delete specific boat using given id const deleteBoatById = async (req: Request, res: Response) => { try { - const givenId = req.params.id; - //first we need to destroy entries where the to-be-deleted boat is connected with sport in BoatHasSport table, because it violates the foreign constraint //TODO: Replace /*await BoatTypeHasSport.destroy({ @@ -159,10 +85,9 @@ const deleteBoatById = async (req: Request, res: Response) => { boattypeid: givenId, }, });*/ - const boatToDelete = await Boat.destroy({ where: { - id: givenId, + id: req.params.id, }, }); if (boatToDelete == 0) { @@ -172,7 +97,6 @@ const deleteBoatById = async (req: Request, res: Response) => { } return res.status(200).json({ success: true }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -182,7 +106,6 @@ const updateBoatById = async (req: Request, res: Response) => { try { //get new input const input = req.body; - //return 200 with empty response if no data was given if (Object.keys(input).length === 0) { return res @@ -190,11 +113,8 @@ const updateBoatById = async (req: Request, res: Response) => { .json({ success: true, result: {}, message: "noInputFound" }); } - //get id - const givenId = req.params.id; - //check if boat can be found using givenId - const foundBoat = await Boat.findByPk(givenId); + const foundBoat = await Boat.findByPk(req.params.id); if (!foundBoat) { return res.status(404).json({ success: false, error: "boatIdNotFound" }); @@ -230,7 +150,7 @@ const updateBoatById = async (req: Request, res: Response) => { //try to update the attributes, which are in Boat table const updatedBoat = await Boat.update(input, { where: { - id: givenId, + id: req.params.id, }, returning: true, }); @@ -278,7 +198,7 @@ const updateBoatById = async (req: Request, res: Response) => { } //if sports Array is with valid id's, assign them to boat; create entry (boatid, each id of given sportIds) inf BoatHasSport table for (let i = 0; i < listIfFound.length; i++) { - const boatid = givenId; + const boatid = req.params.id; const sportid = listIfFound[i]; const entry = { boatid, sportid }; @@ -311,7 +231,7 @@ const updateBoatById = async (req: Request, res: Response) => { return res.status(200).json({ success: true, result: { - id: givenId, + id: req.params.id, name: foundBoat.name, status: foundBoat.status, sports: listOfNames, @@ -331,7 +251,6 @@ const updateBoatById = async (req: Request, res: Response) => { }, }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; diff --git a/server/src/controllers/sport.controllers.ts b/server/src/controllers/sport.controllers.ts index 6da947eceedf0d4ed71f08c79b34ba509934bb8d..cc15a7f39f98a73f870f5a548701e7bda43290c7 100644 --- a/server/src/controllers/sport.controllers.ts +++ b/server/src/controllers/sport.controllers.ts @@ -97,7 +97,6 @@ const updateSportById = async (req: Request, res: Response) => { }, }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; @@ -136,7 +135,6 @@ const showSportByBoatId = async (req: Request, res: Response) => { } return res.status(404).json({ success: false, error: "boatIdNotFound" }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; diff --git a/server/src/controllers/user.controllers.ts b/server/src/controllers/user.controllers.ts index ee01e007b98ba592d394248ade89309ea74fe8b2..3713fd64fa59d71fcdd66377139388914a87cb3b 100644 --- a/server/src/controllers/user.controllers.ts +++ b/server/src/controllers/user.controllers.ts @@ -23,7 +23,6 @@ const showCurrentUserController = async (req: Request, res: Response) => { }, }); } catch (error) { - console.error("server error: ", error.message); res.status(500).json({ success: false, error: "serverError!" }); } }; @@ -88,7 +87,6 @@ const updateCurrentUser = async (req: Request, res: Response) => { }, }); } catch (error) { - console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; diff --git a/server/src/db/index.ts b/server/src/db/index.ts index 318f21e3b5eb452075c57ee5c52626fd8d5bc288..8e7df20cf5d9ff051daacb59cd22fa280667a811 100644 --- a/server/src/db/index.ts +++ b/server/src/db/index.ts @@ -20,12 +20,15 @@ export default async function initializeDatabase() { } ); await initEmployee(sequelize); - await initSport(sequelize); - await initBoat(sequelize); - await initBoatType(sequelize); + const Sport = await initSport(sequelize); + const Boat = await initBoat(sequelize); + const BoatType = await initBoatType(sequelize); await initCheckIn(sequelize); - await sequelize.sync({alter: true}); + BoatType.belongsToMany(Sport, { through: "Sport_BoatType" }); + Boat.hasOne(BoatType); + + await sequelize.sync({ alter: true }); } async function createDbIfNotExists() { diff --git a/server/src/db/models/Boat.ts b/server/src/db/models/Boat.ts index 16a57ebd0477798aeca15c9e1f6d59a32507a3ec..1b931e2c9495b19fb1a2494109cf0168e69d45ab 100644 --- a/server/src/db/models/Boat.ts +++ b/server/src/db/models/Boat.ts @@ -21,9 +21,6 @@ class Boat declare readonly updatedAt: Date; } -// TODO -//Boat.hasOne(BoatType); - export const initBoat = async (sequelizeConnection: Sequelize) => { Boat.init( { @@ -47,6 +44,7 @@ export const initBoat = async (sequelizeConnection: Sequelize) => { sequelize: sequelizeConnection, } ); + return Boat; }; export default Boat; diff --git a/server/src/db/models/BoatType.ts b/server/src/db/models/BoatType.ts index c8a92ab9122810de3a907fcda6004e226539394f..d1075ef9a32fe54276d6b211d585bd13360afb8b 100644 --- a/server/src/db/models/BoatType.ts +++ b/server/src/db/models/BoatType.ts @@ -4,14 +4,9 @@ import { Model, Optional, Association, - HasManyGetAssociationsMixin, HasManyAddAssociationMixin, BelongsToManySetAssociationsMixin, - HasManyHasAssociationMixin, - HasManyCountAssociationsMixin, - HasManyCreateAssociationMixin, } from "sequelize"; -import Boat from "./Boat"; import Sport from "./Sport"; interface BoatTypeAttributes { @@ -64,6 +59,6 @@ export const initBoatType = async (sequelizeConnection: Sequelize) => { sequelize: sequelizeConnection, } ); - BoatType.belongsToMany(Sport, { through: "Sport_BoatType" }); + return BoatType }; export default BoatType; diff --git a/server/src/db/models/Sport.ts b/server/src/db/models/Sport.ts index a223eb7d7b9143578f94e7510486f8f8b523a20a..97c14ba9a7dbd290aa1d3095e5d54b6fa0ca11b6 100644 --- a/server/src/db/models/Sport.ts +++ b/server/src/db/models/Sport.ts @@ -42,5 +42,6 @@ export const initSport = async (sequelizeConnection: Sequelize) => { sequelize: sequelizeConnection, } ); + return Sport; }; export default Sport; diff --git a/server/src/routes/boat.routes.ts b/server/src/routes/boat.routes.ts index ef3ceddb4b21b33793304076899a03d081b40cbd..8b7c5747070335a7688014ee0ce69d962659acfe 100644 --- a/server/src/routes/boat.routes.ts +++ b/server/src/routes/boat.routes.ts @@ -3,6 +3,7 @@ import { body } from "express-validator"; import validateToken from "../middleware/validateToken"; import boatControllers from "../controllers/boat.controllers"; import handleValidationResult from "../middleware/handleValidationResult"; +import isCoord from "../middleware/isCoord"; const boatsRouter = Router(); @@ -16,6 +17,7 @@ boatsRouter.get("/api/boat/:id", boatControllers.showBoatById); boatsRouter.delete( "/api/boat/:id", validateToken, + isCoord, boatControllers.deleteBoatById ); @@ -27,6 +29,7 @@ boatsRouter.post( body("status").not().isEmpty() && body("status").isIn([1, 0]), handleValidationResult, validateToken, + isCoord, boatControllers.createBoat ); @@ -38,6 +41,7 @@ boatsRouter.patch( body("status").if(body("status").exists()).not().isEmpty().isIn([1, 0]), handleValidationResult, validateToken, + isCoord, boatControllers.updateBoatById );