Files
nomadic-weather/gui/shared/src/LocationEditor.kt
T

141 lines
5.3 KiB
Kotlin

package com.hyperling.weather
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Cancel
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
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.unit.dp
import androidx.compose.ui.unit.sp
/**
* Dialog component for adding or editing a location.
*/
@Composable
fun LocationEditor(
entry: LocationEntry?,
onDismiss: () -> Unit,
onSave: (LocationEntry) -> Unit,
) {
var zip by androidx.compose.runtime.mutableStateOf(entry?.zipCode ?: "")
var lat by androidx.compose.runtime.mutableStateOf(if (entry != null && entry.latitude != 0.0) entry.latitude.toString() else "")
var lon by androidx.compose.runtime.mutableStateOf(if (entry != null && entry.longitude != 0.0) entry.longitude.toString() else "")
val isEdit = entry != null
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.fillMaxWidth(0.8f)
.background(Color.White, RoundedCornerShape(16.dp))
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = if (isEdit) "Edit Location" else "Add Location",
fontWeight = FontWeight.Bold,
fontSize = 20.sp,
color = SeasonColors.TextPrimary
)
Spacer(modifier = Modifier.size(16.dp))
// Nickname / Zip Code input
TextField(
value = zip,
onValueChange = { zip = it },
label = { Text("Zip Code or Place Name") },
modifier = Modifier.fillMaxWidth(),
placeholder = { Text("e.g. 90210 or London") }
)
Spacer(modifier = Modifier.size(8.dp))
// Latitude / Longitude (Advanced)
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.fillMaxWidth()
) {
TextField(
value = lat,
onValueChange = { lat = it },
label = { Text("Latitude") },
modifier = Modifier.weight(1f)
)
TextField(
value = lon,
onValueChange = { lon = it },
label = { Text("Longitude") },
modifier = Modifier.weight(1f)
)
}
Spacer(modifier = Modifier.size(24.dp))
// Actions
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier.fillMaxWidth()
) {
IconButton(onClick = onDismiss) {
Icon(Icons.Default.Cancel, contentDescription = "Cancel", tint = SeasonColors.TextSecondary)
}
androidx.compose.material3.Button(
onClick = {
// Parse inputs to create/update LocationEntry
val latParsed = lat.toDoubleOrNull() ?: 0.0
val lonParsed = lon.toDoubleOrNull() ?: 0.0
onSave(
LocationEntry(
id = entry?.id ?: System.currentTimeMillis(),
zipCode = zip,
latitude = latParsed,
longitude = lonParsed,
nickname = zip, // Default nickname is the input string
lastUpdated = entry?.lastUpdated ?: 0L
)
)
},
enabled = zip.isNotBlank() || lat != "0.0" || lon != "0.0"
) {
Icon(Icons.Default.Check, contentDescription = "Save")
androidx.compose.material3.Text("Save", modifier = Modifier.padding(start = 4.dp))
}
}
}
// Backdrop / Overlay to dismiss
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.5f))
.clickable { onDismiss() }
) {}
}
}