diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000..f793e17
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/delecrode/devhub/di/AppModule.kt b/app/src/main/java/com/delecrode/devhub/di/AppModule.kt
index 4f93016..62a871e 100644
--- a/app/src/main/java/com/delecrode/devhub/di/AppModule.kt
+++ b/app/src/main/java/com/delecrode/devhub/di/AppModule.kt
@@ -67,7 +67,7 @@ val appModule = module {
viewModel { RepoDetailViewModel(get()) }
viewModel { AuthViewModel(get()) }
viewModel { SessionViewModel(get()) }
- viewModel { RegisterViewModel(get()) }
+ viewModel { RegisterViewModel(get(),get()) }
viewModel { ProfileViewModel(get(), get()) }
viewModel { RepoFavViewModel(get()) }
viewModel { ForgotPasswordViewModel(get()) }
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/components/OutlineTextField.kt b/app/src/main/java/com/delecrode/devhub/presentation/components/OutlineTextField.kt
index 9678fec..dc16c09 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/components/OutlineTextField.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/components/OutlineTextField.kt
@@ -23,6 +23,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
@@ -35,6 +36,7 @@ import androidx.compose.ui.unit.dp
import com.delecrode.devhub.R
import com.delecrode.devhub.presentation.ui.theme.DevHubTheme
import com.delecrode.devhub.presentation.ui.theme.PrimaryBlue
+import com.delecrode.devhub.presentation.ui.theme.Success
@Composable
@@ -59,7 +61,7 @@ fun EmailTextField(
MaterialTheme.colorScheme.background,
RoundedCornerShape(8.dp)
),
- placeholder = { Text(label) },
+ placeholder = { Text(label, color = MaterialTheme.colorScheme.onBackground) },
leadingIcon = {
Icon(
imageVector = Icons.Default.Person,
@@ -134,7 +136,7 @@ fun PasswordTextField(
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background, RoundedCornerShape(8.dp)),
- placeholder = { Text(label) },
+ placeholder = { Text(label, color = MaterialTheme.colorScheme.onBackground) },
leadingIcon = {
Icon(
imageVector = Icons.Default.Lock,
@@ -225,6 +227,9 @@ fun GenericOutlinedTextField(
modifier: Modifier = Modifier,
label: String,
leadingIcon: ImageVector? = null,
+ trailingIcon: @Composable (() -> Unit)? = null,
+ isSuccess: Boolean = false,
+ successMessage: String = "",
isError: Boolean = false,
errorMessage: String = "",
keyboardType: KeyboardType = KeyboardType.Text,
@@ -238,7 +243,7 @@ fun GenericOutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier.fillMaxWidth(),
- placeholder = { Text(label) },
+ placeholder = { Text(label, color = MaterialTheme.colorScheme.onBackground) },
leadingIcon = {
leadingIcon?.let {
Icon(
@@ -248,6 +253,7 @@ fun GenericOutlinedTextField(
)
}
},
+ trailingIcon = trailingIcon,
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = keyboardType,
@@ -262,9 +268,20 @@ fun GenericOutlinedTextField(
focusedContainerColor = MaterialTheme.colorScheme.background,
unfocusedContainerColor = MaterialTheme.colorScheme.background,
disabledContainerColor = MaterialTheme.colorScheme.background,
- focusedIndicatorColor = MaterialTheme.colorScheme.onBackground,
- unfocusedIndicatorColor = MaterialTheme.colorScheme.onBackground,
- errorIndicatorColor = MaterialTheme.colorScheme.error
+ focusedIndicatorColor = when {
+ isError -> MaterialTheme.colorScheme.error
+ isSuccess -> Color.Green
+ else -> MaterialTheme.colorScheme.onBackground
+ },
+
+ unfocusedIndicatorColor = when {
+ isError -> MaterialTheme.colorScheme.error
+ isSuccess -> Color.Green
+ else -> MaterialTheme.colorScheme.onBackground
+ },
+
+ errorIndicatorColor = MaterialTheme.colorScheme.error,
+
),
shape = RoundedCornerShape(8.dp)
)
@@ -277,6 +294,14 @@ fun GenericOutlinedTextField(
modifier = Modifier.padding(start = 16.dp, top = 4.dp)
)
}
+ if (isSuccess && successMessage.isNotEmpty()) {
+ Text(
+ text = successMessage,
+ color = Success,
+ style = MaterialTheme.typography.bodySmall,
+ modifier = Modifier.padding(start = 16.dp, top = 4.dp)
+ )
+ }
}
}
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/components/UserProfileHeader.kt b/app/src/main/java/com/delecrode/devhub/presentation/components/UserProfileHeader.kt
index d4f890e..5d4435c 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/components/UserProfileHeader.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/components/UserProfileHeader.kt
@@ -1,18 +1,21 @@
package com.delecrode.devhub.presentation.components
import androidx.compose.foundation.background
+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.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
@@ -24,54 +27,59 @@ import coil.compose.AsyncImage
@Composable
fun UserProfileHeader(avatar_url: String?,name: String, login: String, bio: String ) {
- if(avatar_url != null){
- Box(
- modifier = Modifier
- .background(Color.White, shape = CircleShape)
- .wrapContentSize()
- ) {
- AsyncImage(
- model = avatar_url,
- contentDescription = "Foto de Perfil",
- modifier = Modifier
- .size(100.dp)
- .clip(CircleShape)
- )
- }
- }
- Spacer(modifier = Modifier.height(16.dp))
+ Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.Center){
+ Row(modifier = Modifier.fillMaxWidth()){
+ if(avatar_url != null){
+ Box(
+ modifier = Modifier
+ .background(Color.White, shape = CircleShape)
+ .wrapContentSize()
+ ) {
+ AsyncImage(
+ model = avatar_url,
+ contentDescription = "Foto de Perfil",
+ modifier = Modifier
+ .size(68.dp)
+ .clip(CircleShape)
+ )
+ }
+ }
+ Spacer(modifier = Modifier.width(6.dp))
- Column(
- modifier = Modifier.fillMaxWidth(),
- horizontalAlignment = CenterHorizontally
- ) {
- Spacer(modifier = Modifier.height(12.dp))
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalAlignment = Alignment.Start
+ ) {
- Text(
- text = name,
- fontWeight = FontWeight.Bold,
- fontSize = 28.sp,
- color = MaterialTheme.colorScheme.onBackground
- )
- Spacer(modifier = Modifier.height(12.dp))
+ Text(
+ text = name,
+ fontWeight = FontWeight.Bold,
+ fontSize = 28.sp,
+ color = MaterialTheme.colorScheme.onBackground
+ )
- Text(
- text = login,
- fontWeight = FontWeight.Bold,
- fontSize = 20.sp,
- color = MaterialTheme.colorScheme.onBackground
- )
- Spacer(modifier = Modifier.height(12.dp))
+ Text(
+ text = login,
+ fontWeight = FontWeight.Bold,
+ fontSize = 20.sp,
+ color = MaterialTheme.colorScheme.onBackground
+ )
- Text(
- text = bio,
- fontWeight = FontWeight.Bold,
- fontSize = 18.sp,
- textAlign = TextAlign.Center,
- color = MaterialTheme.colorScheme.onBackground
- )
- }
+
+ }
+ }
+
+ Spacer(modifier = Modifier.height(12.dp))
+
+ Text(
+ text = bio,
+ fontWeight = FontWeight.Normal,
+ fontSize = 18.sp,
+ textAlign = TextAlign.Start,
+ color = MaterialTheme.colorScheme.onBackground
+ )
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/login/LoginScreen.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/login/LoginScreen.kt
index e54dcbf..1feac37 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/login/LoginScreen.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/login/LoginScreen.kt
@@ -12,6 +12,7 @@ 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.shape.RoundedCornerShape
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -29,6 +30,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@@ -41,10 +43,10 @@ import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.delecrode.devhub.R
-import com.delecrode.devhub.presentation.navigation.AppDestinations
import com.delecrode.devhub.presentation.components.EmailTextField
import com.delecrode.devhub.presentation.components.PasswordTextField
import com.delecrode.devhub.presentation.components.PrimaryButton
+import com.delecrode.devhub.presentation.navigation.AppDestinations
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -115,11 +117,18 @@ fun LoginScreen(navController: NavController, viewModel: AuthViewModel) {
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center){
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(220.dp),
+ contentAlignment = Alignment.Center
+ ) {
Image(
- painter = painterResource(R.drawable.git_logo),
+ painter = painterResource(R.drawable.dev_hub_logo),
contentDescription = "Logo",
- modifier = Modifier.size(100.dp),
+ modifier = Modifier
+ .size(220.dp)
+ .clip(RoundedCornerShape(8.dp))
)
}
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterScreen.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterScreen.kt
index ec0828e..04ce83c 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterScreen.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterScreen.kt
@@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Person
+import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@@ -20,6 +21,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@@ -27,7 +29,6 @@ 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.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
@@ -38,11 +39,11 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
-import com.delecrode.devhub.presentation.navigation.AppDestinations
import com.delecrode.devhub.presentation.components.EmailTextField
import com.delecrode.devhub.presentation.components.GenericOutlinedTextField
import com.delecrode.devhub.presentation.components.PasswordTextField
import com.delecrode.devhub.presentation.components.PrimaryButton
+import com.delecrode.devhub.presentation.navigation.AppDestinations
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -70,7 +71,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
}
LaunchedEffect(state.isSuccess) {
- if(state.isSuccess){
+ if (state.isSuccess) {
navController.navigate(AppDestinations.Login.route)
}
}
@@ -87,6 +88,13 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
}
}
+ DisposableEffect(Unit) {
+ onDispose {
+ viewModel.clearState()
+ }
+ }
+
+
Scaffold(
@@ -130,20 +138,23 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
Text(
"Preencha os campos abaixo para criar sua conta no DevHub " +
- "\nO seu nome de usuario deve ser o mesmo do seu usuario do GitHub",
+ "\nO seu nome de usuario deve ser o mesmo do seu usuario do GitHub " +
+ "\nClicando no pesquisar pode validar se o usuario existe no GitHub",
modifier = Modifier.padding(8.dp),
textAlign = TextAlign.Center,
- fontSize = 14.sp
+ fontSize = 14.sp,
+ color = MaterialTheme.colorScheme.onBackground
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Nome Completo",
- color = Color.Black,
+ color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
- fontSize = 14.sp
+ fontSize = 14.sp,
+
)
GenericOutlinedTextField(
@@ -160,7 +171,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Nome de Usuario",
- color = Color.Black,
+ color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
@@ -172,8 +183,19 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
onValueChange = { userName = it },
label = "Nome de Usuario",
leadingIcon = Icons.Default.Person,
+ trailingIcon = {
+ IconButton(onClick = { viewModel.validateGithubUsername(userName) }) {
+ Icon(
+ imageVector = Icons.Default.Search,
+ contentDescription = "Validar Usuario",
+ tint = MaterialTheme.colorScheme.primary
+ )
+ }
+ },
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next,
+ isSuccess = state.usernameSuccess,
+ successMessage = state.usernameSuccessMessage ?: "",
isError = state.usernameError != null,
errorMessage = state.usernameError ?: ""
)
@@ -182,7 +204,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
Text(
text = "E-mail",
- color = Color.Black,
+ color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
@@ -201,7 +223,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
Text(
text = "Senha",
- color = Color.Black,
+ color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
@@ -223,7 +245,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
Text(
text = "Confirmar Senha",
- color = Color.Black,
+ color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
@@ -243,7 +265,7 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
errorMessage = state.confirmPasswordError ?: ""
)
- Spacer(modifier = Modifier.height(16.dp))
+ Spacer(modifier = Modifier.height(30.dp))
PrimaryButton(
text = "Cadastrar",
@@ -258,6 +280,8 @@ fun RegisterScreen(navController: NavController, viewModel: RegisterViewModel) {
},
enabled = state.canRegister && name.isNotBlank() && userName.isNotBlank() && email.isNotBlank() && password.isNotBlank()
)
+
+ Spacer(modifier = Modifier.height(16.dp))
}
}
}
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterState.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterState.kt
index 7e66718..0b9c488 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterState.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterState.kt
@@ -5,6 +5,10 @@ data class RegisterState(
val isSuccess: Boolean = false,
val error: String? = null,
+ val usernameSuccess: Boolean = false,
+ val usernameSuccessMessage: String? = null,
+
+
val nameError: String? = null,
val usernameError: String? = null,
val emailError: String? = null,
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterViewModel.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterViewModel.kt
index 36b467c..18af5bb 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterViewModel.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/register/RegisterViewModel.kt
@@ -2,20 +2,62 @@ package com.delecrode.devhub.presentation.ui.register
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.delecrode.devhub.domain.repository.AuthRepository
import com.delecrode.devhub.data.utils.Result
+import com.delecrode.devhub.domain.repository.AuthRepository
+import com.delecrode.devhub.domain.repository.UserRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
class RegisterViewModel(
- private val repository: AuthRepository
+ private val authRepository: AuthRepository,
+ private val userRepository: UserRepository
) : ViewModel() {
private val _state = MutableStateFlow(RegisterState())
val state = _state.asStateFlow()
- fun signUp(name: String, username: String, email: String, password: String, confirmPassword: String) {
+ fun validateGithubUsername(username: String) {
+ viewModelScope.launch {
+
+ if (username.isBlank()) {
+ _state.value = _state.value.copy(
+ usernameError = "Username é obrigatório",
+ isLoading = false
+ )
+ return@launch
+ }
+
+ _state.value = _state.value.copy(isLoading = true)
+
+ when (userRepository.getUserForGitHub(username)) {
+ is Result.Success -> {
+ _state.value = _state.value.copy(
+ usernameSuccess = true,
+ usernameSuccessMessage = "Usuário validado com sucesso",
+ usernameError = null,
+ isLoading = false
+ )
+ }
+
+ is Result.Error -> {
+ _state.value = _state.value.copy(
+ usernameError = "Usuário não existe no GitHub",
+ isLoading = false
+ )
+ }
+ }
+ }
+ }
+
+
+ fun signUp(
+ name: String,
+ username: String,
+ email: String,
+ password: String,
+ confirmPassword: String
+ ) {
viewModelScope.launch {
validateName(name)?.let {
_state.value = _state.value.copy(nameError = it)
@@ -26,6 +68,16 @@ class RegisterViewModel(
_state.value = _state.value.copy(usernameError = it)
return@launch
}
+ when (userRepository.getUserForGitHub(username)) {
+ is Result.Success -> Unit
+ is Result.Error -> {
+ _state.value = _state.value.copy(
+ usernameError = "Usuário não existe no GitHub"
+ )
+ return@launch
+ }
+ }
+
val emailValidation = validateEmail(email)
if (emailValidation != null) {
_state.value = _state.value.copy(
@@ -50,7 +102,7 @@ class RegisterViewModel(
return@launch
}
- when (val result = repository.signUp(name, username, email, password)) {
+ when (val result = authRepository.signUp(name, username, email, password)) {
is Result.Success -> {
_state.value = RegisterState(isSuccess = true)
}
@@ -104,8 +156,6 @@ class RegisterViewModel(
}
-
-
fun clearEmailError() {
_state.value = _state.value.copy(emailError = null)
}
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Color.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Color.kt
index 6350916..f990d1a 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Color.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Color.kt
@@ -5,8 +5,11 @@ import androidx.compose.ui.graphics.Color
// Light Theme
val BackgroundLight = Color(0xFFFFFFFF)
val TextLight = Color(0xFF000000)
-val PrimaryBlue = Color(0xFF2196F3)
// Dark Theme
val BackgroundDark = Color(0xFF000000)
val TextDark = Color(0xFFFFFFFF)
+
+//All Themes
+val PrimaryBlue = Color(0xFF2196F3)
+val Success = Color.Green
diff --git a/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Theme.kt b/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Theme.kt
index 8142978..c2edfb1 100644
--- a/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Theme.kt
+++ b/app/src/main/java/com/delecrode/devhub/presentation/ui/theme/Theme.kt
@@ -18,7 +18,8 @@ private val DarkColorScheme = darkColorScheme(
onPrimary = Color.White,
onBackground = TextDark,
onSurface = TextDark,
- onSurfaceVariant = TextLight
+ onSurfaceVariant = TextLight,
+
)
private val LightColorScheme = lightColorScheme(
diff --git a/app/src/main/res/drawable/dev_hub_logo.png b/app/src/main/res/drawable/dev_hub_logo.png
new file mode 100644
index 0000000..3fb8a97
Binary files /dev/null and b/app/src/main/res/drawable/dev_hub_logo.png differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
index 07d5da9..ca3826a 100644
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -1,170 +1,74 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
similarity index 56%
rename from app/src/main/res/mipmap-anydpi/ic_launcher.xml
rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 6f3b755..c4a603d 100644
--- a/app/src/main/res/mipmap-anydpi/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,6 +1,5 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
similarity index 56%
rename from app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index 6f3b755..c4a603d 100644
--- a/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,6 +1,5 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
index c209e78..d58c559 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..e8554dc
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
index b2dfe3d..24de63d 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
index 4f0f1d6..e2dbefb 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..481fa7d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
index 62b611d..27efac9 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
index 948a307..feb76fe 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..d7775bd
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
index 1b9a695..4491d7d 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
index 28d4b77..e5fde28 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..891c54d
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
index 9287f50..356ea95 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
index aa7d642..0bd030b 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..66082e6
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
index 9126ae3..9b7e64f 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