From 43ad32ba8a68bccbdde1c3dd9055a87b9cfb141c Mon Sep 17 00:00:00 2001 From: jjangddu Date: Fri, 10 Jul 2026 11:52:37 +0900 Subject: [PATCH] =?UTF-8?q?refactor(ui):=20Design=20Token=20=EC=A4=91?= =?UTF-8?q?=EC=95=99=ED=99=94=20+=20AlertModalDialog=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=ED=99=94=20(Step=201~3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 초 고수 앱 디자이너 코드 리뷰 결과 반영. 저비용/저리스크 항목만 우선 진행, 대형 파일 분해 등은 별도 로드맵. Step 1: Design Token (Color.kt + Theme.kt) - Color.kt 에 semantic token 추가: MlCritical / MlWarning / MlSuccess / MlInfo / MlNeutral / MlAccentPurple + ContainerAlpha / ChipAlpha 상수 - Theme.kt LightColorScheme 를 Purple40 → MlPrimary 로 override. 기존에는 Material3 default 가 Purple 이라 Button 등 커스텀 UI 와 색상 불일치 발생. brand 통일. Step 2: AlertModalDialog 컴포넌트화 (ui/components/AlertModalDialog.kt) - 3개 알람 다이얼로그 (Wakeup 주황, Walking 빨강, Detach 주황) 가 100% 동일 구조 (배경색만 다름) 로 각각 40~50줄 반복. - 재사용 가능한 AlertModalDialog(backgroundColor, icon, title, subtitle, detail, confirmLabel, onConfirm, widthFraction, iconSize, titleSize, dismissible) 로 통합. - dismissible=false 가 default (의료 알람은 사용자 명시 확인 필요). - PiezoMonitoringView (Wakeup + Walking) / PlacementGuideView (Detach) 3곳 모두 새 컴포넌트로 교체. 코드량 ~120줄 감소. Step 3: LabdbAutoRetry 배너 semantic token 적용 - ClinicalHomeView 자동 업로드 배너의 Color(0xFF1976D2) → MlInfo, Color(0xFFFF9800) → MlWarning, Color(0xFF4CAF50) → MlSuccess. - ChipAlpha (0.12f) 로 배경 alpha 통일. 효과: - 신규 배너/Dialog 는 반드시 semantic token 사용 → 색상 일관성 관리 용이. - 색상 변경 시 Color.kt 한 파일만 수정하면 전역 반영. - AlertModalDialog 로 신규 알람 추가 시 10~15줄로 가능 (이전 50줄+). 미완료 (별도 로드맵): - 기존 파일의 나머지 매직 hex 색상 (~300개) → semantic token 마이그레이션. 광범위 변경 + 실기 회귀 위험 있어 순차 진행 필요. - 대형 파일 분해 (PiezoMonitoringView 2900L, PlacementGuideView 2200L). - ViewModel 도입, BLE 콜백 → Flow 이전. Co-Authored-By: Claude Opus 4.7 --- .../ui/components/AlertModalDialog.kt | 139 ++++++++++++++++++ .../com/medithings/vesiscan/ui/theme/Color.kt | 28 +++- .../com/medithings/vesiscan/ui/theme/Theme.kt | 20 ++- .../ui/views/clinical/ClinicalHomeView.kt | 15 +- .../views/monitoring/PiezoMonitoringView.kt | 112 +++----------- .../ui/views/monitoring/PlacementGuideView.kt | 54 ++----- 6 files changed, 222 insertions(+), 146 deletions(-) create mode 100644 app/src/main/java/com/medithings/vesiscan/ui/components/AlertModalDialog.kt diff --git a/app/src/main/java/com/medithings/vesiscan/ui/components/AlertModalDialog.kt b/app/src/main/java/com/medithings/vesiscan/ui/components/AlertModalDialog.kt new file mode 100644 index 0000000..dc51ecb --- /dev/null +++ b/app/src/main/java/com/medithings/vesiscan/ui/components/AlertModalDialog.kt @@ -0,0 +1,139 @@ +package com.medithings.vesiscan.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties + +/** + * 전면 모달 알람 다이얼로그 — semantic 배경색 위 아이콘/타이틀/서브/설명 + 확인 버튼. + * + * 통합 대상 (2026-07-10): + * - Wakeup Alarm (주황, LYING → NON_LYING/WALKING 전이) + * - Walking Alarm (빨강, WALKING 전이 즉시 낙상 경고) + * - Detach Alert (주황, 센서 분리) + * + * 사용 예: + * ``` + * if (showWakeupAlarm) { + * AlertModalDialog( + * backgroundColor = MlWarning, + * icon = Icons.Default.WbSunny, + * title = stringResource(R.string.wakeup_detected_title), + * subtitle = stringResource(R.string.wakeup_safely_get_up), + * detail = stringResource(R.string.alarm_lying_duration, mins, secs), + * onConfirm = { showWakeupAlarm = false }, + * ) + * } + * ``` + * + * 접근성: + * - 기본은 `dismissOnBackPress = false / dismissOnClickOutside = false` + * (의료 알람은 사용자 명시적 확인 필요). 필요 시 [dismissible]=true 로 override. + */ +@Composable +fun AlertModalDialog( + backgroundColor: Color, + icon: ImageVector, + title: String, + subtitle: String? = null, + detail: String? = null, + confirmLabel: String, + onConfirm: () -> Unit, + widthFraction: Float = 0.92f, + iconSize: androidx.compose.ui.unit.Dp = 56.dp, + titleSize: androidx.compose.ui.unit.TextUnit = 28.sp, + dismissible: Boolean = false, +) { + Dialog( + onDismissRequest = { if (dismissible) onConfirm() }, + properties = DialogProperties( + dismissOnBackPress = dismissible, + dismissOnClickOutside = dismissible, + ) + ) { + Box( + modifier = Modifier + .fillMaxWidth(widthFraction) + .clip(RoundedCornerShape(24.dp)) + .background(backgroundColor) + .padding(horizontal = 28.dp, vertical = 36.dp), + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Icon( + imageVector = icon, + contentDescription = null, + tint = Color.White, + modifier = Modifier.size(iconSize), + ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = title, + fontSize = titleSize, + fontWeight = FontWeight.ExtraBold, + color = Color.White, + textAlign = TextAlign.Center, + ) + if (subtitle != null) { + Spacer(modifier = Modifier.height(6.dp)) + Text( + text = subtitle, + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + color = Color.White.copy(alpha = 0.9f), + textAlign = TextAlign.Center, + ) + } + if (detail != null) { + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = detail, + fontSize = 14.sp, + color = Color.White.copy(alpha = 0.85f), + textAlign = TextAlign.Center, + ) + } + Spacer(modifier = Modifier.height(24.dp)) + Button( + onClick = onConfirm, + colors = ButtonDefaults.buttonColors( + containerColor = Color.White, + contentColor = backgroundColor, + ), + modifier = Modifier + .fillMaxWidth() + .height(56.dp), + shape = RoundedCornerShape(14.dp), + ) { + Text( + text = confirmLabel, + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + ) + } + } + } + } +} diff --git a/app/src/main/java/com/medithings/vesiscan/ui/theme/Color.kt b/app/src/main/java/com/medithings/vesiscan/ui/theme/Color.kt index 563572d..0d9eedd 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/theme/Color.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/theme/Color.kt @@ -2,7 +2,7 @@ package com.medithings.vesiscan.ui.theme import androidx.compose.ui.graphics.Color -// Material theme colors +// Material theme colors (legacy — Material3 template default. 실사용 X, LightColorScheme 를 MlPrimary 로 override.) val Purple80 = Color(0xFFD0BCFF) val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) @@ -10,7 +10,7 @@ val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) -// MediLight theme colors +// ─────────── Brand colors ─────────── val MlPrimary = Color(0xFF008FFF) val MlTeal = Color(0xFF00DB9F) val MlBackground = Color(0xFFF5F8FF) @@ -18,3 +18,27 @@ val MlCardBackground = Color.White val MlSecondaryText = Color(0xFF80808C) val MlInputBackground = Color(0xFFF5F8FF) val MlInputBorder = Color(0xFF00DB9F) + +// ─────────── Semantic tokens (2026-07-10) ─────────── +// 매직 hex 코드가 각 파일에 흩어져 있어 일관성 관리 어려움 → semantic 이름으로 통일. +// 새 UI 코드는 반드시 아래 토큰을 사용. 기존 코드는 점진적으로 마이그레이션. + +/** Critical / danger — 위치 놓침, 기기 응답 없음, 낙상 위험, walking alarm 등. */ +val MlCritical = Color(0xFFD32F2F) +/** Warning — 배터리 낮음, firmware 구버전, mtb 응답 지연, 자동 업로드 일부 실패, wakeup 알람 등. */ +val MlWarning = Color(0xFFFF9800) +/** Success — GREEN zone, 정렬 완료, 자동 업로드 성공, NON_LYING posture chip 등. */ +val MlSuccess = Color(0xFF4CAF50) +/** Info — 자동 업로드 진행 중, "확인 중" 등의 중립 정보. */ +val MlInfo = Color(0xFF1976D2) +/** Neutral — UNKNOWN posture, disable 상태의 회색 아이콘 등. */ +val MlNeutral = Color(0xFF616161) +/** Purple accent — dev toggle, alignment algo selector 등 dev 전용 UI. */ +val MlAccentPurple = Color(0xFF7C3AED) + +/** Container / background alpha helpers. + * 카드/배너 배경으로 semantic 색 사용 시 알파 12~15% 가 일관적. + * 사용 예: `MlWarning.copy(alpha = ContainerAlpha)`. */ +const val ContainerAlpha = 0.15f +/** 배지/inline 강조 (chip 배경 등). */ +const val ChipAlpha = 0.12f diff --git a/app/src/main/java/com/medithings/vesiscan/ui/theme/Theme.kt b/app/src/main/java/com/medithings/vesiscan/ui/theme/Theme.kt index 544080d..f597429 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/theme/Theme.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/theme/Theme.kt @@ -3,21 +3,25 @@ package com.medithings.vesiscan.ui.theme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +// 2026-07-10: Purple40 기반 Material3 default 를 MediLight 브랜드 색상으로 override. +// 기존에는 colorScheme.primary = Purple40 (Material 템플릿 기본) 이지만 실제 UI 는 +// MlPrimary 사용 → MaterialTheme 를 참조하는 default 컴포넌트 (예: Button 배경) 와 +// 커스텀 UI 사이에 색상 불일치 발생했음. brand 색상으로 통일. private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), + primary = MlPrimary, onPrimary = Color.White, + secondary = MlTeal, onSecondary = Color.White, + tertiary = MlAccentPurple, onTertiary = Color.White, + background = MlBackground, onBackground = Color(0xFF1C1B1F), + surface = MlCardBackground, onSurface = Color(0xFF1C1B1F), - */ + error = MlCritical, + onError = Color.White, ) @Composable diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/ClinicalHomeView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/ClinicalHomeView.kt index 8e176b5..19d4e6b 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/ClinicalHomeView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/ClinicalHomeView.kt @@ -144,25 +144,28 @@ fun ClinicalHomeView(appState: AppState) { // 2026-07-09: 자동 업로드 진행/결과 배너. if (autoUploadPending > 0 || autoUploadingName != null) { + // 2026-07-10: semantic token 사용 (MlInfo = 진행 중 파랑). Row( modifier = Modifier.fillMaxWidth() .clip(RoundedCornerShape(10.dp)) - .background(Color(0xFF1976D2).copy(alpha = 0.12f)) + .background(com.medithings.vesiscan.ui.theme.MlInfo.copy( + alpha = com.medithings.vesiscan.ui.theme.ChipAlpha)) .padding(horizontal = 12.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically ) { CircularProgressIndicator( modifier = Modifier.size(16.dp), strokeWidth = 2.dp, - color = Color(0xFF1976D2) + color = com.medithings.vesiscan.ui.theme.MlInfo ) Spacer(Modifier.width(10.dp)) Column { Text("자동 업로드 진행 중 · 남은 세션 $autoUploadPending", fontSize = 13.sp, fontWeight = FontWeight.SemiBold, - color = Color(0xFF1976D2)) + color = com.medithings.vesiscan.ui.theme.MlInfo) autoUploadingName?.let { - Text(it, fontSize = 11.sp, color = Color(0xFF1976D2).copy(alpha = 0.8f), + Text(it, fontSize = 11.sp, + color = com.medithings.vesiscan.ui.theme.MlInfo.copy(alpha = 0.8f), maxLines = 1) } } @@ -171,7 +174,9 @@ fun ClinicalHomeView(appState: AppState) { } else if (autoUploadResult != null) { val msg = autoUploadResult ?: "" val hasFail = msg.contains("failed") - val bg = if (hasFail) Color(0xFFFF9800) else Color(0xFF4CAF50) + // 2026-07-10: semantic token 사용 (MlWarning 실패 / MlSuccess 완료). + val bg = if (hasFail) com.medithings.vesiscan.ui.theme.MlWarning + else com.medithings.vesiscan.ui.theme.MlSuccess Row( modifier = Modifier.fillMaxWidth() .clip(RoundedCornerShape(10.dp)) diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PiezoMonitoringView.kt index 791264e..d940cc2 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PiezoMonitoringView.kt @@ -156,99 +156,35 @@ fun PiezoMonitoringView(appState: AppState) { // 직전 walking 상태 추적 — false → true 전이 시 critical 알람 var prevIsWalking by remember { mutableStateOf(false) } // Wakeup alarm (warning, 주황) — LYING → NON_LYING/WALKING 전이 + // 2026-07-10: 3개 알람 Dialog 를 AlertModalDialog 로 통합 (ui/components/AlertModalDialog.kt). if (showWakeupAlarm) { - androidx.compose.ui.window.Dialog( - onDismissRequest = { }, - properties = androidx.compose.ui.window.DialogProperties( - dismissOnBackPress = false, dismissOnClickOutside = false - ) - ) { - Box( - modifier = Modifier - .fillMaxWidth(0.92f) - .clip(RoundedCornerShape(24.dp)) - .background(Color(0xFFFF9800)) // Material Orange 500 - .padding(horizontal = 28.dp, vertical = 36.dp), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon(Icons.Default.Warning, contentDescription = null, - tint = Color.White, modifier = Modifier.size(56.dp)) - Spacer(modifier = Modifier.height(12.dp)) - Text(stringResource(R.string.alarm_patient_woke_up), fontSize = 28.sp, - fontWeight = FontWeight.ExtraBold, color = Color.White, - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(6.dp)) - Text(stringResource(R.string.alarm_patient_woke_up_en), fontSize = 16.sp, - fontWeight = FontWeight.Medium, color = Color.White.copy(alpha = 0.9f), - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(8.dp)) - val mins = wakeupAlarmElapsedSec / 60 - val secs = wakeupAlarmElapsedSec % 60 - Text(stringResource(R.string.alarm_lying_duration, mins, secs), - fontSize = 14.sp, color = Color.White.copy(alpha = 0.85f)) - Spacer(modifier = Modifier.height(24.dp)) - Button( - onClick = { showWakeupAlarm = false }, - colors = ButtonDefaults.buttonColors( - containerColor = Color.White, contentColor = Color(0xFFFF9800) - ), - modifier = Modifier.fillMaxWidth().height(56.dp), - shape = RoundedCornerShape(14.dp) - ) { - Text(stringResource(R.string.confirm), fontSize = 20.sp, fontWeight = FontWeight.Bold) - } - } - } - } + val mins = wakeupAlarmElapsedSec / 60 + val secs = wakeupAlarmElapsedSec % 60 + com.medithings.vesiscan.ui.components.AlertModalDialog( + backgroundColor = com.medithings.vesiscan.ui.theme.MlWarning, + icon = Icons.Default.Warning, + title = stringResource(R.string.alarm_patient_woke_up), + subtitle = stringResource(R.string.alarm_patient_woke_up_en), + detail = stringResource(R.string.alarm_lying_duration, mins, secs), + confirmLabel = stringResource(R.string.confirm), + onConfirm = { showWakeupAlarm = false }, + ) } // Walking alarm (critical, 빨강) — NON_LYING/LYING → WALKING 전이 (보행 시작) if (showWalkingAlarm) { - androidx.compose.ui.window.Dialog( - onDismissRequest = { }, - properties = androidx.compose.ui.window.DialogProperties( - dismissOnBackPress = false, dismissOnClickOutside = false - ) - ) { - Box( - modifier = Modifier - .fillMaxWidth(0.94f) - .clip(RoundedCornerShape(24.dp)) - .background(Color(0xFFD32F2F)) - .padding(horizontal = 28.dp, vertical = 36.dp), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon(Icons.Default.DirectionsWalk, contentDescription = null, - tint = Color.White, modifier = Modifier.size(64.dp)) - Spacer(modifier = Modifier.height(12.dp)) - Text(stringResource(R.string.alarm_patient_walking), fontSize = 30.sp, - fontWeight = FontWeight.ExtraBold, color = Color.White, - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(6.dp)) - Text(stringResource(R.string.alarm_patient_walking_en), - fontSize = 16.sp, fontWeight = FontWeight.Medium, - color = Color.White.copy(alpha = 0.92f), - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(8.dp)) - Text(stringResource(R.string.alarm_immediate_check), - fontSize = 14.sp, color = Color.White.copy(alpha = 0.9f), - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(24.dp)) - Button( - onClick = { showWalkingAlarm = false }, - colors = ButtonDefaults.buttonColors( - containerColor = Color.White, contentColor = Color(0xFFD32F2F) - ), - modifier = Modifier.fillMaxWidth().height(56.dp), - shape = RoundedCornerShape(14.dp) - ) { - Text(stringResource(R.string.confirm), fontSize = 20.sp, fontWeight = FontWeight.Bold) - } - } - } - } + com.medithings.vesiscan.ui.components.AlertModalDialog( + backgroundColor = com.medithings.vesiscan.ui.theme.MlCritical, + icon = Icons.Default.DirectionsWalk, + title = stringResource(R.string.alarm_patient_walking), + subtitle = stringResource(R.string.alarm_patient_walking_en), + detail = stringResource(R.string.alarm_immediate_check), + confirmLabel = stringResource(R.string.confirm), + onConfirm = { showWalkingAlarm = false }, + widthFraction = 0.94f, + iconSize = 64.dp, + titleSize = 30.sp, + ) } val screenWidth = LocalConfiguration.current.screenWidthDp diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt index 3e43aa1..694643d 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/monitoring/PlacementGuideView.kt @@ -208,50 +208,18 @@ fun PlacementGuideView(appState: AppState) { ) // 센서 분리 알림 (주황 warning) — wakeup 알람과 동일 패턴 + // 2026-07-10: AlertModalDialog 로 통합 (ui/components/AlertModalDialog.kt). if (showDetachAlert) { - androidx.compose.ui.window.Dialog( - onDismissRequest = { }, - properties = androidx.compose.ui.window.DialogProperties( - dismissOnBackPress = false, dismissOnClickOutside = false - ) - ) { - Box( - modifier = Modifier - .fillMaxWidth(0.92f) - .clip(RoundedCornerShape(24.dp)) - .background(Color(0xFFFF9800)) // Material Orange 500 - .padding(horizontal = 28.dp, vertical = 36.dp), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon(Icons.Default.Warning, contentDescription = null, - tint = Color.White, modifier = Modifier.size(56.dp)) - Spacer(modifier = Modifier.height(12.dp)) - Text(stringResource(R.string.sensor_detached_title), fontSize = 26.sp, - fontWeight = FontWeight.ExtraBold, color = Color.White, - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(6.dp)) - Text(stringResource(R.string.sensor_detached_subtitle), fontSize = 16.sp, - fontWeight = FontWeight.Medium, color = Color.White.copy(alpha = 0.9f), - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(8.dp)) - Text(stringResource(R.string.sensor_detached_desc), - fontSize = 14.sp, color = Color.White.copy(alpha = 0.85f), - textAlign = TextAlign.Center) - Spacer(modifier = Modifier.height(24.dp)) - Button( - onClick = { showDetachAlert = false }, - colors = ButtonDefaults.buttonColors( - containerColor = Color.White, contentColor = Color(0xFFFF9800) - ), - modifier = Modifier.fillMaxWidth().height(56.dp), - shape = RoundedCornerShape(14.dp) - ) { - Text(stringResource(R.string.confirm), fontSize = 20.sp, fontWeight = FontWeight.Bold) - } - } - } - } + com.medithings.vesiscan.ui.components.AlertModalDialog( + backgroundColor = com.medithings.vesiscan.ui.theme.MlWarning, + icon = Icons.Default.Warning, + title = stringResource(R.string.sensor_detached_title), + subtitle = stringResource(R.string.sensor_detached_subtitle), + detail = stringResource(R.string.sensor_detached_desc), + confirmLabel = stringResource(R.string.confirm), + onConfirm = { showDetachAlert = false }, + titleSize = 26.sp, + ) } Column(