diff --git a/.gitignore b/.gitignore index aa724b7..faf530b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,7 @@ *.iml .gradle /local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml +/.idea/ .DS_Store /build /captures diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml deleted file mode 100644 index 4a53bee..0000000 --- a/.idea/AndroidProjectSystem.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml deleted file mode 100644 index 371f2e2..0000000 --- a/.idea/appInsightsSettings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b86273d..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml deleted file mode 100644 index b268ef3..0000000 --- a/.idea/deploymentTargetSelector.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 97f0a8e..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml deleted file mode 100644 index f8051a6..0000000 --- a/.idea/migrations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 74dd639..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 16660f1..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/hyeon/dayroutine/MainActivity.kt b/app/src/main/java/com/hyeon/dayroutine/MainActivity.kt index 1a1fe00..147f907 100644 --- a/app/src/main/java/com/hyeon/dayroutine/MainActivity.kt +++ b/app/src/main/java/com/hyeon/dayroutine/MainActivity.kt @@ -2,6 +2,7 @@ package com.hyeon.dayroutine import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize @@ -10,38 +11,26 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.tooling.preview.Preview +import com.hyeon.dayroutine.ui.home.HomeScreen import com.hyeon.dayroutine.ui.theme.DayRoutineTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enableEdgeToEdge() + enableEdgeToEdge( + statusBarStyle = SystemBarStyle.dark( + scrim = Color.Transparent.toArgb() + ) + ) setContent { DayRoutineTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - Greeting( - name = "Android", - modifier = Modifier.padding(innerPadding) - ) + HomeScreen() } } } } -} - -@Composable -fun Greeting(name: String, modifier: Modifier = Modifier) { - Text( - text = "Hello $name!", - modifier = modifier - ) -} - -@Preview(showBackground = true) -@Composable -fun GreetingPreview() { - DayRoutineTheme { - Greeting("Android") - } } \ No newline at end of file diff --git a/app/src/main/java/com/hyeon/dayroutine/ui/component/RoutineProgress.kt b/app/src/main/java/com/hyeon/dayroutine/ui/component/RoutineProgress.kt new file mode 100644 index 0000000..b3ab257 --- /dev/null +++ b/app/src/main/java/com/hyeon/dayroutine/ui/component/RoutineProgress.kt @@ -0,0 +1,41 @@ +package com.hyeon.dayroutine.ui.component + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.ProgressIndicatorDefaults.drawStopIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.unit.dp + +@Composable +fun RoutineProgress( + modifier: Modifier, + progress: Float +) { + Canvas( + modifier = modifier + .fillMaxWidth() + .height(6.dp) + ) { + val radius = size.height / 2 + + drawRoundRect( + color = Color(0xFF33334a), + cornerRadius = CornerRadius(radius) + ) + + drawRoundRect( + color = Color(0xFF6c63ff), + cornerRadius = CornerRadius(radius), + size = Size(width = size.width * progress, height = size.height) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hyeon/dayroutine/ui/home/AddRoutineBottomSheet.kt b/app/src/main/java/com/hyeon/dayroutine/ui/home/AddRoutineBottomSheet.kt new file mode 100644 index 0000000..a3b37e5 --- /dev/null +++ b/app/src/main/java/com/hyeon/dayroutine/ui/home/AddRoutineBottomSheet.kt @@ -0,0 +1,328 @@ +package com.hyeon.dayroutine.ui.home + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +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.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.SheetState +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +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 +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 +import java.time.DayOfWeek +import java.time.format.TextStyle +import java.util.Locale +import kotlin.collections.listOf + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AddRoutineBottomSheet( + bottomSheetState: SheetState, + onDismiss: () -> Unit, +) { + var text by remember { mutableStateOf("") } + var selectedIcon by remember { mutableStateOf("") } + var startTime by remember { mutableStateOf("") } + var durationTime by remember { mutableStateOf("") } + var selectedDates by remember { mutableStateOf(setOf()) } + + ModalBottomSheet( + onDismissRequest = onDismiss, + sheetState = bottomSheetState, + shape = RoundedCornerShape(20.dp), + containerColor = Color(0xFF1a1a2e) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + Text( + text = "새 루틴 추가", + color = Color.White, + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ) + + RoutineNameEditBox( + text = text, + onValueChanged = { text = it } + ) + + RoutineIconSelector( + selectedIcon = selectedIcon, + onSelected = { selectedIcon = it } + ) + + RoutineTimeBox( + startTime = startTime, + durationTime = durationTime, + onStartTimeValueChanged = { startTime = it }, + onDurationTimeValueChanged = { durationTime = it } + ) + + RoutineDateSelector( + selectedDates = selectedDates, + onSelected = { date -> + selectedDates = if (selectedDates.contains(date)) selectedDates - date else selectedDates + date + } + ) + + Button( + modifier = Modifier + .fillMaxWidth(), + contentPadding = PaddingValues(vertical = 12.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors( + containerColor = Color(0xFF6c63ff) + ), + onClick = { /** 루틴 저장하기 **/ } + ) { + Text( + text = "루틴 저장하기", + color = Color.White, + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ) + } + + } + } +} + +@Composable +fun RoutineNameEditBox( + text: String, + onValueChanged: (String) -> Unit +) { + Text( + text = "루틴 이름", + color = Color.Gray, + fontSize = 12.sp, + ) + /** Basic TextField로 디테일한 TextField 수정 **/ + OutlinedTextField( + modifier = Modifier + .fillMaxWidth(), + value = text, + onValueChange = onValueChanged, + placeholder = { + Text( + text = "예) 스트레칭, 독서...", + color = Color(0xFF555577) + ) + }, + singleLine = true, + shape = RoundedCornerShape(20.dp), + ) +} + +@Composable +fun RoutineIconSelector( + selectedIcon: String, + onSelected: (String) -> Unit +) { + Text( + text = "아이콘", + color = Color.Gray, + fontSize = 12.sp, + ) + BoxWithConstraints( + modifier = Modifier.fillMaxWidth() + ) { + val itemMinWidth = 50.dp + val space = 8.dp + + /** 전체너비 = 아이템너비 * n + spacing * (n-1) + * 전체너비 = 아이템너비 * n + spacing * n - spacing + * 전체너비 + spacing = n(아이템너비 + spacing) + * + * 아이템너비 * n = 전체너비 - spacing * (n-1) + * 아이템 너비 = (전체너비 + spacing - (spacing * n)) / n + * **/ + val maxItems = ((maxWidth + space) / (itemMinWidth + space)).toInt() + val itemWidth = (maxWidth - space * (maxItems - 1)) / maxItems + + FlowRow( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + routineIconList.forEach { icon -> + Surface( + modifier = Modifier.size(itemWidth), + shape = RoundedCornerShape(10.dp), + color = if (icon == selectedIcon) Color(0xFF6c63ff) else Color((0xFF1a1a2e)), + border = if (icon == selectedIcon) BorderStroke( + width = 1.5.dp, + color = Color(0xFF6c63ff) + ) + else BorderStroke( + width = 1.dp, + color = Color(0xFF2a2a3e) + ), + onClick = { onSelected(icon) } + ) { + Box(contentAlignment = Alignment.Center) { + Text( + text = icon, + ) + } + } + } + } + } + +} + +private val routineIconList = listOf("🧘", "🏃", "📖", "✍️", "💊", "🥗", "💧", "🎯") + +@Composable +fun RoutineTimeBox( + startTime: String, + durationTime: String, + onStartTimeValueChanged: (String) -> Unit, + onDurationTimeValueChanged: (String) -> Unit +) { + Row( + modifier = Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + TimeEditBox( + modifier = Modifier.weight(1f), + timeLabel = "시작 시간", + timeText = startTime, + onValueChanged = onStartTimeValueChanged, + placeHolder = { + Text( + text = "오전 7:00", + fontSize = 14.sp, + color = Color(0xFF555577) + ) + } + ) + + TimeEditBox( + modifier = Modifier.weight(1f), + timeLabel = "소요 시간", + timeText = durationTime, + onValueChanged = onDurationTimeValueChanged, + placeHolder = { + Text( + text = "10분", + fontSize = 14.sp, + color = Color(0xFF555577) + ) + } + ) + } +} + +@Composable +fun TimeEditBox( + modifier: Modifier = Modifier, + timeLabel: String, + timeText: String, + onValueChanged: (String) -> Unit, + placeHolder: @Composable () -> Unit +) { + Column( + modifier = modifier.fillMaxWidth() + ) { + Text( + text = timeLabel, + color = Color.Gray, + fontSize = 12.sp, + ) + + Spacer(modifier = Modifier.height(12.dp)) + + OutlinedTextField( + value = timeText, + onValueChange = onValueChanged, + placeholder = placeHolder, + singleLine = true, + shape = RoundedCornerShape(20.dp) + ) + + } +} + +@Composable +fun RoutineDateSelector( + selectedDates: Set, + onSelected: (DayOfWeek) -> Unit +) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Text( + text = "반복 요일", + color = Color.Gray, + fontSize = 12.sp, + ) + + Row( + modifier = Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + DayOfWeek.entries.forEach { date -> + Box( + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .background( + color = if (selectedDates.contains(date)) Color(0xFF6c63ff) else Color(0xFF1a1a2e), + shape = CircleShape + ) + .border( + if (selectedDates.contains(date)) BorderStroke(width = 1.dp, color = Color(0xFF6c63ff)) + else BorderStroke(width = 1.5.dp, color = Color(0xFF2a2a3e)), + shape = CircleShape + ) + .clickable { onSelected(date) }, + contentAlignment = Alignment.Center, + ) { + Text( + text = date.getDisplayName(TextStyle.SHORT, Locale.ENGLISH), + color = if (selectedDates.contains(date)) Color.White else Color.Gray, + fontWeight = FontWeight.Bold, + fontSize = 14.sp + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hyeon/dayroutine/ui/home/HomeScreen.kt b/app/src/main/java/com/hyeon/dayroutine/ui/home/HomeScreen.kt new file mode 100644 index 0000000..4d545c2 --- /dev/null +++ b/app/src/main/java/com/hyeon/dayroutine/ui/home/HomeScreen.kt @@ -0,0 +1,425 @@ +package com.hyeon.dayroutine.ui.home + +import android.annotation.SuppressLint +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +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.layout.statusBars +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +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.platform.LocalDensity +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.hyeon.dayroutine.domain.model.Routine +import com.hyeon.dayroutine.ui.component.RoutineProgress +import java.time.DayOfWeek +import java.time.LocalDate +import java.time.LocalTime +import java.time.format.TextStyle +import java.util.Locale + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun HomeScreen() { + val dayOfWeekList = testDayDate() + val dayChipGroupListState = rememberLazyListState() + var isShowBottomSheet by remember { mutableStateOf(false) } + val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + + var checkTest by remember { mutableStateOf(false) } + + Scaffold( + modifier = Modifier.fillMaxSize(), + containerColor = Color(0xFF13131f), + topBar = { TopBar() } + ) { innerPadding -> + Column( + modifier = Modifier + .padding(innerPadding) + .padding(horizontal = 12.dp, vertical = 20.dp) + ) { + DayChipGroupList( + dayChipGroupListState = dayChipGroupListState, + dayOfWeekList = dayOfWeekList, + ) { /** 해당 날짜 루틴 목록 업데이트 **/ } + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 12.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "루틴 목록", + color = Color.Gray, + fontSize = 14.sp + ) + + Text( + modifier = Modifier + .clickable{ + isShowBottomSheet = true + }, + text = "+ 추가", + color = Color(0xFF6c63ff), + fontSize = 14.sp, + fontWeight = FontWeight.Bold + ) + } + + RoutineList( + routineList = routines, + onClickRoutine = { /** 루틴 상세 페이지 이동 **/ }, + isChecked = checkTest, + onChecked = { checkTest = it } + ) + + if (isShowBottomSheet) { + AddRoutineBottomSheet( + bottomSheetState = bottomSheetState + ) { + isShowBottomSheet = false + } + } + } + } +} + +@Composable +fun TopBar() { + Column( + modifier = Modifier + .fillMaxWidth() + .background(Color(0xFF1a1a2e)) + .padding(horizontal = 12.dp, vertical = 12.dp) + .windowInsetsPadding(WindowInsets.statusBars), + ) { + Text( + text = "오늘의 루틴을 향하여🔥", + color = Color.Gray, + fontSize = 14.sp + ) + + Text( + text = "오늘의 루틴", + color = Color.White, + fontSize = 20.sp, + fontWeight = FontWeight.Bold + ) + + Spacer(Modifier.height(12.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .background( + color = Color(0xFF252540), + shape = RoundedCornerShape(12.dp) + ) + .padding(horizontal = 14.dp, vertical = 12.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "오늘의 진행률", + color = Color.Gray, + fontSize = 12.sp + ) + Text( + text = "3/5 완료", + color = Color(0xFF8888aa), + fontSize = 12.sp, + fontWeight = FontWeight.Bold + ) + } + + Spacer(modifier = Modifier.height(6.dp)) + + RoutineProgress( + modifier = Modifier.fillMaxWidth(), + progress = 0.6f + ) + } + } +} + +@Composable +fun DayChipGroupList( + dayChipGroupListState: LazyListState, + dayOfWeekList: List, + onDayClick: (DayItem) -> Unit +) { + BoxWithConstraints { + val width = maxWidth + val density = LocalDensity.current + + LazyRow( + state = dayChipGroupListState, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + items(dayOfWeekList) { + DayOfWeekItem( + dayItem = it, + onDayClick = onDayClick + ) + } + } + + LaunchedEffect(Unit) { + val offset = with(density) { + ((width / 2) - (50 / 2).dp).toPx() + } + + dayChipGroupListState.animateScrollToItem( + index = 5, + scrollOffset = -offset.toInt() + ) + } + } +} + +@Composable +fun DayOfWeekItem( + dayItem: DayItem, + onDayClick: (DayItem) -> Unit +) { + Column( + modifier = Modifier + .size(width = 50.dp, height = 60.dp) + .background( + if (dayItem.isToday) Color(0xFF6c63ff) else Color(0xFF1e1e30), + shape = RoundedCornerShape(6.dp) + ) + .clickable { + onDayClick(dayItem) + }, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = dayItem.dayOfWeek, + fontSize = 12.sp, + color = if (dayItem.isToday) Color(0xFFd4d0ff) else Color(0xFF555577) + ) + + Text( + text = dayItem.day.toString(), + fontSize = 12.sp, + fontWeight = FontWeight.Bold, + color = if (dayItem.isToday) Color(0xFFffffff) else Color(0xFFcccccc) + ) + + Box( + modifier = Modifier + .size(6.dp) + .clip(shape = CircleShape) + .background(color = if (dayItem.isToday) Color(0xFFa09fff) else Color(0xFF33334a)) + ) + } +} + +@Composable +fun RoutineList( + routineList: List, + onClickRoutine: (Routine) -> Unit, + isChecked: Boolean, + onChecked: (Boolean) -> Unit +) { + LazyColumn( + modifier = Modifier.padding(top = 12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + items(routineList) { + RoutineItem( + routineItem = it, + onClickRoutine = onClickRoutine, + isChecked = isChecked, + onChecked = onChecked, + ) + } + } +} + +@Composable +fun RoutineItem( + routineItem: Routine, + onClickRoutine: (Routine) -> Unit, + isChecked: Boolean, + onChecked: (Boolean) -> Unit +) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(color = Color(0xFF1a1a2e), shape = RoundedCornerShape(12.dp)) + .border(width = 1.dp, color = Color(0xFF2a2a3e), shape = RoundedCornerShape(12.dp)) + .padding(12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + // TODO: 추후 이미지사용 + Box( + modifier = Modifier + .padding(end = 8.dp) + .size(50.dp) + .background(color = Color.Red, shape = RoundedCornerShape(12.dp)) + ) + + Column( + modifier = Modifier + .weight(1f) + .clickable{ + onClickRoutine(routineItem) + }, + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Text( + text = "운동명", + fontWeight = FontWeight.Bold, + color = Color.White + ) + + Text( + text = "시작시간 및 소요시간", + fontSize = 12.sp, + color = Color.Gray + ) + } + + Checkbox( + checked = isChecked, + onCheckedChange = { onChecked(it) }, + colors = CheckboxDefaults.colors( + checkedColor = Color(0xFF6c63ff), + checkmarkColor = Color.White + ) + ) + + } + +} + +fun testDayDate(): List { + val today = LocalDate.now() + val range = -5..5 + + return range.map { + val day = today.plusDays(it.toLong()) + + DayItem( + dayOfWeek = day.dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.ENGLISH), + day = day.dayOfMonth, + isToday = it == 0 + ) + } +} + +val routines = listOf( + Routine( + id = 1, + title = "스트레칭", + icon = "🧘", + startTime = LocalTime.of(7, 0), + repeatDays = listOf( + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY + ), + createdAt = LocalDate.of(2025, 3, 1) + ), + Routine( + id = 2, + title = "독서", + icon = "📖", + startTime = LocalTime.of(7, 30), + repeatDays = listOf( + DayOfWeek.MONDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.FRIDAY + ), + createdAt = LocalDate.of(2025, 3, 1) + ), + Routine( + id = 3, + title = "모닝 커피", + icon = "☕", + startTime = LocalTime.of(8, 0), + repeatDays = DayOfWeek.entries.toList(), // 매일 + createdAt = LocalDate.of(2025, 3, 5) + ), + Routine( + id = 4, + title = "조깅", + icon = "🏃", + startTime = LocalTime.of(8, 30), + repeatDays = listOf( + DayOfWeek.TUESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.SATURDAY + ), + createdAt = LocalDate.of(2025, 3, 10) + ), + Routine( + id = 5, + title = "명상", + icon = "🧘", + startTime = LocalTime.of(9, 0), + repeatDays = listOf( + DayOfWeek.MONDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SUNDAY + ), + createdAt = LocalDate.of(2025, 3, 15) + ), + Routine( + id = 6, + title = "일기 쓰기", + icon = "✍️", + startTime = LocalTime.of(22, 0), + repeatDays = DayOfWeek.entries.toList(), // 매일 + createdAt = LocalDate.of(2025, 3, 20) + ) +) + +data class DayItem( + val dayOfWeek: String, + val day: Int, + val isToday: Boolean, +)