Skip to content

Commit

Permalink
Implemented Firebase Authentication and optimized some screens
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmeddwalid committed Jan 7, 2025
1 parent b1c9dfd commit 7c81858
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 225 deletions.
11 changes: 6 additions & 5 deletions app/src/main/java/com/example/finjan/NavigationManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.finjan.ui.screens.authentication.LoginScreen
import com.example.finjan.ui.screens.authentication.SignInScreen
import com.example.finjan.ui.screens.authentication.SignUpScreen
import com.example.finjan.ui.screens.welcome.PageViewScreen
import com.example.finjan.ui.screens.welcome.WelcomeScreen
Expand All @@ -14,7 +14,7 @@ import com.example.finjan.ui.screens.home.OffersScreen
import com.example.finjan.ui.screens.home.ProfileScreen
import com.example.finjan.ui.screens.settings.SettingsScreen
import com.example.finjan.ui.screens.welcome.SplashScreen
import com.example.finjan.viewmodel.LoginViewModel
import com.example.finjan.viewmodel.AuthenticationViewModel
import com.example.finjan.viewmodel.SharedViewModel

@Composable
Expand All @@ -36,11 +36,12 @@ fun NavigationManager(
WelcomeScreen(navController)
}
composable("login_screen") {
val loginViewModel = androidx.lifecycle.viewmodel.compose.viewModel<LoginViewModel>()
LoginScreen(navController, loginViewModel)
val loginViewModel = androidx.lifecycle.viewmodel.compose.viewModel<AuthenticationViewModel>()
SignInScreen(navController, loginViewModel)
}
composable("signup_screen") {
SignUpScreen(navController)
val loginViewModel = androidx.lifecycle.viewmodel.compose.viewModel<AuthenticationViewModel>()
SignUpScreen(navController, loginViewModel)
}
composable("home") {
HomeScreen(navController)
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/com/example/finjan/model/PageItem.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
package com.example.finjan.model

data class PageItem(val image: Int, val title: String, val subTitle: String)
data class PageItem(
val image: Int,
val title: String,
val subtitle: String
)
8 changes: 4 additions & 4 deletions app/src/main/java/com/example/finjan/ui/Uicomponents.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.example.finjan.R
import com.example.finjan.ui.screens.welcome.primaryFontColor
import com.example.finjan.ui.theme.BackgroundColor
import com.example.finjan.ui.theme.PoppinsFontFamily
import com.example.finjan.ui.theme.PrimaryColor
Expand Down Expand Up @@ -220,7 +219,7 @@ fun AppTextField(


@Composable
fun Footer(text: String, textButton: String, onClick: @Composable () -> Unit, function: @Composable () -> Unit) {
fun Footer(text: String, textButton: String, onClick: () -> Unit, function: @Composable () -> Unit) {
Row(
Modifier
.fillMaxWidth()
Expand All @@ -236,7 +235,7 @@ fun Footer(text: String, textButton: String, onClick: @Composable () -> Unit, fu
fontFamily = PoppinsFontFamily
)
)
TextButton(onClick = { onClick }) {
TextButton(onClick = { onClick() }) { // Invoke onClick() here
Text(
textButton,
style = TextStyle(
Expand All @@ -250,6 +249,7 @@ fun Footer(text: String, textButton: String, onClick: @Composable () -> Unit, fu
}
}


@Composable
fun SplashScreen() {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.splash_screen))
Expand Down Expand Up @@ -346,7 +346,7 @@ fun SearchBar() {
),
singleLine = true,
textStyle = TextStyle(
color = primaryFontColor,
color = PrimaryColor,
fontSize = 15.sp,
fontFamily = PoppinsFontFamily
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.finjan.ui.AppTextField
import com.example.finjan.ui.BorderButton
import com.example.finjan.ui.FilledButton
import com.example.finjan.ui.Logo
import com.example.finjan.ui.theme.BackgroundColor
import com.example.finjan.ui.theme.PoppinsFontFamily
import com.example.finjan.ui.theme.PrimaryColor
import com.example.finjan.viewmodel.LoginViewModel
import com.example.finjan.viewmodel.AuthenticationViewModel
import com.example.finjan.ui.theme.FinjanTheme


@Composable
fun LoginScreen(navController: NavController, loginViewModel: LoginViewModel) {
fun SignInScreen(navController: NavController, authViewModel: AuthenticationViewModel) {
FinjanTheme {
// Observe the error message from the ViewModel
val errorMessage = loginViewModel.errorMessage
val errorMessage = authViewModel.errorMessage
val isLoading = authViewModel.isLoading

Column(
modifier = Modifier
Expand All @@ -41,7 +42,11 @@ fun LoginScreen(navController: NavController, loginViewModel: LoginViewModel) {
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Logo(modifier = Modifier)

Logo(modifier = Modifier
.align(Alignment.CenterHorizontally)
)

Text(
text = "Welcome Back!",
style = TextStyle(
Expand All @@ -51,43 +56,47 @@ fun LoginScreen(navController: NavController, loginViewModel: LoginViewModel) {
color = PrimaryColor
)
)

Spacer(modifier = Modifier.height(45.dp))

AppTextField(
hint = "Email",
value = loginViewModel.email, // Bind to ViewModel state
onValueChange = { input -> // Validate and update ViewModel state
loginViewModel.email = input // Update email in ViewModel
loginViewModel.isEmailValid = loginViewModel.isEmailValid(input) // Validate email
value = authViewModel.email,
onValueChange = { input ->
authViewModel.email = input
authViewModel.isEmailValid = authViewModel.isEmailValid(input)
},
keyboardType = KeyboardType.Email // Email-specific keyboard
keyboardType = KeyboardType.Email
)

Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Password",
value = loginViewModel.password,
onValueChange = { input -> // Validate and update ViewModel state
loginViewModel.password = input
loginViewModel.isPasswordValid = loginViewModel.isPasswordValid(input)
value = authViewModel.password,
onValueChange = { input ->
authViewModel.password = input
authViewModel.isPasswordValid = authViewModel.isPasswordValid(input)
},
keyboardType = KeyboardType.Password
)

Spacer(modifier = Modifier.height(28.dp))

FilledButton(
modifier = Modifier.padding(horizontal = 34.dp),
onClick = {
if (loginViewModel.authenticate()) {
authViewModel.signIn {
navController.navigate("home")
}
},
text = "Login",
modifier = Modifier.padding(horizontal = 34.dp)
text = if (isLoading) "Logging In..." else "Login"
)

// Display the error message in a Snackbar or Text
Spacer(modifier = Modifier.height(16.dp))

// Display the error message
if (errorMessage.isNotEmpty()) {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = errorMessage,
style = TextStyle(color = androidx.compose.ui.graphics.Color.Red)
Expand All @@ -96,13 +105,13 @@ fun LoginScreen(navController: NavController, loginViewModel: LoginViewModel) {

Spacer(modifier = Modifier.height(8.dp))

// Hidden back button
OutlinedButton (onClick = {
// Navigate back to the previous screen
navController.popBackStack()
}) {
Text(text = "Back")
}
BorderButton(
modifier = Modifier.padding(horizontal = 100.dp),
text = "Sign Up",
onClick = {
navController.navigate("signup_screen")
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,48 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.finjan.ui.AppTextField
import com.example.finjan.ui.FilledButton
import com.example.finjan.ui.Footer
import com.example.finjan.ui.Logo
import com.example.finjan.ui.theme.BackgroundColor
import com.example.finjan.ui.theme.FinjanTheme
import com.example.finjan.ui.theme.PoppinsFontFamily
import com.example.finjan.ui.theme.PrimaryColor
import com.example.finjan.viewmodel.AuthenticationViewModel

@Composable
fun SignUpScreen(navController: NavController) {
fun SignUpScreen(navController: NavController, loginViewModel: AuthenticationViewModel) {
FinjanTheme {
// State variables for the form fields
var username by remember { mutableStateOf("") }
var email by remember { mutableStateOf("") }
var mobileNumber by remember { mutableStateOf("") }
var address by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var confirmPassword by remember { mutableStateOf("") }

val errorMessage = loginViewModel.errorMessage
val isLoading = loginViewModel.isLoading

Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(BackgroundColor)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(60.dp))

Logo(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
.align(Alignment.CenterHorizontally)
)

Text(
text = "Sign Up",
style = TextStyle(
Expand All @@ -51,73 +61,77 @@ fun SignUpScreen(navController: NavController) {
color = PrimaryColor
)
)
Spacer(modifier = Modifier.height(12.dp))

Spacer(modifier = Modifier.height(36.dp))

// Updated AppTextFields
AppTextField(
hint = "Name",
value = username,
onValueChange = { username = it }
)

Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Email",
value = email,
onValueChange = { email = it },
onValueChange = {
email = it
loginViewModel.email = it
},
keyboardType = KeyboardType.Email
)
Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Mobile Number",
value = mobileNumber,
onValueChange = { mobileNumber = it },
keyboardType = KeyboardType.Phone
)
Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Address",
value = address,
onValueChange = { address = it }
)
Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Password",
value = password,
onValueChange = { password = it },
onValueChange = {
password = it
loginViewModel.password = it
},
keyboardType = KeyboardType.Password
)

Spacer(modifier = Modifier.height(28.dp))

AppTextField(
hint = "Confirm password",
value = confirmPassword,
onValueChange = { confirmPassword = it },
keyboardType = KeyboardType.Password,
action = ImeAction.Done
keyboardType = KeyboardType.Password
)

Spacer(modifier = Modifier.height(28.dp))

// Sign-Up Button
FilledButton(
onClick = {
if (password != confirmPassword) {
// Display error message if passwords don't match
println("Passwords do not match!")
loginViewModel.errorMessage = "Passwords do not match!"
} else if (username.isBlank()) {
loginViewModel.errorMessage = "Name cannot be empty!"
} else {
navController.navigate("home")
loginViewModel.signUp(username) {
navController.navigate("home")
}
}
},
text = "Sign Up",
modifier = Modifier
.padding(horizontal = 34.dp)
text = if (isLoading) "Signing Up..." else "Sign Up",
modifier = Modifier.padding(horizontal = 34.dp)
)

Spacer(modifier = Modifier.height(16.dp))

// Error Message
if (errorMessage.isNotEmpty()) {
Text(
text = errorMessage,
style = TextStyle(color = androidx.compose.ui.graphics.Color.Red)
)
}

Spacer(modifier = Modifier.height(28.dp))

Footer(
Expand All @@ -127,16 +141,6 @@ fun SignUpScreen(navController: NavController) {
) {
Text(text = "Sign Up")
}

Spacer(modifier = Modifier.height(8.dp))

// Hidden back button
OutlinedButton (onClick = {
// Navigate back to the previous screen
navController.popBackStack()
}) {
Text(text = "Back")
}
}
}
}
}
Loading

0 comments on commit 7c81858

Please sign in to comment.