diff --git a/src/main/java/com/example/clientproject/data/rewards/Rewards.java b/src/main/java/com/example/clientproject/data/rewards/Rewards.java index e285c9d0cf3dffc600809af9c552c9b4c6abe58a..bb123c252868a48939da75d0899291b7d630b9f6 100644 --- a/src/main/java/com/example/clientproject/data/rewards/Rewards.java +++ b/src/main/java/com/example/clientproject/data/rewards/Rewards.java @@ -2,6 +2,7 @@ package com.example.clientproject.data.rewards; import com.example.clientproject.data.shops.Shops; import com.example.clientproject.data.stampBoards.StampBoards; +import com.example.clientproject.data.twoFactorMethods.TwoFactorMethods; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -29,4 +30,7 @@ public class Rewards { rewardStampLocation = rewardLocation; } + @ManyToOne + @JoinColumn(name="Stamp_Board_Id", nullable=false) + private StampBoards stampBoards; } diff --git a/src/main/java/com/example/clientproject/data/rewards/RewardsRepo.java b/src/main/java/com/example/clientproject/data/rewards/RewardsRepo.java index e2c27b286bef940fbbd961298a625d6e2656734b..c1ab9c191a5068e3377af33ae003e574d668cf06 100644 --- a/src/main/java/com/example/clientproject/data/rewards/RewardsRepo.java +++ b/src/main/java/com/example/clientproject/data/rewards/RewardsRepo.java @@ -22,10 +22,19 @@ public interface RewardsRepo extends JpaRepository<StampBoards, Long> { /** * Find a Reward by the name - * @param rewardName - name of the Reward to find + * @param rewardId Id of reward to find * @return - Optional object containing the Reward found, if it's present */ @Query("select r from Rewards r where r.rewardId = ?1") - Optional<Rewards> findByRewardName(String rewardName); + Optional<Rewards> findByRewardId(long rewardId); + + + /** + * Find a Reward by the name + * @param rewardId Id of reward to find + * @return - Optional Integer containing the reward, if it's present + */ + @Query("select r.rewardStampLocation from Rewards r where r.rewardId = ?1") + Optional<Integer> getRewardValueFromId(long rewardId); } diff --git a/src/main/java/com/example/clientproject/services/GetStampBoardIdFromRewardId.java b/src/main/java/com/example/clientproject/services/GetStampBoardIdFromRewardId.java new file mode 100644 index 0000000000000000000000000000000000000000..ec93834e30a2164233f9f6c89ad9e7f95c3ff08c --- /dev/null +++ b/src/main/java/com/example/clientproject/services/GetStampBoardIdFromRewardId.java @@ -0,0 +1,29 @@ +package com.example.clientproject.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public class GetStampBoardIdFromRewardId { + @Autowired + JdbcTemplate jdbc; + + /** + * @param rewardId the rewardId of the stampBoardId you want to retrieve + */ + public int getStampBoardId(Integer rewardId){ + String query = "SELECT Stamp_Board_Id FROM rewards WHERE Reward_Id = " + rewardId + ";"; + try{ + List<Map<String, Object>> rs = jdbc.queryForList(query); + + System.out.println((int) rs.get(0).get("Stamp_Board_Id")); + return (int) rs.get(0).get("Stamp_Board_Id"); + }catch (Exception e){ + return 0; + } + } +} diff --git a/src/main/java/com/example/clientproject/services/UserStampBoardRetriever.java b/src/main/java/com/example/clientproject/services/UserStampBoardService.java similarity index 63% rename from src/main/java/com/example/clientproject/services/UserStampBoardRetriever.java rename to src/main/java/com/example/clientproject/services/UserStampBoardService.java index b2232bb0be5ab5642a1763ca9bc362b78d009758..b5391f7c6b490d671c8852b9554256065941b1e5 100644 --- a/src/main/java/com/example/clientproject/services/UserStampBoardRetriever.java +++ b/src/main/java/com/example/clientproject/services/UserStampBoardService.java @@ -10,9 +10,10 @@ import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.util.List; import java.util.Map; +import java.util.Objects; @Service -public class UserStampBoardRetriever { +public class UserStampBoardService { @Autowired JdbcTemplate jdbc; @@ -29,7 +30,6 @@ public class UserStampBoardRetriever { public int getUserStampPos(int userID, int stampBoardID){ String query = "SELECT User_Stamp_Position FROM user_stamp_boards WHERE User_Id = " + userID + " AND Stamp_Board_Id = " + stampBoardID + ";"; try{ - System.out.println(query); List<Map<String, Object>> rs = jdbc.queryForList(query); System.out.println((int) rs.get(0).get("User_Stamp_Position")); @@ -39,4 +39,15 @@ public class UserStampBoardRetriever { } } + + public void changeUserStampPosition(int userID, int incrementValue, int currentUserStampPos, int stampBoardId){ + int newStampPos = currentUserStampPos + incrementValue; + String query = "UPDATE user_stamp_boards SET User_Stamp_Position = " + newStampPos + " WHERE User_Id = " + userID + " AND Stamp_Board_Id = " + stampBoardId + ";"; + jdbc.execute(query); + } + + public void createStampRecord(int userID, int stampPosition, int stampBoardId){ + String query = "INSERT INTO user_stamp_boards (User_Id, Stamp_Board_Id, User_Stamp_Position) VALUES ("+userID+", "+stampBoardId+", "+ stampPosition +");"; + jdbc.execute(query); + } } diff --git a/src/main/java/com/example/clientproject/web/controllers/BusinessDetails.java b/src/main/java/com/example/clientproject/web/controllers/BusinessDetails.java index 576d98f44e0e1b10c38697f1d52eb3baf34679d8..e1e203a73d734b0974d6d04ef2b548d335dc7264 100644 --- a/src/main/java/com/example/clientproject/web/controllers/BusinessDetails.java +++ b/src/main/java/com/example/clientproject/web/controllers/BusinessDetails.java @@ -6,13 +6,15 @@ import com.example.clientproject.data.socials.Socials; import com.example.clientproject.data.socials.SocialsRepo; import com.example.clientproject.data.stampBoards.StampBoards; import com.example.clientproject.data.stampBoards.StampBoardsRepo; +import com.example.clientproject.data.userPermissions.UserPermissions; +import com.example.clientproject.data.userPermissions.UserPermissionsRepo; import com.example.clientproject.data.userStampBoards.UserStampBoards; import com.example.clientproject.data.userStampBoards.UserStampBoardsRepo; import com.example.clientproject.data.users.Users; import com.example.clientproject.data.users.UsersRepo; import com.example.clientproject.service.Utils.JWTUtils; import com.example.clientproject.services.UserFavouriteTagSaver; -import com.example.clientproject.services.UserStampBoardRetriever; +import com.example.clientproject.services.UserStampBoardService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -35,20 +37,24 @@ public class BusinessDetails { private JWTUtils jwtUtils; - private UserStampBoardRetriever userStampService; + private UserStampBoardService userStampService; private SocialsRepo socialsRepo; + UserPermissionsRepo userPermissionsRepo; + public BusinessDetails(ShopsRepo aShopRepo, StampBoardsRepo aStampBoard, - UsersRepo aUsersRepo, UserStampBoardRetriever aUserStampService, - JWTUtils ajwtUtils, SocialsRepo aSocialsRepo){ + UsersRepo aUsersRepo, UserStampBoardService aUserStampService, + JWTUtils ajwtUtils, SocialsRepo aSocialsRepo, + UserPermissionsRepo upr){ shopsRepo = aShopRepo; stampRepo = aStampBoard; usersRepo = aUsersRepo; jwtUtils = ajwtUtils; userStampService = aUserStampService; socialsRepo = aSocialsRepo; + userPermissionsRepo = upr; } @GetMapping("/businessDetails") @@ -80,6 +86,20 @@ public class BusinessDetails { List<Socials> socialMedia = socialsRepo.findByShopId(shop.getShopId()); + //gets users permission level for shop + long shopPermissionLevel = 0; + List<UserPermissions> userShops = userPermissionsRepo.findByUserId(jwtUtils.getLoggedInUserId(session).get()); + //loops through userPermissions and saves it to variable to be passed into model + for (UserPermissions u : userShops) { + if (u.getShop().getShopId() == shop.getShopId()) { + shopPermissionLevel = u.getAdminType().getAdminTypeId(); + } + } + //creates an object to pass into model + ArrayList <Integer> userShopPermissionOBJ = new ArrayList<>(); + userShopPermissionOBJ.add((int) shopPermissionLevel); + model.addAttribute("userPermission", userShopPermissionOBJ); + model.addAttribute("socials", socialMedia); diff --git a/src/main/java/com/example/clientproject/web/restControllers/UpdateUserStampPosition.java b/src/main/java/com/example/clientproject/web/restControllers/UpdateUserStampPosition.java new file mode 100644 index 0000000000000000000000000000000000000000..3b517f939a069bce3e0c169b5bf43e4f81b3ba64 --- /dev/null +++ b/src/main/java/com/example/clientproject/web/restControllers/UpdateUserStampPosition.java @@ -0,0 +1,124 @@ +package com.example.clientproject.web.restControllers; + +import com.example.clientproject.data.rewards.Rewards; +import com.example.clientproject.data.rewards.RewardsRepo; +import com.example.clientproject.data.shops.Shops; +import com.example.clientproject.data.shops.ShopsRepo; +import com.example.clientproject.data.stampBoards.StampBoards; +import com.example.clientproject.data.userPermissions.UserPermissions; +import com.example.clientproject.data.userPermissions.UserPermissionsRepo; +import com.example.clientproject.data.userStampBoards.UserStampBoards; +import com.example.clientproject.data.users.Users; +import com.example.clientproject.data.users.UsersRepo; +import com.example.clientproject.service.Utils.JWTUtils; +import com.example.clientproject.services.GetStampBoardIdFromRewardId; +import com.example.clientproject.services.StampboardUpdater; +import com.example.clientproject.services.UserStampBoardService; +import com.example.clientproject.web.forms.UpdateStampboardForm; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpSession; +import java.nio.charset.Charset; +import java.util.*; + +@RestController +public class UpdateUserStampPosition { + JWTUtils jwtUtils; + UserStampBoardService userStampBoardService; + UserPermissionsRepo userPermissionsRepo; + RewardsRepo rewardsRepo; + UsersRepo usersRepo; + GetStampBoardIdFromRewardId getStampBoardIdFromRewardId; + ShopsRepo shopsRepo; + + public UpdateUserStampPosition(JWTUtils jwt, UserStampBoardService usbs, + UserPermissionsRepo upr, RewardsRepo rr, + UsersRepo ur, GetStampBoardIdFromRewardId gsbifri, + ShopsRepo sr){ //need to add service for changing stamp pos + jwtUtils = jwt; + userStampBoardService = usbs; + userPermissionsRepo = upr; + rewardsRepo = rr; + usersRepo = ur; + getStampBoardIdFromRewardId = gsbifri; + shopsRepo = sr; + } + + @PostMapping("/changeUserPos") + public void updateUserPos(@RequestParam(name="direction", required = true) String direction, + @RequestParam(name="shopId", required = true) String shopId, HttpSession session) { + //will firstly check that user has permission to do action + //Optional<Users> user = jwtUtils.getLoggedInUserRow(session); + long shopPermissionLevel = 0; + int currentUserStampPos = 0; + long shopStampBoardId = 0; + int shopStampBoardSize = 0; + int shopIdConverted = Integer.parseInt(shopId); + List<UserPermissions> userShops = userPermissionsRepo.findByUserId(jwtUtils.getLoggedInUserId(session).get()); + for (UserPermissions u : userShops) { //loops through userPermissions and saves it to variable to be checked + if (u.getShop().getShopId() == shopIdConverted) { + shopPermissionLevel = u.getAdminType().getAdminTypeId(); + shopStampBoardId = u.getShop().getStampBoard().getStampBoardId(); + shopStampBoardSize = u.getShop().getStampBoard().getStampBoardSize(); + } + } + if(shopPermissionLevel > 1){//user has the correct level to add/subtract their own stampBoard place + currentUserStampPos = userStampBoardService.getUserStampPos(jwtUtils.getLoggedInUserId(session).get(), (int) shopStampBoardId ); + Shops shop = shopsRepo.getById(Long.valueOf(shopId)); + StampBoards stampBoard = shop.getStampBoard(); + if(Objects.equals(direction, "subtract")){ + if(currentUserStampPos != 0){ + userStampBoardService.changeUserStampPosition(jwtUtils.getLoggedInUserId(session).get(), -1, currentUserStampPos, (int) stampBoard.getStampBoardId()); + } + } else if(Objects.equals(direction, "add")){ + if(currentUserStampPos != shopStampBoardSize){ + userStampBoardService.changeUserStampPosition(jwtUtils.getLoggedInUserId(session).get(), 1, currentUserStampPos, (int) stampBoard.getStampBoardId()); + currentUserStampPos = userStampBoardService.getUserStampPos(jwtUtils.getLoggedInUserId(session).get(), (int) shopStampBoardId ); + } + if(currentUserStampPos == 0){ + System.out.println("Attempting to create record for user"); + userStampBoardService.createStampRecord(jwtUtils.getLoggedInUserId(session).get(), 1, (int) shopStampBoardId); + } + } + } + } + + @PostMapping("/reedeemReward") + public String reedeemStamps(@RequestParam(name="rewardId", required = true) int rewardId, HttpSession session){ + Optional<Rewards> reward = rewardsRepo.findByRewardId(Long.valueOf(rewardId)); + int stampBoardId = getStampBoardIdFromRewardId.getStampBoardId(rewardId); + Optional<Users> user = usersRepo.findById(Long.valueOf(jwtUtils.getLoggedInUserId(session).get())); + Set<UserStampBoards> userStampBoards = user.get().getUserStampBoards(); + int userStampPos = 0; + + boolean userIsLinkedToStampBoard = false; + for(UserStampBoards u : userStampBoards){ + if(stampBoardId == u.getStampBoard().getStampBoardId()){ + userStampPos = u.getUserStampPosition(); + userIsLinkedToStampBoard = true; + } + } + if(userIsLinkedToStampBoard){ + if(userStampPos >= reward.get().getRewardStampLocation()){ + userStampBoardService.changeUserStampPosition(jwtUtils.getLoggedInUserId(session).get(), -reward.get().getRewardStampLocation(), userStampPos, stampBoardId); + //credit to www.programiz.com for code generator + String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//creates a string of all characters + StringBuilder sb = new StringBuilder(); + Random random = new Random(); + for(int i = 0; i < 8; i++) { + int index = random.nextInt(alphabet.length()); + char randomChar = alphabet.charAt(index); + sb.append(randomChar); + } + String code = sb.toString().toUpperCase(); + return code; + } + } else { + System.out.println("User is not linked to stampboard they are trying to claim a reward from"); + } + + return "no"; + } +} diff --git a/src/main/resources/static/css/viewShop.css b/src/main/resources/static/css/viewShop.css index c7a22395bfae22da772326ab5d3ede32c8ac2498..a42ee8bb8ec07fa002f15ac0ed2a4942acc82f29 100644 --- a/src/main/resources/static/css/viewShop.css +++ b/src/main/resources/static/css/viewShop.css @@ -183,3 +183,49 @@ img.stamp{ align-items: center; position: relative; } + +.change-stamp-progress-container{ + position: absolute; + display: flex; + flex-direction: column; + top: 70%; + right: 3%; + width: 10px; +} + +.reward-box{ + width: inherit; + +} + +.text-align-center{ + text-align: center; +} + +.inherit-width{ + width: inherit; +} + +.reward-claim-title{ + font-weight: bold; + font-size: 40px; +} + +.big-margin-top{ + margin-top: 70px; +} + +.reward-claim-code{ + color: black; + font-weight: bold; + font-size: 60px; +} + +.custom-modal-card-body{ + background-color: #fff; + flex-grow: 1; + flex-shrink: 1; + padding: 20px; + height: 400px; + border-radius: 0px 0px 10px 10px; +} diff --git a/src/main/resources/static/js/selectCategories.js b/src/main/resources/static/js/selectCategories.js index 7c3a3ebad97dcbff9665c58ecb306781e6839090..285dbe05020044f8bc20386366806c70c1cdbec0 100644 --- a/src/main/resources/static/js/selectCategories.js +++ b/src/main/resources/static/js/selectCategories.js @@ -40,9 +40,9 @@ function submitCategories(listSize){ status.innerHTML = "There was an error try again later."; } }; - xhttp.onerror = function () { - status.innerHTML = "There was an error. Please try again later."; - } + xhttp.onerror = function () { + status.innerHTML = "There was an error. Please try again later."; + } xhttp.send(params); return false; } diff --git a/src/main/resources/static/js/viewShop.js b/src/main/resources/static/js/viewShop.js index 2f409ca8c5920d0905bc479634ff03c6a037347e..3d7fc0ecf7bc079d4003e3de184fcf3b2585a771 100644 --- a/src/main/resources/static/js/viewShop.js +++ b/src/main/resources/static/js/viewShop.js @@ -1,5 +1,6 @@ var currentPage = 1; + function pageNav(direction){ //this checks that current page will not go to 0 if "direction" = -1 / left if (direction === -1){ //"-1" = left @@ -26,6 +27,55 @@ function pageNav(direction){ } } -function toBusinessWebsite(URL){ - window.location.href = URL; + +function changeUserStampPos(increment, shopId){ + if (increment === "subtract"){ //take away a stamp position from user + params = 'direction=subtract'; + } else if(increment === "add"){ //add a stamp to user + params = 'direction=add'; + } else { + return null; + } + params = params + '&shopId=' + shopId; + var xhttp = new XMLHttpRequest(); + xhttp.open("POST", '/changeUserPos', true); // true is asynchronous + xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + xhttp.onload = function () { + if (xhttp.readyState === 4 && xhttp.status === 200) { + console.log(xhttp.responseText); + window.location.reload(true); + } + } + xhttp.onerror = function () { + alert("There was an error. Database has not been updated."); + } + xhttp.send(params); + return false; } + +function claimReward(rewardId){ + params = 'rewardId=' + rewardId; + var xhttp = new XMLHttpRequest(); + xhttp.open("POST", '/reedeemReward', true); // true is asynchronous + xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + xhttp.onload = function () { + if (xhttp.readyState === 4 && xhttp.status === 200) { + console.log(xhttp.responseText); + var modal = document.getElementById("rewardModal"); + var code = document.getElementById("reward-code"); + code.innerText = xhttp.responseText; + modal.classList.add("is-active"); + } + } + xhttp.onerror = function () { + alert("There was an error. Database has not been updated."); + } + xhttp.send(params); + return false; +} + + +function closeModal(){ + window.location.reload(true); +} + diff --git a/src/main/resources/templates/shopDetails.html b/src/main/resources/templates/shopDetails.html index 95a7c9903d83b2a3686d7e8be650d4faf9abc05a..18882f8fa9592f9d7258f761adc0e0688a38a90f 100644 --- a/src/main/resources/templates/shopDetails.html +++ b/src/main/resources/templates/shopDetails.html @@ -41,7 +41,7 @@ <div th:each="reward : ${stampBoard.rewards}" class="reward is-fullwidth"> <p class="reward-text" th:text="${reward.rewardName}"></p> <button th:unless="${UserStampPos[0]>=reward.rewardStampLocation}" class="button is-small buttonRewardNotReady">Cannot afford</button> - <button th:if="${UserStampPos[0]>=reward.rewardStampLocation}" class="button is-small buttonRewardisReady">Click to claim!</button> + <button th:if="${UserStampPos[0]>=reward.rewardStampLocation}" class="button is-small buttonRewardisReady" th:onclick="claimReward([[${reward.rewardId}]])">Click to claim!</button> <progress class="progress is-small marginBottom7px is-success" th:value="${UserStampPos[0]}" th:max="${reward.rewardStampLocation}"></progress> <!-- TH:STYLE HAS NOT BEEN SET SO EXPECT AN ERROR --> <p class="stampProgressText" th:unless="${UserStampPos[0]>=reward.rewardStampLocation}" th:text="${reward.rewardStampLocation - UserStampPos[0]} + ' away from reward'"/> @@ -75,7 +75,7 @@ </div> </div> - <div th:if="${@loadSocials.getSocial(socials, 'facebook' != '')}" class="control"> + <div th:if="${@loadSocials.getSocial(socials, 'facebook') != ''}" class="control"> <div class="tags has-addons"> <span class="tag is-large is-grey"> <span class="icon-text"> @@ -110,7 +110,7 @@ </span> </span> </span> - <a th:href="'https://twitter.com/' + ${@loadSocials.getSocial(socials, 'instagram')}"><span class="tag is-large is-danger mousePointerWhenHovered">Instagram</span></a> + <a th:href="'https://instagram.com/' + ${@loadSocials.getSocial(socials, 'instagram')}"><span class="tag is-large is-danger mousePointerWhenHovered">Instagram</span></a> </div> </div> @@ -132,5 +132,24 @@ <!-- <img th:src="${shop.shopImage}" alt=""> --> <!-- <h1 th:text="${stampBoard.stampBoardSize}"></h1> --> </div> + <div class="change-stamp-progress-container" th:if="${userPermission[0] > 1}"> + <button class="button is-rounded is-info" th:onclick="changeUserStampPos('add', [[${shop.getShopId}]])">+</button> + <button class="button is-rounded is-info" th:onclick="changeUserStampPos('subtract', [[${shop.getShopId}]])">-</button> + </div> + <div class="modal" id="rewardModal"> + <div class="modal-background"></div> + <div class="modal-card"> + <header class="modal-card-head text-align-center"> + <p class="modal-card-title reward-claim-title">Claim your reward!</p> + <button class="delete" aria-label="close" onclick="closeModal()"></button> + </header> + <section class="custom-modal-card-body"> + <div class="inherit-width text-align-center big-margin-top">reward code:</div> + <div class="inherit-width text-align-center reward-claim-code" id="reward-code">XKMSTVZ</div> + + </section> + </div> + </div> + <span th:value="${shop.getShopId}" id="shopId"/> </body> </html>