Skip to content

Commit

Permalink
Merge pull request #278 from PermanentOrg/VSP-1350
Browse files Browse the repository at this point in the history
Chart your path to success screen implementation for phone.
  • Loading branch information
flaviahandrea-vsp authored May 21, 2024
2 parents 2e302e2 + 4515d44 commit 53fcb2c
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.permanent.permanent.R
import org.permanent.permanent.models.ArchiveType
import org.permanent.permanent.ui.composeComponents.CustomProgressIndicator
import org.permanent.permanent.viewmodels.ArchiveOnboardingViewModel
import java.util.EnumMap

@Composable
fun ArchiveOnboardingScreen(
Expand All @@ -57,7 +58,7 @@ fun ArchiveOnboardingScreen(
type = ArchiveType.PERSON,
typeName = context.getString(R.string.personal),
name = "",
goals = "",
goals = EnumMap(OnboardingGoal::class.java),
priorities = ""
)
)
Expand Down Expand Up @@ -120,12 +121,26 @@ fun ArchiveOnboardingScreen(
OnboardingPage.ARCHIVE_TYPE_PAGE.value -> ArchiveTypePage(isTablet = isTablet,
pagerState = pagerState,
onArchiveTypeClick = { type: ArchiveType, typeName: String ->
val archive = NewArchive(type = type, typeName = typeName, "", "", "")
val archive = NewArchive(
type = type,
typeName = typeName,
name = "",
goals = EnumMap(OnboardingGoal::class.java),
priorities = ""
)
newArchive = archive
})

else -> ArchiveNamePage(
isTablet = isTablet, pagerState = pagerState, newArchive = newArchive
OnboardingPage.ARCHIVE_NAME_PAGE.value -> ArchiveNamePage(
isTablet = isTablet,
pagerState = pagerState,
newArchive = newArchive
)

OnboardingPage.GOALS_PAGE.value -> GoalsPage(
isTablet = isTablet,
pagerState = pagerState,
newArchive = newArchive
)
}
}
Expand Down Expand Up @@ -165,10 +180,21 @@ data class NewArchive(
var type: ArchiveType,
var typeName: String,
var name: String,
var goals: String?,
var goals: EnumMap<OnboardingGoal, Boolean>,
var priorities: String?
)

enum class OnboardingGoal {
CAPTURE,
DIGITIZE,
COLLABORATE,
CREATE_AN_ARCHIVE,
SHARE,
CREATE_A_PLAN,
ORGANIZE,
SOMETHING_ELSE
}

enum class OnboardingPage(val value: Int) {
WELCOME_PAGE(0),
ARCHIVE_TYPE_PAGE(1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private fun TabletBody(
) else stringResource(id = R.string.lets_create_a_archive, archiveTypeName)

TextAndIconButton(
style = ButtonColor.LIGHT, text = text, showButtonEnabled = true
style = ButtonColor.LIGHT, text = text
) {
coroutineScope.launch {
pagerState.animateScrollToPage(OnboardingPage.ARCHIVE_NAME_PAGE.value)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
@file:OptIn(ExperimentalFoundationApi::class)

package org.permanent.permanent.ui.archiveOnboarding.compose

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.permanent.permanent.R
import org.permanent.permanent.ui.composeComponents.ButtonColor
import org.permanent.permanent.ui.composeComponents.ButtonIconAlignment
import org.permanent.permanent.ui.composeComponents.CustomCheckbox
import org.permanent.permanent.ui.composeComponents.SmallTextAndIconButton


@Composable
fun GoalsPage(
isTablet: Boolean, pagerState: PagerState, newArchive: NewArchive
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
val whiteColor = Color(ContextCompat.getColor(context, R.color.white))
val regularFont = FontFamily(Font(R.font.open_sans_regular_ttf))

if (isTablet) {
TabletBody(
whiteColor, regularFont, coroutineScope, pagerState, newArchive
)
} else {
PhoneBody(
whiteColor, regularFont, coroutineScope, pagerState, newArchive
)
}
}

@Composable
private fun PhoneBody(
whiteColor: Color,
regularFont: FontFamily,
coroutineScope: CoroutineScope,
pagerState: PagerState,
newArchive: NewArchive
) {
val scrollState = rememberScrollState()
val captureCheckedState = remember { mutableStateOf(false) }
val digitizeCheckedState = remember { mutableStateOf(false) }
val collaborateCheckedState = remember { mutableStateOf(false) }
val createArchiveCheckedState = remember { mutableStateOf(false) }
val shareCheckedState = remember { mutableStateOf(false) }
val createPlanCheckedState = remember { mutableStateOf(false) }
val organizeCheckedState = remember { mutableStateOf(false) }
val somethingElseCheckedState = remember { mutableStateOf(false) }

Column(
modifier = Modifier
.fillMaxHeight()
.padding(vertical = 32.dp)
.verticalScroll(scrollState),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
val titleText = stringResource(id = R.string.chart_your_path_title)
val boldedWord = "path"
val start = titleText.indexOf(boldedWord)
val spanStyles = listOf(
AnnotatedString.Range(
SpanStyle(fontWeight = FontWeight.Bold),
start = start,
end = start + boldedWord.length
)
)

Text(
text = AnnotatedString(text = titleText, spanStyles = spanStyles),
fontSize = 32.sp,
lineHeight = 48.sp,
color = whiteColor,
fontFamily = regularFont
)

Text(
text = stringResource(id = R.string.chart_your_path_description),
fontSize = 14.sp,
lineHeight = 24.sp,
color = whiteColor,
fontFamily = regularFont
)

Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CustomCheckbox(
isTablet = false,
text = stringResource(id = R.string.goals_capture),
checkedState = captureCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_digitize),
checkedState = digitizeCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_collaborate),
checkedState = collaborateCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_create_an_archive),
checkedState = createArchiveCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_share), checkedState = shareCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_create_a_plan),
checkedState = createPlanCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_organize),
checkedState = organizeCheckedState
)
CustomCheckbox(
text = stringResource(id = R.string.goals_something_else),
checkedState = somethingElseCheckedState
)
}

