diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 754be01a8a285e9898092e08c8474f2e4ba0d6f2..1a2fb332eebd28bc6a603951aa2661f1a909e08d 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,6 +2,5 @@ <project version="4"> <component name="TypeScriptCompiler"> <option name="recompileOnChanges" value="true" /> - <option name="useTypesFromServer" value="true" /> </component> </project> \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index 8471b760194c4c867d89f319343b2ba59f2d8931..129607019d7a1816855f90d1bf3b6c25e9a26720 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="DataSourceManagerImpl" format="xml" multifile-model="true"> - <data-source source="LOCAL" name="@localhost" uuid="d13d7697-126d-49bc-9966-26b7a09db16d"> + <data-source source="LOCAL" name="@localhost" uuid="f87a3ffc-0511-4957-ba46-fa48cbddcc4f"> <driver-ref>mysql.8</driver-ref> <synchronize>true</synchronize> <jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver> diff --git a/.idea/ip1_gruppe8.iml b/.idea/ip1_gruppe8.iml new file mode 100644 index 0000000000000000000000000000000000000000..24643cc37449b4bde54411a80b8ed61258225e34 --- /dev/null +++ b/.idea/ip1_gruppe8.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="WEB_MODULE" version="4"> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/.tmp" /> + <excludeFolder url="file://$MODULE_DIR$/temp" /> + <excludeFolder url="file://$MODULE_DIR$/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..193c6b5cbea2aa63a92ebf603d3fa5e662c151b9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/ip1_gruppe8.iml" filepath="$PROJECT_DIR$/.idea/ip1_gruppe8.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000000000000000000000000000000000000..6405bb6ce8f556c6c6c2ff5c150e34b48f5684f7 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="SqlDialectMappings"> + <file url="file://$PROJECT_DIR$/userman_all/server/db/init.sql" dialect="MySQL" /> + <file url="file://$USER_HOME$/_localhost__2_-2025_01_19_11_02_40-dump.sql" dialect="MySQL" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index d843f340d228380d0809b446083dfc066e5de60a..35eb1ddfbbc029bcab630581847471d7f238ec53 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="VcsDirectoryMappings" defaultProject="true" /> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> </project> \ No newline at end of file diff --git a/datenbank_horizon_changers.sql b/datenbank_horizon_changers.sql new file mode 100644 index 0000000000000000000000000000000000000000..46a1a9321ea1110afc15004ba03ae309d11afeaf --- /dev/null +++ b/datenbank_horizon_changers.sql @@ -0,0 +1,214 @@ +-- MySQL dump 10.13 Distrib 8.4.3, for macos14 (arm64) +-- +-- Host: 127.0.0.1 Database: horizon_changers +-- ------------------------------------------------------ +-- Server version 8.4.3 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `activity` +-- + +DROP TABLE IF EXISTS `activity`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `activity` ( + `activity_id` int NOT NULL, + `title` text, + `price` int DEFAULT NULL, + PRIMARY KEY (`activity_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `activity` +-- + +LOCK TABLES `activity` WRITE; +/*!40000 ALTER TABLE `activity` DISABLE KEYS */; +INSERT INTO `activity` VALUES (1,'Taj Mahal',90),(2,'Gewürztour',120),(3,'Tanzkurs',70); +/*!40000 ALTER TABLE `activity` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `booking` +-- + +DROP TABLE IF EXISTS `booking`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `booking` ( + `booking_id` int NOT NULL, + `bookingTime` datetime DEFAULT NULL, + `user_id` int DEFAULT NULL, + `numberFlights` int DEFAULT NULL, + `numberInsurance` int DEFAULT NULL, + PRIMARY KEY (`booking_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `booking` +-- + +LOCK TABLES `booking` WRITE; +/*!40000 ALTER TABLE `booking` DISABLE KEYS */; +INSERT INTO `booking` VALUES (1,'2024-12-12 12:05:08',1,NULL,NULL),(2,'2024-04-23 17:04:38',2,NULL,NULL),(3,'2024-02-12 22:01:43',3,NULL,NULL); +/*!40000 ALTER TABLE `booking` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `booking_activity_connection` +-- + +DROP TABLE IF EXISTS `booking_activity_connection`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `booking_activity_connection` ( + `booking_id` int NOT NULL, + `activity_id` int NOT NULL, + KEY `booking_activity_connection_activity_activity_id_fk` (`activity_id`), + KEY `booking_activity_connection_booking_booking_id_fk` (`booking_id`), + CONSTRAINT `booking_activity_connection_activity_activity_id_fk` FOREIGN KEY (`activity_id`) REFERENCES `activity` (`activity_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `booking_activity_connection_booking_booking_id_fk` FOREIGN KEY (`booking_id`) REFERENCES `booking` (`booking_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `booking_activity_connection` +-- + +LOCK TABLES `booking_activity_connection` WRITE; +/*!40000 ALTER TABLE `booking_activity_connection` DISABLE KEYS */; +/*!40000 ALTER TABLE `booking_activity_connection` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `booking_product_connection` +-- + +DROP TABLE IF EXISTS `booking_product_connection`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `booking_product_connection` ( + `booking_id` int NOT NULL, + `product_id` int NOT NULL, + PRIMARY KEY (`product_id`,`booking_id`), + KEY `booking_product_connection_booking_booking_id_fk` (`booking_id`), + CONSTRAINT `booking_product_connection_booking_booking_id_fk` FOREIGN KEY (`booking_id`) REFERENCES `booking` (`booking_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `booking_product_connection_product_product_id_fk` FOREIGN KEY (`product_id`) REFERENCES `product` (`product_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `booking_product_connection` +-- + +LOCK TABLES `booking_product_connection` WRITE; +/*!40000 ALTER TABLE `booking_product_connection` DISABLE KEYS */; +INSERT INTO `booking_product_connection` VALUES (1,3),(2,1),(3,2); +/*!40000 ALTER TABLE `booking_product_connection` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `product` +-- + +DROP TABLE IF EXISTS `product`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `product` ( + `product_id` int NOT NULL, + `title` text, + `price` int DEFAULT NULL, + `description` text, + PRIMARY KEY (`product_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `product` +-- + +LOCK TABLES `product` WRITE; +/*!40000 ALTER TABLE `product` DISABLE KEYS */; +INSERT INTO `product` VALUES (1,'Indien',1500,'Schulen und Bildungseinrichtungen in Indien bauen'),(2,'Spanien',1500,'Reise zur Rettung von Straßenhunden'),(3,'Kenia',1500,'Brunnenbau für eine bessere Welt'); +/*!40000 ALTER TABLE `product` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `reviews` +-- + +DROP TABLE IF EXISTS `reviews`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `reviews` ( + `reviews_id` int NOT NULL, + `title` text, + `description` text, + `product_id` int DEFAULT NULL, + `user_id` int DEFAULT NULL, + PRIMARY KEY (`reviews_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `reviews` +-- + +LOCK TABLES `reviews` WRITE; +/*!40000 ALTER TABLE `reviews` DISABLE KEYS */; +INSERT INTO `reviews` VALUES (1,'Meine Reise in Indien','Jeder Moment erzählt eine neue Geschichte....',1,1),(2,'Meine Reise in Spanien','Jeder Tag war wunderbar...',2,2),(3,'Meine Reise in Kenia','Schon bei der Ankunft war mir klar dieses Abenteuer wird unvergesslich...',3,3); +/*!40000 ALTER TABLE `reviews` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user` +-- + +DROP TABLE IF EXISTS `user`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `user` ( + `user_id` int NOT NULL AUTO_INCREMENT, + `firstName` text, + `lastName` text, + `eMail` text, + `password` text, + `adress` text, + `role` text, + PRIMARY KEY (`user_id`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user` +-- + +LOCK TABLES `user` WRITE; +/*!40000 ALTER TABLE `user` DISABLE KEYS */; +INSERT INTO `user` VALUES (2,'Bob','Hase','bob.hase@outlook.com','09876543','Musterstraße 9, 12345 Musterstadt',NULL),(3,'Claus','Krause','claus.krause@gmail.com','passwort','Hauptstraße 10, 123890 Großbusek',NULL),(4,'Anna','Peters','anna.peters@gmail.com','mausmaus','Walltorstraße 8 34678 Riegen',NULL),(5,'cdkwjbwdk','dwbckwqd','hwdhcvkdsa','347824085851149d03448e7530d4874ce35930bacc7e393c8807a8f9a83f971d7c11b48e5e994e565df7c17c3b69df18687f79dde9b1fea90470e1aaaa6ad2c8','1/16/2025, 9:43:59 PM',NULL),(6,'zdfiizrfi','fttjj','dhhf','6b741a6a48215b2d7d974dbd0a54ebf1deaca773df0f828c42fc5012bbd9f63da4907c2bddc69ec0726f95ebd5cb6c40fcc210b4e9e28aebfe86b3c9ae6c7c64','1/16/2025, 9:57:16 PM',NULL),(7,'CDBLBDCSB','DCJBJLB','cdjsbckbcw','68552f2270d34dc859d75f542038f89cb6c8028a11525af040e668dd86e2c976b46ab22496d31bb859b45566840d34b434a440ae91c9e256b1d3c707f7030e03','1/16/2025, 10:03:36 PM',NULL),(8,'ahvjdascv,','dbwsjcl,j','cdhxnvs,dv,c','d5ef249a9d4b20c939c27d5bdbbae78bc199a721e2d3b74ceb832848bf57eb4b1b44c61a216fd7e002fc9fd50ec36ba1198ddaec9a8d80a23c40a95caf642cc4','1/17/2025, 8:58:31 AM',NULL),(9,'Peter','Kneisel','anna.peters@gmail.com','mausmaus','Berliner Str.12 35422 München',NULL),(10,'Bruce','Wayne','bat','d404559f602eab6fd602ac7680dacbfaadd13630335e951f097af3900e9de176b6db28512f2e000b9d04fba5133e8b1c6e8df59db3a8ab9d60be4b97cc9e81db',NULL,NULL); +/*!40000 ALTER TABLE `user` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2025-01-19 11:02:41 diff --git a/userman_all/client/assets/Bild.jpg b/userman_all/client/assets/Bild.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d9f830c430494b26e363bfb272ea73a3ff56ba8 Binary files /dev/null and b/userman_all/client/assets/Bild.jpg differ diff --git a/userman_all/client/assets/HORIZON CHANGERS.PNG b/userman_all/client/assets/HORIZON CHANGERS.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f80c5dc57f1c0b7ba1f3cf940fd84890a89833cc Binary files /dev/null and b/userman_all/client/assets/HORIZON CHANGERS.PNG differ diff --git "a/userman_all/client/assets/MAPL\303\204NDER.png" "b/userman_all/client/assets/MAPL\303\204NDER.png" new file mode 100644 index 0000000000000000000000000000000000000000..6fb10390f50b8bab6ccade0e240f57f89bc05adb Binary files /dev/null and "b/userman_all/client/assets/MAPL\303\204NDER.png" differ diff --git a/userman_all/client/assets/angetreteneReisen.jpg b/userman_all/client/assets/angetreteneReisen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8963575ab1d51c14985ffa1607a6d05913bada02 Binary files /dev/null and b/userman_all/client/assets/angetreteneReisen.jpg differ diff --git a/userman_all/client/assets/bevorstehendeReisen.jpg b/userman_all/client/assets/bevorstehendeReisen.jpg new file mode 100644 index 0000000000000000000000000000000000000000..db40ab0de1484e36799b8a9d81fcb5da42bc95b5 Binary files /dev/null and b/userman_all/client/assets/bevorstehendeReisen.jpg differ diff --git a/userman_all/client/assets/helles logo.png b/userman_all/client/assets/helles logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d62c13babde03c0b1bc93b03e3147e1ac3d3d8f4 Binary files /dev/null and b/userman_all/client/assets/helles logo.png differ diff --git a/userman_all/client/assets/heroimage.jpg b/userman_all/client/assets/heroimage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d46ba48fb7ed6f20903a6450f8156137fd081f44 Binary files /dev/null and b/userman_all/client/assets/heroimage.jpg differ diff --git a/userman_all/client/assets/keniaprojekt.jpeg b/userman_all/client/assets/keniaprojekt.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..10a86f87ca03d1dd6f38b7ac9cc4f556eda32478 Binary files /dev/null and b/userman_all/client/assets/keniaprojekt.jpeg differ diff --git a/userman_all/client/assets/peruprojekt (1).jpeg b/userman_all/client/assets/peruprojekt (1).jpeg new file mode 100644 index 0000000000000000000000000000000000000000..59ab5dccd4b6607f4e246f47b545b90c5fd1213b Binary files /dev/null and b/userman_all/client/assets/peruprojekt (1).jpeg differ diff --git a/userman_all/client/assets/spanienprojket 2.jpg b/userman_all/client/assets/spanienprojket 2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..90c0d7d442d437bf967157e2c97048fd7812f20c Binary files /dev/null and b/userman_all/client/assets/spanienprojket 2.jpg differ diff --git a/userman_all/client/index.html b/userman_all/client/index.html index cc0162b2e885c5361ba7f2044dc77aa7fde2cfed..9835e7b2e78560ab8f6afd81422e900bf3b2fd74 100644 --- a/userman_all/client/index.html +++ b/userman_all/client/index.html @@ -7,130 +7,478 @@ <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css"> <script src="node_modules/bootstrap/dist/js/bootstrap.bundle.js"></script> <link rel="stylesheet" href="node_modules/@fortawesome/fontawesome-free/css/all.css"> + + + <link rel="stylesheet" href="stylesheet.css"> <script src="src/client.js"></script> </head> + <body> -<nav class="navbar bg-dark navbar-dark mb-3"> - <div class="container-fluid"> - <a class="navbar-brand" href="#">User Manager</a> - </div> -</nav> + +<!--header--> +<header> + <nav class="navbar"> + <div class="container"> + <a class="navbar-brand" href="#"> + + <img src="assets/helles logo.png" width="94" height="80" alt="Logo" onclick="showPage('startseite')"/> + + </a> + <ul class="nav-links"> + <li><a onclick="showPage('reisen')">Reisen</a></li> + <li><a onclick="showPage('about-Us')">About Us</a></li> + <li><a onclick="showPage('kontakt')">Kontakt</a></li> + + </ul> + + <div class="icons"> + <i class="> fa-regular fa-heart" id="merkliste-navbar"></i> + </div> + <div class="dropdown"> + <div type="button" class="btn" data-bs-toggle="dropdown"> + <i class="fa-solid fa-circle-user"></i> + </div> + <form class="dropdown-menu p-4" id="dropdown-anmelden"> + <div class="mb-3"> + <label for="exampleDropdownFormEmail2" class="form-label">E-Mail</label> + <input type="email" class="form-control" id="exampleDropdownFormEmail2"> + </div> + <div class="mb-3"> + <label for="exampleDropdownFormPassword2" class="form-label">Passwort</label> + <input type="password" class="form-control" id="exampleDropdownFormPassword2"> + </div> + + <button type="submit" class="btn btn-primary" id="login-button" onclick="showPage('meineReisen')">Login</button> + + <a class="dropdown-item" onclick="showPage('registrieren')"><u>Registrieren</u></a> + + </form> + </div> + </div> + + </nav> +</header> + <div class="container mb-3"> <div id="messages"></div> </div> -<!-- Login area --> -<div class="container mb-3" id="login-container"> - <form id="login-form"> - <div class="row"> - <div class="col"> - <label for="login-user-username-input" class="d-none">Username</label> - <input autocomplete="off" type="text" class="form-control" placeholder="Username" id="login-user-username-input"> +<div id="startseite" class="page active"> + <!-- Login area --> + <div class="container mb-3" id="login-container"> + <form id="login-form"> + <div class="row"> + <div class="col"> + <label for="login-user-username-input" class="d-none">Username</label> + <input autocomplete="off" type="text" class="form-control" placeholder="Username" id="login-user-username-input"> + </div> + <div class="col"> + <label for="login-user-password-input" class="d-none">Password</label> + <input autocomplete="off" type="password" class="form-control" placeholder="Password" id="login-user-password-input"> + </div> + <div class="col"> + <button id="loginBtn" type="submit" class="btn btn-primary">Login</button> + </div> </div> - <div class="col"> - <label for="login-user-password-input" class="d-none">Password</label> - <input autocomplete="off" type="password" class="form-control" placeholder="Password" id="login-user-password-input"> + </form> + </div> + + <!-- logout area --> + <div class="container mb-3 d-none" id="logout-container"> + <form id="logout-form"> + <div class="row"> + <div class="col"> + <span id="current-user-username"></span> + </div> + <div class="col"> + <button id="logoutBtn" type="submit" class="btn btn-primary">Logout</button> + </div> </div> - <div class="col"> - <button id="loginBtn" type="submit" class="btn btn-primary">Login</button> + </form> + </div> + + + <div class="container mb-3 d-none" id="add-user-container"> + <form id="add-user-form"> + <div class="row mb-3"> + <div class="col"> + <label for="add-user-email" class="d-none">E-Mail</label> + <input type="text" class="form-control" id="add-user-email"> + </div> + <div class="col"> + <label for="add-user-password" class="d-none">Passwort</label> + <input type="password" class="form-control" id="add-user-password"> + </div> + <div class="col"></div> </div> - </div> - </form> -</div> + <div class="row"> + <div class="col"> + <label for="add-user-first-name" class="d-none">Vorname</label> + <input type="text" class="form-control" id="add-user-first-name"> + </div> + <div class="col"> + <label for="add-user-last-name" class="d-none">Name</label> + <input type="text" class="form-control" id="add-user-last-name"> + </div> + <div class="col"> + <button type="submit" class="btn btn-primary">Registrieren</button> + </div> + </div> + </form> + </div> -<!-- logout area --> -<div class="container mb-3 d-none" id="logout-container"> - <form id="logout-form"> - <div class="row"> - <div class="col"> - <span id="current-user-username"></span> + <div class="container d-none" id="user-list-container"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th> + ID + </th> + <th> + Vorname + </th> + <th> + Name + </th> + <th> + E-Mail + </th> + <th> + Adresse + </th> + <th> + Rolle + </th> + <th> + Actions + </th> + </tr> + </thead> + <tbody id="user-list"> + + </tbody> + </table> + </div> + + <div class="modal fade" id="edit-user-modal"> + <div class="modal-dialog"> + <div class="modal-content"> + <form id="edit-user-form"> + <div class="modal-header"> + <h5 class="modal-title">Edit User</h5> + <button type="button" class="btn-close" data-bs-dismiss="modal"></button> + </div> + <div class="modal-body"> + <input type="hidden" id="edit-user-id"> + <label for="edit-user-first-name">Vorname</label> + <input type="text" class="form-control mb-3" id="edit-user-first-name"> + <label for="edit-user-last-name">Name</label> + <input type="text" class="form-control" id="edit-user-last-name"> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button> + <button type="submit" class="btn btn-primary">Sichern</button> + </div> + </form> </div> - <div class="col"> - <button id="logoutBtn" type="submit" class="btn btn-primary">Logout</button> + </div> + </div> + <div class="hero"> + <img src="assets/heroimage.jpg" height="570" width="1668" alt="Hero-Bild" class="hero-image"/> + <div class="hero-text"> + <p>your journey begins</p> + <h1>Entdecken, Erleben, Unterstützen</h1> + <button id="hero-button" onclick="showPage('reisen')">Reise mit uns! </button> + </div> + </div> + <!-- Titeltext--> + <section class="horizon-changers-opening"> + <div class="horizon-changers-opening-container"> + <h2 class="horizon-changers-opening-title">Horizon Changers</h2> + <p class="horizon-changers-description"> + Bei uns erlebst du Reisen, die Herz und Abenteuerlust vereinen. Tauche ein in soziale Projekte, entdecke <br> neue Kulturen und spüre den Nervenkitzel unvergesslicher Outdoor-Erlebnisse. Mach deine Reise zu etwas Bedeutungsvollem! <br> Wähle ein soziales Projekt plus passende abenteuerliche Freizeitaktivitäten (die Erste ist inklusive) und <br> starte in dein Abenteuer... + </p> + <a class="horizon-changers-button" onclick="showPage('about-Us')"> Mehr erfahren</a> + </div> + </section> + + <!-- Titelbereich --> + <div class="carousel-title" id="carousel-title"> + <h2>Unsere Reisen</h2> + <p>Beginne jetzt die Reise deines Lebens</p> + </div> + + <div class="carousel-wrapper" id="beispielreisen-carrousel"> + <!-- Karussell --> + <div id="travelCarousel" class="carousel slide"> + <div class="carousel-inner"> + <!-- Erstes Element --> + <div class="carousel-item active"> + <div class="card-carrousel-reisen"> + <div class="position-relative"> + + <img src="assets/spanienprojket 2.jpg" class="card-img-beispiel" alt="Erlebe Spanien"><img/> + <span class="bestseller-badge">Bestseller</span> + <i class="favorite-icon fa-regular fa-heart"></i> + </div> + <div class="card-body"> + <h5 class="card-title-carousel">Erlebe Spanien von einer besonderen Seite - Pfoten ohne Grenzen</h5> + <p class="card-text-carousel">Hilf dabei, Straßenhunde zu retten und ihnen ein besseres Leben zu schenken! Tauche ein in die lokale Kultur, arbeite mit engagierten Tierschutzteams zusammen und genieße unvergessliche Momente an Spaniens sonnigen Küsten. Dein Einsatz macht den Unterschied!</p> + </div> + </div> + </div> + <!-- Zweites Element --> + <div class="carousel-item"> + <div class="card-carrousel-reisen"> + <div class="position-relative"> + <img src="assets/keniaprojekt.jpeg" class="card-img-beispiel" alt="Reiseziel 2"> + <span class="bestseller-badge">Neu</span> + <i class="favorite-icon fa-regular fa-heart"></i> + </div> + <div class="card-body"> + <h5 class="card-title-carousel">Mach den Unterschied - Lebensquelle in Kenia</h5> + <p class="card-text-carousel">Hilf dabei Brunnen für Trinkwasser zu bauen. Sei der Unterschied selbst.</p> + </div> + </div> + </div> + <!-- Drittes Element --> + <div class="carousel-item"> + <div class="card-carrousel-reisen"> + <div class="position-relative"> + + <img src="assets/peruprojekt (1).jpeg" class="card-img-beispiel" alt="Reiseziel 3"> + <span class="bestseller-badge">Beliebt</span> + <i class="favorite-icon fa-regular fa-heart"></i> + </div> + <div class="card-body"> + <h5 class="card-title-carousel">Lebensqualität in Peru - Lebenscomfort für jeden</h5> + <p class="card-text-carousel">Tauche ein in die Welt des Inselparadieses. Genieße traumhafte Strände, kristallklares Wasser und entspannte Stunden unter der Sonne.</p> + </div> + </div> + </div> + </div> + <div> + <button class="carousel-control-prev" type="button" data-bs-target="#travelCarousel" data-bs-slide="prev"> + <i class="fa-solid fa-chevron-left" aria-hidden="true"></i> + <span class="visually-hidden">Vorherige</span> + </button> + <button class="carousel-control-next" type="button" data-bs-target="#travelCarousel" data-bs-slide="next"> + <i class="fa-solid fa-chevron-right" aria-hidden="true"></i> + <span class="visually-hidden">Nächste</span> + </button> + </div> </div> + + </div> + + <div class="header"> + <h1 id="h1-landkarte"> Unsere Länder</h1> + <p id="subtitle-landkarte">Die Welt ist voller Abenteuer – wohin führt Deine nächste Reise?</p> + </div> + <div class="map-container"> + + <img src="assets/MAPLÄNDER.png" alt="Weltkarte" class="map" height="484" width="860"/> + <div class="pin" title="Südamerika"></div> + <div class="pin" title="Afrika"></div> + <div class="pin" title="Asien"></div> + </div> +</div> + +<div id="registrieren" class="page"> + <i class="fa-solid fa-circle-arrow-left" id="backButtonRegistrieren"></i> + + <div class="card" id="card-registrieren"> + <div class="card-body"> + + <h1>Registrieren</h1> + + <!-- Formular erstellen --> + <form> + + <input type="text" id="inputTextVorname" class="form-control-registrieren" aria-describedby="label1"> + <div id="label1" class="form-text-registrieren"> + Vorname + </div> + + <input type="text" id="inputTextName" class="form-control-registrieren" aria-describedby="label2"> + <div id="label2" class="form-text-registrieren"> + Name + </div> + + <input type="text" id="inputTextE-Mail" class="form-control-registrieren" aria-describedby="label3"> + <div id="label3" class="form-text-registrieren"> + E-Mail + </div> + + <input type="password" id="inputPasswort" class="form-control-registrieren" aria-describedby="label4"> + <div id="label4" class="form-text-registrieren"> + Passwort + </div> + + <input type="password" id="inputPasswortWiederholen" class="form-control-registrieren" aria-describedby="label5"> + <div id="label5" class="form-text-registrieren"> + Passwort wiederholen + </div> + + <button type="button" class="btn btn-primary" id="registrierenButton" onclick="showPage('meineReisen')">Registrieren</button> + + </form> </div> - </form> + </div> </div> +<div id="meineReisen" class="page"> -<div class="container mb-3 d-none" id="add-user-container"> - <form id="add-user-form"> - <div class="row mb-3"> - <div class="col"> - <label for="add-user-username" class="d-none">Username</label> - <input type="text" class="form-control" placeholder="Username" id="add-user-username"> - </div> - <div class="col"> - <label for="add-user-password" class="d-none">Password</label> - <input type="password" class="form-control" placeholder="Password" id="add-user-password"> +<div class="container"> + <aside class="sidebar"> + <i class="fa-solid fa-circle-arrow-left" id="backButtonMeineReisen"></i> + <p class="greeting">Hallo, Annika!</p> + <nav class="menu"> + <ul> + <li><a href="#">Meine Reisen</a></li> + <li><a onclick="showPage('profil')">Mein Profil</a></li> + <li><a href="#">Merkliste</a></li> + <li><a href="#">Meine Supportanfragen</a></li> + <li><a href="#">Reisebericht schreiben</a></li> + <li><a href="#">Abmelden</a></li> + </ul> + </nav> + </aside> + <main class="content"> + <section> + <h2>Meine bevorstehenden Reisen</h2> + <div class="trip-card"> + <img src="assets/bevorstehendeReisen.jpg" height="890" width="736" alt="Projekt Bildung für Frauen"/> + <div class="trip-info"> + <h3>Projekt Bildungslicht für Frauen (Indien)</h3> + <button class="details-button">Details</button> + </div> </div> - <div class="col"></div> - </div> - <div class="row"> - <div class="col"> - <label for="add-user-given-name" class="d-none">Given Name</label> - <input type="text" class="form-control" placeholder="Given Name" id="add-user-given-name"> + </section> + <section> + <h2>Meine angetretenen Reisen</h2> + <div class="trip-card"> + <img src="assets/angetreteneReisen.jpg" height="1000" width="667" alt="Projekt Bausteine der Gesundheit"/> + <div class="trip-info"> + <h3>Projekt Bausteine der Gesundheit (Peru)</h3> + <button class="details-button">Details</button> + <button class="report-button">Reisebericht schreiben</button> + </div> </div> - <div class="col"> - <label for="add-user-family-name" class="d-none">Family Name</label> - <input type="text" class="form-control" placeholder="Family Name" id="add-user-family-name"> + </section> + </main> +</div> +</div> + +<!--Profil--> + +<div id="profil" class="page"> + <div class="container"> + <aside class="sidebar"> + <i class="fa-solid fa-circle-arrow-left" id="backButtonProfil"></i> + <p class="greeting">Hallo, Annika!</p> + <nav class="menu"> + <ul> + <li><a href="#">Meine Reisen</a></li> + <li><a href="#">Mein Profil</a></li> + <li><a href="#">Merkliste</a></li> + <li><a href="#">Meine Supportanfragen</a></li> + <li><a href="#">Reisebericht schreiben</a></li> + <li><a href="#">Abmelden</a></li> + </ul> + </nav> + </aside> +</div> + <div class="profil-container"> + <h1>Profil</h1> + <div class="profil-card"> + <div class="section"> + <h2>Persönliche Daten</h2> + <div class="row"> + <span>Vorname</span> + <span>Annika</span> + </div> + <div class="row"> + <span>Name</span> + <span>Kastner</span> + </div> + <div class="row"> + <span>Email Adresse</span> + <span>annika.k@outlook.com</span> + </div> + <div class="row"> + <span>Passwort</span> + <span>************</span> + </div> </div> - <div class="col"> - <button type="submit" class="btn btn-primary">Add User</button> + <div class="section"> + <h2>Adressdaten</h2> + <div class="row"> + <span>Straße</span> + <span>Musterstraße</span> + </div> + <div class="row"> + <span>Hausnummer</span> + <span>1</span> + </div> + <div class="row"> + <span>Postleitzahl</span> + <span>68165</span> + </div> + <div class="row"> + <span>Stadt/Ort</span> + <span>Mannheim</span> + </div> + <div class="row"> + <span>Bundesland</span> + <span>Baden-Württemberg</span> + </div> + <div class="row"> + <span>Land</span> + <span>Deutschland</span> + </div> </div> </div> - </form> + </div> </div> -<div class="container d-none" id="user-list-container"> - <table class="table table-striped table-hover"> - <thead> - <tr> - <th> - ID - </th> - <th> - Given Name - </th> - <th> - Family Name - </th> - <th> - Date - </th> - <th> - Actions - </th> - </tr> - </thead> - <tbody id="user-list"> - - </tbody> - </table> -</div> +<footer class="footer"> + <div class="footer-container"> + <div class="footer-logo"> -<div class="modal fade" id="edit-user-modal"> - <div class="modal-dialog"> - <div class="modal-content"> - <form id="edit-user-form"> - <div class="modal-header"> - <h5 class="modal-title">Edit User</h5> - <button type="button" class="btn-close" data-bs-dismiss="modal"></button> - </div> - <div class="modal-body"> - <input type="hidden" id="edit-user-id"> - <label for="edit-user-given-name">Given Name</label> - <input type="text" class="form-control mb-3" placeholder="Max" id="edit-user-given-name"> - <label for="edit-user-family-name">Family Name</label> - <input type="text" class="form-control" placeholder="Mustermann" id="edit-user-family-name"> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> - <button type="submit" class="btn btn-primary">Save</button> - </div> - </form> + <img src="assets/HORIZON CHANGERS.PNG" alt="Horizon Changers Logo"/> + </div> + <div class="footer-section"> + <h4>Nützliche Informationen</h4> + <ul> + <li> <a href="#">FAQ</a> + <a href="#">Impressum</a> + </li> + </ul> + </div> + <div class="footer-section"> + <h4>Unsere Zahlungsmöglichkeiten</h4> + <div class="payment-icons"> + <img src="https://upload.wikimedia.org/wikipedia/commons/a/a4/Paypal_2014_logo.png" alt="PayPal"> + <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Klarna_Payment_Badge.svg/1280px-Klarna_Payment_Badge.svg.png" alt="Klarna"> + <img src="https://e7.pngegg.com/pngimages/530/165/png-clipart-logo-mastercard-pentagram-flat-design-brand-mastercard-text-trademark.png" alt="Mastercard"> + <img src="https://img.icons8.com/?size=512&id=13608&format=png" alt="Visa"> + </div> + </div> + <div class="footer-section"> + <h4>Mehr Inspirationen</h4> + <div class="social-icons"> + <a href="https://www.instagram.com" target="_blank"><i class="fab fa-instagram"></i></a> + <a href="https://www.facebook.com" target="_blank"><i class="fa-brands fa-facebook"></i></a> + <a href="https://www.youtube.com" target="_blank"><i class="fab fa-youtube"></i></a> + </div> </div> </div> -</div> + <div class="footer-bottom"> + <p>Copyright © 2025 Horizon Changers GmbH | Alle Rechte vorbehalten</p> + </div> +</footer> + + </body> </html> diff --git a/userman_all/client/package-lock.json b/userman_all/client/package-lock.json index f5566e2ceb7a8fedfce47584d8e98d3957a9dfb7..c4c245ed8fa541ebfa3e333e515b56e07b12679a 100644 --- a/userman_all/client/package-lock.json +++ b/userman_all/client/package-lock.json @@ -8,9 +8,12 @@ "@fortawesome/fontawesome-free": "^6.6.0", "@types/bootstrap": "^5.2.10", "@types/express": "^5.0.0", + "@types/express-session": "^1.18.1", "bootstrap": "^5.3.3", "express": "^4.21.2", - "fortawesome": "^0.0.1-security" + "express-session": "^1.18.1", + "fortawesome": "^0.0.1-security", + "mysql2": "^3.12.0" } }, "node_modules/@fortawesome/fontawesome-free": { @@ -62,6 +65,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -80,6 +84,14 @@ "@types/send": "*" } }, + "node_modules/@types/express-session": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.1.tgz", + "integrity": "sha512-S6TkD/lljxDlQ2u/4A70luD8/ZxZcrU5pQwI1rVXCiaVIywoFgbA+PIUNDjPhQpPdK0dGleLtYc/y7XWBfclBg==", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -144,6 +156,14 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", @@ -181,6 +201,7 @@ "url": "https://opencollective.com/bootstrap" } ], + "license": "MIT", "peerDependencies": { "@popperjs/core": "^2.11.8" } @@ -260,6 +281,14 @@ "ms": "2.0.0" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -347,6 +376,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -388,6 +418,37 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-session": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz", + "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express-session/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + }, "node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", @@ -434,6 +495,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-intrinsic": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", @@ -541,6 +610,38 @@ "node": ">= 0.10" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/lru.min": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.1.tgz", + "integrity": "sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -608,6 +709,48 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/mysql2": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.12.0.tgz", + "integrity": "sha512-C8fWhVysZoH63tJbX8d10IAoYCyXy4fdRFz2Ihrt9jtPILYynFEKUUzpp1U7qxzDc3tMbotvaBH+sl6bFnGZiw==", + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.1", + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru.min": "^1.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -638,6 +781,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -677,6 +828,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -759,6 +918,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -846,6 +1010,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -874,6 +1046,17 @@ "node": ">= 0.6" } }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", diff --git a/userman_all/client/package.json b/userman_all/client/package.json index 83205893934d3cc506012d1edfb795e363e68197..a75fffab4f0626531b80f163348aa9f5c771c648 100644 --- a/userman_all/client/package.json +++ b/userman_all/client/package.json @@ -3,8 +3,11 @@ "@fortawesome/fontawesome-free": "^6.6.0", "@types/bootstrap": "^5.2.10", "@types/express": "^5.0.0", + "@types/express-session": "^1.18.1", "bootstrap": "^5.3.3", "express": "^4.21.2", - "fortawesome": "^0.0.1-security" + "express-session": "^1.18.1", + "fortawesome": "^0.0.1-security", + "mysql2": "^3.12.0" } } diff --git a/userman_all/client/src/client.ts b/userman_all/client/src/client.ts index 1003c6b483a1d15207038652f8cfe5b2703518ce..6e7a24e421101fc3d7076a317a21193bae776b75 100644 --- a/userman_all/client/src/client.ts +++ b/userman_all/client/src/client.ts @@ -1,10 +1,49 @@ +// Funktion, die die aktive Seite anzeigt und alle anderen ausblendet +function showPage(pageId: string): void { + // Alle Seiten ausblenden + const pages: NodeListOf<HTMLDivElement> = document.querySelectorAll('.page'); + pages.forEach((page: HTMLDivElement) => { + page.classList.remove('active'); + }); + + // Die ausgewählte Seite anzeigen + const activePage: HTMLElement | null = document.getElementById(pageId); + if (activePage) { + activePage.classList.add('active'); + } else { + console.error(`Seite mit der ID "${pageId}" wurde nicht gefunden.`); + } +} + +// Event-Listener für die Initialisierung beim Laden der Seite +document.addEventListener('DOMContentLoaded', () => { + showPage('reisen'); // Standardmäßig die Seite "Reisen" anzeigen +}); + interface User { - id: number; - givenName: string; - familyName: string; - creationTime: string; + user_id: number; + firstName: string; + lastName: string; + eMail: string; + adress: string; + role: string; } +// Funktion, die die aktive Seite anzeigt und alle anderen ausblendet +function showPage(pageId: string): void { + // Alle Seiten ausblenden + const pages = document.querySelectorAll<HTMLElement>('.page'); // Elemente mit der Klasse 'page' auswählen + pages.forEach(page => { + page.classList.remove('active'); // Klasse 'active' entfernen + }); + // Die ausgewählte Seite anzeigen + const activePage = document.getElementById(pageId); // Das Element mit der gegebenen ID auswählen + if (activePage) { + activePage.classList.add('active'); // Klasse 'active' hinzufügen + } else { + console.error(`Seite mit der ID "${pageId}" wurde nicht gefunden.`); + } +} let modalEl: bootstrap.Modal document.addEventListener("DOMContentLoaded", (): void => { @@ -16,18 +55,20 @@ document.addEventListener("DOMContentLoaded", (): void => { //--- Form Eventhandlers ------------------------------------------------------- document.getElementById("add-user-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); - const usernameEl: HTMLInputElement = document.getElementById("add-user-username") as HTMLInputElement; + const emailEl: HTMLInputElement = document.getElementById("add-user-email") as HTMLInputElement; const passwordEl: HTMLInputElement = document.getElementById("add-user-password") as HTMLInputElement; - const givenNameEl: HTMLInputElement = document.getElementById("add-user-given-name") as HTMLInputElement; - const familyNameEl: HTMLInputElement = document.getElementById("add-user-family-name") as HTMLInputElement; - const username: string = usernameEl.value; + const firstNameEl: HTMLInputElement = document.getElementById("add-user-first-name") as HTMLInputElement; + const lastNameEl: HTMLInputElement = document.getElementById("add-user-last-name") as HTMLInputElement; + + const email: string = emailEl.value; const password: string = passwordEl.value; - const givenName: string = givenNameEl.value; - const familyName: string = familyNameEl.value; + const firstName: string = firstNameEl.value; + const lastName: string = lastNameEl.value; + // Check, if any given value is empty. // Don't allow creation of users without given name or family name. - if (givenName.length == 0 || familyName.length == 0 || username.length == 0 || password.length == 0) { + if (firstName.length == 0 || lastName.length == 0 || email.length == 0 || password.length == 0) { addMessage("The given name or family name is empty."); return; } @@ -38,7 +79,7 @@ document.addEventListener("DOMContentLoaded", (): void => { headers: { "Content-type": "application/json" }, - body: JSON.stringify({ givenName, familyName, username, password }) + body: JSON.stringify({ firstName, lastName, email, password}) }); const data: any = await res.json(); @@ -48,29 +89,29 @@ document.addEventListener("DOMContentLoaded", (): void => { readUsers(); // Clear the input fields - usernameEl.value = ""; + emailEl.value = ""; passwordEl.value = ""; - givenNameEl.value = ""; - familyNameEl.value = ""; + firstNameEl.value = ""; + lastNameEl.value = ""; }); document.getElementById("edit-user-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); let idEl: HTMLInputElement = document.getElementById("edit-user-id") as HTMLInputElement; - let givenNameEl: HTMLInputElement = document.getElementById("edit-user-given-name") as HTMLInputElement; - let familyNameEl: HTMLInputElement = document.getElementById("edit-user-family-name") as HTMLInputElement; + let firstNameEl: HTMLInputElement = document.getElementById("edit-user-first-name") as HTMLInputElement; + let lastNameEl: HTMLInputElement = document.getElementById("edit-user-last-name") as HTMLInputElement; // Read the user's id from the hidden field. let userId: number = parseInt(idEl.value); - let givenName: string = givenNameEl.value; - let familyName: string = familyNameEl.value; + let firstName: string = firstNameEl.value; + let lastName: string = lastNameEl.value; const res: Response = await fetch('/user/' + userId, { method: 'put', headers: { "Content-type": "application/json" }, - body: JSON.stringify({ givenName, familyName }), + body: JSON.stringify({ firstName, lastName }), }); const data: any = await res.json(); addMessage(data.message); @@ -84,10 +125,10 @@ document.addEventListener("DOMContentLoaded", (): void => { document.getElementById("login-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); - const usernameInput: HTMLInputElement = document.getElementById('login-user-username-input') as HTMLInputElement; + const emailInput: HTMLInputElement = document.getElementById('login-user-email-input') as HTMLInputElement; const passwordInput: HTMLInputElement = document.getElementById('login-user-password-input') as HTMLInputElement; - const username: string = usernameInput.value; + const email: string = emailInput.value; const password: string = passwordInput.value; const response: Response = await fetch('http://localhost:8080/login', { @@ -95,7 +136,7 @@ document.addEventListener("DOMContentLoaded", (): void => { headers: { "Content-type": "application/json" }, - body: JSON.stringify({username, password}), + body: JSON.stringify({email, password}), } ); @@ -151,8 +192,8 @@ async function readUsers(): Promise<void> { * Displays the logged in username */ function showLoggedInStatus(user: User): void { - const username: HTMLElement = document.getElementById('current-user-username')!; - username.innerHTML = `Hello ${user.givenName}`; + const email: HTMLElement = document.getElementById('current-user-email')!; + email.innerHTML = `Hello ${user.firstName}`; const addUserForm: HTMLElement = document.getElementById('add-user-container')!; addUserForm.classList.remove("d-none"); // show content area @@ -176,8 +217,8 @@ function showLoggedInStatus(user: User): void { * Clears user list, shows login form, hides logout form- */ function showLoggedOutStatus(): void { - const username: HTMLElement = document.getElementById('current-user-username')!; - username.innerHTML = ``; + const email: HTMLElement = document.getElementById('current-user-email')!; + email.innerHTML = ``; const addUserForm: HTMLElement = document.getElementById('add-user-container')!; addUserForm.classList.add("d-none"); // hide content area @@ -210,20 +251,28 @@ function renderList(userList: User[]): void { let tr: HTMLTableRowElement = document.createElement("tr"); // ID cell - let tdId: HTMLTableCellElement = document.createElement("td"); - tdId.textContent = user.id.toString(); + let tdUser_id: HTMLTableCellElement = document.createElement("td"); + tdUser_id.textContent = user.user_id.toString(); // Given name cell - let tdGivenName: HTMLTableCellElement = document.createElement("td"); - tdGivenName.textContent = user.givenName; + let tdFirstName: HTMLTableCellElement = document.createElement("td"); + tdFirstName.textContent = user.firstName; // Family name cell - let tdFamilyName: HTMLTableCellElement = document.createElement("td"); - tdFamilyName.textContent = user.familyName; + let tdLastName: HTMLTableCellElement = document.createElement("td"); + tdLastName.textContent = user.lastName; - // Creation date cell - let tdDate: HTMLTableCellElement = document.createElement("td"); - tdDate.textContent = user.creationTime; + // email cell + let tdEmail: HTMLTableCellElement = document.createElement("td"); + tdEmail.textContent = user.eMail; + + // adress cell + let tdAdress: HTMLTableCellElement = document.createElement("td"); + tdAdress.textContent = user.adress; + + // role cell + let tdRole: HTMLTableCellElement = document.createElement("td"); + tdRole.textContent = user.role; // Buttons cell let tdButtons: HTMLTableCellElement = document.createElement("td"); @@ -232,7 +281,7 @@ function renderList(userList: User[]): void { let deleteButton: HTMLButtonElement = document.createElement("button"); deleteButton.className = "btn btn-danger"; deleteButton.addEventListener("click", async () => { - const res: Response = await fetch('/user/' + user.id, { + const res: Response = await fetch('/user/' + user.user_id, { method: 'DELETE' }); const data: any = await res.json(); @@ -261,7 +310,7 @@ function renderList(userList: User[]): void { tdButtons.append(deleteButton, editButton); // Add the cells to the table row - tr.append(tdId, tdGivenName, tdFamilyName, tdDate, tdButtons); + tr.append(tdUser_id, tdFirstName, tdLastName, tdEmail,tdAdress, tdRole, tdButtons); // Add the table row to the table userListEl.append(tr); @@ -273,16 +322,16 @@ function renderList(userList: User[]): void { * 2) Opens the modal window. */ function showEditModal(user: User): void { - let idEl: HTMLInputElement = document.getElementById("edit-user-id") as HTMLInputElement; - let givenNameEl: HTMLInputElement = document.getElementById("edit-user-given-name") as HTMLInputElement; - let familyNameEl: HTMLInputElement = document.getElementById("edit-user-family-name") as HTMLInputElement; + let user_idEl: HTMLInputElement = document.getElementById("edit-user-user_id") as HTMLInputElement; + let firstNameEl: HTMLInputElement = document.getElementById("edit-user-first-name") as HTMLInputElement; + let lastNameEl: HTMLInputElement = document.getElementById("edit-user-last-name") as HTMLInputElement; // Write the user's id into the hidden field. - idEl.value = user.id.toString(); + user_idEl.value = user.user_id.toString(); // Write the user's data into the text fields. - givenNameEl.value = user.givenName; - familyNameEl.value = user.familyName; + firstNameEl.value = user.firstName; + lastNameEl.value = user.lastName; // Show the modal window. modalEl.show(); @@ -321,3 +370,4 @@ function addMessage(message: string): void { alert.close(); }, 5000); } + diff --git a/userman_all/client/stylesheet.css b/userman_all/client/stylesheet.css new file mode 100644 index 0000000000000000000000000000000000000000..8f5d92bd84d4e228a064286567fc1a61693fd400 --- /dev/null +++ b/userman_all/client/stylesheet.css @@ -0,0 +1,746 @@ +body { + margin: 0; + font-family: "DM Sans", sans-serif; + color: #03355C; + justify-content: center; + align-items: center; + background-color: #ffffff; + +header { + background-color: #ffffff; + color: #ffffff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Optional: Schatten für Abgrenzung */ +} + +.nav { + height: 100px; + display: flex; + justify-content: space-between; + align-items: center; + justify-items: center; + padding: 20px 10%; + +} + +.logo img { + height: 50px; + align-items: center; +} + +.nav-links { + list-style: none; + display: flex; + gap: 100px; + margin: 0; + padding: 0; + align-items: center; + box-sizing: border-box; + color: #03355C; +} + +.nav-links li a { + text-decoration: none; + color: #03355c; + font-size: 26px; + font-weight: 500; + align-items: center; +} + +.nav-links li a:hover { + color: #03355c; /* Hover-Farbe */ + opacity: 0.5; +} + +#merkliste-navbar { + font-size:40px; + color: #03355c; + +} +#merkliste-navbar:hover { + color: #03355c; /* Hover-Farbe */ + opacity: 0.5; +} + +.fa-circle-user { + margin-right: 30px; + color: #03355c; + font-size: 40px; +} +.fa-circle-user:hover { + color: #03355c; + opacity: 0.5; + border: none; +} + +#dropdown-anmelden { + border: none; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Optional: Schatten für Abgrenzung */ + color: #03355c; +} + +#login-button { + background-color: #fb7300; + color: #ffffff; + border: none; + border-radius: 50px; + margin-left: 10px; + +} +#login-button:hover { + background-color: #e36c20; + color: #ffffff; +} +#exampleDropdownFormEmail2 { + border-color: #03355c; + border-radius: 50px; +} +#exampleDropdownFormPassword2 { + border-color: #03355c; + border-radius: 50px; +} + +.footer { + background-color: #03355C; + color: #fff; + padding: 20px 10%; + font-size: 20px; +} + +.footer-container { + display: flex; + justify-content: space-between; + gap: 20px; +} + +.footer-logo img { + max-width: 150px; +} + + +.footer-section h4 { + margin-bottom: 20px; +} + + + +.footer-section ul { + list-style: none; + font-size: 20px; + padding: 0; + margin: 0; +} + +.footer-section ul li a { + color: #fff; + margin: 20px; +} + +.footer-section ul li a:hover { + opacity: 0.5; +} + +.payment-icons img { + max-height: 40px; + margin-right: 20px; +} + +.social-icons a { + color: #fff; + font-size: 45px; + margin-right: 20px; +} + +.social-icons a:hover { + opacity: 0.5; +} + +.footer-bottom { + text-align: center; + margin-top: 20px; + font-size: 0.9em; + border-top: 1px solid #fff; + padding-top: 10px; +} + +/* Überschrift mit eigener Schriftart */ +#h1-landkarte { + font-family: Cy Grotesk Wide; + color: #03355C; + font-size: 34px; + margin: 0; + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ + padding-top: 200px; +} + +/* Absatztext mit Standardschriftart */ +#subtitle-landkarte { + font-family: 'DM Sans', sans-serif; /* Schriftart für den Absatztext */ + color: #03355C; + font-size: 20px; /* Schriftgröße */ + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ +} + + + +/* Kartensektion */ +.map-container { + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ +} + +.map { + max-width: 100%; /* Karte passt sich der Bildschirmbreite an */ + height: auto; +} + + +#beispielreisen-carrousel { + display: flex; + justify-content: center; + align-items: center; +} + +.card-carrousel-reisen .position-relative { + object-position: center; /* Zentriert das Bild innerhalb des Containers */ + display: flex; + flex-direction: column; /* Für vertikale Inhalte */ + gap: 10px; +} + +.card-img-beispiel { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + fill-rule: evenodd; + width: 600px; + height: 200px; +} + +.bestseller-badge { + position: absolute; + top: 10px; + left: 10px; + color: #e36c20; + background: #ffffff; + padding: 5px 10px; + border-radius: 5px; +} + +.favorite-icon { + position: absolute; + top: 10px; + right: 10px; + width: 40px; + height: 40px; + color: #03355C; +} + + + .card-carrousel-reisen { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin: 20px auto; /* Automatische Zentrierung */ + width: 600px; /* Maximale Breite der Karte */ + height: 450px; + box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.2); /* Schatten */ + border-radius: 10px; /* Abgerundete Ecken */ + overflow: hidden; /* Damit der Inhalt innerhalb der abgerundeten Kanten bleibt */ + } + .card-body { + text-align: center; + padding: 15px; + } + + #carousel-title { + padding: 20px 10px; + border-radius: 15px; + margin-bottom: 20px; + +} + +#carousel-title h2 { + font-family: Cy Grotesk Wide; + font-size: 34px; + margin: 0; + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ + padding-top: 200px; +} + +#carousel-title p { + font-family: "DM Sans", sans-serif; + margin: 0; + font-size: 26px; + color: #03355c; + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ +} + +.card-title-carousel { + font-family: 'DM Sans', sans-serif; + color: #03355C; + text-align: start; +} +.card-text-carousel { + font-family: 'DM Sans', sans-serif; + color: #03355C; + text-align: start; +} +.carousel-control-prev, +.carousel-control-next { + color: #03355c; +} +/* Positioniere die Pfeile außerhalb des Karussells */ +.carousel-control-prev, +.carousel-control-next { + top: 50%; + transform: translateY(-50%); +} + +/* Verschiebe die Pfeile nach außen */ +.carousel-control-prev { + left: -70px +} + +.carousel-control-next { + right: -70px; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + background-color: #03355c; +} + +.carousel-control-next-icon { + width: 40px; + height: 40px; + border-radius: 50%; + color: #03355C; +} + +.fa-chevron-right { + font-size: 40px; + color: #03355C; +} + +/* Pfeil links (Karussell) */ +.fa-chevron-left { + font-size: 40px; + color: #03355C; + +} + + /*SPA*/ + .page { + display: none; + } + .active { + display: block; + +#backButton { + position: absolute; + top: 20px; + left: 20px; + font-size: 30px; + color: #03355C; /* Dunkelblau passend zur Überschrift */ + cursor: pointer; +} + +#card-registrieren { + background-color: #FCF3E4; /* Heller Beige-Hintergrund */ + border-radius: 10px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + padding: 20px; + width: 701px; /* Breite des Formulars */ + height: 775px; + text-align: center; + +} + +h1 { + font-family: Cy Grotesk Wide; + font-size: 34px; + color: #03355C; /* Dunkelblau für die Überschrift */ + margin-bottom: 20px; +} + +.form-control-registrieren { + width: 525px; + height: 57px; + padding-left: 15px; + margin-bottom: 10px; + border: 1px solid #03355C; /* dunkelblauer Rahmen */ + border-radius: 30px; /* Runde Ecken für Eingabefelder */ + box-sizing: border-box; + font-family: "DM Sans", sans-serif; + font-size: 20px; + color: #03355C; +} + +.form-text-registrieren { + text-align: left; + font-size: 20px; + margin-top: 5px; + margin-bottom: 15px; + color: #03355C; /* Dunkelblauer Text */ + padding-left: 90px; /* Gleiche Einrückung wie das Eingabefeld */ +} + + +#registrierenButton { + background-color: #FB7300; /* Orange Farbe */ + font-family: "DM Sans", sans-serif, bold; + font-size: 26px; + color: white; + border: none; + border-radius: 50px; + padding: 10px 20px; + cursor: pointer; + width: 242px; + height: 55px; + margin: 30px; +} + +#registrierenButton:hover { + background-color: #e36c20; /* Etwas dunkleres Orange bei Hover */ +} + + /*Meine Reisen*/ + +/* Sidebar */ +.sidebar { + background-color: #f1f4f9; + width: 322px; + padding: 20px; + display: flex; + flex-direction: column; + align-items: flex-start; + box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); +} + +.back-button { + background: none; + border: none; + font-size: 30px; + color: #03355C; + cursor: pointer; + margin-bottom: 20px; +} + +.greeting { + font-family: 'DM Sans', sans-serif; + color: #03355C; + font-size: 26px; + margin-bottom: 40px; +} + +.menu ul { + list-style: none; + padding: 0; + width: 100%; +} + +.menu li { + margin-bottom: 15px; +} + +.menu a { + font-family: 'DM Sans', sans-serif; + text-decoration: none; + color: #03355C; + font-size: 20px; +} + + /* Main Content */ +.content { + flex-grow: 1; + padding: 20px; + background-color: #ffffff; + overflow-y: auto; +} + +h2 { + font-family: 'Cy Grotesk Wide'; + font-size: 34px; + color: #03355C; + margin-bottom: 20px; +} + +.trip-card { + width: 662px; + height: 163px; + display: flex; + align-items: center; + background-color: #FCF3E4; + border-radius: 30px; + padding: 15px; + margin-bottom: 20px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.trip-card img { + width: 246px; + height: 163px; + border-radius: 30px; + margin-right: 15px; + object-fit: cover; +} + +.trip-info { + font-family: 'DM Sans', sans-serif; + color: #03355C; + font-size: 20px; + flex-grow: 1; +} + +h3 { + font-family: 'dM Sans', sans-serif; + font-size: 34px; + margin: 0; + color: #03355C; +} + +.details-button, .report-button { + margin-top: 10px; + padding: 10px 15px; + font-family: 'dm sans', sans-serif, bold; + font-size: 20px; + border: none; + border-radius: 50px; + cursor: pointer; +} + +.details-button { + background-color: #FB7300; + color: #fff; +} + +.report-button { + background-color: #FCF3E4; + color: #03355C; + border: 1px solid #FB7300; + margin-left: 10px; +} + +/*Profil*/ + +/* Sidebar */ +.sidebar { + background-color: #f1f4f9; + width: 322px; + padding: 20px; + display: flex; + flex-direction: column; + align-items: flex-start; + box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); +} + +.back-button { + background: none; + border: none; + font-size: 30px; + color: #03355C; + cursor: pointer; + margin-bottom: 20px; +} + +.greeting { + font-family: 'DM Sans', sans-serif; + color: #03355C; + font-size: 26px; + margin-bottom: 40px; +} + +.menu ul { + list-style: none; + padding: 0; + width: 100%; +} + +.menu li { + margin-bottom: 15px; +} + +.menu a { + font-family: 'DM Sans', sans-serif; + text-decoration: none; + color: #03355C; + font-size: 20px; +} + +/*Main Body*/ + + .profil-container { + max-width: 600px; + margin: 50px auto; + padding: 20px; + } + + h1 { + text-align: center; + font-family: 'Cy Grotesk Wide'; + font-size: 34px; + color: #03355C; + } + + .profil-card { + width: 644px; + height: auto; /* Automatische Höhe für dynamische Inhalte */ + background-color: #FCF3E4; + padding: 20px; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + .section { + margin-bottom: 20px; + } + + h2 { + margin-bottom: 10px; + font-family: 'DM Sans', sans-serif; + font-weight: bold; + color: #03355C; + font-size: 26px; + } + + .row { + display: flex; + justify-content: space-between; /* Platz zwischen den Spans */ + align-items: center; /* Zentriere den Text vertikal */ + padding: 5px 0; + } + + .row span { + display: inline-block; /* Stellt sicher, dass Spans korrekt dargestellt werden */ + white-space: nowrap; /* Verhindert, dass Inhalte umbrechen */ + } + + .row span:first-child { + font-family: 'DM Sans', sans-serif; + font-size: 20px; + color: #03355C; + flex: 1; /* Erlaubt dynamische Breite */ + } + + .row span:last-child { + font-family: 'DM Sans', sans-serif; + font-size: 20px; + color: #03355C; + text-align: right; /* Richtet den Text am rechten Rand aus */ + flex: 1; /* Erlaubt dynamische Breite */ + } + + .row:last-child { + border-bottom: none; + } + + .hero { + position: relative; + text-align: right; + color: white; + padding-bottom: 200px; + } + + .hero-image { + width: 100%; + height: auto; + } + + .hero-text { + color: #03355C; + position: absolute; + top: 30%; + left: 80%; + transform: translate(-50%, -50%); + white-space: nowrap; /* Verhindert Zeilenumbrüche */ + } + + #hero-button { + background-color: #fb7300; + color: #ffffff; + border: none; + border-radius: 50px; + margin-left: 10px; + cursor: pointer; + + } + + #hero-button:hover { + background-color: #e36c20 /* Dunkleres Orange bei Hover */ + } + +/* Horizon Changers Section */ +.horizon-changers-opening { + background-color: #f5f9ff; /* Heller Hintergrund */ + padding: 60px 20px; /* Abstand innen */ + text-align: center; /* Zentriert den Text */ +} + +.horizon-changers-opening-container { + max-width: 900px; /* Maximale Breite für den Textbereich */ + margin: 0 auto; /* Zentriert den Container */ + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + +} + +.horizon-changers-opening-title { + font-family: Cy Grotesk Wide; + font-size: 43px; /* Schriftgröße */ + color: #03355c; /* Dunkelblau */ + margin-bottom: 20px; /* Abstand nach unten */ + margin-top: 60px; + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ + +} + +.horizon-changers-description { + font-family: "DM Sans", sans-serif; /* Standardschriftart */ + font-size: 1.2rem; /* Schriftgröße für den Absatz */ + color: #03355c; /* Dunkelblau */ + margin-bottom: 40px; /* Abstand nach unten */ + line-height: 1.6; /* Zeilenhöhe für Lesbarkeit */ + display: flex; + justify-content: center; /* Zentriert horizontal */ + align-items: center; /* Zentriert vertikal */ + text-align: center; + white-space: nowrap; /* Verhindert Zeilenumbrüche */ +} + +.horizon-changers-button { + background-color: #fb7300; + color: #ffffff; + font-family: "DM Sans", sans-serif; /* Button-Schriftart */ + font-size: 26px; /* Schriftgröße */ + padding: 12px 25px; /* Innenabstand */ + border: none; /* Keine Umrandung */ + border-radius: 30px; /* Runde Kanten */ + cursor: pointer; /* Zeigt Klickbarkeit an */ + align-items: center; +} + +.horizon-changers-button:hover { + background-color: #e36c20 +} /* Dunkleres Orange bei Hover */ + +.page { + display: none; +} + +.active { + display: block; +} +} \ No newline at end of file diff --git a/userman_all/server/db/init.sql b/userman_all/server/db/init.sql index cb8db01d6fc14ba45341826ec68c06b5602403ef..6b4a966b5cd86f6afee1f0669cbb3f17e984c9d9 100644 --- a/userman_all/server/db/init.sql +++ b/userman_all/server/db/init.sql @@ -1,14 +1,14 @@ -CREATE DATABASE IF NOT EXISTS `userman` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -USE `userman`; +CREATE DATABASE IF NOT EXISTS `horizon_changers` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; +USE `horizon_changers`; -CREATE TABLE `userlist` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(255) NOT NULL, +CREATE TABLE `user` ( + `user_id` int(11) NOT NULL AUTO_INCREMENT, + `eMail` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, - `givenName` varchar(255) NOT NULL, - `familyName` varchar(255) NOT NULL, - `creationTime` varchar(32) NOT NULL, - PRIMARY KEY (id) + `firstName` varchar(255) NOT NULL, + `lastName` varchar(255) NOT NULL, + `adress` varchar(32) NOT NULL, + PRIMARY KEY (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; @@ -17,5 +17,5 @@ Die Logindaten für den Nutzer lauten: Username: admin Password: admin */ -INSERT INTO `userlist` (`id`, `username`, `password`, `givenName`, `familyName`, `creationTime`) VALUES -(1, 'admin', 'c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec', 'Peter', 'Kneisel', '24.09.2022, 12:24:59'); +INSERT INTO `user` (`user_id`, `eMail`, `password`, `firstName`, `lastName`, `adress`) VALUES +(2, 'bob.hase@outlook.com', '09876543', 'Bob', 'Hase', 'Musterstraße 9, 12345 Musterstadt'); diff --git a/userman_all/server/package-lock.json b/userman_all/server/package-lock.json index c2fdcd1fb99c2152aab355ec2f716a82d1fd135e..b404ec07045d143cbaa84b3aef8831eb8df48217 100644 --- a/userman_all/server/package-lock.json +++ b/userman_all/server/package-lock.json @@ -493,6 +493,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -1655,6 +1656,7 @@ "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -2588,6 +2590,7 @@ "version": "3.12.0", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.12.0.tgz", "integrity": "sha512-C8fWhVysZoH63tJbX8d10IAoYCyXy4fdRFz2Ihrt9jtPILYynFEKUUzpp1U7qxzDc3tMbotvaBH+sl6bFnGZiw==", + "license": "MIT", "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", diff --git a/userman_all/server/src/server.ts b/userman_all/server/src/server.ts index 97999af95c88449ea1a28f3de8ef8a771e45afc8..f45bc022654eca85be28aff16b668a5f9c68aeeb 100644 --- a/userman_all/server/src/server.ts +++ b/userman_all/server/src/server.ts @@ -17,7 +17,7 @@ async function connectDatabase() { host: "localhost", user: "root", password: "toortoor", - database: "userman" + database: "horizon_changers" }); await database.connect(); console.log("Database is connected"); @@ -62,10 +62,12 @@ declare module 'express-session' { * Datastructure * *****************************************************************************/ export interface User { - id: number; - givenName: string; - familyName: string; - creationTime: string; + user_id: number; + firstName: string; + lastName: string; + adress: string; + role: string; + eMail: string; } /** @@ -174,15 +176,17 @@ app.get('/login', isLoggedIn, (req: Request, res: Response): void => { */ app.post('/login', async (req: Request, res: Response): Promise<void> => { // Read data from request - const username: string = req.body.username; + const eMail: string = req.body.eMail; const password: string = req.body.password; // Create database query and data const data: [string, string] = [ - username, - crypto.createHash("sha512").update(password).digest('hex') + eMail, + password + //crypto.createHash("sha512").update(password).digest('hex') ]; - const query: string = 'SELECT * FROM userlist WHERE username = ? AND password = ?;'; + console.log(data) + const query: string = 'SELECT * FROM user WHERE eMail = ? AND password = ?;'; try { const [rows] = await database.query<RowDataPacket[]>(query, data); @@ -190,10 +194,13 @@ app.post('/login', async (req: Request, res: Response): Promise<void> => { if (rows.length === 1) { // Login data is correct, user is logged in const user: User = { - id: rows[0].id, - givenName: rows[0].givenName, - familyName: rows[0].familyName, - creationTime: rows[0].time + user_id: rows[0].user_id, + firstName: rows[0].firstName, + lastName: rows[0].lastName, + eMail: rows[0].eMail, + adress: rows[0].adress, + role: rows[0].role, + }; req.session.user = user; // Store user object in session for authentication res.status(200).send({ @@ -201,7 +208,7 @@ app.post('/login', async (req: Request, res: Response): Promise<void> => { user: user, // Send user object to client for greeting message }); } else { - // Login data is incorrect, user is not logged in + // Login data is incorrect res.status(401).send({ message: 'Username or password is incorrect.', }); @@ -264,20 +271,20 @@ app.post('/logout', (req: Request, res: Response): void => { */ app.post('/user', isLoggedIn, async (req: Request, res: Response): Promise<void> => { // Read data from request body - const username: string = req.body.username; + const eMail: string = req.body.eMail; const password: string = req.body.password; - const givenName: string = req.body.givenName; - const familyName: string = req.body.familyName; + const firstName: string = req.body.firstName; + const lastName: string = req.body.lastName; // add a new user if first- and familyName exist - if (username && password && givenName && familyName) { + if (eMail && password && firstName && lastName) { const data: [string, string, string, string, string] = [ - username, + eMail, crypto.createHash("sha512").update(password).digest('hex'), - givenName, - familyName, + firstName, + lastName, new Date().toLocaleString() ]; - const query: string = 'INSERT INTO userlist (username, password, givenName, familyName, creationTime) VALUES (?, ?, ?, ?, ?);'; + const query: string = 'INSERT INTO user (eMail, password, firstName, lastName) VALUES (?, ?, ?, ?);'; // Execute database query try { const [result] = await database.query<ResultSetHeader>(query, data); @@ -333,16 +340,18 @@ app.get('/user/:userId', isLoggedIn, async (req: Request, res: Response): Promis parseInt(req.params.userId) ]; // Search user in database - const query: string = 'SELECT * FROM userlist WHERE id = ?;'; + const query: string = 'SELECT * FROM user WHERE user_id = ?;'; try { const [rows] = await database.query<RowDataPacket[]>(query, data); if (rows.length === 1) { const user: User = { - id: rows[0].id, - givenName: rows[0].givenName, - familyName: rows[0].familyName, - creationTime: rows[0].time + user_id: rows[0].user_id, + firstName: rows[0].firstName, + lastName: rows[0].lastName, + eMail: rows[0].eMail, + adress: rows[0].adress, + role: rows[0].role }; // Send user list to client @@ -398,17 +407,17 @@ app.get('/user/:userId', isLoggedIn, async (req: Request, res: Response): Promis app.put('/user/:userId', isLoggedIn, async (req: Request, res: Response): Promise<void> => { // Read data from request const userId: number = parseInt(req.params.userId); - const givenName: string = req.body.givenName; - const familyName: string = req.body.familyName; + const firstName: string = req.body.firstName; + const lastName: string = req.body.lastName; // Check that all arguments are given - if (givenName && familyName) { + if (firstName && lastName) { // Create database query and data const data: [string, string, number] = [ - givenName, - familyName, + firstName, + lastName, userId ]; - const query: string = 'UPDATE userlist SET givenName = ?, familyName = ? WHERE id = ?;'; + const query: string = 'UPDATE user SET firstName = ?, lastName = ? WHERE user_id = ?;'; // Execute database query try { @@ -420,7 +429,7 @@ app.put('/user/:userId', isLoggedIn, async (req: Request, res: Response): Promis }); } else { res.status(200).send({ - message: `Successfully updated user ${givenName} ${familyName}`, + message: `Successfully updated user ${firstName} ${lastName}`, }); } } catch (error) { @@ -454,7 +463,7 @@ app.delete('/user/:userId', isLoggedIn, async (req: Request, res: Response): Pro // Read data from request const userId: number = parseInt(req.params.userId); // Delete user - const query: string = 'DELETE FROM userlist WHERE id = ?;'; + const query: string = 'DELETE FROM user WHERE user_id = ?;'; try { const [result] = await database.query<ResultSetHeader>(query, userId); if (result.affectedRows === 1) { @@ -504,7 +513,7 @@ app.delete('/user/:userId', isLoggedIn, async (req: Request, res: Response): Pro */ app.get('/users', isLoggedIn, async (req: Request, res: Response): Promise<void> => { // Send user list to client - const query: string = 'SELECT * FROM userlist;'; + const query: string = 'SELECT * FROM user;'; try { const [rows] = await database.query<RowDataPacket[]>(query); @@ -513,10 +522,12 @@ app.get('/users', isLoggedIn, async (req: Request, res: Response): Promise<void> // Parse every entry for (const row of rows) { const user: User = { - id: row.id, - givenName: row.givenName, - familyName: row.familyName, - creationTime: row.creationTime + user_id: row.user_id, + firstName: row.firstName, + lastName: row.lastName, + eMail: row.eMail, + adress: row.adress, + role: row.role }; userList.push(user); } diff --git a/userman_all/server/test/userman.http b/userman_all/server/test/userman.http index c41485027ef796c62a56b868a62c5fd5d12adcf2..8964baa8d73797d4d0d33a55d58782058f747593 100644 --- a/userman_all/server/test/userman.http +++ b/userman_all/server/test/userman.http @@ -3,8 +3,8 @@ POST http://localhost:8080/login HTTP/1.1 Content-Type: application/json { - "username": "admin", - "password": "admin" + "eMail": "bob.hase@outlook.com", + "password": "09876543" } ### Create a new user @@ -12,9 +12,9 @@ POST http://localhost:8080/user HTTP/1.1 Content-Type: application/json { - "givenName": "Bruce", - "familyName": "Wayne", - "username": "bat", + "firstName": "Bruce", + "lastName": "Wayne", + "eMail": "bat", "password": "1234" } @@ -29,8 +29,8 @@ PUT http://localhost:8080/user/1 HTTP/1.1 Content-Type: application/json { - "givenName": "Selina", - "familyName": "Kyle" + "firstName": "Selina", + "lastName": "Kyle" } ### Delete specific user