From a727e2dbd1dbbea9c2b72188e827053d434e93b6 Mon Sep 17 00:00:00 2001 From: b-dev-mobile Date: Wed, 8 Jul 2026 10:15:41 +0000 Subject: [PATCH] =?UTF-8?q?calendar:=20=D1=80=D0=B5=D1=81=D0=BA=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=B5=D1=81=D1=8F=D1=87=D0=BD=D0=BE=D0=B9=20?= =?UTF-8?q?=D1=81=D0=B5=D1=82=D0=BA=D0=B8=20=D0=BF=D0=BE=D0=B4=20=D0=BC?= =?UTF-8?q?=D0=B0=D0=BA=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По «Календарь · Месяц»: дни недели — серые пилюли; сетка безрамочная с гридлайнами (0.5dp) вместо скруглённых боксов; номер дня сверху-слева; сегодня — в зелёном круге (Primary, белый текст); событие — зелёная пилюля PrimaryLight (до 2 + «+N»), было одно превью/точка. Компактная модель (месяц + список дня снизу) сохранена. Компилируется. --- .../feature/calendar/CalendarComponents.kt | 154 ++++++++++-------- .../feature/calendar/CalendarScreen.kt | 1 - 2 files changed, 86 insertions(+), 69 deletions(-) diff --git a/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarComponents.kt b/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarComponents.kt index bf50ec4..7ce1731 100644 --- a/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarComponents.kt +++ b/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarComponents.kt @@ -9,7 +9,6 @@ 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.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -388,49 +387,59 @@ private fun CalendarIconButton( fun CalendarMonthGrid( month: YearMonth, selectedDay: LocalDate, - daysWithEvents: Set, eventsByDay: Map>, onSelectDay: (LocalDate) -> Unit, ) { val days = CalendarRepository.monthGridDays(month) val today = LocalDate.now() Column( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(12.dp)) - .background(F7Colors.Surface) - .border(1.dp, F7Colors.Border, RoundedCornerShape(12.dp)) - .padding(8.dp), - verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(6.dp), ) { - Row(modifier = Modifier.fillMaxWidth()) { + // Заголовок дней недели — серые пилюли (по макету «Календарь · Месяц») + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { weekDayLabels.forEach { label -> - Text( - text = label, - modifier = Modifier.weight(1f), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.labelSmall, - color = F7Colors.TextMuted, - ) + Box( + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(100.dp)) + .background(F7Colors.Grey2) + .padding(vertical = 6.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = label, + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.Medium, + color = F7Colors.TextSecondary, + ) + } } } - days.chunked(7).forEach { week -> - Row(modifier = Modifier.fillMaxWidth()) { - week.forEach { day -> - val inMonth = day.month == month.month - val selected = day == selectedDay - val hasEvents = daysWithEvents.contains(day) - val dayEvents = eventsByDay[day].orEmpty() - CalendarDayCell( - day = day.dayOfMonth, - inMonth = inMonth, - isToday = day == today, - selected = selected, - hasEvents = hasEvents, - preview = dayEvents.firstOrNull()?.summary.orEmpty(), - onClick = { onSelectDay(day) }, - modifier = Modifier.weight(1f), - ) + // Гридлайн-сетка без скруглений (по макету) + Column( + modifier = Modifier + .fillMaxWidth() + .border(0.5.dp, F7Colors.Grey3), + ) { + days.chunked(7).forEach { week -> + Row(modifier = Modifier.fillMaxWidth()) { + week.forEach { day -> + val inMonth = day.month == month.month + val dayEvents = eventsByDay[day].orEmpty() + CalendarDayCell( + day = day.dayOfMonth, + inMonth = inMonth, + isToday = day == today, + selected = day == selectedDay, + events = dayEvents, + onClick = { onSelectDay(day) }, + modifier = Modifier.weight(1f), + ) + } } } } @@ -443,65 +452,74 @@ private fun CalendarDayCell( inMonth: Boolean, isToday: Boolean, selected: Boolean, - hasEvents: Boolean, - preview: String, + events: List, onClick: () -> Unit, modifier: Modifier = Modifier, ) { - val bg = when { + val cellBg = when { + isToday -> F7Colors.Green10 selected -> F7Colors.PrimaryLight - isToday -> F7Colors.PrimaryLight.copy(alpha = 0.55f) else -> F7Colors.Surface } - val borderColor = when { - selected -> F7Colors.Primary - isToday -> F7Colors.PrimaryDark - else -> F7Colors.BorderLight - } - Box( + Column( modifier = modifier - .aspectRatio(1f) - .padding(2.dp) - .clip(RoundedCornerShape(8.dp)) - .background(bg) - .border(1.dp, borderColor, RoundedCornerShape(8.dp)) + .heightIn(min = 66.dp) + .border(0.5.dp, F7Colors.Grey3) + .background(cellBg) .clickable(onClick = onClick) - .padding(2.dp), - contentAlignment = Alignment.TopCenter, + .padding(horizontal = 4.dp, vertical = 4.dp), + verticalArrangement = Arrangement.spacedBy(2.dp), ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { + // Номер дня сверху-слева; сегодня — в зелёном круге + Box( + modifier = Modifier + .size(22.dp) + .then(if (isToday) Modifier.clip(CircleShape).background(F7Colors.Primary) else Modifier), + contentAlignment = Alignment.Center, + ) { Text( text = day.toString(), style = MaterialTheme.typography.bodySmall, - fontWeight = if (isToday) FontWeight.Bold else FontWeight.Normal, + fontWeight = if (isToday) FontWeight.SemiBold else FontWeight.Normal, color = when { + isToday -> F7Colors.TextOnPrimary !inMonth -> F7Colors.TextMuted - selected -> F7Colors.PrimaryDark else -> F7Colors.TextPrimary }, ) - if (hasEvents && inMonth && preview.isNotBlank()) { + } + if (inMonth) { + events.take(2).forEach { event -> + CalendarDayEventPill(event.summary.ifBlank { "Событие" }) + } + if (events.size > 2) { Text( - preview, + "+${events.size - 2}", style = MaterialTheme.typography.labelSmall, - color = F7Colors.PrimaryDark, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(top = 1.dp), - ) - } else if (hasEvents && inMonth) { - Box( - modifier = Modifier - .padding(top = 2.dp) - .size(5.dp) - .clip(CircleShape) - .background(F7Colors.Primary), + color = F7Colors.Primary, + fontWeight = FontWeight.Medium, ) } } } } +@Composable +private fun CalendarDayEventPill(text: String) { + Text( + text = text, + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(4.dp)) + .background(F7Colors.PrimaryLight) + .padding(horizontal = 4.dp, vertical = 1.dp), + style = MaterialTheme.typography.labelSmall, + color = F7Colors.PrimaryDark, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) +} + @Composable fun CalendarWeekView( selectedDay: LocalDate, diff --git a/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarScreen.kt b/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarScreen.kt index 2560542..d5a85d4 100644 --- a/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarScreen.kt +++ b/feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarScreen.kt @@ -343,7 +343,6 @@ fun CalendarScreen( CalendarMonthGrid( month = state.visibleMonth, selectedDay = state.selectedDay, - daysWithEvents = vm.daysWithEvents(), eventsByDay = eventsByDay, onSelectDay = vm::selectDay, )