Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace this with svg

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@
<string name="kg">كجم</string>
<string name="ft">قدم</string>
<string name="lb">رطل</string>
<string name="ready_to_start">مستعد للبدء</string>
<string name="do_you_have_an_account">هل لديك حساب؟</string>
<string name="login">تسجيل الدخول</string>
<string name="choose_language" >اختر اللغة</string>
<string name="language_selection_description">سيتم استخدام هذه اللغة في جميع أنحاء التطبيق.</string>
<string name="arabic">العربية</string>
<string name="english">الإنجليزية</string>
<string name="confirm">تأكيد</string>
</resources>
9 changes: 9 additions & 0 deletions composeApp/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
<string name="meal_image">Meal Image</string>
<string name="calories_icon">Calories Icon</string>
<string name="kcal">Kcal</string>
<string name="ready_to_start">Ready to Start</string>
<string name="do_you_have_an_account">Do you have an account?</string>
<string name="login">Login</string>
<string name="choose_language">Choose Language</string>
<string name="language_selection_description">This language will be used throughout the app.</string>
<string name="arabic">Arabic</string>
<string name="english">English</string>
<string name="confirm">Confirm</string>

<string name="cm">cm</string>
<string name="kg">kg</string>
<string name="ft">ft</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.cairosquad.evolvefit.di

import com.cairosquad.evolvefit.ui.screen.onBoarding.OnBoardingViewModel
import com.cairosquad.evolvefit.viewmodel.register.RegisterViewModel
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module

val viewModelModule = module {
viewModelOf(::RegisterViewModel)
viewModelOf(::OnBoardingViewModel)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.cairosquad.evolvefit.ui.screen.onBoarding

import com.cairosquad.evolvefit.viewmodel.base.BaseViewModel

class OnBoardingViewModel :
BaseViewModel<OnboardingScreenState, OnboardingScreenEffect>(OnboardingScreenState()),
OnboardingScreenListener {

override fun onChangeLanguage(language: OnboardingScreenState.Language) {
updateState {
it.copy(bottomSheetSelectedLanguage = language)
}
}

override fun onConfirmClicked() {
updateState {
it.copy(
selectedLanguage = it.bottomSheetSelectedLanguage,
isBottomSheetOpen = false
)
}
}

override fun toggleBottomSheet(isOpen: Boolean) {
updateState {
it.copy(isBottomSheetOpen = isOpen)
}
}

override fun onSignUpClicked() {
sendEffect(OnboardingScreenEffect.NavigateToRegister)
}

override fun onLoginClicked() {
sendEffect(OnboardingScreenEffect.NavigateToLogin)
}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,222 @@
package com.cairosquad.evolvefit.ui.screen.onBoarding

import androidx.compose.foundation.Image
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
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.cairosquad.evolvefit.design_system.component.BottomSheet
import com.cairosquad.evolvefit.design_system.component.CheckboxItem
import com.cairosquad.evolvefit.design_system.component.CheckboxStyle
import com.cairosquad.evolvefit.design_system.component.PrimaryButton
import com.cairosquad.evolvefit.design_system.theme.AppTheme
import com.cairosquad.evolvefit.design_system.theme.Theme
import com.cairosquad.evolvefit.ui.navigation.LoginRoute
import com.cairosquad.evolvefit.ui.navigation.RegisterRoute
import com.cairosquad.evolvefit.ui.util.ObserveAsEffect
import com.cairosquad.evolvefit.ui.util.noRippleClickable
import org.jetbrains.compose.ui.tooling.preview.Preview
import evolvefit.composeapp.generated.resources.Onboarding
import evolvefit.composeapp.generated.resources.Res
import evolvefit.composeapp.generated.resources.arrow_down
import evolvefit.composeapp.generated.resources.choose_language
import evolvefit.composeapp.generated.resources.do_you_have_an_account
import evolvefit.composeapp.generated.resources.language_selection_description
import evolvefit.composeapp.generated.resources.login
import evolvefit.composeapp.generated.resources.ready_to_start
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel

@Composable
fun OnboardingScreen(
navigateToLogin: () -> Unit,
navigateToRegister: () -> Unit,
viewmodel: OnBoardingViewModel = koinViewModel(),
navigateToRegister : () -> Unit,
navigateToLogin : () -> Unit,
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally
val state by viewmodel.screenState.collectAsStateWithLifecycle()
ObserveAsEffect(viewmodel.effect) { effect ->
when (effect) {
OnboardingScreenEffect.NavigateToLogin -> {
navigateToLogin()
}
OnboardingScreenEffect.NavigateToRegister -> {
navigateToRegister()
}
}
}
OnboardingScreenContent(
state = state,
onSignupClick = viewmodel::onSignUpClicked,
onLoginClick = viewmodel::onLoginClicked,
onToggleBottomSheet = viewmodel::toggleBottomSheet,
onLanguageSelected = viewmodel::onChangeLanguage,
onConfirmClick = viewmodel::onConfirmClicked
)
}

@Composable
fun OnboardingScreenContent(
state: OnboardingScreenState,
modifier: Modifier = Modifier,
onSignupClick: () -> Unit,
onLoginClick: () -> Unit,
onToggleBottomSheet: (isOpen: Boolean) -> Unit,
onLanguageSelected: (language: OnboardingScreenState.Language) -> Unit,
onConfirmClick: () -> Unit
) {
Box(
modifier = modifier.fillMaxSize()
) {
Image(
painter = painterResource(Res.drawable.Onboarding),
contentDescription = "onboarding image",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.FillBounds
)
Row(
modifier = Modifier.align(Alignment.TopEnd).statusBarsPadding().height(48.dp)
.wrapContentWidth()
.noRippleClickable { onToggleBottomSheet(state.isBottomSheetOpen.not()) },
horizontalArrangement = Arrangement.End
) {
Text(
text = stringResource(state.selectedLanguage.displayNameRes),
style = Theme.textStyle.label.mediumMedium16,
color = Theme.color.surfaces.textColor,
modifier = Modifier.padding(top = 14.5.dp, bottom = 14.5.dp, end = 8.dp)
)
Image(
painter = painterResource(Res.drawable.arrow_down),
contentDescription = "arrow down",
modifier = Modifier.padding(
end = 16.dp, top = 14.5.dp, bottom = 14.5.dp
).size(20.dp)
)
}
//bottom section [ready to start - login]
Column(
modifier = Modifier.align(Alignment.BottomCenter),
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 24.dp)
.clip(RoundedCornerShape(24.dp))
.height(48.dp).background(
Theme.color.brand.primary,
).fillMaxWidth().noRippleClickable(onClick = onSignupClick),
contentAlignment = Alignment.Center
) {
Text(
text = stringResource(Res.string.ready_to_start),
style = Theme.textStyle.body.mediumMedium14,
color = Theme.color.brand.onPrimary
)
}

Text("Welcome to EvolveFit", color = Theme.color.surfaces.onSurface)
Text("Get Fit Don't Quit", color = Theme.color.surfaces.onSurface)
Row(
modifier = Modifier.padding(bottom = 24.dp).fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(Res.string.do_you_have_an_account),
style = Theme.textStyle.label.mediumMedium14,
color = Theme.color.surfaces.textColor,
modifier = Modifier.padding(end = 4.dp)
)
Text(
text = stringResource(Res.string.login),
style = Theme.textStyle.label.mediumMedium16,
color = Theme.color.brand.primary,
modifier = Modifier.padding(end = 4.dp).noRippleClickable(onClick = onLoginClick)
)

}

Button(
onClick = navigateToLogin
){
Text("go to Login")
}
Button(
onClick = navigateToRegister
){
Text("go to Register")
}

BottomSheet(
isVisible = state.isBottomSheetOpen,
onDismiss = {
onToggleBottomSheet(false)
},
content = {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = stringResource(Res.string.choose_language),
style = Theme.textStyle.label.mediumMedium16,
color = Theme.color.surfaces.onSurface,
modifier = Modifier.padding(bottom = 4.dp)
)
Text(
text = stringResource(Res.string.language_selection_description),
style = Theme.textStyle.label.mediumMedium12,
color = Theme.color.surfaces.onSurfaceVariant,
modifier = Modifier.padding(bottom = 16.dp)
)
OnboardingScreenState.Language.entries.forEach { language ->
CheckboxItem(
text = stringResource(language.displayNameRes),
isChecked = language == state.bottomSheetSelectedLanguage,
onCheckedChange = { onLanguageSelected(language) },
style = CheckboxStyle.Tick,
modifier = modifier.padding(
bottom = 12.dp
)
)
}
PrimaryButton(
text = "Confirm",
onClick = { onConfirmClick() },
modifier = Modifier.padding(
start = 16.dp, end = 16.dp, bottom = 16.dp , top = 28.dp
)
)
}
},
)

}
}
}

