Added improved submission model.
This commit is contained in:
parent
184491b9ea
commit
080c44c467
|
@ -6,6 +6,8 @@ import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
|||
import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.service.GymService;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -37,8 +39,9 @@ public class GymController {
|
|||
@PostMapping(path = "/submissions")
|
||||
public ExerciseSubmissionResponse createSubmission(
|
||||
@PathVariable String compoundId,
|
||||
@AuthenticationPrincipal User user,
|
||||
@RequestBody ExerciseSubmissionPayload payload
|
||||
) {
|
||||
return submissionService.createSubmission(CompoundGymId.parse(compoundId), payload);
|
||||
return submissionService.createSubmission(CompoundGymId.parse(compoundId), user.getId(), payload);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
||||
|
||||
public record ExerciseSubmissionPayload(
|
||||
String name,
|
||||
String exerciseShortName,
|
||||
float weight,
|
||||
String weightUnit,
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
||||
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse;
|
||||
import nl.andrewlalis.gymboard_api.util.StandardDateFormatter;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public record ExerciseSubmissionResponse(
|
||||
String id,
|
||||
String createdAt,
|
||||
GymSimpleResponse gym,
|
||||
ExerciseResponse exercise,
|
||||
UserResponse user,
|
||||
String performedAt,
|
||||
String videoFileId,
|
||||
String submitterName,
|
||||
double rawWeight,
|
||||
String weightUnit,
|
||||
double metricWeight,
|
||||
|
@ -23,8 +23,9 @@ public record ExerciseSubmissionResponse(
|
|||
StandardDateFormatter.format(submission.getCreatedAt()),
|
||||
new GymSimpleResponse(submission.getGym()),
|
||||
new ExerciseResponse(submission.getExercise()),
|
||||
new UserResponse(submission.getUser()),
|
||||
StandardDateFormatter.format(submission.getPerformedAt()),
|
||||
submission.getVideoFileId(),
|
||||
submission.getSubmitterName(),
|
||||
submission.getRawWeight().doubleValue(),
|
||||
submission.getWeightUnit().name(),
|
||||
submission.getMetricWeight().doubleValue(),
|
||||
|
|
|
@ -3,9 +3,11 @@ package nl.andrewlalis.gymboard_api.domains.api.model.exercise;
|
|||
import jakarta.persistence.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
|
@ -24,6 +26,12 @@ public class ExerciseSubmission {
|
|||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private Exercise exercise;
|
||||
|
||||
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||
private User user;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime performedAt;
|
||||
|
||||
/**
|
||||
* The id of the video file that was submitted for this submission. It lives
|
||||
* on the <em>gymboard-cdn</em> service as a stored file, which can be
|
||||
|
@ -32,9 +40,6 @@ public class ExerciseSubmission {
|
|||
@Column(nullable = false, updatable = false, length = 26)
|
||||
private String videoFileId;
|
||||
|
||||
@Column(nullable = false, updatable = false, length = 63)
|
||||
private String submitterName;
|
||||
|
||||
@Column(nullable = false, precision = 7, scale = 2)
|
||||
private BigDecimal rawWeight;
|
||||
|
||||
|
@ -50,12 +55,13 @@ public class ExerciseSubmission {
|
|||
|
||||
public ExerciseSubmission() {}
|
||||
|
||||
public ExerciseSubmission(String id, Gym gym, Exercise exercise, String videoFileId, String submitterName, BigDecimal rawWeight, WeightUnit unit, BigDecimal metricWeight, int reps) {
|
||||
public ExerciseSubmission(String id, Gym gym, Exercise exercise, User user, LocalDateTime performedAt, String videoFileId, BigDecimal rawWeight, WeightUnit unit, BigDecimal metricWeight, int reps) {
|
||||
this.id = id;
|
||||
this.gym = gym;
|
||||
this.exercise = exercise;
|
||||
this.videoFileId = videoFileId;
|
||||
this.submitterName = submitterName;
|
||||
this.user = user;
|
||||
this.performedAt = performedAt;
|
||||
this.rawWeight = rawWeight;
|
||||
this.weightUnit = unit;
|
||||
this.metricWeight = metricWeight;
|
||||
|
@ -82,8 +88,12 @@ public class ExerciseSubmission {
|
|||
return videoFileId;
|
||||
}
|
||||
|
||||
public String getSubmitterName() {
|
||||
return submitterName;
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public LocalDateTime getPerformedAt() {
|
||||
return performedAt;
|
||||
}
|
||||
|
||||
public BigDecimal getRawWeight() {
|
||||
|
|
|
@ -32,7 +32,13 @@ public class CdnClient {
|
|||
.GET()
|
||||
.build();
|
||||
HttpResponse<String> response = httpClient.send(req, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() == 200) {
|
||||
return objectMapper.readValue(response.body(), responseType);
|
||||
} else if (response.statusCode() == 404) {
|
||||
return null;
|
||||
} else {
|
||||
throw new IOException("Request failed with code " + response.statusCode());
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T postFile(String urlPath, Path filePath, String contentType, Class<T> responseType) throws IOException, InterruptedException {
|
||||
|
|
|
@ -6,6 +6,14 @@ public record UploadsClient(CdnClient client) {
|
|||
public record FileUploadResponse(String id) {}
|
||||
public record VideoProcessingTaskStatusResponse(String status) {}
|
||||
|
||||
public record FileMetadataResponse(
|
||||
String filename,
|
||||
String mimeType,
|
||||
long size,
|
||||
String uploadedAt,
|
||||
boolean availableForDownload
|
||||
) {}
|
||||
|
||||
public FileUploadResponse uploadVideo(Path filePath, String contentType) throws Exception {
|
||||
return client.postFile("/uploads/video", filePath, contentType, FileUploadResponse.class);
|
||||
}
|
||||
|
@ -13,4 +21,8 @@ public record UploadsClient(CdnClient client) {
|
|||
public VideoProcessingTaskStatusResponse getVideoProcessingStatus(String id) throws Exception {
|
||||
return client.get("/uploads/video/" + id + "/status", VideoProcessingTaskStatusResponse.class);
|
||||
}
|
||||
|
||||
public FileMetadataResponse getFileMetadata(String id) throws Exception {
|
||||
return client.get("/files/" + id + "/metadata", FileMetadataResponse.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
|||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -19,6 +21,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Service which handles the rather mundane tasks associated with exercise
|
||||
|
@ -29,15 +33,17 @@ public class ExerciseSubmissionService {
|
|||
private static final Logger log = LoggerFactory.getLogger(ExerciseSubmissionService.class);
|
||||
|
||||
private final GymRepository gymRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final ExerciseRepository exerciseRepository;
|
||||
private final ExerciseSubmissionRepository exerciseSubmissionRepository;
|
||||
private final ULID ulid;
|
||||
|
||||
public ExerciseSubmissionService(GymRepository gymRepository,
|
||||
ExerciseRepository exerciseRepository,
|
||||
UserRepository userRepository, ExerciseRepository exerciseRepository,
|
||||
ExerciseSubmissionRepository exerciseSubmissionRepository,
|
||||
ULID ulid) {
|
||||
this.gymRepository = gymRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.exerciseRepository = exerciseRepository;
|
||||
this.exerciseSubmissionRepository = exerciseSubmissionRepository;
|
||||
this.ulid = ulid;
|
||||
|
@ -53,11 +59,14 @@ public class ExerciseSubmissionService {
|
|||
/**
|
||||
* Handles the creation of a new exercise submission.
|
||||
* @param id The gym id.
|
||||
* @param userId The user's id.
|
||||
* @param payload The submission data.
|
||||
* @return The saved submission.
|
||||
*/
|
||||
@Transactional
|
||||
public ExerciseSubmissionResponse createSubmission(CompoundGymId id, ExerciseSubmissionPayload payload) {
|
||||
public ExerciseSubmissionResponse createSubmission(CompoundGymId id, String userId, ExerciseSubmissionPayload payload) {
|
||||
User user = userRepository.findById(userId)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.FORBIDDEN));
|
||||
Gym gym = gymRepository.findByCompoundId(id)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
Exercise exercise = exerciseRepository.findById(payload.exerciseShortName())
|
||||
|
@ -76,8 +85,9 @@ public class ExerciseSubmissionService {
|
|||
ulid.nextULID(),
|
||||
gym,
|
||||
exercise,
|
||||
user,
|
||||
LocalDateTime.now(),
|
||||
payload.videoFileId(),
|
||||
payload.name(),
|
||||
rawWeight,
|
||||
weightUnit,
|
||||
metricWeight,
|
||||
|
|
|
@ -1,61 +1,124 @@
|
|||
package nl.andrewlalis.gymboard_api.util.sample_data;
|
||||
|
||||
import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionPayload;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.CdnClient;
|
||||
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
||||
import nl.andrewlalis.gymboard_api.util.CsvUtil;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Profile("development")
|
||||
public class SampleSubmissionGenerator implements SampleDataGenerator {
|
||||
private final GymRepository gymRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final ExerciseRepository exerciseRepository;
|
||||
private final ExerciseSubmissionService submissionService;
|
||||
private final ExerciseSubmissionRepository submissionRepository;
|
||||
private final ULID ulid;
|
||||
|
||||
@Value("${app.cdn-origin}")
|
||||
private String cdnOrigin;
|
||||
|
||||
public SampleSubmissionGenerator(ExerciseRepository exerciseRepository, ExerciseSubmissionService submissionService) {
|
||||
public SampleSubmissionGenerator(GymRepository gymRepository, UserRepository userRepository, ExerciseRepository exerciseRepository, ExerciseSubmissionService submissionService, ExerciseSubmissionRepository submissionRepository, ULID ulid) {
|
||||
this.gymRepository = gymRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.exerciseRepository = exerciseRepository;
|
||||
this.submissionService = submissionService;
|
||||
this.submissionRepository = submissionRepository;
|
||||
this.ulid = ulid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate() throws Exception {
|
||||
final CdnClient cdnClient = new CdnClient(cdnOrigin);
|
||||
CsvUtil.load(Path.of("sample_data", "submissions.csv"), r -> {
|
||||
var exercise = exerciseRepository.findById(r.get("exercise-short-name")).orElseThrow();
|
||||
BigDecimal weight = new BigDecimal(r.get("raw-weight"));
|
||||
WeightUnit unit = WeightUnit.parse(r.get("weight-unit"));
|
||||
int reps = Integer.parseInt(r.get("reps"));
|
||||
String name = r.get("submitter-name");
|
||||
CompoundGymId gymId = CompoundGymId.parse(r.get("gym-id"));
|
||||
String videoFilename = r.get("video-filename");
|
||||
|
||||
var video = cdnClient.uploads.uploadVideo(Path.of("sample_data", videoFilename), "video/mp4");
|
||||
submissionService.createSubmission(gymId, new ExerciseSubmissionPayload(
|
||||
name,
|
||||
exercise.getShortName(),
|
||||
weight.floatValue(),
|
||||
unit.name(),
|
||||
reps,
|
||||
video.id()
|
||||
List<String> videoIds = new ArrayList<>();
|
||||
var video1 = cdnClient.uploads.uploadVideo(Path.of("sample_data", "sample_video_curl.mp4"), "video/mp4");
|
||||
var video2 = cdnClient.uploads.uploadVideo(Path.of("sample_data", "sample_video_ohp.mp4"), "video/mp4");
|
||||
videoIds.add(video1.id());
|
||||
videoIds.add(video2.id());
|
||||
|
||||
List<Gym> gyms = gymRepository.findAll();
|
||||
List<User> users = userRepository.findAll();
|
||||
List<Exercise> exercises = exerciseRepository.findAll();
|
||||
|
||||
final int count = 10000;
|
||||
final LocalDateTime earliestSubmission = LocalDateTime.now().minusYears(3);
|
||||
final LocalDateTime latestSubmission = LocalDateTime.now();
|
||||
|
||||
Random random = new Random(1);
|
||||
for (int i = 0; i < count; i++) {
|
||||
generateRandomSubmission(
|
||||
gyms,
|
||||
users,
|
||||
exercises,
|
||||
videoIds,
|
||||
earliestSubmission,
|
||||
latestSubmission,
|
||||
random
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateRandomSubmission(
|
||||
List<Gym> gyms,
|
||||
List<User> users,
|
||||
List<Exercise> exercises,
|
||||
List<String> videoIds,
|
||||
LocalDateTime earliestSubmission,
|
||||
LocalDateTime latestSubmission,
|
||||
Random random
|
||||
) {
|
||||
LocalDateTime time = randomTime(earliestSubmission, latestSubmission, random);
|
||||
BigDecimal metricWeight = new BigDecimal(random.nextInt(20, 250));
|
||||
BigDecimal rawWeight = new BigDecimal(metricWeight.toString());
|
||||
WeightUnit weightUnit = WeightUnit.KILOGRAMS;
|
||||
if (random.nextDouble() > 0.5) {
|
||||
weightUnit = WeightUnit.POUNDS;
|
||||
rawWeight = metricWeight.multiply(new BigDecimal("2.2046226218"));
|
||||
}
|
||||
|
||||
submissionRepository.save(new ExerciseSubmission(
|
||||
ulid.nextULID(),
|
||||
randomChoice(gyms, random),
|
||||
randomChoice(exercises, random),
|
||||
randomChoice(users, random),
|
||||
time,
|
||||
randomChoice(videoIds, random),
|
||||
rawWeight,
|
||||
weightUnit,
|
||||
metricWeight,
|
||||
random.nextInt(13)
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends SampleDataGenerator>> dependencies() {
|
||||
return Set.of(SampleExerciseGenerator.class, SampleUserGenerator.class);
|
||||
return Set.of(SampleExerciseGenerator.class, SampleUserGenerator.class, SampleGymGenerator.class);
|
||||
}
|
||||
|
||||
private <T> T randomChoice(List<T> items, Random rand) {
|
||||
return items.get(rand.nextInt(items.size()));
|
||||
}
|
||||
|
||||
private LocalDateTime randomTime(LocalDateTime start, LocalDateTime end, Random rand) {
|
||||
Duration dur = Duration.between(start, end);
|
||||
return start.plusSeconds(rand.nextLong(dur.toSeconds() + 1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Exercise } from 'src/api/main/exercises';
|
|||
import { api } from 'src/api/main/index';
|
||||
import { getGymCompoundId, GymRoutable } from 'src/router/gym-routing';
|
||||
import { DateTime } from 'luxon';
|
||||
import {User} from "src/api/main/auth";
|
||||
|
||||
/**
|
||||
* The data that's sent when creating a submission.
|
||||
|
@ -33,8 +34,9 @@ export interface ExerciseSubmission {
|
|||
createdAt: DateTime;
|
||||
gym: SimpleGym;
|
||||
exercise: Exercise;
|
||||
user: User;
|
||||
performedAt: DateTime;
|
||||
videoFileId: string;
|
||||
submitterName: string;
|
||||
rawWeight: number;
|
||||
weightUnit: WeightUnit;
|
||||
metricWeight: number;
|
||||
|
@ -43,7 +45,7 @@ export interface ExerciseSubmission {
|
|||
|
||||
export function parseSubmission(data: any): ExerciseSubmission {
|
||||
data.createdAt = DateTime.fromISO(data.createdAt);
|
||||
console.log(data);
|
||||
data.performedAt = DateTime.fromISO(data.performedAt);
|
||||
return data as ExerciseSubmission;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { GymSearchResult } from 'src/api/search/models';
|
||||
import {GymSearchResult, UserSearchResult} from 'src/api/search/models';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: 'http://localhost:8081',
|
||||
|
@ -15,3 +15,14 @@ export async function searchGyms(
|
|||
const response = await api.get('/search/gyms?q=' + query);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for users using the given query, and eventually returns results.
|
||||
* Note that only users whose accounts are not private will be included in
|
||||
* search results.
|
||||
* @param query The query to use.
|
||||
*/
|
||||
export async function searchUsers(query: string): Promise<Array<UserSearchResult>> {
|
||||
const response = await api.get('/search/users?q=' + query);
|
||||
return response.data;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
icon="person"
|
||||
>
|
||||
<q-list>
|
||||
<q-item clickable v-close-popup :to="'/users/' + authStore.user?.id">
|
||||
<q-item-section>
|
||||
<q-item-label>{{ $t('accountMenuItem.myAccount') }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="api.auth.logout(authStore)">
|
||||
<q-item-section>
|
||||
<q-item-label>{{ $t('accountMenuItem.logOut') }}</q-item-label>
|
||||
|
|
|
@ -41,6 +41,7 @@ export default {
|
|||
},
|
||||
accountMenuItem: {
|
||||
logIn: 'Login',
|
||||
myAccount: 'My Account',
|
||||
logOut: 'Log out',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<q-page>
|
||||
<StandardCenteredPage v-if="user">
|
||||
<h3>{{ user?.name }}</h3>
|
||||
<p>{{ user?.email }}</p>
|
||||
<p v-if="isOwnUser">This is your account!</p>
|
||||
</StandardCenteredPage>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||
import {onMounted, ref, Ref} from 'vue';
|
||||
import {User} from 'src/api/main/auth';
|
||||
import api from 'src/api/main';
|
||||
import {useRoute} from 'vue-router';
|
||||
import {useAuthStore} from 'stores/auth-store';
|
||||
|
||||
const route = useRoute();
|
||||
const authStore = useAuthStore();
|
||||
|
||||
/**
|
||||
* The user that this page displays information about.
|
||||
*/
|
||||
const user: Ref<User | undefined> = ref();
|
||||
|
||||
/**
|
||||
* Flag that tells whether this user is the currently authenticated user.
|
||||
*/
|
||||
const isOwnUser = ref(false);
|
||||
|
||||
onMounted(async () => {
|
||||
const userId = route.params.userId as string;
|
||||
user.value = await api.auth.fetchUser(userId, authStore);
|
||||
isOwnUser.value = user.value.id === authStore.user?.id;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -12,6 +12,7 @@ import RegisterPage from 'pages/auth/RegisterPage.vue';
|
|||
import RegistrationSuccessPage from 'pages/auth/RegistrationSuccessPage.vue';
|
||||
import ActivationPage from 'pages/auth/ActivationPage.vue';
|
||||
import SubmissionPage from 'pages/SubmissionPage.vue';
|
||||
import UserPage from 'pages/UserPage.vue';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
// Auth-related pages, which live outside the main layout.
|
||||
|
@ -27,6 +28,7 @@ const routes: RouteRecordRaw[] = [
|
|||
children: [
|
||||
{ path: '', component: IndexPage },
|
||||
{ path: 'testing', component: TestingPage },
|
||||
{ path: 'users/:userId', component: UserPage },
|
||||
{
|
||||
path: 'gyms/:countryCode/:cityShortName/:gymShortName',
|
||||
component: GymPage,
|
||||
|
|
Loading…
Reference in New Issue