...
This commit is contained in:
@@ -11,6 +11,8 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
@@ -23,15 +25,62 @@ import androidx.compose.ui.unit.sp
|
||||
import model.ConfigIndex
|
||||
import model.KisSession
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun TradingDecisionLog() {
|
||||
var searchQuery by remember { mutableStateOf("") }
|
||||
var selectedFilter by remember { mutableStateOf("전체") }
|
||||
val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING")
|
||||
|
||||
// [핵심] 원본 로그에서 필터 조건에 맞는 리스트만 산출
|
||||
val filteredLogs = TradingLogStore.decisionLogs.filter { log ->
|
||||
val matchesType = if (selectedFilter == "전체") true else log.decision == selectedFilter
|
||||
val matchesQuery = log.stockName.contains(searchQuery, ignoreCase = true) ||
|
||||
log.reason.contains(searchQuery, ignoreCase = true)
|
||||
matchesType && matchesQuery
|
||||
}
|
||||
|
||||
Row(modifier = Modifier.fillMaxSize().background(Color(0xFFF2F2F2))) {
|
||||
Column(modifier = Modifier.weight(0.5f).padding(8.dp).fillMaxHeight().background(Color.White)) {
|
||||
Text("AI 자동매매 실시간 로그", style = MaterialTheme.typography.h6)
|
||||
Divider(Modifier.padding(vertical = 8.dp))
|
||||
|
||||
LazyColumn(reverseLayout = true) { // 최신 로그가 위로 오게 함
|
||||
items(TradingLogStore.decisionLogs) { log ->
|
||||
// [추가] 상단 검색 및 필터 UI
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
// 1. 검색창
|
||||
OutlinedTextField(
|
||||
value = searchQuery,
|
||||
onValueChange = { searchQuery = it },
|
||||
label = { Text("종목명 또는 내용 검색") },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
|
||||
singleLine = true
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// 2. 필터 버튼 그룹 (Chip 형태)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
filterOptions.forEach { option ->
|
||||
val isSelected = selectedFilter == option
|
||||
FilterChip(
|
||||
selected = isSelected,
|
||||
onClick = { selectedFilter = option },
|
||||
colors = ChipDefaults.filterChipColors(
|
||||
selectedBackgroundColor = Color(0xFF0E62CF),
|
||||
selectedContentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text(option, fontSize = 11.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Divider(Modifier.padding(bottom = 8.dp))
|
||||
|
||||
// [수정] filteredLogs를 사용하여 최신 로그가 위로 오게 표시
|
||||
LazyColumn(reverseLayout = true) {
|
||||
items(filteredLogs) { log ->
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
|
||||
elevation = 2.dp
|
||||
@@ -43,10 +92,10 @@ fun TradingDecisionLog() {
|
||||
text = log.decision,
|
||||
color = when (log.decision) {
|
||||
"BUY" -> Color.Red
|
||||
"SETTING" -> Color(0xFFFFA500) // 주황색
|
||||
"SELL" -> Color(0xFF800080) // 보라색
|
||||
"HOLD" -> Color.Gray // HOLD는 그레이
|
||||
else -> Color.Gray // 그 외 기본값 그레이
|
||||
"SETTING" -> Color(0xFFFFA500)
|
||||
"SELL" -> Color(0xFF800080)
|
||||
"HOLD" -> Color.Gray
|
||||
else -> Color.Gray
|
||||
},
|
||||
fontWeight = FontWeight.ExtraBold
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user