Skip to content

Commit 8805758

Browse files
committed
Update profile
1 parent 216bdf2 commit 8805758

File tree

20 files changed

+651
-21
lines changed

20 files changed

+651
-21
lines changed

back_end/src/main/java/org/example/cmpe202_final/controller/user/UserController.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package org.example.cmpe202_final.controller.user;
22

33
import lombok.AllArgsConstructor;
4+
import org.example.cmpe202_final.model.course.Course;
45
import org.example.cmpe202_final.model.user.User;
6+
import org.example.cmpe202_final.model.user.UserType;
57
import org.example.cmpe202_final.service.user.UserService;
6-
import org.springframework.web.bind.annotation.GetMapping;
7-
import org.springframework.web.bind.annotation.PathVariable;
8-
import org.springframework.web.bind.annotation.RequestMapping;
9-
import org.springframework.web.bind.annotation.RestController;
8+
import org.example.cmpe202_final.view.course.CourseViewEntity;
9+
import org.springframework.web.bind.annotation.*;
1010

11+
import java.util.ArrayList;
1112
import java.util.List;
1213
import java.util.Optional;
1314

@@ -27,4 +28,9 @@ public Optional<User> fetchById(@PathVariable("userId") String userId){
2728
return userService.findById(userId);
2829
}
2930

31+
@PostMapping
32+
public User updateCourse(@RequestBody User user){
33+
return userService.postUser(user);
34+
}
35+
3036
}

back_end/src/main/java/org/example/cmpe202_final/service/user/UserService.java

+4
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ public User findByEmail(String email){
3232
return repository.findByEmail(email);
3333
}
3434

35+
public User postUser(User user){
36+
return repository.save(user);
37+
}
38+
3539
}

front_end/.idea/deploymentTargetDropDown.xml

+14-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

front_end/app/src/main/java/com/example/studentportal/common/service/ServiceModule.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ private fun buildOkHttpClient(): OkHttpClient {
4545
.build()
4646
}
4747

48-
const val KEY_BASE_URL = "http://10.0.2.2:8080"
48+
const val KEY_BASE_URL = "https://vivekcmpe.csproject.org"

