Bet Creation Screen : Date and Time picker
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
8c0cd243ae
commit
38620fcf49
@ -0,0 +1,45 @@
|
||||
package fr.iut.alldev.allin.ui.betcreation.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import fr.iut.alldev.allin.ui.core.AllInCard
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
|
||||
@Composable
|
||||
fun BetCreationScreenDateTimeButton(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String,
|
||||
onClick: ()->Unit
|
||||
) {
|
||||
AllInCard(
|
||||
modifier = modifier,
|
||||
radius = 10.dp,
|
||||
onClick = onClick
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
color = AllInTheme.colors.allIn_Purple,
|
||||
style = AllInTheme.typography.h2,
|
||||
fontSize = 16.sp,
|
||||
modifier = Modifier.padding(horizontal = 23.dp, vertical = 9.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun BetCreationScreenDateTimeButtonPreview() {
|
||||
AllInTheme {
|
||||
BetCreationScreenDateTimeButton(
|
||||
text = "13:00",
|
||||
onClick = {}
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package fr.iut.alldev.allin.ui.betcreation.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
|
||||
@Composable
|
||||
fun BetCreationScreenDateTimeRow(
|
||||
modifier: Modifier = Modifier,
|
||||
date: String,
|
||||
time: String,
|
||||
onClickDate: ()->Unit,
|
||||
onClickTime: ()->Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
){
|
||||
BetCreationScreenDateTimeButton(text = date, onClick = onClickDate)
|
||||
BetCreationScreenDateTimeButton(text = time, onClick = onClickTime)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun BetCreationScreenDateTimeRowPreview() {
|
||||
AllInTheme {
|
||||
BetCreationScreenDateTimeRow(
|
||||
date = "Sept. 11, 2023",
|
||||
time = "13:00",
|
||||
onClickDate = {},
|
||||
onClickTime = {}
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import fr.iut.alldev.allin.R
|
||||
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenDateTimeRow
|
||||
import fr.iut.alldev.allin.ui.core.AllInTextAndIcon
|
||||
|
||||
@Composable
|
||||
internal fun QuestionTabDateTimeSection(
|
||||
setRegisterDateDialog: (Boolean)->Unit,
|
||||
setEndDateDialog: (Boolean)->Unit,
|
||||
setRegisterTimeDialog: (Boolean)->Unit,
|
||||
setEndTimeDialog: (Boolean)->Unit,
|
||||
registerDate: String,
|
||||
registerTime: String,
|
||||
endDate: String,
|
||||
endTime: String
|
||||
) {
|
||||
AllInTextAndIcon(
|
||||
text = stringResource(id = R.string.End_registration_date),
|
||||
icon = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||
modifier = Modifier.padding(start = 11.dp, bottom = 8.dp),
|
||||
onClick = {}
|
||||
)
|
||||
BetCreationScreenDateTimeRow(
|
||||
date = registerDate,
|
||||
time = registerTime,
|
||||
onClickDate = { setRegisterDateDialog(true) },
|
||||
onClickTime = { setRegisterTimeDialog(true) },
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
AllInTextAndIcon(
|
||||
text = stringResource(id = R.string.End_bet_date),
|
||||
icon = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||
modifier = Modifier.padding(start = 11.dp, bottom = 8.dp),
|
||||
onClick = {}
|
||||
)
|
||||
BetCreationScreenDateTimeRow(
|
||||
date = endDate,
|
||||
time = endTime,
|
||||
onClickDate = { setEndDateDialog(true) },
|
||||
onClickTime = { setEndTimeDialog(true) },
|
||||
)
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.material.icons.filled.Public
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import fr.iut.alldev.allin.R
|
||||
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenBottomText
|
||||
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenFriendLine
|
||||
import fr.iut.alldev.allin.ui.core.AllInIconChip
|
||||
import fr.iut.alldev.allin.ui.core.AllInRetractableCard
|
||||
import fr.iut.alldev.allin.ui.core.AllInTextAndIcon
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
|
||||
@Composable
|
||||
fun QuestionTabPrivacySection(
|
||||
isPublic: Boolean,
|
||||
setIsPublic: (Boolean)->Unit,
|
||||
nbFriends: Int,
|
||||
selectedFriends: MutableList<Int>
|
||||
) {
|
||||
AllInTextAndIcon(
|
||||
text = stringResource(id = R.string.Bet_privacy),
|
||||
icon = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||
modifier = Modifier.padding(start = 11.dp, bottom = 8.dp),
|
||||
onClick = {}
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.padding(bottom = 10.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
){
|
||||
AllInIconChip(
|
||||
text = stringResource(id = R.string.Public),
|
||||
leadingIcon = Icons.Default.Public,
|
||||
onClick = {
|
||||
setIsPublic(true)
|
||||
},
|
||||
isSelected = isPublic
|
||||
)
|
||||
AllInIconChip(
|
||||
text = stringResource(id = R.string.Private),
|
||||
leadingIcon = Icons.Default.Lock,
|
||||
onClick = {
|
||||
setIsPublic(false)
|
||||
},
|
||||
isSelected = !isPublic
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(17.dp)
|
||||
) {
|
||||
var isOpen by remember{
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
if(isPublic){
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(17.dp)
|
||||
) {
|
||||
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_1))
|
||||
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_2))
|
||||
}
|
||||
}else{
|
||||
AllInRetractableCard(
|
||||
text = stringResource(
|
||||
id = R.string.n_friends_available,
|
||||
nbFriends,
|
||||
nbFriends
|
||||
),
|
||||
borderWidth = 1.dp,
|
||||
boldText = nbFriends.toString(),
|
||||
isOpen = isOpen,
|
||||
setIsOpen = { isOpen = it }
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.height(165.dp)
|
||||
){
|
||||
items(nbFriends){
|
||||
val isSelected = remember{
|
||||
selectedFriends.contains(it)
|
||||
}
|
||||
|
||||
var wasClicked by remember{
|
||||
mutableStateOf(isSelected)
|
||||
}
|
||||
|
||||
if(it!=0){
|
||||
HorizontalDivider(color = AllInTheme.themeColors.border)
|
||||
}
|
||||
BetCreationScreenFriendLine(
|
||||
username = "Dave",
|
||||
allCoinsAmount = 542,
|
||||
isSelected = wasClicked
|
||||
) {
|
||||
wasClicked = ! wasClicked
|
||||
if (isSelected) {
|
||||
selectedFriends.remove(it)
|
||||
} else {
|
||||
selectedFriends.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(17.dp)
|
||||
) {
|
||||
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_1))
|
||||
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_2))
|
||||
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_3))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import fr.iut.alldev.allin.R
|
||||
import fr.iut.alldev.allin.ui.core.AllInTextAndIcon
|
||||
import fr.iut.alldev.allin.ui.core.AllInTextField
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
internal fun QuestionTabThemePhraseSection(
|
||||
betTheme: String,
|
||||
setBetTheme: (String)->Unit,
|
||||
betPhrase: String,
|
||||
setBetPhrase: (String)->Unit,
|
||||
bringIntoViewRequester: BringIntoViewRequester
|
||||
) {
|
||||
AllInTextAndIcon(
|
||||
text = stringResource(id = R.string.Theme),
|
||||
icon = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||
modifier = Modifier.padding(start = 11.dp, bottom = 8.dp),
|
||||
onClick = {}
|
||||
)
|
||||
AllInTextField(
|
||||
placeholder = stringResource(id = R.string.Theme_placeholder),
|
||||
value = betPhrase,
|
||||
onValueChange = setBetPhrase,
|
||||
bringIntoViewRequester = bringIntoViewRequester,
|
||||
borderColor = AllInTheme.colors.white,
|
||||
maxChar = 20,
|
||||
placeholderFontSize = 13.sp,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
AllInTextAndIcon(
|
||||
text = stringResource(id = R.string.Bet_Phrase),
|
||||
icon = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||
modifier = Modifier.padding(start = 11.dp, bottom = 8.dp),
|
||||
onClick = {}
|
||||
)
|
||||
AllInTextField(
|
||||
placeholder = stringResource(id = R.string.Bet_Phrase_placeholder),
|
||||
value = betTheme,
|
||||
borderColor = AllInTheme.colors.white,
|
||||
onValueChange = setBetTheme,
|
||||
bringIntoViewRequester = bringIntoViewRequester,
|
||||
multiLine = true,
|
||||
maxChar = 100,
|
||||
placeholderFontSize = 13.sp,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(100.dp)
|
||||
)
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package fr.iut.alldev.allin.ui.core
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import fr.iut.alldev.allin.R
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
import java.time.ZonedDateTime
|
||||
import java.util.*
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AllInDatePicker(
|
||||
currentDate: ZonedDateTime?,
|
||||
onSelectDate: (Long) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val calendar = Calendar.getInstance()
|
||||
val realDate = currentDate?.toEpochSecond()?.let {
|
||||
val offset = calendar.timeZone.getOffset(it * 1000L)
|
||||
(it * 1000L) + offset
|
||||
}
|
||||
val datePickerState = rememberDatePickerState(
|
||||
initialSelectedDateMillis = realDate
|
||||
)
|
||||
|
||||
DatePickerDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
datePickerState.selectedDateMillis?.let {
|
||||
onSelectDate(it)
|
||||
} ?: run {
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.Validate),
|
||||
style = AllInTheme.typography.h1.copy(
|
||||
brush = AllInTheme.colors.allIn_MainGradient
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.Cancel),
|
||||
color = AllInTheme.themeColors.on_background_2,
|
||||
style = AllInTheme.typography.h3
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = DatePickerDefaults.colors(
|
||||
containerColor = AllInTheme.themeColors.main_surface
|
||||
)
|
||||
){
|
||||
DatePicker(
|
||||
state = datePickerState,
|
||||
colors = DatePickerDefaults.colors(
|
||||
todayDateBorderColor = AllInTheme.colors.allIn_Blue,
|
||||
selectedDayContainerColor = AllInTheme.colors.allIn_Blue,
|
||||
todayContentColor = AllInTheme.colors.allIn_Blue,
|
||||
dayContentColor = AllInTheme.colors.allIn_Blue,
|
||||
dividerColor = AllInTheme.themeColors.border,
|
||||
containerColor = AllInTheme.themeColors.background,
|
||||
titleContentColor = AllInTheme.themeColors.on_main_surface,
|
||||
headlineContentColor = AllInTheme.themeColors.on_main_surface,
|
||||
subheadContentColor = AllInTheme.themeColors.on_background_2,
|
||||
dateTextFieldColors = OutlinedTextFieldDefaults.colors(
|
||||
focusedContainerColor = AllInTheme.themeColors.main_surface,
|
||||
unfocusedContainerColor = AllInTheme.themeColors.main_surface,
|
||||
focusedBorderColor = AllInTheme.colors.allIn_Purple,
|
||||
unfocusedBorderColor = AllInTheme.themeColors.border,
|
||||
focusedTextColor = AllInTheme.themeColors.on_main_surface,
|
||||
unfocusedTextColor = AllInTheme.themeColors.on_main_surface,
|
||||
focusedLabelColor = AllInTheme.colors.allIn_Purple,
|
||||
unfocusedLabelColor = AllInTheme.themeColors.on_main_surface,
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun AllInDatePickerPreview() {
|
||||
AllInTheme {
|
||||
AllInDatePicker(
|
||||
currentDate = ZonedDateTime.now(),
|
||||
onSelectDate = {},
|
||||
onDismiss = {}
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package fr.iut.alldev.allin.ui.core
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import fr.iut.alldev.allin.R
|
||||
import fr.iut.alldev.allin.ui.theme.AllInTheme
|
||||
import java.util.*
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AllInTimePicker(
|
||||
hour: Int?,
|
||||
minutes: Int?,
|
||||
onSelectHour: (Int, Int) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val calendar = Calendar.getInstance()
|
||||
val timePickerState = rememberTimePickerState(
|
||||
is24Hour = true,
|
||||
initialHour = hour ?: calendar.get(Calendar.HOUR_OF_DAY),
|
||||
initialMinute = minutes ?: calendar.get(Calendar.MINUTE)
|
||||
)
|
||||
|
||||
DatePickerDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onSelectHour(timePickerState.hour, timePickerState.minute)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.Validate),
|
||||
style = AllInTheme.typography.h1.copy(
|
||||
brush = AllInTheme.colors.allIn_MainGradient
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.Cancel),
|
||||
color = AllInTheme.themeColors.on_background_2,
|
||||
style = AllInTheme.typography.h3
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = DatePickerDefaults.colors(
|
||||
containerColor = AllInTheme.themeColors.main_surface
|
||||
)
|
||||
){
|
||||
TimePicker(
|
||||
state = timePickerState,
|
||||
colors = TimePickerDefaults.colors(
|
||||
selectorColor = AllInTheme.colors.allIn_Pink,
|
||||
containerColor = AllInTheme.themeColors.background,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun AllInTimePickerPreview() {
|
||||
AllInTheme {
|
||||
AllInTimePicker(
|
||||
hour = 13,
|
||||
minutes = 13,
|
||||
onSelectHour = { h, m -> },
|
||||
onDismiss = {}
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package fr.iut.alldev.allin.data.ext
|
||||
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
fun ZonedDateTime.formatToMediumDate(): String {
|
||||
return this.format(
|
||||
DateTimeFormatter.ofPattern("dd MMM. yyyy")
|
||||
).replaceFirstChar { it.uppercase() }
|
||||
}
|
||||
|
||||
fun ZonedDateTime.formatToTime(): String {
|
||||
return this.format(
|
||||
DateTimeFormatter.ofPattern("hh:mm")
|
||||
).replaceFirstChar { it.uppercase() }
|
||||
}
|
Loading…
Reference in new issue