Web admin app loads list of players

This commit is contained in:
2026-08-25 10:10:47 -04:00
parent d62575df16
commit d1ef2956d8
12 changed files with 178 additions and 44 deletions
@@ -0,0 +1,38 @@
package dev.geekback.dopewars.web
import dev.geekback.dopewars.shared.Player
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.get
import io.ktor.http.ContentType
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
object AdminApi {
var baseUrl: String = "http://localhost:8080"
private val client = HttpClient {
install(ContentNegotiation) {
json(
Json {
allowSpecialFloatingPointValues = true
ignoreUnknownKeys = true
prettyPrint = true
isLenient = true
})
}
}
fun setBaseUrl(baseUrl: String) {
this.baseUrl = baseUrl
}
suspend fun loadPlayers(): List<Player> {
val response = this.client.get("${this.baseUrl}/players") {
contentType(ContentType.Application.Json)
}
return response.body()
}
}
@@ -0,0 +1,37 @@
package dev.geekback.dopewars.web
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
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
@Composable
fun ApiControlBox(onUrlUpdate: (String) -> Unit) {
var localUrl by remember { mutableStateOf("http://localhost:8080") }
var visible by remember { mutableStateOf(true) }
Card {
Column {
Button(onClick = {
visible != visible
}) {
Text("API Config")
}
TextField(value = AdminApi.baseUrl, onValueChange = {
localUrl = it
})
Button(onClick = {
onUrlUpdate(localUrl)
}) {
Text("Apply")
}
}
}
}
@@ -0,0 +1,53 @@
package dev.geekback.dopewars.web
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import dev.geekback.dopewars.shared.Player
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun App() {
val scope = rememberCoroutineScope()
var players by mutableStateOf (listOf<Player>())
MaterialTheme {
Scaffold(
modifier = Modifier.padding(16.dp),
content = {
Column {
// List of current Players
Button(onClick = {
println("Reload Players Now")
scope.launch {
players = AdminApi.loadPlayers()
}
}) {
Text("Reload Players")
}
ApiControlBox {
println("Setting API BaseUrl to $it")
AdminApi.setBaseUrl(it)
}
PlayersList(players) {
println("Click on $it")
}
}
}
)
}
}
@@ -0,0 +1,28 @@
package dev.geekback.dopewars.web
import androidx.compose.foundation.clickable
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import dev.geekback.dopewars.shared.Player
@Composable
fun PlayersList(players: List<Player>, onPLayerSelected: (Player) -> Unit) {
Card {
Text("Current Players")
LazyColumn {
if (players.isEmpty()) {
items(1) {
Text("No Players.")
}
} else {
items(players.size) { i ->
val item = players[i];
Text("Player ${item.name}", modifier = Modifier.clickable { onPLayerSelected(item) })
}
}
}
}
}
@@ -1,12 +1,6 @@
package dev.geekback.dopewars.web
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ComposeViewport
@OptIn(ExperimentalComposeUiApi::class)
@@ -15,10 +9,3 @@ fun main() {
App()
}
}
@Composable
fun App() {
MaterialTheme {
Text(modifier = Modifier.padding(16.dp), text = "Taxation is theft")
}
}