Skip to content

Commit e76283b

Browse files
committed
2 parents 7bb3423 + fc56452 commit e76283b

File tree

9 files changed

+91
-61
lines changed

9 files changed

+91
-61
lines changed

backend/demo-group7/src/main/java/com/group7/demo/dtos/ExerciseProgress.java

Lines changed: 0 additions & 13 deletions
This file was deleted.

backend/demo-group7/src/main/java/com/group7/demo/dtos/UserExerciseDetail.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import lombok.Builder;
66
import lombok.Data;
77

8-
import java.time.LocalDateTime;
9-
108
@Data
119
@Builder
1210
@AllArgsConstructor
@@ -16,5 +14,4 @@ public class UserExerciseDetail {
1614
private int repetitions;
1715
private int sets;
1816
private boolean completed;
19-
private String completedAt;
2017
}

backend/demo-group7/src/main/java/com/group7/demo/dtos/mapper/Mapper.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ public ExerciseDetail mapToExerciseDetailResponse(TrainingProgramExercise traini
6666

6767
public UserTrainingProgramResponse mapToUserTrainingProgramResponse(UserTrainingProgram userTrainingProgram) {
6868
TrainingProgram program = userTrainingProgram.getTrainingProgram();
69-
Map<Long, ExerciseProgress> exerciseProgress = userTrainingProgram.getExerciseProgress(); // Now returns Map<Long, Boolean>
69+
Map<Long, Boolean> completedExercises = userTrainingProgram.getExerciseProgress(); // Now returns Map<Long, Boolean>
7070

7171
// Use the new mapper function for exercises
7272
List<UserExerciseDetail> exerciseDetails = program.getExercises().stream()
73-
.map(exercise -> mapToUserExerciseDetailResponse(exercise, exerciseProgress))
73+
.map(exercise -> mapToUserExerciseDetailResponse(exercise, completedExercises))
7474
.sorted(Comparator.comparing(UserExerciseDetail::getId))
7575
.collect(Collectors.toList());
7676

@@ -90,16 +90,13 @@ public UserTrainingProgramResponse mapToUserTrainingProgramResponse(UserTraining
9090
.build();
9191
}
9292

93-
public UserExerciseDetail mapToUserExerciseDetailResponse(TrainingProgramExercise trainingProgramExercise, Map<Long, ExerciseProgress> exerciseProgress) {
94-
ExerciseProgress progress = exerciseProgress.getOrDefault(trainingProgramExercise.getId(), new ExerciseProgress(false, null));
93+
public UserExerciseDetail mapToUserExerciseDetailResponse(TrainingProgramExercise trainingProgramExercise, Map<Long, Boolean> completedExercises) {
9594
return UserExerciseDetail.builder()
9695
.id(trainingProgramExercise.getId())
9796
.exercise(trainingProgramExercise.getExercise())
9897
.repetitions(trainingProgramExercise.getRepetitions())
9998
.sets(trainingProgramExercise.getSets())
100-
.completed(progress.isCompleted())
101-
.completedAt(progress.getCompletedAt())
99+
.completed(completedExercises.getOrDefault(trainingProgramExercise.getId(), false)) // Use `getOrDefault` to handle missing keys
102100
.build();
103101
}
104-
105102
}

backend/demo-group7/src/main/java/com/group7/demo/models/UserTrainingProgram.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.core.type.TypeReference;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.group7.demo.dtos.ExerciseProgress;
65
import com.group7.demo.models.enums.UserTrainingProgramStatus;
76
import jakarta.persistence.*;
87
import lombok.AllArgsConstructor;
@@ -46,14 +45,14 @@ public class UserTrainingProgram {
4645
private LocalDateTime completedAt;
4746

4847
// Deserialize the JSON string into a Map
49-
public Map<Long, ExerciseProgress> getExerciseProgress() {
48+
public Map<Long, Boolean> getExerciseProgress() {
5049
if (exerciseProgress == null) {
5150
return new HashMap<>(); // return empty map if no progress is available
5251
}
5352

5453
try {
5554
ObjectMapper objectMapper = new ObjectMapper();
56-
return objectMapper.readValue(exerciseProgress, new TypeReference<Map<Long, ExerciseProgress>>() {});
55+
return objectMapper.readValue(exerciseProgress, new TypeReference<Map<Long, Boolean>>() {});
5756
} catch (Exception e) {
5857
e.printStackTrace();
5958
return new HashMap<>(); // return empty map on error

backend/demo-group7/src/main/java/com/group7/demo/services/TrainingProgramService.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
65
import com.group7.demo.dtos.*;
76
import com.group7.demo.dtos.mapper.Mapper;
87
import com.group7.demo.models.*;
@@ -18,7 +17,6 @@
1817
import org.springframework.stereotype.Service;
1918

2019
import java.time.LocalDateTime;
21-
import java.time.format.DateTimeFormatter;
2220
import java.util.List;
2321
import java.util.Map;
2422
import java.util.Set;
@@ -129,7 +127,7 @@ public void deleteTrainingProgram(Long id, HttpServletRequest request) throws Ex
129127
}
130128

131129
@Transactional
132-
public UserTrainingProgramResponse joinTrainingProgram(Long trainingProgramId, HttpServletRequest request) {
130+
public UserTrainingProgramResponse joinTrainingProgram(Long trainingProgramId , HttpServletRequest request) {
133131
User user = authenticationService.getAuthenticatedUserInternal(request);
134132

135133
TrainingProgram trainingProgram = trainingProgramRepository.findById(trainingProgramId)
@@ -144,10 +142,10 @@ public UserTrainingProgramResponse joinTrainingProgram(Long trainingProgramId, H
144142

145143
// Initialize the progress JSON object
146144
ObjectMapper objectMapper = new ObjectMapper();
147-
Map<Long, ExerciseProgress> exerciseProgress = trainingProgram.getExercises().stream()
145+
Map<Long, Boolean> exerciseProgress = trainingProgram.getExercises().stream()
148146
.collect(Collectors.toMap(
149147
TrainingProgramExercise::getId, // Exercise ID
150-
exercise -> new ExerciseProgress(false, null)
148+
TrainingProgramExercise -> false // Not completed yet
151149
));
152150

153151
String progressJson;
@@ -171,7 +169,6 @@ public UserTrainingProgramResponse joinTrainingProgram(Long trainingProgramId, H
171169
return mapper.mapToUserTrainingProgramResponse(userTrainingProgramRepository.save(userTrainingProgram));
172170
}
173171

174-
175172
@Transactional
176173
public Set<String> getRegisteredUsernames(Long trainingProgramId) {
177174
// Fetch the training program by its ID
@@ -218,21 +215,17 @@ public UserTrainingProgramResponse markExerciseAsCompleted(Long trainingProgramI
218215
UserTrainingProgram userTrainingProgram = getOngoingUserTrainingProgram(user, trainingProgramId);
219216

220217
// Get the current progress map
221-
Map<Long, ExerciseProgress> exerciseProgress = userTrainingProgram.getExerciseProgress();
218+
Map<Long, Boolean> exerciseProgress = userTrainingProgram.getExerciseProgress();
222219

223220
// Mark the exercise as completed
224-
ExerciseProgress progress = exerciseProgress.getOrDefault(exerciseId, new ExerciseProgress(false, null));
225-
progress.setCompleted(true);
226-
progress.setCompletedAt(LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME));
227-
exerciseProgress.put(exerciseId, progress);
221+
exerciseProgress.put(exerciseId, true);
228222

229223
// Serialize the updated exercise progress map back to JSON
230224
ObjectMapper objectMapper = new ObjectMapper();
231-
objectMapper.findAndRegisterModules();
232225
try {
233226
String updatedProgressJson = objectMapper.writeValueAsString(exerciseProgress);
234227
userTrainingProgram.setExerciseProgress(updatedProgressJson); // Save the updated JSON string
235-
} catch (JsonProcessingException e) {
228+
} catch (Exception e) {
236229
throw new IllegalStateException("Failed to update exercise progress JSON", e);
237230
}
238231

@@ -241,21 +234,17 @@ public UserTrainingProgramResponse markExerciseAsCompleted(Long trainingProgramI
241234

242235

243236

244-
245-
246237
@Transactional
247238
public UserTrainingProgramResponse unmarkExerciseAsCompleted(Long trainingProgramId, Long exerciseId, HttpServletRequest request) {
248239
User user = authenticationService.getAuthenticatedUserInternal(request);
249240

250241
UserTrainingProgram userTrainingProgram = getOngoingUserTrainingProgram(user, trainingProgramId);
251242

252-
Map<Long, ExerciseProgress> exerciseProgress = userTrainingProgram.getExerciseProgress();
243+
// Get the current progress map from the serialized exerciseProgress
244+
Map<Long, Boolean> exerciseProgress = userTrainingProgram.getExerciseProgress();
253245

254-
// Update the progress for the specified exercise
255-
ExerciseProgress progress = exerciseProgress.getOrDefault(exerciseId, new ExerciseProgress(false, null));
256-
progress.setCompleted(false); // Mark as incomplete
257-
progress.setCompletedAt(null); // Remove the completion time
258-
exerciseProgress.put(exerciseId, progress);
246+
// Mark the exercise as incomplete (unmark)
247+
exerciseProgress.put(exerciseId, false);
259248

260249
// Serialize the updated progress map back to JSON
261250
ObjectMapper objectMapper = new ObjectMapper();
@@ -269,7 +258,6 @@ public UserTrainingProgramResponse unmarkExerciseAsCompleted(Long trainingProgra
269258
return mapper.mapToUserTrainingProgramResponse(userTrainingProgramRepository.save(userTrainingProgram));
270259
}
271260

272-
273261
@Transactional
274262
public UserTrainingProgramResponse markTrainingProgramAsCompleted(Long trainingProgramId, HttpServletRequest request) {
275263
User user = authenticationService.getAuthenticatedUserInternal(request);

mobile/__tests__/App.test.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,18 @@ test('Renders Search Result Page Correctly', () => {
5353
expect(tree).toMatchSnapshot();
5454
});
5555

56-
test('Searches Correctly', async () => { /* TODO: Change the endpoints */
56+
test('Searches Correctly', async () => {
5757
const mockTitle = jest.fn();
5858
const mockImage = jest.fn();
59-
const mockCreator = jest.fn();
60-
const mockType = jest.fn();
61-
62-
const response = await apiInstance().post("search", { mockTitle, mockImage, mockCreator, mockType });
59+
const mockExercies = jest.fn();
60+
const mockName = jest.fn();
61+
const mockEquipment = jest.fn();
62+
const mockBodyPart = jest.fn();
63+
const mockInstruction = jest.fn();
64+
const mockTargetMuscle = jest.fn();
65+
const mockSecondaryMuscles = jest.fn();
66+
67+
const response = await apiInstance().post("search", { mockTitle, mockImage, mockExercies, mockName, mockEquipment, mockBodyPart, mockInstruction, mockTargetMuscle, mockSecondaryMuscles });
6368
expect(response).toBe( /* TODO: The Object That Returns */ );
6469
});
6570

@@ -72,11 +77,16 @@ test('Renders Create Post Page Correctly', () => {
7277

7378
test('Create Post Correctly', async () => {
7479
const mockTitle = jest.fn();
80+
const mockPost = jest.fn();
7581
const mockDescription = jest.fn();
82+
const mockImage = jest.fn();
7683
const mockLabels = jest.fn();
7784
const mockLabelTest = jest.fn();
85+
const mockProfile = jest.fn();
86+
const mockPassword = jest.fn();
87+
const mockSessionToken = jest.fn();
7888

79-
const response = await apiInstance().post("createPost", { mockTitle, mockDescription, mockLabels, mockLabelTest });
89+
const response = await apiInstance().post("createPost", { mockTitle, mockPost, mockDescription, mockImage, mockLabels, mockLabelTest, mockProfile, mockPassword, mockSessionToken });
8090
expect(response).toBe( /* TODO: The Object That Returns */ );
8191
});
8292

mobile/components/ProfilePage.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,14 @@ useEffect(() => {
175175
const programs = [
176176
{ id: 1, title: "Full Body Workout",
177177
description: "This is a comprehensive program targeting all major muscle groups.",
178-
trainerUsername: "fitness_guru_123",
178+
trainerUsername: "sametalan",
179+
participants:[
180+
"sametalan2",
181+
"Hanaaa",
182+
"deno",
183+
"fit_deniz"
184+
],
185+
createdAt:'2024-11-25T13:52:56.512941',
179186
exercises: [
180187
{ exercise:{
181188
name: "Push-Up",
@@ -204,7 +211,14 @@ useEffect(() => {
204211
]},
205212
{ id: 2, title: "Full Body Workout",
206213
description: "This is a comprehensive program targeting all major muscle groups.",
207-
trainerUsername: "fitness_guru_123",
214+
trainerUsername: "fit_deniz",
215+
participants:[
216+
"sametalan2",
217+
"Hanaaa",
218+
"deno",
219+
"fit_deniz"
220+
],
221+
createdAt:'2024-11-25T13:52:56.512941',
208222
exercises: [
209223
{ exercise:{
210224
name: "Push-Up",
@@ -353,7 +367,7 @@ useEffect(() => {
353367
{/* Profile Header */}
354368
<View style={styles.header}>
355369
<Image
356-
source={{ uri: 'https://via.placeholder.com/150' }} // Mock profile image
370+
source={{ uri: 'https://example.com/push-up.gif' }} // Mock profile image
357371
style={styles.profileImage}
358372
/>
359373
<Text style={styles.profileName}>{username}</Text>

mobile/components/ProgramCard.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const ProgramCard = ({ trainerUsername, title, description, exercises, date, par
55
return (
66
<TouchableOpacity
77
style={styles.card}
8-
onPress={() => navigation.navigate('ProgramDetail', { trainerUsername, title, description, exercises, navigation })}
8+
onPress={() => navigation.navigate('ProgramDetail', { trainerUsername, title, description, exercises, participants, date, navigation })}
99
>
1010
<TouchableOpacity onPress={() => navigation.navigate('UserProfile', { username: trainerUsername })}>
1111
<Text style={styles.owner}>{trainerUsername}</Text>

mobile/components/ProgramDetail.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from 'react-native';
1212

1313
const ProgramDetail = ({ route }) => {
14-
const { title, description, trainerUsername, exercises } = route.params;
14+
const { trainerUsername, title, description, exercises, date, participants, navigation } = route.params;
1515
/*const {title, description, trainerUsername, exercises} = {
1616
title: "Full Body Workout",
1717
description: "This is a comprehensive program targeting all major muscle groups.",
@@ -43,11 +43,19 @@ const ProgramDetail = ({ route }) => {
4343
}
4444
],
4545
}*/
46+
console.log(participants);
4647
const [expandedExercise, setExpandedExercise] = useState(null);
4748

4849
const toggleExerciseDetails = (index) => {
4950
setExpandedExercise(expandedExercise === index ? null : index);
5051
};
52+
const renderParticipant = ({ item, index }) => {
53+
return(
54+
<TouchableOpacity onPress={() => navigation.navigate('UserProfile', { username: item })}>
55+
<Text style={styles.owner}>{item}</Text>
56+
</TouchableOpacity>
57+
);
58+
}
5159

5260
const renderExercise = ({ item, index }) => {
5361
const isExpanded = expandedExercise === index;
@@ -100,11 +108,21 @@ const ProgramDetail = ({ route }) => {
100108
return (
101109
<ScrollView contentContainerStyle={styles.container}>
102110
<View style={styles.postContainer}>
103-
{/* Program Info */}
111+
{/* Participant Info */}
104112
<Text style={styles.title}>{title}</Text>
105113
<Text style={styles.owner}>{trainerUsername}</Text>
106114
<Text style={styles.description}>{description}</Text>
107115
</View>
116+
<View style={styles.participantsContainer}>
117+
<Text style={styles.participantListTitle}>Participants:</Text>
118+
<FlatList
119+
data={participants}
120+
keyExtractor={(item, index) => index.toString()}
121+
renderItem={renderParticipant}
122+
contentContainerStyle={styles.participantsList}
123+
/>
124+
</View>
125+
108126
{/* Exercises List */}
109127
<View style={styles.exercisesContainer}>
110128
<Text style={styles.exerciseListTitle}>Exercises:</Text>
@@ -185,7 +203,26 @@ container: {
185203
shadowColor: '#000',
186204
shadowOpacity: 0.1,
187205
shadowRadius: 5,
188-
marginBottom: 20},
206+
marginBottom: 20
207+
},
208+
participantListTitle: {
209+
fontSize: 18,
210+
fontWeight: 'bold',
211+
color: '#333',
212+
marginBottom: 10,
213+
},
214+
participantsList: {
215+
paddingBottom: 20,
216+
},
217+
participantsContainer:{
218+
backgroundColor: '#FFFFFF',
219+
borderRadius: 12,
220+
padding: 15,
221+
shadowColor: '#000',
222+
shadowOpacity: 0.1,
223+
shadowRadius: 5,
224+
marginBottom: 20
225+
},
189226
exerciseContainer: {
190227
backgroundColor: '#f9f9f9',
191228
borderRadius: 10,
@@ -196,6 +233,7 @@ container: {
196233
shadowRadius: 5,
197234
elevation: 2,
198235
},
236+
199237
exerciseHeader: {
200238
flexDirection: 'row',
201239
justifyContent: 'space-between',

0 commit comments

Comments
 (0)