Skip to content

Commit

Permalink
Merge pull request #497 from bounswe/feature/mobile-496-add-resource
Browse files Browse the repository at this point in the history
Implement resource creation
  • Loading branch information
alperenDagi authored Nov 27, 2023
2 parents e112135 + 20d7d26 commit 3e90d6b
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fun NavGraph(
RequestScreen(navController, appContext)
}
composable(NavigationItem.Resource.route) {
ResourceScreen(navController)
ResourceScreen(navController, appContext)
}
composable(NavigationItem.OngoingTasks.route) {
OngoingTasksScreen(navController)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.cmpe451.resq.data.models

data class CategoryTreeNode(
val id: Int,
val data: String,
val children: List<CategoryTreeNode>
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package com.cmpe451.resq.data.models

data class CategoryNode(
val id: Int,
val data: String,
val children: List<CategoryNode>
)

data class CreateNeedRequestBody(
val description: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.cmpe451.resq.data.models

data class CreateResourceRequestBody(
var senderId: Int?,
val categoryTreeId: String,
val quantity: Int,
val latitude: Double,
val longitude: Double,
val gender: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import android.os.Build
import androidx.annotation.RequiresApi
import com.cmpe451.resq.data.Constants
import com.cmpe451.resq.data.manager.UserSessionManager
import com.cmpe451.resq.data.models.CategoryNode
import com.cmpe451.resq.data.models.CategoryTreeNode
import com.cmpe451.resq.data.models.CreateNeedRequestBody
import com.cmpe451.resq.data.models.CreateResourceRequestBody
import com.cmpe451.resq.data.models.LoginRequestBody
import com.cmpe451.resq.data.models.LoginResponse
import com.cmpe451.resq.data.models.ProfileData
Expand All @@ -26,9 +27,17 @@ interface CategoryTreeNodeService {
suspend fun getMainCategories(
@Header("Authorization") jwtToken: String,
@Header("X-Selected-Role") role: String
): Response<List<CategoryNode>>
): Response<List<CategoryTreeNode>>
}

interface ResourceService {
@POST("resource/createResource")
suspend fun createResource(
@Header("Authorization") jwtToken: String,
@Header("X-Selected-Role") role: String,
@Body requestBody: CreateResourceRequestBody
): Response<Int>
}
interface NeedService {
@POST("need/createNeed")
suspend fun createNeed(
Expand Down Expand Up @@ -74,14 +83,15 @@ class ResqService(appContext: Context) {
.build()

private val categoryTreeNodeService: CategoryTreeNodeService = retrofit.create(CategoryTreeNodeService::class.java)
private val resourceService: ResourceService = retrofit.create(ResourceService::class.java)
private val needService: NeedService = retrofit.create(NeedService::class.java)
private val authService: AuthService = retrofit.create(AuthService::class.java)
private val profileService: ProfileService = retrofit.create(ProfileService::class.java)

private val userSessionManager: UserSessionManager = UserSessionManager.getInstance(appContext)

// Category Tree Node methods
suspend fun getMainCategories(): Response<List<CategoryNode>> {
suspend fun getMainCategories(): Response<List<CategoryTreeNode>> {
val token = userSessionManager.getUserToken() ?: ""
val selectedRole = userSessionManager.getSelectedRole() ?: ""

Expand All @@ -91,16 +101,31 @@ class ResqService(appContext: Context) {
)
}

// Resource methods
suspend fun createResource(request: CreateResourceRequestBody): Response<Int> {
val userId = userSessionManager.getUserId()
val token = userSessionManager.getUserToken() ?: ""
// val selectedRole = userSessionManager.getSelectedRole() ?: ""

request.senderId = userId

return resourceService.createResource(
jwtToken = "Bearer $token",
role = "RESPONDER",
requestBody = request
)
}

// Need methods
suspend fun createNeed(request: CreateNeedRequestBody): Response<Int> {
val userId = userSessionManager.getUserId()
val token = userSessionManager.getUserToken() ?: ""
val selectedRole = userSessionManager.getSelectedRole() ?: ""
// val selectedRole = userSessionManager.getSelectedRole() ?: ""

return needService.createNeed(
userId = userId,
jwtToken = "Bearer $token",
role = selectedRole,
role = "VICTIM",
requestBody = request
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.cmpe451.resq.ui.views.components

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

@Composable
fun <T> DropdownMenuComponent(
label: String,
items: List<T>,
selectedItem: T,
itemToString: (T) -> String,
onItemSelected: (T) -> Unit
) {
var expandState by remember { mutableStateOf(false) }
Box(modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.Start)
) {
OutlinedTextField(
value = itemToString(selectedItem),
onValueChange = {},
label = { Text(label) },
readOnly = true,
modifier = Modifier
.fillMaxWidth()
.clickable { expandState = true },
trailingIcon = {
Icon(
imageVector = if (expandState) Icons.Filled.KeyboardArrowUp else Icons.Filled.KeyboardArrowDown,
contentDescription = "Dropdown Icon",
modifier = Modifier.clickable { expandState = !expandState }
)
}
)
DropdownMenu(
expanded = expandState,
onDismissRequest = { expandState = false },
modifier = Modifier
.fillMaxWidth()
) {
items.forEach { item ->
DropdownMenuItem(onClick = {
onItemSelected(item)
expandState = false
}) {
Text(text = itemToString(item))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,24 @@ package com.cmpe451.resq.ui.views.screens

import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
Expand All @@ -42,9 +36,10 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.cmpe451.resq.data.models.CategoryNode
import com.cmpe451.resq.data.models.CategoryTreeNode
import com.cmpe451.resq.ui.theme.LightGreen
import com.cmpe451.resq.ui.theme.RequestColor
import com.cmpe451.resq.ui.views.components.DropdownMenuComponent
import com.cmpe451.resq.viewmodels.RequestViewModel

@Composable
Expand Down Expand Up @@ -100,7 +95,7 @@ fun RequestScreen(
DropdownMenuComponent(
label = "Category",
items = categories,
selectedItem = selectedCategoryState.value ?: CategoryNode(-1, "Select a Category", emptyList()),
selectedItem = selectedCategoryState.value ?: CategoryTreeNode(-1, "Select a Category", emptyList()),
itemToString = { it.data },
onItemSelected = { category ->
viewModel.updateCategory(category)
Expand All @@ -112,7 +107,7 @@ fun RequestScreen(
DropdownMenuComponent(
label = "Type",
items = viewModel.types.value,
selectedItem = viewModel.selectedType.value ?: CategoryNode(-1, "Select a Type", emptyList()),
selectedItem = viewModel.selectedType.value ?: CategoryTreeNode(-1, "Select a Type", emptyList()),
itemToString = { it.data },
onItemSelected = { type ->
viewModel.updateType(type)
Expand All @@ -125,7 +120,7 @@ fun RequestScreen(
DropdownMenuComponent(
label = "Item",
items = viewModel.items.value,
selectedItem = viewModel.selectedItem.value ?: CategoryNode(-1, "Select an Item", emptyList()),
selectedItem = viewModel.selectedItem.value ?: CategoryTreeNode(-1, "Select an Item", emptyList()),
itemToString = { it.data },
onItemSelected = { item ->
viewModel.updateItem(item)
Expand Down Expand Up @@ -176,50 +171,3 @@ fun RequestScreen(
SnackbarHost(hostState = snackbarHostState)
}
}

@Composable
fun <T> DropdownMenuComponent(
label: String,
items: List<T>,
selectedItem: T,
itemToString: (T) -> String,
onItemSelected: (T) -> Unit
) {
var expandState by remember { mutableStateOf(false) }
Box(modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.Start)
) {
OutlinedTextField(
value = itemToString(selectedItem),
onValueChange = {},
label = { Text(label) },
readOnly = true,
modifier = Modifier
.fillMaxWidth()
.clickable { expandState = true },
trailingIcon = {
Icon(
imageVector = if (expandState) Icons.Filled.KeyboardArrowUp else Icons.Filled.ArrowDropDown,
contentDescription = "Dropdown Icon",
modifier = Modifier.clickable { expandState = !expandState }
)
}
)
DropdownMenu(
expanded = expandState,
onDismissRequest = { expandState = false },
modifier = Modifier
.fillMaxWidth()
) {
items.forEach { item ->
DropdownMenuItem(onClick = {
onItemSelected(item)
expandState = false
}) {
Text(text = itemToString(item))
}
}
}
}
}
Loading

0 comments on commit 3e90d6b

Please sign in to comment.