diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/ExerciseSubmission.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/ExerciseSubmission.java
new file mode 100644
index 0000000..9ddc07b
--- /dev/null
+++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/ExerciseSubmission.java
@@ -0,0 +1,25 @@
+package nl.andrewlalis.gymboard_api.model;
+
+import jakarta.persistence.*;
+import org.hibernate.annotations.CreationTimestamp;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "gym_exercise_submission")
+public class ExerciseSubmission {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @CreationTimestamp
+ private LocalDateTime createdAt;
+
+ @Column(nullable = false, updatable = false, length = 63)
+ private String submitterName;
+
+ @ManyToOne(optional = false, fetch = FetchType.LAZY)
+ private Gym gym;
+
+
+}
diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java
new file mode 100644
index 0000000..80b7f8e
--- /dev/null
+++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java
@@ -0,0 +1,38 @@
+package nl.andrewlalis.gymboard_api.model;
+
+import jakarta.persistence.EmbeddedId;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import org.hibernate.annotations.CreationTimestamp;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "gym")
+public class Gym {
+ @EmbeddedId
+ private GymId id;
+
+ @CreationTimestamp
+ private LocalDateTime createdAt;
+
+ public GymId getId() {
+ return id;
+ }
+
+ public String getName() {
+ return id.getName();
+ }
+
+ public String getCityId() {
+ return id.getCityId();
+ }
+
+ public String getCountryId() {
+ return id.getCountryId();
+ }
+
+ public LocalDateTime getCreatedAt() {
+ return createdAt;
+ }
+}
diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java
new file mode 100644
index 0000000..ccf73e8
--- /dev/null
+++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java
@@ -0,0 +1,56 @@
+package nl.andrewlalis.gymboard_api.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Embeddable;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Compound primary key used to identify a single {@link Gym}.
+ */
+@Embeddable
+public class GymId implements Serializable {
+ @Column(nullable = false, length = 127)
+ private String name;
+ @Column(nullable = false, length = 127)
+ private String cityId;
+ @Column(nullable = false, length = 2)
+ private String countryId;
+
+ public GymId() {}
+
+ public GymId(String name, String cityId, String countryId) {
+ this.name = name;
+ this.cityId = cityId;
+ this.countryId = countryId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getCityId() {
+ return cityId;
+ }
+
+ public String getCountryId() {
+ return countryId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o instanceof GymId gymId) {
+ return getName().equals(gymId.getName()) &&
+ getCityId().equals(gymId.getCityId()) &&
+ getCountryId().equals(gymId.getCountryId());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getName(), getCityId(), getCountryId());
+ }
+}
diff --git a/gymboard-api/src/main/resources/application.properties b/gymboard-api/src/main/resources/application.properties
index 8b13789..91d36ec 100644
--- a/gymboard-api/src/main/resources/application.properties
+++ b/gymboard-api/src/main/resources/application.properties
@@ -1 +1 @@
-
+spring.jpa.open-in-view=false
diff --git a/gymboard-app/src/layouts/MainLayout.vue b/gymboard-app/src/layouts/MainLayout.vue
index ed15bd4..9117847 100644
--- a/gymboard-app/src/layouts/MainLayout.vue
+++ b/gymboard-app/src/layouts/MainLayout.vue
@@ -28,8 +28,8 @@
>
Pages
- First Page
- Second Page
+ Gyms
+ Global Leaderboard
diff --git a/gymboard-app/src/pages/GymPage.vue b/gymboard-app/src/pages/GymPage.vue
index cf64a36..b838230 100644
--- a/gymboard-app/src/pages/GymPage.vue
+++ b/gymboard-app/src/pages/GymPage.vue
@@ -1,16 +1,17 @@
Hello Gym Page
+
+ Leaderboard total
+
-
\ No newline at end of file
diff --git a/gymboard-app/src/pages/IndexPage.vue b/gymboard-app/src/pages/IndexPage.vue
index 25462dc..9189fbe 100644
--- a/gymboard-app/src/pages/IndexPage.vue
+++ b/gymboard-app/src/pages/IndexPage.vue
@@ -1,7 +1,10 @@
Index
- Test
+ Test
+
+ Search bar for gyms.
+
diff --git a/gymboard-app/src/router/routes.ts b/gymboard-app/src/router/routes.ts
index 2c26d3c..cb445ff 100644
--- a/gymboard-app/src/router/routes.ts
+++ b/gymboard-app/src/router/routes.ts
@@ -13,7 +13,7 @@ const routes: RouteRecordRaw[] = [
component: IndexPage
},
{
- path: 'gyms/:id',
+ path: 'g/:countryId/:cityId/:gymName',
component: GymPage
}
],