Skip to content

Commit aa5b8a6

Browse files
authored
feat(agendaPage): add the agenda page (#8)
1 parent fbe2440 commit aa5b8a6

File tree

14 files changed

+266
-77
lines changed

14 files changed

+266
-77
lines changed

app/src/main/java/com/xpeho/xpeapp/enums/Screens.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ enum class Screens {
77
Vacation,
88
Colleague,
99
Qvst,
10-
Profile
10+
Profile,
11+
Agenda
1112
}

app/src/main/java/com/xpeho/xpeapp/ui/Navigation.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.xpeho.xpeapp.ui.components.layout.DisabledFeaturePlaceHolder
1111
import com.xpeho.xpeapp.ui.page.HomePage
1212
import com.xpeho.xpeapp.ui.page.LoginPage
1313
import com.xpeho.xpeapp.ui.page.NewsletterPage
14+
import com.xpeho.xpeapp.ui.page.AgendaPage
1415
import com.xpeho.xpeapp.ui.page.qvst.QvstCampaignDetailPage
1516
import com.xpeho.xpeapp.ui.page.qvst.QvstPage
1617
import com.xpeho.xpeapp.ui.page.user.ProfilePage
@@ -80,4 +81,13 @@ fun NavGraphBuilder.navigationBuilder(
8081
}
8182
}
8283
}
84+
composable(route = Screens.Agenda.name) {
85+
Layout(navigationController) {
86+
if (ffManager.isFeatureEnabled(FeatureFlippingEnum.AGENDA)) {
87+
AgendaPage()
88+
} else {
89+
DisabledFeaturePlaceHolder()
90+
}
91+
}
92+
}
8393
}

app/src/main/java/com/xpeho/xpeapp/ui/Resources.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class Resources {
6363
redirection = Screens.Vacation.name,
6464
featureFlippingId = FeatureFlippingEnum.VACATION,
6565
),
66+
Menu(
67+
idImage = XpehoRes.calendar,
68+
title = "Agenda",
69+
redirection = Screens.Agenda.name,
70+
featureFlippingId = FeatureFlippingEnum.AGENDA,
71+
)
6672
)
6773

6874
var listOfRequest: Array<RequestLeaveDetail> =

