Bet Creation Screen : Date and Time picker
continuous-integration/drone/push Build is passing Details

pull/3/head
Arthur VALIN 2 years ago
parent 8c0cd243ae
commit 38620fcf49

@ -11,7 +11,7 @@ android {
defaultConfig {
applicationId "fr.iut.alldev.allin"
minSdk 21
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"

@ -4,22 +4,18 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.HelpOutline
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.SportsSoccer
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.BetType
@Composable
fun BetType.getTitle(): String {
fun BetType.getTitle(): Int {
return when (this) {
BetType.YES_NO -> stringResource(id = R.string.yes_no)
BetType.MATCH -> stringResource(id = R.string.sport_match)
BetType.CUSTOM -> stringResource(id = R.string.custom_answers)
BetType.YES_NO -> R.string.yes_no
BetType.MATCH -> R.string.sport_match
BetType.CUSTOM -> R.string.custom_answers
}
}
@Composable
fun BetType.getIcon(): ImageVector {
return when (this) {
BetType.YES_NO -> Icons.AutoMirrored.Default.HelpOutline

@ -34,7 +34,7 @@ fun BetScreenCard(
onClickParticipate: ()->Unit
) {
AllInCard(
modifier = modifier,
modifier = modifier.fillMaxWidth(),
radius = 16.dp
){
Column(

@ -32,7 +32,8 @@ fun BetScreenPopularCard(
modifier: Modifier = Modifier
) {
AllInCard(
modifier = modifier.let {
modifier = modifier
.let {
if(isSystemInDarkTheme()){
it.shadow(
colors = listOf(
@ -51,7 +52,9 @@ fun BetScreenPopularCard(
cornerRadius = 15.dp
)
}
},
}
.fillMaxWidth()
,
backgroundColor = AllInTheme.colors.allIn_Dark,
borderWidth = 2.dp,
borderBrush = AllInTheme.colors.allIn_MainGradient

@ -16,50 +16,43 @@ import fr.iut.alldev.allin.ext.getIcon
import fr.iut.alldev.allin.ext.getTitle
import fr.iut.alldev.allin.ui.betcreation.tabs.BetCreationScreenAnswerTab
import fr.iut.alldev.allin.ui.betcreation.tabs.BetCreationScreenQuestionTab
import fr.iut.alldev.allin.ui.core.AllInSections
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.SectionElement
import fr.iut.alldev.allin.ui.core.SelectionElement
import fr.iut.alldev.allin.ui.core.*
import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime
@Composable
fun BetCreationScreen(
) {
var theme by remember{
mutableStateOf("")
}
var phrase by remember{
mutableStateOf("")
}
var isPublic by remember{
mutableStateOf(true)
}
val betTypes = remember {
BetType.values().toList()
}
val selectedFriends = remember {
mutableListOf<Int>()
}
var theme by remember{ mutableStateOf("") }
var phrase by remember{ mutableStateOf("") }
val (registerDate, setRegisterDate) = remember { mutableStateOf<ZonedDateTime>(ZonedDateTime.now()) }
val (registerTime, setRegisterTime) = remember { mutableStateOf<ZonedDateTime>(ZonedDateTime.now()) }
val (betDate, setBetDate) = remember { mutableStateOf<ZonedDateTime>(ZonedDateTime.now()) }
val (betTime, setBetTime) = remember { mutableStateOf<ZonedDateTime>(ZonedDateTime.now()) }
var isPublic by remember{ mutableStateOf(true) }
val betTypes = remember { BetType.values().toList() }
val selectedFriends = remember { mutableListOf<Int>() }
val selectedBetType by remember { mutableStateOf(betTypes[0]) }
var selectionElements by remember { mutableStateOf(listOf<SelectionElement>()) }
var selectedBetTypeElement by remember { mutableStateOf<SelectionElement?>(null)}
val elements = betTypes.map {
LaunchedEffect(key1 = betTypes) {
selectionElements = betTypes.map {
SelectionElement(
it.getTitle(),
it.getIcon()
textId = it.getTitle(),
imageVector = it.getIcon()
)
}
var selected by remember {
mutableStateOf(elements[0])
selectedBetTypeElement = selectionElements.getOrNull(0)
}
val selectedBetType by remember {
derivedStateOf {
betTypes[elements.indexOf(selected)]
}
}
val (showRegisterDatePicker, setRegisterDatePicker) = remember { mutableStateOf(false) }
val (showEndDatePicker, setEndDatePicker) = remember { mutableStateOf(false) }
val (showRegisterTimePicker, setRegisterTimePicker) = remember { mutableStateOf(false) }
val (showEndTimePicker, setEndTimePicker) = remember { mutableStateOf(false) }
Box(
Modifier
@ -82,6 +75,14 @@ fun BetCreationScreen(
setBetTheme = { theme = it },
nbFriends = 42,
selectedFriends = selectedFriends,
registerDate = registerDate,
betDate = betDate,
registerTime = registerTime,
betTime = betTime,
setRegisterDateDialog = { setRegisterDatePicker(it) },
setEndDateDialog = { setEndDatePicker(it) },
setRegisterTimeDialog = { setRegisterTimePicker(it) },
setEndTimeDialog = { setEndTimePicker(it) },
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
@ -91,9 +92,9 @@ fun BetCreationScreen(
SectionElement(stringResource(id = R.string.Answer)){
BetCreationScreenAnswerTab(
selectedBetType = selectedBetType,
selected = selected,
setSelected = { selected = it },
elements = elements,
selected = selectedBetTypeElement,
setSelected = { selectedBetTypeElement = it },
elements = selectionElements,
modifier = Modifier
.fillMaxSize()
.padding(vertical = 12.dp, horizontal = 20.dp)
@ -111,4 +112,47 @@ fun BetCreationScreen(
}
)
}
if (showRegisterDatePicker || showEndDatePicker) {
AllInDatePicker(
currentDate = if(showRegisterDatePicker) registerDate else betDate,
onSelectDate = { date ->
val selectedDate = ZonedDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.systemDefault())
if(showRegisterDatePicker) {
setRegisterDate(selectedDate)
} else {
setBetDate(selectedDate)
}
setRegisterDatePicker(false)
setEndDatePicker(false)
},
onDismiss = {
setRegisterDatePicker(false)
setEndDatePicker(false)
}
)
}
if (showRegisterTimePicker || showEndTimePicker) {
val timeToEdit = if(showRegisterTimePicker) registerTime else betTime
AllInTimePicker(
hour = timeToEdit.hour,
minutes = timeToEdit.minute,
onSelectHour = { hour, min ->
val time = (timeToEdit)
.withHour(hour)
.withMinute(min)
if(showRegisterDatePicker) {
setRegisterTime(time)
} else {
setBetTime(time)
}
setRegisterTimePicker(false)
setEndTimePicker(false)
},
onDismiss = {
setRegisterTimePicker(false)
setEndTimePicker(false)
}
)
}
}

@ -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 = {}
)
}
}

@ -15,7 +15,7 @@ import fr.iut.alldev.allin.ui.core.SelectionElement
@Composable
fun BetCreationScreenAnswerTab(
modifier: Modifier = Modifier,
selected: SelectionElement,
selected: SelectionElement?,
selectedBetType: BetType,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
@ -24,6 +24,7 @@ fun BetCreationScreenAnswerTab(
mutableStateOf(false)
}
Column(modifier) {
AllInSelectionBox(
isOpen = isOpen,
@ -44,10 +45,14 @@ fun BetCreationScreenAnswerTab(
}
}
BetType.MATCH -> {
BetCreationScreenBottomText(text = selectedBetType.getTitle())
BetCreationScreenBottomText(
text = stringResource(selectedBetType.getTitle())
)
}
BetType.CUSTOM -> {
BetCreationScreenBottomText(text = selectedBetType.getTitle())
BetCreationScreenBottomText(
text = stringResource(selectedBetType.getTitle())
)
}
}
}

@ -2,26 +2,16 @@ package fr.iut.alldev.allin.ui.betcreation.tabs
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.relocation.BringIntoViewRequester
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 androidx.compose.ui.unit.sp
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.core.AllInTextField
import fr.iut.alldev.allin.ui.theme.AllInTheme
import fr.iut.alldev.allin.data.ext.formatToMediumDate
import fr.iut.alldev.allin.data.ext.formatToTime
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabDateTimeSection
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabPrivacySection
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabThemePhraseSection
import java.time.ZonedDateTime
@OptIn(ExperimentalFoundationApi::class)
@Composable
@ -34,141 +24,42 @@ fun BetCreationScreenQuestionTab(
setBetPhrase: (String)->Unit,
isPublic: Boolean,
setIsPublic: (Boolean)->Unit,
selectedFriends: MutableList<Int>
registerDate: ZonedDateTime,
betDate: ZonedDateTime,
registerTime: ZonedDateTime,
betTime: ZonedDateTime,
selectedFriends: MutableList<Int>,
setRegisterDateDialog: (Boolean)->Unit,
setEndDateDialog: (Boolean)->Unit,
setRegisterTimeDialog: (Boolean)->Unit,
setEndTimeDialog: (Boolean)->Unit
) {
val bringIntoViewRequester = remember { BringIntoViewRequester() }
Column(modifier){
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)
QuestionTabThemePhraseSection(
betTheme = betTheme,
setBetTheme = setBetTheme,
betPhrase = betPhrase,
setBetPhrase = setBetPhrase,
bringIntoViewRequester = bringIntoViewRequester
)
Spacer(modifier = Modifier.height(35.dp))
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
QuestionTabDateTimeSection(
registerDate = registerDate.formatToMediumDate(),
registerTime = registerTime.formatToTime(),
endDate = betDate.formatToMediumDate(),
endTime = betTime.formatToTime(),
setEndDateDialog = setEndDateDialog,
setRegisterDateDialog = setRegisterDateDialog,
setRegisterTimeDialog = setRegisterTimeDialog,
setEndTimeDialog = setEndTimeDialog
)
AllInIconChip(
text = stringResource(id = R.string.Private),
leadingIcon = Icons.Default.Lock,
onClick = {
setIsPublic(false)
},
isSelected = !isPublic
Spacer(modifier = Modifier.height(44.dp))
QuestionTabPrivacySection(
isPublic = isPublic,
setIsPublic = setIsPublic,
nbFriends = nbFriends,
selectedFriends = selectedFriends
)
}
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(172.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,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)
)
}

@ -2,7 +2,6 @@ package fr.iut.alldev.allin.ui.core
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
@ -34,7 +33,7 @@ fun AllInCard(
) {
val cardShape = AbsoluteSmoothCornerShape(radius, smoothnessAsPercent = 100)
val cardModifier = modifier.fillMaxWidth()
val cardModifier = modifier
.run {
backgroundBrush?.let{
this.clip(cardShape).background(it)

@ -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 = {}
)
}
}

@ -20,7 +20,8 @@ fun AllInGradientButton(
) {
AllInCard(
onClick = onClick,
modifier = modifier.shadow(
modifier = modifier
.shadow(
colors = listOf(
AllInTheme.colors.allIn_Pink,
AllInTheme.colors.allIn_Blue
@ -28,7 +29,8 @@ fun AllInGradientButton(
blurRadius = 20.dp,
alpha = .5f,
cornerRadius = 15.dp
),
)
.fillMaxWidth(),
radius = 10.dp,
backgroundBrush = AllInTheme.colors.allIn_MainGradient
) {

@ -31,7 +31,7 @@ fun AllInRetractableCard(
content: @Composable ()->Unit
) {
AllInCard(
modifier = modifier,
modifier = modifier.fillMaxWidth(),
borderWidth = borderWidth,
borderColor = AllInTheme.colors.allIn_Purple.copy(.5f)
){

@ -16,21 +16,23 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.theme.AllInTheme
class SelectionElement(
val text: String,
val iconVector: ImageVector
val textId: Int,
val imageVector: ImageVector
)
@Composable
fun AllInSelectionLine(
text: String,
iconVector: ImageVector,
iconVector: ImageVector?,
modifier: Modifier = Modifier,
onClick: ()->Unit,
trailingIcon: ImageVector? = null,
@ -47,12 +49,14 @@ fun AllInSelectionLine(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
iconVector?.let {
Icon(
imageVector = iconVector,
imageVector = it,
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
modifier = Modifier.size(20.dp)
)
}
Text(
text = text,
color = AllInTheme.colors.allIn_Purple,
@ -78,18 +82,22 @@ fun AllInSelectionBox(
modifier: Modifier = Modifier,
isOpen: Boolean,
setIsOpen: (Boolean)->Unit,
selected: SelectionElement,
selected: SelectionElement?,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
) {
val interactionSource = remember { MutableInteractionSource() }
AllInCard(modifier){
AllInCard(modifier.fillMaxWidth()){
Column(
Modifier.animateContentSize()
) {
AllInSelectionLine(
text = selected.text,
iconVector = selected.iconVector,
text = selected?.let{
stringResource(id = it.textId)
} ?: "",
iconVector = selected?.let{
selected.imageVector
},
onClick = { setIsOpen(!isOpen) },
interactionSource = interactionSource,
trailingIcon = with(Icons.Default){
@ -101,8 +109,8 @@ fun AllInSelectionBox(
elements.filter { it != selected }.forEach{
element ->
AllInSelectionLine(
text = element.text,
iconVector = element.iconVector,
text = stringResource(id = element.textId),
iconVector = element.imageVector,
interactionSource = interactionSource,
onClick = {
setSelected(element)
@ -121,9 +129,9 @@ fun AllInSelectionBox(
private fun AllInSelectionBoxClosedPreview() {
AllInTheme {
val elements = listOf(
SelectionElement("Oui/Non", Icons.AutoMirrored.Default.HelpOutline),
SelectionElement("Sport", Icons.Default.SportsFootball),
SelectionElement("Perso", Icons.Default.PinEnd)
SelectionElement(R.string.yes_no, Icons.AutoMirrored.Default.HelpOutline),
SelectionElement(R.string.sport_match, Icons.Default.SportsFootball),
SelectionElement(R.string.custom_answers, Icons.Default.PinEnd)
)
AllInSelectionBox(
isOpen = false,
@ -141,9 +149,9 @@ private fun AllInSelectionBoxClosedPreview() {
private fun AllInSelectionBoxOpenPreview() {
AllInTheme {
val elements = listOf(
SelectionElement("Oui/Non", Icons.AutoMirrored.Default.HelpOutline),
SelectionElement("Sport", Icons.Default.SportsFootball),
SelectionElement("Perso", Icons.Default.Edit)
SelectionElement(R.string.yes_no, Icons.AutoMirrored.Default.HelpOutline),
SelectionElement(R.string.sport_match, Icons.Default.SportsFootball),
SelectionElement(R.string.custom_answers, Icons.Default.Edit)
)
AllInSelectionBox(
isOpen = true,

@ -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 = {}
)
}
}

@ -25,7 +25,7 @@ fun RainbowButton(
AllInCard(
borderWidth = if (enabled) 1.dp else 2.dp,
onClick = onClick,
modifier = modifier,
modifier = modifier.fillMaxWidth(),
enabled = enabled
) {
val textStyle =

@ -24,8 +24,8 @@ import fr.iut.alldev.allin.ui.theme.AllInTheme
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LoginScreen(
onClickLogin: ()->Unit,
onClickRegister: ()->Unit,
navigateToDashboard: ()->Unit,
navigateToRegister: ()->Unit,
loginViewModel: LoginViewModel = hiltViewModel()
) {
@ -98,7 +98,7 @@ fun LoginScreen(
) {
AllInGradientButton(
text = stringResource(id = R.string.Login),
onClick = onClickLogin,
onClick = navigateToDashboard,
modifier = Modifier
)
Spacer(modifier = Modifier.height(30.dp))
@ -122,7 +122,7 @@ fun LoginScreen(
fontWeight = FontWeight.Bold
)
) {
onClickRegister()
navigateToRegister()
}
}
}

@ -98,10 +98,10 @@ private fun NavGraphBuilder.allInWelcomeScreen(
){
composable(route = Routes.WELCOME){
WelcomeScreen(
onClickJoin = {
navigateToRegister = {
navController.popUpTo(Routes.REGISTER, Routes.WELCOME)
},
onClickLogin = {
navigateToLogin = {
navController.popUpTo(Routes.LOGIN, Routes.WELCOME)
}
)
@ -113,10 +113,10 @@ private fun NavGraphBuilder.allInRegisterScreen(
){
composable(route = Routes.REGISTER){
RegisterScreen(
onClickRegister = {
navigateToDashboard = {
navController.popUpTo(Routes.DASHBOARD, Routes.REGISTER)
},
onClickLogin = {
navigateToLogin = {
navController.popUpTo(Routes.LOGIN, Routes.REGISTER)
}
)
@ -128,10 +128,10 @@ private fun NavGraphBuilder.allInLoginScreen(
){
composable(route = Routes.LOGIN){
LoginScreen(
onClickRegister = {
navigateToRegister = {
navController.popUpTo(Routes.REGISTER, Routes.LOGIN)
},
onClickLogin = {
navigateToDashboard = {
navController.popUpTo(Routes.DASHBOARD, Routes.LOGIN)
}
)

@ -26,8 +26,8 @@ import fr.iut.alldev.allin.ui.theme.AllInTheme
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun RegisterScreen(
onClickRegister: () -> Unit,
onClickLogin: () -> Unit,
navigateToDashboard: () -> Unit,
navigateToLogin: () -> Unit,
registerViewModel: RegisterViewModel = hiltViewModel(),
) {
val (username, setUsername) = remember{ registerViewModel.username }
@ -118,7 +118,7 @@ fun RegisterScreen(
) {
AllInGradientButton(
text = stringResource(id = R.string.Register),
onClick = onClickRegister
onClick = navigateToDashboard
)
Spacer(modifier = Modifier.height(30.dp))
Row(
@ -140,7 +140,7 @@ fun RegisterScreen(
fontWeight = FontWeight.Bold
)
) {
onClickLogin()
navigateToLogin()
}
}
}

@ -24,8 +24,8 @@ import fr.iut.alldev.allin.ui.theme.AllInTheme
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun WelcomeScreen(
onClickJoin: ()->Unit,
onClickLogin: ()->Unit
navigateToRegister: ()->Unit,
navigateToLogin: ()->Unit
) {
Box(
Modifier
@ -75,7 +75,7 @@ fun WelcomeScreen(
color = AllInTheme.themeColors.tint_1,
text = stringResource(id = R.string.join),
textColor = AllInTheme.themeColors.background,
onClick = onClickJoin,
onClick = navigateToRegister,
modifier = Modifier.padding(bottom = 13.dp)
)
Row(
@ -97,7 +97,7 @@ fun WelcomeScreen(
fontWeight = FontWeight.Bold
)
){
onClickLogin()
navigateToLogin()
}
}
}
@ -109,6 +109,6 @@ fun WelcomeScreen(
@Composable
private fun WelcomeScreenPreview() {
AllInTheme{
WelcomeScreen(onClickJoin = {}, onClickLogin = {})
WelcomeScreen(navigateToRegister = {}, navigateToLogin = {})
}
}

@ -9,6 +9,9 @@
<string name="forgot_password">Mot de passe oublié ?</string>
<string name="no_account">Pas encore inscrit ?</string>
<string name="Register">S\'inscrire</string>
<string name="Validate">Valider</string>
<string name="Cancel">Annuler</string>
<!--Drawer-->
<string name="bets">Bets</string>
<string name="best_win">Meilleur gain</string>

@ -12,6 +12,8 @@
<string name="forgot_password">Forgot password ?</string>
<string name="no_account">Don\'t have an account ?</string>
<string name="Register">Register</string>
<string name="Validate">Validate</string>
<string name="Cancel">Cancel</string>
<!--Drawer-->
<string name="bets">Bets</string>

@ -9,7 +9,7 @@ android {
compileSdk 34
defaultConfig {
minSdk 21
minSdk 26
targetSdk 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

@ -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…
Cancel
Save