Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #609

Merged
merged 6 commits into from
Dec 24, 2023
Merged

Dev #609

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ data class CategoryTreeNode(
val id: Int,
val data: String,
val children: List<CategoryTreeNode>
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ data class Need(
val requestId: Int?,
val status: String,
val createdDate: String,
val size: String
val size: String?
)

Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ data class UserInfoRequest(
var height: Int?,
val isEmailConfirmed: Boolean? = false,
val isPrivacyPolicyAccepted: Boolean? = false,
)

data class UserInfo(
var email: String,
var name: String,
var surname: String,
var roles: List<String>
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.cmpe451.resq.data.models.NotificationItem
import com.cmpe451.resq.data.models.ProfileData
import com.cmpe451.resq.data.models.RegisterRequestBody
import com.cmpe451.resq.data.models.Resource
import com.cmpe451.resq.data.models.UserInfo
import com.cmpe451.resq.data.models.UserInfoRequest
import com.google.gson.GsonBuilder
import okhttp3.ResponseBody
Expand All @@ -27,8 +28,6 @@ import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import java.time.LocalDate
import java.time.format.DateTimeParseException
import retrofit2.Call
import retrofit2.Callback
interface CategoryTreeNodeService {
@GET("categorytreenode/getMainCategories")
suspend fun getMainCategories(
Expand Down Expand Up @@ -67,14 +66,13 @@ interface NeedService {
@Header("Authorization") jwtToken: String
): Call<List<Need>>


@GET("need/viewNeedsByUserId")
fun viewNeedsByUserId(
@Query("userId") userId: Int,
@Header("Authorization") jwtToken: String,
): Call<List<Need>>

}

interface AuthService {
@POST("auth/signin")
suspend fun login(@Body requestBody: LoginRequestBody): Response<LoginResponse>
Expand All @@ -85,25 +83,30 @@ interface AuthService {

interface ProfileService {
@GET("profile/getProfileInfo")
suspend fun getUserInfo(
suspend fun getProfileInfo(
@Query("userId") userId: Int,
@Header("Authorization") jwtToken: String
): Response<ProfileData>

@POST("profile/updateProfile")
suspend fun updateProfile(
@Query("userId") userId: Int,
@Header("Authorization") jwtToken: String,
@Body request: UserInfoRequest
): Response<String>

@POST("user/requestRole")
suspend fun selectRole(
@Query("userId") userId: Int,
@Query("role") requestedRole: String,
@Header("Authorization") jwtToken: String
): Response<String>


@POST("profile/updateProfile")
suspend fun updateProfile(
@GET("user/getUserInfo")
fun getUserInfo(
@Query("userId") userId: Int,
@Header("Authorization") jwtToken: String,
@Body request: UserInfoRequest
): Response<String>
@Header("Authorization") jwtToken: String
): Call<UserInfo>

}

Expand Down Expand Up @@ -261,11 +264,11 @@ class ResqService(appContext: Context) {
}

@RequiresApi(Build.VERSION_CODES.O)
suspend fun getUserInfo(): ProfileData {
suspend fun getProfileInfo(): ProfileData {
val token = userSessionManager.getUserToken() ?: ""
val userId = userSessionManager.getUserId()

val response = profileService.getUserInfo(
val response = profileService.getProfileInfo(
userId = userId,
jwtToken = "Bearer $token"
)
Expand Down Expand Up @@ -336,4 +339,20 @@ class ResqService(appContext: Context) {
Log.d("AAA", "getNotifications: ${response.isSuccessful}")
return response
}
}
fun getUserInfo(userId: Int, callback: (UserInfo?) -> Unit) {
val token = userSessionManager.getUserToken() ?: ""
profileService.getUserInfo(userId, "Bearer $token").enqueue(object : Callback<UserInfo> {
override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
if (response.isSuccessful) {
callback(response.body())
} else {
callback(null)
}
}
override fun onFailure(call: Call<UserInfo>, t: Throwable) {
callback(null)
}
})
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
Expand Down Expand Up @@ -76,6 +77,12 @@ fun MapScreen(navController: NavController, appContext: Context, mapViewModel: M
val needsList = mapViewModel.needMarkerList.value
val resourcesList = mapViewModel.resourceMarkerList.value

LaunchedEffect(key1 = true) {
mapViewModel.fetchMainCategories(appContext)
}

val categories = mapViewModel.categories.value

Box(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
Expand Down Expand Up @@ -166,33 +173,28 @@ fun MapScreen(navController: NavController, appContext: Context, mapViewModel: M
elevation = 4.dp
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "Category ID: ${need.categoryTreeId}")
Text(
text = "${mapViewModel.findNodeById(categories, need.categoryTreeId.toInt())?.data}",
fontWeight = FontWeight.Bold
)
Text(text = "Quantity: ${need.quantity}")
AnimatedVisibility(visible = need.id == expandedNeedId) {
Column {
Text(text = "User ID: ${need.userId}")
UsernameDisplay(mapViewModel, appContext, need.userId)
Text(text = "Description: ${need.description}")
Row {
Button(
onClick = { /* TODO: Handle Button 1 action */ },
colors = ButtonDefaults.buttonColors(backgroundColor = RequestColor, contentColor = Color.White)
) {
Text("Button 1")
}
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = { /* TODO: Handle Button 2 action */ },
colors = ButtonDefaults.buttonColors(backgroundColor = RequestColor, contentColor = Color.White)
) {
Text("Button 2")
}
} }
if (need.size != null) {
Text(text = "Size: ${need.size}")
}
}
}
}
}
}
}
} else { // Resources list
}

// Resources list
else {
LazyColumn(
modifier = Modifier
.align(Alignment.BottomStart)
Expand All @@ -212,27 +214,18 @@ fun MapScreen(navController: NavController, appContext: Context, mapViewModel: M
elevation = 4.dp
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "Category ID: ${resource.categoryTreeId}")
Text(
text = "${mapViewModel.findNodeById(categories, resource.categoryTreeId.toInt())?.data}",
fontWeight = FontWeight.Bold
)
Text(text = "Quantity: ${resource.quantity}")
AnimatedVisibility(visible = resource.id == expandedResourceId) {
Column {
Text(text = "User ID: ${resource.senderId}")
Text(text = "Size: ${resource.size}")
Row {
Button(
onClick = { /* TODO: Handle Button 1 action */ },
colors = ButtonDefaults.buttonColors(backgroundColor = ResourceColor, contentColor = Color.White)
) {
Text("Button 1")
}
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = { /* TODO: Handle Button 2 action */ },
colors = ButtonDefaults.buttonColors(backgroundColor = ResourceColor, contentColor = Color.White)
) {
Text("Button 2")
}
} }
UsernameDisplay(mapViewModel, appContext, resource.senderId)
if (resource.size != null) {
Text(text = "Size: ${resource.size}")
}
}
}
}
}
Expand Down Expand Up @@ -362,49 +355,13 @@ fun AddSignUpButton(onClick: () -> Unit) {
}

@Composable
fun ExpandableItemList() {
// Mock data similar to the JSON response you showed
val items = listOf(
Need(1, 13, "52", "Please help!", 1, 41.08, 29.05, null, "NOT_INVOLVED", "2023-11-26T02:23:04.731365"),
Need(2, 13, "54", "Help me for god's sake", 1, 30.0, 40.0, null, "NOT_INVOLVED", "2023-11-26T10:57:10.71784")
)

// State to track expanded items
val expandedItemId = remember { mutableStateOf(-1) }

LazyColumn {
items(items) { item ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
.clickable {
expandedItemId.value = if (expandedItemId.value == item.id) -1 else item.id
},
elevation = 4.dp
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "Category ID: ${item.categoryTreeId}")
Text(text = "Quantity: ${item.quantity}")

AnimatedVisibility(visible = expandedItemId.value == item.id) {
Column {
Text(text = "User ID: ${item.userId}")
Text(text = "Description: ${item.description}")
Row {
Button(onClick = { /* Handle button click */ }) {
Text("Button 1")
}
Spacer(modifier = Modifier.width(8.dp))
Button(onClick = { /* Handle button click */ }) {
Text("Button 2")
}
// Add more buttons if needed
}
}
}
}
}
fun UsernameDisplay(mapViewModel: MapViewModel, appContext: Context, userId: Int) {
val userInfo = remember { mutableStateOf("Loading...") }
LaunchedEffect(userId) {
mapViewModel.getUserInfoById(appContext, userId) { result ->
userInfo.value = result
}
}
}
Text(text = "User: ${userInfo.value}")
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,27 @@ package com.cmpe451.resq.viewmodels
import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.cmpe451.resq.data.models.CategoryTreeNode
import com.cmpe451.resq.data.models.Need
import com.cmpe451.resq.data.models.Resource
import com.cmpe451.resq.data.remote.ResqService
import com.google.android.gms.location.FusedLocationProviderClient
import kotlinx.coroutines.launch

class MapViewModel : ViewModel() {
val searchQuery = mutableStateOf("")
val lastKnownLocation = mutableStateOf<Location?>(null)
val needMarkerList = mutableStateOf<List<Need>>(emptyList())
val resourceMarkerList = mutableStateOf<List<Resource>>(emptyList())

// For convert category ids to names
private val _categories = mutableStateOf<List<CategoryTreeNode>>(emptyList())
val categories: State<List<CategoryTreeNode>> = _categories

fun getNeedsByDistance(appContext: Context) {
val api = ResqService(appContext)
api.filterNeedByDistance(
Expand Down Expand Up @@ -65,4 +73,39 @@ class MapViewModel : ViewModel() {
// Show error or something
}
}

fun fetchMainCategories(appContext: Context) {
viewModelScope.launch {
val api = ResqService(appContext)

val response = api.getMainCategories()
if (response.isSuccessful) {
_categories.value = response.body() ?: emptyList()
} else {
// TODO: Handle error
}
}
}

fun findNodeById(rootNodes: List<CategoryTreeNode>, idToFind: Int): CategoryTreeNode? {
for (node in rootNodes) {
if (node.id == idToFind) {
return node
}
val childResult = findNodeById(node.children, idToFind)
if (childResult != null) {
return childResult
}
}
return null
}

fun getUserInfoById(appContext: Context, userId: Int, callback: (String) -> Unit) {
val api = ResqService(appContext)
api.getUserInfo(userId) { userInfo ->
val username = userInfo?.let { "${it.name} ${it.surname}" } ?: "Unknown"
callback(username)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ProfileViewModel() : ViewModel() {

viewModelScope.launch {
try {
val data = api.getUserInfo()
val data = api.getProfileInfo()
Log.d("Service", "getUserData: $data")
_profileData.value = data
} catch (e: Exception) {
Expand Down
Loading
Loading