Prettify a bit the report UI.
This commit is contained in:
parent
3645b92a82
commit
1bbd523e88
4 changed files with 217 additions and 60 deletions
|
|
@ -1,12 +1,18 @@
|
|||
package com.pixelized.headache.ui.page.summary.monthly
|
||||
|
||||
import android.icu.util.Calendar
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.gestures.snapping.SnapPosition
|
||||
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.NavigationBarDefaults
|
||||
import androidx.compose.material3.Scaffold
|
||||
|
|
@ -22,6 +28,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.keepScreenOn
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
|
|
@ -36,7 +44,6 @@ import com.pixelized.headache.ui.page.summary.monthly.item.MonthSummaryTitle
|
|||
import com.pixelized.headache.ui.page.summary.monthly.item.MonthSummaryTitleUio
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import java.util.Date
|
||||
|
||||
@Stable
|
||||
data object MonthSummaryPageDefault {
|
||||
|
|
@ -72,6 +79,11 @@ fun MonthSummaryPage(
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
private fun MonthSummaryContent(
|
||||
modifier: Modifier = Modifier,
|
||||
state: LazyListState = rememberLazyListState(),
|
||||
flingBehavior: FlingBehavior = rememberSnapFlingBehavior(
|
||||
lazyListState = state,
|
||||
snapPosition = SnapPosition.Start,
|
||||
),
|
||||
spacing: Dp = MonthSummaryPageDefault.spacing,
|
||||
listPadding: PaddingValues = MonthSummaryPageDefault.listPadding,
|
||||
events: State<Map<MonthSummaryTitleUio, List<MonthSummaryItemUio>>>,
|
||||
|
|
@ -95,6 +107,8 @@ private fun MonthSummaryContent(
|
|||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues = paddingValues),
|
||||
state = state,
|
||||
flingBehavior = flingBehavior,
|
||||
contentPadding = listPadding,
|
||||
verticalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
reverseLayout = false,
|
||||
|
|
@ -123,37 +137,109 @@ private fun MonthSummaryContent(
|
|||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun MonthSummaryPreview() {
|
||||
private fun MonthSummaryPreview(
|
||||
@PreviewParameter(MonthSummaryPreviewProvider::class) preview: Map<MonthSummaryTitleUio, List<MonthSummaryItemUio>>,
|
||||
) {
|
||||
HeadacheTheme {
|
||||
val events = remember {
|
||||
mutableStateOf(
|
||||
mapOf(
|
||||
MonthSummaryTitleUio(
|
||||
date = Date(),
|
||||
) to listOf(
|
||||
MonthSummaryItemUio(
|
||||
date = Date(),
|
||||
days = 8,
|
||||
pills = listOf(
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Spifen 400",
|
||||
amount = 4,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
),
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Élétriptan 40",
|
||||
amount = 2,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
val events = remember { mutableStateOf(preview) }
|
||||
MonthSummaryContent(
|
||||
events = events,
|
||||
onItem = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class MonthSummaryPreviewProvider :
|
||||
PreviewParameterProvider<Map<MonthSummaryTitleUio, List<MonthSummaryItemUio>>> {
|
||||
|
||||
private fun date(
|
||||
year: Int,
|
||||
) = Calendar.getInstance().also {
|
||||
it.set(Calendar.YEAR, year)
|
||||
it.set(Calendar.MONTH, Calendar.JANUARY)
|
||||
it.set(Calendar.DAY_OF_MONTH, 1)
|
||||
it.set(Calendar.MILLISECONDS_IN_DAY, 1)
|
||||
}
|
||||
|
||||
private fun Calendar.year(
|
||||
vararg month: MonthSummaryItemUio,
|
||||
): Pair<MonthSummaryTitleUio, List<MonthSummaryItemUio>> {
|
||||
this.add(Calendar.YEAR, -1)
|
||||
return MonthSummaryTitleUio(
|
||||
date = this.time
|
||||
) to month.toList()
|
||||
}
|
||||
|
||||
private fun Calendar.month(
|
||||
headache: Int = 0,
|
||||
eletriptan: Int = 0,
|
||||
ibuprofen: Int = 0,
|
||||
paracetamol: Int = 0,
|
||||
spifen: Int = 0,
|
||||
): MonthSummaryItemUio {
|
||||
val date = this.time
|
||||
this.add(Calendar.MONTH, 1)
|
||||
return MonthSummaryItemUio(
|
||||
date = date,
|
||||
days = headache,
|
||||
pills = listOfNotNull(
|
||||
eletriptan.takeIf { it > 0 }?.let {
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Élétriptan 40",
|
||||
amount = it,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
)
|
||||
},
|
||||
ibuprofen.takeIf { it > 0 }?.let {
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Ibuprofène 400",
|
||||
amount = it,
|
||||
color = HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
)
|
||||
},
|
||||
paracetamol.takeIf { it > 0 }?.let {
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Paracetamol 1000",
|
||||
amount = it,
|
||||
color = HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
)
|
||||
},
|
||||
spifen.takeIf { it > 0 }?.let {
|
||||
MonthSummaryPillItemUio(
|
||||
label = "Spifen 400",
|
||||
amount = it,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override val values: Sequence<Map<MonthSummaryTitleUio, List<MonthSummaryItemUio>>>
|
||||
get() = sequenceOf(
|
||||
mapOf(
|
||||
with(date(year = 2025)) {
|
||||
year(
|
||||
month(headache = 6, eletriptan = 4, spifen = 6),
|
||||
month(headache = 15, eletriptan = 9, paracetamol = 2, spifen = 14),
|
||||
month(headache = 14, eletriptan = 6, spifen = 10),
|
||||
month(headache = 16, eletriptan = 7, spifen = 11),
|
||||
month(headache = 14, eletriptan = 7, ibuprofen = 1, spifen = 12),
|
||||
month(headache = 12, eletriptan = 3, spifen = 10),
|
||||
month(headache = 7, spifen = 3),
|
||||
month(headache = 8, eletriptan = 1, spifen = 4),
|
||||
month(headache = 8, eletriptan = 1, spifen = 4),
|
||||
month(),
|
||||
month(),
|
||||
month(),
|
||||
)
|
||||
},
|
||||
with(date(year = 2024)) {
|
||||
year(
|
||||
month(),
|
||||
month(),
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import android.icu.text.DateFormat
|
|||
import android.icu.text.SimpleDateFormat
|
||||
import android.icu.util.Calendar
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -67,7 +68,7 @@ object ReportBoxDefault {
|
|||
@Stable
|
||||
val barSize: DpSize = DpSize(
|
||||
width = 28.dp,
|
||||
height = 320.dp,
|
||||
height = 240.dp,
|
||||
)
|
||||
|
||||
@Stable
|
||||
|
|
@ -90,6 +91,7 @@ fun ReportBox(
|
|||
barSpace: Dp = ReportBoxDefault.barSpace,
|
||||
titleSpace: Dp = ReportBoxDefault.titleSpace,
|
||||
item: ReportBoxUio,
|
||||
onMonth: (ReportBoxUio.Month) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
|
|
@ -109,6 +111,7 @@ fun ReportBox(
|
|||
barSize = barSize,
|
||||
barShape = barShape,
|
||||
item = it,
|
||||
onItem = onMonth,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -122,10 +125,12 @@ private fun Month(
|
|||
barSize: DpSize = ReportBoxDefault.barSize,
|
||||
barShape: Shape = ReportBoxDefault.barShape,
|
||||
item: ReportBoxUio.Month,
|
||||
onItem: (ReportBoxUio.Month) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.width(width = barSize.width)
|
||||
.clickable { onItem(item) }
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
|
|
@ -174,6 +179,7 @@ private fun ReportBoxPreview(
|
|||
Surface {
|
||||
ReportBox(
|
||||
item = preview,
|
||||
onMonth = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ package com.pixelized.headache.ui.page.summary.report
|
|||
|
||||
import android.icu.util.Calendar
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.gestures.snapping.SnapPosition
|
||||
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -13,8 +16,15 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBarDefaults
|
||||
import androidx.compose.material3.Scaffold
|
||||
|
|
@ -42,6 +52,8 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.pixelized.headache.R
|
||||
import com.pixelized.headache.ui.navigation.destination.navigateToEventPage
|
||||
import com.pixelized.headache.ui.navigation.main.LocalMainNavigator
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.calculate
|
||||
|
|
@ -66,6 +78,7 @@ data object ReportPageDefault {
|
|||
fun ReportPage(
|
||||
viewModel: ReportViewModel = hiltViewModel(),
|
||||
) {
|
||||
val navigator = LocalMainNavigator.current
|
||||
val events = viewModel.events.collectAsStateWithLifecycle()
|
||||
|
||||
ReportContent(
|
||||
|
|
@ -73,6 +86,9 @@ fun ReportPage(
|
|||
.keepScreenOn()
|
||||
.fillMaxSize(),
|
||||
events = events,
|
||||
onMonth = {
|
||||
navigator.navigateToEventPage(date = it.date)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -80,11 +96,17 @@ fun ReportPage(
|
|||
@Composable
|
||||
private fun ReportContent(
|
||||
modifier: Modifier = Modifier,
|
||||
state: LazyListState = rememberLazyListState(),
|
||||
flingBehavior: FlingBehavior = rememberSnapFlingBehavior(
|
||||
lazyListState = state,
|
||||
snapPosition = SnapPosition.Start,
|
||||
),
|
||||
paddingValues: PaddingValues = ReportPageDefault.paddingValues,
|
||||
contentSpace: Dp = ReportPageDefault.contentSpace,
|
||||
barSpace: Dp = ReportPageDefault.barSpace,
|
||||
barSize: DpSize = rememberBarSize(column = 12, paddingValues = paddingValues, space = barSpace),
|
||||
events: State<List<ReportBoxUio>>,
|
||||
onMonth: (ReportBoxUio.Month) -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
|
|
@ -95,42 +117,27 @@ private fun ReportContent(
|
|||
containerColor = NavigationBarDefaults.containerColor,
|
||||
),
|
||||
title = {
|
||||
Text(text = stringResource(R.string.year_summary_title))
|
||||
Text(
|
||||
text = stringResource(R.string.year_summary_title),
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
Column(
|
||||
modifier = Modifier.padding(end = 16.dp)
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
Box {
|
||||
val expanded = remember { mutableStateOf(false) }
|
||||
IconButton(
|
||||
onClick = { expanded.value = true },
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(
|
||||
color = HeadacheColorPalette.Calendar.Headache,
|
||||
)
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "Jours de migraine",
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
DropdownMenu(
|
||||
expanded = expanded.value,
|
||||
onDismissRequest = { expanded.value = false }
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(
|
||||
color = HeadacheColorPalette.Calendar.Pill,
|
||||
)
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "Prise de cachet",
|
||||
Legend(
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -140,6 +147,8 @@ private fun ReportContent(
|
|||
content = { it ->
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(paddingValues = it),
|
||||
state = state,
|
||||
flingBehavior = flingBehavior,
|
||||
contentPadding = paddingValues,
|
||||
verticalArrangement = Arrangement.spacedBy(space = contentSpace),
|
||||
) {
|
||||
|
|
@ -150,6 +159,7 @@ private fun ReportContent(
|
|||
barSize = barSize,
|
||||
barSpace = barSpace,
|
||||
item = item,
|
||||
onMonth = onMonth,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -157,6 +167,48 @@ private fun ReportContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Legend(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(
|
||||
color = HeadacheColorPalette.Calendar.Headache,
|
||||
)
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "Jours de migraine",
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(8.dp)
|
||||
.background(
|
||||
color = HeadacheColorPalette.Calendar.Pill,
|
||||
)
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "Prise de cachet",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberBarSize(
|
||||
column: Int,
|
||||
|
|
@ -186,6 +238,7 @@ private fun ReportPreview(
|
|||
Surface {
|
||||
ReportContent(
|
||||
events = remember { mutableStateOf(preview) },
|
||||
onMonth = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.pixelized.headache.ui.page.summary.yearly
|
||||
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.gestures.snapping.SnapPosition
|
||||
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
|
|
@ -7,8 +10,10 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridState
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBarDefaults
|
||||
|
|
@ -87,6 +92,11 @@ fun YearSummaryPage(
|
|||
@Composable
|
||||
fun YearSummaryContent(
|
||||
modifier: Modifier = Modifier,
|
||||
state: LazyGridState = rememberLazyGridState(),
|
||||
flingBehavior: FlingBehavior = rememberSnapFlingBehavior(
|
||||
lazyGridState = state,
|
||||
snapPosition = SnapPosition.Start,
|
||||
),
|
||||
paddingValues: PaddingValues = YearSummaryPageDefault.paddingValues,
|
||||
space: Dp = YearSummaryPageDefault.space,
|
||||
daySize: Dp = rememberDaySize(column = YearSummaryPageDefault.column),
|
||||
|
|
@ -117,6 +127,8 @@ fun YearSummaryContent(
|
|||
}
|
||||
LazyVerticalGrid(
|
||||
modifier = Modifier.padding(paddingValues = it),
|
||||
state = state,
|
||||
flingBehavior = flingBehavior,
|
||||
columns = GridCells.Adaptive(minSize = daySize * 7),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = space),
|
||||
verticalArrangement = Arrangement.spacedBy(space = space),
|
||||
|
|
@ -128,7 +140,7 @@ fun YearSummaryContent(
|
|||
contentType = { "Title" },
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
text = "$year",
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue