diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 492e413..2ebcf6f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -48,7 +48,13 @@ dependencies { implementation(Dependencies.Retrofit.gsonConverter) implementation("com.squareup.okhttp3:logging-interceptor:4.10.0") - implementation("com.squareup.picasso:picasso:2.8") + // Убираем Picasso + // implementation("com.squareup.picasso:picasso:2.8") + + // Добавляем Glide + implementation("com.github.bumptech.glide:glide:4.14.2") + kapt("com.github.bumptech.glide:compiler:4.14.2") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") implementation("androidx.datastore:datastore-preferences:1.1.2") implementation("com.google.mlkit:barcode-scanning:17.3.0") diff --git a/app/src/main/java/ru/myitschool/work/api/NetworkModule.kt b/app/src/main/java/ru/myitschool/work/api/NetworkModule.kt index 205c1c3..3b19c42 100644 --- a/app/src/main/java/ru/myitschool/work/api/NetworkModule.kt +++ b/app/src/main/java/ru/myitschool/work/api/NetworkModule.kt @@ -6,6 +6,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import dagger.hilt.android.qualifiers.ApplicationContext +import ru.myitschool.work.api.admin.ApiServiceAdmin import ru.myitschool.work.api.list.ApiServiceList import ru.myitschool.work.api.login.ApiServiceLogin import ru.myitschool.work.api.main.ApiServiceMain @@ -45,4 +46,10 @@ object NetworkModule { fun provideListApiService(retrofitClient: RetrofitClient): ApiServiceList { return retrofitClient.getApiServiceList() } + + @Provides + @Singleton + fun provideApiServiceAdmin(retrofitClient: RetrofitClient): ApiServiceAdmin { + return retrofitClient.getApiServiceAdmin() + } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/RetrofitClient.kt b/app/src/main/java/ru/myitschool/work/api/RetrofitClient.kt index ce4b061..01f981e 100644 --- a/app/src/main/java/ru/myitschool/work/api/RetrofitClient.kt +++ b/app/src/main/java/ru/myitschool/work/api/RetrofitClient.kt @@ -1,11 +1,11 @@ package ru.myitschool.work.api import android.content.Context -import com.google.android.datatransport.BuildConfig import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import ru.myitschool.work.api.admin.ApiServiceAdmin import ru.myitschool.work.api.list.ApiServiceList import ru.myitschool.work.api.login.ApiServiceLogin import ru.myitschool.work.api.main.ApiServiceMain @@ -57,4 +57,8 @@ class RetrofitClient(context: Context) { fun getApiServiceList(): ApiServiceList { return retrofitWithAuth.create(ApiServiceList::class.java) } + fun getApiServiceAdmin(): ApiServiceAdmin { + return retrofitWithAuth.create(ApiServiceAdmin::class.java) + } + } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/admin/AdminJson.kt b/app/src/main/java/ru/myitschool/work/api/admin/AdminJson.kt new file mode 100644 index 0000000..34993c3 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/api/admin/AdminJson.kt @@ -0,0 +1,7 @@ +package ru.myitschool.work.api.admin + +import com.google.gson.annotations.SerializedName + +class AdminJson( + @SerializedName("authority") var authority: String? = null, +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/admin/ApiServiceAdmin.kt b/app/src/main/java/ru/myitschool/work/api/admin/ApiServiceAdmin.kt new file mode 100644 index 0000000..e31acd3 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/api/admin/ApiServiceAdmin.kt @@ -0,0 +1,16 @@ +package ru.myitschool.work.api.admin + +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.PATCH +import retrofit2.http.Path +import ru.myitschool.work.api.main.UserInfo + +interface ApiServiceAdmin { + @PATCH("api/admin/authority/change/{login}") + suspend fun block( + @Path("login") login: String, + @Body data: AdminJson + ): Response +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/list/ApiServiceList.kt b/app/src/main/java/ru/myitschool/work/api/list/ApiServiceList.kt index c92f80e..86105a3 100644 --- a/app/src/main/java/ru/myitschool/work/api/list/ApiServiceList.kt +++ b/app/src/main/java/ru/myitschool/work/api/list/ApiServiceList.kt @@ -5,6 +5,6 @@ import retrofit2.http.GET import retrofit2.http.Path interface ApiServiceList { - @GET("api/list/{login}") + @GET("api/user/list/{login}") suspend fun getList(@Path("login") login: String): Response> } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/login/ApiServiceLogin.kt b/app/src/main/java/ru/myitschool/work/api/login/ApiServiceLogin.kt index 51dd1d0..451c80b 100644 --- a/app/src/main/java/ru/myitschool/work/api/login/ApiServiceLogin.kt +++ b/app/src/main/java/ru/myitschool/work/api/login/ApiServiceLogin.kt @@ -1,13 +1,9 @@ package ru.myitschool.work.api.login import retrofit2.Call -import retrofit2.http.Body import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Path -import ru.myitschool.work.api.main.UserInfo interface ApiServiceLogin { - @GET("api/login") + @GET("api/user/login") fun authenticate(): Call } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/main/ApiServiceMain.kt b/app/src/main/java/ru/myitschool/work/api/main/ApiServiceMain.kt index c99468c..7b3a832 100644 --- a/app/src/main/java/ru/myitschool/work/api/main/ApiServiceMain.kt +++ b/app/src/main/java/ru/myitschool/work/api/main/ApiServiceMain.kt @@ -5,6 +5,6 @@ import retrofit2.http.GET import retrofit2.http.Path interface ApiServiceMain { - @GET("api/info/{login}") + @GET("api/user/info/{login}") fun getDataUser(@Path("login") login: String): Call } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/main/UserInfo.kt b/app/src/main/java/ru/myitschool/work/api/main/UserInfo.kt index 31fc8d1..617cd2a 100644 --- a/app/src/main/java/ru/myitschool/work/api/main/UserInfo.kt +++ b/app/src/main/java/ru/myitschool/work/api/main/UserInfo.kt @@ -9,15 +9,16 @@ data class UserInfo( @SerializedName("photo") val photoUrl: String, @SerializedName("position") val position: String, @SerializedName("lastVisit") val lastVisit: String, -) { - companion object { - val Initial = UserInfo( - id = 0, - login = "", - name = "", - photoUrl = "", - position = "", - lastVisit = "", - ) - } + @SerializedName("authority") val authority: List +) + +data class AuthorityData( + @SerializedName("id") val id: Int, + @SerializedName("authority") val authority: String, +) + +object Authorities { + const val ROLE_ADMIN = "ROLE_ADMIN" + const val ROLE_USER = "ROLE_USER" + const val ROLE_BLOCK = "ROLE_BLOCK" } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/scan/ApiServiceScan.kt b/app/src/main/java/ru/myitschool/work/api/scan/ApiServiceScan.kt index e83ffd4..8eadd2d 100644 --- a/app/src/main/java/ru/myitschool/work/api/scan/ApiServiceScan.kt +++ b/app/src/main/java/ru/myitschool/work/api/scan/ApiServiceScan.kt @@ -6,6 +6,6 @@ import retrofit2.http.POST import retrofit2.http.Path interface ApiServiceScan { - @POST("api/add/{login}") + @POST("api/user/add/{login}") fun open(@Path("login") login: String, @Body data: CodeJson): Call } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt b/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt index 8f1b5fe..2eadf1a 100644 --- a/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt +++ b/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt @@ -36,6 +36,7 @@ class RootActivity : AppCompatActivity() { fragment() fragment() fragment() + /*fragment()*/ } } diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt index 60695ac..7894194 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt @@ -104,8 +104,6 @@ class LoginFragment : Fragment(R.layout.fragment_login) { text = "Ошибка авторизации" } - authPreferences.clearLoginState() - Log.d("Authentication", "Ошибка авторизации") } diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt index 8996957..699e12d 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt @@ -36,7 +36,7 @@ class LoginViewModel @Inject constructor( _state.value = LoginState.InvalidCredentials } 401 -> { - _state.value = LoginState.Error + _state.value = LoginState.InvalidCredentials } else -> { _state.value = LoginState.Error diff --git a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt index b4b1ede..00f0012 100644 --- a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt @@ -8,9 +8,9 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager -import com.squareup.picasso.Picasso import dagger.hilt.android.AndroidEntryPoint import ru.myitschool.work.R +import ru.myitschool.work.api.main.Authorities import ru.myitschool.work.databinding.FragmentMainBinding import ru.myitschool.work.ui.list.ListAdapter import ru.myitschool.work.ui.login.LoginDestination @@ -100,6 +100,16 @@ class MainFragment : Fragment(R.layout.fragment_main) { username.text = state.userInfo.name position.text = state.userInfo.position + + if (state.userInfo.authority[0].authority == Authorities.ROLE_ADMIN) { + admin.visibleOrGone(true) + } else if (state.userInfo.authority[0].authority == Authorities.ROLE_USER) { + admin.visibleOrGone(false) + } else { + admin.visibleOrGone(false) + Log.e("MainFragment", "Unknown role") + } + loadImageFromUrl(state.userInfo.photoUrl) val inputFormat = java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()) @@ -107,7 +117,8 @@ class MainFragment : Fragment(R.layout.fragment_main) { try { val parsedDate = inputFormat.parse(state.userInfo.lastVisit) - lastEntry.text = parsedDate?.let { outputFormat.format(it) } ?: state.userInfo.lastVisit + lastEntry.text = parsedDate?.let { outputFormat.format(it) } + ?: state.userInfo.lastVisit } catch (e: Exception) { lastEntry.text = state.userInfo.lastVisit } @@ -125,13 +136,13 @@ class MainFragment : Fragment(R.layout.fragment_main) { viewModel.listState.collectWhenStarted(this) { state -> when (state) { is MainViewModel.ListState.Loading -> { - //TODO + hideAll() } is MainViewModel.ListState.Success -> { listAdapter.submitList(state.data) } is MainViewModel.ListState.Error -> { - //TODO + hideAll() binding.error.text = state.message } } @@ -139,11 +150,7 @@ class MainFragment : Fragment(R.layout.fragment_main) { } private fun loadImageFromUrl(url: String) { - Picasso - .get() - .load(url) - .error(R.drawable.icon_profile) - .into(binding.photo) + } private fun setupMainComponents() { @@ -152,6 +159,10 @@ class MainFragment : Fragment(R.layout.fragment_main) { navigateToLogin() } + binding.admin.setOnClickListener { + navigateToAdmin() + } + binding.refresh.setOnClickListener { viewModel.getUserData(authPreferences.getLogin() ?: "") } @@ -173,6 +184,19 @@ class MainFragment : Fragment(R.layout.fragment_main) { } } + + private fun navigateToAdmin() { + try {/* + authPreferences.clearLoginState() + findNavController().apply { + popBackStack(AdminDestination, false) + navigate(AdminDestination) + }*/ + } catch (e: Exception) { + Log.e("MainFragment", "Error navigating to login", e) + } + } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt index 73c6a29..286a0ed 100644 --- a/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt @@ -36,12 +36,15 @@ class MainViewModel @Inject constructor( when { response.isSuccessful -> { - val userInfo = response.body() ?: UserInfo.Initial - _state.value = MainState.Success(userInfo) + val userInfo = response.body() + _state.value = userInfo?.let { MainState.Success(it) }!! } response.code() == 401 -> { _state.value = MainState.Error("Unauthorized") } + response.code() == 403 -> { + _state.value = MainState.Error("Block") + } else -> { _state.value = MainState.Error("Error") } diff --git a/app/src/main/res/drawable/baseline_admin_panel_settings_24.xml b/app/src/main/res/drawable/baseline_admin_panel_settings_24.xml new file mode 100644 index 0000000..e8b27be --- /dev/null +++ b/app/src/main/res/drawable/baseline_admin_panel_settings_24.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 9a5efcd..4a92509 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -33,13 +33,14 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> +