@@ -35,7 +35,7 @@ import java.util.Locale
3535import androidx.compose.ui.platform.LocalLocale
3636import java.time.temporal.WeekFields
3737
38- private const val DAYS_AHEAD = 90
38+ private const val DAYS_AHEAD = 180
3939private val DAY_COLUMN_WIDTH = 56 .dp
4040private val firstDayOfWeek: DayOfWeek
4141 get() = WeekFields .of(Locale .getDefault()).firstDayOfWeek
@@ -48,7 +48,8 @@ private data class WeekBlock(
4848
4949private data class DayBlock (
5050 val date : LocalDate ,
51- val tasks : List <Task >
51+ val tasks : List <Task >,
52+ val isFirstOfMonth : Boolean = false
5253)
5354
5455@Composable
@@ -87,28 +88,31 @@ private fun WeekSection(
8788 week : WeekBlock ,
8889 onTaskToggle : (Task ) -> Unit
8990) {
90- Row (
91- modifier = Modifier
92- .fillMaxWidth()
93- .padding(top = 12 .dp),
94- verticalAlignment = Alignment .CenterVertically
95- ) {
96- // Left column spacer — keeps week label aligned with task cards
97- Spacer (modifier = Modifier .width(DAY_COLUMN_WIDTH ))
98-
99- // Week label sits directly above its day rows, in the same column as the cards
100- Text (
101- text = week.label,
102- style = MaterialTheme .typography.labelMedium.copy(fontWeight = FontWeight .Medium ),
103- color = MaterialTheme .colorScheme.onSurfaceVariant,
104- )
105- }
91+ Column {
92+ Row (
93+ modifier = Modifier .fillMaxWidth().padding(top = 12 .dp),
94+ verticalAlignment = Alignment .CenterVertically
95+ ) {
96+ // Left column spacer — keeps week label aligned with task cards
97+ Spacer (modifier = Modifier .width(DAY_COLUMN_WIDTH ))
98+ // Week label sits directly above its day rows, in the same column as the cards
99+ Text (
100+ text = week.label,
101+ style = MaterialTheme .typography.labelMedium,
102+ color = MaterialTheme .colorScheme.onSurfaceVariant.copy(alpha = 0.8f ),
103+ )
104+ }
106105
107- Spacer (modifier = Modifier .height(6 .dp))
106+ Spacer (modifier = Modifier .height(6 .dp))
108107
109- if (week.days.isNotEmpty()) {
110108 week.days.forEach { day ->
111- DayRow (day = day, onTaskToggle = onTaskToggle)
109+ if (day.isFirstOfMonth) {
110+ MonthBanner (day.date)
111+ }
112+
113+ if (day.tasks.isNotEmpty()) {
114+ DayRow (day = day, onTaskToggle = onTaskToggle)
115+ }
112116 }
113117 }
114118}
@@ -194,24 +198,28 @@ private fun buildWeekBlocks(
194198 var weekStart = startDate.with (TemporalAdjusters .previousOrSame(firstDayOfWeek))
195199
196200 while (weekStart <= endDate) {
197- val weekEnd = weekStart.plusDays(6 )
198- val days = (0L .. 6L )
199- .map { weekStart.plusDays(it) }
200- .filter { it in startDate.. endDate }
201- .mapNotNull { day ->
202- tasksByDate[day]?.takeIf { it.isNotEmpty() }?.let { DayBlock (day, it) }
203- }
204-
205- blocks.add(
206- WeekBlock (
207- weekKey = weekKeyFor(weekStart),
208- label = buildWeekLabel(weekStart, weekEnd),
209- days = days
201+ val days = (0L .. 6L ).map { offset ->
202+ val dayDate = weekStart.plusDays(offset)
203+ val tasks = tasksByDate[dayDate] ? : emptyList()
204+
205+ DayBlock (
206+ date = dayDate,
207+ tasks = tasks,
208+ isFirstOfMonth = dayDate.dayOfMonth == 1
210209 )
211- )
210+ }.filter { it.date in startDate.. endDate }
211+
212+ if (days.isNotEmpty()) {
213+ blocks.add(
214+ WeekBlock (
215+ weekKey = weekKeyFor(weekStart),
216+ label = buildWeekLabel(weekStart, weekStart.plusDays(6 )),
217+ days = days
218+ )
219+ )
220+ }
212221 weekStart = weekStart.plusWeeks(1 )
213222 }
214-
215223 return blocks
216224}
217225
0 commit comments