#18 Edit and delete profile implemented

This commit is contained in:
Tibo De Peuter 2023-04-16 22:40:43 +02:00
parent f263b34c12
commit 5e2c8de521
9 changed files with 32 additions and 25 deletions

View file

@ -118,6 +118,6 @@ fun NavGraphBuilder.studeezGraph(appState: StudeezAppstate) {
// Edit screens // Edit screens
composable(StudeezDestinations.EDIT_PROFILE_SCREEN) { composable(StudeezDestinations.EDIT_PROFILE_SCREEN) {
EditProfileScreen(goBack) EditProfileScreen(goBack, openAndPopUp)
} }
} }

View file

@ -1,7 +1,6 @@
package be.ugent.sel.studeez.common.composable package be.ugent.sel.studeez.common.composable
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
@ -12,17 +11,15 @@ import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.* import androidx.compose.runtime.*
import be.ugent.sel.studeez.R.string as AppText
import be.ugent.sel.studeez.R.drawable as AppIcon
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import be.ugent.sel.studeez.common.ext.fieldModifier import be.ugent.sel.studeez.common.ext.fieldModifier
import be.ugent.sel.studeez.R.drawable as AppIcon
import be.ugent.sel.studeez.R.string as AppText
@Composable @Composable
fun BasicField( fun BasicField(

View file

@ -29,5 +29,6 @@ interface AccountDAO {
suspend fun sendRecoveryEmail(email: String) suspend fun sendRecoveryEmail(email: String)
suspend fun signUpWithEmailAndPassword(email: String, password: String) suspend fun signUpWithEmailAndPassword(email: String, password: String)
suspend fun deleteAccount() suspend fun deleteAccount()
suspend fun signOut() suspend fun signOut()
} }

View file

@ -4,4 +4,10 @@ interface UserDAO {
suspend fun getUsername(): String? suspend fun getUsername(): String?
suspend fun save(newUsername: String) suspend fun save(newUsername: String)
/**
* Delete all references to this user in the database. Similar to the deleteCascade in
* relational databases.
*/
suspend fun deleteUserReferences()
} }

View file

@ -1,19 +1,13 @@
package be.ugent.sel.studeez.domain.implementation package be.ugent.sel.studeez.domain.implementation
import androidx.compose.runtime.rememberCoroutineScope import be.ugent.sel.studeez.R
import be.ugent.sel.studeez.common.snackbar.SnackbarManager
import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.UserDAO import be.ugent.sel.studeez.domain.UserDAO
import com.google.firebase.firestore.DocumentReference import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.coroutineContext
class FirebaseUserDAO @Inject constructor( class FirebaseUserDAO @Inject constructor(
private val firestore: FirebaseFirestore, private val firestore: FirebaseFirestore,
@ -34,4 +28,10 @@ class FirebaseUserDAO @Inject constructor(
companion object { companion object {
private const val USER_COLLECTION = "users" private const val USER_COLLECTION = "users"
} }
override suspend fun deleteUserReferences() {
currentUserDocument().delete()
.addOnSuccessListener { SnackbarManager.showMessage(R.string.success) }
.addOnFailureListener { SnackbarManager.showMessage(R.string.generic_error) }
}
} }

View file

@ -17,6 +17,7 @@ import be.ugent.sel.studeez.ui.theme.StudeezTheme
@Composable @Composable
fun EditProfileScreen( fun EditProfileScreen(
goBack: () -> Unit, goBack: () -> Unit,
openAndPopUp: (String, String) -> Unit,
viewModel: ProfileEditViewModel = hiltViewModel() viewModel: ProfileEditViewModel = hiltViewModel()
) { ) {
val uiState by viewModel.uiState val uiState by viewModel.uiState
@ -36,7 +37,7 @@ fun EditProfileScreen(
viewModel.onSaveClick() viewModel.onSaveClick()
} }
BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) { BasicTextButton(text = R.string.delete_profile, Modifier.textButton()) {
viewModel.onDeleteClick() viewModel.onDeleteClick(openAndPopUp)
} }
} }
} }
@ -47,7 +48,8 @@ fun EditProfileScreen(
fun EditProfileScreenComposable() { fun EditProfileScreenComposable() {
StudeezTheme { StudeezTheme {
EditProfileScreen ( EditProfileScreen (
{} {},
{_, _ -> {}}
) )
} }
} }

View file

@ -6,6 +6,7 @@ import be.ugent.sel.studeez.common.snackbar.SnackbarManager
import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.LogService
import be.ugent.sel.studeez.domain.UserDAO import be.ugent.sel.studeez.domain.UserDAO
import be.ugent.sel.studeez.navigation.StudeezDestinations
import be.ugent.sel.studeez.screens.StudeezViewModel import be.ugent.sel.studeez.screens.StudeezViewModel
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject import javax.inject.Inject
@ -33,13 +34,15 @@ class ProfileEditViewModel @Inject constructor(
fun onSaveClick() { fun onSaveClick() {
launchCatching { launchCatching {
userDAO.save(uiState.value.username) userDAO.save(uiState.value.username)
SnackbarManager.showMessage(R.string.save_success) SnackbarManager.showMessage(R.string.success)
} }
} }
fun onDeleteClick() { fun onDeleteClick(openAndPopUp: (String, String) -> Unit) {
launchCatching { launchCatching {
accountDAO.deleteAccount() userDAO.deleteUserReferences() // Delete references
accountDAO.deleteAccount() // Delete authentication
} }
openAndPopUp(StudeezDestinations.SIGN_UP_SCREEN, StudeezDestinations.EDIT_PROFILE_SCREEN)
} }
} }

View file

@ -13,11 +13,8 @@ import be.ugent.sel.studeez.navigation.StudeezDestinations.LOGIN_SCREEN
import be.ugent.sel.studeez.navigation.StudeezDestinations.SIGN_UP_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.SIGN_UP_SCREEN
import be.ugent.sel.studeez.screens.StudeezViewModel import be.ugent.sel.studeez.screens.StudeezViewModel
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.take
import be.ugent.sel.studeez.R.string as AppText
import javax.inject.Inject import javax.inject.Inject
import be.ugent.sel.studeez.R.string as AppText
@HiltViewModel @HiltViewModel
class SignUpViewModel @Inject constructor( class SignUpViewModel @Inject constructor(

View file

@ -5,16 +5,17 @@
<string name="email">Email</string> <string name="email">Email</string>
<string name="password">Password</string> <string name="password">Password</string>
<string name="repeat_password">Repeat password</string> <string name="repeat_password">Repeat password</string>
<string name="go_back">Go back</string>
<string name="menu">Menu</string> <string name="menu">Menu</string>
<!-- Actions --> <!-- Actions -->
<string name="confirm">Confirm</string> <string name="confirm">Confirm</string>
<string name="save">Save</string> <string name="save">Save</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="go_back">Go back</string>
<string name="next">Next</string>
<!-- Messages --> <!-- Messages -->
<string name="save_success">Saved successfully!</string> <string name="success">Success!</string>
<string name="try_again">Try again</string> <string name="try_again">Try again</string>
<string name="generic_error">Something wrong happened. Please try again.</string> <string name="generic_error">Something wrong happened. Please try again.</string>
<string name="email_error">Please insert a valid email.</string> <string name="email_error">Please insert a valid email.</string>