From adaf82d7af1c5eb2b2adf7f9f0bd2ede53868b33 Mon Sep 17 00:00:00 2001 From: Mariano Riefolo Date: Fri, 12 Apr 2024 22:50:24 +0200 Subject: [PATCH] Added connection to teachers information api, formatted code, updated gradle --- .../flowschool/remote/ApiService.kt | 21 ++- .../remote/dto/TeacherInfoResult.kt | 11 ++ .../flowschool/screens/LoginScreen.kt | 4 +- .../flowschool/screens/PermissionScreen.kt | 2 +- .../flowschool/screens/SearchingScreen.kt | 161 ++++++++---------- .../flowschool/screens/TeacherScreen.kt | 42 ++++- build.gradle.kts | 2 +- 7 files changed, 142 insertions(+), 101 deletions(-) create mode 100644 app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/dto/TeacherInfoResult.kt diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/ApiService.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/ApiService.kt index 0f2414f..8464aad 100644 --- a/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/ApiService.kt +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/ApiService.kt @@ -1,6 +1,7 @@ package it.edu.cassandroferminervi.flowschool.remote import it.edu.cassandroferminervi.flowschool.remote.dto.LoginResult +import it.edu.cassandroferminervi.flowschool.remote.dto.TeacherInfoResult import retrofit2.Response import retrofit2.http.Field import retrofit2.http.FormUrlEncoded @@ -9,5 +10,23 @@ import retrofit2.http.POST interface ApiService { @FormUrlEncoded @POST("login.php") - suspend fun postLogin(@Field("username") code: String, @Field("password") password: String): Response + suspend fun postLogin( + @Field("username") code: String, + @Field("password") password: String + ): Response + + @FormUrlEncoded + @POST("presenza.php") + suspend fun postPresence(@Field("token") token: String): Response + + @FormUrlEncoded + @POST("lista.php") + suspend fun postTeacherList(@Field("token") token: String): Response> + + @FormUrlEncoded + @POST("ricerca.php") + suspend fun postTeacherInfo( + @Field("token") token: String, + @Field("profId") teacherId: Int + ): Response } \ No newline at end of file diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/dto/TeacherInfoResult.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/dto/TeacherInfoResult.kt new file mode 100644 index 0000000..243c474 --- /dev/null +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/remote/dto/TeacherInfoResult.kt @@ -0,0 +1,11 @@ +package it.edu.cassandroferminervi.flowschool.remote.dto + +import androidx.annotation.Keep + +@Keep +data class TeacherInfoResult( + val codice: Int, + val nome: String, + val cognome: String, + val email: String? +) diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/LoginScreen.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/LoginScreen.kt index bf0440e..995d722 100644 --- a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/LoginScreen.kt +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/LoginScreen.kt @@ -90,8 +90,8 @@ fun LoginScreen(navigator: DestinationsNavigator) { val description = if (passwordVisible) "Nascondi password" else "Mostra password" - IconButton(onClick = {passwordVisible = !passwordVisible}){ - Icon(imageVector = image, description) + IconButton(onClick = { passwordVisible = !passwordVisible }) { + Icon(imageVector = image, description) } }, modifier = Modifier.fillMaxWidth() diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/PermissionScreen.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/PermissionScreen.kt index ac58697..7b9b18a 100644 --- a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/PermissionScreen.kt +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/PermissionScreen.kt @@ -22,7 +22,7 @@ fun PermissionScreen(token: String) { if (cameraPermissionState.status.isGranted) { CameraScreen() } else { - Box ( + Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize() ) { diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/SearchingScreen.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/SearchingScreen.kt index e1f1e0f..e0cb483 100644 --- a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/SearchingScreen.kt +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/SearchingScreen.kt @@ -1,129 +1,104 @@ package it.edu.cassandroferminervi.flowschool.screens +import android.widget.Toast import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.material3.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import com.ramcosta.composedestinations.TeacherScreenDestination import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator +import it.edu.cassandroferminervi.flowschool.remote.RetrofitInstance +import it.edu.cassandroferminervi.flowschool.remote.dto.TeacherInfoResult +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +@OptIn(ExperimentalFoundationApi::class) @Destination @Composable -fun SearchingScreen(navigator: DestinationsNavigator, token: String) { - val teachers = listOf( - "Mario Rossi", - "Michele Verdi", - "Fabio Bianchi" - ).groupBy { - it.first() - }.toSortedMap() - .map { - Category( - it.key.toString(), - items = it.value - ) +fun SearchingScreen( + navigator: DestinationsNavigator, + token: String, +) { + val context = LocalContext.current + + var professorList by remember { mutableStateOf>(emptyList()) } + var searchText by remember { mutableStateOf("") } + + LaunchedEffect(Unit) { + val response = withContext(Dispatchers.IO) { + RetrofitInstance.api.postTeacherList(token) } - var filter by remember { mutableStateOf("") } + if (response.isSuccessful) { + professorList = response.body() ?: emptyList() + } else { + Toast.makeText(context, "Errore nel server", Toast.LENGTH_SHORT).show() + } + } + + val groupedByLetter = professorList.sortedWith(compareBy({ it.cognome }, { it.nome })) + .groupBy { it.cognome.first().uppercaseChar() } Column { - TextField( - value = filter, - onValueChange = { filter = it }, - label = { Text("Cerca") }, - singleLine = true, + OutlinedTextField( + value = searchText, + onValueChange = { searchText = it }, + label = { Text("Cerca professore") }, modifier = Modifier .fillMaxWidth() .padding(16.dp) ) - CategorizedLazyColumn( - categories = teachers, - navigator = navigator, - filter = filter - ) - } -} - -data class Category( - val name: String, - val items: List -) - -@Composable -private fun CategoryHeader( - text: String, - modifier: Modifier = Modifier -) { - Text( - text = text, - fontSize = 16.sp, - fontWeight = FontWeight.Bold, - modifier = modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.primaryContainer) - .padding(16.dp) - ) -} - -@Composable -private fun CategoryItem( - text: String, - navigator: DestinationsNavigator, - modifier: Modifier = Modifier -) { - TextButton(onClick = { - navigator.navigate(TeacherScreenDestination("test")) - }) { - Text( - text = text, - fontSize = 14.sp, - modifier = modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.background) - .padding(16.dp) - ) - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun CategorizedLazyColumn( - categories: List, - navigator: DestinationsNavigator, - filter: String, - modifier: Modifier = Modifier -) { - LazyColumn(modifier) { - categories.forEach { category -> - if (category.items.any { - it.contains(filter, ignoreCase = true) - }) { + LazyColumn { + groupedByLetter.forEach { (letter, professors) -> stickyHeader { - CategoryHeader(category.name) + Text( + text = letter.toString(), + style = TextStyle(fontWeight = FontWeight.Bold), + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray) + .padding(horizontal = 16.dp, vertical = 8.dp) + ) + } + items(professors.filter { + it.nome.contains(searchText, ignoreCase = true) || + it.cognome.contains(searchText, ignoreCase = true) + }) { professor -> + ProfessorItem(navigator = navigator, token = token, professor = professor) } - } - - items(items = category.items.filter { - it.contains(filter, ignoreCase = true) - }) { text -> - CategoryItem(text, navigator) } } } -} \ No newline at end of file +} + +@Composable +fun ProfessorItem(navigator: DestinationsNavigator, token: String, professor: TeacherInfoResult) { + Column( + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = { + navigator.navigate(TeacherScreenDestination(token, professor.codice)) + }) + .padding(16.dp) + ) { + Text(text = "${professor.nome} ${professor.cognome}") + } +} diff --git a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/TeacherScreen.kt b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/TeacherScreen.kt index 3c0a14b..a39fa69 100644 --- a/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/TeacherScreen.kt +++ b/app/src/main/java/it/edu/cassandroferminervi/flowschool/screens/TeacherScreen.kt @@ -1,23 +1,59 @@ package it.edu.cassandroferminervi.flowschool.screens +import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import com.ramcosta.composedestinations.annotation.Destination +import it.edu.cassandroferminervi.flowschool.remote.RetrofitInstance +import it.edu.cassandroferminervi.flowschool.remote.dto.TeacherInfoResult +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext @Destination @Composable -fun TeacherScreen(codice: String) { +fun TeacherScreen(token: String, code: Int) { + val context = LocalContext.current + var resBody by remember { + mutableStateOf( + TeacherInfoResult( + code, + "err", + "err", + null + ) + ) + } + + LaunchedEffect(Unit) { + val response = withContext(Dispatchers.IO) { + RetrofitInstance.api.postTeacherInfo(token, code) + } + + if (response.isSuccessful && response.body() != null) { + resBody = response.body()!! + } else { + Toast.makeText(context, "Errore nel server", Toast.LENGTH_SHORT).show() + } + } + Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, modifier = Modifier.fillMaxSize() ) { - Text("Codice prof: $codice") - Text("Presente: si") + Text("Nome: ${resBody.nome}") + Text("Cognome: ${resBody.cognome}") + Text("Email: ${resBody.email}") } } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index a7d3dac..edfcfd3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.3.1" apply false + id("com.android.application") version "8.3.2" apply false id("org.jetbrains.kotlin.android") version "1.9.0" apply false } \ No newline at end of file