From b7f5f0e30f293a112d13258e1328a684045f4208 Mon Sep 17 00:00:00 2001 From: Gabriel Copat <copatg@cardiff.ac.uk> Date: Tue, 12 Dec 2023 17:02:38 +0000 Subject: [PATCH] Mobile phone layout for user page --- .../security/SecurityConfiguration.java | 3 +- .../SmartTowns/users/UserController.java | 26 +- src/main/resources/data.sql | 4 + .../css/{userProfile2.css => userProfile.css} | 282 +++++++++--------- .../templates/fragments/banners.html | 12 +- .../resources/templates/users/userFrags.html | 18 +- .../templates/users/userProfile.html | 81 ++--- 7 files changed, 209 insertions(+), 217 deletions(-) rename src/main/resources/static/css/{userProfile2.css => userProfile.css} (51%) diff --git a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java index afce617e..eabe292e 100644 --- a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java +++ b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java @@ -9,6 +9,7 @@ import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.provisioning.UserDetailsManager; +import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.SecurityFilterChain; import javax.sql.DataSource; @@ -29,7 +30,7 @@ public class SecurityConfiguration { ) .formLogin((login) -> login .loginPage("/login").permitAll() - .defaultSuccessUrl("/userProfile") + .defaultSuccessUrl("/mobile-home") ) .logout((logout) -> logout.permitAll()); diff --git a/src/main/java/Team5/SmartTowns/users/UserController.java b/src/main/java/Team5/SmartTowns/users/UserController.java index 1cc58ecd..7c5ace9c 100644 --- a/src/main/java/Team5/SmartTowns/users/UserController.java +++ b/src/main/java/Team5/SmartTowns/users/UserController.java @@ -66,26 +66,13 @@ public class UserController { } } - @GetMapping("/userProfile") - public ModelAndView userProfile(){ - ModelAndView mav = new ModelAndView("users/userProfile"); - List<Pack> allPacks = rewardsRepository.getAllPacks(); - mav.addObject("packs", allPacks); - - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - System.out.println(user.getUsername()); - mav.addObject("user", userRepository.findUserByName("Admin")); - mav.addAllObjects(getPackInfo("Admin", 1).getModelMap()); - return mav; - } - - /* USER MAPPING & FUNCTIONS */ - @GetMapping("/user/{username}") + @GetMapping("/profile/{username}") public ModelAndView getUserPage(@PathVariable String username) { ModelAndView mav = new ModelAndView("users/userProfile"); List<Pack> allPacks = rewardsRepository.getAllPacks(); - mav.addObject("user", userRepository.findUserByName("Admin")); + allPacks.remove(0); + mav.addObject("user", userRepository.findUserByName(username)); mav.addObject("packs", allPacks); mav.addAllObjects(getPackInfo(username, 1).getModelMap()); return mav; @@ -99,13 +86,16 @@ public class UserController { ModelAndView mav = new ModelAndView("users/userFrags :: stickersBox"); List<Sticker> allStickers = rewardsRepository.getAllStickersFromPack(packID); List<Long> userStickers = userRepository.getUserStickersFromPack(username, packID); - System.out.println(userStickers); - + List<Pack> allPacks = rewardsRepository.getAllPacks(); + Pack current = allPacks.stream().filter(pack -> pack.getId() == packID).findFirst().get(); + allPacks.remove(current); mav.addObject("stickers", setStickerVisibility(allStickers, userStickers)); mav.addObject("progress", getPackProgress(allStickers)); mav.addObject("selectedPack", rewardsRepository.findPackByID(packID)); + mav.addObject("packs", allPacks); + mav.addObject("user", userRepository.findUserByName(username)); return mav; } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index b91b4f71..08ef0945 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -34,6 +34,10 @@ DELETE FROM packs; INSERT INTO packs (name, description) VALUE ('Wales Football Team', 'Pack of Welsh Football Players in the National Team'); INSERT INTO packs (name, description) VALUE ('Wales Rugby Team', 'Pack of Welsh Rugby Players in the National Team'); INSERT INTO packs (name, description) VALUE ('Welsh Heritage', 'Pack About Welsh Heritage'); +INSERT INTO packs (name, description) VALUE ('Welsh Heritage', 'Pack About Welsh Heritage'); +INSERT INTO packs (name, description) VALUE ('Welsh Heritage', 'Pack About Welsh Heritage'); +INSERT INTO packs (name, description) VALUE ('Welsh Heritage', 'Pack About Welsh Heritage'); +INSERT INTO packs (name, description) VALUE ('Welsh Heritage', 'Pack About Welsh Heritage'); DELETE FROM stickers; INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUE (1, 1, 'wayne_hennessey', 'Wales Football Team Player', '2'); diff --git a/src/main/resources/static/css/userProfile2.css b/src/main/resources/static/css/userProfile.css similarity index 51% rename from src/main/resources/static/css/userProfile2.css rename to src/main/resources/static/css/userProfile.css index 0c5c0e9c..a3de978e 100644 --- a/src/main/resources/static/css/userProfile2.css +++ b/src/main/resources/static/css/userProfile.css @@ -2,29 +2,13 @@ @import url('https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap'); @import url('https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap'); - - - - /* DEFAULT CSS MADE FOR SCREEN SIZES WIDTHS BETWEEN 320px and 640px:*/ -body { - background: linear-gradient(to bottom right, - var(--primary-darker), - var(--primary-dark), - var(--primary-darker)); - - display: flex; - flex-direction: column; - justify-content: center; - align-content: center; - - position: fixed; - width: 100vw; - height: 100svh; +main { + row-gap: 1svh; + padding: 4vw; } - .grayedSticker { filter: grayscale(1); } @@ -32,58 +16,27 @@ body { filter: drop-shadow(0 0 10px yellow); } - -html { - position: fixed; - width: 100vw; - height: 100svh; -} -main { - width: 90%; - height: 95%; - background: linear-gradient(to bottom left, #1f1f1f, #1e1e1e, #1f1f1f); - overflow-x: hidden; - overflow-y: scroll; - margin-inline: auto; - - display: flex; - flex-direction: column; - align-content: flex-start; - align-items: center; - border-radius: 5vw; -} .userContainer { - width: 90%; - padding-block: 2em; - margin-block: 1em; - border-radius: 5vw; + width: 90vw; display: flex; - flex-direction: row-reverse; - /*align-items: center;*/ - justify-content: space-evenly; - + justify-content: flex-start; + padding-inline: 2vw; + column-gap: 3vw; row-gap: 1svh; - & h1 { - font-size: 5em; - text-align: center; - text-shadow: black 0 0.2em 0.5em; + font-size: 3em; + text-align: right; + display: flex; + align-items: center; + text-shadow: rgba(0,0,0,0.3) 0 1svh 1svh; letter-spacing: 0.1em; - width: 40vw; + width: 400px; max-height: 40vw; - /*border-bottom: black solid 3px;*/ - padding-inline: 5%; - padding-block: 2%; - border-radius: 35%; - /*box-shadow: var(--accent-shadow);*/ - /*background: var(--accent-border);*/ - align-self: center; text-wrap: normal; } & #userPicture { border-radius: 100%; - box-shadow: var(--accent-shadow); - overflow: hidden; + box-shadow: rgba(0,0,0,0.3) 0 1svh 1svh; } } @@ -94,109 +47,158 @@ main { display: flex; flex-direction: column; overflow: visible; - width: 100%; + width: 90vw; } #packsBar { position: relative; - display: flex; - flex-direction: column; - justify-content: space-evenly; text-align: center; width: 100%; & h2 { - font-size: 4em; + font-size: 2em; letter-spacing: 0.1em; - border-bottom: 10px solid darkred; + border-width: 0 0 10px 0 ; + border-style: solid; + border-image: linear-gradient(to left, transparent 20%, darkred 50%, transparent 80%) + 50; margin-inline: 5%; } } + +#packRewardsWrapper { + display: flex; + flex-direction: column; + width: 90vw; + row-gap: 2svh; +} +.pack-title { + display: flex; + justify-content: center; + font-family: MedievalSharp, serif; + padding-block: 0.5svh; + letter-spacing: 0.1svw; + font-size: 3em; + border-width: 10px 0 10px 0 ; + border-style: solid; + border-image: linear-gradient(to left, transparent 10%, darkred 50%, transparent 90%) + 50; +} +.packs-area { + position: relative; + display: grid; + grid-template-columns: 20vw auto; + grid-template-rows: 20% auto; + grid-template-areas: + "current pack-title" + "current other-packs"; + margin-inline: 2vw; + align-items: end; +} +.other-packs { + width: 60vw; +} +.progImgContainer { + grid-area: current; + position: relative; + padding-top: 1.5svh; + z-index: 1; +} +.pack-text { + grid-area: pack-title; + font-size: 0.8em; +} +.progImg { + height: 10svh; + border-radius: 20%; +} +.progImgFill { + position: absolute; + overflow: hidden; + width: 50%; +} +.progImgOutline { + opacity: 0.1; + filter: grayscale(1); +} +.progText { + font-family: Consolas, serif; + opacity: 0.4; + -webkit-text-stroke: 1px black; + position: absolute; + text-align: center; + width: 16svh; + left:50%; + top:50%; + transform: translate(-50%, -50%); + font-size: 1.5em; +} + #allPacksContainer { - padding-top: 3em; + grid-area: other-packs; + height: 100%; + width: 100%; display: flex; overflow-x: scroll; - padding-inline: 20%; - justify-content: space-between; - border-bottom: 10px solid rgba(139, 0, 0, 0.5); - margin-bottom: 2em; - & .packName { - font-size: 2em; - height: 2.4em; - overflow: hidden; - padding-bottom: 1em; - display: flex; - justify-content: center; - align-content: flex-start; - - } - & .packImg { - transition: 0.5s ease-in-out 1ms; - border-radius: 20%; - } + justify-content: flex-start; + column-gap: 3vw; + padding-inline: 5vw; + z-index: 5; } -.packImg:hover { - transform: scale(1.5, 1.5) +.packContainer { + flex: 0 0; + border-radius: 20px; + /*border: darkred solid 3px;*/ + width: 250px; + height: 100%; + display: grid; + grid-template-rows: 80% auto; + flex-direction: column; + align-items: center; + justify-content: space-evenly; +} +.packImg { + transition: 0.5s ease-in-out 1ms; + border-radius: 20%; + height: 100px; + padding-inline: 10px; + aspect-ratio: 1; } -.progressionContainer { +.packName { + font-size: 0.5em; + font-weight: lighter; + height: 2.4em; + overflow: hidden; + padding-bottom: 1em; display: flex; - flex-direction: column; - height: 18svh; - & h1 { - font-size: 4em; - width: 100%; - font-family: 'MedievalSharp', cursive; - text-align: center; - overflow-x: scroll; - overflow-y: hidden; - } - & .progImgContainer { - position: relative; - margin-inline: auto; - & .progImg { - height: 14svh; - /*width: 16svh;*/ - border-radius: 20%; - } - & .progImgFill { - position: absolute; - overflow: hidden; - width: 50%; - } - & .progImgOutline { - opacity: 0.1; - filter: grayscale(1); - } - & .progText { - font-family: Consolas, serif; - opacity: 0.5; - -webkit-text-stroke: 1px black; - position: absolute; - text-align: center; - width: 16svh; - left:50%; - transform: translate(-50%, 150%); - font-size: 3em; - } - - } + justify-content: center; + align-content: flex-start; } - +.packImg:hover { + transform: scale(1.5, 1.5) +} #stickersBox { width: 100%; + height: 40svh; + overflow: hidden; + overflow-y: scroll; + padding-block: 1svh; + margin-top:0.5svh; } .stickersContainer { display: flex; flex-wrap: wrap; justify-content: center; - margin-top: 2em; - row-gap: 2em; + align-items: center; + align-content: flex-start; + row-gap: 1svh; height: 100%; } .stickerImg { - height: 17em; - margin: 1.5em; + height: 250px; + margin-inline: 2vw; + } /* LOGIN FORM PAGE */ @@ -210,15 +212,9 @@ main { and (min-device-width: 320px) and (max-device-width: 640px) { #userPicture { - width: 30vw; - height: 30vw; - border: solid #989898 0.8em; - } - .packImg { - height: 10svh; - width: 15em; - padding-inline: 1em; - margin-inline: 1em; + width: 300px; + aspect-ratio: 1; + border: solid #989898 10px; } #allPacksContainer::-webkit-scrollbar { display: none; diff --git a/src/main/resources/templates/fragments/banners.html b/src/main/resources/templates/fragments/banners.html index 57bfda57..2a56ff54 100644 --- a/src/main/resources/templates/fragments/banners.html +++ b/src/main/resources/templates/fragments/banners.html @@ -2,9 +2,15 @@ <a class="nav-logo-container"><img th:src="@{/images/icons/VZTA.png}" alt="Logo" class="nav-logo"></a> <nav class="head-navbar"> <ul class="nav-ul"> - <li class="nav-li li-first"><a href="/mobile-home" class="nav-links">Home</a></li> - <li class="nav-li li-middle"><a class="nav-links">Profile</a></li> - <li class="nav-li li-middle"><a class="nav-links">FAQ</a></li> + <li class="nav-li li-first"> + <a href="/mobile-home" class="nav-links">Home</a> + </li> + <li class="nav-li li-middle" th:if="${#authentication.principal}!=anonymousUser"> + <a th:href="'/profile/' + ${#authentication.getName()}" class="nav-links">Profile</a> + </li> + <li class="nav-li li-middle"> + <a class="nav-links">FAQ</a> + </li> <li class="nav-li li-last" th:if="${#authentication.principal}==anonymousUser"> <a href="/login" class="nav-links">Log In</a> </li> diff --git a/src/main/resources/templates/users/userFrags.html b/src/main/resources/templates/users/userFrags.html index 5b5e8201..33fb7b7b 100644 --- a/src/main/resources/templates/users/userFrags.html +++ b/src/main/resources/templates/users/userFrags.html @@ -2,10 +2,9 @@ <!-- @thymesVar id="user" type="Team5.SmartTowns.users.User" --> <!-- @thymesVar id="selectedPack" type="Team5.SmartTowns.rewards.Pack" --> <div th:fragment="stickersBox" id="packRewardsWrapper"> - <article class="progressionContainer"> - <h1 th:text="${selectedPack.getName()}"></h1> + <div class="packs-area"> <div class="progImgContainer"> - <div class="progImgFill" th:style="'width:'+ ${progress} + '%;'"> + <div class="progImgFill gotSticker" th:style="'width:'+ ${progress} + '%;'"> <img th:src="@{'../' + ${selectedPack.getDisplayImg()}}" alt="Filled Dragon" id="FilledDragon" class="progImg"> </div> @@ -17,7 +16,18 @@ alt="Outline Dragon" id="OutlineDragon" class="progImg"> </div> </div> - </article> + <h2 class="pack-text">Other Packs</h2> + <div id="allPacksContainer" class="centerFlex"> + <div th:each="pack : ${packs}" class="packContainer"> + <img class="packImg" th:src="@{'../' + ${pack.getDisplayImg()}}" + th:id="'packImg' + ${pack.getId()}" th:alt="${pack.getName()}" + th:data-url="@{/packInfo/{username}/{packID}(username=${user.getName()}, packID=${pack.getId()})}" + onclick="updatePack(this.getAttribute('data-url'))"> + <h4 class="packName" th:text="${pack.getName()}"></h4> + </div> + </div> + </div> + <h1 class="pack-title" th:text="${selectedPack.getName()}"></h1> <article id="stickersBox"> <div class="stickersContainer"> diff --git a/src/main/resources/templates/users/userProfile.html b/src/main/resources/templates/users/userProfile.html index edbe1391..3377dde2 100644 --- a/src/main/resources/templates/users/userProfile.html +++ b/src/main/resources/templates/users/userProfile.html @@ -3,60 +3,45 @@ <head> <meta charset="UTF-8"> <title th:text="'VZLA Profile Page of ' + ${user.getName()}"></title> - <link rel="stylesheet" th:href="@{/css/style.css}"> - <link rel="stylesheet" th:href="@{/css/userProfile2.css}"> + <link rel="stylesheet" th:href="@{/css/colours.css.css}"> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> + <link rel="stylesheet" th:href="@{/css/userProfile.css}"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- <link rel="stylesheet" th:href="@{/css/templatingstyle.css}">--> </head> -<body> - -<!--<header>--> -<!-- <ul class="footerBar">--> -<!-- <li class="footerButton"><b>Home</b></li>--> -<!-- <li class="footerButton"><b>About</b></li>--> -<!-- <li class="footerButton"><b>Map</b></li>--> -<!-- <li class="footerButton"><b>Facilities</b></li>--> -<!-- <li class="footerButton"><b>Log In</b></li>--> -<!-- </ul>--> -<!--</header>--> -<main> - <!--PICTURE - DATA - BADGES --> - <div class="userContainer"> - <h1 th:text="${user.getName()}"></h1> - <img th:src="@{${user.getImgPath()}}" - th:alt="${user.getName()}" - id="userPicture" - > - - <!--TODO add some progression info here?--> - </div> - <section class="rewards"> <!--Reward lists, badges on top, stickers (larger) on the bottom--> - <article id="packsBar"> - <h2>Packs</h2> - <!--Shows first earned badges, followed by greyed out badges--> - <div id="allPacksContainer" class="centerFlex"> - <div th:each="pack : ${packs}" class="packContainer"> - <img class="packImg" th:src="@{'../' + ${pack.getDisplayImg()}}" - th:id="'packImg' + ${pack.getId()}" th:alt="${pack.getName()}" - th:data-url="@{/packInfo/{username}/{packID}(username=${user.getName()}, packID=${pack.getId()})}" - onclick="updatePack(this.getAttribute('data-url'))"> - <h4 class="packName" th:text="${pack.getName()}"></h4> +<body> + <header th:replace="~{/fragments/banners::header}"></header> + + <main> + <!--PICTURE - DATA - BADGES --> + <div class="userContainer"> + <img th:src="@{${user.getImgPath()}}" + th:alt="${user.getName()}" + id="userPicture" + > + <h1 th:text="${user.getName()}"></h1> + </div> + <section class="rewards"> <!--Reward lists, badges on top, stickers (larger) on the bottom--> + <!--<article id="packsBar"> + <h2>Packs</h2> + <!–Shows first earned badges, followed by greyed out badges–> + <div id="allPacksContainer" class="centerFlex"> + <div th:each="pack : ${packs}" class="packContainer"> + <img class="packImg" th:src="@{'../' + ${pack.getDisplayImg()}}" + th:id="'packImg' + ${pack.getId()}" th:alt="${pack.getName()}" + th:data-url="@{/packInfo/{username}/{packID}(username=${user.getName()}, packID=${pack.getId()})}" + onclick="updatePack(this.getAttribute('data-url'))"> + <h4 class="packName" th:text="${pack.getName()}"></h4> + </div> </div> - </div> - </article> - <article th:replace="~{users/userFrags.html::stickersBox}" id="stickersBox"></article> - </section> - - -</main> - -<footer> + </article>--> + <article th:replace="~{users/userFrags.html::stickersBox}" id="stickersBox"></article> + </section> + </main> -</footer> -<script type="text/javascript" th:src="@{../scripts/userPage.js}"></script> + <footer th:replace="~{/fragments/banners::footer}"></footer> -<script> -</script> + <script type="text/javascript" th:src="@{../scripts/userPage.js}"></script> </body> </html> \ No newline at end of file -- GitLab