From 205dd30644d734eab66cc49bb0141c7c3af58eb4 Mon Sep 17 00:00:00 2001 From: Panos Daskalopoulos Date: Sat, 4 Jan 2025 18:26:29 +0200 Subject: [PATCH] Created navigations --- .../com/example/estiaseek/EstiaSeekScreen.kt | 41 ++++++++++++--- .../com/example/estiaseek/MainActivity.kt | 9 +--- .../com/example/estiaseek/ResultsScreen.kt | 43 ++++++++++++++-- .../example/estiaseek/ui/profile/Profile.kt | 13 +++-- .../ui/screens/CandidateSearchScreen.kt | 50 +++++++++++++++---- .../estiaseek/ui/screens/CreateApplicant.kt | 8 ++- .../estiaseek/ui/screens/HomeScreen.kt | 18 +++++-- 7 files changed, 143 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/example/estiaseek/EstiaSeekScreen.kt b/app/src/main/java/com/example/estiaseek/EstiaSeekScreen.kt index b5cdbe1..32706b5 100644 --- a/app/src/main/java/com/example/estiaseek/EstiaSeekScreen.kt +++ b/app/src/main/java/com/example/estiaseek/EstiaSeekScreen.kt @@ -3,8 +3,11 @@ package com.example.estiaseek import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -13,35 +16,59 @@ import com.example.estiaseek.ui.screens.CreateApplicant import com.example.estiaseek.ui.screens.HomeScreen import com.example.estiaseek.ui.profile.Profile import com.example.estiaseek.ResultsScreen +import com.example.estiaseek.ui.screens.CandidateSearchScreen +import com.example.estiaseek.ui.viewmodels.ProfileViewModel +import com.example.estiaseek.ui.viewmodels.SearchUiState +import com.example.estiaseek.ui.viewmodels.SearchViewModel enum class EstiaSeekScreen() { Start, CreateApplicant, ShowResults, - Profile + Profile, + Search } @Composable fun EstiaSeekScreen( - navController: NavHostController = rememberNavController() + navController: NavHostController = rememberNavController(), + searchViewModel: SearchViewModel = viewModel(), + profileViewModel: ProfileViewModel = viewModel() ) { NavHost( navController = navController, startDestination = EstiaSeekScreen.Start.name, - modifier = Modifier + modifier = Modifier, ) { composable(route = EstiaSeekScreen.Start.name) { - HomeScreen() + HomeScreen( + onSearchButtonClicked = { navController.navigate(EstiaSeekScreen.Search.name) }, + onCreateApplicantButtonClicked = { navController.navigate(EstiaSeekScreen.CreateApplicant.name) } + ) } composable(route = EstiaSeekScreen.CreateApplicant.name) { - CreateApplicant() + CreateApplicant( + onCreateApplicantButtonClicked = { navController.navigate(EstiaSeekScreen.Start.name)} + ) } composable(route = EstiaSeekScreen.ShowResults.name) { - ResultsScreen() + ResultsScreen( + onProfileClicked = { navController.navigate(EstiaSeekScreen.Profile.name)}, + searchViewModel = searchViewModel, + profileViewModel = profileViewModel + ) } composable(route = EstiaSeekScreen.Profile.name) { - Profile() + Profile( + profileViewModel = profileViewModel + ) + } + composable(route = EstiaSeekScreen.Search.name) { + CandidateSearchScreen( + onSearchButtonClicked = { navController.navigate(EstiaSeekScreen.ShowResults.name)}, + searchViewModel = searchViewModel + ) } } diff --git a/app/src/main/java/com/example/estiaseek/MainActivity.kt b/app/src/main/java/com/example/estiaseek/MainActivity.kt index 7a410b0..41ec387 100644 --- a/app/src/main/java/com/example/estiaseek/MainActivity.kt +++ b/app/src/main/java/com/example/estiaseek/MainActivity.kt @@ -32,12 +32,5 @@ class MainActivity : ComponentActivity() { @Composable fun MainScreen() { - // Toggle between screens dynamically - val showApplicantScreen = remember { mutableStateOf(true) } - - if (showApplicantScreen.value) { - CreateApplicant() - } else { - CandidateSearchScreen() - } + EstiaSeekScreen() } diff --git a/app/src/main/java/com/example/estiaseek/ResultsScreen.kt b/app/src/main/java/com/example/estiaseek/ResultsScreen.kt index 624d0e6..683a688 100644 --- a/app/src/main/java/com/example/estiaseek/ResultsScreen.kt +++ b/app/src/main/java/com/example/estiaseek/ResultsScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close +import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.InputChip @@ -23,6 +24,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -34,16 +36,29 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.compose.rememberNavController import com.example.estiaseek.ui.components.BottomNavigationBar import com.example.estiaseek.ui.components.ImageCard +import com.example.estiaseek.ui.viewmodels.ProfileViewModel +import com.example.estiaseek.ui.viewmodels.SearchUiState +import com.example.estiaseek.ui.viewmodels.SearchViewModel @OptIn(ExperimentalMaterial3Api::class) -@Preview(showBackground = false) @Composable -fun ResultsScreen() { +fun ResultsScreen( + searchViewModel : SearchViewModel, + profileViewModel: ProfileViewModel, + onProfileClicked: () -> Unit, +) { + val profileViewState by profileViewModel.profileViewState.collectAsState() + + val searchUiState by searchViewModel.searchUIState.collectAsState() + + //TODO we cant have a full fat nav controller here val navController = rememberNavController() Scaffold( @@ -52,7 +67,23 @@ fun ResultsScreen() { } ) { paddingValues -> - + // TODO Clicking on profile should envoke onProfileClicked and updaye state with username + // FIXME TEST BUTTON REMOVE WHEN FIXED + Button( + onClick = { + profileViewModel.updateProfileView( + newState = profileViewState.copy( + username = "panos1b" + ) + ) + onProfileClicked() + }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 32.dp) + ) { + Text(text = "Search Candidate") + } Column(modifier = Modifier.padding(35.dp).padding(paddingValues)) { Row( modifier = Modifier @@ -174,7 +205,11 @@ fun ResultsScreen() { @Composable @Preview(showBackground = false) fun PreviewResults() { - ResultsScreen() + ResultsScreen( + searchViewModel = SearchViewModel(), + profileViewModel = ProfileViewModel(), + onProfileClicked = {} + ) } @Composable diff --git a/app/src/main/java/com/example/estiaseek/ui/profile/Profile.kt b/app/src/main/java/com/example/estiaseek/ui/profile/Profile.kt index f6410af..c96fd22 100644 --- a/app/src/main/java/com/example/estiaseek/ui/profile/Profile.kt +++ b/app/src/main/java/com/example/estiaseek/ui/profile/Profile.kt @@ -30,12 +30,17 @@ import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView +import com.example.estiaseek.ui.viewmodels.ProfileViewModel +import com.example.estiaseek.ui.viewmodels.SearchUiState @OptIn(UnstableApi::class) @Composable -fun Profile() { +fun Profile( + profileViewModel: ProfileViewModel +) { val context = LocalContext.current + val profileViewState by profileViewModel.profileViewState.collectAsState() // Remember ExoPlayer instance val exoPlayer = remember { @@ -105,7 +110,7 @@ fun Profile() { ) { // User Name Text( - text = "Lil Pop", + text = "Lil Pop - ${profileViewState.username}", style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.Bold ) @@ -198,5 +203,7 @@ fun Profile() { @Preview @Composable fun PreviewProfile() { - Profile() + Profile( + profileViewModel = ProfileViewModel() + ) } diff --git a/app/src/main/java/com/example/estiaseek/ui/screens/CandidateSearchScreen.kt b/app/src/main/java/com/example/estiaseek/ui/screens/CandidateSearchScreen.kt index 34f97c0..db71dd9 100644 --- a/app/src/main/java/com/example/estiaseek/ui/screens/CandidateSearchScreen.kt +++ b/app/src/main/java/com/example/estiaseek/ui/screens/CandidateSearchScreen.kt @@ -18,16 +18,23 @@ import androidx.compose.material.icons.rounded.LocationOn import androidx.compose.material.icons.rounded.Person import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Star +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.compose.viewModel +import com.example.estiaseek.ui.viewmodels.SearchUiState +import com.example.estiaseek.ui.viewmodels.SearchViewModel @Composable -fun CandidateSearchScreen() { - var selectedJobTitle by remember { mutableStateOf("") } - var selectedLocation by remember { mutableStateOf("") } - var selectedExperience by remember { mutableStateOf("") } +fun CandidateSearchScreen( + onSearchButtonClicked: (SearchUiState) -> Unit, + searchViewModel : SearchViewModel +) { + + val searchUiState by searchViewModel.searchUIState.collectAsState() val context = LocalContext.current @@ -97,8 +104,14 @@ fun CandidateSearchScreen() { DropdownMenuField( label = R.string.job_title, options = jobTitles, - selectedOption = selectedJobTitle, - onOptionSelected = { selectedJobTitle = it }, + selectedOption = searchUiState.selectedJobTitle, + onOptionSelected = { + searchViewModel.updateSearchState( + newState = searchUiState.copy( + selectedJobTitle = it + ) + ) + }, icon = Icons.Rounded.Person, modifier = Modifier.fillMaxWidth() ) @@ -106,8 +119,14 @@ fun CandidateSearchScreen() { DropdownMenuField( label = R.string.location, options = locations, - selectedOption = selectedLocation, - onOptionSelected = { selectedLocation = it }, + selectedOption = searchUiState.selectedLocation, + onOptionSelected = { + searchViewModel.updateSearchState( + newState = searchUiState.copy( + selectedLocation = it + ) + ) + }, icon = Icons.Rounded.LocationOn, modifier = Modifier.fillMaxWidth() ) @@ -115,8 +134,14 @@ fun CandidateSearchScreen() { DropdownMenuField( label = R.string.experience_level, options = experienceLevels, - selectedOption = selectedExperience, - onOptionSelected = { selectedExperience = it }, + selectedOption = searchUiState.selectedExperience, + onOptionSelected = { + searchViewModel.updateSearchState( + newState = searchUiState.copy( + selectedExperience = it + ) + ) + }, icon = Icons.Rounded.Star, modifier = Modifier.fillMaxWidth() ) @@ -125,7 +150,10 @@ fun CandidateSearchScreen() { // Search Button Button( - onClick = { /* Search action to be implemented */ }, + onClick = { + onSearchButtonClicked(searchUiState); + /* TODO Search action to be implemented */ + }, modifier = Modifier .fillMaxWidth() .height(56.dp), diff --git a/app/src/main/java/com/example/estiaseek/ui/screens/CreateApplicant.kt b/app/src/main/java/com/example/estiaseek/ui/screens/CreateApplicant.kt index 7b867cd..9f504ab 100644 --- a/app/src/main/java/com/example/estiaseek/ui/screens/CreateApplicant.kt +++ b/app/src/main/java/com/example/estiaseek/ui/screens/CreateApplicant.kt @@ -38,9 +38,12 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.example.estiaseek.R import com.example.estiaseek.ui.components.DropdownMenuField +import kotlin.Unit @Composable -fun CreateApplicant() { +fun CreateApplicant( + onCreateApplicantButtonClicked: () -> Unit, +) { var name by remember { mutableStateOf("") } var surname by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } @@ -224,7 +227,8 @@ fun CreateApplicant() { // Submit Button Button( - onClick = { /* Search action to be implemented */ }, + onClick = { onCreateApplicantButtonClicked() + /* TODO create applicant!*/ }, modifier = Modifier .fillMaxWidth() .padding(bottom = 32.dp), diff --git a/app/src/main/java/com/example/estiaseek/ui/screens/HomeScreen.kt b/app/src/main/java/com/example/estiaseek/ui/screens/HomeScreen.kt index aa3a59c..f084d9c 100644 --- a/app/src/main/java/com/example/estiaseek/ui/screens/HomeScreen.kt +++ b/app/src/main/java/com/example/estiaseek/ui/screens/HomeScreen.kt @@ -19,7 +19,10 @@ import com.example.estiaseek.R import com.example.estiaseek.ui.theme.EstiaSeekTheme @Composable -fun HomeScreen() { +fun HomeScreen( + onSearchButtonClicked: () -> Unit, + onCreateApplicantButtonClicked: () -> Unit, +) { EstiaSeekTheme { // Ensure the app's theme is applied Surface( modifier = Modifier.fillMaxSize(), @@ -59,7 +62,9 @@ fun HomeScreen() { // First Button Button( - onClick = { /* TODO: Add action */ }, + onClick = { + onSearchButtonClicked() + }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 32.dp) @@ -71,7 +76,9 @@ fun HomeScreen() { // Second Button Button( - onClick = { /* TODO: Add action */ }, + onClick = { + onCreateApplicantButtonClicked() + }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 32.dp) @@ -87,5 +94,8 @@ fun HomeScreen() { @Preview(showBackground = true) @Composable fun HomeScreenPreview() { - HomeScreen() + HomeScreen( + onSearchButtonClicked = {}, + onCreateApplicantButtonClicked = {} + ) }