Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • d1656298/client-project
  • d1634883/client-project
2 results
Show changes
Commits on Source (97)
Showing
with 819 additions and 3 deletions
......@@ -24,10 +24,14 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok:1.18.28'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
// implementation 'org.springframework.boot:spring-boot-starter-jdbc'
// implementation 'org.mariadb.jdbc:mariadb-java-client:2.1.2'
}
tasks.named('bootBuildImage') {
......
package Team5.SmartTowns.Landmarks;
import Team5.SmartTowns.trails.Trail;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Landmarks {
// Intialised object to getID from trail.
//Predefined Landmark for Dragons Tale.
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")
);
private Integer trailID;
private int landmarkID;
@NotEmpty(message = "You must type in a username.")
private String landmarkName;
@Email(message = "You must attach a contact address.")
private String landmarkEmail;
private String landmarkDescription;
private String landmarkLocation;
private String landmarkPicture;
// Constructor for List above.
public Landmarks( int landmarkID, String landmarkName, String landmarkDescription, String landmarkLocation) {
this.landmarkID = landmarkID;
this.landmarkName = landmarkName;
this.landmarkDescription = landmarkDescription;
this.landmarkLocation = landmarkLocation; }
}
package Team5.SmartTowns.Landmarks;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
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 jakarta.validation.Valid;
@Controller
public class LandmarksController {
// Controllers for LandmarkFormTh.html landmark submission form
@GetMapping("/landmarkSubmission")
public ModelAndView landmarkSubmission(){
ModelAndView modelAndView1 = new ModelAndView("Landmarks/LandmarkFormTh.html");
modelAndView1.addObject("landmarkData", new Landmarks());
return modelAndView1;
}
@PostMapping("/landmarkSub")
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{
System.out.println(landmarks);
// current functionality only prints successful Landmarks, (todo )database integration is necessary here
ModelAndView modelAndView = new ModelAndView("redirect:/test.html");
return modelAndView;
}
}
}
package Team5.SmartTowns.Webpages;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Controller;
@Controller
public class WebpageController {
@GetMapping("/Caerleon")
public ModelAndView getCaerleonPage(){
ModelAndView modelAndView = new ModelAndView("towns/caerleon");
......@@ -26,6 +27,17 @@ public class WebpageController {
return modelAndView;
}
@GetMapping("/home")
public ModelAndView getHome(){
ModelAndView modelAndView = new ModelAndView("towns/home/homePage");
return modelAndView;
}
@RequestMapping(value="/test_ajax_frag", method=RequestMethod.POST)
public String sendHtmlFragment(Model map) {
//map.addAttribute("foo", "bar");
return "fragments/temp_frags.html :: trailInfo2";
}
......
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;
}
}
package Team5.SmartTowns.trails;
import Team5.SmartTowns.Landmarks.Landmarks;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
import static Team5.SmartTowns.Landmarks.Landmarks.landmarksDragonstrail;
@Controller
public class TrailsController {
@GetMapping("/allTrails")
public ModelAndView getAllTrails(){
ModelAndView mav = new ModelAndView("allTrails/allTrails");
mav.addObject("trails", Trail.trails); //Mock data for trails
return mav;
}
@RequestMapping(value="/id", method=RequestMethod.POST)
public String sendHtmlFragment(Model map) {
map.addAttribute("foo", "bar");
return "allTrails/allTrails";
}
@GetMapping("/allTrails/{id}")
public ModelAndView getResultBySearchKey(@PathVariable int id)
{
List<Trail> trailList= Trail.trails;//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;
}
}
* {
box-sizing: border-box;
}
body {
background-color: rgb(41, 41, 41);
margin: 0;
display: flex;
flex-direction: column;
min-height: 100svh;
}
main {
}
.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);
}
.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; }
}
main {
margin: 0;
}
#trailInfoContainer {
overflow: scroll;
}
.trailInfoFrag {
background-color: rgb(84, 33, 128);
border: #000000 solid 2px;
border-radius: 10px;
box-shadow: 0 5px 20px 0 #000000;
margin: 2svh auto;
padding-bottom: 2svw;
width: 70vw;
height: auto;
min-height: 30svh;
animation: fadeIn 3s;
display: grid;
grid-template-areas:
"header header header"
"image text text";
grid-template-columns: 30% 30% auto;
grid-template-rows: 10% auto;
grid-column-gap: 2vw;
grid-row-gap: 2svh;
& .trailInfoHeader {
grid-area: header;
width: 100%;
height: 100%;
margin-top: 1svh;
padding: 0;
& h1 {
color: white;
padding:0;
margin:0 25%;
font-size: 2vw;
text-align: center;
box-shadow: 0 10px 10px -10px black;
}
}
& img {
grid-area: image;
border-radius: 10px;
border: black solid 1px;
margin-left: 2vw;
margin-right: 2vw;
width: 100%;
height: auto;
box-shadow: 0 10px 20px -10px black;
}
& p {
grid-area: text;
color: white;
margin: 0;
padding: 0 2vw;
font-size: 1.3vw;
text-align: justify;
text-justify: inter-character;
line-height: 1.5;
width: fit-content;
height: fit-content;
overflow: scroll;
}
}
#trailFragContent {
margin: 0;
padding: 0;
display: flex;
min-height: 40svh;
flex-wrap: wrap;
}
header {
box-shadow: #1e1e1e 0 0 10px 10px;
font-size: 1vw;
}
.centre{
display: flex;
flex-direction: column;
text-align: center;
margin-left: auto;
margin-right: auto;
width: 50%;
background-color: #927BB7;
}
#homeimg.centre{
box-shadow: 100px -100px purple;
}
body{
background-color: #927BB7;
}
\ No newline at end of file
body{
background-color: rgb(41, 41, 41)
}
#homeTitle{
grid-area: pageTitle;
color: whitesmoke;
}
.submitLand{
grid-area: submitButton;
}
.caerphillyBanner , .riscaBanner,.penarthBanner{
margin-top: 20px;
background-color: darkslategrey;
margin-bottom: 20px;
border: solid 2px whitesmoke;
/*border colour here at .banner and .bannertrail*/
border-right: none;
}
.caerphillyBannerTrail,.riscaBannerTrail,.penarthBannerTrail{
background-color: darkslategrey;
margin-top: 20px;
margin-bottom: 20px;
border: solid 2px whitesmoke;
border-left: none;
text-align: center;
}
.penarthBannerTrail{
background-image: linear-gradient(to right, darkslategrey , darkgoldenrod 40%);
}
.caerphillyBannerTrail{
margin-top: 20px;
margin-bottom: 20px;
border: solid 2px whitesmoke;
border-left: none;
background-image: linear-gradient(to right, darkslategrey , darkgoldenrod 30%);
}
.caerphillyBanner{
grid-area:townBannerC;
background-image: url('/images/CaerphillyCastle.jpg');
/*// from cadw*/
background-size: 850px 200px;
background-repeat: no-repeat;
background-position: left 35%;
color: inherit;
text-decoration: none;
/*filter: grayscale(30%);*/
}
/*!*https://www.stayinwales.co.uk/wales_picture.cfm?p=4454*! Risca img*/
.riscaBanner {
/* #caerUrl{*/
grid-area: townBannerR;
background-image: url('/images/RiscaBanner.jpg');
background-size: 850px 200px;
background-repeat: no-repeat;
background-position: left 65%;
color: inherit;
text-decoration: none;
}
.penarthBanner {
grid-area: townBannerP;
background-image: url('/images/PenarthBanner.jpg');
background-size: 850px 200px;
background-repeat: no-repeat;
background-position: left 78%;
color: inherit;
text-decoration: none;
}
.caerphillyBannerTrail{
grid-area:townBannerDetsC;
}
.riscaBanner{
grid-area:townBannerR;
}
.riscaBannerTrail{
grid-area:townBannerDetsR;
}
.penarthBanner{
grid-area:townBannerP;
}
.penarthBannerTrail{
grid-area:townBannerDetsP;
}
#aboutUsFlavour{
grid-area: textFlavour;
margin-top: 25px;
margin-bottom: 15px;
color: whitesmoke;
}
#trailCountCaer,#trailCountRisca,#trailCountPenarth{
flex:1;
/*align-items: center;*/
/*justify-content: center;*/
}
#trailProgressCaer,#trailProgressRisca,#trailProgressPenarth{
flex:2;
align-content: center;
}
.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 ."
". townBannerC townBannerC townBannerDetsC . ."
". townBannerR townBannerR townBannerDetsR . ."
". townBannerP townBannerP townBannerDetsP . ."
" . . textFlavour . . .";
}
/*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
}
#landmarkFormTitle{
color:white;
text-align: center;
}
\ No newline at end of file
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
#homeHead{
color: inherit;
text-decoration: none;
padding: 0;
margin: 0;}
.center {
text-align: center;
}
body {
background-color: rgb(41, 41, 41);
margin: 0%;
}
.headerBlock {
background-color: rgb(15, 15, 15);
padding-bottom: 20px;
box-shadow: 0 10px 20px black;
.headerTitle {
text-align: center;
padding: 10px 10px 0 10px;
margin: 0 50px 0 50px;
letter-spacing: 10px;
font-size: 50px;
font-style: italic;
color: blueviolet;
text-shadow: black 3px 3px 5px;
border-bottom: 3px blueviolet solid;
}
.headerBanner {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
position: relative;
height: 200px;
border-top: grey solid 2px;
border-bottom: grey solid 2px;
.bannerBack {
opacity: 0.6;
width: 100%;
left: 0;
top: 0;
position: absolute
}
.bigTitle {
color:white;
text-align: center;
position: relative;
font-size: 50px;
margin: 20px 20px 5px;
}
.smallTitle {
position: relative;
color:white;
text-align: center;
font-size: 20px;
margin: 5px 20px 20px;
}
}
}
.mainTrails{
overflow: hidden;
position: relative;
height: 200px;
border-top: grey solid 2px;
border-bottom: grey solid 2px;
}
.trailList {
.ulHeader {
margin: 30px;
display: flex;
list-style: none;
justify-content: center;
padding: 0px;
border-bottom: solid black 5px;
.liHeader {
flex: 1 1 0px;
padding-left: 10px;
padding-right: 10px;
color: white;
text-align: center;
}
.liHeader:hover {
color: blueviolet;
border-bottom: solid blueviolet 2px;
}
.selected {
flex: 1 1 0px;
padding-left: 10px;
padding-right: 10px;
color: rgb(154, 69, 234);
border-bottom: solid blueviolet 2px;
text-align: center;
}
}
}
.mainBlock {
display: flex;
min-width: 300px;
flex-wrap: wrap;
margin-top: 20px;
margin-bottom: 100px;
}
.mainBlock .trailStats{
background-color: rgb(206, 153, 253);
flex: 0 0 0px;
min-width: 400px;
height: 600px;
margin: auto;
margin-bottom: 20px;
box-shadow: 0px 0px 20px rgb(20, 20, 20);
border-radius: 30px;
.stats {
display: block;
width: 200px;
margin: auto;
}
.textStats {
display: block;
text-align: left;
margin: 20px;
}
}
.mainBlock .trailInfo{
background-color: rgb(206, 153, 253);
flex: 0 0 0px;
min-width: 400px;
height: 600px;
margin: auto;
margin-bottom: 20px;
box-shadow: 0px 10px 10px rgb(20, 20, 20);
border-radius: 30px;
.trailInfoTxt {
margin: 15px;
}
}
.titleH1 {
padding: 0px;
margin: 10px 30px 20px 30px;
text-align: center;
font-size: 40px;
font-style: italic;
border-bottom: solid black 1px;
}
.mainBlock p {
font-size: 25px;
text-align: left;
padding: 1px;
}
main .badgesBlock{
bottom: 0%;
background-color: rgb(222, 75, 255);
flex: 0 0 0px;
min-width: 500px;
min-height: 100px;
margin: auto;
margin-bottom: 10px;
box-shadow: 0px 10px 10px rgb(20, 20, 20);
border-radius: 30px;
}
.badgesList {
display: flex;
}
.badgeImg {
flex: 0 1 0px;
width: 60px;
margin: auto;
margin-bottom: 20px;
}
footer {
bottom: 0%;
left: 0%;
position: fixed;
width: 100%;
min-width: 300px;
}
footer .footerBar {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
footer .footerButton {
padding: 20px;
text-align: center;
flex: 1 1 0px;
color:crimson;
background-color: white;
}
footer .footerButton:hover {
background-color: black;
}
\ No newline at end of file
/* Header */
.headerBar {
border-bottom: 2px rgb(230, 230, 230) solid;
margin-bottom: 20px;
display: flex;
background-color: rgb(84, 33, 128);
}
/* Navbar Links */
.navBar {
margin: 2svh 1vw 2svh auto;
text-align: right;
}
.work{
color: rgb(255, 255, 255);
}
.navBar ul {
list-style: none;
display: flex;
margin-left: 100px;
}
.navBar a {
/*border-left: 2px rgb(185, 185, 185) solid;*/
/*padding: 10px 40px;*/
padding-left:5px ;padding-right: 5px;
text-decoration: none;
/*color:rgb(87, 86, 86);*/
/*// original color*/
color:white;
white-space: nowrap;
overflow: hidden;
float: right;
}
.navBar a:hover {
background-color: rgb(209, 209, 209);
}
.navBar li{
margin-left: 10px;
margin-right: 10px;
color: rgb(255, 255, 255);
}
.navListLast {
border-right: 2px rgb(185, 185, 185) solid;
margin-right:40px;
}
/* Navbar Logo */
.Logo {
margin-left:10px;
padding: 20px;
width: fit-content;
}
.Logo img {
width: 120px;
margin-left:15px;
}
/* Footer */
footer {
margin-top:auto;
display: flex;
justify-content: center;
background-color: rgb(84, 33, 128);
border-top: 2px rgb(230, 230, 230) solid;
font-size: 1vw;
}
.footerBar{
text-align: left;
display: flex;
color: rgb(255, 255, 255);
padding-left: 30px;
}
.footerBar ul {
list-style: none;
display: flex;
}
.copyright{
text-align: left;
display: flex;
}
.containerFooter{
display: flex;
flex-direction: row;
}
.leftFooter{
flex:1;
color: rgb(255, 255,255);
}
.centerFooter{
flex: 1;
color: rgb(255, 255,255);
}
.rightFooter{
flex:1;
color: rgb(255, 255, 255);
}
/*CHANGES*/
.headerBar, .footerBar{
margin:0px;
padding: 0px;
width: 100%;
}
src/main/resources/static/images/CaerphillyCastle.jpg

351 KiB

src/main/resources/static/images/Facebook.png

5.53 KiB

src/main/resources/static/images/Instagram.jpg

7.69 KiB

src/main/resources/static/images/Linkedin.png

24.9 KiB

src/main/resources/static/images/PenarthBanner.jpg

263 KiB

src/main/resources/static/images/RiscaBanner.jpg

110 KiB

src/main/resources/static/images/Twitter.jpg

47.5 KiB

src/main/resources/static/images/VZTA.png

11.2 KiB