app/src/main/java/com/xpeho/xpeapp/ui/components/agenda/AgendaBirthdayCard.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fun AgendaBirthdayCard(
4343

4444
@Composable
4545
private fun getBirthdayTagsList(birthday: AgendaBirthday, color: Color): @Composable () -> Unit {
46-
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH)
46+
val dateFormat = SimpleDateFormat("dd/MM", Locale.FRENCH)
4747

4848
return {
4949
TagPill(

app/src/main/java/com/xpeho/xpeapp/ui/components/agenda/AgendaCard.kt

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.xpeho.xpeho_ui_android.TagPill
1616
import com.xpeho.xpeho_ui_android.foundations.Colors as XpehoColors
1717
import com.xpeho.xpeapp.R
1818
import androidx.core.graphics.toColorInt
19+
import com.xpeho.xpeapp.ui.components.layout.TagPillCustom
1920
import java.text.SimpleDateFormat
2021
import java.util.Locale
2122

@@ -49,23 +50,21 @@ fun AgendaCard(
4950

5051
@Composable
5152
private fun getTagsList(event: AgendaEvent, eventType: List<AgendaEventType>, color: Color): @Composable () -> Unit {
52-
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH)
53+
val dateFormat = SimpleDateFormat("dd/MM", Locale.FRENCH)
54+
val timeInfo = listOfNotNull(
55+
event.startTime?.let { "De: $it" },
56+
event.endTime?.let { "à: $it" }
57+
).joinToString(separator = " ")
58+
5359
return {
5460
TagPill(
5561
label = dateFormat.format(event.date),
5662
backgroundColor = color,
5763
size = 9.sp
5864
)
59-
event.startTime?.let {
65+
if (timeInfo.isNotEmpty()) {
6066
TagPill(
61-
label = event.startTime.toString(),
62-
backgroundColor = color,
63-
size = 9.sp
64-
)
65-
}
66-
event.endTime?.let {
67-
TagPill(
68-
label = event.endTime.toString(),
67+
label = timeInfo,
6968
backgroundColor = color,
7069
size = 9.sp
7170
)
@@ -78,7 +77,8 @@ private fun getTagsList(event: AgendaEvent, eventType: List<AgendaEventType>, co
7877
)
7978
}
8079
event.location?.takeIf { it.isNotEmpty() }?.let {
81-
TagPill(
80+
TagPillCustom(
81+
iconResId = R.drawable.location,
8282
label = it,
8383
backgroundColor = color,
8484
size = 9.sp
@@ -112,13 +112,13 @@ private fun getTagColor(baseColor: Color): Color {
112112
}
113113

114114
private fun getEventTypeIcon(event: AgendaEvent, eventType: List<AgendaEventType>): Int {
115-
return when (eventType.firstOrNull { it.id == event.typeId.toInt() }?.label) {
116-
"XpeUp" -> R.drawable.birthday
117-
"Event interne" -> R.drawable.building
118-
"Formation" -> R.drawable.study
119-
"RSE" -> R.drawable.leaf
120-
"Activité" -> R.drawable.gamepad
121-
"Event externe" -> R.drawable.outside
122-
else -> R.drawable.building
115+
return when (eventType.firstOrNull { it.id == event.typeId.toInt() }?.label) {
116+
"XpeUp" -> R.drawable.birthday
117+
"Event interne" -> R.drawable.building
118+
"Formation" -> R.drawable.study
119+
"RSE" -> R.drawable.leaf
120+
"Activité" -> R.drawable.gamepad
121+
"Event externe" -> R.drawable.outside
122+
else -> R.drawable.building
123123
}
124124
}

app/src/main/java/com/xpeho/xpeapp/ui/components/agenda/AgendaCardList.kt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,34 @@ import androidx.compose.foundation.layout.height
66
import androidx.compose.runtime.Composable
77
import androidx.compose.ui.Modifier
88
import androidx.compose.ui.unit.dp
9-
import com.xpeho.xpeapp.data.model.agenda.AgendaBirthday
10-
import com.xpeho.xpeapp.data.model.agenda.AgendaEvent
119
import com.xpeho.xpeapp.data.model.agenda.AgendaEventType
10+
1211
@Composable
1312
fun AgendaCardList(
14-
events: List<AgendaEvent>,
15-
birthdays: List<AgendaBirthday>,
13+
items: List<AgendaItem>,
1614
eventsTypes: List<AgendaEventType>,
1715
collapsable: Boolean = true
1816
) {
1917
Column {
20-
for (birthday in birthdays) {
21-
AgendaBirthdayCard(
22-
birthday = birthday,
23-
collapsable = collapsable,
24-
defaultOpen = true
25-
)
26-
Spacer(modifier = Modifier.height(10.dp))
27-
}
28-
for (event in events) {
29-
AgendaCard(
30-
event = event,
31-
eventTypes = eventsTypes,
32-
collapsable = collapsable,
33-
defaultOpen = true
34-
)
18+
for (item in items) {
19+
when (item) {
20+
is AgendaBirthdayItem -> {
21+
AgendaBirthdayCard(
22+
birthday = item.birthday,
23+
collapsable = collapsable,
24+
defaultOpen = true
25+
)
26+
}
27+
is AgendaEventItem -> {
28+
AgendaCard(
29+
event = item.event,
30+
eventTypes = eventsTypes,
31+
collapsable = collapsable,
32+
defaultOpen = true
33+
)
34+
}
35+
}
3536
Spacer(modifier = Modifier.height(10.dp))
3637
}
37-
3838
}
3939
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.xpeho.xpeapp.ui.components.agenda
2+
3+
import com.xpeho.xpeapp.data.model.agenda.AgendaBirthday
4+
import com.xpeho.xpeapp.data.model.agenda.AgendaEvent
5+
import java.util.Date
6+
7+
// Common base class to sort the global display by the dates
8+
// of each event and birthday in ascending order
9+
sealed class AgendaItem(val date: Date)
10+
11+
data class AgendaBirthdayItem(val birthday: AgendaBirthday) : AgendaItem(birthday.birthdate)
12+
data class AgendaEventItem(val event: AgendaEvent) : AgendaItem(event.date)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.xpeho.xpeapp.ui.components.layout
2+
3+
import androidx.compose.foundation.layout.Row
4+
import androidx.compose.foundation.layout.Spacer
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.layout.size
7+
import androidx.compose.foundation.layout.width
8+
import androidx.compose.foundation.shape.RoundedCornerShape
9+
import androidx.compose.material3.Card
10+
import androidx.compose.material3.CardDefaults
11+
import androidx.compose.material3.Icon
12+
import androidx.compose.material3.Text
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.graphics.Color
17+
import androidx.compose.ui.res.painterResource
18+
import androidx.compose.ui.text.font.FontWeight
19+
import androidx.compose.ui.text.style.TextOverflow
20+
import androidx.compose.ui.unit.TextUnit
21+
import androidx.compose.ui.unit.dp
22+
import androidx.compose.ui.unit.sp
23+
import com.xpeho.xpeho_ui_android.foundations.Colors
24+
import com.xpeho.xpeho_ui_android.foundations.Fonts
25+
26+
@Composable
27+
fun TagPillCustom(
28+
label: String,
29+
size: TextUnit = 10.sp,
30+
backgroundColor: Color = Colors.GREEN_DARK_COLOR,
31+
labelColor: Color = Color.White,
32+
iconResId: Int? = null
33+
) {
34+
Card(
35+
shape = RoundedCornerShape(6.dp),
36+
colors = CardDefaults.cardColors(
37+
containerColor = backgroundColor,
38+
),
39+
) {
40+
Row(
41+
modifier = Modifier.padding(vertical = 1.dp, horizontal = 4.dp),
42+
verticalAlignment = Alignment.CenterVertically
43+
) {
44+
iconResId?.let {
45+
Icon(
46+
painter = painterResource(id = it),
47+
contentDescription = null,
48+
tint = labelColor,
49+
modifier = Modifier.size(12.dp)
50+
)
51+
Spacer(modifier = Modifier.width(4.dp))
52+
}
53+
Text(
54+
text = label.uppercase(),
55+
fontSize = size,
56+
fontFamily = Fonts.rubik,
57+
fontWeight = FontWeight.Medium,
58+
color = labelColor,
59+
softWrap = false,
60+
overflow = TextOverflow.Ellipsis,
61+
)
62+
}
63+
}
64+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.xpeho.xpeapp.ui.page
2+
3+
import androidx.compose.foundation.layout.fillMaxSize
4+
import androidx.compose.foundation.layout.padding
5+
import androidx.compose.foundation.lazy.LazyColumn
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.LaunchedEffect
8+
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.res.stringResource
10+
import androidx.compose.ui.unit.dp
11+
import androidx.lifecycle.viewmodel.compose.viewModel
12+
import com.xpeho.xpeapp.R
13+
import com.xpeho.xpeapp.ui.components.CustomDialog
14+
import com.xpeho.xpeapp.ui.components.agenda.AgendaBirthdayItem
15+
import com.xpeho.xpeapp.ui.components.agenda.AgendaCardList
16+
import com.xpeho.xpeapp.ui.components.agenda.AgendaEventItem
17+
import com.xpeho.xpeapp.ui.components.layout.Title
18+
import com.xpeho.xpeapp.ui.sendAnalyticsEvent
19+
import com.xpeho.xpeapp.ui.uiState.AgendaUiState
20+
import com.xpeho.xpeapp.ui.uiState.QvstUiState
21+
import com.xpeho.xpeapp.ui.viewModel.agenda.AgendaViewModel
22+
import com.xpeho.xpeapp.ui.viewModel.viewModelFactory
23+
24+
@Composable
25+
fun AgendaPage() {
26+
val agendaViewModel = viewModel<AgendaViewModel>(
27+
factory = viewModelFactory {
28+
AgendaViewModel()
29+
}
30+
)
31+
32+
sendAnalyticsEvent("agenda_page")
33+
34+
LaunchedEffect(Unit) {
35+
agendaViewModel.updateState()
36+
}
37+
38+
LazyColumn(
39+
modifier = Modifier
40+
.padding(horizontal = 24.dp, vertical = 10.dp)
41+
.fillMaxSize(),
42+
) {
43+
when (agendaViewModel.state) {
44+
is AgendaUiState.SUCCESS -> {
45+
item {
46+
Title(label = "Agenda")
47+
val state = agendaViewModel.state as AgendaUiState.SUCCESS
48+
val events = state.agendaEvent.map { AgendaEventItem(it) }
49+
val birthdays = state.agendaBirthday.map { AgendaBirthdayItem(it) }
50+
val items = (events + birthdays).sortedBy { it.date }
51+
AgendaCardList(
52+
items = items,
53+
eventsTypes = state.agendaEventType,
54+
collapsable = true
55+
)
56+
}
57+
}
58+
is AgendaUiState.ERROR -> {
59+
item {
60+
CustomDialog(
61+
title = stringResource(id = R.string.login_page_error_title),
62+
message = (agendaViewModel.state as AgendaUiState.ERROR).error,
63+
) {
64+
agendaViewModel.resetState()
65+
}
66+
}
67+
}
68+
}
69+
}
70+
}

app/src/main/java/com/xpeho/xpeapp/ui/page/HomePage.kt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ import com.xpeho.xpeapp.R
1818
import com.xpeho.xpeapp.XpeApp
1919
import com.xpeho.xpeapp.data.FeatureFlippingEnum
2020
import com.xpeho.xpeapp.data.entity.QvstCampaignEntity
21-
import com.xpeho.xpeapp.data.model.agenda.AgendaBirthday
22-
import com.xpeho.xpeapp.data.model.agenda.AgendaEvent
23-
import com.xpeho.xpeapp.data.model.agenda.AgendaEventType
2421
import com.xpeho.xpeapp.domain.FeatureFlippingState
2522
import com.xpeho.xpeapp.ui.components.CustomDialog
23+
import com.xpeho.xpeapp.ui.components.agenda.AgendaBirthdayItem
2624
import com.xpeho.xpeapp.ui.components.agenda.AgendaCardList
25+
import com.xpeho.xpeapp.ui.components.agenda.AgendaEventItem
2726
import com.xpeho.xpeapp.ui.components.layout.NoContentPlaceHolder
2827
import com.xpeho.xpeapp.ui.components.layout.Title
2928
import com.xpeho.xpeapp.ui.components.newsletter.NewsletterPreview
3029
import com.xpeho.xpeapp.ui.components.qvst.QvstCardList
3130
import com.xpeho.xpeapp.ui.sendAnalyticsEvent
31+
import com.xpeho.xpeapp.ui.uiState.AgendaUiState
3232
import com.xpeho.xpeapp.ui.uiState.QvstActiveUiState
3333
import com.xpeho.xpeapp.ui.viewModel.FeatureFlippingViewModel
3434
import com.xpeho.xpeapp.ui.viewModel.agenda.AgendaViewModel
35-
import com.xpeho.xpeapp.ui.viewModel.agenda.AgendaViewModelState
3635
import com.xpeho.xpeapp.ui.viewModel.newsletter.NewsletterViewModel
3736
import com.xpeho.xpeapp.ui.viewModel.qvst.QvstActiveCampaignsViewModel
3837
import com.xpeho.xpeapp.ui.viewModel.viewModelFactory
@@ -161,29 +160,27 @@ fun HomePage(navigationController: NavController) {
161160
when (agendaViewModel.state) {
162161

163162
// If we successfully loaded the events
164-
is AgendaViewModelState.SUCCESS -> {
163+
is AgendaUiState.SUCCESS -> {
165164
item {
166-
val events: List<AgendaEvent> =
167-
(agendaViewModel.state as AgendaViewModelState.SUCCESS).agendaEvent
168-
val eventsTypes: List<AgendaEventType> =
169-
(agendaViewModel.state as AgendaViewModelState.SUCCESS).agendaEventType
170-
val birthdays: List<AgendaBirthday> =
171-
(agendaViewModel.state as AgendaViewModelState.SUCCESS).agendaBirthday
165+
val state = agendaViewModel.state as AgendaUiState.SUCCESS
166+
val events = state.agendaEvent.map { AgendaEventItem(it) }
167+
val birthdays = state.agendaBirthday.map { AgendaBirthdayItem(it) }
168+
val items = (events + birthdays).sortedBy { it.date }
169+
val eventsTypes = state.agendaEventType
172170
AgendaCardList(
173-
events = events,
171+
items = items,
174172
eventsTypes = eventsTypes,
175-
birthdays = birthdays,
176173
collapsable = false
177174
)
178175
}
179176
}
180177

181178
// If there was an error loading the events
182-
is AgendaViewModelState.ERROR -> {
179+
is AgendaUiState.ERROR -> {
183180
item {
184181
CustomDialog(
185182
title = stringResource(id = R.string.login_page_error_title),
186-
message = (agendaViewModel.state as AgendaViewModelState.ERROR).error,
183+
message = (agendaViewModel.state as AgendaUiState.ERROR).error,
187184
) {
188185
agendaViewModel.resetState()
189186
}

0 commit comments

Comments
 (0)