diff --git a/src/main/java/Team5/SmartTowns/rewards/Badge.java b/src/main/java/Team5/SmartTowns/rewards/Badge.java
new file mode 100644
index 0000000000000000000000000000000000000000..25c231e14e3f0afdd4ecfc2d6e9f352925224097
--- /dev/null
+++ b/src/main/java/Team5/SmartTowns/rewards/Badge.java
@@ -0,0 +1,51 @@
+/*AUTHOR: Gabriel Copat*/
+package Team5.SmartTowns.rewards;
+
+import lombok.Data;
+
+import java.io.File;
+import java.util.Objects;
+
+@Data
+public class Badge {
+    /* Badges can be earned by completing certain goals.
+     * They are displayed in the user profile page
+     *
+     * For example, one might earn a badge after visiting 20 locations */
+
+    int id;
+    String name;
+    String description;
+    String imgPath;
+    int difficulty; //1-5
+
+    public Badge(int id, String name, String description, int difficulty) {
+        this.id = id;
+        this.name = name;
+        this.description = description;
+        this.difficulty = difficulty;
+        imgPath = findImagePath();
+    }
+
+    private String findImagePath(){
+        /* Finds the image in the Path folder, if image is not found assigns default image */
+        String imgPath = "images/rewards/badges/" + id + ".jpg";
+        String notFoundPath = "/images/rewards/badges/0.png";
+
+        File imgFile = new File("src/main/resources/static/" + imgPath);
+        return imgFile.exists() ? imgPath : notFoundPath;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Badge badge = (Badge) o;
+        return id == badge.id && Objects.equals(name, badge.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name);
+    }
+}
diff --git a/src/main/java/Team5/SmartTowns/rewards/RewardsController.java b/src/main/java/Team5/SmartTowns/rewards/RewardsController.java
new file mode 100644
index 0000000000000000000000000000000000000000..af9d33cba34dd12ac6aa5ca1e54320b8124af9d4
--- /dev/null
+++ b/src/main/java/Team5/SmartTowns/rewards/RewardsController.java
@@ -0,0 +1,7 @@
+package Team5.SmartTowns.rewards;
+
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class RewardsController {
+}
diff --git a/src/main/java/Team5/SmartTowns/rewards/Sticker.java b/src/main/java/Team5/SmartTowns/rewards/Sticker.java
new file mode 100644
index 0000000000000000000000000000000000000000..274091bdacbaf6199349956be041eb09e34074ff
--- /dev/null
+++ b/src/main/java/Team5/SmartTowns/rewards/Sticker.java
@@ -0,0 +1,50 @@
+/*AUTHOR: Gabriel Copat*/
+package Team5.SmartTowns.rewards;
+
+import lombok.Data;
+
+import java.io.File;
+import java.util.Objects;
+
+@Data
+public class Sticker {
+    /* Stickers are trade-able rewards, they vary in rarity and are earned at random */
+
+    int id;
+    String name;
+    String description;
+    String imgPath;
+    int rarity; //1-5
+
+    public Sticker(int id, String name, String description, int rarity) {
+        this.id = id;
+        this.name = name;
+        this.description = description;
+        this.rarity = rarity;
+        imgPath = findImagePath();
+    }
+
+    private String findImagePath(){
+        /* Finds the image in the Path folder, if image is not found assigns default image */
+        String imgPath = "images/rewards/stickers/" + id + ".jpg";
+        String notFoundPath = "images/rewards/stickers/0.png";
+
+        File imgFile = new File("src/main/resources/static/" + imgPath);
+        return imgFile.exists() ? imgPath : notFoundPath;
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Sticker sticker = (Sticker) o;
+        return id == sticker.id && Objects.equals(name, sticker.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name);
+    }
+}
+
diff --git a/src/main/java/Team5/SmartTowns/users/User.java b/src/main/java/Team5/SmartTowns/users/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..667222393c481b9e2f573ca1773700a93cf7667d
--- /dev/null
+++ b/src/main/java/Team5/SmartTowns/users/User.java
@@ -0,0 +1,37 @@
+package Team5.SmartTowns.users;
+
+import Team5.SmartTowns.rewards.Badge;
+import Team5.SmartTowns.rewards.Sticker;
+import lombok.Data;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+public class User {
+
+    int id;
+    String email; //Validation would be done by email, since they will have that
+    String name;
+    String imgPath;
+
+    Map<Badge, Integer> badgeProgress = new HashMap<>(); // Demonstrates the progress towards a specific badge (0-100)
+    Map<Sticker, Boolean> hasStickers = new HashMap<>(); // True if User has sticker (key)
+
+    public User(int id, String email, String name) {
+        this.id = id;
+        this.email = email;
+        this.name = name;
+        imgPath = findImagePath();
+    }
+
+    private String findImagePath(){
+        /* Finds the image in the Path folder, if image is not found assigns default image */
+        String imgPath = "images/users/" + id + ".jpg";
+        String notFoundPath = "../images/users/0.png";
+
+        File imgFile = new File("src/main/resources/static/" + imgPath);
+        return imgFile.exists() ? "../" + imgPath : notFoundPath;
+    }
+}
diff --git a/src/main/java/Team5/SmartTowns/users/UserController.java b/src/main/java/Team5/SmartTowns/users/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0df6457070de7a7db2ff33576c569e20120be554
--- /dev/null
+++ b/src/main/java/Team5/SmartTowns/users/UserController.java
@@ -0,0 +1,57 @@
+package Team5.SmartTowns.users;
+
+import Team5.SmartTowns.rewards.Badge;
+import Team5.SmartTowns.rewards.Sticker;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.util.List;
+
+@Controller
+public class UserController {
+
+    /* TEMPORARY USER LIST --- TODO REPLACE IT WITH DATABASE LIST*/
+    static List<User> users = List.of(
+            new User(1, "johndoe@gmail.com", "Claire Redfield"),
+            new User(2, "johndoe@gmail.com", "Albert Wesker"),
+            new User(3, "johndoe@gmail.com", "Leon Kennedy"),
+            new User(4, "johndoe@gmail.com", "Jill Valentine")
+    );
+    static List<Badge> badges = List.of(
+            new Badge(1, "Badge1", "Bage One is This", 1),
+            new Badge(2, "Badge1", "Bage One is This", 4),
+            new Badge(3, "Badge1", "Bage One is This", 4),
+            new Badge(4, "Badge1", "Bage One is This", 5),
+            new Badge(5, "Badge1", "Bage One is This", 5),
+            new Badge(46, "Badge1", "Bage One is This", 5),
+            new Badge(7, "Badge1", "Bage One is This", 2)
+    );
+
+    static List<Sticker> stickers = List.of(
+            new Sticker(1, "Sticker", "Sticker", 1),
+            new Sticker(2, "Sticker", "Sticker", 4),
+            new Sticker(3, "Sticker", "Sticker One is This", 4),
+            new Sticker(4, "Sticker", "Sticker One is This", 5),
+            new Sticker(5, "Sticker", "Sticker One is This", 5),
+            new Sticker(46, "Sticker", "Sticker One is This", 5),
+            new Sticker(7, "Sticker", "Sticker One is This", 2)
+    );
+
+    @GetMapping("/user/{id}")
+    public ModelAndView getUserPage(@PathVariable int id) {
+        ModelAndView mav = new ModelAndView("rewards/userProfile");
+        users.stream()
+                .filter(user -> user.getId() == id)
+                .findFirst() //Convoluted way of finding the matching user to the id, probably easier to do a hashmap
+                .ifPresent(result -> mav.addObject("user", result));
+        mav.addObject("badges", badges);
+        mav.addObject("stickers", stickers);
+        return mav;
+    }
+//    @GetMapping("/userProfile")
+//    public ModelAndView getUserPage(ModelAndView mav) {
+//        return mav;
+//    }
+}
diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css
index 3d1973fac582203a1fbfa9cab0937ff213a45c51..08273bc1bba5a74c518361f71f7d88bb53774811 100644
--- a/src/main/resources/static/css/style.css
+++ b/src/main/resources/static/css/style.css
@@ -183,6 +183,7 @@ main .badgesBlock{
 }
 
 footer {
+    z-index: 99;
     bottom: 0%;
     left: 0%;
     position: fixed;
diff --git a/src/main/resources/static/css/userProfile.css b/src/main/resources/static/css/userProfile.css
new file mode 100644
index 0000000000000000000000000000000000000000..d59daa0689371b0adb2a204035b6a42d89dadab3
--- /dev/null
+++ b/src/main/resources/static/css/userProfile.css
@@ -0,0 +1,230 @@
+/* AUTHOR: Gabriel Copat*/
+
+/*FONTS, TYPOGRAPHY & BACKGROUNDS*/
+* {
+    margin: 0;
+    padding: 0;
+
+    & h1, & h2 {
+        letter-spacing: 0.25vw;
+        line-height: 1.3;
+        text-align: center;
+        color: white;
+        text-justify: inter-word;
+    }
+}
+@media only screen and (max-device-width: 500px) {
+    /*ADJUSTING FOR SMALLER SCREENS*/
+    * {
+        & h1, & h2 { text-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh 1svh;}
+        & p { line-height: 1.1; color: white;}
+    }
+}
+
+body {
+    background: linear-gradient(135deg, #9f74be, #3e126b);
+    height: 100svh;
+}
+main {
+    background: linear-gradient(to bottom, #1e1e1e 10%, darkgoldenrod 50%, #1e1e1e 90%);
+    border-radius: 1vw;
+    margin-inline: 5%;
+    /*margin-block: 5%;*/
+    width: auto;
+    padding-block: 2svh;
+    margin-top: 6em;
+    padding-inline: 1vw;
+    box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh max(1vw, 1em);
+}
+
+
+.userInfo {
+    display: flex;
+    flex-direction: column;
+    /*padding: min(2vw, 4em);*/
+    text-align: center;
+
+    & #userPicture {
+        width: min(30vw, 30em);
+        margin-inline: auto;
+        border-radius: 100%;
+        border: solid #a2a2a2 4px;
+        box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh max(1vw, 1em);
+    }
+
+    & h1 {
+        font-size: max(5vw, 2em);
+        margin: 1svh 25%;
+        color:white;
+        border-bottom: #36454F solid 2px;
+        border-radius: 5vw;
+        box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh 1vw -1vw;
+    }
+}
+#badgesBar::-webkit-scrollbar {
+    display: none;
+    -ms-scrollbar-darkshadow-color: transparent;
+}
+#badgesBar {
+    display: grid;
+    grid-template-areas:
+        "header"
+        "badges";
+    overflow-x: scroll;
+    overflow-y: hidden;
+    color: white;
+    padding-bottom: 2%;
+    @media only screen and (min-device-width: 501px) {
+        height: 24vw;
+    }
+    & h2 {
+        position: absolute;
+        grid-area: header;
+        margin-inline: 5vw;
+        padding-inline: 2vw;
+        margin-block: -1svh;
+        box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh 1vw -1vw;
+        border-bottom: #36454F solid 2px;
+        font-size: 4vw;
+        width: 7em;
+        height: 1.2em;
+
+    }
+    & #allBadgesContainer {
+        margin-top: 3svh;
+        grid-area: badges;
+        height: 10svh;
+        align-content: center;
+        display: flex;
+        @media only screen and (min-device-width: 501px) {
+            height: 20vw;
+            margin-top: 6vw;
+        }
+    }
+    & .badgeImg {
+        margin-inline: 3vw;
+        height: 8svh;
+        z-index: 50;
+        @media only screen and (min-device-width: 501px) {
+            height: 15vw;
+        }
+        transition: 0.3s ease-out 100ms;
+    }
+    & .badgeImg:hover {
+        /*box-shadow: 0 0 20px 10px #bbbb00;*/
+        transform: scale(1.5,1.5);
+
+    }
+}
+
+#stickersBox {
+    padding-top: 5%;
+    display: flex;
+    flex-direction: column;
+    /* border-bottom-left-radius: 2vw; */
+    /* border-bottom-right-radius: 2vw; */
+    /*background: linear-gradient(to bottom, darkgoldenrod, transparent 90%);*/
+    margin-top: -1%;
+    & h2 {
+        font-size: 4em;
+        text-align: center;
+        box-shadow: rgba(0, 0, 0, 0.7) 0 2vw 2vw -2vw;
+        border-bottom: #36454F solid 2px;
+        margin-block: 1svh;
+        margin-inline: 25%;
+    }
+    & .stickersContainer {
+        margin-block: 1svh;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-around;
+        width: 100%;
+
+        & .stickerImg {
+            width: 20vw;
+            margin-block: 1em;
+
+        }
+    }
+}
+.locked {
+    filter: grayscale(100%);
+}
+
+.dragonProgression {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    text-align: center;
+    height: 16svh;
+    box-sizing: content-box;
+    /*background: linear-gradient(to bottom, transparent -50%, darkgoldenrod 50%);*/
+    width: 100%;
+    /*padding-top: 1svh;*/
+
+    @media only screen and (min-device-width: 501px) {
+        height: 28vw;
+        margin-bottom: 0;
+        padding-bottom: 5svh;
+    }
+    & h1 {
+        font-size: 3em;
+        box-shadow: rgba(0, 0, 0, 0.7) 0 2vw 2vw -2vw;
+        border-bottom: #36454F solid 2px;
+        border-top: #36454F solid 2px;
+        margin-inline: 25%;
+        margin-bottom: 1%;
+    }
+    & .dragonContainer {
+        position: relative;
+        margin: auto;
+    }
+    & .dragonImg {
+        height: 10svh;
+        width: 16svh;
+        @media only screen and (min-device-width: 501px) {
+            height: 22vw;
+            width: 30vw;
+        }
+
+    }
+    & .dragonFill {
+        position: absolute;
+        overflow: hidden;
+        width: 40%;
+    }
+    & .dragonOut {
+        /*position: absolute;*/
+        overflow: hidden;
+    }
+}
+header {
+    z-index: 99;
+    top: 0.5svh;
+    left: 0;
+    position: fixed;
+    width: 100vw;
+    justify-content: center;
+    display: flex;
+}
+header .footerBar {
+    display: flex;
+    list-style: none;
+    border-radius: 1vw;
+    overflow: hidden;
+    justify-content: space-evenly;
+    background-color: rgba(0, 0, 0, 0.7);
+}
+header .footerButton {
+    padding: 1vw;
+    text-align: center;
+    /*flex: 1 1;*/
+    color:crimson;
+    background-color: rgba(31, 31, 31, 0.7);
+    font-size: 2.5em;
+    width: 15vw;
+}
+header .footerButton:hover {
+    background-color: #36454F;
+}
\ No newline at end of file
diff --git a/src/main/resources/static/images/rewards/badges/0.png b/src/main/resources/static/images/rewards/badges/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..57e379c719f5fe28ba827d7007be9637cfd9ff73
Binary files /dev/null and b/src/main/resources/static/images/rewards/badges/0.png differ
diff --git a/src/main/resources/static/images/rewards/dragonFilled.png b/src/main/resources/static/images/rewards/dragonFilled.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b0be9867d8b02500393ef2488dc8facf6c20711
Binary files /dev/null and b/src/main/resources/static/images/rewards/dragonFilled.png differ
diff --git a/src/main/resources/static/images/rewards/dragonOutline.png b/src/main/resources/static/images/rewards/dragonOutline.png
new file mode 100644
index 0000000000000000000000000000000000000000..12f6c621e392b57573717b0f4cb496a0b9e96b99
Binary files /dev/null and b/src/main/resources/static/images/rewards/dragonOutline.png differ
diff --git a/src/main/resources/static/images/rewards/stickers/0.png b/src/main/resources/static/images/rewards/stickers/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..54eb8acb855af1730b2ba00b947a957ac7dfddca
Binary files /dev/null and b/src/main/resources/static/images/rewards/stickers/0.png differ
diff --git a/src/main/resources/static/images/users/0.png b/src/main/resources/static/images/users/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..75a9de71d2fd7e9b4f8e5a0992d0edeabe50c888
Binary files /dev/null and b/src/main/resources/static/images/users/0.png differ
diff --git a/src/main/resources/static/scripts/gabScripts.js b/src/main/resources/static/scripts/gabScripts.js
deleted file mode 100644
index 3053fc2316552e2f8c588847aa67e1aaa44aed44..0000000000000000000000000000000000000000
--- a/src/main/resources/static/scripts/gabScripts.js
+++ /dev/null
@@ -1,16 +0,0 @@
-function selectTrail(string, element) {
- console.log('Clicked')
- let listEl = document.getElementsByClassName('liHeader')
- for (let i = 0; i < listEl.length; i++) {
-  listEl[i].classList.remove('selected')
- }
- document.getElementById(string).classList.add("selected")
-
-}
-
-function updateOutput() {
- $.post("test_ajax_frag").done(function (fragment) {
-  console.log(fragment);
-  $("#trailInfoBox").replaceWith(fragment);
- });
-}
\ No newline at end of file
diff --git a/src/main/resources/templates/rewards/userProfile.html b/src/main/resources/templates/rewards/userProfile.html
new file mode 100644
index 0000000000000000000000000000000000000000..bd502cfc61f804533f7195de53ef812187d3f0ec
--- /dev/null
+++ b/src/main/resources/templates/rewards/userProfile.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title th:text="'VZLA Profile Page of ' + ${user.getName()}"></title>
+    <link rel="stylesheet" th:href="@{/css/userProfile.css}">
+<!--    <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>Search</b></li>
+    </ul>
+</header>
+
+<main>
+    <!--PICTURE - DATA - BADGES -->
+    <div class="userInfo">
+        <img th:src="@{${user.getImgPath()}}"
+             th:alt="${user.getName()}"
+             id="userPicture"
+        >
+        <h1 th:text="${user.getName()}"></h1>
+        <!--TODO add some progression info here?-->
+    </div>
+    <section class="rewards"> <!--Reward lists, badges on top, stickers (larger) on the bottom-->
+        <article id="badgesBar">
+            <h2>Your Badges: </h2> <!--Shows first earned badges, followed by greyed out badges-->
+            <div id="allBadgesContainer"  class="centerFlex">
+                <img class="badgeImg"  th:each="badge : ${badges}" th:src="@{'..' + ${badge.getImgPath()}}"
+                     th:id="'img' + ${badge.getId()}" th:alt="${badge.getName()}" >
+            </div>
+        </article>
+        <article class="dragonProgression">
+            <h1>The Dragon Trail</h1>
+            <div class="dragonContainer">
+                <div class="dragonFill">
+                    <img th:src="@{/images/rewards/dragonFilled.png}"
+                         alt="Filled Dragon" id="FilledDragon" class="dragonImg">
+                </div>
+                <div class="dragonOut">
+                    <img th:src="@{/images/rewards/dragonOutline.png}"
+                         alt="Outline Dragon" id="OutlineDragon" class="dragonImg">
+                </div>
+            </div>
+            <h2>40%</h2>
+        </article>
+        <article id="stickersBox"> <!--Need a controller to show earned stickers -->
+            <h2> STICKERS! </h2>
+            <div class="stickersContainer">
+                <img class="stickerImg"  th:each="sticker : ${stickers}" th:src="@{'../' + ${sticker.getImgPath()}}"
+                     th:id="'img' + ${sticker.getId()}" th:alt="${sticker.getName()}" >
+            </div>
+        </article>
+    </section>
+
+
+</main>
+
+<footer>
+
+</footer>
+
+
+
+</body>
+</html>
+
+<!--TODO finished doing the tooltips, need to add some more changes to them for sure
+    TODO afterwards probably need to implement thymeleaf so it shows badges based on the list
+    TODO implement some placeholder pictures as well for the badges and for the stickers -->
\ No newline at end of file