Row(
modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(24.dp)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
SmallTextAndIconButton(
buttonColor = ButtonColor.TRANSPARENT,
text = stringResource(id = R.string.back),
icon = painterResource(id = R.drawable.ic_arrow_back_rounded_white),
iconAlignment = ButtonIconAlignment.START
) {
coroutineScope.launch {
pagerState.animateScrollToPage(OnboardingPage.ARCHIVE_NAME_PAGE.value)
}
}
}

Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
SmallTextAndIconButton(
buttonColor = ButtonColor.LIGHT, text = stringResource(id = R.string.next)
) {
newArchive.goals[OnboardingGoal.CAPTURE] = captureCheckedState.value
newArchive.goals[OnboardingGoal.DIGITIZE] = digitizeCheckedState.value
newArchive.goals[OnboardingGoal.COLLABORATE] = collaborateCheckedState.value
newArchive.goals[OnboardingGoal.CREATE_AN_ARCHIVE] =
createArchiveCheckedState.value
newArchive.goals[OnboardingGoal.SHARE] = shareCheckedState.value
newArchive.goals[OnboardingGoal.CREATE_A_PLAN] = createPlanCheckedState.value
newArchive.goals[OnboardingGoal.ORGANIZE] = organizeCheckedState.value
newArchive.goals[OnboardingGoal.SOMETHING_ELSE] =
somethingElseCheckedState.value
coroutineScope.launch {
pagerState.animateScrollToPage(OnboardingPage.PRIORITIES_PAGE.value)
}
}
}
}
}
}

@Composable
private fun TabletBody(
whiteColor: Color,
regularFont: FontFamily,
coroutineScope: CoroutineScope,
pagerState: PagerState,
newArchive: NewArchive
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package org.permanent.permanent.ui.composeComponents

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import org.permanent.permanent.R

@Composable
fun CustomCheckbox(
isTablet: Boolean = false,
text: String,
checkedState: MutableState<Boolean>
) {
val context = LocalContext.current
val whiteTransparentColor =
Color(ContextCompat.getColor(context, R.color.whiteSuperExtraTransparent))
val barneyPurpleColor = Color(ContextCompat.getColor(context, R.color.barneyPurple))
val barneyPurpleLightColor = Color(ContextCompat.getColor(context, R.color.barneyPurpleLight))
val regularFont = FontFamily(Font(R.font.open_sans_regular_ttf))

Row(
modifier = Modifier
.fillMaxWidth()
.border(1.dp, whiteTransparentColor, RoundedCornerShape(10.dp))
.background(
if (checkedState.value) Brush.horizontalGradient(
listOf(
barneyPurpleLightColor,
barneyPurpleColor
)
) else Brush.horizontalGradient(
listOf(
Color.Transparent,
Color.Transparent
)
), RoundedCornerShape(10.dp)
),
horizontalArrangement = Arrangement.spacedBy(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
modifier = Modifier.padding(start = 24.dp),
checked = checkedState.value,
onCheckedChange = { checkedState.value = it },
colors = CheckboxDefaults.colors(
uncheckedColor = Color.White,
checkedColor = Color.White,
checkmarkColor = barneyPurpleLightColor
)
)

Text(
modifier = Modifier.padding(top = 24.dp, bottom = 24.dp, end = 24.dp),
text = text,
fontSize = 14.sp,
lineHeight = 24.sp,
color = Color.White,
fontFamily = regularFont
)
}
}

@Preview
@Composable
fun CustomCheckboxPreview() {
val checkedState = remember { mutableStateOf(false) }

CustomCheckbox(
isTablet = false,
text = stringResource(id = R.string.goals_capture),
checkedState = checkedState
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fun TextAndIconButton(
style: ButtonColor,
text: String,
icon: Painter = painterResource(id = R.drawable.ic_arrow_next_rounded_primary),
showButtonEnabled: Boolean,
showButtonEnabled: Boolean = true,
onButtonClick: () -> Unit
) {
val context = LocalContext.current
Expand Down
Loading

0 comments on commit 53fcb2c

Please sign in to comment.