From 8350ef65b5df7f37101a5eeb75b54e13f49bc484 Mon Sep 17 00:00:00 2001 From: Clara Dautermann Date: Thu, 29 May 2025 18:58:58 +0200 Subject: [PATCH] working calendar!!! --- .../de/cdaut/dbtapp/components/Tracking.kt | 126 +++++++++++++++--- .../java/de/cdaut/dbtapp/util/DateHelpers.kt | 3 +- 2 files changed, 105 insertions(+), 24 deletions(-) diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt index 5b81a30..971fdbd 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/components/Tracking.kt @@ -6,36 +6,44 @@ 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.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ChevronLeft import androidx.compose.material.icons.filled.ChevronRight -import androidx.compose.material3.DatePicker -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.Text -import androidx.compose.material3.rememberDatePickerState 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.platform.LocalConfiguration +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview -import de.cdaut.dbtapp.util.WeekdayListByLocale +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em +import de.cdaut.dbtapp.util.weekdayListByLocale +import java.time.LocalDate +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.time.temporal.WeekFields @Composable fun TrackingScreen() { TopCalendar() } -@OptIn(ExperimentalMaterial3Api::class) -@Preview -@Composable -private fun DatePickerPreview() { - val datePickerState = rememberDatePickerState() - DatePicker(datePickerState) -} -@Preview +@Preview(device = "id:pixel_5", locale = "de") @Composable private fun TopCalendarPrev() { Box(Modifier.background(Color.White)) { @@ -45,35 +53,109 @@ private fun TopCalendarPrev() { @Composable private fun TopCalendar() { - Column { + + var currentDate: LocalDate by remember { + mutableStateOf(LocalDate.now()) + } + + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { //Top Navigation and display items Row( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { - Text(text = "currentDate") + //Header stating the currently selected date + Text( + fontSize = 4.5.em, + text = currentDate.format( + DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG) + .withLocale(LocalConfiguration.current.locales[0]) + ) + ) + // arrows to switch month Row { Icon( - modifier = Modifier.clickable(onClick = {}), + modifier = Modifier + .clickable(onClick = { + currentDate = currentDate.minusMonths(1) + }) + .size(30.dp), imageVector = Icons.Filled.ChevronLeft, contentDescription = "TODO: Provide" ) Icon( - modifier = Modifier.clickable(onClick = {}), + modifier = Modifier + .clickable(onClick = { + currentDate = currentDate.plusMonths(1) + }) + .size(30.dp), imageVector = Icons.Filled.ChevronRight, contentDescription = "TODO: Provide" ) } } + + // labels for current day Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, ) { - for (label in WeekdayListByLocale()) { - Text(text = label) + weekdayListByLocale(LocalConfiguration.current.locales[0]).map { label -> + Text( + text = label, + modifier = Modifier.padding(10.dp), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Bold + ) + } + } + + CalendarDaysGrid(currentDate) + } +} + +@Composable +fun CalendarDaysGrid(date: LocalDate, modifier: Modifier = Modifier) { + val locale = LocalConfiguration.current.locales[0] + + val firstDayOfMonth = LocalDate.of(date.year, date.month, 1) + val totalDaysInMonth = firstDayOfMonth.lengthOfMonth() + val firstDayOfWeek = WeekFields.of(locale).firstDayOfWeek + + //calculate shift required in the beginning + val shift = (firstDayOfMonth.dayOfWeek.value - firstDayOfWeek.value + 7) % 7 + val totalCells = ((shift + totalDaysInMonth + 6) / 7) * 7 + + val days = List(totalCells) { index -> + val dayNumber = index - shift + 1 + if (dayNumber in 1..totalDaysInMonth) dayNumber else null + } + + // Calendar Grid + LazyVerticalGrid( + columns = GridCells.Fixed(7), + userScrollEnabled = false, + modifier = Modifier.fillMaxWidth() + ) { + items(days.size) { index -> + Box( + modifier = Modifier + .aspectRatio(1f) + .padding(4.dp), + contentAlignment = Alignment.Center + ) { + days[index]?.let { + Text(text = it.toString()) + } } } } -} +} \ No newline at end of file diff --git a/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt b/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt index 528d4fd..03d52b9 100644 --- a/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt +++ b/DBTApp/app/src/main/java/de/cdaut/dbtapp/util/DateHelpers.kt @@ -5,8 +5,7 @@ import java.time.format.TextStyle import java.time.temporal.WeekFields import java.util.Locale -fun WeekdayListByLocale(): List { - val locale = Locale.getDefault() +fun weekdayListByLocale(locale: Locale): List { val listOfDayNames = DayOfWeek.entries.map { it.getDisplayName(TextStyle.NARROW, locale).substring(0, 1) } val firstDayOfWeek = WeekFields.of(locale).firstDayOfWeek.ordinal val orderedListOfDayNames =