Added report and voting entities, and api status controller.
This commit is contained in:
parent
080c44c467
commit
aa843227d2
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.andrewlalis.gymboard_api;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class StatusController {
|
||||||
|
@GetMapping(path = "/status")
|
||||||
|
public ResponseEntity<?> getServiceStatus() {
|
||||||
|
return ResponseEntity.ok(Map.of("online", true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,7 +47,10 @@ public class SecurityConfig {
|
||||||
"/leaderboards",
|
"/leaderboards",
|
||||||
"/gyms/**",
|
"/gyms/**",
|
||||||
"/submissions/**",
|
"/submissions/**",
|
||||||
"/auth/reset-password"
|
"/auth/reset-password",
|
||||||
|
"/auth/users/*",
|
||||||
|
"/auth/users/*/followers",
|
||||||
|
"/auth/users/*/following"
|
||||||
).permitAll()
|
).permitAll()
|
||||||
.requestMatchers(// Allow the following POST endpoints to be public.
|
.requestMatchers(// Allow the following POST endpoints to be public.
|
||||||
HttpMethod.POST,
|
HttpMethod.POST,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
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.dto.SubmissionPayload;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse;
|
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.GymService;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
||||||
|
@ -32,15 +32,15 @@ public class GymController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/recent-submissions")
|
@GetMapping(path = "/recent-submissions")
|
||||||
public List<ExerciseSubmissionResponse> getRecentSubmissions(@PathVariable String compoundId) {
|
public List<SubmissionResponse> getRecentSubmissions(@PathVariable String compoundId) {
|
||||||
return gymService.getRecentSubmissions(CompoundGymId.parse(compoundId));
|
return gymService.getRecentSubmissions(CompoundGymId.parse(compoundId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(path = "/submissions")
|
@PostMapping(path = "/submissions")
|
||||||
public ExerciseSubmissionResponse createSubmission(
|
public SubmissionResponse createSubmission(
|
||||||
@PathVariable String compoundId,
|
@PathVariable String compoundId,
|
||||||
@AuthenticationPrincipal User user,
|
@AuthenticationPrincipal User user,
|
||||||
@RequestBody ExerciseSubmissionPayload payload
|
@RequestBody SubmissionPayload payload
|
||||||
) {
|
) {
|
||||||
return submissionService.createSubmission(CompoundGymId.parse(compoundId), user.getId(), payload);
|
return submissionService.createSubmission(CompoundGymId.parse(compoundId), user.getId(), payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.service.LeaderboardService;
|
import nl.andrewlalis.gymboard_api.domains.api.service.LeaderboardService;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
@ -21,7 +21,7 @@ public class LeaderboardController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Page<ExerciseSubmissionResponse> getLeaderboard(
|
public Page<SubmissionResponse> getLeaderboard(
|
||||||
@RequestParam(name = "exercise") Optional<String> exerciseShortName,
|
@RequestParam(name = "exercise") Optional<String> exerciseShortName,
|
||||||
@RequestParam(name = "gyms") Optional<String> gymCompoundIdsString,
|
@RequestParam(name = "gyms") Optional<String> gymCompoundIdsString,
|
||||||
@RequestParam(name = "t") Optional<String> timeframe,
|
@RequestParam(name = "t") Optional<String> timeframe,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
package nl.andrewlalis.gymboard_api.domains.api.controller;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
@ -17,7 +17,7 @@ public class SubmissionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/{submissionId}")
|
@GetMapping(path = "/{submissionId}")
|
||||||
public ExerciseSubmissionResponse getSubmission(@PathVariable String submissionId) {
|
public SubmissionResponse getSubmission(@PathVariable String submissionId) {
|
||||||
return submissionService.getSubmission(submissionId);
|
return submissionService.getSubmission(submissionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.dao.exercise;
|
package nl.andrewlalis.gymboard_api.domains.api.dao;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.dao.exercise;
|
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface ExerciseSubmissionRepository extends JpaRepository<ExerciseSubmission, String>, JpaSpecificationExecutor<ExerciseSubmission> {
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.andrewlalis.gymboard_api.domains.api.dao.submission;
|
||||||
|
|
||||||
|
import nl.andrewlalis.gymboard_api.domains.api.model.submission.Submission;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface SubmissionRepository extends JpaRepository<Submission, String>, JpaSpecificationExecutor<Submission> {
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
|
|
||||||
public record ExerciseResponse(
|
public record ExerciseResponse(
|
||||||
String shortName,
|
String shortName,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
||||||
|
|
||||||
public record ExerciseSubmissionPayload(
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public record SubmissionPayload(
|
||||||
String exerciseShortName,
|
String exerciseShortName,
|
||||||
|
LocalDateTime performedAt,
|
||||||
float weight,
|
float weight,
|
||||||
String weightUnit,
|
String weightUnit,
|
||||||
int reps,
|
int reps,
|
|
@ -1,10 +1,10 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
package nl.andrewlalis.gymboard_api.domains.api.dto;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
import nl.andrewlalis.gymboard_api.domains.api.model.submission.Submission;
|
||||||
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse;
|
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse;
|
||||||
import nl.andrewlalis.gymboard_api.util.StandardDateFormatter;
|
import nl.andrewlalis.gymboard_api.util.StandardDateFormatter;
|
||||||
|
|
||||||
public record ExerciseSubmissionResponse(
|
public record SubmissionResponse(
|
||||||
String id,
|
String id,
|
||||||
String createdAt,
|
String createdAt,
|
||||||
GymSimpleResponse gym,
|
GymSimpleResponse gym,
|
||||||
|
@ -17,7 +17,7 @@ public record ExerciseSubmissionResponse(
|
||||||
double metricWeight,
|
double metricWeight,
|
||||||
int reps
|
int reps
|
||||||
) {
|
) {
|
||||||
public ExerciseSubmissionResponse(ExerciseSubmission submission) {
|
public SubmissionResponse(Submission submission) {
|
||||||
this(
|
this(
|
||||||
submission.getId(),
|
submission.getId(),
|
||||||
StandardDateFormatter.format(submission.getCreatedAt()),
|
StandardDateFormatter.format(submission.getCreatedAt()),
|
|
@ -1,4 +1,4 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.model.exercise;
|
package nl.andrewlalis.gymboard_api.domains.api.model;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
|
@ -1,18 +1,18 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.model.exercise;
|
package nl.andrewlalis.gymboard_api.domains.api.model.submission;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
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.WeightUnit;
|
||||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||||
import org.hibernate.annotations.CreationTimestamp;
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "exercise_submission")
|
@Table(name = "submission")
|
||||||
public class ExerciseSubmission {
|
public class Submission {
|
||||||
@Id
|
@Id
|
||||||
@Column(nullable = false, updatable = false, length = 26)
|
@Column(nullable = false, updatable = false, length = 26)
|
||||||
private String id;
|
private String id;
|
||||||
|
@ -53,9 +53,9 @@ public class ExerciseSubmission {
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private int reps;
|
private int reps;
|
||||||
|
|
||||||
public ExerciseSubmission() {}
|
public Submission() {}
|
||||||
|
|
||||||
public ExerciseSubmission(String id, Gym gym, Exercise exercise, User user, LocalDateTime performedAt, String videoFileId, BigDecimal rawWeight, WeightUnit unit, BigDecimal metricWeight, int reps) {
|
public Submission(String id, Gym gym, Exercise exercise, User user, LocalDateTime performedAt, String videoFileId, BigDecimal rawWeight, WeightUnit unit, BigDecimal metricWeight, int reps) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.gym = gym;
|
this.gym = gym;
|
||||||
this.exercise = exercise;
|
this.exercise = exercise;
|
|
@ -0,0 +1,63 @@
|
||||||
|
package nl.andrewlalis.gymboard_api.domains.api.model.submission;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "submission_report")
|
||||||
|
public class SubmissionReport {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@CreationTimestamp
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||||
|
private Submission submission;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Column(length = 1024)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public SubmissionReport() {}
|
||||||
|
|
||||||
|
public SubmissionReport(Submission submission, User user, String reason, String description) {
|
||||||
|
this.submission = submission;
|
||||||
|
this.user = user;
|
||||||
|
this.reason = reason;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Submission getSubmission() {
|
||||||
|
return submission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package nl.andrewlalis.gymboard_api.domains.api.model.submission;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(
|
||||||
|
name = "submission_vote",
|
||||||
|
uniqueConstraints = @UniqueConstraint(columnNames = {"submission_id", "user_id"})
|
||||||
|
)
|
||||||
|
public class SubmissionVote {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||||
|
private Submission submission;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public SubmissionVote() {}
|
||||||
|
|
||||||
|
public SubmissionVote(Submission submission, User user) {
|
||||||
|
this.submission = submission;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Submission getSubmission() {
|
||||||
|
return submission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.service;
|
package nl.andrewlalis.gymboard_api.domains.api.service;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.ExerciseRepository;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.service;
|
package nl.andrewlalis.gymboard_api.domains.api.service;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.submission.SubmissionRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||||
import nl.andrewlalis.gymboard_api.util.PredicateBuilder;
|
import nl.andrewlalis.gymboard_api.util.PredicateBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -22,9 +22,9 @@ public class GymService {
|
||||||
private static final Logger log = LoggerFactory.getLogger(GymService.class);
|
private static final Logger log = LoggerFactory.getLogger(GymService.class);
|
||||||
|
|
||||||
private final GymRepository gymRepository;
|
private final GymRepository gymRepository;
|
||||||
private final ExerciseSubmissionRepository submissionRepository;
|
private final SubmissionRepository submissionRepository;
|
||||||
|
|
||||||
public GymService(GymRepository gymRepository, ExerciseSubmissionRepository submissionRepository) {
|
public GymService(GymRepository gymRepository, SubmissionRepository submissionRepository) {
|
||||||
this.gymRepository = gymRepository;
|
this.gymRepository = gymRepository;
|
||||||
this.submissionRepository = submissionRepository;
|
this.submissionRepository = submissionRepository;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class GymService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<ExerciseSubmissionResponse> getRecentSubmissions(CompoundGymId id) {
|
public List<SubmissionResponse> getRecentSubmissions(CompoundGymId id) {
|
||||||
Gym gym = gymRepository.findByCompoundId(id)
|
Gym gym = gymRepository.findByCompoundId(id)
|
||||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
return submissionRepository.findAll((root, query, criteriaBuilder) -> {
|
return submissionRepository.findAll((root, query, criteriaBuilder) -> {
|
||||||
|
@ -49,7 +49,7 @@ public class GymService {
|
||||||
.with(criteriaBuilder.equal(root.get("gym"), gym))
|
.with(criteriaBuilder.equal(root.get("gym"), gym))
|
||||||
.build();
|
.build();
|
||||||
}, PageRequest.of(0, 10))
|
}, PageRequest.of(0, 10))
|
||||||
.map(ExerciseSubmissionResponse::new)
|
.map(SubmissionResponse::new)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.service;
|
package nl.andrewlalis.gymboard_api.domains.api.service;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository;
|
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.dao.ExerciseRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.submission.SubmissionRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.LeaderboardTimeframe;
|
import nl.andrewlalis.gymboard_api.domains.api.model.LeaderboardTimeframe;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import nl.andrewlalis.gymboard_api.util.PredicateBuilder;
|
import nl.andrewlalis.gymboard_api.util.PredicateBuilder;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
@ -27,18 +27,18 @@ import java.util.Optional;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class LeaderboardService {
|
public class LeaderboardService {
|
||||||
private final ExerciseSubmissionRepository submissionRepository;
|
private final SubmissionRepository submissionRepository;
|
||||||
private final ExerciseRepository exerciseRepository;
|
private final ExerciseRepository exerciseRepository;
|
||||||
private final GymRepository gymRepository;
|
private final GymRepository gymRepository;
|
||||||
|
|
||||||
public LeaderboardService(ExerciseSubmissionRepository submissionRepository, ExerciseRepository exerciseRepository, GymRepository gymRepository) {
|
public LeaderboardService(SubmissionRepository submissionRepository, ExerciseRepository exerciseRepository, GymRepository gymRepository) {
|
||||||
this.submissionRepository = submissionRepository;
|
this.submissionRepository = submissionRepository;
|
||||||
this.exerciseRepository = exerciseRepository;
|
this.exerciseRepository = exerciseRepository;
|
||||||
this.gymRepository = gymRepository;
|
this.gymRepository = gymRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Page<ExerciseSubmissionResponse> getTopSubmissions(
|
public Page<SubmissionResponse> getTopSubmissions(
|
||||||
Optional<String> exerciseShortName,
|
Optional<String> exerciseShortName,
|
||||||
Optional<String> gymCompoundIdsString,
|
Optional<String> gymCompoundIdsString,
|
||||||
Optional<String> optionalTimeframe,
|
Optional<String> optionalTimeframe,
|
||||||
|
@ -68,7 +68,7 @@ public class LeaderboardService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return pb.build();
|
return pb.build();
|
||||||
}, pageable).map(ExerciseSubmissionResponse::new);
|
}, pageable).map(SubmissionResponse::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Gym> parseGymCompoundIdsString(String s) {
|
private List<Gym> parseGymCompoundIdsString(String s) {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package nl.andrewlalis.gymboard_api.domains.api.service.submission;
|
package nl.andrewlalis.gymboard_api.domains.api.service.submission;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository;
|
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.dao.ExerciseRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.submission.SubmissionRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId;
|
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.dto.SubmissionPayload;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse;
|
import nl.andrewlalis.gymboard_api.domains.api.dto.SubmissionResponse;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
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.WeightUnit;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
import nl.andrewlalis.gymboard_api.domains.api.model.submission.Submission;
|
||||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||||
|
@ -21,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,25 +34,25 @@ public class ExerciseSubmissionService {
|
||||||
private final GymRepository gymRepository;
|
private final GymRepository gymRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final ExerciseRepository exerciseRepository;
|
private final ExerciseRepository exerciseRepository;
|
||||||
private final ExerciseSubmissionRepository exerciseSubmissionRepository;
|
private final SubmissionRepository submissionRepository;
|
||||||
private final ULID ulid;
|
private final ULID ulid;
|
||||||
|
|
||||||
public ExerciseSubmissionService(GymRepository gymRepository,
|
public ExerciseSubmissionService(GymRepository gymRepository,
|
||||||
UserRepository userRepository, ExerciseRepository exerciseRepository,
|
UserRepository userRepository, ExerciseRepository exerciseRepository,
|
||||||
ExerciseSubmissionRepository exerciseSubmissionRepository,
|
SubmissionRepository submissionRepository,
|
||||||
ULID ulid) {
|
ULID ulid) {
|
||||||
this.gymRepository = gymRepository;
|
this.gymRepository = gymRepository;
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
this.exerciseRepository = exerciseRepository;
|
this.exerciseRepository = exerciseRepository;
|
||||||
this.exerciseSubmissionRepository = exerciseSubmissionRepository;
|
this.submissionRepository = submissionRepository;
|
||||||
this.ulid = ulid;
|
this.ulid = ulid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ExerciseSubmissionResponse getSubmission(String submissionId) {
|
public SubmissionResponse getSubmission(String submissionId) {
|
||||||
ExerciseSubmission submission = exerciseSubmissionRepository.findById(submissionId)
|
Submission submission = submissionRepository.findById(submissionId)
|
||||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
return new ExerciseSubmissionResponse(submission);
|
return new SubmissionResponse(submission);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +63,7 @@ public class ExerciseSubmissionService {
|
||||||
* @return The saved submission.
|
* @return The saved submission.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public ExerciseSubmissionResponse createSubmission(CompoundGymId id, String userId, ExerciseSubmissionPayload payload) {
|
public SubmissionResponse createSubmission(CompoundGymId id, String userId, SubmissionPayload payload) {
|
||||||
User user = userRepository.findById(userId)
|
User user = userRepository.findById(userId)
|
||||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.FORBIDDEN));
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.FORBIDDEN));
|
||||||
Gym gym = gymRepository.findByCompoundId(id)
|
Gym gym = gymRepository.findByCompoundId(id)
|
||||||
|
@ -81,7 +80,7 @@ public class ExerciseSubmissionService {
|
||||||
if (weightUnit == WeightUnit.POUNDS) {
|
if (weightUnit == WeightUnit.POUNDS) {
|
||||||
metricWeight = WeightUnit.toKilograms(rawWeight);
|
metricWeight = WeightUnit.toKilograms(rawWeight);
|
||||||
}
|
}
|
||||||
ExerciseSubmission submission = exerciseSubmissionRepository.saveAndFlush(new ExerciseSubmission(
|
Submission submission = submissionRepository.saveAndFlush(new Submission(
|
||||||
ulid.nextULID(),
|
ulid.nextULID(),
|
||||||
gym,
|
gym,
|
||||||
exercise,
|
exercise,
|
||||||
|
@ -93,6 +92,6 @@ public class ExerciseSubmissionService {
|
||||||
metricWeight,
|
metricWeight,
|
||||||
payload.reps()
|
payload.reps()
|
||||||
));
|
));
|
||||||
return new ExerciseSubmissionResponse(submission);
|
return new SubmissionResponse(submission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package nl.andrewlalis.gymboard_api.domains.auth.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "auth_user_report")
|
||||||
|
public class UserReport {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@CreationTimestamp
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
private User reportedBy;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Column(length = 1024)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public UserReport(User user, User reportedBy, String reason, String description) {
|
||||||
|
this.user = user;
|
||||||
|
this.reportedBy = reportedBy;
|
||||||
|
this.reason = reason;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getReportedBy() {
|
||||||
|
return reportedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package nl.andrewlalis.gymboard_api.util.sample_data;
|
package nl.andrewlalis.gymboard_api.util.sample_data;
|
||||||
|
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.ExerciseRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import nl.andrewlalis.gymboard_api.util.CsvUtil;
|
import nl.andrewlalis.gymboard_api.util.CsvUtil;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package nl.andrewlalis.gymboard_api.util.sample_data;
|
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.GymRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.ExerciseRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository;
|
import nl.andrewlalis.gymboard_api.domains.api.dao.submission.SubmissionRepository;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.Gym;
|
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.WeightUnit;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise;
|
import nl.andrewlalis.gymboard_api.domains.api.model.Exercise;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission;
|
import nl.andrewlalis.gymboard_api.domains.api.model.submission.Submission;
|
||||||
import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.CdnClient;
|
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.domains.api.service.submission.ExerciseSubmissionService;
|
||||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
|
||||||
|
@ -29,13 +29,13 @@ public class SampleSubmissionGenerator implements SampleDataGenerator {
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final ExerciseRepository exerciseRepository;
|
private final ExerciseRepository exerciseRepository;
|
||||||
private final ExerciseSubmissionService submissionService;
|
private final ExerciseSubmissionService submissionService;
|
||||||
private final ExerciseSubmissionRepository submissionRepository;
|
private final SubmissionRepository submissionRepository;
|
||||||
private final ULID ulid;
|
private final ULID ulid;
|
||||||
|
|
||||||
@Value("${app.cdn-origin}")
|
@Value("${app.cdn-origin}")
|
||||||
private String cdnOrigin;
|
private String cdnOrigin;
|
||||||
|
|
||||||
public SampleSubmissionGenerator(GymRepository gymRepository, UserRepository userRepository, ExerciseRepository exerciseRepository, ExerciseSubmissionService submissionService, ExerciseSubmissionRepository submissionRepository, ULID ulid) {
|
public SampleSubmissionGenerator(GymRepository gymRepository, UserRepository userRepository, ExerciseRepository exerciseRepository, ExerciseSubmissionService submissionService, SubmissionRepository submissionRepository, ULID ulid) {
|
||||||
this.gymRepository = gymRepository;
|
this.gymRepository = gymRepository;
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
this.exerciseRepository = exerciseRepository;
|
this.exerciseRepository = exerciseRepository;
|
||||||
|
@ -94,7 +94,7 @@ public class SampleSubmissionGenerator implements SampleDataGenerator {
|
||||||
rawWeight = metricWeight.multiply(new BigDecimal("2.2046226218"));
|
rawWeight = metricWeight.multiply(new BigDecimal("2.2046226218"));
|
||||||
}
|
}
|
||||||
|
|
||||||
submissionRepository.save(new ExerciseSubmission(
|
submissionRepository.save(new Submission(
|
||||||
ulid.nextULID(),
|
ulid.nextULID(),
|
||||||
randomChoice(gyms, random),
|
randomChoice(gyms, random),
|
||||||
randomChoice(exercises, random),
|
randomChoice(exercises, random),
|
||||||
|
|
|
@ -7,6 +7,8 @@ export interface User {
|
||||||
activated: boolean;
|
activated: boolean;
|
||||||
email: string;
|
email: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
personalDetails?: UserPersonalDetails;
|
||||||
|
preferences?: UserPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PersonSex {
|
export enum PersonSex {
|
||||||
|
@ -20,6 +22,7 @@ export interface UserPersonalDetails {
|
||||||
birthDate?: string;
|
birthDate?: string;
|
||||||
currentWeight?: number;
|
currentWeight?: number;
|
||||||
currentWeightUnit?: number;
|
currentWeightUnit?: number;
|
||||||
|
currentMetricWeight?: number;
|
||||||
sex: PersonSex;
|
sex: PersonSex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +48,18 @@ class AuthModule {
|
||||||
|
|
||||||
private tokenRefreshTimer?: Timeout;
|
private tokenRefreshTimer?: Timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to use the given credentials to obtain an access token for
|
||||||
|
* sending authenticated requests.
|
||||||
|
* @param authStore The auth store to use to update app state.
|
||||||
|
* @param credentials The credentials for logging in.
|
||||||
|
*/
|
||||||
public async login(authStore: AuthStoreType, credentials: TokenCredentials) {
|
public async login(authStore: AuthStoreType, credentials: TokenCredentials) {
|
||||||
authStore.token = await this.fetchNewToken(credentials);
|
authStore.token = await this.getNewToken(credentials);
|
||||||
authStore.user = await this.fetchMyUser(authStore);
|
authStore.user = await this.getMyUser(authStore);
|
||||||
|
// Load the user's attached data right away too.
|
||||||
|
authStore.user.personalDetails = await this.getMyPersonalDetails(authStore);
|
||||||
|
authStore.user.preferences = await this.getMyPreferences(authStore);
|
||||||
|
|
||||||
clearTimeout(this.tokenRefreshTimer);
|
clearTimeout(this.tokenRefreshTimer);
|
||||||
this.tokenRefreshTimer = setTimeout(
|
this.tokenRefreshTimer = setTimeout(
|
||||||
|
@ -71,7 +83,7 @@ class AuthModule {
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchNewToken(credentials: TokenCredentials): Promise<string> {
|
public async getNewToken(credentials: TokenCredentials): Promise<string> {
|
||||||
const response = await api.post('/auth/token', credentials);
|
const response = await api.post('/auth/token', credentials);
|
||||||
return response.data.token;
|
return response.data.token;
|
||||||
}
|
}
|
||||||
|
@ -81,12 +93,12 @@ class AuthModule {
|
||||||
authStore.token = response.data.token;
|
authStore.token = response.data.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchMyUser(authStore: AuthStoreType): Promise<User> {
|
public async getMyUser(authStore: AuthStoreType): Promise<User> {
|
||||||
const response = await api.get('/auth/me', authStore.axiosConfig);
|
const response = await api.get('/auth/me', authStore.axiosConfig);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchUser(userId: string, authStore: AuthStoreType): Promise<User> {
|
public async getUser(userId: string, authStore: AuthStoreType): Promise<User> {
|
||||||
const response = await api.get(`/auth/users/${userId}`, authStore.axiosConfig);
|
const response = await api.get(`/auth/users/${userId}`, authStore.axiosConfig);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{{ submission.exercise.displayName }}
|
{{ submission.exercise.displayName }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
<q-item-label caption>
|
<q-item-label caption>
|
||||||
{{ submission.submitterName }}
|
{{ submission.user.name }}
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section side top>
|
<q-item-section side top>
|
||||||
|
|
|
@ -39,6 +39,12 @@ export default {
|
||||||
submit: 'Submit',
|
submit: 'Submit',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
userPage: {
|
||||||
|
notFound: {
|
||||||
|
title: 'User Not Found',
|
||||||
|
description: 'We couldn\'t find the user you\'re looking for.'
|
||||||
|
}
|
||||||
|
},
|
||||||
accountMenuItem: {
|
accountMenuItem: {
|
||||||
logIn: 'Login',
|
logIn: 'Login',
|
||||||
myAccount: 'My Account',
|
myAccount: 'My Account',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{{ submission.exercise.displayName }}
|
{{ submission.exercise.displayName }}
|
||||||
</h3>
|
</h3>
|
||||||
<p>{{ submission.reps }} reps</p>
|
<p>{{ submission.reps }} reps</p>
|
||||||
<p>by {{ submission.submitterName }}</p>
|
<p>by <router-link :to="'/users/' + submission.user.id">{{ submission.user.name }}</router-link></p>
|
||||||
<p>At <router-link :to="getGymRoute(submission.gym)">{{ submission.gym.displayName }}</router-link></p>
|
<p>At <router-link :to="getGymRoute(submission.gym)">{{ submission.gym.displayName }}</router-link></p>
|
||||||
<p>
|
<p>
|
||||||
{{ submission.createdAt.setLocale($i18n.locale).toLocaleString(DateTime.DATETIME_MED) }}
|
{{ submission.createdAt.setLocale($i18n.locale).toLocaleString(DateTime.DATETIME_MED) }}
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
<p>{{ user?.email }}</p>
|
<p>{{ user?.email }}</p>
|
||||||
<p v-if="isOwnUser">This is your account!</p>
|
<p v-if="isOwnUser">This is your account!</p>
|
||||||
</StandardCenteredPage>
|
</StandardCenteredPage>
|
||||||
|
<StandardCenteredPage v-if="userNotFound">
|
||||||
|
<h3>{{ $t('userPage.notFound.title') }}</h3>
|
||||||
|
<p>{{ $t('userPage.notFound.description') }}</p>
|
||||||
|
</StandardCenteredPage>
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -29,10 +33,22 @@ const user: Ref<User | undefined> = ref();
|
||||||
*/
|
*/
|
||||||
const isOwnUser = ref(false);
|
const isOwnUser = ref(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag used to indicate whether we should show a "not found" message instead
|
||||||
|
* of the usual user page.
|
||||||
|
*/
|
||||||
|
const userNotFound = ref(false);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const userId = route.params.userId as string;
|
const userId = route.params.userId as string;
|
||||||
user.value = await api.auth.fetchUser(userId, authStore);
|
try {
|
||||||
isOwnUser.value = user.value.id === authStore.user?.id;
|
user.value = await api.auth.getUser(userId, authStore);
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response && error.response.code === 404) {
|
||||||
|
userNotFound.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isOwnUser.value = authStore.loggedIn && user.value.id === authStore.user?.id;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { defineStore } from 'pinia';
|
|
||||||
|
|
||||||
export const useCounterStore = defineStore('counter', {
|
|
||||||
state: () => ({
|
|
||||||
counter: 0,
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
doubleCount: (state) => state.counter * 2,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
increment() {
|
|
||||||
this.counter++;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
Loading…
Reference in New Issue