diff --git a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/models/Profile.kt b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/models/Profile.kt index 218bcb7f..0c005a37 100644 --- a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/models/Profile.kt +++ b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/models/Profile.kt @@ -5,14 +5,14 @@ data class ProfileData( var surname: String?, var birth_date: String?, var gender:String?, - var bloodType: String?, var phoneNumber: String?, - var country: String?, - var city: String?, - var state: String?, + var bloodType: String?, var weight: Int?, var height: Int?, + var state: String?, + var country: String?, val emailConfirmed: Boolean? = false, + var city: String?, val privacyPolicyAccepted: Boolean? = false, ) @@ -22,15 +22,15 @@ data class UserInfoRequest( var surname: String?, var birth_date: String?, var gender:String?, - var bloodType: String?, var phoneNumber: String?, - var Country: String?, - var City: String?, - var State: String?, + var bloodType: String?, var weight: Int?, var height: Int?, - val isEmailConfirmed: Boolean? = false, - val isPrivacyPolicyAccepted: Boolean? = false, + var state: String?, + var country: String?, + val emailConfirmed: Boolean? = false, + var city: String?, + val privacyPolicyAccepted: Boolean? = false, ) data class UserInfo( diff --git a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/remote/ResqService.kt b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/remote/ResqService.kt index ebcca6ea..522b0df1 100644 --- a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/remote/ResqService.kt +++ b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/data/remote/ResqService.kt @@ -286,28 +286,29 @@ class ResqService(appContext: Context) { state = response.body()?.state, emailConfirmed = response.body()?.emailConfirmed, privacyPolicyAccepted = response.body()?.privacyPolicyAccepted, - birth_date = response.body()?.birth_date.toString(), + birth_date = response.body()?.birth_date, ) } @RequiresApi(Build.VERSION_CODES.O) suspend fun updateUserData(profileData: ProfileData): Response { val token = userSessionManager.getUserToken() ?: "" + Log.d("AAA", "updateUserData: $profileData") + Log.d("AAA", "token: $token") val userId = userSessionManager.getUserId() - val request = UserInfoRequest( name = profileData.name ?: "", surname = profileData.surname ?: "", - birth_date = null, - Country = profileData.country ?: "", - City = profileData.city ?: "", - State = profileData.state ?: "", + birth_date = profileData.birth_date ?: null, + country = profileData.country ?: "", + city = profileData.city ?: "", + state = profileData.state ?: "", bloodType = profileData.bloodType ?: "", height = profileData.height, weight = profileData.weight, gender = profileData.gender ?: "", phoneNumber = profileData.phoneNumber ?: "", - isEmailConfirmed = true, - isPrivacyPolicyAccepted = true + emailConfirmed = true, + privacyPolicyAccepted = true ) return profileService.updateProfile( userId = userId, diff --git a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/ui/views/screens/ProfileScreen.kt b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/ui/views/screens/ProfileScreen.kt index d4177da4..a892d3b8 100644 --- a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/ui/views/screens/ProfileScreen.kt +++ b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/ui/views/screens/ProfileScreen.kt @@ -5,6 +5,7 @@ package com.cmpe451.resq.ui.views.screens import android.content.Context import android.net.Uri import android.os.Build +import android.util.Log import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.RequiresApi @@ -73,8 +74,7 @@ import com.cmpe451.resq.ui.theme.RequestColor import com.cmpe451.resq.ui.theme.ResourceColor import com.cmpe451.resq.viewmodels.ProfileViewModel import kotlinx.coroutines.launch - -@OptIn(ExperimentalMaterial3Api::class) +import java.time.Year @Composable fun TextListSelectionWithColorChange( items: List, @@ -179,44 +179,32 @@ fun ProfilePhoto() { // TO DO: Add deletion option } -@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @RequiresApi(Build.VERSION_CODES.O) @Composable fun ProfileScreen(navController: NavController, appContext: Context) { val viewModel: ProfileViewModel = viewModel() - - viewModel.getUserData(appContext) + val profileData by viewModel.profile + LaunchedEffect(profileData) { + viewModel.getUserData(appContext) + } val allRoles = listOf("VICTIM", "RESPONDER", "FACILITATOR") val userRoles = UserSessionManager.getInstance(appContext).getUserRoles() val availableRoles = allRoles.filter { !userRoles.contains(it) } - val profileData by viewModel.profile - when (profileData) { - null -> { - // Data is loading - Text("Loading...") - } - else -> { - val userRoles = UserSessionManager.getInstance(appContext).getUserRoles() - if (userRoles != null) { - if (userRoles.contains("VICTIM") || userRoles.contains("RESPONDER") || userRoles.contains("FACILITATOR")) { - - Profile(profileData = profileData!!, navController = navController, availableRoles, viewModel, appContext) - } else { - Text("Unknown Role") - } - } - } + if (profileData != null) { + Profile(profileData!!, navController, availableRoles, viewModel, appContext) + } else { + Text("Loading...") } } private fun String.letterOrSpace() = filter { it.isLetter() || it.isWhitespace() } private fun String.isDigit() = filter { it.isDigit() } -fun generateYears(start: Int, end: Int): List{ +fun generateYears(start: Int, end: Int): List { val years = mutableListOf() - for (i in start..end){ + for (i in end downTo start) { years.add(i.toString()) } return years @@ -248,9 +236,8 @@ fun generateDays(month: String): List{ @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @Composable fun Profile(profileData:ProfileData, navController: NavController, availableRoles: List, viewModel: ProfileViewModel, appContext: Context) { - val genders = listOf("Male", "Female") + val genders = listOf("MALE", "FEMALE") val bloodTypes = listOf("AB Rh+", "AB Rh-", "A Rh+", "A Rh-", "B Rh+", "B Rh-", "O Rh+", "O Rh-") - val userSessionManager = UserSessionManager.getInstance(appContext) var name by remember { mutableStateOf(profileData.name ?: "") } var surname by remember { mutableStateOf(profileData.surname ?: "") } var weight by remember { mutableStateOf(profileData.weight?.toString() ?: "") } @@ -263,17 +250,36 @@ fun Profile(profileData:ProfileData, navController: NavController, availableRole var bloodType by remember { mutableStateOf(profileData.bloodType ?: "") } var isPhoneValid by remember { mutableStateOf(false) } var message by remember { mutableStateOf("") } + var year by remember { mutableStateOf(profileData.birth_date?.substring(0, 4) ?: "") } + var month by remember { mutableStateOf(profileData.birth_date?.substring(5, 7) ?: "") } + var day by remember { mutableStateOf(profileData.birth_date?.substring(8, 10) ?: "") } val snackbarHostState = remember { SnackbarHostState() } - + val userSessionManager: UserSessionManager = UserSessionManager.getInstance(appContext) var profileColor = Color(0xFFFFFFFF) + val years = generateYears(1900, Year.now().value) + val months = generateMonths() + when (userSessionManager.getSelectedRole()) { + null -> { + // Data is loading + Text("Loading...") + } + else -> { + val selectedRole = userSessionManager.getSelectedRole() + if (selectedRole != null) { + if (selectedRole == "FACILITATOR") { + profileColor = RequestColor + } else if (selectedRole == "RESPONDER") { + profileColor = ResourceColor + } else if (selectedRole == "VICTIM") { + profileColor = MyTasksColor + } + } + } + } val coroutineScope = rememberCoroutineScope() val modalBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) - - LaunchedEffect(Unit) { - viewModel.getUserData(appContext) - } ModalBottomSheetLayout( sheetContent = { BottomSheetContent( @@ -544,6 +550,48 @@ fun Profile(profileData:ProfileData, navController: NavController, availableRole ) } } + Row( + modifier = Modifier + .fillMaxWidth(), + + ) { + Column(modifier = Modifier.weight(1f)) { + year.let { + TextListSelectionWithColorChange( + items = years, + selectedItem = year, + onItemSelected = { year = it }, + label = "Year", + color = profileColor + ) + } + } + Column(modifier = Modifier.weight(1f)) { + month.let { + TextListSelectionWithColorChange( + items = months, + selectedItem = month, + onItemSelected = { month = it }, + label = "Month", + color = profileColor + ) + } + } + Column(modifier = Modifier.weight(1f)) { + val days = generateDays(month) + + day.let { + TextListSelectionWithColorChange( + items = days, + selectedItem = day, + onItemSelected = { day = it }, + label = "Day", + color = profileColor + ) + } + } + } + } } } @@ -582,7 +630,6 @@ fun Profile(profileData:ProfileData, navController: NavController, availableRole message = "Please check your phone number." } else { - // @TO DO Handle Save Details button click viewModel.updateProfile(appContext, ProfileData( name = name, surname = surname, @@ -590,23 +637,16 @@ fun Profile(profileData:ProfileData, navController: NavController, availableRole country = country, city = city, state = state, - gender = gender.takeIf { it.isNotEmpty() } , + gender = gender.takeIf { it.isNotEmpty() }, height = height.takeIf { it.isNotEmpty() }?.toInt(), weight = weight.takeIf { it.isNotEmpty() }?.toInt(), phoneNumber = phoneNumber, - birth_date = null + birth_date = if (year == null || month == null || day == null) null else "$year-$month-$day" )) if (viewModel.updateMessage.value != null) { message = "Details saved successfully." + viewModel.errorMessage.value = null } - - else if (viewModel.errorMessage.value != null) { - message = viewModel.errorMessage.value!! - } - else{ - message = "Details saved successfully." - } - } }, @@ -741,7 +781,7 @@ fun ResponderProfileButtons(navController: NavController) { ProfileButton( color = RequestColor, text = "My Request", - route = "request", + route = "myRequests", navController = navController ) } @@ -757,7 +797,7 @@ fun VictimProfileButtons(navController: NavController) { ProfileButton( color = RequestColor, text = "My Request", - route = "request", + route = "myRequests", navController = navController ) } diff --git a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/viewmodels/ProfileViewModel.kt b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/viewmodels/ProfileViewModel.kt index c73134d8..ac516f6b 100644 --- a/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/viewmodels/ProfileViewModel.kt +++ b/resq/mobile/ResQ/app/src/main/java/com/cmpe451/resq/viewmodels/ProfileViewModel.kt @@ -32,7 +32,6 @@ class ProfileViewModel() : ViewModel() { viewModelScope.launch { try { val data = api.getProfileInfo() - Log.d("Service", "getUserData: $data") _profileData.value = data } catch (e: Exception) { errorMessage.value = e.message @@ -42,20 +41,18 @@ class ProfileViewModel() : ViewModel() { @RequiresApi(Build.VERSION_CODES.O) - fun updateProfile(appContext: Context, profileData: ProfileData){ + fun updateProfile(appContext: Context, profileData: ProfileData) { val api = ResqService(appContext) viewModelScope.launch { try { - val response = api.updateUserData(profileData) - if (response.isSuccessful) { + // Update was successful, now fetch the latest profile data + getUserData(appContext) _updateMessage.value = response.body() _errorMessage.value = null - } - else { - _errorMessage.value = response.message() - ?: "Profile update failed. Please try again." + } else { + _errorMessage.value = response.message() ?: "Profile update failed. Please try again." } } catch (e: Exception) { _errorMessage.value = e.message ?: "Unexpected error occurred."