From 7a5c56b12c25559d3427d95462a0bc4dfba996b2 Mon Sep 17 00:00:00 2001 From: alperenDagi <111731140+alperenDagi@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:16:22 +0300 Subject: [PATCH] Request Role Implementation --- .../cmpe451/resq/data/remote/ResqService.kt | 23 + .../resq/ui/views/screens/ProfileScreen.kt | 831 ++++++++++-------- .../resq/viewmodels/ProfileViewModel.kt | 16 + 3 files changed, 483 insertions(+), 387 deletions(-) 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 456b7438..28becd74 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 @@ -49,6 +49,14 @@ interface ProfileService { @Header("Authorization") jwtToken: String, @Header("X-Selected-Role") role: String ): Response + + @POST("user/requestRole") + suspend fun selectRole( + @Query("userId") userId: Int, + @Query("role") requestedRole: String, + @Header("Authorization") jwtToken: String, + @Header("X-Selected-Role") role: String + ): Response } class ResqService(appContext: Context) { @@ -115,4 +123,19 @@ class ResqService(appContext: Context) { phoneNumber = "05321234567", state = "Kadikoy", ) } + + suspend fun selectRole(requestedRole: String): Response { + val userId = userSessionManager.getUserId() + val token = userSessionManager.getUserToken() ?: "" + val role = userSessionManager.getSelectedRole() ?: "" + + val response = profileService.selectRole( + userId = userId, + requestedRole = requestedRole, + jwtToken = "Bearer $token", + role = requestedRole + ) + + return response + } } 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 14fa7b21..be6f46bd 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 @@ -20,10 +20,15 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Divider import androidx.compose.material.DropdownMenu import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Icon import androidx.compose.material.IconButton +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.TextButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.ArrowBack @@ -31,6 +36,7 @@ import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost @@ -55,11 +61,14 @@ import com.cmpe451.resq.data.models.ProfileData import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.text.input.KeyboardType +import com.cmpe451.resq.data.manager.UserSessionManager import java.time.Year - - +import androidx.compose.material.MaterialTheme.typography +import kotlinx.coroutines.launch +import androidx.compose.material.* @OptIn(ExperimentalMaterial3Api::class) @Composable fun TextListSelectionWithColorChange( @@ -115,6 +124,7 @@ fun TextListSelectionWithColorChange( } +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @RequiresApi(Build.VERSION_CODES.O) @Composable fun ProfileScreen(navController: NavController, appContext: Context) { @@ -122,6 +132,10 @@ fun ProfileScreen(navController: NavController, appContext: Context) { 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 -> { @@ -132,7 +146,8 @@ fun ProfileScreen(navController: NavController, appContext: Context) { val userRoles = profileData!!.roles if (userRoles != null) { if (userRoles.contains("VICTIM") || userRoles.contains("RESPONDER") || userRoles.contains("FACILITATOR")) { - Profile(profileData = profileData!!, navController = navController) + + Profile(profileData = profileData!!, navController = navController, availableRoles, viewModel, appContext) } else { Text("Unknown Role") @@ -175,9 +190,9 @@ fun generateDays(month: String): List{ } @RequiresApi(Build.VERSION_CODES.O) -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) @Composable -fun Profile(profileData:ProfileData, navController: NavController) { +fun Profile(profileData:ProfileData, navController: NavController, availableRoles: List, viewModel: ProfileViewModel, appContext: Context) { 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 years = generateYears(1900, Year.now().value) @@ -202,462 +217,504 @@ fun Profile(profileData:ProfileData, navController: NavController) { var message by remember { mutableStateOf("") } val snackbarHostState = remember { SnackbarHostState() } - - - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .background(Color.White) - ) { - TopAppBar( - navigationIcon = { - IconButton(onClick = { navController.navigateUp() }) { - Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Back") + val coroutineScope = rememberCoroutineScope() + val modalBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) + + ModalBottomSheetLayout( + sheetContent = { + BottomSheetContent( + availableRoles = availableRoles, + onRoleSelected = { selectedRole -> + viewModel.selectRole(selectedRole, appContext) + // Handle the role selection + coroutineScope.launch { modalBottomSheetState.hide() } } - }, - title = { - Text( - text = "Account", - style = TextStyle( - fontSize = 25.sp, - color = Color(0xFF224957), - textAlign = TextAlign.Center - ), - modifier = Modifier.align(Alignment.CenterHorizontally) - ) - }, - modifier = Modifier.fillMaxWidth() - ) - Row (verticalAlignment = Alignment.CenterVertically){ - Image( - Icons.Default.AccountCircle, - contentDescription = "User Profile", - modifier = Modifier - .size(150.dp) - .weight(1f) ) - Text( - text = "$name $surname", - modifier = Modifier.weight(1f), - style = TextStyle( - fontWeight = FontWeight.Bold, - fontSize = 18.sp - ) - ) - } + }, + sheetState = modalBottomSheetState, - - Box( + ) { + Column( modifier = Modifier .fillMaxSize() - .background(color = Color.White) + .verticalScroll(rememberScrollState()) + .background(Color.White) ) { - Column( - modifier = Modifier - .fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally - ) { + TopAppBar( + navigationIcon = { + IconButton(onClick = { navController.navigateUp() }) { + Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Back") + } + }, + title = { + Text( + text = "Account", + style = TextStyle( + fontSize = 25.sp, + color = Color(0xFF224957), + textAlign = TextAlign.Center + ), + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + }, + modifier = Modifier.fillMaxWidth() + ) + Row(verticalAlignment = Alignment.CenterVertically) { + Image( + Icons.Default.AccountCircle, + contentDescription = "User Profile", + modifier = Modifier + .size(150.dp) + .weight(1f) + ) + Text( + text = "$name $surname", + modifier = Modifier.weight(1f), + style = TextStyle( + fontWeight = FontWeight.Bold, + fontSize = 18.sp + ) + ) + } - Spacer(modifier = Modifier.height(16.dp)) + Box( + modifier = Modifier + .fillMaxSize() + .background(color = Color.White) + ) { Column( modifier = Modifier - .fillMaxWidth() - .padding(16.dp) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally ) { - Row( + + Spacer(modifier = Modifier.height(16.dp)) + + Column( modifier = Modifier .fillMaxWidth() - .padding(4.dp) - .background(Color.White) + .padding(16.dp) ) { - name?.let { - OutlinedTextField( - value = it, - onValueChange = { name = it.letterOrSpace() }, - label = { Text("First Name") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Text - ), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + .background(Color.White) + ) { + name?.let { + OutlinedTextField( + value = it, + onValueChange = { name = it.letterOrSpace() }, + label = { Text("First Name") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Text + ), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black - ) + ) - ) - } + ) + } - surname?.let { - OutlinedTextField( - value = it, - onValueChange = { surname = it.letterOrSpace() }, - label = { Text("Last Name") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Text - ), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black + surname?.let { + OutlinedTextField( + value = it, + onValueChange = { surname = it.letterOrSpace() }, + label = { Text("Last Name") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Text + ), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black + ) ) - ) + } + } - } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - - ) { + ) { - email?.let { - val isValidEmail = android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches() - isEmailValid = isValidEmail - - OutlinedTextField( - value = it, - onValueChange = { - email = it - isEmailValid = android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches() - }, - label = { Text("Email") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, - focusedBorderColor = if (isEmailValid) Color.Black else Color.Red - ), - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Email + email?.let { + val isValidEmail = + android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches() + isEmailValid = isValidEmail + + OutlinedTextField( + value = it, + onValueChange = { + email = it + isEmailValid = + android.util.Patterns.EMAIL_ADDRESS.matcher(it) + .matches() + }, + label = { Text("Email") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, + focusedBorderColor = if (isEmailValid) Color.Black else Color.Red + ), + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Email + ) ) - ) + } } - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { - phoneNumber?.let { - OutlinedTextField( - value = it, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Phone - ), - onValueChange = { phoneNumber = it.isDigit() - isPhoneValid = android.util.Patterns.PHONE.matcher(it).matches()}, - - label = { Text("Phone Number") }, - shape = RoundedCornerShape(15), - - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, - focusedBorderColor = if (isPhoneValid) Color.Black else Color.Red + phoneNumber?.let { + OutlinedTextField( + value = it, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Phone + ), + onValueChange = { + phoneNumber = it.isDigit() + isPhoneValid = + android.util.Patterns.PHONE.matcher(it).matches() + }, + + label = { Text("Phone Number") }, + shape = RoundedCornerShape(15), + + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, + focusedBorderColor = if (isPhoneValid) Color.Black else Color.Red + ) ) - ) + } } - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { - - country?.let { - OutlinedTextField( - value = it, - onValueChange = { country = it.letterOrSpace() }, - label = { Text("Country") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { + country?.let { + OutlinedTextField( + value = it, + onValueChange = { country = it.letterOrSpace() }, + label = { Text("Country") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, + + ) + ) + } + city?.let { + OutlinedTextField( + value = it, + onValueChange = { city = it.letterOrSpace() }, + label = { Text("City") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, ) - ) - } - city?.let { - OutlinedTextField( - value = it, - onValueChange = { city = it.letterOrSpace() }, - label = { Text("City") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, ) - ) - } - state?.let { - OutlinedTextField( - value = it, - onValueChange = { state = it.letterOrSpace() }, - label = { Text("State") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, + } + state?.let { + OutlinedTextField( + value = it, + onValueChange = { state = it.letterOrSpace() }, + label = { Text("State") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, + ) ) - ) + } } - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { - - weight?.let { - OutlinedTextField( - value = it, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Number - ), - onValueChange = { weight = it.isDigit() }, - label = { Text("Weight (kg)") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black - ) - ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { - } - height?.let { - OutlinedTextField( - value = it, - keyboardOptions = KeyboardOptions.Default.copy( - keyboardType = KeyboardType.Number - ), - onValueChange = { height = it.isDigit() }, - label = { Text("Height (cm)") }, - shape = RoundedCornerShape(15), - modifier = Modifier - .weight(1f) - .padding(4.dp) - .background(Color.White), - colors = TextFieldDefaults.outlinedTextFieldColors( - containerColor = Color.White, - textColor = Color.Black, - cursorColor = Color.Black, + weight?.let { + OutlinedTextField( + value = it, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Number + ), + onValueChange = { weight = it.isDigit() }, + label = { Text("Weight (kg)") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black + ) ) - ) - } - } - Row( - modifier = Modifier - .fillMaxWidth(), - ) { - Column ( modifier = Modifier.weight(1f)){ - gender?.let { - TextListSelectionWithColorChange( - items = genders, - selectedItem = gender, - onItemSelected = { gender = it }, - label = "Gender", - color = Color(0xFFB356AF) + } + height?.let { + OutlinedTextField( + value = it, + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Number + ), + onValueChange = { height = it.isDigit() }, + label = { Text("Height (cm)") }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(4.dp) + .background(Color.White), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = Color.White, + textColor = Color.Black, + cursorColor = Color.Black, + ) ) } } + Row( + modifier = Modifier + .fillMaxWidth(), + + ) { + Column(modifier = Modifier.weight(1f)) { + gender?.let { + TextListSelectionWithColorChange( + items = genders, + selectedItem = gender, + onItemSelected = { gender = it }, + label = "Gender", + color = Color(0xFFB356AF) + ) + } + } - Column ( modifier = Modifier.weight(1f)){ - bloodType?.let { - TextListSelectionWithColorChange( - items = bloodTypes, - selectedItem = bloodType, - onItemSelected = { bloodType = it }, - label = "Blood Type", - color = Color(0xFFB356AF) - ) + Column(modifier = Modifier.weight(1f)) { + bloodType?.let { + TextListSelectionWithColorChange( + items = bloodTypes, + selectedItem = bloodType, + onItemSelected = { bloodType = it }, + label = "Blood Type", + color = Color(0xFFB356AF) + ) + } } } - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) - ) { - Column ( modifier = Modifier.weight(1f)){ - year?.let { - TextListSelectionWithColorChange( - items = years, - selectedItem = year, - onItemSelected = { year = it }, - label = "Year", - color = Color(0xFFB356AF) - ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(4.dp) + ) { + Column(modifier = Modifier.weight(1f)) { + year?.let { + TextListSelectionWithColorChange( + items = years, + selectedItem = year, + onItemSelected = { year = it }, + label = "Year", + color = Color(0xFFB356AF) + ) + } } - } - Column ( modifier = Modifier.weight(1f)){ - month?.let { - TextListSelectionWithColorChange( - items = months, - selectedItem = month, - onItemSelected = { month = it }, - label = "Month", - color = Color(0xFFB356AF) - ) + Column(modifier = Modifier.weight(1f)) { + month?.let { + TextListSelectionWithColorChange( + items = months, + selectedItem = month, + onItemSelected = { month = it }, + label = "Month", + color = Color(0xFFB356AF) + ) + } } - } - Column ( modifier = Modifier.weight(1f)){ - val days = generateDays(month) - day?.let { - TextListSelectionWithColorChange( - items = days, - selectedItem = day, - onItemSelected = { day = it }, - label = "Day", - color = Color(0xFFB356AF) - ) + Column(modifier = Modifier.weight(1f)) { + val days = generateDays(month) + day?.let { + TextListSelectionWithColorChange( + items = days, + selectedItem = day, + onItemSelected = { day = it }, + label = "Day", + color = Color(0xFFB356AF) + ) + } } } } } } - } - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - Row( - modifier = Modifier.align(Alignment.Start) - ) { - Button( - onClick = { - // @TO DO: Handle button click - }, - colors = ButtonDefaults.buttonColors(Color(0xFFB356AF)), - modifier = Modifier - .size(170.dp, 60.dp) - ) { - Text(text = "My Requests") - } - } - Spacer(modifier = Modifier.height(20.dp)) - Row( - modifier = Modifier.align(Alignment.Start) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(start = 16.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), ) { Row( - modifier = Modifier - .fillMaxWidth() - .padding(4.dp) + modifier = Modifier.align(Alignment.Start) ) { Button( onClick = { - - if (!isEmailValid and !isPhoneValid) { - // @TO DO: Save details - message = "Please check your email address and phone number." - - } - else if (!isPhoneValid){ - message = "Please check your phone number." - - } - else if (!isEmailValid){ - message = "Please check your email address." - } - else{ - // @TO DO Handle Save Details button click - message = "Details saved successfully." - } - + // @TO DO: Handle button click }, - colors = ButtonDefaults.buttonColors(Color(0xFF224957)), - modifier = Modifier.size(170.dp, 60.dp) + colors = ButtonDefaults.buttonColors(Color(0xFFB356AF)), + modifier = Modifier + .size(170.dp, 60.dp) ) { - Text(text = "Save Details") + Text(text = "My Requests") } - - Spacer(modifier = Modifier.width(25.dp)) - Button( - onClick = { - //@ TO DO Handle button click - }, - colors = ButtonDefaults.buttonColors(Color(0xFF224957)), + } + Spacer(modifier = Modifier.height(20.dp)) + Row( + modifier = Modifier.align(Alignment.Start) + ) { + Row( modifier = Modifier - .size(170.dp, 60.dp) + .fillMaxWidth() + .padding(4.dp) ) { - Text(text = "Request Role") + Button( + onClick = { + + if (!isEmailValid and !isPhoneValid) { + // @TO DO: Save details + message = "Please check your email address and phone number." + + } else if (!isPhoneValid) { + message = "Please check your phone number." + + } else if (!isEmailValid) { + message = "Please check your email address." + } else { + // @TO DO Handle Save Details button click + message = "Details saved successfully." + } + + }, + colors = ButtonDefaults.buttonColors(Color(0xFF224957)), + modifier = Modifier.size(170.dp, 60.dp) + ) { + Text(text = "Save Details") + } + + Spacer(modifier = Modifier.width(25.dp)) + Button( + onClick = { + //@ TO DO Handle button click + coroutineScope.launch { + modalBottomSheetState.show() + } + }, + colors = ButtonDefaults.buttonColors(Color(0xFF224957)), + modifier = Modifier + .size(170.dp, 60.dp) + ) { + Text(text = "Request Role") + } } } + } } - - } - LaunchedEffect(key1 = message) { - if (message.isNotEmpty()) { - snackbarHostState.showSnackbar(message, duration = SnackbarDuration.Short) + LaunchedEffect(key1 = message) { + if (message.isNotEmpty()) { + snackbarHostState.showSnackbar(message, duration = SnackbarDuration.Short) + } } + SnackbarHost( + hostState = snackbarHostState, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) } - SnackbarHost( - hostState = snackbarHostState, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) } + +@Composable +fun BottomSheetContent(availableRoles: List, onRoleSelected: (String) -> Unit) { + Column(modifier = Modifier.fillMaxWidth()) { + Text("Select a Role", style = MaterialTheme.typography.headlineMedium, modifier = Modifier.padding(16.dp)) + Divider() + // List the available roles for the user to choose + availableRoles.forEach { role -> + TextButton( + onClick = { onRoleSelected(role) }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) { + Text(role, style = MaterialTheme.typography.bodyMedium) + } + Divider() + } + } +} \ No newline at end of file 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 7fed99d9..3144fd73 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 @@ -1,10 +1,12 @@ package com.cmpe451.resq.viewmodels import android.content.Context +import android.util.Log import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.cmpe451.resq.data.manager.UserSessionManager import com.cmpe451.resq.data.models.ProfileData import com.cmpe451.resq.data.remote.ResqService import kotlinx.coroutines.flow.MutableStateFlow @@ -28,4 +30,18 @@ class ProfileViewModel() : ViewModel() { } } + fun selectRole(role: String, appContext: Context) { + val userSessionManager: UserSessionManager = UserSessionManager.getInstance(appContext) + val api = ResqService(appContext) + val roles = userSessionManager.getUserRoles() + viewModelScope.launch { + try { + val response = api.selectRole(role) + Log.d("ProfileViewModel", "selectRole: $response") + } catch (e: Exception) { + errorMessage.value = e.message + } + } + } + }