Updated Proper User Api
This commit is contained in:
parent
1277ae09b6
commit
80cc72bb9d
|
|
@ -217,6 +217,55 @@ class AuthApiClient(private val context: Context) {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test API: Get user by ID from BuySellService (port 3200)
|
||||||
|
suspend fun getUserById(userId: String, baseUrl: String = "http://10.0.2.2:3200"): Result<String> = runCatching {
|
||||||
|
android.util.Log.d("AuthApiClient", "getUserById: Calling $baseUrl/users/$userId")
|
||||||
|
|
||||||
|
// Create a separate client for this external service call
|
||||||
|
HttpClient(CIO) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json(Json {
|
||||||
|
prettyPrint = true
|
||||||
|
isLenient = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
install(Auth) {
|
||||||
|
bearer {
|
||||||
|
loadTokens {
|
||||||
|
val accessToken = tokenManager.getAccessToken()
|
||||||
|
if (accessToken != null) {
|
||||||
|
BearerTokens(accessToken, "")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultRequest {
|
||||||
|
url(baseUrl)
|
||||||
|
}
|
||||||
|
}.use { testClient ->
|
||||||
|
val response = testClient.get("users/$userId")
|
||||||
|
android.util.Log.d("AuthApiClient", "getUserById: Response status=${response.status}")
|
||||||
|
|
||||||
|
if (response.status.isSuccess()) {
|
||||||
|
// Get raw JSON string
|
||||||
|
val jsonString = response.bodyAsText()
|
||||||
|
android.util.Log.d("AuthApiClient", "getUserById: Success - JSON=${jsonString.take(200)}...")
|
||||||
|
jsonString
|
||||||
|
} else {
|
||||||
|
val errorText = try {
|
||||||
|
response.bodyAsText()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"Error reading response body"
|
||||||
|
}
|
||||||
|
android.util.Log.e("AuthApiClient", "getUserById: Error - status=${response.status}, body=$errorText")
|
||||||
|
throw Exception("API call failed: ${response.status} - $errorText")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getDeviceInfo(): DeviceInfo {
|
private fun getDeviceInfo(): DeviceInfo {
|
||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
platform = "android",
|
platform = "android",
|
||||||
|
|
|
||||||
|
|
@ -4,28 +4,24 @@ import android.widget.Toast
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.automirrored.filled.Logout
|
import androidx.compose.material.icons.automirrored.filled.Logout
|
||||||
import androidx.compose.material.icons.filled.Construction
|
import androidx.compose.material.icons.filled.Construction
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.example.livingai_lg.api.AuthApiClient
|
import com.example.livingai_lg.api.AuthApiClient
|
||||||
import com.example.livingai_lg.api.AuthManager
|
import com.example.livingai_lg.api.AuthManager
|
||||||
import com.example.livingai_lg.api.TokenManager
|
import com.example.livingai_lg.api.TokenManager
|
||||||
|
|
@ -41,6 +37,12 @@ fun AccountsScreen(
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val authManager = remember { AuthManager(context, AuthApiClient(context), TokenManager(context)) }
|
val authManager = remember { AuthManager(context, AuthApiClient(context), TokenManager(context)) }
|
||||||
|
val apiClient = remember { AuthApiClient(context) }
|
||||||
|
|
||||||
|
// State for API test dialog
|
||||||
|
var showApiResultDialog by remember { mutableStateOf(false) }
|
||||||
|
var apiResultJson by remember { mutableStateOf<String?>(null) }
|
||||||
|
var isLoading by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -130,7 +132,44 @@ fun AccountsScreen(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth().padding(vertical = 12.dp)
|
.fillMaxWidth().padding(vertical = 12.dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
onApiTest()
|
// Call API test directly instead of navigating
|
||||||
|
scope.launch {
|
||||||
|
isLoading = true
|
||||||
|
try {
|
||||||
|
// First get current user's ID
|
||||||
|
val userDetails = apiClient.getUserDetails().getOrNull()
|
||||||
|
if (userDetails != null) {
|
||||||
|
// Call GET /users/:userId on port 3200
|
||||||
|
val result = apiClient.getUserById(userDetails.id, "http://10.0.2.2:3200")
|
||||||
|
result.onSuccess { jsonString ->
|
||||||
|
apiResultJson = jsonString
|
||||||
|
showApiResultDialog = true
|
||||||
|
isLoading = false
|
||||||
|
}.onFailure { error ->
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
"API Test Failed: ${error.message}",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
"Failed to get user details",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
"Error: ${e.message}",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(12.dp),
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
|
|
@ -147,14 +186,21 @@ fun AccountsScreen(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
Icon(
|
if (isLoading) {
|
||||||
imageVector = Icons.Default.Construction,
|
CircularProgressIndicator(
|
||||||
contentDescription = "Api test",
|
modifier = Modifier.size(24.dp),
|
||||||
tint = Color.Gray,
|
strokeWidth = 2.dp
|
||||||
modifier = Modifier.size(24.dp)
|
)
|
||||||
)
|
} else {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Construction,
|
||||||
|
contentDescription = "Api test",
|
||||||
|
tint = Color.Gray,
|
||||||
|
modifier = Modifier.size(24.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
Text(
|
Text(
|
||||||
text = "Test API",
|
text = if (isLoading) "Testing API..." else "Test API",
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
color = Color.Gray
|
color = Color.Gray
|
||||||
|
|
@ -164,5 +210,88 @@ fun AccountsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API Result Dialog
|
||||||
|
if (showApiResultDialog) {
|
||||||
|
Dialog(onDismissRequest = { showApiResultDialog = false }) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.fillMaxHeight(0.8f)
|
||||||
|
.padding(16.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
color = Color.White
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
// Dialog Header
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "API Test Result",
|
||||||
|
fontSize = 20.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.Black
|
||||||
|
)
|
||||||
|
IconButton(onClick = { showApiResultDialog = false }) {
|
||||||
|
Text(
|
||||||
|
text = "✕",
|
||||||
|
fontSize = 20.sp,
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// JSON Content
|
||||||
|
apiResultJson?.let { json ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = json,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color.Black,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "No result",
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close Button
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Button(
|
||||||
|
onClick = { showApiResultDialog = false },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
) {
|
||||||
|
Text("Close")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue