diff --git a/app/src/main/java/ru/myitschool/work/data/auth/AuthNetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/auth/AuthNetworkDataSource.kt index 229f2a0..e359888 100644 --- a/app/src/main/java/ru/myitschool/work/data/auth/AuthNetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/auth/AuthNetworkDataSource.kt @@ -18,16 +18,6 @@ import ru.myitschool.work.data.user.UserDto object AuthNetworkDataSource { -// suspend fun isUserExist(login: String): Result = withContext(Dispatchers.IO) { -// runCatching { -// val result = client.get("$SERVER_ADDRESS/api/login/$login") //10.0.2.2 -// when (result.status) { -// HttpStatusCode.OK -> { return@runCatching true } -// HttpStatusCode.NotFound -> { return@runCatching false } -// else -> {return@runCatching null } -// } -// } -// } suspend fun login(token: String): Result = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/ru/myitschool/work/data/auth/AuthRepoImpl.kt b/app/src/main/java/ru/myitschool/work/data/auth/AuthRepoImpl.kt index fc38cb4..784f383 100644 --- a/app/src/main/java/ru/myitschool/work/data/auth/AuthRepoImpl.kt +++ b/app/src/main/java/ru/myitschool/work/data/auth/AuthRepoImpl.kt @@ -7,9 +7,6 @@ class AuthRepoImpl( private val authNetworkDataSource: AuthNetworkDataSource, private val authStorageDataSource: AuthStorageDataSource ) : AuthRepo { -// override suspend fun isUserExist(email: String): Result { -// return authNetworkDataSource.isUserExist(email) -// } override suspend fun login(email: String, password: String): Result { val token = authStorageDataSource.updateToken(email, password) diff --git a/app/src/main/java/ru/myitschool/work/data/user/EntrancesDto.kt b/app/src/main/java/ru/myitschool/work/data/user/EntrancesDto.kt index c03157b..f50b426 100644 --- a/app/src/main/java/ru/myitschool/work/data/user/EntrancesDto.kt +++ b/app/src/main/java/ru/myitschool/work/data/user/EntrancesDto.kt @@ -1,14 +1,16 @@ package ru.myitschool.work.data.user import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +@Serializable data class EntranceDto( @SerialName("login") val login : String, @SerialName("name") var name: String, - @SerialName("enterAt") - var enterAt: String, + @SerialName("enteredAt") + var enteredAt: String, @SerialName("enterType") var enterType: String, ) { diff --git a/app/src/main/java/ru/myitschool/work/data/user/UserDto.kt b/app/src/main/java/ru/myitschool/work/data/user/UserDto.kt index 07ae1b9..09b3680 100644 --- a/app/src/main/java/ru/myitschool/work/data/user/UserDto.kt +++ b/app/src/main/java/ru/myitschool/work/data/user/UserDto.kt @@ -20,18 +20,9 @@ data class UserDto( val position: String, @SerialName("lastEnter") val lastEntry : String? = null, + @SerialName("access") + val access : String, @SerialName("authorities") val authorities : String ) { - fun toEntity(): UserEntity { - return UserEntity( - id = id ?: throw IllegalArgumentException("User ID cannot be null"), - login, - name = name, - avatarUrl = avatarUrl, - position = position, - lastEntry = lastEntry, - authorities = authorities - ) - } } diff --git a/app/src/main/java/ru/myitschool/work/data/user/UserNetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/user/UserNetworkDataSource.kt index 1bd7f31..2c68b00 100644 --- a/app/src/main/java/ru/myitschool/work/data/user/UserNetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/user/UserNetworkDataSource.kt @@ -1,11 +1,9 @@ -package ru.sicampus.bootcamp2025.data.user +package ru.myitschool.work.data.user import android.util.Log import io.ktor.client.call.body import io.ktor.client.request.get import io.ktor.client.request.header -import io.ktor.client.request.put -import io.ktor.client.request.setBody import io.ktor.client.statement.bodyAsText import io.ktor.http.HttpHeaders import io.ktor.http.HttpStatusCode @@ -14,26 +12,25 @@ import kotlinx.coroutines.withContext import ru.myitschool.work.core.Constants.SERVER_ADDRESS import ru.myitschool.work.data.auth.AuthStorageDataSource.token import ru.myitschool.work.data.auth.Network.client -import ru.myitschool.work.data.user.EntranceDto -import ru.myitschool.work.data.user.UserDto class UserNetworkDataSource { suspend fun getUser(login : String): Result = withContext(Dispatchers.IO) { - runCatching { + //runCatching { - val result = client.get("http://$SERVER_ADDRESS/api/${login}/info") { - header(HttpHeaders.Authorization, token) - } - Log.d("tututuut", "${result.status}") - - - - if (result.status != HttpStatusCode.OK) { - error("Status ${result.status}") - } - Log.d("result", result.bodyAsText()) - result.body() + val result = client.get("$SERVER_ADDRESS/api/${login}/info") { + header(HttpHeaders.Authorization, token) } + + Log.d("tututuut", "${result.status}") + + + + if (result.status != HttpStatusCode.OK) { + error("Status ${result.status}") + } + Log.d("result", result.bodyAsText()) + result.body() + // } } suspend fun getEntrancesList(login : String) : Result> = withContext(Dispatchers.IO){ diff --git a/app/src/main/java/ru/myitschool/work/data/user/UserRepoImpl.kt b/app/src/main/java/ru/myitschool/work/data/user/UserRepoImpl.kt index b544690..71cc30b 100644 --- a/app/src/main/java/ru/myitschool/work/data/user/UserRepoImpl.kt +++ b/app/src/main/java/ru/myitschool/work/data/user/UserRepoImpl.kt @@ -1,7 +1,4 @@ -package ru.sicampus.bootcamp2025.data.user - -import ru.myitschool.work.data.user.EntranceDto -import ru.myitschool.work.data.user.UserDto +package ru.myitschool.work.data.user import ru.myitschool.work.domain.user.EntranceEntity import ru.myitschool.work.domain.user.UserEntity import ru.myitschool.work.domain.user.UserRepo @@ -35,7 +32,7 @@ class UserRepoImpl ( return EntranceEntity( login = login, name = this.name, - enterAt = this.enterAt, + enteredAt = this.enteredAt, enterType = this.enterType ) } diff --git a/app/src/main/java/ru/myitschool/work/domain/user/EntranceEntity.kt b/app/src/main/java/ru/myitschool/work/domain/user/EntranceEntity.kt index 9bf4638..aeb9db0 100644 --- a/app/src/main/java/ru/myitschool/work/domain/user/EntranceEntity.kt +++ b/app/src/main/java/ru/myitschool/work/domain/user/EntranceEntity.kt @@ -1,11 +1,13 @@ package ru.myitschool.work.domain.user import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +@Serializable data class EntranceEntity( val login : String, var name: String, - var enterAt: String, + var enteredAt: String, var enterType: String, ) { diff --git a/app/src/main/java/ru/myitschool/work/domain/user/UserEntity.kt b/app/src/main/java/ru/myitschool/work/domain/user/UserEntity.kt index afe2c60..4ccf054 100644 --- a/app/src/main/java/ru/myitschool/work/domain/user/UserEntity.kt +++ b/app/src/main/java/ru/myitschool/work/domain/user/UserEntity.kt @@ -1,7 +1,7 @@ package ru.myitschool.work.domain.user -import java.sql.Timestamp - +import kotlinx.serialization.Serializable +@Serializable data class UserEntity( val id : Long, var login: String, 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 1a7ee74..92a26b7 100644 --- a/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt +++ b/app/src/main/java/ru/myitschool/work/ui/RootActivity.kt @@ -21,34 +21,42 @@ class RootActivity : AppCompatActivity() { @SuppressLint("ResourceType") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.fragment_profile) + setContentView(R.layout.activity_root) val userRole = intent.getStringExtra("USER_ROLE") - /*val navHostFragment = supportFragmentManager + val navHostFragment = supportFragmentManager .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? - val navController = navHostFragment.navController*/ + val navController = navHostFragment?.navController ?: throw IllegalStateException("NavHostFragment not found") + + navController.setGraph(R.navigation.main_nav_graph) + navController.navigate(R.id.fragment_profile) /*if (userRole == "ROLE_ADMIN") { - bottomNavigationView.menu.clear() - bottomNavigationView.inflateMenu(R.menu.bottom_menu_admin) + //bottomNavigationView.menu.clear() + //bottomNavigationView.inflateMenu(R.menu.bottom_menu_admin) navController.setGraph(R.navigation.main_admin_nav_graph) } else { - bottomNavigationView.menu.clear() - bottomNavigationView.inflateMenu(R.menu.bottom_menu) navController.setGraph(R.navigation.main_nav_graph) + navController.navigate(R.id.fragment_profile) }*/ - onBackPressedDispatcher.addCallback( + + + + + + + /*onBackPressedDispatcher.addCallback( this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { onSupportNavigateUp() } } - ) + )*/ } /*override fun onSupportNavigateUp(): Boolean { diff --git a/app/src/main/java/ru/myitschool/work/ui/profile/EntranceAdapter.kt b/app/src/main/java/ru/myitschool/work/ui/profile/EntranceAdapter.kt new file mode 100644 index 0000000..eada599 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/profile/EntranceAdapter.kt @@ -0,0 +1,53 @@ +package ru.sicampus.bootcamp2025.ui.centerList + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import ru.myitschool.work.databinding.OneEntryListViewBinding +import ru.myitschool.work.domain.user.EntranceEntity + + +class EntranceAdapter( + //private val onCenterClick: (CenterEntity) -> Unit +) : ListAdapter(EntranceDiff) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + OneEntryListViewBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + + class ViewHolder( + private val binding: OneEntryListViewBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(item : EntranceEntity) { + binding.time.text = item.enteredAt + binding.type.text = item.enterType + binding.entry.text = item.name + } + } + + object EntranceDiff : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: EntranceEntity, newItem: EntranceEntity): Boolean { + return oldItem.enteredAt == newItem.enteredAt + } + + override fun areContentsTheSame(oldItem: EntranceEntity, newItem: EntranceEntity): Boolean { + return oldItem == newItem + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/profile/ProfileFragment.kt b/app/src/main/java/ru/myitschool/work/ui/profile/ProfileFragment.kt index f177909..bcacf61 100644 --- a/app/src/main/java/ru/myitschool/work/ui/profile/ProfileFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/profile/ProfileFragment.kt @@ -10,6 +10,7 @@ import com.squareup.picasso.Picasso import ru.myitschool.work.R import ru.myitschool.work.databinding.FragmentProfileBinding import ru.myitschool.work.ui.login.EntryActivity +import ru.myitschool.work.ui.qr.scan.QrScanFragment import ru.myitschool.work.utils.collectWithLifecycle class ProfileFragment : Fragment(R.layout.fragment_profile) { @@ -31,6 +32,14 @@ class ProfileFragment : Fragment(R.layout.fragment_profile) { startActivity(intent) requireActivity().finish() } + viewBinding.qrScan.setOnClickListener{ + val qrScanFragment = QrScanFragment() + val fragmentManager = parentFragmentManager + val fragmentTransaction = fragmentManager.beginTransaction() + fragmentTransaction.replace(R.id.fragment_container, qrScanFragment) + fragmentTransaction.addToBackStack(null) + fragmentTransaction.commit() + } viewModel.state.collectWithLifecycle(this) { state -> @@ -42,25 +51,27 @@ class ProfileFragment : Fragment(R.layout.fragment_profile) { when(state) { is ProfileViewModel.State.Loading -> Unit is ProfileViewModel.State.Show -> { + viewBinding.noData.visibility = View.GONE viewBinding.name.text = state.profileInfo.name viewBinding.position.text = "Должность: ${state.profileInfo.name}" if (state.profileInfo.lastEntry == null) viewBinding.lastEntry.text = "Время последнего входа: Нет данных" else viewBinding.lastEntry.text = "Время последнего входа: ${state.profileInfo.lastEntry}" Picasso.get().load(state.profileInfo.avatarUrl).resize(100, 100).centerCrop().into(viewBinding.imageView) - //if (state.entrancesList == emptyList()) - //viewBinding.recyclerView.visibility = View.GONE + if (state.entrancesList.size == 0) { + viewBinding.noData.visibility = View.VISIBLE + } + } is ProfileViewModel.State.Error -> { viewBinding.errorText.text = state.text - //viewBinding.noData.visibility = View.VISIBLE + } } } } - override fun onDestroyView() { _viewBinding = null super.onDestroyView() diff --git a/app/src/main/java/ru/myitschool/work/ui/profile/ProfileViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/profile/ProfileViewModel.kt index 2229547..66fc4af 100644 --- a/app/src/main/java/ru/myitschool/work/ui/profile/ProfileViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/profile/ProfileViewModel.kt @@ -8,11 +8,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import ru.myitschool.work.data.auth.AuthStorageDataSource +import ru.myitschool.work.data.user.UserNetworkDataSource +import ru.myitschool.work.data.user.UserRepoImpl import ru.myitschool.work.domain.user.EntranceEntity import ru.myitschool.work.domain.user.GetUserUseCase import ru.myitschool.work.domain.user.UserEntity -import ru.sicampus.bootcamp2025.data.user.UserNetworkDataSource -import ru.sicampus.bootcamp2025.data.user.UserRepoImpl + class ProfileViewModel( private val getUserUseCase: GetUserUseCase diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index 8939629..a8148de 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -130,7 +130,7 @@ tools:text="Время последнего входа: 12:00 16.09" /> + app:layout_constraintVertical_bias="0.0" + tools:listitem="@layout/one_entry_list_view"/> diff --git a/app/src/main/res/layout/one_entry_list_view.xml b/app/src/main/res/layout/one_entry_list_view.xml index 0d9b637..554c10e 100644 --- a/app/src/main/res/layout/one_entry_list_view.xml +++ b/app/src/main/res/layout/one_entry_list_view.xml @@ -1,6 +1,54 @@ + android:layout_height="60dp" + xmlns:tools="http://schemas.android.com/tools"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/main_nav_graph.xml b/app/src/main/res/navigation/main_nav_graph.xml new file mode 100644 index 0000000..84aa4ed --- /dev/null +++ b/app/src/main/res/navigation/main_nav_graph.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file