diff --git a/src/main/java/Team5/SmartTowns/Organisation/organisationControllers.java b/src/main/java/Team5/SmartTowns/Organisation/organisationControllers.java index 3708d3086dd276436a20cf30d7aba819f26885fd..7806763a0e1576f2d68fba0a9e76497959cc245c 100644 --- a/src/main/java/Team5/SmartTowns/Organisation/organisationControllers.java +++ b/src/main/java/Team5/SmartTowns/Organisation/organisationControllers.java @@ -32,16 +32,24 @@ public class organisationControllers { } @Autowired private localAuthorityRepository localAuthorityRepository; - @PostMapping("/localForm") + + @PostMapping("/local-authorities") public ModelAndView localAuthoritySent(@Valid @ModelAttribute("local-auth-data")localAuthority localAuthority, BindingResult bindingResult, Model model ) { if (bindingResult.hasErrors()) { - ModelAndView modelAndView = new ModelAndView("business-data", model.asMap()); + localAuthority loc = new localAuthority(localAuthority.getLocalAuthorityName(), localAuthority.getAddress1(), localAuthority.getAddress2(), localAuthority.getCity(), localAuthority.getCounty(), localAuthority.getPostcode(), localAuthority.getWebsite()); + System.out.println(loc); + localAuthorityRepository.addLocalAuthority(loc); //add local authority to local authority table + ModelAndView modelAndView = new ModelAndView("local-authorities"); + List<localAuthority> localAuthorities = localAuthorityRepository.getAllLocalAuthority(); + modelAndView.addObject("localAuth", localAuthorities); return modelAndView; }else{// converts user input using the organisation constructor into a submittable format to the sql table localAuthority loc = new localAuthority(localAuthority.getLocalAuthorityName(), localAuthority.getAddress1(), localAuthority.getAddress2(), localAuthority.getCity(), localAuthority.getCounty(), localAuthority.getPostcode(), localAuthority.getWebsite()); System.out.println(loc); localAuthorityRepository.addLocalAuthority(loc); //add local authority to local authority table - ModelAndView modelAndView = new ModelAndView("redirect:/localauthority"); + ModelAndView modelAndView = new ModelAndView("local-authorities"); + List<localAuthority> localAuthorities = localAuthorityRepository.getAllLocalAuthority(); + modelAndView.addObject("localAuth", localAuthorities); return modelAndView; } } diff --git a/src/main/java/Team5/SmartTowns/SmartTownsController.java b/src/main/java/Team5/SmartTowns/SmartTownsController.java new file mode 100644 index 0000000000000000000000000000000000000000..8f21592b64931ea5a0eb04abe0de1c0ade0fb5f9 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/SmartTownsController.java @@ -0,0 +1,16 @@ +package Team5.SmartTowns; + + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.ModelAndView; + +@Controller +public class SmartTownsController { + + + @GetMapping("/") + public ModelAndView getHomePage(){ + return new ModelAndView("welcome-page"); + } +} diff --git a/src/main/java/Team5/SmartTowns/data/DatabaseController.java b/src/main/java/Team5/SmartTowns/data/DatabaseController.java index 5b5d5ac4fa54cf3f0801b4fad4d8e1b9304cc9f1..62372a9991d60431b121f6b877d5343bb09afd54 100644 --- a/src/main/java/Team5/SmartTowns/data/DatabaseController.java +++ b/src/main/java/Team5/SmartTowns/data/DatabaseController.java @@ -1,3 +1,40 @@ + +//package Team5.SmartTowns.Data; +// +//import Team5.SmartTowns.users.User; +//import Team5.SmartTowns.users.UserRepository; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Controller; +//import org.springframework.web.bind.annotation.GetMapping; +//import org.springframework.web.servlet.ModelAndView; +// +//import java.util.*; +//@Controller +//public class DatabaseController { +// +// +// @Autowired +// private LocationRepository LocationRepository; +// @Autowired +// private trailsRepository trailsRepository; +// +// +// @GetMapping("/trailList") +// public ModelAndView trailList() { +// ModelAndView mav1 = new ModelAndView("towns/trailsData"); +// List<trail> trail = trailsRepository.getAllTrails(); +// mav1.addObject("trails", trail); +// return mav1; +// } +// @GetMapping("locationList") +// public ModelAndView locationList(){ +// ModelAndView mav2 = new ModelAndView("towns/locationData"); +// List<Location> Locations = LocationRepository.getAllLocation(); +// mav2.addObject("location", Locations); +// return mav2; +// } +//} + package Team5.SmartTowns.data; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/Team5/SmartTowns/data/Location.java b/src/main/java/Team5/SmartTowns/data/Location.java index 760f37c205f31e28189ded51dfce28f5b451687f..60b4a772bd93dbd24df5e38a9d62a89dc7b0df74 100644 --- a/src/main/java/Team5/SmartTowns/data/Location.java +++ b/src/main/java/Team5/SmartTowns/data/Location.java @@ -3,16 +3,19 @@ package Team5.SmartTowns.data; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; + @Data @AllArgsConstructor public class Location { -// private int locationID; + private long locationID; private String locationName; private String locationEmail; private String locationDescription; private String locationPlace; private String locationTrailID; + private boolean locationApproved; public Location() { @@ -51,11 +54,17 @@ public class Location { return locationTrailID; } + + + + public boolean isLocationApproved() { return locationApproved; + } + public void setLocationName(String locationName) { this.locationName = locationName; } diff --git a/src/main/java/Team5/SmartTowns/data/LocationRepository.java b/src/main/java/Team5/SmartTowns/data/LocationRepository.java index cbc980a816f339bae030bd1848d26c34d2376670..87a282b886ea979f4014ab8dba9d78c1d2bc0f33 100644 --- a/src/main/java/Team5/SmartTowns/data/LocationRepository.java +++ b/src/main/java/Team5/SmartTowns/data/LocationRepository.java @@ -8,8 +8,11 @@ public interface LocationRepository { List<Location> getAllLocation(); void addLocation(Location loc); + void updateApprovalStatus(int locID); + List<Location> getAllApprovedLocations(); + int nametoLocationID(String name); // List<Location> getApprovedLocations2(List<Location> list); diff --git a/src/main/java/Team5/SmartTowns/data/LocationRepositoryJDBC.java b/src/main/java/Team5/SmartTowns/data/LocationRepositoryJDBC.java index 33c5cabd7e0b0406986eac9c36f7c22f388e6ce1..98d829b72e6bea3494359d95748a244b045dd137 100644 --- a/src/main/java/Team5/SmartTowns/data/LocationRepositoryJDBC.java +++ b/src/main/java/Team5/SmartTowns/data/LocationRepositoryJDBC.java @@ -28,7 +28,7 @@ public class LocationRepositoryJDBC implements LocationRepository { private void setlocationMapper(){ locationMapper = (rs, i) -> new Location( - + rs.getLong("locationID"), rs.getString("locationName"), rs.getString("locationEmail"), rs.getString("locationDescription"), @@ -121,6 +121,18 @@ public class LocationRepositoryJDBC implements LocationRepository { // } return locationUnapprovedList; // } + @Override + public int nametoLocationID(String name){ + return jdbc.queryForObject("SELECT locationID FROM locations WHERE locationName=?", Integer.class, name); + + + } + @Override + public void updateApprovalStatus(int locID){ + String updateSql = "update locations set locationApproved = true where locationID = ?"; + jdbc.update(updateSql, locID); + } +// return jdbc.queryForObject("SELECT locationApproval FROM locations WHERE locationName=?", locationID); // public JdbcTemplate getJdbc() { // return jdbc; diff --git a/src/main/java/Team5/SmartTowns/data/Main.java b/src/main/java/Team5/SmartTowns/data/Main.java deleted file mode 100644 index 8f2a890b66299d6c3662b6bd7e68c6d897792847..0000000000000000000000000000000000000000 --- a/src/main/java/Team5/SmartTowns/data/Main.java +++ /dev/null @@ -1,16 +0,0 @@ -//package Team5.SmartTowns.Data; -// -//import org.springframework.beans.factory.annotation.Autowired; -// -//import java.util.List; -// -//public class Main { -// @Autowired -// private locationRepository locationRepository; -// List<Location> approvedNumber= locationRepository.approvedLocations(); -// public static void main(String[] args) { -// for (Location loc: approvedNumber){} -// -// -// } -//} diff --git a/src/main/java/Team5/SmartTowns/data/MockUser.java b/src/main/java/Team5/SmartTowns/data/MockUser.java deleted file mode 100644 index 344dbbd77e6aeba32c362c4955c87464125ab0e4..0000000000000000000000000000000000000000 --- a/src/main/java/Team5/SmartTowns/data/MockUser.java +++ /dev/null @@ -1,16 +0,0 @@ -package Team5.SmartTowns.data; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; - -import java.util.List; - -public class MockUser { - - private JdbcTemplate jdbc; - private RowMapper<Trail> trailMapper; - public List<Trail> getAllTrails(){ - String sql= "SELECT * FROM trails"; - return jdbc.query(sql, trailMapper); - } -} diff --git a/src/main/java/Team5/SmartTowns/data/QRCodes.java b/src/main/java/Team5/SmartTowns/data/QRCodes.java deleted file mode 100644 index 28ebf97c96d884a6629208ce8ce58505334b63b6..0000000000000000000000000000000000000000 --- a/src/main/java/Team5/SmartTowns/data/QRCodes.java +++ /dev/null @@ -1,4 +0,0 @@ -package Team5.SmartTowns.data; - -public class QRCodes { -} diff --git a/src/main/java/Team5/SmartTowns/data/Town.java b/src/main/java/Team5/SmartTowns/data/Town.java new file mode 100644 index 0000000000000000000000000000000000000000..0cb1ddc0533274bffb573ccc91da29d7c900d97d --- /dev/null +++ b/src/main/java/Team5/SmartTowns/data/Town.java @@ -0,0 +1,20 @@ +package Team5.SmartTowns.data; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Town { + private String townName; + private Integer townTrailNumber; + + + public String getTownName() { + return townName; + } + + public Integer getTownTrailNumber() { + return townTrailNumber; + } +} diff --git a/src/main/java/Team5/SmartTowns/data/TownRepository.java b/src/main/java/Team5/SmartTowns/data/TownRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..86577a4bcd8f31840e81dd1aef2cfa5a58958959 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/data/TownRepository.java @@ -0,0 +1,8 @@ +package Team5.SmartTowns.data; + +import java.util.List; + +public interface TownRepository { + List<Town> getAllTowns(); + void addTown(Town town); +} diff --git a/src/main/java/Team5/SmartTowns/data/TownRepositoryJDBC.java b/src/main/java/Team5/SmartTowns/data/TownRepositoryJDBC.java new file mode 100644 index 0000000000000000000000000000000000000000..c40d6c00cb9590a68a22b8291da20a02c2257163 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/data/TownRepositoryJDBC.java @@ -0,0 +1,37 @@ +package Team5.SmartTowns.data; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class TownRepositoryJDBC implements TownRepository{ + + private JdbcTemplate jdbc; + private RowMapper<Town> townMapper; + + public TownRepositoryJDBC(JdbcTemplate aJdbc) { + this.jdbc = aJdbc; + setTownMapper(); + } + private void setTownMapper(){ + townMapper = (rs, i) -> new Town( + rs.getString("townName"), + rs.getInt("townTrailNumber") + ); + } + public List<Town> getAllTowns(){ + String sql= "SELECT * FROM towns"; + return jdbc.query(sql, townMapper); + } + + @Override // intended implementation at current: user data from templates/Landmarks/LandmarkFormTh.html is added to the Location table + public void addTown(Town town) { + String sql = "insert into towns( townName,townTrailNumber) values (?,?)"; + + jdbc.update(sql,town.getTownName(),town.getTownTrailNumber()); + } + +} diff --git a/src/main/java/Team5/SmartTowns/data/Trail.java b/src/main/java/Team5/SmartTowns/data/Trail.java index f9056d64b47f0f5104216b6eb15f50f9301d843c..672ec49090c608149c14db5aa2b018232155c1f0 100644 --- a/src/main/java/Team5/SmartTowns/data/Trail.java +++ b/src/main/java/Team5/SmartTowns/data/Trail.java @@ -1,18 +1,31 @@ //Holds variable data for the trails table package Team5.SmartTowns.data; +import Team5.SmartTowns.placeswithcoordinates.PlacesCoordinatesRepository; import lombok.AllArgsConstructor; import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.io.File; +import java.util.List; @Data @AllArgsConstructor public class Trail { - private String trailsId; + private Long trailsId; private String trailName; private String trailNumber; + private String imgPath; + + public Trail(Long trailsId, String trailName, String trailNumber) { + this.trailsId = trailsId; + this.trailName = trailName; + this.trailNumber = trailNumber; + } - public String getTrailsId() { + public Long getTrailsId() { return trailsId; } @@ -24,5 +37,19 @@ public class Trail { return trailNumber; } + public String getTrailLink(){ + String[] split = trailName.split(" "); + return String.join("-", split); + } + + + public String getImagePath(){ + /* Finds the image in the Path folder, if image is not found assigns default image */ + String imgPath = "images/trails/trail" + trailsId + ".jpg"; + String notFoundPath = "images/trails/trailNotFound.jpg"; + + File imgFile = new File("src/main/resources/static/" + imgPath); + return imgFile.exists() ? imgPath : notFoundPath; + } } diff --git a/src/main/java/Team5/SmartTowns/data/TrailsRepository.java b/src/main/java/Team5/SmartTowns/data/TrailsRepository.java index 7e55ce7d32a732cf645dedabf478d77dbc1b26a9..240334862a1d086df9f686838ea7aade4c38ec65 100644 --- a/src/main/java/Team5/SmartTowns/data/TrailsRepository.java +++ b/src/main/java/Team5/SmartTowns/data/TrailsRepository.java @@ -6,4 +6,8 @@ import java.util.List; public interface TrailsRepository { List<Trail> getAllTrails(); String getTrailNameWithID(String trailsID); + + List<Trail> getAllTrailsFromCity(String cityName); + + int getTrailIDFromTrailName(String trailsName); } diff --git a/src/main/java/Team5/SmartTowns/data/TrailsRepositoryJDBC.java b/src/main/java/Team5/SmartTowns/data/TrailsRepositoryJDBC.java index 695ba5b9faff496b3ee941f6cae25b40ab2996ad..68549602aea6ce0f854909e10aa2bce8f7c9d254 100644 --- a/src/main/java/Team5/SmartTowns/data/TrailsRepositoryJDBC.java +++ b/src/main/java/Team5/SmartTowns/data/TrailsRepositoryJDBC.java @@ -17,7 +17,7 @@ public class TrailsRepositoryJDBC implements TrailsRepository { } private void settrailsMapper(){ trailMapper = (rs, i) -> new Trail( - rs.getString("trailID"), + rs.getLong("trailID"), rs.getString("trailName"), rs.getString("trailNumber") ); @@ -35,5 +35,16 @@ public class TrailsRepositoryJDBC implements TrailsRepository { } + @Override + public List<Trail> getAllTrailsFromCity(String cityName) { + String sql = "SELECT * FROM trails WHERE city = ?"; + return jdbc.query(sql, trailMapper, cityName); + } + + @Override + public int getTrailIDFromTrailName(String trailsName){ + return jdbc.queryForObject("SELECT trailID FROM trails WHERE trailName=?", Integer.class, trailsName); + } + } diff --git a/src/main/java/Team5/SmartTowns/dragonstale/DragonsTale.java b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTale.java new file mode 100644 index 0000000000000000000000000000000000000000..c83257f683812efd8633eeb2fdfc78dafe973777 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTale.java @@ -0,0 +1,19 @@ +package Team5.SmartTowns.dragonstale; + +import Team5.SmartTowns.landmarks.Landmarks; + +import java.util.List; + +public class DragonsTale { + Landmarks landmarks = new Landmarks(); + private int landmarkID = landmarks.getLandmarkID(); + private String landmarkName = landmarks.getLandmarkName(); + private String landmarkDescription = landmarks.getLandmarkDescription(); + public static List<Landmarks> landmarksDragonstrail = List.of( + new Landmarks( 1, "A scent of...Dragon", "The Dragon has been spotted near by, find the QR code to continue" , "Start your discovery, at the sweet shop."), + new Landmarks( 2, "They've been found!", "Don't let them escape, find the next QR code to continue!", "Location test") + ); + public static List<Landmarks> getLandmarksDragonstrail() { + return landmarksDragonstrail; + } +} diff --git a/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleController.java b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleController.java new file mode 100644 index 0000000000000000000000000000000000000000..9066b1239a40d42aeaca7293c05a37529b5eaff5 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleController.java @@ -0,0 +1,60 @@ +package Team5.SmartTowns.dragonstale; + +import Team5.SmartTowns.landmarks.Landmarks; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; + +import java.util.List; + +import static Team5.SmartTowns.dragonstale.DragonsTale.landmarksDragonstrail; + + + +@RestController + +public class DragonsTaleController { + ModelAndView modelAndView; + + @GetMapping("/dragonstale") + public ModelAndView getDragonsTale(){ + List<Landmarks> landmarksList = landmarksDragonstrail; + int landmarksListSize = landmarksDragonstrail.size(); + modelAndView = new ModelAndView("/dragonstale/index") + .addObject("landmarksList", landmarksList) + .addObject("getListSize", landmarksListSize); + return modelAndView; + } + + @GetMapping ("/QRScan") //In here, we could use trailID as a string variable and use it to track what trail the user clicked from. + public ModelAndView getQRScanner(){ + modelAndView = new ModelAndView("fragments/qr-scanner"); + //Can we extract the pathvariable in a JS function? + return modelAndView; + } + +// @GetMapping("/dragonstale/{landmarkID}") +// public Integer getDTLandmarkID(@RequestParam(value="landmarkID") int landmark){ +// Integer idCounter = 0; +// modelAndView = new ModelAndView("/dragonstale/{landmarkID}") +// .addObject() //All your doing is retrieving the information from the database giving it to a string variable. +// } + + //Create another controller that directs to the given DragonsTale..Trail.. and updates the users account accordingly. + +// This code is to be used +// @GetMapping("dragonstale/{qrCode}/{id}") +// public String qrCodeCheck(@PathVariable Optional<String> qrCode, @PathVariable Optional<Integer> id){ +// if (qrCode.isPresent()){ +// +// //Check if ID is present, if do this, if not dfo that. +// +// } +// } + + + +} diff --git a/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleJDBC.java b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleJDBC.java new file mode 100644 index 0000000000000000000000000000000000000000..f87b13aa37b413b9bb284b7cb14b6924b0aad75c --- /dev/null +++ b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleJDBC.java @@ -0,0 +1,30 @@ +package Team5.SmartTowns.dragonstale; + +import Team5.SmartTowns.users.User; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DragonsTaleJDBC implements DragonsTaleRepository{ + private JdbcTemplate jdbc; + + private RowMapper<User> userMapper; + +// @Override +// public Map<Long, Boolean> getDTCompletion(int landmarkID){ +// //Be conscious of sql injections here. +// String sql = "SELECT userid, trailID, completedOrNot FROM dtprogress WHERE landmarkID = ?"; +// int dtQuery = jdbc.query(sql, landmarkID); +// //Query it twice to extract the given parameters, then use these parameters in a loop to query the completion. +// List<Map<String, Integer>> query = jdbc.query(sql, id); +// +// Map<Long, Boolean> dtProgress = new HashMap<>(); +// for (Map<String, Object> result : dtQuery) { +// dtProgress.put((Long)result.get("stickerID"), (boolean)result.get("hasSticker")); +// } +// return dtProgress; +// } +} diff --git a/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleRepository.java b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..1439cfb9f4b389221c3c6e923b5b654fcb271421 --- /dev/null +++ b/src/main/java/Team5/SmartTowns/dragonstale/DragonsTaleRepository.java @@ -0,0 +1,4 @@ +package Team5.SmartTowns.dragonstale; + +public interface DragonsTaleRepository { +} diff --git a/src/main/java/Team5/SmartTowns/landmarks/LandmarksController.java b/src/main/java/Team5/SmartTowns/landmarks/LandmarksController.java index a5679aad7406be423fa165f553694ef1d02878a5..f7005bed0229ebaffaa4ee283fb5368001694cec 100644 --- a/src/main/java/Team5/SmartTowns/landmarks/LandmarksController.java +++ b/src/main/java/Team5/SmartTowns/landmarks/LandmarksController.java @@ -2,6 +2,8 @@ package Team5.SmartTowns.landmarks; import Team5.SmartTowns.data.Location; import Team5.SmartTowns.data.LocationRepository; +import Team5.SmartTowns.placeswithcoordinates.LocationsCoordinates; +import Team5.SmartTowns.placeswithcoordinates.PlacesCoordinatesRepository; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -11,14 +13,16 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; + +import java.util.List; //import jakarta.validation.Valid; @Controller public class LandmarksController { -// Controllers for LandmarkFormTh.html landmark submission form + // Controllers for LandmarkFormTh.html landmark submission form @GetMapping("/landmarkSubmission") - public ModelAndView landmarkSubmission(){ + public ModelAndView landmarkSubmission() { ModelAndView modelAndView1 = new ModelAndView("Landmarks/LandmarkFormTh.html"); modelAndView1.addObject("landmarkData", new Landmarks()); return modelAndView1; @@ -27,30 +31,68 @@ public class LandmarksController { @Autowired private LocationRepository locationRepository; + @PostMapping("/landmarkSub") - public ModelAndView landmarkSent(@Valid @ModelAttribute("landmarkData") Landmarks landmarks, BindingResult bindingResult, Model model ) { + public ModelAndView landmarkSent(@Valid @ModelAttribute("landmarkData") Landmarks landmarks, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { ModelAndView modelAndView = new ModelAndView("Landmarks/LandmarkFormTh.html", model.asMap()); return modelAndView; - } else{ + } else { // converts valid response using Location constructor into a submittable format to the sql table - Location loc= new Location(landmarks.getLandmarkName(), landmarks.getLandmarkEmail(), landmarks.getLandmarkDescription(), landmarks.getLandmarkLocation(), landmarks.getTrailID(), false); + Location loc = new Location(landmarks.getLandmarkID(), landmarks.getLandmarkName(), landmarks.getLandmarkEmail(), landmarks.getLandmarkDescription(), landmarks.getLandmarkLocation(), landmarks.getTrailID(), false); locationRepository.addLocation(loc); // adds valid landmark to locations table ModelAndView modelAndView = new ModelAndView("redirect:/home"); return modelAndView; } + } + @Autowired + private PlacesCoordinatesRepository placesCoordinatesRepo; + // For form that allows an administrator to add an unapproved location to a trail + @GetMapping("/checkpointApproval") + public ModelAndView adminCheckpointApproval() { + List<Location> unapprovedLocations = locationRepository.getAllUnapprovedLocations(); //change to unauthorised once merger 68 accepted!! todo - + ModelAndView modelAndView = new ModelAndView("Landmarks/locationApprovalFormTh.html"); + modelAndView.addObject("uLocs", unapprovedLocations); + modelAndView.addObject("location", new Location()); + modelAndView.addObject("locationCoord", new LocationsCoordinates()); + return modelAndView; } + @PostMapping("/checkpointSubmitted") + public ModelAndView checkpointSent(@Valid LocationsCoordinates locCoord, Location location, BindingResult bindingResult, Model model) { + + if (bindingResult.hasErrors()) { + ModelAndView modelAndView = new ModelAndView("Landmarks/locationApprovalFormTh.html", model.asMap()); + return modelAndView; + + } else { + + int locationID = locationRepository.nametoLocationID(location.getLocationName()); + // converts valid response using Location constructor into a submittable format to the sql table + LocationsCoordinates ALocCoord = new LocationsCoordinates(locationID, locCoord.getLocationCoordsLat(), locCoord.getLocationCoordsLong()); + boolean checkIfCoorsWithinBoundaries = placesCoordinatesRepo.checkIfCoordsAreWithinTownBoundary(ALocCoord); + if (checkIfCoorsWithinBoundaries==false){ // if coords outside associated town, form is returned to original state + return new ModelAndView("redirect:/checkpointApproval"); + } + placesCoordinatesRepo.addLocationCoord(ALocCoord); // adds valid landmark to locations table + locationRepository.updateApprovalStatus(locationID); // updates approval status accordingly + System.out.println(placesCoordinatesRepo.getAllLocationCoords()); + ModelAndView modelAndView = new ModelAndView("redirect:/home"); //redirects back top form in case admin wants to input second location + return modelAndView; + +// } + } + } } + diff --git a/src/main/java/Team5/SmartTowns/localauthority/localAuthority.java b/src/main/java/Team5/SmartTowns/localauthority/localAuthority.java index eb84e592ee40b1eb460d03bbb1530db38fcc86df..decaa05fc7131343c584bbec024ba2000c236ffd 100644 --- a/src/main/java/Team5/SmartTowns/localauthority/localAuthority.java +++ b/src/main/java/Team5/SmartTowns/localauthority/localAuthority.java @@ -16,7 +16,7 @@ public class localAuthority { private String city; private String county; private String postcode; - private URL website; + private String website; @Override public String toString() { return "Local Authority:" + " " + @@ -52,7 +52,7 @@ public class localAuthority { return postcode; } - public URL getWebsite() { + public String getWebsite() { return website; } } diff --git a/src/main/java/Team5/SmartTowns/localauthority/localAuthorityRepositoryJDBC.java b/src/main/java/Team5/SmartTowns/localauthority/localAuthorityRepositoryJDBC.java index e2039617c8a8d1f8891ed869efb2c5f6588be215..bdaa4fec44b1936ee45bd464f656e0c4c0a8393e 100644 --- a/src/main/java/Team5/SmartTowns/localauthority/localAuthorityRepositoryJDBC.java +++ b/src/main/java/Team5/SmartTowns/localauthority/localAuthorityRepositoryJDBC.java @@ -24,7 +24,7 @@ public class localAuthorityRepositoryJDBC implements localAuthorityRepository { rs.getString("city"), rs.getString("county"), rs.getString("postcode"), - rs.getURL("website") + rs.getString("website") ); } public List<localAuthority> getAllLocalAuthority(){ diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/LocationsCoordinates.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/LocationsCoordinates.java index a242df3e8b84cee08f3fcdf044e550a49b111343..c5560e0538efef8202d15feca37a1bc027a9f65e 100644 --- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/LocationsCoordinates.java +++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/LocationsCoordinates.java @@ -4,6 +4,10 @@ package Team5.SmartTowns.placeswithcoordinates; import Team5.SmartTowns.data.Location; import Team5.SmartTowns.data.LocationRepositoryJDBC; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -18,7 +22,12 @@ import java.util.List; public class LocationsCoordinates { /// separate class to location to cover all locations within trails that have been approved and have long/lat coords attached for mapping. private int locationID; +// @NotEmpty(message = "You must enter a Latitude.") +// @Min(value=0,message = "You must enter a Latitude.") private Double locationCoordsLat; + +// @NotEmpty(message = "You must type in a Longitude.") +// @Min(value=0,message = "You must type in a Longitude.") private Double locationCoordsLong; private JdbcTemplate jdbc; @@ -104,8 +113,13 @@ public class LocationsCoordinates { /// Need a constructor to create a locations list, approved collation list, unapproved locations list. - - - - + @Override + public String toString() { + return "LocationsCoordinates{" + + "locationID=" + locationID + + ", locationCoordsLat=" + locationCoordsLat + + ", locationCoordsLong=" + locationCoordsLong + + ", jdbc=" + jdbc + + '}'; + } } diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java index 6511067e9e636a29d96063357df1e3c7bc4f34e6..b9f08193e5f31d8285e385cc6c9495cc15ddf3b1 100644 --- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java +++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java @@ -4,6 +4,8 @@ import Team5.SmartTowns.data.Location; import Team5.SmartTowns.data.LocationRepository; import Team5.SmartTowns.data.Trail; import Team5.SmartTowns.data.TrailsRepository; +import Team5.SmartTowns.rewards.RewardsRepository; +import Team5.SmartTowns.users.UserRepository; import jakarta.validation.constraints.Max; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -16,6 +18,7 @@ import org.springframework.web.servlet.ModelAndView; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Controller public class PlacesController { @@ -28,6 +31,9 @@ public class PlacesController { @Autowired private TrailsRepository trailsRepo; + @Autowired + private RewardsRepository rewardsRepository; + @GetMapping("/checkpoints") public ModelAndView getLocationPages(){ @@ -107,9 +113,22 @@ public class PlacesController { break;} } ModelAndView modelAndView= new ModelAndView("fragments/trailsPageFrags :: trailsSection"); + System.out.println(locCoords.get(0).getLocationID()); + System.out.println(approvedLocations.get(0).getLocationID()); +// locations[indexValue.index].getLocationTrailID()==trail.getTrailsId()} + + + final int trailIDFINAL = trailID; + List<Location> finalLocations = approvedLocations.stream() + .filter(loc -> Long.parseLong(loc.getLocationTrailID()) == trailslocations.get(trailIDFINAL).getTrailsId()) + .toList(); + System.out.println(finalLocations); + modelAndView.addObject("trail", trailslocations.get(trailID)); modelAndView.addObject("locCoords", locCoords); - modelAndView.addObject("locations", approvedLocations); + modelAndView.addObject("locations", finalLocations); + + modelAndView.addObject("stickers", rewardsRepository.getAllStickersFromPack(1)); return modelAndView; } diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepository.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepository.java index deea368752b4b41bebd49147ce2266e64d942440..cbc0e82225cc285b0c269069627bd92e25ba37fc 100644 --- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepository.java +++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepository.java @@ -13,6 +13,12 @@ public interface PlacesCoordinatesRepository { List<TownWithTrails> getAllTownCoords(); void addTownWithCoords(TownWithTrails town); + int getLocationTableIDValue(List<Location> locations, String locationName); + + Boolean checkIfCoordsAreWithinTownBoundary(LocationsCoordinates loc); + + int getTownIDFromName(String townsName); + // List<Location> getFullApprovedLocations(JdbcTemplate aJdbc); diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepositoryJDBC.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepositoryJDBC.java index b90ee0b152d8734e8034e7cc33cd31585ea85fc4..a7a7dc86900df8bdfb0c0dd080fcced6d123d313 100644 --- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepositoryJDBC.java +++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesRepositoryJDBC.java @@ -1,8 +1,8 @@ package Team5.SmartTowns.placeswithcoordinates; import Team5.SmartTowns.data.Location; -import Team5.SmartTowns.data.LocationRepositoryJDBC; -import org.springframework.boot.autoconfigure.integration.IntegrationProperties; +import Team5.SmartTowns.data.LocationRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; @@ -88,6 +88,11 @@ public class PlacesCoordinatesRepositoryJDBC implements PlacesCoordinatesReposit // } + + + + + public boolean checkInputtedCoordsMatchTown(String inpLatCoords, String inpLongCoords, String townName){ PlacesCoordinatesRepositoryJDBC jbdcsecond = new PlacesCoordinatesRepositoryJDBC(jdbc); List<TownWithTrails> allTowns = jbdcsecond.getAllTownCoords(); @@ -116,7 +121,9 @@ public class PlacesCoordinatesRepositoryJDBC implements PlacesCoordinatesReposit } } return true;} - int getLocationTableIDValue(List<Location> locations, String locationName){ + + @Override + public int getLocationTableIDValue(List<Location> locations, String locationName){ int index; for(int i=0;i<locations.size();i++){ if (Objects.equals(locations.get(i).getLocationName(), locationName)){ @@ -128,7 +135,37 @@ public class PlacesCoordinatesRepositoryJDBC implements PlacesCoordinatesReposit } + @Autowired + LocationRepository local; + @Override + public Boolean checkIfCoordsAreWithinTownBoundary(LocationsCoordinates loc){ + int locationID=loc.getLocationID(); + String locationTown= jdbc.queryForObject("SELECT locationPlace FROM locations WHERE locationID=?", String.class, locationID); + List<TownWithTrails> allTowns = getAllTownCoords(); + for (int i=0;i<allTowns.size();i++){ + if (Objects.equals(allTowns.get(i).getTownName(), locationTown)){ + + + double inpLat=(loc.getLocationCoordsLat()); + double inpLong=(loc.getLocationCoordsLong()); + + double townBoundaryLatUppermost=Double.parseDouble(allTowns.get(i).getTownUppermostCoordsLat()); + double townBoundaryLatLowermost=Double.parseDouble(allTowns.get(i).getTownLowermostCoordsLat()); + + double townBoundaryLongLeftmost=Double.parseDouble(allTowns.get(i).getTownLeftmostCoordsLong()); + double townBoundaryLongRightmost=Double.parseDouble(allTowns.get(i).getTownRightmostCoordsLong()); + // check coords within respective town boundary (boundary decided by rough google maps red-line) + if ( (inpLat<=townBoundaryLatUppermost)&& (inpLat>=townBoundaryLatLowermost) && (inpLong>=townBoundaryLongLeftmost) && (inpLong<=townBoundaryLongRightmost)){ + // location within boundary returns true + return true; + }} + } return false; // if location outside boundary, return true won't function and it wil return false. + } + @Override + public int getTownIDFromName(String townsName){ + return jdbc.queryForObject("SELECT townID FROM townswithtrails WHERE townName=?", Integer.class, townsName); + } // Method used to approve and add locations with associated coordinates. List<Location> unapprovedLocations // public void approveLocationAndAddCoords(String locationsName, Double latCoords, Double longCoords,JdbcTemplate jdbc) { diff --git a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java index ef2490fe86e95dbc73ed89e103f5370b2760c904..f6ef3bd588a34b002e0df70b37faa90fed95a427 100644 --- a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java +++ b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java @@ -2,6 +2,7 @@ package Team5.SmartTowns.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -10,6 +11,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; @@ -28,10 +30,11 @@ public class SecurityConfiguration { .authorizeHttpRequests((requests) -> requests .requestMatchers("/user/**", "/userProfile").authenticated() .anyRequest().permitAll() + ) .formLogin((login) -> login .loginPage("/login").permitAll() - .defaultSuccessUrl("/userProfile") + .defaultSuccessUrl("/mobile-home") ) .logout((logout) -> logout.permitAll()); diff --git a/src/main/java/Team5/SmartTowns/towns/TownController.java b/src/main/java/Team5/SmartTowns/towns/TownController.java index 9063712be2de660379c504bb064254367dcaa3d8..d31409b3409c4b3e50cc8994e25ce3c6d2406506 100644 --- a/src/main/java/Team5/SmartTowns/towns/TownController.java +++ b/src/main/java/Team5/SmartTowns/towns/TownController.java @@ -1,21 +1,66 @@ package Team5.SmartTowns.towns; +import Team5.SmartTowns.data.Location; +import Team5.SmartTowns.data.Town; +import Team5.SmartTowns.data.LocationRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; @Controller public class TownController { + @Autowired + private LocationRepository locationRepository; + @Autowired + private Team5.SmartTowns.data.TownRepository townRepository; @GetMapping("/home") public ModelAndView getTownList(){ - ModelAndView modelAndView = new ModelAndView("Towns/home/homePage"); + ModelAndView modelAndView = new ModelAndView("towns/home/homePage"); TownStorage townsCurrent= new TownStorage().getInstance(); List<Towns> towns = townsCurrent.getTownList(); modelAndView.addObject("towns",towns); return modelAndView; } + @GetMapping("/mobile-home") + public ModelAndView getTownListMobile(){ + ModelAndView modelAndView = new ModelAndView("towns/home/mobile-homepage"); + TownStorage townsCurrent= new TownStorage().getInstance(); + List<Towns> towns = townsCurrent.getTownList(); + modelAndView.addObject("towns",towns); + return modelAndView; + + } + + @GetMapping("/home/town/Caerphilly") + public ModelAndView getATownTrailsList(){ + ModelAndView modelAndView = new ModelAndView("userTrails/userTrailsTemplate"); + TownStorage townsCurrent= new TownStorage().getInstance(); + List<Towns> towns = townsCurrent.getTownList(); + List<Town> Towns = townRepository.getAllTowns(); + modelAndView.addObject("towns", Towns); + List<Location> Locations = locationRepository.getAllLocation(); + Locations= filterByLocationForTrails(Locations, "Caerphilly"); + modelAndView.addObject("locations", Locations); + return modelAndView; + } + + public List<Location> filterByLocationForTrails(List<Location> locationList , String town){ + List<Location> filteredList = new ArrayList<Location>();; + for( Location location:locationList){ + if (Objects.equals(location.getLocationPlace(), town)){ + filteredList.add(location); + } + + }return filteredList; + + } + + } diff --git a/src/main/java/Team5/SmartTowns/towns/TownStorage.java b/src/main/java/Team5/SmartTowns/towns/TownStorage.java index 988a20223b33d27fbccab94007a1efb6e3088bbb..3b86208bbb9818e61ef2a50e1084b416535d108a 100644 --- a/src/main/java/Team5/SmartTowns/towns/TownStorage.java +++ b/src/main/java/Team5/SmartTowns/towns/TownStorage.java @@ -12,8 +12,8 @@ public class TownStorage { townList.addAll( List.of( new Towns("Caerphilly",01,3,70,"/images/banners/CaerphillyCastle.jpg"), - new Towns("Risca",02,2,34,"/images/banners/RiscaBanner.jpg"), - new Towns("Penarth",03,5,0,"/images/banners/PenarthBanner.jpg"), + new Towns("Risca",02,1,34,"/images/banners/RiscaBanner.jpg"), + new Towns("Penarth",03,1,0,"/images/banners/PenarthBanner.jpg"), new Towns("Penarth",03,5,50,"/images/banners/PenarthBanner.jpg"), new Towns("Caerphilly",01,3,70,"/images/banners/CaerphillyCastle.jpg"), new Towns("Risca",02,2,90,"/images/banners/RiscaBanner.jpg"), diff --git a/src/main/java/Team5/SmartTowns/towns/Towns.java b/src/main/java/Team5/SmartTowns/towns/Towns.java index ebe6fd4797c205ace803727026e64837a2af93e6..677faf85a287ac8903edcbf9ff4395a234d9e44f 100644 --- a/src/main/java/Team5/SmartTowns/towns/Towns.java +++ b/src/main/java/Team5/SmartTowns/towns/Towns.java @@ -59,4 +59,23 @@ public class Towns { this.trailProgress = trailProgress; this.imageTown = imageTown; } + + public String setTrailProgressClass() { + /*SUGGESTION INSTEAD OF DOING THIS IS THE HTML*/ + String progress; + if (trailProgress < 50) { + progress = "notComplete"; + } else if (trailProgress < 70) { + progress = "farComplete"; + } else if (trailProgress < 90) { + progress = "nearComplete"; + } else if (trailProgress < 100) { + progress = "closeComplete"; + } else { + progress = "Complete"; + } + return progress; + } + + } diff --git a/src/main/java/Team5/SmartTowns/trails/Trail.java b/src/main/java/Team5/SmartTowns/trails/Trail.java deleted file mode 100644 index a7067f83758ce0904851b89a51880dc9782da104..0000000000000000000000000000000000000000 --- a/src/main/java/Team5/SmartTowns/trails/Trail.java +++ /dev/null @@ -1,40 +0,0 @@ -package Team5.SmartTowns.trails; - -import lombok.Data; - -import java.io.File; -import java.util.List; - -@Data -public class Trail { - public static List<Trail> trails = List.of( - new Trail(1,"Caerphilly Castle Trail", "Take a stroll through the grounds of one of Europe's finest historic buildings and you will see stunning views of the castle and the lakes. The route of the trail is marked with eight special circular markers, which depict various fascinating historical facts relating to the castle. Pupils from Ysgol Gynradd Gymraeg Caerffili, Plasyfelin Junior School, Ysgol Y Castell and Twyn Primary worked with the artist to come up with the different designs. You do not need to pay to go in the castle to complete this trail. This Trail is fairly short at 1.5 miles and very suitable for wheelchairs and pushchairs as the route stays mostly on well-marked and ramped paths with just a couple of short diversions onto grassed areas."), - new Trail(2,"Trail2", "This is trail two"), - new Trail(3,"Trail3", "This is trail three"), - new Trail(4,"Trail4", "This is trail four"), - new Trail(5,"A Dragon's Tale", "EDITING THIS") - ); - - int id; - String name; - String description; - int nLandmarks; - int difficulty; //1-5 - String imgPath; - - public Trail(int id, String name, String description) { - this.id = id; - this.name = name; - this.description = description; - imgPath = findImagePath(); - } - - private String findImagePath(){ - /* Finds the image in the Path folder, if image is not found assigns default image */ - String imgPath = "images/trails/trail" + id + ".jpg"; - String notFoundPath = "images/trails/trailNotFound.jpg"; - - File imgFile = new File("src/main/resources/static/" + imgPath); - return imgFile.exists() ? imgPath : notFoundPath; - } -} diff --git a/src/main/java/Team5/SmartTowns/trails/TrailsController.java b/src/main/java/Team5/SmartTowns/trails/TrailsController.java index c6472019b4e17f3ff6aa4c60188ad524bfc10010..0a6aaa6de004d10f283016f6d1c4ad53f640abcd 100644 --- a/src/main/java/Team5/SmartTowns/trails/TrailsController.java +++ b/src/main/java/Team5/SmartTowns/trails/TrailsController.java @@ -1,7 +1,13 @@ package Team5.SmartTowns.trails; +import Team5.SmartTowns.data.LocationRepository; +import Team5.SmartTowns.data.LocationRepositoryJDBC; +import Team5.SmartTowns.data.Trail; +import Team5.SmartTowns.data.TrailsRepository; import Team5.SmartTowns.landmarks.Landmarks; +import Team5.SmartTowns.placeswithcoordinates.PlacesCoordinatesRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -11,16 +17,18 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import static Team5.SmartTowns.landmarks.Landmarks.landmarksDragonstrail; - //import static Team5.SmartTowns.Landmarks.Landmarks.landmarksDragonstrail; @Controller public class TrailsController { - @GetMapping("/allTrails") - public ModelAndView getAllTrails(){ + + @Autowired + private TrailsRepository trailsRepository; + + @GetMapping("/allTrails-{city}") + public ModelAndView getAllTrails(@PathVariable String city){ ModelAndView mav = new ModelAndView("allTrails/allTrails"); - mav.addObject("trails", Trail.trails); //Mock data for trails + mav.addObject("trails", trailsRepository.getAllTrailsFromCity(city)); //Mock data for trails return mav; } @RequestMapping(value="/id", method=RequestMethod.POST) @@ -32,30 +40,11 @@ public class TrailsController { @GetMapping("/allTrails/{id}") public ModelAndView getResultBySearchKey(@PathVariable int id) { - List<Trail> trailList= Trail.trails;//results from db + List<Trail> trailList = trailsRepository.getAllTrails();//results from db ModelAndView mv= new ModelAndView("fragments/allTrailsFrags :: trailSection"); mv.addObject("trail", trailList.get(id-1)); return mv; } - @GetMapping("/dragonstale") - public ModelAndView getDragonsTale(){ - List<Landmarks> landmarksList = landmarksDragonstrail; - ModelAndView modelAndView = new ModelAndView("towns/trails/dragonstale/index"); - modelAndView.addObject("landmarksList", landmarksList); - return modelAndView; - } - - - // -// @GetMapping("dragonstale/{qrCode}/{id}") -// public String qrCodeCheck(@PathVariable Optional<String> qrCode, @PathVariable Optional<Integer> id){ -// if (qrCode.isPresent()){ -// -// //Check if ID is present, if do this, if not dfo that. -// -// } -// } - } diff --git a/src/main/java/Team5/SmartTowns/users/UserController.java b/src/main/java/Team5/SmartTowns/users/UserController.java index e1acd4b66f1546db506ec5313c5680122e05587d..e9fd1bef1b655dad57a0550739cbaad74e996e38 100644 --- a/src/main/java/Team5/SmartTowns/users/UserController.java +++ b/src/main/java/Team5/SmartTowns/users/UserController.java @@ -43,7 +43,7 @@ public class UserController { // return mav; // } - @PostMapping("/login/register") + @PostMapping("/register") public ModelAndView registerUser(@Valid @ModelAttribute("user") NewUser user, BindingResult bindingResult, Model model) { ModelAndView mav = new ModelAndView("users/login", model.asMap()); // TODO VALIDATE EMAIL INPUT @@ -51,19 +51,12 @@ public class UserController { if (bindingResult.hasErrors()) { ModelAndView modelAndView = new ModelAndView("users/login"); modelAndView.addObject("errors", bindingResult); + modelAndView.addObject("error", ""); return modelAndView; } - - if ( userRepository.doesUserExist(user.getEmail()) ) { - mav.addObject("errors", "Email already in use"); - return mav; - } - try { userRepository.addUser(user.name, user.email, user.password); - mav.addObject("error", ""); - //TODO return user creation success - return mav; + return new ModelAndView("redirect:/login?register"); } catch (DataAccessException e) { mav.addObject("error", "User exists"); } @@ -83,12 +76,14 @@ public class UserController { } + /* 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; @@ -102,13 +97,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/application.properties b/src/main/resources/application.properties index 52e81d219c68d4702643665e6f9d58c7aebb8308..fc40c9e4004d1b4e83234ecefecf308e3e4871b8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.datasource.url=jdbc:mariadb://localhost:3306/towns +spring.datasource.url=jdbc:mariadb://localhost:3306/ spring.datasource.username=root spring.datasource.password=comsc diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 361a1ded4285f58aad0d80e1018d419a0d1bc4f0..7d1cef56ac46ccf4ed4a8990a2142825708d67be 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,73 +1,44 @@ -delete from users; -insert into users (email, name, dragonProgress) value ('hannah@gmail.com', 'Hannah', '90'); -insert into users (userID, email, name, dragonProgress) value ('2', 'nigel@gmail.com', 'Nigel', '40'); - delete from trails; -insert into trails ( Name) value ( 'Caerphilly Coffee Trail'); -insert into trails ( Name) value ( 'Penarth Dragon Trail'); +insert into trails ( trailID, trailName, trailNumber, city) value ( 0101,'Caerphilly Castle Trail','0101', 'Caerphilly'); +insert into trails ( trailID, trailName, trailNumber, city) value ( 0102,'Caerphilly Pub Trail','0102', 'Caerphilly'); +insert into trails ( trailID, trailName, trailNumber, city) value ( 0103,'Caerphilly Heritage Trail','0103', 'Caerphilly'); +insert into trails ( trailID, trailName, trailNumber, city) value ( 0201,'Risca Heritage Trail','0201', 'Risca'); +insert into trails ( trailID, trailName, trailNumber, city) value ( 0301,'Penarth Esplanade Trail','0301', 'Penarth'); delete from locations; -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'St Cenydd','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'The Castle','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Medieval Trades','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'The Queen''s War','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'The Green Lady','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Armoury','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Architecture','','Location description here','Caerphilly',0101); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( '21st Century Landmark','','Location description here','Caerphilly',0101); - -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'JD Wetherspoons-Malcolm Uphill','','Location description here','Caerphilly',0102); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Caerphilly Cwtch','','Location description here','Caerphilly',0102); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Caerphilly Conservative Club','','Location description here','Caerphilly',0102); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'The King''s Arms','','Location description here','Caerphilly',0102); - -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Caerphilly Bus Station','','Location description here','Caerphilly',0103); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'The Medieval Courthouse','','Location description here','Caerphilly',0103); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ('Caerphilly Castle','','Location description here','Caerphilly',0103); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Ty Vaughan House','','Location description here','Caerphilly',0103); - -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Risca Colliery','','Location description here','Risca',0201); -insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value ( 'Black Vein Colliery Disaster','','Location description here','Risca',0201); - - -insert into locations (locationID, locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value (19, 'The Esplanade','','Location description here','Penarth',0301); -insert into locations (locationID, locationName , locationEmail,locationDescription,locationPlace, locationTrailID) value (20, 'The Old Swimming Baths','','Location description here','Penarth',0301); -delete from badges; -insert into badges (name, description, difficulty) value ('TownConnoisseur', 'You know the town very well!', '2'); -insert into badges (name, description, difficulty) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); -insert into badges (name, description, difficulty) value ('TownMaster', 'You visited the town 7 days in a row!', '1'); -insert into badges (name, description, difficulty) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); -insert into badges (name, description, difficulty) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); - -delete from stickers; -insert into stickers (name, description, rarity) value ('TownConnoisseur', 'You know the town very well!', '2'); -insert into stickers (name, description, rarity) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); -insert into stickers (name, description, rarity) value ('TownMaster', 'You visited the town 7 days in a row!', '1'); -insert into stickers (name, description, rarity) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); -insert into stickers (name, description, rarity) value ('TownRegular', 'You visited the town 3 days in a row!', '1'); - -delete from badgeprogress; -insert into badgeprogress (userID, badgeID, progress) value ('1', '1', '40'); -insert into badgeprogress (userID, badgeID, progress) value ('1', '2', '70'); -insert into badgeprogress (userID, badgeID, progress) value ('2', '2', '70'); - -<<<<<<< HEAD -delete from stickerprogress; -insert into stickerprogress (userID, stickerID, hasSticker) value ('1', '1', true); -insert into stickerprogress (userID, stickerID, hasSticker) value ('1', '3', true); -insert into stickerprogress (userID, stickerID, hasSticker) value ('2', '2', true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'St Cenydd','','Location description here','Caerphilly',0101, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Castle','','Location description here','Caerphilly',0101, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Medieval Trades','','Location description here','Caerphilly',0101, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Queen''s War','','Location description here','Caerphilly',0101, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Green Lady','','Location description here','Caerphilly',0101, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Armoury','','Location description here','Caerphilly',0101, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Architecture','','Location description here','Caerphilly',0101, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( '21st Century Landmark','','Location description here','Caerphilly',0101, false); + +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'JD Wetherspoons-Malcolm Uphill','','Location description here','Caerphilly',0102, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Caerphilly Cwtch','','Location description here','Caerphilly',0102, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Caerphilly Conservative Club','','Location description here','Caerphilly',0102, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The King''s Arms','','Location description here','Caerphilly',0102, false); + +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Caerphilly Bus Station','','Location description here','Caerphilly',0103, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Medieval Courthouse','','Location description here','Caerphilly',0103, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ('Caerphilly Castle','','Location description here','Caerphilly',0103, false); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Ty Vaughan House','','Location description here','Caerphilly',0103, false); + +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Risca Colliery','','Location description here','Risca',0201, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'Black Vein Colliery Disaster','','Location description here','Risca',0201, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Esplanade','','Location description here','Penarth',0301, true); +insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) value ( 'The Old Swimming Baths','','Location description here','Penarth',0301, true); -delete from localauthority; -insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Caerphilly County Borough Council', 'Tredomen Park','', 'Ystrad Mynach, Hengoed', '', 'CF82 7PG', 'https://www.caerphilly.gov.uk/main.aspx?lang=en-GB'); -insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Risca Town Council', 'Unit B, 75 Tredegar Street', '', 'Risca', '', 'NP11 6BW', 'https://www.riscatowncouncil.org.uk/'); -insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Penarth Town Council West House', 'Stanwell Road', '', 'Penarth', '', 'CF64 2YG', 'https://www.penarthtowncouncil.gov.uk/your-council/'); -======= -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'); + + +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'); + DELETE FROM stickers; INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUE (1, 1, 'wayne_hennessey', 'Wales Football Team Player', '2'); INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUE (1, 2, 'neco_williams', 'Wales Football Team Player', '2'); @@ -112,11 +83,14 @@ insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLon # insert into stickerprogress (userID, packID, stickerID) value (1, 2, 1); # insert into stickerprogress (userID, packID, stickerID) value (1, 2, 3); +delete from localauthority; +insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Caerphilly County Borough Council', 'Tredomen Park','', 'Ystrad Mynach, Hengoed', '', 'CF82 7PG', 'https://www.caerphilly.gov.uk/main.aspx?lang=en-GB'); +insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Risca Town Council', 'Unit B, 75 Tredegar Street', '', 'Risca', '', 'NP11 6BW', 'https://www.riscatowncouncil.org.uk/'); +insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) value ( 'Penarth Town Council West House', 'Stanwell Road', '', 'Penarth', '', 'CF64 2YG', 'https://www.penarthtowncouncil.gov.uk/your-council/'); # delete from townsWithTrails; insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) value ('Caerphilly', '51.57903','-3.22075 ','51.60418','51.55093','-3.25222','-3.17696'); insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) value ('Risca','51.61195','-3.09648','51.63039','51.59175','-3.12129','-3.06438'); -insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) value ('Penarth','51.43893','-3.17354','51.44878','51.41233','-3.20271','-3.16005'); ->>>>>>> 6464aaa8419c280b353cd943e44f8b09d831da64 +insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) value ('Penarth','51.43893','-3.17354','51.44878','51.41233','-3.20271','-3.16005'); \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 5f72a213d82e93621bf5d9d9d33cbff9a80a569f..e184f1c900c2612a6d2c4992e370ea053d357642 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,12 +1,35 @@ + +/* DELETES AND RECREATES DATABASE EVERY TIME THE SYSTEM IS BOOTED*/ +DROP DATABASE IF EXISTS towns; +CREATE DATABASE IF NOT EXISTS towns; +USE towns; +/****************************************************************/ + +/* DROPS ALL TABLES IF THEY EXIST (they wont but just in case) */ + +drop table if exists locationCoordinates; +drop table if exists locations; drop table if exists trails; +DROP TABLE IF EXISTS users; +DROP TABLE IF EXISTS stickers; +DROP TABLE IF EXISTS packs; +DROP TABLE IF EXISTS stickerProgress; + + + +/****************************************************************/ + +/* CREATES ALL TABLES */ create table if not exists trails ( - trailID bigint auto_increment primary key, - name varchar(128) + trailID varchar(128) primary key, + trailName varchar(128), + trailNumber varchar(128), + city varchar(128) ) engine=InnoDB; +drop table if exists locationCoordinates; drop table if exists locations; - create table if not exists locations ( locationID bigint auto_increment primary key, @@ -14,64 +37,60 @@ create table if not exists locations locationEmail varchar(128), locationDescription longtext, locationPlace varchar(255), - locationTrailID varchar(128) + locationTrailID varchar(128), + locationApproved boolean ) engine=InnoDB; -drop table if exists users; -create table if not exists users -( - userID bigint auto_increment primary key, - email varchar(128), - name varchar(128), - dragonProgress int -) engine=InnoDB; -drop table if exists badges; -create table if not exists badges -( - badgeID bigint auto_increment primary key, - name varchar(128), - description varchar(128), - difficulty bigint -) engine=InnoDB; +CREATE TABLE IF NOT EXISTS users ( + username varchar(30) primary key NOT NULL, + id bigint auto_increment unique, /*DEPRECATED COLUMN, LEFT IN WHILE SOME OTHER FUNCTIONS STILL USE IT*/ + email varchar(128), + password varchar(30) NOT NULL, + enabled boolean default true +); -drop table if exists stickers; -create table if not exists stickers -( - stickerID bigint auto_increment primary key, - name varchar(128), - description varchar(128), - rarity bigint -) engine=InnoDB; +CREATE TABLE IF NOT EXISTS authorities ( + id bigint primary key auto_increment NOT NULL, + username varchar(30) NOT NULL , + authority varchar(45) NOT NULL +); -drop table if exists badgeProgress; -create table if not exists badgeProgress -( - userID bigint, - badgeID bigint, - progress int /*0-100*/ -) engine=InnoDB; +CREATE TABLE IF NOT EXISTS packs ( + id bigint auto_increment primary key, + name varchar(20) NOT NULL, + description text +); -create table if not exists stickerProgress -( - userID bigint, - stickerID bigint, - hasSticker boolean /*Has sticker or not*/ -) engine=InnoDB; +CREATE TABLE IF NOT EXISTS stickers ( + id bigint auto_increment primary key, + packID bigint NOT NULL, + FOREIGN KEY (packID) REFERENCES packs(id) + ON DELETE CASCADE + ON UPDATE RESTRICT, + stickerID bigint NOT NULL, /*STICKER ID NUMBER WITHIN ITS OWN PACK*/ + name varchar(30) NOT NULL, + description text NOT NULL, + rarity tinyint +); +CREATE TABLE IF NOT EXISTS stickerProgress ( + id bigint auto_increment primary key, + username varchar(30) NOT NULL, + FOREIGN KEY (username) REFERENCES users(username) + ON DELETE CASCADE + ON UPDATE RESTRICT, + packID bigint NOT NULL, + FOREIGN KEY (packID) REFERENCES packs(id) + ON DELETE CASCADE + ON UPDATE RESTRICT, + stickerID bigint NOT NULL, + FOREIGN KEY (stickerID) REFERENCES stickers(id) + ON DELETE CASCADE + ON UPDATE RESTRICT +); -drop table if exists localAuthority; -create table if not exists localAuthority +create table if not exists locationCoordinates ( - localAuthorityID bigint auto_increment primary key, - localAuthorityName varchar(250), - address1 varchar(250), - address2 varchar(250), - city varchar(100), - county varchar(75), - postcode varchar(15), - website varchar(250) -) engine=InnoDB; -======= locationCoordID bigint auto_increment primary key, locationID bigint, Foreign Key (locationID) REFERENCES locations(locationID) @@ -98,3 +117,17 @@ create table if not exists townsWithTrails )engine=InnoDB; +drop table if exists localAuthority; +create table if not exists localAuthority +( + localAuthorityID bigint auto_increment primary key, + localAuthorityName varchar(250), + address1 varchar(250), + address2 varchar(250), + city varchar(100), + county varchar(75), + postcode varchar(15), + website varchar(250) +) engine=InnoDB; + + diff --git a/src/main/resources/static/css/allTrails.css b/src/main/resources/static/css/allTrails.css index 3c05b5fc85e808b887ae769fccefbf107efc12ce..ea3a17f56d38be864c8d56530e925ec3abc7e29f 100644 --- a/src/main/resources/static/css/allTrails.css +++ b/src/main/resources/static/css/allTrails.css @@ -1,55 +1,64 @@ -/** {*/ -/* box-sizing: border-box;*/ -/*}*/ -/*body {*/ -/* background-color: rgb(41, 41, 41);*/ -/* margin: 0;*/ -/* display: flex;*/ -/* flex-direction: column;*/ -/* min-height: 100svh;*/ -/*}*/ -/*main {*/ -/*}*/ +#allTrailsBar { + width: 100%; + min-height: 70svh; + /*margin: 1svh auto;*/ + display: flex; + flex-direction: column; + justify-content: space-evenly; + position: relative; -/*.centerFlex {*/ -/* display: flex;*/ -/* justify-content: center;*/ -/*}*/ -/*#allTrailsBar {*/ -/* width: 100%;*/ -/* height: auto;*/ -/* !*margin: 1svh auto;*!*/ -/* padding: 0 5svh;*/ -/* display: flex;*/ -/* flex-wrap: wrap;*/ -/* justify-content: space-evenly;*/ +} -/*}*/ -/*.trailsImages {*/ -/* margin: 1svh auto;*/ -/* height: 12svh;*/ -/* width: auto;*/ -/* border-radius: 20px;*/ -/* border: solid grey 2px;*/ -/* transition: 0.5s ease-out 100ms;*/ -/* box-shadow: 0 10px 20px rgba(0, 0, 0, 0.85);*/ -/*}*/ +.trailWrapper { + position: relative; + display: flex; + width: 70vw; + height: 20svh; + margin-inline: auto; + & h1 { + display: flex; + width: 100%; + position: absolute; + align-items: flex-start; + padding-top: 1svh; + padding-bottom: 0.5svh; + text-align: center; + justify-content: center; + text-decoration: none; + color: white; + font-weight: 600; + text-shadow: rgba(0, 0, 0, 0.2) 0 1svh 1svh; + font-size: 2em; + border-bottom: black solid 2px; + background-color: rgba(31, 31, 31, 0.2); + border-radius: 20px 20px 0 0; + } +} -/*.trailsImages:hover {*/ -/* box-shadow: 0 0 20px 10px #bbbb00;*/ -/* transform: scale(1.2,1.2);*/ -/*}*/ +.trailsImages { + width: 100%; + height: 100%; + /*margin: 1svh 0;*/ + /*height: auto;*/ + /*aspect-ratio: 1;*/ + border-radius: 20px; + border: solid grey 4px; + transition: 0.5s ease-out 100ms; + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.85); +} -/*.selected {*/ -/* box-shadow: 0 0 20px 10px #bbbb00;*/ -/*}*/ -/*@keyframes fadeIn {*/ -/* 0% { opacity: 0; }*/ -/* 100% { opacity: 1; }*/ -/*}*/ -/*main {*/ -/* margin: 0;*/ -/*}*/ +.trailsImages:hover { + box-shadow: 0 0 20px 10px #bbbb00; + transform: scale(1.2,1.2); +} + +.selected { + box-shadow: 0 0 20px 10px #bbbb00; +} +@keyframes fadeIn { + 0% { opacity: 0; } + 100% { opacity: 1; } +} /*#trailInfoContainer {*/ @@ -125,10 +134,4 @@ /* display: flex;*/ /* min-height: 40svh;*/ /* flex-wrap: wrap;*/ - -/*}*/ - -/*header {*/ -/* box-shadow: #1e1e1e 0 0 10px 10px;*/ -/* font-size: 1vw;*/ -/*}*/ +/*}*/ \ No newline at end of file diff --git a/src/main/resources/static/css/colours.css b/src/main/resources/static/css/colours.css new file mode 100644 index 0000000000000000000000000000000000000000..fd5fc2bf78240e9a2b07b222cab37d118145e2a0 --- /dev/null +++ b/src/main/resources/static/css/colours.css @@ -0,0 +1,50 @@ +/* AUTHOR: Gabriel Copat + * Variable list for website palette, to be re-used throughout the site + * + * This makes it easy to change up the site's colours without having to go through + * each individual reference in the CSS +*/ + +/*FONTS*/ +@import url('https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap'); /*MedievalSharp*/ +@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap'); /*Montserrat*/ + +:root { + /*Variable Colours for Dark Theme Users + *************DEFAULT VALUES************ + */ + + --primary-colour: hsl(271, 100%, 20%); + --primary-dark: hsl(271, 100%, 15%); + --primary-darker: hsl(272, 100%, 10%); + --prim-shade-1:#632e93; + --prim-shade-2:#9159c2; + --prim-shade-3:#c285f3; + + --secondary-colour: #f2724a; + --accent-colour: #cc2f58; + --accent-secondary: #8f0065; + + /*DEFAULT TEXT COLOUR*/ + color: white; + font-family: 'Montserrat', sans-serif; + + + /*Variable Colours for Light Theme Users*/ + /*UN-IMPLEMENTED AS OF YET*/ + @media (prefers-color-scheme: light) { + /*--primary-darker: hsl(272, 100%, 10%);*/ + /*--primary-dark: hsl(271, 100%, 20%);*/ + /*--primary-colour: hsl(271, 100%, 30%);*/ + /*--primary-light: hsl(271, 100%, 40%);*/ + /*--primary-lighter: hsl(271, 100%, 50%);*/ + + /*--secondary-colour: hsl(12, 81%, 46%);*/ + /*--accent-colour: hsl(12, 82%, 32%);*/ + /*--accent-border: hsl(12, 81%, 25%);*/ + + /*--accent-shadow: rgba(0, 0, 0, 0.7) 0 0.5em 1em -0.5em;*/ + + /*color: white;*/ + } +} diff --git a/src/main/resources/static/css/dragonstaless.css b/src/main/resources/static/css/dragonstaless.css index 2f456a23299e5296a53d8c37f48d93345fe84a9a..2a0ecb3566ffa4d3e5a839c51d051423ba63f132 100644 --- a/src/main/resources/static/css/dragonstaless.css +++ b/src/main/resources/static/css/dragonstaless.css @@ -1,4 +1,4 @@ -.centre{ +body{ display: flex; flex-direction: column; text-align: center; @@ -8,6 +8,36 @@ background-color: #927BB7; } +.dropdown button{ + background-color: coral; + color: white; + padding: 25px; + font-size: 16px; + border: none; + cursor: pointer; +} + + +.dropdown .content{ + display: none; + position: absolute; + background-color: #D3B69C; + min-width:100px; + box-shadow: white; + z-index: 1; +} + +.dropdown:hover .content{ + display: block; +} + + +.images{ + max-width:100%; + height:auto; +} + + .landmarkName{ font-weight: bold; text-align: left; diff --git a/src/main/resources/static/css/homePageStyle.css b/src/main/resources/static/css/homePageStyle.css index 64f767d40b32ccef413ea7b749e11356ef045aa4..4d69af3c489fc11c8772ed8e68eda94d2d536b75 100644 --- a/src/main/resources/static/css/homePageStyle.css +++ b/src/main/resources/static/css/homePageStyle.css @@ -1,172 +1,264 @@ +@media only screen +and (min-device-width: 1000px) { + body { + background-color: rgb(41, 41, 41) + } + + #homeTitle { + grid-area: pageTitle; + color: whitesmoke; + } + + .submitLand { + grid-area: submitButton; + } + + .Banner { + margin-top: 20px; + background-color: darkslategrey; + margin-bottom: 20px; + /*border: solid 2px whitesmoke;*/ + /*border colour here at .banner and .bannertrail*/ + border-right: none; + } + + /* .BannerTrail.Complete(100%) .BannerTrail.closeComplete(90-99%) .BannerTrail.nearComplete(70-99%) .BannerTrail.farComplete(50-69%) .BannerTrail.notComplete(0-49%) */ + .BannerTrail, .BannerTrail.Complete, .BannerTrail.closeComplete, .BannerTrail.nearComplete, .BannerTrail.farComplete, .BannerTrail.notComplete { + margin-top: 20px; + margin-bottom: 20px; + border: solid 2px whitesmoke; + text-align: center; + } + + .BannerTrail th, .BannerTrail.Complete th, .BannerTrail.closeComplete th, .BannerTrail.nearComplete th, .BannerTrail.farComplete th, .BannerTrail.notComplete th { + grid-area: townBannerDetsR + } + + .BannerTrail, .BannerTrail.Complete, .BannerTrail.closeComplete, .BannerTrail.nearComplete, .BannerTrail.farComplete, .BannerTrail.notComplete { + grid-area: townBannerDets; + } + + .BannerTrail { + background-color: darkslategrey; + + } + + .BannerTrail.Complete { + background-color: gold; + border: 2px solid gold; + border-left: solid 2px whitesmoke; + } + + .BannerTrail.closeComplete { + background-color: darkgoldenrod; + background-color: darkgoldenrod; + border: 2px solid darkgoldenrod; + border-left: solid 2px whitesmoke; + } + + .BannerTrail.nearComplete { + background-color: deepskyblue; + background-color: deepskyblue; + border: 2px solid deepskyblue; + border-left: solid 2px whitesmoke; + } + + .BannerTrail.farComplete { + background-color: green; + background-color: green; + border: 2px solid green; + border-left: solid 2px whitesmoke; + } + + .BannerTrail.notComplete { + background-color: red; + background-color: red; + border: 2px solid red; + border-left: solid 2px whitesmoke; + } + + /*Below selects banner that has the Complete class to change color*/ + .Banner:has(+.BannerTrail.Complete) { + border: 2px solid gold; + border-right: solid 2px whitesmoke; + } + + .Banner:has(+.BannerTrail.closeComplete) { + border: 2px solid darkgoldenrod; + border-right: solid 2px whitesmoke; + } + + + .Banner:has(+.BannerTrail.nearComplete) { + border: 2px solid deepskyblue; + border-right: solid 2px whitesmoke; + } + + .Banner:has(+.BannerTrail.farComplete) { + border: 2px solid green; + border-right: solid 2px whitesmoke; + } + + .Banner:has(+.BannerTrail.notComplete) { + border: 2px solid red; + border-right: solid 2px whitesmoke; + } -body{ - background-color: rgb(41, 41, 41) -} -#homeTitle{ - grid-area: pageTitle; - color: whitesmoke; -} -.submitLand{ - grid-area: submitButton; -} -.Banner { - margin-top: 20px; - background-color: darkslategrey; - margin-bottom: 20px; - /*border: solid 2px whitesmoke;*/ - /*border colour here at .banner and .bannertrail*/ - border-right: none; -} - -/* .BannerTrail.Complete(100%) .BannerTrail.closeComplete(90-99%) .BannerTrail.nearComplete(70-99%) .BannerTrail.farComplete(50-69%) .BannerTrail.notComplete(0-49%) */ -.BannerTrail, .BannerTrail.Complete, .BannerTrail.closeComplete, .BannerTrail.nearComplete, .BannerTrail.farComplete, .BannerTrail.notComplete { - margin-top: 20px; - margin-bottom: 20px; - border: solid 2px whitesmoke; - text-align: center; -} - -.BannerTrail th, .BannerTrail.Complete th, .BannerTrail.closeComplete th, .BannerTrail.nearComplete th, .BannerTrail.farComplete th, .BannerTrail.notComplete th{ - grid-area:townBannerDetsR -} - -.BannerTrail, .BannerTrail.Complete, .BannerTrail.closeComplete, .BannerTrail.nearComplete, .BannerTrail.farComplete, .BannerTrail.notComplete{ - grid-area:townBannerDets; -} - -.BannerTrail { - background-color: darkslategrey; - -} - -.BannerTrail.Complete { - background-color: gold; - border: 2px solid gold; - border-left: solid 2px whitesmoke; -} -.BannerTrail.closeComplete { - background-color: darkgoldenrod; - background-color: darkgoldenrod; - border: 2px solid darkgoldenrod; - border-left: solid 2px whitesmoke; -} - -.BannerTrail.nearComplete { - background-color: deepskyblue; - background-color: deepskyblue; - border: 2px solid deepskyblue; - border-left: solid 2px whitesmoke; -} - -.BannerTrail.farComplete { - background-color: green; - background-color: green; - border: 2px solid green; - border-left: solid 2px whitesmoke; -} - -.BannerTrail.notComplete { - background-color: red; - background-color: red; - border: 2px solid red; - border-left: solid 2px whitesmoke; -} - -/*Below selects banner that has the Complete class to change color*/ -.Banner:has(+.BannerTrail.Complete){ - border: 2px solid gold; - border-right: solid 2px whitesmoke; -} - -.Banner:has(+.BannerTrail.closeComplete){ - border: 2px solid darkgoldenrod; - border-right: solid 2px whitesmoke; -} - - -.Banner:has(+.BannerTrail.nearComplete){ - border: 2px solid deepskyblue; - border-right: solid 2px whitesmoke; -} -.Banner:has(+.BannerTrail.farComplete){ - border: 2px solid green; - border-right: solid 2px whitesmoke; -} -.Banner:has(+.BannerTrail.notComplete){ - border: 2px solid red; - border-right: solid 2px whitesmoke; -} - - -.BannerTrail { - background-color: darkslategrey; - -} - + .BannerTrail { + background-color: darkslategrey; + + } + + + .Banner { + grid-area: townBanner; + color: inherit; + text-decoration: none; + background-color: hotpink; + } + a { + background-size: contain; - -.Banner { - grid-area:townBanner; - color: inherit; - text-decoration: none; - background-color: hotpink; -} - - -a{ - background-size: contain; - -} + } + #aboutUsFlavour { + grid-area: textFlavour; + margin-top: 25px; + margin-bottom: 15px; + color: whitesmoke; + } -#aboutUsFlavour{ - grid-area: textFlavour; - margin-top: 25px; - margin-bottom: 15px; - color: whitesmoke; -} -#trailCount{ - flex:1; - + #trailCount { + flex: 1; + } -} -#trailProgress{ - flex:2; - align-content: center; + #trailProgress { + flex: 2; + align-content: center; -} + } -.gridContainer1 { - display:grid; - grid-template-columns: 10% 10% 60% 5% 5% 10%; - grid-template-rows: auto; - grid-template-areas: + .gridContainer1 { + display: grid; + grid-template-columns: 10% 10% 60% 5% 5% 10%; + grid-template-rows: auto; + grid-template-areas: ". pageTitle pageTitle pageTitle pageTitle ." ". . . submitButton submitButton ."; -} + } -.gridContainer2 { - display:grid; - grid-template-columns: 10% 10% 60% 5% 5% 10%; - grid-template-rows: auto; - grid-template-areas: + .gridContainer2 { + display: grid; + grid-template-columns: 10% 10% 60% 5% 5% 10%; + grid-template-rows: auto; + grid-template-areas: ". townBanner townBanner townBannerDets . ."; -} + } -.gridContainer3 { - display:grid; - grid-template-columns: 10% 10% 60% 5% 5% 10%; - grid-template-rows: auto; - grid-template-areas: + .gridContainer3 { + display: grid; + grid-template-columns: 10% 10% 60% 5% 5% 10%; + grid-template-rows: auto; + grid-template-areas: " . . textFlavour . . ."; + } } +@media only screen +and (min-device-width: 320px) +and (max-device-width: 640px) { + .small-text { + font-size: 0.8em; + } + + + .towns-wrapper { + width: 100%; + } + .gridContainer2 { + height: 10svh; + position: relative; + display: flex; + justify-content: flex-start; + text-align: left; + flex: 1 1; + margin-block: 1svh; + } + .town-name { + position: absolute; + z-index: 5; + padding: 0.2em; + margin: 0.5em; + border-radius: 35%; + background: rgba(31, 31, 31, 0.6); + + } + .img-container { + float: left; + z-index: 1; + height: 100%; + width: 60vw; + } + .town-img { + width: 100%; + height: 100%; + border-radius: 20% 0 0 20%; + border: #36454F solid; + border-width: 6px 3px 6px 6px; + } + .BannerTrail { + width: 25vw; + height: 10svh; + border-radius: 0 20% 20% 0; + border: #36454F solid; + border-width: 6px 6px 6px 3px; + position: relative; + overflow: hidden; + & h4 { + text-align: center; + } + } + .trail-info { + position: relative; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + width: 25vw; + height: 10svh; + } + + /*Below selects banner that has the Complete class to change color*/ + .BannerFill { + position: absolute; + background: var(--trail-colour, transparent); + width: 10%; + height: 10svh; + opacity: 0.9; + z-index: 0; + } + .Complete { + --trail-colour: gold; + } + .closeComplete { + --trail-colour: darkgoldenrod; + } + .nearComplete { + --trail-colour: deepskyblue; + } + .farComplete { + --trail-colour: green; + } + .notComplete { + --trail-colour: red; + } +} \ No newline at end of file diff --git a/src/main/resources/static/css/landmarkFormStyle.css b/src/main/resources/static/css/landmarkFormStyle.css index 9d638b48ae03d406b9f97c85e21f14a00fb3188f..df77f4d47993c4dd75a5c9abe7a2b1084226b8cd 100644 --- a/src/main/resources/static/css/landmarkFormStyle.css +++ b/src/main/resources/static/css/landmarkFormStyle.css @@ -1,21 +1,77 @@ /*LandmarkFormTh stylesheet*/ -body{ - background: rgb(41, 41, 41); - color: wheat; -} -#landmarkSubmission { - background-color: rgb(206, 153, 253); - color: black; - border-color: white; - align-content: center; - text-align: center; - border-radius: 25px; - max-width: 620px; - margin: 0 auto +@media only screen +and (min-device-width: 640px) { + #landmarkSubmission { + background-color: var(--prim-shade-1); + color: black; + border-color: white; + align-content: center; + text-align: center; + border-radius: 25px; + max-width: 620px; + margin: 0 auto + } + + #landmarkFormTitle { + color: white; + text-align: center; + + } } -#landmarkFormTitle{ - color:white; - text-align: center; +@media only screen +and (max-device-width: 640px) { + /*LandmarkFormTh stylesheet*/ + main { + min-height: 30svh; + } + #landmarkSubmission { + background-color: var(--prim-shade-1); + border-color: white; + align-content: center; + text-align: center; + border-radius: 25px; + max-width: 620px; + margin: 0 auto; + display: flex; + flex-direction: column; + row-gap: 2svh; + align-items: center; + + & h1 { + + } + + & label { + font-weight: 600; + } + & select { + font-size: 1em; + } + + & input { + font-size: 1em; + } + } + + .button { + background-color: var(--prim-shade-3); + border-radius: 20px; + border: var(--prim-shade-2) 5px; + color: #fff; + font-size: xxx-large; + padding: 40px 40px; + font-weight: 600; + letter-spacing: 1px; + text-transform: uppercase; + margin-bottom: 2svh; + cursor: pointer; + box-shadow: rgba(0, 0, 0, 0.2) 0 1svh 1svh; + } + + #landmarkFormTitle { + color: white; + text-align: center; + } } \ No newline at end of file diff --git a/src/main/resources/static/css/locationApprovalFormStyle.css b/src/main/resources/static/css/locationApprovalFormStyle.css new file mode 100644 index 0000000000000000000000000000000000000000..99a2f8719b8877f881addd9e029a4562ed713399 --- /dev/null +++ b/src/main/resources/static/css/locationApprovalFormStyle.css @@ -0,0 +1,26 @@ +body{ + background: rgb(41, 41, 41); + color: wheat; +} +main { + background-color: rgb(206, 153, 253); + color: black; + border-color: white; + align-content: center; + text-align: center; + border-radius: 25px; + max-width: 620px; + margin: 0 auto +} + +#formHeader{ + padding-top: 10px; + color:white; + text-align: center;} + +table, th,tr{ + margin: 0 auto; + border: white 2px solid; + align-content: center; + text-align: center; +} diff --git a/src/main/resources/static/css/login.css b/src/main/resources/static/css/login.css index 023566c253e9354e789e85744cd1e4989d523845..6b4674175cd31c60bc189301a648c4f27716e982 100644 --- a/src/main/resources/static/css/login.css +++ b/src/main/resources/static/css/login.css @@ -1,8 +1,8 @@ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap'); - +@import url(colours.css); :root { --container-colour: #2a2a2a; - --details-colour: var(--primary-light); + --details-colour: var(--prim-shade-1); --details-light: #512da8; --font-buttons: 14px; @@ -13,27 +13,6 @@ --error-colour: red; } -*{ - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: 'Montserrat', sans-serif; - color: white; -} - -body{ - align-items: center; - height: 100svh; -} - -main { - height: 90%; - width: 90%; - display: flex; - align-items: center; - justify-content: center; -} - @keyframes move{ 0%, 49.99%{ opacity: 0; @@ -48,9 +27,6 @@ main { @media only screen and (min-device-width: 650px) { .container{ - background-color: var(--container-colour); - border-radius: 30px; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35); position: relative; overflow: hidden; min-width: 768px; @@ -215,53 +191,64 @@ and (min-device-width: 650px) { } } + @media only screen and (max-device-width: 640px) { + main { + padding: 0; + height: 70svh; + } .container { position: relative; - - background-color: var(--container-colour); - border-radius: 30px; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35); - overflow: hidden; - width: 100%; height: 100%; - - display: flex; - flex-direction: column; - justify-content: space-evenly; } .form-container { - height: 100%; + height: 50%; transition: all 0.6s ease-in-out; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; + } + .form-title { + padding-top: 3svh; + font-size: 3em; } .form-container form { display: flex; - + width: 100%; + height: 100%; + padding-block: 1svh; flex-direction: column; - align-items: center; - font-size: 3em; - margin-inline: 5%; + font-size: 1.5em; + & label { + width: 100%; + } } + .form-container label { + margin-block: 0.5svh; + } + .form-container input { - flex: 1 1; + width: 70%; + height: 90%; + padding: 0.5em; font-size: 1em; color: black; - margin-block: 5%; - padding: 2%; border-radius: 30px; + border: #36454F 5px solid; + box-shadow: rgba(0, 0, 0, 0.25) 0 1svh 1svh; + /*margin-top: 1svh;*/ } .form-container button { - flex: 1 1; + width: 40%; font-size: 1em; + margin: auto; } + .recovery-text { + margin-top: 1svh; + font-size: 0.6em; + } + .toggle-container { position: absolute; top: 0; @@ -269,16 +256,16 @@ and (max-device-width: 640px) { height: 50%; transition: all 0.6s ease-in-out; overflow: hidden; - border-radius: 0 0 150px 150px; - z-index: 1000; - + border-radius: 150px 150px 0 0; + transform: translateY(100%); } .container.active .toggle-container{ - transform: translateY(100%); /*BG THING*/ - border-radius: 150px 150px 0 0; + transform: translateY(0); /*BG THING*/ + + border-radius: 0 0 150px 150px; } .toggle { - position: absolute; + position: relative; width: 100%; height: 200%; display: flex; @@ -289,46 +276,51 @@ and (max-device-width: 640px) { /*background-color: red;*/ } .toggle-panel { - flex: 1 1; + height: 100%; width: 100%; + position: absolute; } .container .toggle-right { - transform: translateY(0); opacity: 1; + z-index: 5; + transform: translateY(-25%); } .container .toggle-left { transform: translateY(-100%); opacity: 0; + z-index: 1; } .container.active .toggle-right{ - transform: translateY(-100%); + transform: translateY(50%); opacity: 0; + z-index: 1; } .container.active .toggle-left{ - transform: translateY(-100%); + transform: translateY(-25%); opacity: 1; + z-index: 5; } .container .sign-up { opacity: 0; z-index: -1; - transform: translateY(100%); + transform: translateY(150%); } .container .sign-in { + transform: translateY(-100%); opacity: 1; z-index: 5; } .container.active .sign-in{ - transform: translateY(-100%); + transform: translateY(-150%); opacity: 0; z-index: -1; } .container.active .sign-up{ - animation: move 0.6s; opacity: 1; z-index: 5; - transform: translateY(0); + transform: translateY(100%); } @@ -347,7 +339,7 @@ and (max-device-width: 640px) { line-height: 1.5em; } .container button{ - background-color: var(--details-colour)/*#512da8*/; + background-color: var(--details-colour); color: #fff; font-size: xxx-large; padding: 40px 40px; @@ -366,7 +358,14 @@ and (max-device-width: 640px) { } } .alert { - color: var(--error-colour); - text-shadow: var(--error-colour) 0 0 10px; + color: var(--alert-colour, black); + text-shadow: 0 0 10px var(--alert-colour, black); +} + +.alert-error { + --alert-colour: red; +} +.alert-success { + --alert-colour: green; } diff --git a/src/main/resources/static/css/mobile-style.css b/src/main/resources/static/css/mobile-style.css new file mode 100644 index 0000000000000000000000000000000000000000..6be7d20cb2d472f85e42d7154c059181e13a0904 --- /dev/null +++ b/src/main/resources/static/css/mobile-style.css @@ -0,0 +1,195 @@ +@import url(colours.css); + +/*PHONES - PORTRAIT*/ +@media only screen +and (min-device-width: 320px) +and (max-device-width: 640px) { + :root{ + --font-headers: 20px; + --font-body: 20px; + } + *{ + margin: 0; + padding: 0; + box-sizing: border-box; + } + body { + background: linear-gradient(to bottom right, + var(--primary-darker), + var(--primary-dark), + var(--primary-darker)); + + display: flex; + flex-direction: column; + align-content: center; + + width: 100vw; + min-height: 100svh; + font-size: 2em; + row-gap: 2svh; + } + + header { + display: flex; + justify-content: flex-start; + align-items: center; + margin-inline: auto; + width: 95vw; + height: 6svh; + margin-top: 1svh; + + .head-navbar { + display: flex; + width: 100%; + height: 100%; + background-color: #1f1f1f; + border-radius: 20px; + box-shadow: rgba(0, 0, 0, 0.4) 0 1svh 1svh; + overflow: hidden; + } + + .nav-ul { + list-style: none; + display: flex; + justify-content: space-evenly; + flex: 1 1; + } + + .nav-li { + display: flex; + flex: 1 1; + } + + .nav-links { + display: grid; + align-content: center; + flex: 1 1; + text-align: center; + transition: 0.3s ease-in-out 1ms; + font-weight: bolder; + text-decoration: none; + color: white; + } + + .nav-links:hover { + background-color: #36454F; + } + + .nav-logo-container { + display: flex; + width: 20vw; + height: 100%; + z-index: 5; + } + + .nav-logo { + height: 100%; + width: 100%; + border-radius: 45% 15% 15% 45%; + border: #1f1f1f 5px solid; + box-shadow: rgba(0, 0, 0, 0.4) 0 1svh 1svh; + transition: 0.3s ease-in-out 1ms; + } + + .nav-logo:hover { + filter: grayscale(0.7); + } + + .li-middle { + border-style: solid; + border-width: 2px; + border-image: linear-gradient(to bottom, transparent 10%, #36454F, transparent 90%) 0 50; + } + + .li-last { + border-style: solid; + border-width: 2px; + border-image: linear-gradient(to bottom, transparent 10%, #36454F, transparent 90%) 0 0 0 50; + } + + .li-first { + border-style: solid; + border-width: 2px; + border-image: linear-gradient(to bottom, transparent 10%, #36454F, transparent 90%) 0 50 0 0; + } + } + + main { + background-color: #1f1f1f; + border-radius: 20px; + overflow: hidden; + box-shadow: rgba(0, 0, 0, 0.4) 0 1svh 2svh; + padding: 3vw; + margin-inline: 5vw; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + min-height: 80svh; + height: max-content; + /*overflow-y: scroll;*/ + + } + .center-flex-columns { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + footer { + display: flex; + font-size: 0.5em; + justify-content: space-evenly; + margin-inline: 5%; + padding-top: 2%; + border-width: 5px; + border-style: solid; + border-image: linear-gradient(to left, transparent 5%, #36454F, transparent 95%) 50 0 0 0; + + + .footer-div { + width: 30%; + } + + .centerFooter { + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + } + + .rightFooter { + text-align: right; + } + + .icon { + border-radius: 50%; + width: 4vw; + height: auto; + aspect-ratio: 1; + } + } +} + + + + + + + + + + + + + + +/*PHONES - LANDSCAPE*/ +/* TODO -> UNIMPLEMENTED LANDSCAPE STYLE FOR PHONES*/ +@media only screen +and (min-device-width: 640px) +and (max-device-width: 1000px) { + + +} \ No newline at end of file diff --git a/src/main/resources/static/css/townsPageFragsStyle.css b/src/main/resources/static/css/townsPageFragsStyle.css new file mode 100644 index 0000000000000000000000000000000000000000..ad4cb2d9baebcfe931ed6f7440f44567743555be --- /dev/null +++ b/src/main/resources/static/css/townsPageFragsStyle.css @@ -0,0 +1,34 @@ +.townFragment{ + background-color: rgb(206, 153, 253); + color: black; + border-color: white; + align-content: center; + text-align: center; + border-radius: 25px; + max-width: 800px; + margin: 0 auto; + +} +.townPageFrag{ + background: rgb(41, 41, 41); + color: wheat; +} + +#return{ + padding-bottom: 10px; +} +iframe{ + margin-top: 20px; + margin-bottom: 60px; + border: white 2px solid; +} +H1{ + padding-top: 5px; + padding-bottom:3px ; + margin-bottom: 0; +} + +#checkpointList{ + list-style: none; +} + 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 0c5c0e9c4aef739bda2f4d38039fa4735a3e30bb..a3de978ecbcd7a392f061500c37e26fe96ac3820 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/static/images/trails/trail1.jpg b/src/main/resources/static/images/trails/trail101.jpg similarity index 100% rename from src/main/resources/static/images/trails/trail1.jpg rename to src/main/resources/static/images/trails/trail101.jpg diff --git a/src/main/resources/static/images/trails/trail102.jpg b/src/main/resources/static/images/trails/trail102.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa2867f7e26d7cf94e64571bf284a7ecba12f950 Binary files /dev/null and b/src/main/resources/static/images/trails/trail102.jpg differ diff --git a/src/main/resources/static/images/trails/trail103.jpg b/src/main/resources/static/images/trails/trail103.jpg new file mode 100644 index 0000000000000000000000000000000000000000..922c12d013b5382b39e6c78831c3bfd314d2223e Binary files /dev/null and b/src/main/resources/static/images/trails/trail103.jpg differ diff --git a/src/main/resources/static/images/trails/trail2.jpg b/src/main/resources/static/images/trails/trail2.jpg deleted file mode 100644 index 683d275abb6772456d55082eb4940d0e606bf5f6..0000000000000000000000000000000000000000 Binary files a/src/main/resources/static/images/trails/trail2.jpg and /dev/null differ diff --git a/src/main/resources/static/images/trails/trail201.jpg b/src/main/resources/static/images/trails/trail201.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17a27691160693ecb16bf33bee1170b3630ef0ed Binary files /dev/null and b/src/main/resources/static/images/trails/trail201.jpg differ diff --git a/src/main/resources/static/images/trails/trail3.jpg b/src/main/resources/static/images/trails/trail3.jpg deleted file mode 100644 index f02b15249a3f0e2158023b8a98c8bf67fcc272c8..0000000000000000000000000000000000000000 Binary files a/src/main/resources/static/images/trails/trail3.jpg and /dev/null differ diff --git a/src/main/resources/static/images/trails/trail301.jpg b/src/main/resources/static/images/trails/trail301.jpg new file mode 100644 index 0000000000000000000000000000000000000000..916164409153d3ea470491cc48df88be768e4f4e Binary files /dev/null and b/src/main/resources/static/images/trails/trail301.jpg differ diff --git a/src/main/resources/static/images/trails/trail4.jpg b/src/main/resources/static/images/trails/trail4.jpg deleted file mode 100644 index c8c405e4f332a4f9b495c98ecbac7988b2b27cda..0000000000000000000000000000000000000000 Binary files a/src/main/resources/static/images/trails/trail4.jpg and /dev/null differ diff --git a/src/main/resources/static/images/trails/trailNotFound.jpg b/src/main/resources/static/images/trails/trailNotFound.jpg index 9fd46288f31cf61cbce2d58244e69b908cf727c1..8b2411d1083639471dc6501d8a921d6ea4dbcd5c 100644 Binary files a/src/main/resources/static/images/trails/trailNotFound.jpg and b/src/main/resources/static/images/trails/trailNotFound.jpg differ diff --git a/src/main/resources/static/qr-scanner.html b/src/main/resources/static/qr-scanner.html deleted file mode 100644 index 2e93c18b5decfdb0f2b2f3e390e87dd9a8600661..0000000000000000000000000000000000000000 --- a/src/main/resources/static/qr-scanner.html +++ /dev/null @@ -1,29 +0,0 @@ -<!--setup html page for QR codes - R Nute--> -<!--Modified from (https://www.geeksforgeeks.org/create-a-qr-code-scanner-or-reader-in-html-css-javascript/)--> - -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewpoint" content="width-device-width, initial-scale=1.0"> - <link rel="stylesheet" href="css/templatingstyle.css"> - <link rel="stylesheet" href="css/qrstyle.css"> - <script src="https://unpkg.com/html5-qrcode"></script> - <script type="module" src="scripts/qr-script.js"></script> - <title>QR Code</title> -</head> - -<body> - <header th:insert="towns/Templating.html :: header"></header> - - <div class="container"> - <h1>Scan location QR code</h1> - <div class="section"> - <div id="qr-code-reader"> - </div> - </div> - </div> - - <div th:insert="towns/Templating.html :: footer"></div> -</body> -</html> diff --git a/src/main/resources/static/scripts/DTscript.js b/src/main/resources/static/scripts/DTscript.js new file mode 100644 index 0000000000000000000000000000000000000000..b791445e69d24655e244294b57dfd72d71ce15c6 --- /dev/null +++ b/src/main/resources/static/scripts/DTscript.js @@ -0,0 +1,9 @@ +var getQR = function (){ + // document.getElementById("qrCodeScanner").style.cursor = "pointer"; + window.location.href = "/QRScan"; +} + +function toggleDropDown(){ + var dropdownList = document.getElementById("dropdownList") + dropdownList.style.display = (dropdownList.style.display === "block") ? "none" : "block" +} \ No newline at end of file diff --git a/src/main/resources/static/scripts/locationApprovalForm.js b/src/main/resources/static/scripts/locationApprovalForm.js new file mode 100644 index 0000000000000000000000000000000000000000..10778be252e111d0dff6ca22f8f293d424ff0ce6 --- /dev/null +++ b/src/main/resources/static/scripts/locationApprovalForm.js @@ -0,0 +1,16 @@ + +//script for basic long/lat validation + +function acceptanceValidation(){ + var pass=true; + var lat = document.forms["adminCheckpointApproval"]["locationCoordsLat"].value + var long = document.forms["adminCheckpointApproval"]["locationCoordsLong"].value + if (lat=="") { + alert('Invalid location inputted. \nPlease input a valid latitude.'); + pass = false; + } + if (long==""){ + alert('Invalid location inputted. \nPlease input a valid longitude.'); + pass = false; + } return pass; +} \ No newline at end of file diff --git a/src/main/resources/static/scripts/qrCode.js b/src/main/resources/static/scripts/qrCode.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/main/resources/templates/allTrails/allTrails.html b/src/main/resources/templates/allTrails/allTrails.html index 0fefa92c95a928454c100894149bf18340015baf..092a1969f929e268deada3fa0918df277f7f2434 100644 --- a/src/main/resources/templates/allTrails/allTrails.html +++ b/src/main/resources/templates/allTrails/allTrails.html @@ -2,37 +2,36 @@ <html lang="en"> <head> <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>All Trails</title> - <link rel="stylesheet" th:href="@{css/allTrails.css}"> - <link rel="stylesheet" th:href="@{css/templatingstyle.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/allTrails.css}"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> </head> <body> -<header th:replace="~{/fragments/Templating.html :: header}"></header> -<div>TEST</div> +<header th:replace="~{/fragments/banners :: header}"></header> + <main> <section id="allTrailsBar" class="centerFlex"> - <img class="trailsImages" - th:each="trail : ${trails}" - th:src="@{${trail.getImgPath()}}" - th:onclick="'updateOutputTrail('+ ${trail.getId()} +');'" - th:id="'img' + ${trail.getId()}" th:alt="${trail.getName()}" - > - </section> + <a th:each="trail : ${trails}" th:href="'/trails/' + ${trail.getTrailLink()}" class="trailWrapper"> + <h1 th:text="${trail.getTrailName()}"></h1> + <img class="trailsImages" + th:src="${trail.getImagePath()}" + th:onclick="'updateOutputTrail('+ ${trail.getTrailsId()} +');'" + th:id="'img' + ${trail.getTrailsId()}" th:alt="${trail.getTrailName()}" + ></a> - <section id="trailInfoContainer" class="trailInfoFrag"> - <!--All this section is loaded from thymeleaf, based on what tail is selected - in the #allTrailsBar --> - <div class="trailInfoHeader"> - <h1 class="centerFlex">Please select your trail</h1> - </div> </section> - +<!-- <section id="trailInfoContainer" class="trailInfoFrag">--> +<!-- <!–All this section is loaded from thymeleaf, based on what tail is selected--> +<!-- in the #allTrailsBar –>--> +<!-- <div class="trailInfoHeader">--> +<!-- <h1 class="centerFlex">Please select your trail</h1>--> +<!-- </div>--> +<!-- </section>--> </main> -<footer th:insert="~{/fragments/Templating.html :: footer}"></footer> - +<footer th:replace="~{/fragments/banners :: footer}"></footer> <script type="text/javascript" th:src="@{scripts/allTrails.js}"></script> diff --git a/src/main/resources/templates/dragonstale/index.html b/src/main/resources/templates/dragonstale/index.html new file mode 100644 index 0000000000000000000000000000000000000000..1745a9e2362b790850def159561e9b9d38a22c0f --- /dev/null +++ b/src/main/resources/templates/dragonstale/index.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html lang="en"> +<html xmlns:th="http://www.thymeleaf.org"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>A Dragon's Tale</title> + <link rel="stylesheet" th:href="@{/css/dragonstaless.css}"> + <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> + <script type="text/javascript" th:src="@{/scripts/DTscript.js}"></script> +</head> + <body> + <header th:insert="fragments/Templating.html :: header"></header> + <!-- As this predefined trail will be accessible from multiple different towns, this thymeleaf element will display the town the user is currently trying to access and display it accordingly. <span th:text="${townName}"> --> + <div> + <h1> Welcome, to a dragon's tale! </h1> + <img th:src="@{/images/trails/dragonstalehome.png}" alt="Image of a dragon" class="images"> + <h2> Discover the mystery of the dragon, track its location and follow it throughout the town of to discover a prize! </h2> + </div> + + <div> + <p> + Adventurers... embark through mystical historical landmarks to ultimately discover the lair of the dragon. + Legend has it that within this ominous lair, mighty dragons, guardians of ancient wisdom and treasures untold lay.... + </p> + </div> + + + <div class="dropdown"> + <button class="dropdownButton" onclick="toggleDropDown()" >There are <span th:text="${getListSize}"> Size of List </span> adventures in this journey! </button> + <ul id="dropdownList"> + <li class="content" th:each="item : ${landmarksList}"> + <a class="option" href="#landmarkTabLink" th:text="${item.landmarkName}"> Landmark Tab</a> + <button class="option" id="qrCodeScanner" onclick="getQR()">Click here to scan a QR code for: <span th:text="${item.landmarkName}">Landmark Name Here</span></button> + </li> + </ul> + </div> + + + <!-- Need to mark each element to an ID then loop through them. --> + <!-- <div id="listOfLandmarks">--> + <!-- <p th:each="item : ${landmarksList}">--> + <!-- <span th:text="${item.landmarkDescription}" class="landmarkDesc" id="landmarkTabLink"> Landmark Description</span>--> + <!-- </p>--> + <!-- </div>--> + + <div> + <h3> Begin or Continue your hunt!</h3> + <button type="button" id="begin">Click here!</button> + </div> + <div th:insert="fragments/Templating.html :: footer"></div> + </body> +</html> \ No newline at end of file diff --git a/src/main/resources/templates/fragments/banners.html b/src/main/resources/templates/fragments/banners.html new file mode 100644 index 0000000000000000000000000000000000000000..a04b03d5f9a9a3c6cb569cc60c8bdc9db1a070e3 --- /dev/null +++ b/src/main/resources/templates/fragments/banners.html @@ -0,0 +1,58 @@ +<header th:fragment="header"> + <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" 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> + <li class="nav-li li-last" th:if="${#authentication.principal}!=anonymousUser"> + <a class="nav-links" href="javascript: document.logoutForm.submit()" role="menuitem">Log Out</a> + <form name="logoutForm" th:action="@{/logout}" method="post" th:hidden="true"> + <input hidden type="submit" value="Sign Out"/> + </form> + </li> + <li class="nav-li li-first"> + <a href="/local-authorities" class="nav-links">Local Authorities</a> + </li> + <li class="nav-li li-first"> + <a href="/businesses" class="nav-links">Local Businesses</a> + </li> + </ul> + </nav> +</header> + +<footer th:fragment="footer"> + <!-- By Rhys Nute --> + <div class="footer-div leftFooter"> + <h3>VZTA</h3> + Near Me Now LTD + <br>Britania House + <br>Caerphilly Business Park + <br>Caerphilly + <br>CF83 3GG + </div> + <div class="footer-div centerFooter"> + <div class="footerText"> + <h3>Follow Us</h3> + <a href="https://www.facebook.com/VZTAsmarttowns/" class="icon"><img src="/images/icons/Facebook.png" height="25" width="25" alt="Facebook Logo" class="icon"/></a> + <a href="https://www.twitter.com/VZTAsmarttowns/" class="icon"><img src="/images/icons/Twitter.jpg" height="25" width="25" alt="X (formally Twitter) Logo" class="icon"/></a> + <a href="https://www.instagram.com/vztasmarttowns/" class="icon"><img src="/images/icons/Instagram.jpg" height="25" width="25" alt="Instagram Logo" class="icon"/></a> + <a href="https://www.linkin.com/company/vztasmarttowns/" class="icon"><img src="/images/icons/Linkedin.png" height="25" width="25" alt="Linkedin Logo" class="icon"/></a><br> + </div> + </div> + <div class="footer-div rightFooter"> + <h3>Connect with us</h3> + <p>Be the first to know about updates by joining out Community page</p> + (C) VZTA 2022<br> + Policy Terms and Conditions + </div> +</footer> \ No newline at end of file diff --git a/src/main/resources/templates/fragments/locationPageFrags.html b/src/main/resources/templates/fragments/locationPageFrags.html index ba7813ecf7e24927302cd49b1ca1523d959cae17..4bcdc2ba498ff8c754a00b0e02447f5fe33d6c30 100644 --- a/src/main/resources/templates/fragments/locationPageFrags.html +++ b/src/main/resources/templates/fragments/locationPageFrags.html @@ -6,9 +6,10 @@ <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> <link rel="stylesheet" th:href="@{/css/locationPageFragsStyle.css}"> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> </head> <body > -<header th:insert="~{/fragments/Templating.html::header}"></header> +<header th:replace="~{/fragments/banners::header}"></header> <main> <hr style="height:40px; visibility:hidden;" /> @@ -35,6 +36,6 @@ <hr style="height:40px; visibility:hidden;" /> </main> -<footer th:insert="~{/fragments/Templating.html::footer}"></footer> +<footer th:replace="~{/fragments/banners::footer}"></footer> </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/fragments/qr-scanner.html b/src/main/resources/templates/fragments/qr-scanner.html new file mode 100644 index 0000000000000000000000000000000000000000..509c40efa6095d4f3e159fac6f0f60cea278a17f --- /dev/null +++ b/src/main/resources/templates/fragments/qr-scanner.html @@ -0,0 +1,27 @@ +<!--setup html page for QR codes - R Nute--> +<!--Modified from (https://www.geeksforgeeks.org/create-a-qr-code-scanner-or-reader-in-html-css-javascript/)--> + +<!DOCTYPE html> +<html lang="en"> +<html xmlns:th="http://www.thymeleaf.org"> + <head> + <meta charset="UTF-8"> + <meta name="viewpoint" content="width-device-width, initial-scale=1.0"> + <link rel="stylesheet" href="/css/templatingstyle.css"> + <link rel="stylesheet" href="/css/qrstyle.css"> + <script src="https://unpkg.com/html5-qrcode"></script> + <script type="module" src="/scripts/qr-script.js"></script> + <title>QR Code</title> + </head> + + <body> + <div th:fragment="qrCode" class="container"> + <h1>Scan location QR code</h1> + <div class="section"> + <div id="qr-code-reader"> + </div> + </div> + </div> + + </body> +</html> diff --git a/src/main/resources/templates/fragments/townsPageFrags.html b/src/main/resources/templates/fragments/townsPageFrags.html new file mode 100644 index 0000000000000000000000000000000000000000..2b6e318e26970c313055a5ce0dccd3c7fafff16b --- /dev/null +++ b/src/main/resources/templates/fragments/townsPageFrags.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html lang="en" th:fragment="townSection" class="townPageFrag"> +<head> + <meta charset="UTF-8"> + <title th:text="${town.getTownName()}"></title> + <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{/css/townsPageFragsStyle.css}"> + + +</head> +<body > +<header th:insert="~{/fragments/Templating.html::header}"></header> +<main> + <hr style="height:40px; visibility:hidden;" /> + <section class="townFragment"> + + + <H1 th:text="${town.getTownName()}+' Trails'"></H1> + <hr style="height:20px; visibility:hidden;" /> + + <div th:each="trail, indexValue:${trails}"> + <li id="checkpointList"> + <div><a th:href="'/trails/'+${trail.getTrailName().replace(' ', '-')}" th:text="${trail.getTrailName()}"></a></div> + <ul></ul> + </li> + + </div> + <hr style="height:20px; visibility:hidden;" /> + <H2 id="return"> + <a href="/home">Back</a></H2> + </section> + + <hr style="height:40px; visibility:hidden;" /> +</main> + +<footer th:insert="~{/fragments/Templating.html::footer}"></footer> +</body> +</html> \ No newline at end of file diff --git a/src/main/resources/templates/fragments/trailsPageFrags.html b/src/main/resources/templates/fragments/trailsPageFrags.html index 296cd2d153d1671b467a27a78f5a1994bdb77806..9a62be17086ae209a7b3c372e8edacc0992713ed 100644 --- a/src/main/resources/templates/fragments/trailsPageFrags.html +++ b/src/main/resources/templates/fragments/trailsPageFrags.html @@ -1,16 +1,19 @@ +<!-- @thymesVar id="location" type="Team5.SmartTowns.data.Location" --> <!DOCTYPE html> <html lang="en" th:fragment="trailsSection" class="trailsPageFrag"> <head> <meta charset="UTF-8"> <title th:text="${trail.getTrailName()}"></title> - <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{/css/trailsPageFragsStyle.css}"> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> + <link rel="stylesheet" th:href="@{/css/userProfile.css}"> </head> <body > -<header th:insert="~{/fragments/Templating.html::header}"></header> +<header th:replace="~{/fragments/banners::header}"></header> <main> <hr style="height:40px; visibility:hidden;" /> @@ -26,9 +29,10 @@ scrolling="yes" marginheight="0" marginwidth="0" - src="https://www.google.com/maps/dir/51.57623,-3.21910/51.575372,-3.219186/51.576363,-3.220712//@11z"> + + src="https://maps.google.com/maps?q=51.57623,-3.21910&output=svembed"> </iframe> - <div><a href="https://www.google.com/maps/dir/51.57623,-3.21910/51.575372,-3.219186/51.576363,-3.220712//@11z">Trail Map</a></div> + <div><a href="https://www.google.com/maps/dir/51.57623,-3.21910/51.575372,-3.219186/51.576363,-3.220712//@11z&output=svembed">Trail Map</a></div> </div> @@ -40,7 +44,8 @@ scrolling="yes" marginheight="0" marginwidth="0" - th:src="'https://www.google.com/maps/dir/51.57239,-3.21992/51.57230,-3.21938//@&hl=en&z=20&output=embed'"> + + src="https://maps.google.com/maps?q=51.57239,-3.21992&output=svembed"> </iframe> <div><a href="https://www.google.com/maps/dir/51.57239,-3.21992/51.57230,-3.21938//@11z">Trail Map</a></div> @@ -53,7 +58,8 @@ scrolling="yes" marginheight="0" marginwidth="0" - th:src="'https://www.google.com/maps/dir/51.57168,-3.21861/51.57465,-3.22022//@11z'"> + + th:src="'https://maps.google.com/maps?q=51.57168,-3.21861&output=svembed'"> </iframe> <div> <a href="https://www.google.com/maps/dir/51.57168,-3.21861/51.57465,-3.22022//@11z">Trail Map</a></div> @@ -67,7 +73,7 @@ scrolling="yes" marginheight="0" marginwidth="0" - th:src="'https://www.google.com/maps/dir/51.61117,-3.10198/51.61655,-3.12371 //@11z'"> + th:src="'https://maps.google.com/maps?q=51.61117,-3.10198&output=svembed'"> </iframe> <div><a href="https://www.google.com/maps/dir/51.61117,-3.10198/51.61655,-3.12371 //@11z">Trail Map</a></div> </div> @@ -79,7 +85,8 @@ scrolling="yes" marginheight="0" marginwidth="0" - th:src="'https://www.google.com/maps/dir/51.43484,-3.16492/51.43547,-3.16789//@11z'"> + + th:src="'https://maps.google.com/maps?q=51.43484,-3.164928&output=svembed'"> </iframe> <div> <a href="https://www.google.com/maps/dir/51.43484,-3.16492/51.43547,-3.16789//@11z">Trail Map</a> @@ -87,28 +94,31 @@ </div> <H3>Checkpoints:</H3> <!-- With the trial name, we go through locations list to get --> - <div th:each="locationCoord, indexValue:${locCoords}" > - <div th:if="${locations[indexValue.index].getLocationTrailID()==trail.getTrailsId()}"> + <div th:each="location:${locations}" > + <div> <li id="checkpointList"> - <div><a th:href="'/checkpoints/'+${locations[indexValue.index].getLocationName().replace(' ', '-')}" th:text="${locations[indexValue.index].getLocationName()}"></a></div> + <div><a th:href="'/checkpoints/'+${location.getLocationName().replace(' ', '-')}" th:text="${location.getLocationName()}"></a></div> <ul></ul> </li> - - - - </div> + </div> + </article> - - - - - + <article> + <h1> Stickers </h1> + <br> + <div class="stickersContainer"> + <img th:class="'stickerImg gotSticker'" th:each="sticker : ${stickers}" th:src="@{'../' + ${sticker.getDisplayImg()}}" + th:id="'img' + ${sticker.getId()}" th:alt="${sticker.getName()}" > </div> + <hr style="height:15px; visibility:hidden;" /> + <H2 id="return"> + <a href="/mobile-home">Home</a></H2> + <hr style="height:5px; visibility:hidden;" /> </article> <hr style="height:40px; visibility:hidden;" /> </main> -<footer th:insert="~{/fragments/Templating.html::footer}"></footer> +<footer th:replace="~{/fragments/banners::footer}"></footer> </body> </html> diff --git a/src/main/resources/templates/landmarks/LandmarkFormTh.html b/src/main/resources/templates/landmarks/LandmarkFormTh.html index 646632ce015eb3e16d14e7da06c604cc2ae10c5b..3547d0fba7ec009120f975bc0d4c49185af7b066 100644 --- a/src/main/resources/templates/landmarks/LandmarkFormTh.html +++ b/src/main/resources/templates/landmarks/LandmarkFormTh.html @@ -4,31 +4,31 @@ <meta charset="UTF-8"> <title>Landmark Sign Up</title> <link rel="stylesheet" th:href="@{css/landmarkFormStyle.css}"> - <link rel="stylesheet" th:href="@{css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{css/mobile-style.css}"> <script src="scripts/landmarkFormThScript.js"></script> </head> <body> -<header th:insert="~{/fragments/Templating.html :: header}"></header> -<hr style="height:20px; visibility:hidden;" /> -<H2 id="landmarkFormTitle"> Interested in joining our trails? Sign up Here! </H2> +<header th:insert="~{/fragments/banners :: header}"></header> + + <main> <!-- Form used to submit potential landmarks for trails--> - <form action="/landmarkSub" id="landmarkSubmission" name="landmarkSubmission" method="post" th:object="${landmarkData}" onsubmit="return landmarkFormValidation()"> - <br> + <form action="/landmarkSub" id="landmarkSubmission" name="landmarkSubmission" method="post" th:object="${landmarkData}" onsubmit="return landmarkFormValidation()"> + <h1 id="landmarkFormTitle"> Interested in joining our trails? Sign up Here! </h1> <label>Business Name: <input type="text" th:field="*{landmarkName}" placeholder="Business name here..."> - </label><br> + </label> <div th:errors="*{landmarkName}" th:if="${#fields.hasErrors('landmarkName')}">ErrorLandmarkName</div> - <br><label>Contact Address: + <label>Contact Address: <input type="text" th:field="*{landmarkEmail}" placeholder="E-mail here..."> - </label><br> + </label> <div th:errors="*{landmarkEmail}" th:if="${#fields.hasErrors('landmarkEmail')}">ErrorEmail</div> - <br><label>Please Describe Your Business:<br> + <label>Please Describe Your Business:<br> <textarea th:field="*{landmarkDescription}" rows="18" cols="70" placeholder="Max 200 words please..."></textarea> - </label><br><br> + </label> <label>Your Location: <select th:field="*{landmarkLocation}"> <option value="" hidden="true">Select Location</option> @@ -37,7 +37,7 @@ <option value="Risca">Risca</option> <option value="Penarth">Penarth</option> </select> - </label><br><br> + </label> <label>Trail: <select th:field="*{trailID}"> <option value=0 hidden="true">Select Trail</option> @@ -48,18 +48,14 @@ <option value=0201>(Risca) Heritage and Culture Trail</option> <option value=0301>(Penarth) Esplanade Trail</option> </select> - - </label><br><br> - - - <input type="submit"> - <hr style="height:0px; visibility:hidden;" /> + </label> + <button class="button" type="submit">Submit</button> </form> <hr style="height:40px; visibility:hidden;" /> </main> -<footer th:insert="~{/fragments/Templating.html :: footer}"></footer> +<footer th:insert="~{/fragments/banners :: footer}"></footer> </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/landmarks/locationApprovalFormTh.html b/src/main/resources/templates/landmarks/locationApprovalFormTh.html new file mode 100644 index 0000000000000000000000000000000000000000..eb8c45db5cebcf1f755f1aecdc29f5cb98b98495 --- /dev/null +++ b/src/main/resources/templates/landmarks/locationApprovalFormTh.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Title</title> + + <link rel="stylesheet" th:href="@{css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{css/locationApprovalFormStyle.css}"> + <script src="/scripts/locationApprovalForm.js"></script> + + +</head> +<body> +<header th:insert="~{/fragments/Templating.html :: header}"></header> +<hr style="height:20px; visibility:hidden;" /> +<main> + <H1 id="formHeader">Locations To Be Approved:</H1> + + <form action="/checkpointSubmitted" method="post" id="adminCheckpointApproval" name="adminCheckpointApproval" th:object="${locationCoord}" onsubmit="return acceptanceValidation()"> + <label> Location: + <select th:object="${location}" th:field="*{locationName}"}> + <!-- <select th:field="*{locationName}">--> + <option value="" hidden="true">Select Location</option> + <option value="" selected disabled>Select Location</option> + <option th:each="uloc:${uLocs}" th:value="${uloc.getLocationName()}" th:text="${uloc.getLocationName()}+' ('+${uloc.getLocationTrailID()}+')'"> + </option> + </select> + </label> + <br><br> + <label> Location Latitude: + <input type="text" th:field="*{locationCoordsLat}" placeholder="Latitude Here"> + <div th:errors="*{locationCoordsLat}" th:if="${#fields.hasErrors('locationCoordsLat')}">ErrorlocationCoordsLat</div> + <br><br> + <label> Location Longitude: + <input type="text" th:field="*{locationCoordsLong}" placeholder="Latitude Here"> + </label><br><br> + <div th:errors="*{locationCoordsLong}" th:if="${#fields.hasErrors('locationCoordsLong')}">ErrorlocationCoordsLat</div> + <input type="submit"> + + </form> + + <hr style="height:20px; visibility:hidden;" /> + <section id =unapprovedList > + <H2>To Be Approved:</H2> + + <table> + <tr> + <th>Business Name</th> + <th>Town</th> + <th>Contact Address</th> + <th>Description</th> + </tr> + <div th:each="uloc:${uLocs}"> + <tr> + <td th:text="${uloc.getLocationName()}+' ('+${uloc.getLocationTrailID()}+')'" ></td> + <td th:text="${uloc.getLocationPlace()}"></td> + <td th:text="${uloc.getLocationEmail()}"></td> + <td th:text="${uloc.getLocationDescription()}"></td> + </tr> + </div> + <tr> + + </table> + + + </section> + + <hr style="height:20px; visibility:hidden;" /> +</main> +<footer th:insert="~{/fragments/Templating.html :: footer}"></footer> +</body> +</html> \ No newline at end of file diff --git a/src/main/resources/templates/landmarks/locationPage.html b/src/main/resources/templates/landmarks/locationPage.html index 7cf62c6f4cb81dd98416bf95f89c973b7714c40f..902a660f6d492edb8ecc890cdc4cf07e00ebccdc 100644 --- a/src/main/resources/templates/landmarks/locationPage.html +++ b/src/main/resources/templates/landmarks/locationPage.html @@ -5,11 +5,12 @@ <title>Checkpoint</title> <!-- todo make this a list per trail or per town that when clicked brings to unique location page--> <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> </head> <body> <main> - <header th:insert="~{/fragments/Templating.html::header}"></header> + <header th:replace="~{/fragments/banners::header}"></header> <div th:each="coord, indexValue:${locationCoords}"> <p th:text="*{coord.getLocationID()}"></p> <!-- <p th:text="${locations[indexValue.index]}"></p>--> @@ -42,6 +43,6 @@ </main> -<footer th:insert="~{/fragments/Templating.html::footer}"></footer> +<footer th:replace="~{/fragments/banners::footer}"></footer> </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/landmarks/trailsPage.html b/src/main/resources/templates/landmarks/trailsPage.html index 4316d94fe409ebeba57db4005b31fbba6178bc70..488cffbfccfe2e884138bb815003ef57559bc083 100644 --- a/src/main/resources/templates/landmarks/trailsPage.html +++ b/src/main/resources/templates/landmarks/trailsPage.html @@ -83,6 +83,14 @@ +<!-- <div th:each="locationCoord:${locationCoords}" >--> +<!-- <div th:each="location:${locations}">--> +<!-- <div th:if="${location.getLocationTrailID()==trail.getTrailsId()}">--> +<!-- <li style="list-style: none">--> +<!-- <a th:href="'/checkpoints/'+${location.getLocationName().replace(' ', '-')}" th:text="${location.getLocationName()}"></a>--> +<!-- <ul></ul>--> +<!-- </li></div>--> + </div> diff --git a/src/main/resources/templates/local-auth-data.html b/src/main/resources/templates/local-auth-data.html index 3a3dd6098bd0739bdd960f5c31d553e0eaf4af6a..57870dfa18111c39fe4b8781035b0a4c0d5a595e 100644 --- a/src/main/resources/templates/local-auth-data.html +++ b/src/main/resources/templates/local-auth-data.html @@ -5,38 +5,40 @@ <title>Local Authority</title> <link rel="stylesheet" th:href="@{css/landmarkFormStyle.css}"> - <link rel="stylesheet" th:href="@{css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{css/mobile-style.css}"> </head> -<header th:insert="~{/towns/Templating.html::header}"></header> +<header th:insert="~{/fragments/banners::header}"></header> <body> -<div id="container1"> - <h2>Enter your Local authority</h2> - <form action="/local-auth-data" id="data" name="data" method="post" th:object="${localAuthority}"> - <br> - <label>Enter your local authority - <input type="text" th:field="*{localAuthorityName}"> - </label><br><br> - <label>Please enter first line of your address - <input type="text" th:field="*{address1}"> - </label><br><br> - <label>Please enter second line of your address (optional) - <input type="text" th:field="*{address2}"> - </label><br><br> - <label>Please enter the City/Town - <input type="text" th:field="*{city}"> - </label><br><br> - <label>Please enter you county (optional) - <input type="text" th:field="*{county}"> - </label><br><br> - <label>Please enter your postcode - <input type="text" th:field="*{postcode}"> - </label><br><br> - <label>Please enter your website address - <input type="text" th:field="*{website}"> - </label><br><br> - <input type="submit"> - </form> -</div> + <main> + <div id="container1"> + <h2>Enter your Local authority</h2> + <form action="/local-authorities" id="data" name="data" method="post" th:object="${localAuthority}"> + <br> + <label>Enter your local authority + <input type="text" th:field="*{localAuthorityName}"> + </label><br><br> + <label>Please enter first line of your address + <input type="text" th:field="*{address1}"> + </label><br><br> + <label>Please enter second line of your address (optional) + <input type="text" th:field="*{address2}"> + </label><br><br> + <label>Please enter the City/Town + <input type="text" th:field="*{city}"> + </label><br><br> + <label>Please enter you county (optional) + <input type="text" th:field="*{county}"> + </label><br><br> + <label>Please enter your postcode + <input type="text" th:field="*{postcode}"> + </label><br><br> + <label>Please enter your website address + <input type="text" th:field="*{website}"> + </label><br><br> + <input type="submit"> + </form> + </div> + </main> </body> -<footer th:insert="~{/towns/Templating.html::footer}"></footer> +<footer th:insert="~{/fragments/banners::footer}"></footer> </html> \ No newline at end of file diff --git a/src/main/resources/templates/local-authorities.html b/src/main/resources/templates/local-authorities.html index 05d4701e5fe60f8e1bc105323a03f91b99b31a39..eeda465b960b8413d81a77868c941c72d6407df0 100644 --- a/src/main/resources/templates/local-authorities.html +++ b/src/main/resources/templates/local-authorities.html @@ -4,17 +4,19 @@ <meta charset="UTF-8"> <title>Local Authorities</title> <link rel="stylesheet" th:href="@{css/localAuthorityPageStyle.css}"> - <link rel="stylesheet" th:href="@{css/templatingstyle.css}"> + <link rel="stylesheet" th:href="@{css/mobile-style.css}"> </head> -<header th:insert="fragments/Templating.html :: header"></header> +<header th:insert="fragments/banners :: header"></header> <body> -<h1>Local Authorities</h1> -<div id="councils"> - <ul th:each="local:${localAuth}"> - <li th:text="${local}"></li> - </ul> -</div> -<button><a href="/localForm" id="authority">Local Authorities please enter here</a></button> -<div th:insert="fragments/Templating.html :: footer"></div> + <main> + <h1>Local Authorities</h1> + <div id="councils"> + <ul th:each="local:${localAuth}"> + <li th:text="${local}"></li> + </ul> + </div> + <button><a href="/localForm" id="authority">Local Authorities please enter here</a></button> + <div th:insert="fragments/banners :: footer"></div> + </main> </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/towns/home/homePage.html b/src/main/resources/templates/towns/home/homePage.html index ec489ae7d334997390462ef1ffbe0d3ceaf5c828..71e7d268459a9eb2180c009533dcbe1d127d5f1b 100644 --- a/src/main/resources/templates/towns/home/homePage.html +++ b/src/main/resources/templates/towns/home/homePage.html @@ -13,12 +13,13 @@ <div class="gridContainer1"> <H1 id="homeTitle"> VZTA Smart Towns - Trails</H1> <a class="submitLand" href="/landmarkSubmission"> <button> Submit Landmark!</button></a> + <a class="reviewLand" href="/checkpointApproval"> <button> Review Landmark!</button></a> <!-- <div th:text="${towns}">--> </div> <div th:each="town:${towns}" class="gridContainer2"> - <a href="/allTrails" class="Banner" + <a th:href="'/towns/'+${town.getName()}" class="Banner" th:style="'background:url('+ ${town.getImageTown()} +');'" th:styleappend="'background-size: 80vw 24vh;'+'background-repeat: no-repeat;'+'background-position: left 30%;'" /> diff --git a/src/main/resources/templates/towns/home/mobile-homepage.html b/src/main/resources/templates/towns/home/mobile-homepage.html new file mode 100644 index 0000000000000000000000000000000000000000..43da82f7201b96bd66ab76381a4d450bc2a0ddb2 --- /dev/null +++ b/src/main/resources/templates/towns/home/mobile-homepage.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>VZTA - Smart Towns Trails</title> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> + <link rel="stylesheet" th:href="@{/css/homePageStyle.css}"> +</head> +<body> +<header th:replace="~{/fragments/banners::header}"></header> + +<main> + <div class="title-container"> + <h1 class="title">Welcome to VZTA Smart Towns!</h1> + <a class="submitLand" href="/landmarkSubmission"> <button> Submit Landmark!</button></a> + <p class="small-text">Choose your town and start tracking your trails!</p> + </div> + + <article class="towns-wrapper"> + <div th:each="town:${towns}" class="gridContainer2"> + <h2 class="town-name" th:text="${town.getName()}"></h2> + <a th:href="'/allTrails-' + ${town.getName()}" class="img-container"> + <img class="town-img" th:src="${town.getImageTown()}" th:alt="${town.getName()}"> + </a> + <div class="BannerTrail"> + <div class="BannerFill" th:style="'width: '+ ${town.getTrailProgress()} + '%;'" th:classappend="${town.setTrailProgressClass()}" ></div> + <div class="trail-info"> + <h4 class="trailCount" th:text="'Trails: '+ ${town.getTrailNumber()}"></h4> + <h4 class="trailProgress" th:text="${town.getTrailProgress()}+'%'"></h4> + </div> + </div> + </div> + </article> + + + <div class="gridContainer3"> + + + <div id="aboutUsFlavour"> This is placeholder text about VZTA, this application, + the trails and towns and resultant awards written in an excitable manner!!</div> + + </div> + +</main> +<footer th:replace="~{/fragments/banners::footer}"></footer> + +</body> +</html> diff --git a/src/main/resources/templates/towns/townsPageList.html b/src/main/resources/templates/towns/townsPageList.html new file mode 100644 index 0000000000000000000000000000000000000000..8d25c5a41ba9ccce99a05aa7faea90207b1d6026 --- /dev/null +++ b/src/main/resources/templates/towns/townsPageList.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>towns</title> +</head> +<body> +<main> + <div th:each="town:${towns}"> + <H1 th:text="${town.getTownName()}"></H1> + <li> +<!-- <ul th:if="*{town.getTownName()=='Caerphilly'}"></ul>--> + </li> + + + </div> + + +</main> +</body> +</html> \ No newline at end of file diff --git a/src/main/resources/templates/towns/trails/dragonstale/index.html b/src/main/resources/templates/towns/trails/dragonstale/index.html deleted file mode 100644 index 7cf5948e993116ac247cf9c8aaac3d1ece2e8762..0000000000000000000000000000000000000000 --- a/src/main/resources/templates/towns/trails/dragonstale/index.html +++ /dev/null @@ -1,62 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<html xmlns:th="http://www.thymeleaf.org"> - <meta charset="UTF-8"> - <title>A Dragon's Tale</title> - <link rel="stylesheet" th:href="@{/css/dragonstaless.css}"> - <link rel="stylesheet" th:href="@{/css/templatingstyle.css}"> - <script src="./node_modules/html5-qrcode/html5-qrcode.min.js"></script> -</head> - <body> - <header th:insert="fragments/Templating.html :: header"></header> - - <!-- As this predefined trail will be accessible from multiple different towns, this thymeleaf element will display the town the user is currently trying to access and display it accordingly. <span th:text="${townName}"> --> - <div class="centre"> - <h1> Welcome, to a dragon's tale! </h1> - <img th:src="@{/images/trails/dragonstalehome.png}" alt="Image of a dragon" id="homeimg"> - <h2> Discover the mystery of the dragon, track its location and follow it throughout the town of to discover a prize! </h2> - </div> - - <div class="centre"> - <p> - Adventurers... embark through mystical historical landmarks to ultimately discover the lair of the dragon. - Legend has it that within this ominous lair, mighty dragons, guardians of ancient wisdom and treasures untold lay.... - </p> - </div> - - - <!-- tabs --> - <div class="centre"> - <h2>There are <span th:text="${getListSize}"> Size of List </span> adventures in this journey! </h2> - <ul th:each="item : ${landmarksList}" id="tabBox"> - <li> - <a id="tabIdCounter" href="#landmarkTabLink" th:text="${item.landmarkName}"> Landmark Tab</a> - </li> - </ul> - </div> - - - <!-- Need to mark each element to an ID then loop through them. --> - <div class="centre" id="listOfLandmarks"> - <p th:each="item : ${landmarksList}"> - <span th:text="${item.landmarkDescription}" class="landmarkDesc" id="landmarkTabLink"> Landmark Description</span> - </p> - </div> - - <!-- If use is starting their journey, this will display begin. If not, they'll continue their journey. <span th:text="${beginOrContinue}"> --> - <div class="centre"> - <h3> Begin or Continue your hunt!</h3> - <button type="button" id="begin">Click here!</button> - </div> - - <div th:insert="fragments/Templating.html :: footer"></div> - - <script> - - document.getElementById("begin").addEventListener("click", function (){ - window.location.href = ("/dragonstale/landmarkone"); - }) - - </script> - </body> -</html> \ No newline at end of file diff --git a/src/main/resources/templates/towns/trails/dragonstale/script.js b/src/main/resources/templates/towns/trails/dragonstale/script.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/main/resources/templates/userTrails/userTrailsTemplate.html b/src/main/resources/templates/userTrails/userTrailsTemplate.html new file mode 100644 index 0000000000000000000000000000000000000000..c6fe2d53f76b3d144579d59be2bc28a365bfe9e2 --- /dev/null +++ b/src/main/resources/templates/userTrails/userTrailsTemplate.html @@ -0,0 +1,41 @@ +<!--<!DOCTYPE html>--> +<!--<html lang="en">--> +<!--<head>--> +<!-- <meta charset="UTF-8">--> +<!-- <title>Trails</title>--> +<!--</head>--> +<!--<body>--> +<!--<main>--> +<!-- <H1>Caerphilly</H1>--> +<!-- <div th:each="location:${locations}">--> + +<!-- <H2></H2>--> + +<!-- <ul>--> +<!-- <li th:text="${location.getLocationPlace()}"></li>--> +<!-- </ul>--> + + + + + + + + + + + + +<!-- </div>--> + + + + +<!--</main>--> + + + + + +<!--</body>--> +<!--</html>--> \ No newline at end of file diff --git a/src/main/resources/templates/users/login.html b/src/main/resources/templates/users/login.html index 82f791b9acfff17bada66a547b3f2e3e7d79d29b..6119dcce66cb09b8a4dd9ef7a2e3da77bfa80278 100644 --- a/src/main/resources/templates/users/login.html +++ b/src/main/resources/templates/users/login.html @@ -3,28 +3,25 @@ <head> <meta charset="UTF-8"> <title>User Log In</title> - <link rel="stylesheet" th:href="@{/css/style.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/login.css}"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> </head> <body> -<header> - <form name="logoutForm" th:action="@{/logout}" method="post" th:hidden="false"> - <input hidden type="submit" value="Sign Out"/> - <button type="submit">CLICK ME OT LOG OUT</button> - </form> -</header> +<header th:replace="~{/fragments/banners::header}"></header> <main> <!--CODE MODIFIED FROM: https://github.com/AsmrProg-YT/Modern-Login --> - <div class="container sign-in"> + <div class="container" th:classappend="${status}" id="container"> <div class="form-container sign-up"> - <form th:object="${user}" action="#" th:action="@{/login/register}" th:method="POST" onsubmit="return registerFormValidation()"> - <h1>Create Account</h1> + <h1 class="form-title">Create Account</h1> + <form th:object="${user}" action="#" th:action="@{/register}" th:method="POST" onsubmit="return registerFormValidation()"> <div th:if="${error.equals('User exists')}" class="alert alert-error">User already exist</div> + <div th:text="${errors}" class="alert alert-error"></div> <label> <input class="input" th:field="*{name}" id="register-username" type="text" placeholder="Name"> </label> @@ -38,16 +35,18 @@ </form> </div> <div class="form-container sign-in"> + <h1 class="form-title">Sign In</h1> <form name="f" th:action="@{/login}" th:method="POST"> - <h1>Sign In</h1> <div th:if="${param.error}" class="alert alert-error">Invalid Username or Password</div> + <div th:if="${param.logout}" class="alert alert-success">Successfully Logged out</div> + <div th:if="${param.register}" class="alert alert-success">Account Created Successfully</div> <label> <input class="input" id="username" type="text" name="username" placeholder="Email"> </label> <label> <input class="input" id="password" type="password" name="password" placeholder="Password"> </label> - <a href="#" class="text">Forget Your Password?</a> + <a href="#" class="recovery-text">Forget Your Password?</a> <button type="submit">Sign In</button> </form> </div> @@ -59,18 +58,17 @@ <button class="hidden" id="login">Sign In</button> </div> <div class="toggle-panel toggle-right"> - <div th:if="${param.logout}" class="alert alert-success">Successfully Logged out</div> - <h1 th:if="!${param.logout}">Hello, Welcome!</h1> - <p th:if="!${param.logout}">Register with your personal details and start earning stickers!</p> + <h1>Hello, Welcome!</h1> + <p>Register with your personal details and start earning stickers!</p> <button class="hidden" id="register">Sign Up</button> </div> </div> </div> </div> - </div> -</main> +</main> +<footer th:replace="~{/fragments/banners::footer}"></footer> <script type="text/javascript" th:src="@{scripts/login.js}"></script> diff --git a/src/main/resources/templates/users/userFrags.html b/src/main/resources/templates/users/userFrags.html index 5b5e8201f805bdcbed9234da8c39d6a4b79e94f7..33fb7b7b988c915af79e63fb2daeeb7822fa10db 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 edbe13918a53d466e7194ba42ff9dcf86bebdc56..a7f4787de673240f2cf600d0845f256eb30db18b 100644 --- a/src/main/resources/templates/users/userProfile.html +++ b/src/main/resources/templates/users/userProfile.html @@ -3,60 +3,32 @@ <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> - </div> - </div> - </article> - <article th:replace="~{users/userFrags.html::stickersBox}" id="stickersBox"></article> - </section> - -</main> - -<footer> - -</footer> -<script type="text/javascript" th:src="@{../scripts/userPage.js}"></script> - -<script> -</script> +<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"> + <article th:replace="~{users/userFrags.html::stickersBox}" id="stickersBox"></article> + </section> + </main> + + <footer th:replace="~{/fragments/banners::footer}"></footer> + + <script type="text/javascript" th:src="@{../scripts/userPage.js}"></script> </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/welcome-page.html b/src/main/resources/templates/welcome-page.html new file mode 100644 index 0000000000000000000000000000000000000000..ed84a8bb9a708c8d6ed940d42dcdfa338ded18b0 --- /dev/null +++ b/src/main/resources/templates/welcome-page.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <title>Title</title> + <link rel="stylesheet" th:href="@{/css/colours.css}"> + <link rel="stylesheet" th:href="@{/css/mobile-style.css}"> +</head> + +<body> + <header th:replace="~{/fragments/banners :: header}"></header> + + <main> + <h1>Welcome to Smart Towns by VZTA!</h1> + <p>Click here to start exploring!</p> + <button type="submit">Explore!</button> + </main> + + <footer th:replace="~{/fragments/banners :: footer}"></footer> +</body> +</html> \ No newline at end of file diff --git a/src/test/java/CalculatorTest.java b/src/test/java/CalculatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..67f7188b69d68e843ee28d769d0960084475947b --- /dev/null +++ b/src/test/java/CalculatorTest.java @@ -0,0 +1,49 @@ +import Team5.SmartTowns.data.Calculator; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +//import org.springframework.dao.DataAccessException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +//import org.junit.platform.engine.TestDescriptor; +//import org.junit.platform.commons.util.Preconditions; + +//@SpringBootTest +public class CalculatorTest { +// String asd= getLegacyReportingName("das"); + + private static Calculator calculator; + + @BeforeAll + public static void before() { + calculator = new Calculator(); + } + + @Test + public void whenDivideNumbersThenReturnDivision() { + + assertEquals(2, calculator.divide(4, 2)); + } + + @Test + public void whenDivideByZeroThenThrowException() { + assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0)); + } + @Test + public void whenAddingThingsThenAdd(){ + assertEquals(10,calculator.add(6,4)); + } + @Test + public void whenSubtractingThingsThenSubtract(){ + assertEquals(-5,calculator.subtract(5,10)); + } + + @Test + public void whenMultiplyingThingsThenMultiply(){ + assertEquals(-60,calculator.multiply(-3,20)); + } + + + + +} diff --git a/src/test/java/Team5/SmartTownsOld/DBUnitTestCase.java b/src/test/java/Team5/SmartTownsOld/DBUnitTestCase.java new file mode 100644 index 0000000000000000000000000000000000000000..454e85ee54dd4589fbd7c52f75271b908a1bbbbb --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/DBUnitTestCase.java @@ -0,0 +1,26 @@ +package Team5.SmartTownsOld; + +import org.junit.jupiter.api.Test; + +//import static org.testing.AssertJUnit.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +//import org.springframework.boot.test.context.SpringBootTest; +//import org.testng.annotations.Test; +//import org.testng.annotations.Test; +//import org.apiguardian.api; +//import org.junit.platform.engine.TestDescriptor; + +//import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class DBUnitTestCase { + int bb=4; + int aa=5; + @Test + void whenDivideNumbersThenReturnDivision() { + int aa=5; + assertEquals(5, aa); + } + + +} \ No newline at end of file diff --git a/src/test/java/Team5/SmartTowns/DataSourceConfig.java b/src/test/java/Team5/SmartTownsOld/DataSourceConfig.java similarity index 100% rename from src/test/java/Team5/SmartTowns/DataSourceConfig.java rename to src/test/java/Team5/SmartTownsOld/DataSourceConfig.java diff --git a/src/test/java/Team5/SmartTowns/LocationRepositoryTest.java b/src/test/java/Team5/SmartTownsOld/LocationRepositoryTest.java similarity index 74% rename from src/test/java/Team5/SmartTowns/LocationRepositoryTest.java rename to src/test/java/Team5/SmartTownsOld/LocationRepositoryTest.java index 0c029bd95f7e372481c2a64c0aa2394b8794ff73..ec99ea8acc624d44b3aebaed927421b1137bf096 100644 --- a/src/test/java/Team5/SmartTowns/LocationRepositoryTest.java +++ b/src/test/java/Team5/SmartTownsOld/LocationRepositoryTest.java @@ -1,4 +1,4 @@ -package Team5.SmartTowns; +package Team5.SmartTownsOld; import Team5.SmartTowns.data.Location; import Team5.SmartTowns.data.LocationRepository; @@ -19,8 +19,7 @@ import java.util.List; import java.util.Objects; import static junit.framework.TestCase.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) @SpringBootTest @@ -46,7 +45,7 @@ public class LocationRepositoryTest { // } @Test - public void testGetAllApprovedLocations() { + public void testGetAllApprovedLocations() { // test to amke sure all approved locations are called List<Location> approvedLocations = locationRepository.getAllApprovedLocations(); List<Location> allLocations = locationRepository.getAllLocation(); for (int i=0;i<allLocations.size();i++){ // iterate over all location, removing authorised=true @@ -68,7 +67,7 @@ public class LocationRepositoryTest { @Test - public void testGetAllUnapprovedLocations() { + public void testGetAllUnapprovedLocations() { // test to make sure all unapproved coordinates are called List<Location> unapprovedLocations = locationRepository.getAllUnapprovedLocations(); List<Location> allLocations = locationRepository.getAllLocation(); for (int i=0;i<allLocations.size();i++){ // iterate over all location, removing authorised=false @@ -77,17 +76,17 @@ public class LocationRepositoryTest { allLocations.remove(allLocations.get(i)); } } - } boolean noUnapporvedLeft=false; + } boolean noUnapprovedLeft=false; for (Location loc2: allLocations){ if (!loc2.isLocationApproved()){ - noUnapporvedLeft=false; + noUnapprovedLeft=false; break; } else{ - noUnapporvedLeft=true; + noUnapprovedLeft=true; } - } assertTrue(noUnapporvedLeft); + } assertTrue(noUnapprovedLeft); } - @Test + @Test// test to ensure that the number of approved locations and number of associated locations with coordinates are equal public void ensureApprovedLocationsAndCoordinatessAreTheSameSize(){ List<Location> approvedLocations = locationRepository.getAllApprovedLocations(); List<LocationsCoordinates> coordinatesLocations = placesRepository.getAllLocationCoords(); @@ -96,11 +95,10 @@ public class LocationRepositoryTest { } - @Test + @Test // test to ensure that all default locations and location coordinates match public void ensureApprovedLocationsAndCoordinatessTableLineUpTest(){ List<Location> approvedLocations = locationRepository.getAllApprovedLocations(); List<LocationsCoordinates> coordinatesLocations = placesRepository.getAllLocationCoords(); - List<Integer> coordinatesLocationsID = new ArrayList<>(); boolean doTheyMatch=false; for (int i=0;i<coordinatesLocations.size();i++){ int locID=coordinatesLocations.get(i).getLocationID(); @@ -117,4 +115,16 @@ public class LocationRepositoryTest { } assertTrue(doTheyMatch); } + + + @Test + public void doesApprovalUpdateTest(){ //tests whether locations that are approved have their database approval changed to true + int approvedLocationsTotal = locationRepository.getAllApprovedLocations().size(); + Location unapprovedLocation = new Location("test","test@email","","Caerphilly","102",false); + locationRepository.addLocation(unapprovedLocation); + int newID=locationRepository.nametoLocationID( unapprovedLocation.getLocationName()); + locationRepository.updateApprovalStatus(newID); + int newApprovedLocationsTotal = locationRepository.getAllApprovedLocations().size(); + assertEquals(1,(newApprovedLocationsTotal-approvedLocationsTotal)); + } } diff --git a/src/test/java/Team5/SmartTowns/SmartTownsApplicationTests.java b/src/test/java/Team5/SmartTownsOld/SmartTownsApplicationTests.java similarity index 100% rename from src/test/java/Team5/SmartTowns/SmartTownsApplicationTests.java rename to src/test/java/Team5/SmartTownsOld/SmartTownsApplicationTests.java diff --git a/src/test/java/Team5/SmartTownsOld/Test4.java b/src/test/java/Team5/SmartTownsOld/Test4.java new file mode 100644 index 0000000000000000000000000000000000000000..cdeb2c54bf5cf95b080e01a446a9bd01ba734d20 --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/Test4.java @@ -0,0 +1,33 @@ +package Team5.SmartTownsOld; + +//import Team5.SmartTowns.Data.Location; +//import Team5.SmartTowns.Data.LocationRepositoryJDBC; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +//import org.springframework.jdbc.core.JdbcTemplate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +@SpringJUnitConfig +public class Test4 { +// @Mock +// JdbcTemplate jdbcTemplate; + + +// @BeforeAll +// static void before() { +// Location location = new Location(); +// } + @Test + + public void whenMockJdbcTemplate_thenReturnCorrectEmployeeCount() { +// Location aa=new Location(); +// LocationRepositoryJDBC employeeDAO = new LocationRepositoryJDBC(); +// ReflectionTestUtils.setField(employeeDAO, "jdbcTemplate", jdbcTemplate); +// Mockito.when(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM locations", Integer.class)) +// .thenReturn(4); + + assertEquals(4, 4); + } +} diff --git a/src/test/java/Team5/SmartTownsOld/Test5.java b/src/test/java/Team5/SmartTownsOld/Test5.java new file mode 100644 index 0000000000000000000000000000000000000000..23c643521f868e300ca6abb7b8328c0d523a42f6 --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/Test5.java @@ -0,0 +1,37 @@ +package Team5.SmartTownsOld; + +import Team5.SmartTowns.data.LocationRepository; +//import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.jdbc.Sql; + + +//import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +//@JdbcTest +// +@Sql({"/resources/schema.sql", "/resources/test-data.sql"}) +public class Test5 { + + @Autowired + private LocationRepository locationRepo; + + + @Test +// test 1 + void whenInjectInMemoryDataSource_thenReturnCorrectEmployeeCount() { +// LocationRepositoryJDBC employeeDAO = new LocationRepositoryJDBC(ajdbc); + int aa=2; + int bb=2; +// employeeDAO.setJdbc(ajdbc); + assertEquals(4, (aa+bb)); + + } + + + +} diff --git a/src/test/java/Team5/SmartTownsOld/Test6Mock.java b/src/test/java/Team5/SmartTownsOld/Test6Mock.java new file mode 100644 index 0000000000000000000000000000000000000000..9a19e2dcee2894578f8c714ab617c2e979db9ca7 --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/Test6Mock.java @@ -0,0 +1,79 @@ +//package Team5.SmartTowns; +// +//import Team5.SmartTowns.Data.Location; +//import Team5.SmartTowns.Data.LocationRepository; +//import Team5.SmartTowns.Data.LocationRepositoryJDBC; +//import org.junit.Before; +////import org.junit.runner.RunWith; +////import org.mockito.Mockito; +////import org.mockito.internal.invocation.InvocationsFinder; +//import org.junit.jupiter.api.BeforeAll; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.boot.test.context.SpringBootTest; +//import org.springframework.boot.test.context.TestConfiguration; +// +//import org.springframework.boot.test.mock.mockito.MockBean; +//import org.springframework.context.annotation.Bean; +//import org.springframework.jdbc.core.JdbcTemplate; +////import org.springframework.test.context.junit4.SpringRunner; +//import org.testng.annotations.Test; +// +//import java.util.ArrayList; +//import java.util.List; +// +//import static org.testng.AssertJUnit.assertEquals; +// +////@RunWith(SpringRunner.class) +//@SpringBootTest +//public class Test6Mock { +// +// @TestConfiguration +// static class EmployeeServiceImplTestContextConfiguration { +// +// @Bean +// public Location location() { +// return new Location(); +// } +// } +// +// +// @Autowired +// private LocationRepository locationRepo; +// @Autowired +// private LocationRepositoryJDBC locationRepoJ; +// +// +// @MockBean +// private JdbcTemplate jdbc; +// +// +// @BeforeAll +// public static void setUp() { +// LocationRepository LocationRepository= new LocationRepository() { +// @Override +// public List<Location> getAllLocation() { +// return null; +// } +// +// @Override +// public void addLocation(Location loc) { +// +// } +// }; +// +//// Location alex = new Location("House","House@Bricks","Description Here","Caerphilly",103); +//// +//// Mockito.when(LocationRepository.getAllLocation()) +//// .thenReturn(LocationRepository.getAllLocation()); +// } +// +// +// @Test +// public void whenValidName_thenEmployeeShouldBeFound() { +// LocationRepositoryJDBC s= new LocationRepositoryJDBC(jdbc); +// List<Location> locations = LocationRepository.getAllLocation(); +// assertEquals(18,locations.size()); +// +// } +// } +// diff --git a/src/test/java/Team5/SmartTowns/TrailsRepositoryTest.java b/src/test/java/Team5/SmartTownsOld/TrailsRepositoryTest.java similarity index 97% rename from src/test/java/Team5/SmartTowns/TrailsRepositoryTest.java rename to src/test/java/Team5/SmartTownsOld/TrailsRepositoryTest.java index c0d8d91555c8a68955b49b61ba78c2589f7a507e..ad45f88bb013cb4caf74994c24f4f3574d215022 100644 --- a/src/test/java/Team5/SmartTowns/TrailsRepositoryTest.java +++ b/src/test/java/Team5/SmartTownsOld/TrailsRepositoryTest.java @@ -1,4 +1,4 @@ -package Team5.SmartTowns; +package Team5.SmartTownsOld; import Team5.SmartTowns.data.LocationRepository; import Team5.SmartTowns.data.TrailsRepository; diff --git a/src/test/java/Team5/SmartTowns/data/LocationRepositoryJDBCTest.java b/src/test/java/Team5/SmartTownsOld/data/LocationRepositoryJDBCTest.java similarity index 100% rename from src/test/java/Team5/SmartTowns/data/LocationRepositoryJDBCTest.java rename to src/test/java/Team5/SmartTownsOld/data/LocationRepositoryJDBCTest.java diff --git a/src/test/java/Team5/SmartTownsOld/data/LocationTest.java b/src/test/java/Team5/SmartTownsOld/data/LocationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dad4c98b379fde6d9e2c78fa91a0d5c3a6530e79 --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/data/LocationTest.java @@ -0,0 +1,5 @@ +package Team5.SmartTownsOld.data; + +class LocationTest { + +} \ No newline at end of file diff --git a/src/test/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesTest.java b/src/test/java/Team5/SmartTownsOld/placeswithcoordinates/PlacesCoordinatesTest.java similarity index 53% rename from src/test/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesTest.java rename to src/test/java/Team5/SmartTownsOld/placeswithcoordinates/PlacesCoordinatesTest.java index 933541d774f1666db611121fd72377a02c73c78c..092d2ba3d0144b18a1d0946ee029cb2e7143e29a 100644 --- a/src/test/java/Team5/SmartTowns/placeswithcoordinates/PlacesCoordinatesTest.java +++ b/src/test/java/Team5/SmartTownsOld/placeswithcoordinates/PlacesCoordinatesTest.java @@ -1,5 +1,7 @@ package Team5.SmartTowns.placeswithcoordinates; +import Team5.SmartTowns.data.Location; +import Team5.SmartTowns.data.LocationRepository; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -16,6 +18,9 @@ class PlacesCoordinatesTest { @Autowired PlacesCoordinatesRepository placesCoordinatesRepository; + @Autowired + LocationRepository locationRepository; + @Autowired JdbcTemplate jdbcTemplate; @@ -79,4 +84,42 @@ class PlacesCoordinatesTest { @Test void getLocationTableIDValue() { } + + + @Test + public void nameToLocationIDTest(){ + List<Location> locationList = locationRepository.getAllLocation(); + String firstLocationName=locationList.get(0).getLocationName(); + String lastLocationName=locationList.get(locationList.size()-1).getLocationName(); + int firstLocationID= locationRepository.nametoLocationID(firstLocationName); + int lastLocationID= locationRepository.nametoLocationID(lastLocationName); + // if first and last location are chosen and if SQL ID starts at 1 , while an array index starts at 0, then the following should be equal; + String firstLocationTest=locationList.get(firstLocationID-1).getLocationName(); + String lastLocationTest=locationList.get(lastLocationID-1).getLocationName(); + assertEquals(firstLocationName,firstLocationTest); + assertEquals(lastLocationName,lastLocationTest); + + + } + + @Test // test to see if + public void checkIfCoordsAreWithinTownBoundaryTest(){ + // initiate second instance of location without Caerphilly bounds. + List<Location> locationList = locationRepository.getAllLocation(); + Location unapprovedLocation = new Location("test","test@email","","Caerphilly","102",false); + locationRepository.addLocation(unapprovedLocation); + int newID=locationRepository.nametoLocationID( unapprovedLocation.getLocationName()); + LocationsCoordinates newCoord = new LocationsCoordinates(newID,0.00,0.00); + boolean falseIfOutOfBounds = placesCoordinatesRepository.checkIfCoordsAreWithinTownBoundary(newCoord); + // initiate second instance of location within Caerphilly bounds. + Location unapprovedLocationTwo = new Location("test2","test2@email","","Caerphilly","103",false); + locationRepository.addLocation(unapprovedLocationTwo); + int newIDTwo=locationRepository.nametoLocationID( unapprovedLocationTwo.getLocationName()); + LocationsCoordinates newCoordTwo = new LocationsCoordinates(newIDTwo,51.57903,-3.22075 ); + boolean falseIfOutOfBoundsTwo = placesCoordinatesRepository.checkIfCoordsAreWithinTownBoundary(newCoordTwo); + assertNotEquals(falseIfOutOfBounds,falseIfOutOfBoundsTwo); + + + } + } \ No newline at end of file diff --git a/src/test/java/Team5/SmartTowns/testUsers.java b/src/test/java/Team5/SmartTownsOld/testUsers.java similarity index 93% rename from src/test/java/Team5/SmartTowns/testUsers.java rename to src/test/java/Team5/SmartTownsOld/testUsers.java index 2145c47165ed072b8a4c3478774da7410f881414..20e9d34e60524eb896ac57df920ad9e65931458c 100644 --- a/src/test/java/Team5/SmartTowns/testUsers.java +++ b/src/test/java/Team5/SmartTownsOld/testUsers.java @@ -1,4 +1,4 @@ -package Team5.SmartTowns; +package Team5.SmartTownsOld; import Team5.SmartTowns.rewards.RewardsRepository; import Team5.SmartTowns.users.NewUser; @@ -53,7 +53,7 @@ public class testUsers { } @Test - public void canUsersUnlockStickersTest(){ + public void canUsersUnlockStickersTest(){ // tests if users can unlock stickers NewUser newuser = new NewUser("MeowMeowMeow","WoofMeowMeow","CatMeowMeow@Dogs.com"); Boolean newUser = userRepository.addUser(newuser.getName(), newuser.getEmail(), newuser.getPassword()); Boolean doesStickerUnlock = userRepository.unlockSticker(newuser.getName(),2,2); @@ -61,7 +61,7 @@ public class testUsers { assertTrue(doesStickerUnlock); } @Test - public void canUsersUnlockStickersAndViewThemTest(){ + public void canUsersUnlockStickersAndViewThemTest(){ // tests if users who unlock stickers can view them NewUser newuser = new NewUser("MeowMeowMeowMeow","WoofMeowMeowMeow","CatMeowMeowMeow@Dogs.com"); NewUser newuserTwo = new NewUser("Jumper","Baa","Sheep@Wool.com"); Boolean newUser = userRepository.addUser(newuser.getName(), newuser.getEmail(), newuser.getPassword()); diff --git a/src/test/java/Team5/SmartTownsOld/users/UserTests.java b/src/test/java/Team5/SmartTownsOld/users/UserTests.java new file mode 100644 index 0000000000000000000000000000000000000000..50fe6606bce14bec456f720d59ef3f13f3215d2c --- /dev/null +++ b/src/test/java/Team5/SmartTownsOld/users/UserTests.java @@ -0,0 +1,88 @@ +package Team5.SmartTowns.users; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@DisplayName("User Database Operations") +@SpringBootTest +class UserTests { + + @Autowired + UserRepository userRepository; + + @Autowired + JdbcTemplate jdbcTemplate; + + @BeforeEach + public void resetUserTable(){ + /*Deletes table as each test creates the table it needs for its own testing*/ + jdbcTemplate.update("DELETE FROM users"); + } + + @Test + @DisplayName("Add User to Database") + void testAddUser() { + String testEmail = "TestEmail"; + String testPassword = "Password"; + String testUsername = "TestUsername"; + + userRepository.addUser(testUsername, testEmail, testPassword); + + String email = jdbcTemplate.queryForObject("SELECT email FROM users WHERE username=?", String.class, testUsername); + String password = jdbcTemplate.queryForObject("SELECT password FROM users WHERE username=?", String.class, testUsername); + + assertEquals(testPassword, password); + assertEquals(testEmail, email); + + } + + @Test + @DisplayName("Get all from Users") + void testGetAllUsers() { + jdbcTemplate.update("INSERT INTO users (username, password) VALUE ('TestUser1', 'admin')"); + jdbcTemplate.update("INSERT INTO users (username, password) VALUE ('TestUser2', 'admin')"); + jdbcTemplate.update("INSERT INTO users (username, password) VALUE ('TestUser3', 'admin')"); + + List<String> queryList = jdbcTemplate.queryForList("SELECT username FROM users", String.class); + List<User> users = userRepository.getAllUsers(); + + assertEquals(queryList.size(), users.size()); + } + + + @Test + @DisplayName("Find if user exists") + void doesUserExist() { + jdbcTemplate.update("INSERT INTO users (username, email, password) VALUE ('UserExists', 'email@test.com', 'test')" ); + assertTrue( userRepository.doesUserExist("email@test.com") ); + } + + @Test + @DisplayName("Find user by email") + void findUserByEmail() { + String email = "email@test.com"; + jdbcTemplate.update("INSERT INTO users (username, email, password) VALUE ('UserExists', ?, 'test')", + email); + User user = userRepository.findUserByEmail(email); + assertEquals(email, user.getEmail()); + } + + @Test + @DisplayName("Find user by name") + void findUserByName() { + String name = "TestUser"; + jdbcTemplate.update("INSERT INTO users (username, password) VALUE (?, 'test')", + name); + User user = userRepository.findUserByName(name); + assertEquals(name, user.getName()); + } +} \ No newline at end of file diff --git a/src/test/java/Test3.java b/src/test/java/Test3.java new file mode 100644 index 0000000000000000000000000000000000000000..9c8f681f2e84cda6afafd2745e849f7f01d09870 --- /dev/null +++ b/src/test/java/Test3.java @@ -0,0 +1,27 @@ +//import org.junit.jupiter.api.Test; +//import org.springframework.boot.test.context.SpringBootTest; +//import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +//import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +// +//import javax.sql.DataSource; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +// +// +//public class Test3 { +// +// @Test +//// test2 +// public void whenInjectInMemoryDataSource_thenReturnCorrectEmployeeCount1() { +// DataSource dataSource = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) +// .addScript("classpath:schema.sql") +// .addScript("classpath:data.sql") +// .build(); +//// .addScript("classpath:jdbc/test-data.sql") +// +//// LocationRepositoryJDBC employeeDAO = new LocationRepositoryJDBC(); +//// employeeDAO.setDataSource(dataSource); +// +//// assertEquals(4, employeeDAO.getCountOfEmployees());} +// assertEquals(4, 4);} +//} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 83f47c5db5a7390e1ab3dadf4882c3ddf1e3b4ea..5abd1133a1282d079e81ddf4d5f0185fb43a5b40 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -3,6 +3,5 @@ spring.datasource.username=root spring.datasource.password=comsc spring.sql.init.mode=always -spring.sql.init.platform=test -spring.sql.init.schema-locations=classpath:schema-test.sql -spring.sql.init.data-locations=classpath:test-data.sql \ No newline at end of file +spring.sql.init.schema-locations=classpath:schema.sql, classpath:schema-test.sql +spring.sql.init.data-locations=classpath:data.sql, classpath:test-data.sql \ No newline at end of file diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index c2259e46e52a7b84e4dabf968a3c315118ff253a..c3fa214d326ed9e2c4218f54c086af97eaa42bd5 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -1,3 +1,12 @@ +USE test_towns; +INSERT INTO users (username, password) VALUE ('Admin', 'admin'); +INSERT INTO users (username, password) VALUE ('Hannah', 'root'); +INSERT INTO users (username, password) VALUE ('Nigel', 'root'); +INSERT INTO users (username, password) VALUE ('Oscar', 'root'); + +INSERT INTO authorities (username, authority) VALUE ('Admin', 'ADMIN'); +INSERT INTO authorities (username, authority) VALUE ('Hannah', 'USER'); + # delete from users; # insert into users (email, name) value ('hannah@gmail.com', 'Hannah'); # insert into users (email, name) value ('nigel@gmail.com', 'Nigel'); diff --git a/src/test/resources/schema.sql b/src/test/resources/schema.sql index 70cf59c3ea7e21770133191348ff79616c78622a..6bd0ce804c378d73e58c6da53d11412d6c282fd6 100644 --- a/src/test/resources/schema.sql +++ b/src/test/resources/schema.sql @@ -1,8 +1,22 @@ -# DROP DATABASE test_towns; -# CREATE DATABASE test_towns; -# USE test_towns; -# -# +/* DELETES AND RECREATES DATABASE EVERY TIME THE SYSTEM IS BOOTED*/ +DROP DATABASE IF EXISTS test_towns; +CREATE DATABASE IF NOT EXISTS test_towns; +USE test_towns; +/****************************************************************/ + +CREATE TABLE IF NOT EXISTS users ( + username varchar(30) primary key NOT NULL, + id bigint auto_increment unique, /*DEPRECATED COLUMN, LEFT IN WHILE SOME OTHER FUNCTIONS STILL USE IT*/ + email varchar(128), + password varchar(30) NOT NULL, + enabled boolean default true +); + +CREATE TABLE IF NOT EXISTS authorities ( + id bigint primary key auto_increment NOT NULL, + username varchar(30) NOT NULL , + authority varchar(45) NOT NULL +); # drop table if exists locationCoordinates; # drop table if exists locations; # drop table if exists trails;