@Preview
@Composable
fun OnboardingScreenContentPreview() {
var state = OnboardingScreenState().copy(isBottomSheetOpen = true,)
AppTheme(
isDarkTheme = true
) {
OnboardingScreenContent(
state,
onSignupClick = { },
onLoginClick = { },
onToggleBottomSheet = {state.isBottomSheetOpen.not()},
onLanguageSelected = { },
onConfirmClick = {}
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.cairosquad.evolvefit.ui.screen.onBoarding

sealed class OnboardingScreenEffect {
object NavigateToLogin : OnboardingScreenEffect()
object NavigateToRegister : OnboardingScreenEffect()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.cairosquad.evolvefit.ui.screen.onBoarding

interface OnboardingScreenListener {
fun onChangeLanguage(language: OnboardingScreenState.Language)
fun toggleBottomSheet(isOpen: Boolean)
fun onSignUpClicked()
fun onLoginClicked()
fun onConfirmClicked()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.cairosquad.evolvefit.ui.screen.onBoarding

import evolvefit.composeapp.generated.resources.Res
import evolvefit.composeapp.generated.resources.arabic
import evolvefit.composeapp.generated.resources.english
import org.jetbrains.compose.resources.StringResource

data class OnboardingScreenState(
val selectedLanguage: Language = Language.ENGLISH,
val isBottomSheetOpen: Boolean = false,
val bottomSheetSelectedLanguage : Language = Language.ENGLISH
) {
enum class Language( val displayNameRes: StringResource) {
ARABIC(Res.string.arabic),
ENGLISH(Res.string.english)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.cairosquad.evolvefit.ui.util

import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed

fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier = composed {
this.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }) {
onClick()
}
}