package com.peachpasswords.ui.vault import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.peachpasswords.ui.theme.LocalPeachAccent import com.peachpasswords.ui.theme.peachColors import com.peachpasswords.ui.theme.PeachType /** * D2 — EntryEdit CARD field block. Self-contained: drop a single call to * [CardEditFields] in place of the login fields when `f.type == "card"`. * * Mirrors the existing private `Field` underline style in EntryEditScreen.kt * (1.dp T3 border, mono 13sp, accent cursor). Includes its own label+box * primitive (`CardField`) so it does not depend on that file's private members. * * Network is detected live from the card number; CVC maxLength + PAN grouping * follow the detected network (Amex 15/4, others 16/3). */ @Composable fun CardEditFields( cardNickname: String, cardNumber: String, cardholderName: String, expiry: String, cvc: String, showCvc: Boolean, network: String, onCardNickname: (String) -> Unit, onCardNumber: (String) -> Unit, onCardholder: (String) -> Unit, onExpiry: (String) -> Unit, onCvc: (String) -> Unit, onToggleShowCvc: () -> Unit, ) { PeachField( label = "nickname", value = cardNickname, onChange = onCardNickname, mono = false, ) // CARD NUMBER — auto-formatted, network label beside the label. PeachField( label = "card number", value = cardNumber, onChange = { raw -> onCardNumber(CardFieldUtils.formatPan(raw)) }, keyboardType = KeyboardType.Number, labelTrailing = { val net = CardFieldUtils.networkLabel(network) if (net.isNotEmpty()) { Text(net, color = peachColors.T2, fontFamily = PeachType.Mono, fontSize = 9.sp) } }, ) // CARDHOLDER — Inter body, not mono. PeachField( label = "cardholder", value = cardholderName, onChange = onCardholder, mono = false, ) // EXPIRY — browser-style split MM / YYYY fields. Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { PeachField( label = "expiry mm", value = CardFieldUtils.expiryMonth(expiry), onChange = { raw -> onExpiry(CardFieldUtils.combineExpiry(raw, CardFieldUtils.expiryYear(expiry))) }, keyboardType = KeyboardType.Number, modifier = Modifier.weight(1f), ) PeachField( label = "expiry year", value = CardFieldUtils.expiryYear(expiry), onChange = { raw -> onExpiry(CardFieldUtils.combineExpiry(CardFieldUtils.expiryMonth(expiry), raw)) }, keyboardType = KeyboardType.Number, modifier = Modifier.weight(1f), ) } // CVC — masked by default, eye toggle, maxLength by network. val cvcMax = CardFieldUtils.cvcMaxDigits(network) PeachField( label = "cvc", value = cvc, onChange = { raw -> onCvc(raw.filter { it.isDigit() }.take(cvcMax)) }, keyboardType = KeyboardType.NumberPassword, visualTransformation = if (showCvc) VisualTransformation.None else PasswordVisualTransformation(), trailing = { Text( if (showCvc) "hide" else "show", color = LocalPeachAccent.current, fontFamily = PeachType.Mono, fontSize = 9.sp, modifier = Modifier.clip(RoundedCornerShape(6.dp)).clickable(onClick = onToggleShowCvc).padding(6.dp), ) }, ) }