front_end/app/src/main/java/com/example/studentportal/course/ui/fragment/CourseFragment.kt

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.example.studentportal.R
1616
import com.example.studentportal.common.di.areAnnoucementsDisabled
1717
import com.example.studentportal.common.di.koin
1818
import com.example.studentportal.common.ui.fragment.BaseFragment
19+
import com.example.studentportal.common.ui.model.data
1920
import com.example.studentportal.common.ui.showBaseDialogFragment
2021
import com.example.studentportal.course.ui.layout.CourseMenuLayout
2122
import com.example.studentportal.course.ui.model.UserType
@@ -71,7 +72,13 @@ class CourseFragment(
7172
if (it == UserType.ADMIN) {
7273
childFragmentManager.showBaseDialogFragment(
7374
CourseInputFragment.newInstance(
74-
course = course
75+
course = if (viewModel.uiResultLiveData.value.data() != null) {
76+
course?.copy(
77+
instructor = viewModel.uiResultLiveData.value.data()?.courseUiModel?.instructor
78+
)
79+
} else {
80+
course
81+
}
7582
)
7683
)
7784
} else if (it == UserType.FACULTY) {

front_end/app/src/main/java/com/example/studentportal/course/ui/layout/CourseInputLayout.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ fun CourseInputLayout(
137137
disabledContentColor = Color.LightGray
138138
),
139139
onClick = {
140-
viewModel.uiResultLiveData.value?.toUiModel(existingCourse?.id)?.let {
140+
viewModel.uiResultLiveData.value?.toUiModel(
141+
id = existingCourse?.id,
142+
assignments = existingCourse?.assignments.orEmpty(),
143+
enrolledStudents = existingCourse?.enrolledStudents.orEmpty()
144+
)?.let {
141145
onSubmitClicked.invoke(it)
142146
}
143147
}

front_end/app/src/main/java/com/example/studentportal/course/ui/viewmodel/CourseInputViewModel.kt

+7-3
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,17 @@ class CourseInputViewModel(
101101
description.isNotBlank()
102102
}
103103

104-
fun toUiModel(id: String?): BaseCourseUiModel.CourseUiModel {
104+
fun toUiModel(
105+
id: String?,
106+
assignments: Set<String>,
107+
enrolledStudents: Set<String>
108+
): BaseCourseUiModel.CourseUiModel {
105109
return BaseCourseUiModel.CourseUiModel(
106110
id = id ?: UUID.randomUUID().toString(),
107111
name = this.name,
108112
instructor = selectedUser?.id.orEmpty(),
109-
enrolledStudents = setOf(),
110-
assignments = setOf(),
113+
enrolledStudents = enrolledStudents,
114+
assignments = assignments,
111115
semester = selectedSemester?.id.orEmpty(),
112116
isPublished = false,
113117
description = description

front_end/app/src/main/java/com/example/studentportal/profile/service/UserService.kt

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.example.studentportal.profile.service
22

33
import com.example.studentportal.auth.usecase.model.AuthRequest
44
import com.example.studentportal.auth.usecase.model.AuthResponseUseCaseModel
5+
import com.example.studentportal.home.usecase.models.BaseCourseUseCaseModel
56
import com.example.studentportal.profile.usecase.model.UserUseCaseModel
67
import retrofit2.Call
78
import retrofit2.http.Body
@@ -19,4 +20,7 @@ interface UserService {
1920
fun login(
2021
@Body authRequest: AuthRequest
2122
): Call<AuthResponseUseCaseModel>
23+
24+
@POST("/users")
25+
fun updateUser(@Body user: UserUseCaseModel): Call<UserUseCaseModel>
2226
}

front_end/app/src/main/java/com/example/studentportal/profile/service/repository/UserRepository.kt

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.example.studentportal.common.service.Repository
66
import com.example.studentportal.common.service.ServiceProvider
77
import com.example.studentportal.common.service.serviceModule
88
import com.example.studentportal.profile.service.UserService
9+
import com.example.studentportal.profile.ui.model.UserUiModel
910
import com.example.studentportal.profile.usecase.model.UserUseCaseModel
1011
import org.koin.core.module.Module
1112
import org.koin.dsl.module
@@ -23,6 +24,10 @@ class UserRepository(
2324
return provider.service().login(authRequest).execute()
2425
}
2526

27+
suspend fun updateUser(userUseCaseModel: UserUseCaseModel): Response<UserUseCaseModel>{
28+
return provider.service().updateUser(userUseCaseModel).execute()
29+
}
30+
2631
companion object {
2732
fun koinModule(): Module {
2833
return module {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.example.studentportal.profile.ui.fragment
2+
3+
import android.view.LayoutInflater
4+
import android.view.ViewGroup
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.ui.Modifier
7+
import androidx.core.os.bundleOf
8+
import androidx.fragment.app.setFragmentResult
9+
import androidx.fragment.app.viewModels
10+
import com.example.studentportal.common.ui.fragment.BaseDialogFragment
11+
import com.example.studentportal.course.ui.fragment.CourseInputFragment
12+
import com.example.studentportal.databinding.FragmentEditProfileBinding
13+
import com.example.studentportal.profile.ui.layout.EditProfileLayout
14+
import com.example.studentportal.profile.ui.model.UserUiModel
15+
import com.example.studentportal.profile.ui.viewModel.EditProfileViewModel
16+
import kotlinx.coroutines.Dispatchers
17+
18+
class EditProfileFragment : BaseDialogFragment<FragmentEditProfileBinding>(TAG) {
19+
internal val viewModel by viewModels<EditProfileViewModel> {
20+
EditProfileViewModel.ViewModelProviderFactory(
21+
dispatcher = Dispatchers.IO,
22+
userUiModel = existingUser
23+
)
24+
}
25+
26+
private val existingUser: UserUiModel?
27+
get() = requireArguments().getParcelable<UserUiModel>(KEY_USER)
28+
29+
override fun inflateBinding(
30+
inflater: LayoutInflater,
31+
container: ViewGroup?
32+
): FragmentEditProfileBinding {
33+
val binding = FragmentEditProfileBinding.inflate(inflater, container, false)
34+
binding.composeView.setContent {
35+
EditProfileLayout(
36+
existingUser = existingUser,
37+
viewModel = viewModel,
38+
modifier = Modifier.fillMaxSize(),
39+
onCloseClicked = {dismiss()},
40+
onSubmitClicked = {
41+
val initialData = existingUser ?: return@EditProfileLayout
42+
val user = viewModel.uiResultLiveData.value?.toUiModel(
43+
initialData.id,
44+
initialData.password,
45+
initialData.firstName,
46+
initialData.lastName,
47+
initialData.type
48+
) ?: return@EditProfileLayout
49+
50+
setFragmentResult(
51+
KEY_FRAGMENT_RESULT,
52+
bundleOf(
53+
KEY_USER to user
54+
)
55+
)
56+
dismiss()
57+
}
58+
)
59+
}
60+
return binding
61+
}
62+
63+
companion object {
64+
const val TAG = "EDIT_PROFILE"
65+
const val KEY_USER = "KEY_USER"
66+
const val KEY_FRAGMENT_RESULT = "KEY_FRAGMENT_RESULT"
67+
68+
fun newInstance(user: UserUiModel): EditProfileFragment {
69+
val fragment = EditProfileFragment()
70+
fragment.arguments = bundleOf(
71+
KEY_USER to user
72+
)
73+
return fragment
74+
}
75+
}
76+
}

front_end/app/src/main/java/com/example/studentportal/profile/ui/fragment/ProfileFragment.kt

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
package com.example.studentportal.profile.ui.fragment
22

33
import android.content.SharedPreferences
4+
import android.os.Bundle
45
import android.view.LayoutInflater
56
import android.view.ViewGroup
7+
import android.widget.Toast
68
import androidx.compose.foundation.layout.fillMaxSize
7-
import androidx.compose.runtime.getValue
89
import androidx.compose.ui.Modifier
910
import androidx.core.os.bundleOf
1011
import androidx.fragment.app.viewModels
12+
import androidx.lifecycle.ViewModelProvider
1113
import com.example.studentportal.R
1214
import com.example.studentportal.auth.ui.showLogoutDialog
1315
import com.example.studentportal.common.di.clearAuthenticatedUserData
1416
import com.example.studentportal.common.di.getUserId
1517
import com.example.studentportal.common.di.koin
1618
import com.example.studentportal.common.ui.fragment.BaseFragment
19+
import com.example.studentportal.common.ui.model.data
20+
import com.example.studentportal.common.ui.showBaseDialogFragment
1721
import com.example.studentportal.course.ui.model.UserType
1822
import com.example.studentportal.databinding.FragmentProfileBinding
1923
import com.example.studentportal.home.ui.activity.HomeActivity
2024
import com.example.studentportal.profile.ui.layout.ProfileLayout
25+
import com.example.studentportal.profile.ui.model.UserUiModel
2126
import com.example.studentportal.profile.ui.viewModel.UserProfileViewModel
2227

23-
class ProfileFragment : BaseFragment<FragmentProfileBinding>(TAG) {
28+
class ProfileFragment(
29+
viewModelFactory: ViewModelProvider.Factory = UserProfileViewModel.UserProfileViewModelFactory
30+
) : BaseFragment<FragmentProfileBinding>(TAG) {
2431
internal val viewModel by viewModels<UserProfileViewModel> {
25-
UserProfileViewModel.UserProfileViewModelFactory
32+
viewModelFactory
2633
}
2734

2835
val userId: String
@@ -48,12 +55,37 @@ class ProfileFragment : BaseFragment<FragmentProfileBinding>(TAG) {
4855
koin.get<SharedPreferences>().clearAuthenticatedUserData() // Clear JwtToken
4956
requireActivity().finish()
5057
}
58+
},
59+
onEditClicked = {
60+
viewModel.uiResultLiveData.value.data()?.let {
61+
childFragmentManager.showBaseDialogFragment(
62+
EditProfileFragment.newInstance(it)
63+
)
64+
}
5165
}
5266
)
5367
}
5468
return binding
5569
}
5670

71+
override fun onCreate(savedInstanceState: Bundle?) {
72+
super.onCreate(savedInstanceState)
73+
childFragmentManager.setFragmentResultListener(
74+
EditProfileFragment.KEY_FRAGMENT_RESULT,
75+
this
76+
) { key, bundle ->
77+
bundle.getParcelable<UserUiModel>(EditProfileFragment.KEY_USER)?.let { userUiModel ->
78+
viewModel.updateProfile(userUiModel, onError = {
79+
Toast.makeText(
80+
requireContext(),
81+
it.error?.message.orEmpty(),
82+
Toast.LENGTH_LONG
83+
).show()
84+
})
85+
}
86+
}
87+
}
88+
5789
override fun menuItem() = R.id.nav_profile
5890

5991
companion object {

0 commit comments

Comments
 (0)