From 7cf154daa01732c8e1b93eb766722ebab7118ea5 Mon Sep 17 00:00:00 2001 From: Clogon Date: Mon, 29 Jan 2024 10:56:34 +0300 Subject: [PATCH] doctor 1 --- .idea/deploymentTargetDropDown.xml | 17 + .idea/inspectionProfiles/Project_Default.xml | 6 + app/build.gradle | 6 + app/src/main/AndroidManifest.xml | 38 +- .../doctor/Adapter/VpAdapterPatientList.kt | 17 + .../example/doctor/AddSportPatientModel.kt | 19 + .../Appeals/AppealsCreateMessageActivity.kt | 17 + .../example/doctor/Appeals/AppealsFragment.kt | 286 ++- .../doctor/Appeals/AppealsNewAdapter.kt | 36 +- .../example/doctor/Appeals/AppealsNewModel.kt | 10 - .../doctor/Appeals/AppealsOldAdapter.kt | 21 +- .../example/doctor/Appeals/AppealsOldModel.kt | 10 - .../doctor/Appeals/CreateMessageFragment.kt | 275 +++ .../TabLayout/Model/AppealsNewListModel.kt | 6 + .../TabLayout/Model/AppealsNewModel.kt | 16 + .../TabLayout/Model/AppealsOldListModel.kt | 6 + .../TabLayout/Model/AppealsOldModel.kt | 16 + .../Appeals/TabLayout/NewAppealsFragment.kt | 247 +- .../Appeals/TabLayout/OldAppealsFragment.kt | 153 +- .../com/example/doctor/Auth/AuthFragment.kt | 116 +- .../doctor/CodeError/Code429Activity.kt | 136 ++ .../doctor/CodeError/Code500Activity.kt | 178 ++ .../main/java/com/example/doctor/DataModel.kt | 30 + .../com/example/doctor/DoctorViewModel.kt | 55 +- .../doctor/Enternet/EnternetActivity.kt | 23 + .../example/doctor/Enternet/EnternetCheck.kt | 41 + .../doctor/Enternet/EnternetFragment.kt | 38 + .../com/example/doctor/Home/HomeFragment.kt | 111 + .../com/example/doctor/Home/HomeInfoModel.kt | 8 + .../java/com/example/doctor/MainActivity.kt | 382 +++- .../java/com/example/doctor/MainFragment.kt | 126 +- .../Patients/Adapter/PatientListAdapter.kt | 2 +- .../doctor/Patients/Model/PatientAllModel.kt | 1 + .../doctor/Patients/Model/PatientIdModel.kt | 9 + .../doctor/Patients/PatientActivity.kt | 421 ++++ .../doctor/Patients/PatientsListFragment.kt | 244 +- .../Reports/Courses/CoursesAllAdapter.kt | 90 + .../Reports/Courses/CoursesYouAdapter.kt | 99 + .../Courses/SportCoursDoctorListModel.kt | 6 + .../{ => Courses}/SportCoursListModel.kt | 2 +- .../Reports/{ => Courses}/SportCoursModel.kt | 6 +- .../Courses/TabLayout/CoursesAllFragment.kt | 204 ++ .../Courses/TabLayout/CoursesYouFragment.kt | 208 ++ .../doctor/Patients/Reports/CoursesAdapter.kt | 76 - .../Patients/Reports/CoursesListAdapter.kt | 90 + .../Reports/Edit/EditSportNoAdapter.kt | 2 +- .../Edit/TabLayout/EditSportNoFragment.kt | 279 ++- .../Edit/TabLayout/EditSportYesFragment.kt | 277 ++- .../Patients/Reports/PatientFragment.kt | 914 ++++++-- .../doctor/Patients/Reports/QBAModel.kt | 2 +- .../doctor/Patients/Reports/QBBAdapter.kt | 247 +- .../ActiveCoursesPatientFragment.kt | 173 ++ .../NotActiveCoursesPatientFragment.kt | 173 ++ .../java/com/example/doctor/Pref/ClearPref.kt | 30 +- .../com/example/doctor/Pref/ConclusionPref.kt | 26 +- .../java/com/example/doctor/Pref/SavePref.kt | 30 +- .../com/example/doctor/Retrofit/DoctorApi.kt | 108 +- .../Courses/Adapter/CoursesDoctorAdapter.kt | 90 + .../doctor/Setting/Courses/CoursesActivity.kt | 22 + .../EditCourses/CreateCoursesFragment.kt | 407 ++++ .../EditCourses/EditCoursesFragment.kt | 242 ++ .../Adapter/EditCoursesDoctorAllAdapter.kt | 107 + .../Adapter/EditCoursesDoctorYourAdapter.kt | 107 + .../AllSportCoursesDoctorFragment.kt | 292 +++ .../Model/CoursesDoctorCA.kt | 8 + .../Model/EditCoursesDoctorListAllModel.kt | 8 + .../Model/EditCoursesDoctorListYourModel.kt | 8 + .../Model/EditCoursesDoctorModel.kt | 12 + .../YourSportCoursesDoctorFragment.kt | 290 +++ .../Courses/Model/CoursesDoctorListModel.kt | 6 + .../Courses/Model/CoursesDoctorModel.kt | 14 + .../example/doctor/Setting/SettingFragment.kt | 72 +- .../com/example/doctor/Worker/MyWorker.kt | 100 + app/src/main/res/anim/fade_in.xml | 6 + app/src/main/res/anim/fade_out.xml | 6 + app/src/main/res/anim/slide_in.xml | 6 + app/src/main/res/anim/slide_out.xml | 6 + app/src/main/res/drawable/add1.png | Bin 0 -> 13553 bytes app/src/main/res/drawable/loading.gif | Bin 0 -> 35499 bytes app/src/main/res/drawable/tab_indicator.xml | 2 +- app/src/main/res/layout/activity_appeals.xml | 10 + app/src/main/res/layout/activity_code429.xml | 73 + app/src/main/res/layout/activity_code500.xml | 89 + app/src/main/res/layout/activity_courses.xml | 10 + app/src/main/res/layout/activity_enternet.xml | 10 + app/src/main/res/layout/activity_main.xml | 96 +- app/src/main/res/layout/activity_patient.xml | 10 + .../fragment_active_courses_patient.xml | 20 + .../fragment_all_sport_courses_doctor.xml | 35 + app/src/main/res/layout/fragment_appeals.xml | 72 +- .../main/res/layout/fragment_courses_all.xml | 34 + .../main/res/layout/fragment_courses_you.xml | 34 + .../res/layout/fragment_create_courses.xml | 324 +++ .../res/layout/fragment_create_message.xml | 154 ++ .../main/res/layout/fragment_edit_courses.xml | 113 + .../main/res/layout/fragment_edit_sport.xml | 8 +- .../res/layout/fragment_edit_sport_no.xml | 25 + .../res/layout/fragment_edit_sport_yes.xml | 26 + app/src/main/res/layout/fragment_enternet.xml | 31 + app/src/main/res/layout/fragment_home.xml | 302 ++- app/src/main/res/layout/fragment_main.xml | 4 +- .../main/res/layout/fragment_new_appeals.xml | 40 +- .../fragment_not_active_courses_patient.xml | 20 + .../main/res/layout/fragment_old_appeals.xml | 40 + app/src/main/res/layout/fragment_patients.xml | 2028 ++++++++++------- .../res/layout/fragment_patients_list.xml | 106 +- app/src/main/res/layout/fragment_setting.xml | 78 +- .../fragment_your_sport_courses_doctor.xml | 34 + app/src/main/res/layout/item_appeals_new.xml | 26 +- app/src/main/res/layout/item_appeals_old.xml | 23 +- app/src/main/res/layout/item_buttom_menu.xml | 5 +- .../res/layout/item_card_courses_doctor.xml | 89 + app/src/main/res/layout/item_card_patient.xml | 6 +- .../main/res/layout/item_edit_sport_no.xml | 4 +- app/src/main/res/layout/item_qba.xml | 3 +- app/src/main/res/layout/item_sport_course.xml | 2 +- app/src/main/res/menu/bottom_menu.xml | 3 +- app/src/main/res/navigation/main_nav.xml | 8 + app/src/main/res/transition/fade.xml | 3 + app/src/main/res/transition/slide_left.xml | 4 + app/src/main/res/transition/slide_right.xml | 4 + app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/style.xml | 8 + build.gradle | 1 + 124 files changed, 10194 insertions(+), 1799 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 app/src/main/java/com/example/doctor/Adapter/VpAdapterPatientList.kt create mode 100644 app/src/main/java/com/example/doctor/AddSportPatientModel.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/AppealsCreateMessageActivity.kt delete mode 100644 app/src/main/java/com/example/doctor/Appeals/AppealsNewModel.kt delete mode 100644 app/src/main/java/com/example/doctor/Appeals/AppealsOldModel.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/CreateMessageFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewListModel.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewModel.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldListModel.kt create mode 100644 app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldModel.kt create mode 100644 app/src/main/java/com/example/doctor/CodeError/Code429Activity.kt create mode 100644 app/src/main/java/com/example/doctor/CodeError/Code500Activity.kt create mode 100644 app/src/main/java/com/example/doctor/DataModel.kt create mode 100644 app/src/main/java/com/example/doctor/Enternet/EnternetActivity.kt create mode 100644 app/src/main/java/com/example/doctor/Enternet/EnternetCheck.kt create mode 100644 app/src/main/java/com/example/doctor/Enternet/EnternetFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Home/HomeInfoModel.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Model/PatientIdModel.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/PatientActivity.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesAllAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesYouAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursDoctorListModel.kt rename app/src/main/java/com/example/doctor/Patients/Reports/{ => Courses}/SportCoursListModel.kt (60%) rename app/src/main/java/com/example/doctor/Patients/Reports/{ => Courses}/SportCoursModel.kt (70%) create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesAllFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesYouFragment.kt delete mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/CoursesAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/Reports/CoursesListAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/ActiveCoursesPatientFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/NotActiveCoursesPatientFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/Adapter/CoursesDoctorAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/CoursesActivity.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/CreateCoursesFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/EditCoursesFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorAllAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorYourAdapter.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/AllSportCoursesDoctorFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/CoursesDoctorCA.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListAllModel.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListYourModel.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorModel.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/YourSportCoursesDoctorFragment.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorListModel.kt create mode 100644 app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorModel.kt create mode 100644 app/src/main/java/com/example/doctor/Worker/MyWorker.kt create mode 100644 app/src/main/res/anim/fade_in.xml create mode 100644 app/src/main/res/anim/fade_out.xml create mode 100644 app/src/main/res/anim/slide_in.xml create mode 100644 app/src/main/res/anim/slide_out.xml create mode 100644 app/src/main/res/drawable/add1.png create mode 100644 app/src/main/res/drawable/loading.gif create mode 100644 app/src/main/res/layout/activity_appeals.xml create mode 100644 app/src/main/res/layout/activity_code429.xml create mode 100644 app/src/main/res/layout/activity_code500.xml create mode 100644 app/src/main/res/layout/activity_courses.xml create mode 100644 app/src/main/res/layout/activity_enternet.xml create mode 100644 app/src/main/res/layout/activity_patient.xml create mode 100644 app/src/main/res/layout/fragment_active_courses_patient.xml create mode 100644 app/src/main/res/layout/fragment_all_sport_courses_doctor.xml create mode 100644 app/src/main/res/layout/fragment_courses_all.xml create mode 100644 app/src/main/res/layout/fragment_courses_you.xml create mode 100644 app/src/main/res/layout/fragment_create_courses.xml create mode 100644 app/src/main/res/layout/fragment_create_message.xml create mode 100644 app/src/main/res/layout/fragment_edit_courses.xml create mode 100644 app/src/main/res/layout/fragment_enternet.xml create mode 100644 app/src/main/res/layout/fragment_not_active_courses_patient.xml create mode 100644 app/src/main/res/layout/fragment_your_sport_courses_doctor.xml create mode 100644 app/src/main/res/layout/item_card_courses_doctor.xml create mode 100644 app/src/main/res/navigation/main_nav.xml create mode 100644 app/src/main/res/transition/fade.xml create mode 100644 app/src/main/res/transition/slide_left.xml create mode 100644 app/src/main/res/transition/slide_right.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..f60ae34 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..053b7aa --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index a700852..e27a301 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -90,7 +90,13 @@ dependencies { //Свайп implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" + implementation "androidx.work:work-runtime-ktx:2.8.1" +// // Kotlin +// implementation "androidx.navigation:navigation-fragment-ktx:2.5.2" +// implementation "androidx.navigation:navigation-ui-ktx:2.5.2" + + } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4acd25a..7c659b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,13 +1,19 @@ - + xmlns:tools="http://schemas.android.com/tools" > + + + + + + + android:usesCleartextTraffic="true" + tools:targetApi="31" > + + + + + + + + android:windowSoftInputMode="adjustPan|stateAlwaysHidden" > diff --git a/app/src/main/java/com/example/doctor/Adapter/VpAdapterPatientList.kt b/app/src/main/java/com/example/doctor/Adapter/VpAdapterPatientList.kt new file mode 100644 index 0000000..d9c6f2f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Adapter/VpAdapterPatientList.kt @@ -0,0 +1,17 @@ +package com.example.doctor.Adapter + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class VpAdapterPatientList(fr_act:FragmentActivity, private val list:List):FragmentStateAdapter(fr_act) {//private val list:List - список с фрагментами сюда передастся, тоесть с двумя фрагментами + //Возврощаем для createFragment количество элементов(фрагментов) в листе(List) + override fun getItemCount(): Int { + return list.size//возврощаем количество фрагметов + } + + //Позиция фрагмента или 1 или 2, то есть 0 или 1. И по позиции будут выводится фрагмент. + override fun createFragment(position: Int): Fragment { + return list[position]//Возврощаем фрагмент из листа по позиции + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/AddSportPatientModel.kt b/app/src/main/java/com/example/doctor/AddSportPatientModel.kt new file mode 100644 index 0000000..065d225 --- /dev/null +++ b/app/src/main/java/com/example/doctor/AddSportPatientModel.kt @@ -0,0 +1,19 @@ +package com.example.doctor + +data class AddSportPatientModel( + val id: Int, + val status: String, + val one: Int, + val two: Int, + val three: Int, + val four: Int, + val five: Int, + val six: Int, + val seven: Int, + val eight: Int, + val nine: Int, + val ten: Int, + val eleven: Int, + val twelve: Int, + ) + diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsCreateMessageActivity.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsCreateMessageActivity.kt new file mode 100644 index 0000000..3323a12 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/AppealsCreateMessageActivity.kt @@ -0,0 +1,17 @@ +package com.example.doctor.Appeals + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import com.example.doctor.R +import com.example.doctor.databinding.ActivityAppealsBinding + +class AppealsCreateMessageActivity : AppCompatActivity() { + private lateinit var binding: ActivityAppealsBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityAppealsBinding.inflate(layoutInflater) + setContentView(binding.root) + supportFragmentManager.beginTransaction().replace(R.id.CLAppealsActivity, CreateMessageFragment.newInstance()).commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsFragment.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsFragment.kt index a9ad849..104dc31 100644 --- a/app/src/main/java/com/example/doctor/Appeals/AppealsFragment.kt +++ b/app/src/main/java/com/example/doctor/Appeals/AppealsFragment.kt @@ -1,21 +1,58 @@ package com.example.doctor.Appeals +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.fragment.app.FragmentActivity +import androidx.fragment.app.activityViewModels import com.example.doctor.Adapter.VpAdapter import com.example.doctor.R import com.example.doctor.Appeals.TabLayout.OldAppealsFragment import com.example.doctor.Appeals.TabLayout.NewAppealsFragment +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Toast.showCustomInfoToast import com.example.doctor.databinding.FragmentAppealsBinding import com.google.android.material.tabs.TabLayoutMediator +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer class AppealsFragment : Fragment() { - private lateinit var binding:FragmentAppealsBinding + private lateinit var binding: FragmentAppealsBinding + private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + + private val model: DoctorViewModel by activityViewModels() + + val prefDoctorConclusion = ConclusionPref() + private val dataModel: DataModel by activityViewModels()//Для передачи данных + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() private val tList = listOf( "новые", @@ -40,6 +77,138 @@ class AppealsFragment : Fragment() { super.onViewCreated(view, savedInstanceState) init() + binding.btnAddMessage.setOnClickListener { + val intetn = Intent(requireContext(), AppealsCreateMessageActivity::class.java) + startActivity(intetn) +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(R.id.CLAppeals, CreateMessageFragment.newInstance())?.commit() +// binding.ConstrainLayoutProductEdit.visibility = View.GONE +// binding.CLAppeals.visibility = View.VISIBLE + } + +// dataModel.patientAppeal.observe(viewLifecycleOwner, Observer { +// requireActivity().runOnUiThread { +// val viewPatient = prefDoctorConclusion.conclusionViewPatient(requireContext()) +// val idPatient = prefDoctorConclusion.conclusionIdPatient(requireContext()) +// if (viewPatient == 1 && idPatient != 0) { +// +// prefDoctorClear.clearIdPatient(requireContext()) +// prefDoctorClear.clearViewPatient(requireContext()) +// GetPatientID(it) +// } +// } +// }) + +// dataModel.patientAppeal.observe(viewLifecycleOwner, Observer { +// binding.btnExit.visibility = View.GONE +// binding.CLMainPatientAppeals.visibility = View.GONE +// +// }) + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + + + private fun getOldAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorOld("Bearer $Tokens") + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if (List?.appeals_old != null) { + model.appealsOldList.value = List.appeals_old + } + } + } + + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Получение необработанных сообщений + private fun getNewAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorNew("Bearer $Tokens") + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if(List.appeals_new != null){ + model.appealsNewList.value = List.appeals_new + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } //Функция подключения переключения @@ -54,12 +223,121 @@ class AppealsFragment : Fragment() { }.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран //Изменения цвета в зависомости на каком из tabLayout вы находитесь - binding.tabLayoutProduct.setTabTextColors(getResources().getColor(R.color.black), - getResources().getColor(R.color.white)); + binding.tabLayoutProduct.setTabTextColors( + getResources().getColor(R.color.black), + getResources().getColor(R.color.white) + ); + + } + +// //Получение необработанных сообщений +// private fun addCheckAppeals(id: Int, id_patient: Int) { +// if (enternetCheck.isOnline(requireContext())) { +// initRetrofit() +// val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) +// CoroutineScope(Dispatchers.IO).launch { +// val listAppeals = doctorApi.UpdateMessageDoctor("Bearer $Tokens", id, id_patient) +// requireActivity().runOnUiThread { +// +// //Фиксируем полученные данные +// val AppealsMes = listAppeals.body() +// +// //Если нету ошибок +// if (AppealsMes != null) { +// Toast(requireContext()).showCustomInfoToast( +// AppealsMes.message, +// requireActivity() +// ) +// } +// +// } +// +// } +// } else { +// val intetn = Intent(requireContext(), EnternetActivity::class.java) +// activity?.finish() +// startActivity(intetn) +// } +// +// } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + +// private fun GetPatientID(idPatient: Int) { +// if (enternetCheck.isOnline(requireContext())) { +// initRetrofit() +// val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) +// CoroutineScope(Dispatchers.IO).launch { +// val listPatient = doctorApi.GetPatientID("Bearer $Tokens", idPatient) +// requireActivity().runOnUiThread { +// +// //Фиксируем полученные данные +// val patientId = listPatient.body() +// +// //Если нету ошибок +// if (patientId != null) { +// //Вывод фрагмента на активити при первоначальной загрузке +//// activity?.supportFragmentManager?.beginTransaction() +//// ?.replace(R.id.CLMainPatientAppeals, PatientFragment.newInstance()) +//// ?.commit() +// model.patientCurrent.value = patientId +// +// } +// } +// +// } +// } else { +// val intetn = Intent(requireContext(), EnternetActivity::class.java) +// activity?.finish() +// startActivity(intetn) +// } +// +// } + companion object { - fun newInstance() = AppealsFragment() } + + + override fun onStart() { + super.onStart() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 10000) { + activity?.runOnUiThread { + getOldAppeals() + getNewAppeals() + } + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsNewAdapter.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsNewAdapter.kt index bc43850..59afe2e 100644 --- a/app/src/main/java/com/example/doctor/Appeals/AppealsNewAdapter.kt +++ b/app/src/main/java/com/example/doctor/Appeals/AppealsNewAdapter.kt @@ -1,26 +1,26 @@ package com.example.doctor.Appeals import android.annotation.SuppressLint -import android.os.Handler import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.Appeals.TabLayout.Model.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldModel import com.example.doctor.R -import com.example.doctor.databinding.ItemAppealsBinding import com.example.doctor.databinding.ItemAppealsNewBinding -class AppealsNewAdapter(val listener_zakaz: Listener) : +class AppealsNewAdapter(val listener_check_apeals: Listener, val listener_patient_apeals: Listener2) : ListAdapter( Comparator() ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку - class Holder(view: View, val listener_zakaz: Listener) : + class Holder(view: View, val listener_check_apeals: Listener, val listener_patient_apeals: Listener2) : RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. //Для передачи данных @@ -32,23 +32,26 @@ class AppealsNewAdapter(val listener_zakaz: Listener) : //init - дает возможность внутри адаптера обращаться к элементам экрана init { - itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка - itemView.setEnabled(false) - itemTemp?.let { it1 -> listener_zakaz.onClickAppeals(it1) } - + binding.btnAdd.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it1 -> listener_check_apeals.onClickAppeals(it1) } + } + binding.btnPatient.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it2 -> listener_patient_apeals.onClickAppealsPatient(it2) } } } @SuppressLint("SuspiciousIndentation") fun bind(item: AppealsNewModel) = with(binding) {//Productitem - перпедаем данные itemTemp = item - txtNumber.text = item.id.toString()+"." + txtNumber.text = item.number.toString()+"." txtAppeals.text = item.text txtLoginPatient.text = item.login if (item.expand) { - txtAppeals.maxLines = 100 + txtAppeals.maxLines = 30 } else { txtAppeals.maxLines = 1 } @@ -64,9 +67,7 @@ class AppealsNewAdapter(val listener_zakaz: Listener) : } } - btnAdd.setOnClickListener{ - CardViewNew.visibility = View.GONE - } + } } @@ -74,7 +75,7 @@ class AppealsNewAdapter(val listener_zakaz: Listener) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_appeals_new, parent, false)//Создаем(надуваем) list_item - return Holder(view, listener_zakaz)//Через Holder возврощаем view + return Holder(view, listener_check_apeals,listener_patient_apeals)//Через Holder возврощаем view } override fun onBindViewHolder(holder: Holder, position: Int) { @@ -99,12 +100,17 @@ class AppealsNewAdapter(val listener_zakaz: Listener) : } } - //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { fun onClickAppeals(item: AppealsNewModel) } + interface Listener2 { + fun onClickAppealsPatient(item: AppealsNewModel) + } + + } diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsNewModel.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsNewModel.kt deleted file mode 100644 index 136e6f0..0000000 --- a/app/src/main/java/com/example/doctor/Appeals/AppealsNewModel.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.doctor.Appeals - -data class AppealsNewModel( - val id: Int, - val login: String, - val text: String, - val id_user:Int, - var expand : Boolean = false -) - diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsOldAdapter.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsOldAdapter.kt index f49a328..b666a0e 100644 --- a/app/src/main/java/com/example/doctor/Appeals/AppealsOldAdapter.kt +++ b/app/src/main/java/com/example/doctor/Appeals/AppealsOldAdapter.kt @@ -1,25 +1,26 @@ package com.example.doctor.Appeals import android.annotation.SuppressLint -import android.opengl.Visibility import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldModel +import com.example.doctor.Appeals.TabLayout.OldAppealsFragment import com.example.doctor.R import com.example.doctor.databinding.ItemAppealsOldBinding -class AppealsOldAdapter(val listener_zakaz: Listener) : +class AppealsOldAdapter(val listener_appeal: Listener, val listener_patient_apeals: OldAppealsFragment) : ListAdapter( Comparator() ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку - class Holder(view: View, val listener_zakaz: Listener) : + class Holder(view: View, val listener_appeal: Listener, val listener_patient_apeals: OldAppealsFragment) : RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. //Для передачи данных @@ -32,15 +33,18 @@ class AppealsOldAdapter(val listener_zakaz: Listener) : //init - дает возможность внутри адаптера обращаться к элементам экрана init { itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка - itemView.setEnabled(false) - itemTemp?.let { it1 -> listener_zakaz.onClickAppeals(it1) } + itemTemp?.let { it1 -> listener_appeal.onClickAppeals(it1) } + } + binding.btnPatient.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it2 -> listener_patient_apeals.onClickAppealsPatient(it2) } } } @SuppressLint("SuspiciousIndentation") fun bind(item: AppealsOldModel) = with(binding) {//Productitem - перпедаем данные itemTemp = item - txtNumber.text = item.id.toString()+"." + txtNumber.text = item.number.toString()+"." txtAppeals.text = item.text txtLoginPatient.text = item.login @@ -71,7 +75,7 @@ class AppealsOldAdapter(val listener_zakaz: Listener) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_appeals_old, parent, false)//Создаем(надуваем) list_item - return Holder(view, listener_zakaz)//Через Holder возврощаем view + return Holder(view, listener_appeal,listener_patient_apeals)//Через Holder возврощаем view } override fun onBindViewHolder(holder: Holder, position: Int) { @@ -100,6 +104,9 @@ class AppealsOldAdapter(val listener_zakaz: Listener) : interface Listener { fun onClickAppeals(item: AppealsOldModel) } + interface Listener2 { + fun onClickAppealsPatient(item: AppealsOldModel) + } } diff --git a/app/src/main/java/com/example/doctor/Appeals/AppealsOldModel.kt b/app/src/main/java/com/example/doctor/Appeals/AppealsOldModel.kt deleted file mode 100644 index cf7b5a1..0000000 --- a/app/src/main/java/com/example/doctor/Appeals/AppealsOldModel.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.doctor.Appeals - -data class AppealsOldModel( - val id: Int, - val login: String, - val text: String, - val id_user:Int, - var expand : Boolean = false -) - diff --git a/app/src/main/java/com/example/doctor/Appeals/CreateMessageFragment.kt b/app/src/main/java/com/example/doctor/Appeals/CreateMessageFragment.kt new file mode 100644 index 0000000..dd1c68a --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/CreateMessageFragment.kt @@ -0,0 +1,275 @@ +package com.example.doctor.Appeals + +import android.content.Intent +import android.os.Bundle +import android.transition.TransitionInflater +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.Toast +import androidx.fragment.app.activityViewModels +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Model.PatientAllModel +import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentCreateMessageBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + + +class CreateMessageFragment : Fragment() { + private lateinit var binding: FragmentCreateMessageBinding + private val dataModel: DataModel by activityViewModels()//Для передачи данных + private val modelDoctor: DoctorViewModel by activityViewModels() + + private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + + var patientList:List?=null + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCreateMessageBinding.inflate(layoutInflater,container,false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val inflater = TransitionInflater.from(requireContext()) + enterTransition = inflater.inflateTransition(R.transition.slide_right) + exitTransition = inflater.inflateTransition(R.transition.slide_right) + + GetPatientList() + + binding.btnAddMessagePatient.setOnClickListener{ + val login = binding.searchPatient.text.toString() + val text = binding.edTextMessagePatient.text.toString() + if(login!="" && text!=""){ + AddMessageDoctor() + } + else{ + Toast(requireContext()).showCustomInfoToast("Не все данные заполнены", requireActivity()) + + } + } + +// binding.btnExit.setOnClickListener{ +// dataModel.patientAppeal.value = 1 +// } + + binding.btnExit.setOnClickListener{ + activity?.finish() + } + + modelDoctor.patientListSearch.observe(viewLifecycleOwner){ + if(patientList!=it){ + patientList =it + addPatientLogin(it) + } + } + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + + private fun addPatientLogin(patient: List) { + val listPatient = arrayListOf("") + for(i in 0 .. patient.count()-1){ + listPatient.add(patient[i].login.toString()) + } + + val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, listPatient) + + binding.searchPatient.threshold = 1 + binding.searchPatient.setAdapter(adapter) + + binding.searchPatient.setOnItemClickListener { parent, arg1, pos, id -> + //val list = ArrayList() + val serpat = binding.searchPatient.text.toString() + binding.searchPatient.setText(serpat) + + } + } + + + //Получения списка пациентов + fun GetPatientList() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientAll("Bearer $Tokens") + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + //Если нету ошибок + if (List != null) { + modelDoctor.patientListSearch.value = List.patient + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Отправка сообщения + fun AddMessageDoctor() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.AddMessageDoctor("Bearer $Tokens",binding.searchPatient.text.toString(),binding.edTextMessagePatient.text.toString()) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + + if (Nice) { + if (List != null) { + //Если нету ошибок + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + binding.edTextMessagePatient.setText("") + } + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + companion object { + + fun newInstance() = CreateMessageFragment() + } + + + override fun onResume() { + super.onResume() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 10000) { + activity?.runOnUiThread { + GetPatientList() + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewListModel.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewListModel.kt new file mode 100644 index 0000000..b42669c --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewListModel.kt @@ -0,0 +1,6 @@ +package com.example.doctor.Appeals.TabLayout.Model + +data class AppealsNewListModel( + val appeals_new: List +) + diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewModel.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewModel.kt new file mode 100644 index 0000000..ae76119 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsNewModel.kt @@ -0,0 +1,16 @@ +package com.example.doctor.Appeals.TabLayout.Model + +data class AppealsNewModel( + val id: Int, + val number: Int, + val text: String, + val id_patient: Int, + val id_doctor: Int, + val check: Int, + val login: String, + val created_at: String, + val updated_at: String, + var expand : Boolean = false, + + ) + diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldListModel.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldListModel.kt new file mode 100644 index 0000000..e6c2c12 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldListModel.kt @@ -0,0 +1,6 @@ +package com.example.doctor.Appeals.TabLayout.Model + +data class AppealsOldListModel( + val appeals_old: List +) + diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldModel.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldModel.kt new file mode 100644 index 0000000..0c2da4d --- /dev/null +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/Model/AppealsOldModel.kt @@ -0,0 +1,16 @@ +package com.example.doctor.Appeals.TabLayout.Model + +data class AppealsOldModel( + val id: Int, + val number: Int, + val text: String, + val id_patient: Int, + val id_doctor: Int, + val check: Int, + val login: String, + val created_at: String, + val updated_at: String, + var expand : Boolean = false, + + ) + diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/NewAppealsFragment.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/NewAppealsFragment.kt index 09d1a7d..e1a5d5a 100644 --- a/app/src/main/java/com/example/doctor/Appeals/TabLayout/NewAppealsFragment.kt +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/NewAppealsFragment.kt @@ -1,25 +1,56 @@ package com.example.doctor.Appeals.TabLayout +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager import com.example.doctor.Appeals.AppealsNewAdapter -import com.example.doctor.Appeals.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldModel +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Model.PatientIdModel +import com.example.doctor.Patients.PatientActivity +import com.example.doctor.Patients.PatientsListFragment +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Toast.showCustomInfoToast import com.example.doctor.databinding.FragmentNewAppealsBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory -class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener { +class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener,AppealsNewAdapter.Listener2 { private lateinit var binding:FragmentNewAppealsBinding private val model: DoctorViewModel by activityViewModels() + private val dataModel: DataModel by activityViewModels()//Для передачи данных lateinit var adapter: AppealsNewAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorSave = SavePref() + //Класс проверки интеренета + val enternetCheck = EnternetCheck() - + //Список новых соощений + var newAppeals: List? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -30,29 +61,200 @@ class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + //binding.CLNull.visibility = View.VISIBLE initRcViewAppeals() patientListCurrent() model.appealsNewList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment - adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + if(newAppeals != it){ + newAppeals = it + adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + if(newAppeals !=null){ + binding.CLNull.visibility = View.GONE + binding.txtNull.visibility = View.GONE + } + + } } - addNewAppeals() + getNewAppeals() } - private fun addNewAppeals() { - val list = ArrayList() + //Получение необработанных сообщений + private fun getNewAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorNew("Bearer $Tokens") + requireActivity().runOnUiThread { - for (i in 1..5){ - val itemPatient = AppealsNewModel( - i, - "Patient_$i", - "asdasds adnas kjhdkl ashdlkashdkjalks hdjlkasjdlk ajldkhas j djask hsfldksjfksdf", - i, - ) - list.add(itemPatient)//Передали заполненый список + + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if(List?.appeals_new != null){ + + // binding.CLNull.visibility = View.GONE + binding.txtNull.visibility = View.GONE + model.appealsNewList.value = List.appeals_new + } + else{ + // binding.CLNull.visibility = View.VISIBLE + binding.txtNull.visibility = View.VISIBLE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } - model.appealsNewList.value = list + + } + + private fun getOldAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorOld("Bearer $Tokens") + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if(List?.appeals_old != null){ + // binding.txtNull.visibility = View.GONE + model.appealsOldList.value = List.appeals_old + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Получение необработанных сообщений + private fun addCheckAppeals(id:Int,id_patient:Int) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.UpdateMessageDoctor("Bearer $Tokens",id,id_patient) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + + } + } + getNewAppeals() + getOldAppeals() + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + } //Вывод прогресса на один день @@ -66,7 +268,7 @@ class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener { //Инициализация списка private fun initRcViewAppeals() = with(binding) { rcView.layoutManager = GridLayoutManager(requireContext(),1)//По вертикали будет выводить по умолчанию - adapter = AppealsNewAdapter(this@NewAppealsFragment) + adapter = AppealsNewAdapter(this@NewAppealsFragment,this@NewAppealsFragment) rcView.adapter = adapter } @@ -76,6 +278,15 @@ class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener { } override fun onClickAppeals(item: AppealsNewModel) { + addCheckAppeals(item.id,item.id_patient) + } + override fun onClickAppealsPatient(item: AppealsNewModel) { + prefDoctorSave.saveIdPatient(requireContext(),item.id_patient) + prefDoctorSave.saveViewPatient(requireContext(),1) + model.patientId.value = PatientIdModel(item.id) + //dataModel.patientAppeal.value = item.id_patient + val intetn = Intent(requireContext(), PatientActivity::class.java) + startActivity(intetn) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Appeals/TabLayout/OldAppealsFragment.kt b/app/src/main/java/com/example/doctor/Appeals/TabLayout/OldAppealsFragment.kt index 1c0bb62..7f5e09b 100644 --- a/app/src/main/java/com/example/doctor/Appeals/TabLayout/OldAppealsFragment.kt +++ b/app/src/main/java/com/example/doctor/Appeals/TabLayout/OldAppealsFragment.kt @@ -1,5 +1,6 @@ package com.example.doctor.Appeals.TabLayout +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -8,15 +9,48 @@ import android.view.ViewGroup import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager import com.example.doctor.Appeals.AppealsOldAdapter -import com.example.doctor.Appeals.AppealsOldModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldModel +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Model.PatientIdModel +import com.example.doctor.Patients.PatientActivity +import com.example.doctor.Patients.PatientsListFragment +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi import com.example.doctor.databinding.FragmentOldAppealsBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import kotlin.concurrent.fixedRateTimer -class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener { +class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener,AppealsOldAdapter.Listener2 { private lateinit var binding:FragmentOldAppealsBinding private val model: DoctorViewModel by activityViewModels() + private val dataModel: DataModel by activityViewModels()//Для передачи данных + lateinit var adapter: AppealsOldAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + //Список прочитанных соощений + var oldAppeals: List? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -28,29 +62,105 @@ class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + //binding.CLNull.visibility = View.VISIBLE initRcViewAppeals() appealsAllCurrent() - model.appealsAllList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment - adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + model.appealsOldList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(oldAppeals != it){ + + oldAppeals = it + adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + if(oldAppeals !=null){ + binding.CLNull.visibility = View.GONE + binding.txtNull.visibility = View.GONE + } + } } - addAllAppeals() + getOldAppeals() + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } } - private fun addAllAppeals() { - val list = ArrayList() + private fun getOldAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorOld("Bearer $Tokens") + requireActivity().runOnUiThread { - for (i in 1..7){ - val itemPatient = AppealsOldModel( - i, - "Patient_$i", - " 81 23891 23812 37817411 sdasds adnas kjhdkl ashdlk ashdkjalks ashdlkashdkjalks hdjlkasjdlk ajldkhas hdjlkasjdlk ajldkhasas hdlkashdkjalks hdjlkasjdlk ajldkhasashdlkashdkjalks hdjlkasjdlk ajldkhas j djask hsfldksjfksdf", - i, - ) - list.add(itemPatient)//Передали заполненый список + //Фиксируем полученные данные + val List = listAppeals.body() + val Nice = listAppeals.isSuccessful + val Code = listAppeals.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + if(List.appeals_old != null){ + //binding.CLNull.visibility = View.GONE + binding.txtNull.visibility = View.GONE + model.appealsOldList.value = List.appeals_old + } + else{ + //binding.CLNull.visibility = View.VISIBLE + binding.txtNull.visibility = View.VISIBLE + } + }else{ + // binding.CLNull.visibility = View.VISIBLE + binding.txtNull.visibility = View.VISIBLE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } - model.appealsAllList.value = list + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + } //Вывод прогресса на один день @@ -64,7 +174,7 @@ class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener { //Инициализация списка private fun initRcViewAppeals() = with(binding) { rcView.layoutManager = GridLayoutManager(requireContext(),1)//По вертикали будет выводить по умолчанию - adapter = AppealsOldAdapter(this@OldAppealsFragment) + adapter = AppealsOldAdapter(this@OldAppealsFragment,this@OldAppealsFragment) rcView.adapter = adapter } companion object { @@ -75,4 +185,13 @@ class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener { override fun onClickAppeals(item: AppealsOldModel) { } + + override fun onClickAppealsPatient(item: AppealsOldModel) { +// prefDoctorSave.saveIdPatient(requireContext(),item.id_patient) +// prefDoctorSave.saveViewPatient(requireContext(),1) + model.patientId.value = PatientIdModel(item.id) + // dataModel.patientAppeal.value = item.id_patient + val intetn = Intent(requireContext(), PatientActivity::class.java) + startActivity(intetn) + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Auth/AuthFragment.kt b/app/src/main/java/com/example/doctor/Auth/AuthFragment.kt index 8312813..f51e181 100644 --- a/app/src/main/java/com/example/doctor/Auth/AuthFragment.kt +++ b/app/src/main/java/com/example/doctor/Auth/AuthFragment.kt @@ -12,8 +12,13 @@ import android.widget.Toast import androidx.fragment.app.activityViewModels import com.example.doctor.Auth.Model.AuthModel import com.example.doctor.Auth.Model.UserModel +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck import com.example.doctor.MainActivity +import com.example.doctor.Pref.ClearPref import com.example.doctor.Pref.ConclusionPref import com.example.doctor.R import com.example.doctor.Retrofit.DoctorApi @@ -43,6 +48,10 @@ class AuthFragment : Fragment() { private var Token = "" val prefDoctorSave = SavePref() val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -56,6 +65,7 @@ class AuthFragment : Fragment() { super.onViewCreated(view, savedInstanceState) initRetrofit() + prefDoctorClear.clearToken(requireContext()) Token = prefDoctorConclusion.conclusionToken(requireContext()) binding.apply { @@ -81,67 +91,65 @@ class AuthFragment : Fragment() { } } -// private fun Auth(authModel: AuthModel) { -// CoroutineScope(Dispatchers.IO).launch { -// val response = doctorApi.Auth(authModel) -// val errorMessage = response.errorBody()?.string() -// ?.let { JSONObject(it).getString("message") }//JSONObject(response.errorBody()?.string()) -// requireActivity().runOnUiThread { -// binding.textError.text = errorMessage -// val user = response.body() -// -// //Если есть такой пользователь -// if (user != null) { -// DoctorviewModel.token.value = user.token -// prefDoctor.saveToken(user.token) -// val intetn = Intent(requireContext(), MainActivity::class.java) -// startActivity(intetn) -// activity?.finish() -// } -// } -// } -// -// } -// -// private fun Auth(authModel: AuthModel) { -// //Если есть такой пользователь -// if (authModel.login == "asd" && authModel.password == "asd" ) { -// DoctorviewModel.token.value = "sdadssdasdaasdad434fk3ioj9" -// prefDoctorSave.saveToken(requireContext(),"sdadssdasdaasdad434fk3ioj9") -// val intetn = Intent(requireContext(), MainActivity::class.java) -// startActivity(intetn) -// activity?.finish() -// } -// -// } private fun Auth(authModel: AuthModel) { - CoroutineScope(Dispatchers.IO).launch { - val response = doctorApi.LoginDoctor(authModel) - val errorMessage = response.errorBody()?.string() - ?.let { JSONObject(it).getString("error") }//JSONObject(response.errorBody()?.string()) - requireActivity().runOnUiThread { - Log.i("errorMessage",errorMessage.toString()) - val user = response.body() + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + CoroutineScope(Dispatchers.IO).launch { + val response = doctorApi.LoginDoctor(authModel) + val errorMessage = response.errorBody()?.string() + ?.let { JSONObject(it).getString("error") }//JSONObject(response.errorBody()?.string()) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = response.body() + val Nice = response.isSuccessful + val Code = response.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + DoctorviewModel.token.value = List.token + prefDoctorSave.saveToken(requireContext(), List.token) + + val intetn = Intent(requireContext(), MainActivity::class.java) + startActivity(intetn) + activity?.finish() + } + else{ + Toast(requireContext()).showCustomInfoToast( + "Такого пользователя нету", + requireActivity() + ) + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } - //Если есть такой пользователь - if (user != null) { - DoctorviewModel.token.value = user.token - prefDoctorSave.saveToken(requireContext(), user.token) - val intetn = Intent(requireContext(), MainActivity::class.java) - startActivity(intetn) - activity?.finish() - } - else{ - Toast(requireContext()).showCustomInfoToast( - "Такого пользователя нету", - requireActivity() - ) } } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } @@ -156,7 +164,7 @@ class AuthFragment : Fragment() { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/com/example/doctor/CodeError/Code429Activity.kt b/app/src/main/java/com/example/doctor/CodeError/Code429Activity.kt new file mode 100644 index 0000000..afe69f1 --- /dev/null +++ b/app/src/main/java/com/example/doctor/CodeError/Code429Activity.kt @@ -0,0 +1,136 @@ +package com.example.doctor.CodeError + +import android.annotation.SuppressLint +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.CountDownTimer +import android.util.Log +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.MainActivity +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.databinding.ActivityCode429Binding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + +class Code429Activity : AppCompatActivity() { + private lateinit var binding:ActivityCode429Binding + private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode429Binding.inflate(layoutInflater) + setContentView(binding.root) + } + + fun CheckToken(){ + if (enternetCheck.isOnline(this@Code429Activity)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this@Code429Activity) + CoroutineScope(Dispatchers.IO).launch { + val list = doctorApi.CheckToken("Bearer $Tokens") + runOnUiThread { + + + //Фиксируем полученные данные + val List = list.body() + val Nice = list.isSuccessful + val Code = list.code() + if(Code==500){ + val intetn = Intent(this@Code429Activity, Code500Activity::class.java) + finish() + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + + Log.i("clogon1231111","clogon1231111") + finish() + } + + } + } + else if (Code == 401) { + val intetn = Intent(this@Code429Activity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } else { + + val intetn = Intent(this, EnternetActivity::class.java) + finish() + startActivity(intetn) + } + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + + override fun onResume() { + super.onResume() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 15000) { + this@Code429Activity.runOnUiThread { + CheckToken() + } + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/CodeError/Code500Activity.kt b/app/src/main/java/com/example/doctor/CodeError/Code500Activity.kt new file mode 100644 index 0000000..d787358 --- /dev/null +++ b/app/src/main/java/com/example/doctor/CodeError/Code500Activity.kt @@ -0,0 +1,178 @@ +package com.example.doctor.CodeError + +import android.annotation.SuppressLint +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.CountDownTimer +import android.util.Log +import android.view.View +import android.widget.Toast +import androidx.core.content.ContentProviderCompat.requireContext +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.MainActivity +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.ActivityCode500Binding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + +class Code500Activity : AppCompatActivity() { + private lateinit var binding: ActivityCode500Binding + private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + var checkClose = false + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode500Binding.inflate(layoutInflater) + setContentView(binding.root) + + +// val fixedRateTimer = fixedRateTimer("hello-timer", +// false,0,5000) { +// +// } +// try { +// this@Code500Activity.runOnUiThread { +// CheckToken() +// } +// } +// finally { +// fixedRateTimer.cancel(); +// } +//ПОСТОЯННО ВЫЗЫВАЕТСЯ НУЖНО КАК-ТО ОТКЛЮЧАТЬ +// fixedRateTimer("timer", false, 0, 10000) { +// this@Code500Activity?.runOnUiThread { +// } +// } + + binding.apply { + + val timer = object: CountDownTimer(30000, 1000) { + override fun onTick(millisUntilFinished: Long) { + + } + + override fun onFinish() { + val intetn = Intent(this@Code500Activity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + timer.start() + + } + + } + + + fun CheckToken(){ + if (enternetCheck.isOnline(this@Code500Activity)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this@Code500Activity) + CoroutineScope(Dispatchers.IO).launch { + val list = doctorApi.CheckToken("Bearer $Tokens") + runOnUiThread { + + + //Фиксируем полученные данные + val List = list.body() + val Nice = list.isSuccessful + val Code = list.code() + if(Code==429){ + val intetn = Intent(this@Code500Activity, Code429Activity::class.java) + finish() + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + + Log.i("clogon1231111","clogon1231111") + finish() + } + + } + } + else if (Code == 401) { + val intetn = Intent(this@Code500Activity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(this, EnternetActivity::class.java) + finish() + startActivity(intetn) + } + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + + override fun onResume() { + super.onResume() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 15000) { + this@Code500Activity.runOnUiThread { + CheckToken() + } + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/DataModel.kt b/app/src/main/java/com/example/doctor/DataModel.kt new file mode 100644 index 0000000..b5b9afd --- /dev/null +++ b/app/src/main/java/com/example/doctor/DataModel.kt @@ -0,0 +1,30 @@ +package com.example.doctor + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +//Ослеживание за обновлением подробной продуктовой карточкой +open class DataModel: ViewModel() { + /*//Для отлеживания обновлений активити + val messageForActivity: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + }*/ + //Для отлеживания обновлений фрагммента 1 + val messageForFrag1: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + } + + val fragmentMenu: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + } + val patientList: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + } + val patientAppeal: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + } + /*//Для отлеживания обновлений фрагммента 2 + val messageForFrag2: MutableLiveData by lazy{//by lazy - чтобы каждый раз не создавался MutableLiveData(MutableLiveData()), а он один раз при загрузке создаться и дальше будет пользоваться уже созданным + MutableLiveData()//LiveData - означает что будет обновляться в нужынй момент, не постоянна, а в зависимоти от жизни активити + }*/ +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/DoctorViewModel.kt b/app/src/main/java/com/example/doctor/DoctorViewModel.kt index 334ae00..6ce7381 100644 --- a/app/src/main/java/com/example/doctor/DoctorViewModel.kt +++ b/app/src/main/java/com/example/doctor/DoctorViewModel.kt @@ -2,15 +2,17 @@ package com.example.doctor import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.example.doctor.Appeals.AppealsOldModel -import com.example.doctor.Appeals.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsNewModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldModel import com.example.doctor.Patients.Model.PatientAllModel +import com.example.doctor.Patients.Model.PatientIdModel import com.example.doctor.Patients.Model.PatientModel -import com.example.doctor.Patients.Reports.Edit.EditSportListNoModel -import com.example.doctor.Patients.Reports.Edit.EditSportListYesModel +import com.example.doctor.Patients.Reports.Courses.SportCoursModel import com.example.doctor.Patients.Reports.Edit.EditSportModel import com.example.doctor.Patients.Reports.QBAModel -import com.example.doctor.Patients.Reports.SportCoursModel +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorModel +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.CoursesDoctorCA +import com.example.doctor.Setting.Courses.Model.CoursesDoctorModel //import com.example.retrofit.model.Product @@ -20,16 +22,17 @@ class DoctorViewModel: ViewModel() { val token = MutableLiveData() //Пациенты + val patientId = MutableLiveData() val patientCurrent = MutableLiveData() val patientListList= MutableLiveData() - //Обращения новые + //Обращения необработанные val appealsNewCurrent = MutableLiveData() val appealsNewList= MutableLiveData>() - //Обращения все - val appealsAllCurrent = MutableLiveData() - val appealsAllList= MutableLiveData>() + //Обращения обработанные + val appealsOldCurrent = MutableLiveData() + val appealsOldList= MutableLiveData>() //val productList = MutableLiveData>() val patientOneCurrent = MutableLiveData() @@ -41,6 +44,9 @@ class DoctorViewModel: ViewModel() { //КУрсы val SportCoursCurrent = MutableLiveData() val SportCoursList= MutableLiveData>() + val SportCoursDoctorList= MutableLiveData>() + + val BtnSportCoursDoctorCurrent = MutableLiveData() //Редактирование занятий val EditSportCurrentYes = MutableLiveData() @@ -50,7 +56,38 @@ class DoctorViewModel: ViewModel() { val EditSportCurrentNO = MutableLiveData() val EditSportListNo= MutableLiveData>() + //Список пациентов + val PatientActiveCurrent = MutableLiveData() + val PatientActiveList= MutableLiveData>() + val PatientNotCurrent = MutableLiveData() + val PatientNotList= MutableLiveData>() + + //Список со всеми пациентами + val PatientAllModel= MutableLiveData>() //id пациента val id_patient = MutableLiveData() + + //Курсы созданный доктором + val CoursesDoctorCurrent = MutableLiveData() + val CoursesDoctorList= MutableLiveData>() + + + //Упражнения не входяшие в курс доктора + val EditCoursesDoctorAllCurrent = MutableLiveData() + val EditCoursesDoctorAllList= MutableLiveData>() + + //Упражнения входяшие в курс доктора + val EditCoursesDoctorYourCurrent = MutableLiveData() + val EditCoursesDoctorYourList= MutableLiveData>() + + val CoursesDoctorCA = MutableLiveData() + + + //Список пациентов для поисковой строки + val patientListSearch= MutableLiveData>() + + //Для передачи данных редактируемого курса + val CoursesCustomDoctor = MutableLiveData() + } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Enternet/EnternetActivity.kt b/app/src/main/java/com/example/doctor/Enternet/EnternetActivity.kt new file mode 100644 index 0000000..09674f4 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Enternet/EnternetActivity.kt @@ -0,0 +1,23 @@ +package com.example.doctor.Enternet + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import com.example.doctor.R +import com.example.doctor.databinding.ActivityEnternetBinding +import com.example.doctor.databinding.FragmentEnternetBinding + +class EnternetActivity : AppCompatActivity() { + private lateinit var binding: ActivityEnternetBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityEnternetBinding.inflate(layoutInflater) + setContentView(binding.root) + + supportFragmentManager.beginTransaction() + .replace(R.id.CLEnternet, EnternetFragment.newInstance()) + .commit() + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Enternet/EnternetCheck.kt b/app/src/main/java/com/example/doctor/Enternet/EnternetCheck.kt new file mode 100644 index 0000000..a2ec595 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Enternet/EnternetCheck.kt @@ -0,0 +1,41 @@ +package com.example.doctor.Enternet + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build + +class EnternetCheck() { + + //Проверка интернета + fun isOnline(context: Context): Boolean { + if (context == null) return false + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + if (capabilities != null) { + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> { + return true + } + } + } + } else { + val activeNetworkInfo = connectivityManager.activeNetworkInfo + if (activeNetworkInfo != null && activeNetworkInfo.isConnected) { + return true + } + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Enternet/EnternetFragment.kt b/app/src/main/java/com/example/doctor/Enternet/EnternetFragment.kt new file mode 100644 index 0000000..0062d72 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Enternet/EnternetFragment.kt @@ -0,0 +1,38 @@ +package com.example.doctor.Enternet + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.doctor.MainActivity +import com.example.doctor.databinding.FragmentEnternetBinding + + +class EnternetFragment : Fragment() { + private lateinit var binding: FragmentEnternetBinding + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentEnternetBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnEnternet.setOnClickListener{ + val intetn = Intent(requireContext(), MainActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + companion object { + + fun newInstance() = EnternetFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Home/HomeFragment.kt b/app/src/main/java/com/example/doctor/Home/HomeFragment.kt index e5c64dc..27c61c4 100644 --- a/app/src/main/java/com/example/doctor/Home/HomeFragment.kt +++ b/app/src/main/java/com/example/doctor/Home/HomeFragment.kt @@ -1,15 +1,45 @@ package com.example.doctor.Home +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi import com.example.doctor.databinding.FragmentHomeBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory class HomeFragment : Fragment() { private lateinit var binding: FragmentHomeBinding + private val dataModel: DataModel by activityViewModels()//Для передачи данных + + private var Token = "" + val prefDoctorClear= ClearPref() + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + private val modelDoctor: DoctorViewModel by activityViewModels() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -22,6 +52,87 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.CVPatinet.setOnClickListener { + dataModel.fragmentMenu.value = R.id.patient + } + + binding.CVAppeals.setOnClickListener { + dataModel.fragmentMenu.value = R.id.list_check + } + + CountPatientAndAppeals() + } + + //Получение данных для главной страницы + fun CountPatientAndAppeals() = with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listHomeView = doctorApi.CountPatientAndAppeals("Bearer $Tokens") + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listHomeView.body() + val Nice = listHomeView.isSuccessful + val Code = listHomeView.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + txtCountPatient.text = List?.patient.toString() + txtCountAppealsNew.text = List?.appeals_check.toString() + txtCountAppealsAll.text = List?.appeals_all.toString() + CLLoad.visibility = View.GONE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + } companion object { diff --git a/app/src/main/java/com/example/doctor/Home/HomeInfoModel.kt b/app/src/main/java/com/example/doctor/Home/HomeInfoModel.kt new file mode 100644 index 0000000..5e7fc1f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Home/HomeInfoModel.kt @@ -0,0 +1,8 @@ +package com.example.doctor.Home + +data class HomeInfoModel( + val patient: Int, + val appeals_check: Int, + val appeals_all: Int, +) + diff --git a/app/src/main/java/com/example/doctor/MainActivity.kt b/app/src/main/java/com/example/doctor/MainActivity.kt index d7e78b3..37fe284 100644 --- a/app/src/main/java/com/example/doctor/MainActivity.kt +++ b/app/src/main/java/com/example/doctor/MainActivity.kt @@ -1,15 +1,31 @@ package com.example.doctor import android.annotation.SuppressLint +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.SharedPreferences +import android.graphics.BitmapFactory +import android.graphics.Color +import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.widget.ArrayAdapter +import android.widget.RemoteViews import android.widget.Toast import androidx.appcompat.app.AlertDialog +import androidx.constraintlayout.widget.ConstraintSet.Constraint +import androidx.work.Constraints +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequest +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkManager +import androidx.work.WorkRequest import com.example.doctor.Auth.AuthActivity import com.example.doctor.Auth.AuthFragment import com.example.doctor.Auth.Model.AuthModel @@ -17,6 +33,7 @@ import com.example.doctor.Pref.ConclusionPref import com.example.doctor.Pref.SavePref import com.example.doctor.Retrofit.DoctorApi import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.Worker.MyWorker import com.example.doctor.databinding.ActivityMainBinding import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -26,32 +43,258 @@ import okhttp3.logging.HttpLoggingInterceptor import org.json.JSONObject import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit +import android.app.TaskStackBuilder +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.view.View +import androidx.activity.viewModels +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContentProviderCompat.requireContext +import androidx.test.core.app.ActivityScenario.launch +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Enternet.EnternetFragment +import kotlinx.coroutines.Job +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private lateinit var doctorApi: DoctorApi - + private lateinit var timer: Timer //Токен private var Token = "" val prefDoctorSave = SavePref() val prefDoctorConclusion = ConclusionPref() var backPressedTime: Long = 0 + + lateinit var notificationManager: NotificationManager + lateinit var notificationChannel: NotificationChannel + lateinit var builder: Notification.Builder + private val channelId = "i.apps.notifications" + private val description = "Test notification" + + + val CHANNEL_ID = "channelID" + val CHANNEL_NAME = "channelName" + val NOTIF_ID = 0 + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + private val modelDoctor: DoctorViewModel by viewModels()//Инициализировали класс + + @SuppressLint("RemoteViewLayout", "MissingPermission") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - initRetrofit() - MainAndAuth() } + + + //Получение необработанных сообщений + private fun getNewAppeals() { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorNew("Bearer $Tokens") + runOnUiThread { + + //Фиксируем полученные данные + val AppealsMes = listAppeals.body() + + //Если нету ошибок + if (AppealsMes != null) { + if (AppealsMes.appeals_new != null) { + modelDoctor.appealsNewList.value = AppealsMes.appeals_new + } + } + } + } + } else { +// finish() +// val intetn = Intent(this, EnternetActivity::class.java) +// startActivity(intetn) + } + } + + //Получение обработанных сообщений + private fun getOldAppeals() { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = doctorApi.GetAppealsDoctorOld("Bearer $Tokens") + runOnUiThread { + + //Фиксируем полученные данные + val AppealsMes = listAppeals.body() + + //Если нету ошибок + if (AppealsMes != null) { + if (AppealsMes.appeals_old != null) { + modelDoctor.appealsOldList.value = AppealsMes.appeals_old + } + } + } + } + } else { +// finish() +// val intetn = Intent(this, EnternetActivity::class.java) +// startActivity(intetn) + } + } + + //Получения списка пациентов для поиска + fun GetPatientListSearch() { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listPatientList = doctorApi.GetPatientAll("Bearer $Tokens") + + runOnUiThread { + //Фиксируем полученные данные + val patientList = listPatientList.body() + //Если нету ошибок + if (patientList != null) { + modelDoctor.patientListSearch.value = patientList.patient + } + } + + } + } else { +// finish() +// val intetn = Intent(this, EnternetActivity::class.java) +// startActivity(intetn) + } + } + + //Получения списка пациентов + fun GetPatientListYes() { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientAllActive("Bearer $Tokens") + runOnUiThread { + + //Фиксируем полученные данные + val patientList = listProduct.body() + + //Если нету ошибок + if (patientList != null) { + modelDoctor.PatientActiveList.value = patientList.patient + } + } + + } + } else { +// finish() +// val intetn = Intent(this, EnternetActivity::class.java) +// startActivity(intetn) + } + } + + //Получения списка пациентов + fun GetPatientListNo() { + + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientAllNotActive("Bearer $Tokens") + runOnUiThread { + + //Фиксируем полученные данные + val patientList = listProduct.body() + + //Если нету ошибок + if (patientList != null) { + modelDoctor.PatientNotList.value = patientList.patient + } + } + + } + + } else { +// finish() +// val intetn = Intent(this, EnternetActivity::class.java) +// startActivity(intetn) + } + } + +// private fun createNotifChannel() { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// val channel = NotificationChannel( +// CHANNEL_ID, +// CHANNEL_NAME, +// NotificationManager.IMPORTANCE_DEFAULT +// ).apply { +// lightColor = Color.BLUE +// enableLights(true) +// } +// val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager +// manager.createNotificationChannel(channel) +// } +// } + +// //Одинарный +// fun myOneTimeWork() { +// val constraints = Constraints.Builder() +// .setRequiredNetworkType(NetworkType.NOT_REQUIRED)//Тут мы указыаем что сработает при наличие интернета +// .setRequiresCharging(true) +// .build() +// +// //Ограничение +// val myWorkRequest: WorkRequest = +// OneTimeWorkRequest.Builder(MyWorker::class.java)//OneTimeWorkRequest - разовая +// .setConstraints(constraints) +// .build() +// +// WorkManager.getInstance(this@MainActivity).enqueue(myWorkRequest)//Отправка запроса +// } + +// //Повторяющийся +// fun myPriodicTimeWork() { +// val constraints = Constraints.Builder() +// .setRequiredNetworkType(NetworkType.NOT_REQUIRED)//Тут мы указыаем что сработает при наличие интернета +// .setRequiresCharging(true) +// .build() +// +// //Ограничение +// val myWorkRequest = PeriodicWorkRequest.Builder( +// MyWorker::class.java, +// 15, +// TimeUnit.MINUTES +// )//PeriodicWorkRequest - переодически, 15 - время интервала(минимальное 15 минут) +// .setConstraints(constraints) +// .addTag("my_id")//Уникальный индификатор для уведомления, для того чтобы можно было кпримеру обратиться и остановать данный менеджер +// .build() +// +// WorkManager.getInstance(this@MainActivity).enqueueUniquePeriodicWork( +// "my_id", +// ExistingPeriodicWorkPolicy.KEEP, +// myWorkRequest +// )//Отправка запроса +// } + + fun MainAndAuth() { - Token = prefDoctorConclusion.conclusionToken(this) + Token = prefDoctorConclusion.conclusionToken(this@MainActivity) //CheckTokenAuth(Token) if (Token == "") { Auth() @@ -61,31 +304,107 @@ class MainActivity : AppCompatActivity() { } fun Auth() { + binding.CLLoad.visibility = View.GONE supportFragmentManager.beginTransaction() .replace(R.id.CLMain, AuthFragment.newInstance()) .commit() } fun Main() { + binding.CLLoad.visibility = View.GONE fragment_inicializ() + +// fixedRateTimer("timer", false, 0, 10000) { +// this@MainActivity.runOnUiThread { +// getNewAppeals() +// getOldAppeals() +// GetPatientListSearch() +// GetPatientListYes() +// GetPatientListNo() +// } +// } } - @SuppressLint("SuspiciousIndentation") - private fun CheckTokenAuth(token: String) { - CoroutineScope(Dispatchers.IO).launch { - val response = doctorApi.CheckToken("Bearer $token") - runOnUiThread { - val checkToken = response.body() - val user1 = response.code() - Log.i("12213213213", user1.toString()) + @SuppressLint("MissingPermission") + private fun main() = with(binding) { - if (user1.toString() == "200") { - Main() - } else { - Auth() +// btn11.setOnClickListener { +// myOneTimeWork() +// } +// btn22.setOnClickListener { +// myPriodicTimeWork() +// } +// createNotifChannel() +// notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager +// val intent = Intent(this@MainActivity, MainActivity::class.java) +// val pendingIntent = TaskStackBuilder.create(this@MainActivity).run { +// addNextIntentWithParentStack(intent) +// getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) +// } +// +// val notif = NotificationCompat.Builder(this@MainActivity, CHANNEL_ID) +// .setContentTitle("Sample Title") +// .setContentText("This is sample body notif") +// .setSmallIcon(R.drawable.door) +// .setPriority(NotificationCompat.PRIORITY_HIGH) +// .setContentIntent(pendingIntent) +// .build() +// +// +// val notifManger = NotificationManagerCompat.from(this@MainActivity) +// button3.setOnClickListener { +// +// notifManger.notify(NOTIF_ID, notif) +// } +// +// + + } + + + private fun CheckTokenAuth(token: String) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + CoroutineScope(Dispatchers.IO).launch { + val response = doctorApi.CheckToken("Bearer $token") + runOnUiThread { + + + //Фиксируем полученные данные + val List = response.body() + val Nice = response.isSuccessful + val Code = response.code() + if(Code==429){ + val intetn = Intent(this@MainActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (Code.toString() == "200") { + Main() + } else { + Auth() + } + } + } + else if (Code == 500) { + val intetn = Intent(this@MainActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@MainActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } } } - + } else { + val intetn = Intent(this, EnternetActivity::class.java) + finish() + startActivity(intetn) } } @@ -93,6 +412,7 @@ class MainActivity : AppCompatActivity() { //Инициализируем Retrofit private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() interceptor.level = HttpLoggingInterceptor.Level.BODY @@ -102,7 +422,7 @@ class MainActivity : AppCompatActivity() { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -137,10 +457,28 @@ class MainActivity : AppCompatActivity() { // backPressedTime = System.currentTimeMillis() // } - override fun onResume() { - super.onResume() - - } +// override fun onResume() { +// super.onResume() +// checkForUpdates(true) +// } +// +// +// override fun onStop() { +// super.onStop() +// timer.cancel() +// timer.purge() +// } +// +// private fun checkForUpdates(daemonIsTrue: Boolean) { +// Token = prefDoctorConclusion.conclusionToken(this@MainActivity) +// timer = fixedRateTimer("default", daemonIsTrue, 0, 5000) { +// this@MainActivity?.runOnUiThread { +// +// CheckTokenAuth(Token) +// } +// } +// +//} } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/MainFragment.kt b/app/src/main/java/com/example/doctor/MainFragment.kt index 17bee90..aabd73e 100644 --- a/app/src/main/java/com/example/doctor/MainFragment.kt +++ b/app/src/main/java/com/example/doctor/MainFragment.kt @@ -2,11 +2,17 @@ package com.example.doctor import android.annotation.SuppressLint +import android.icu.text.SimpleDateFormat +import android.icu.util.Calendar import android.os.Bundle +import android.os.SystemClock import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Observer +//import androidx.navigation.fragment.findNavController import com.example.doctor.Appeals.AppealsFragment import com.example.doctor.Home.HomeFragment import com.example.doctor.Patients.PatientsListFragment @@ -14,20 +20,24 @@ import com.example.doctor.Pref.ConclusionPref import com.example.doctor.Pref.SavePref import com.example.doctor.Setting.SettingFragment import com.example.doctor.databinding.FragmentMainBinding +import java.util.Date class MainFragment : Fragment() { private lateinit var binding: FragmentMainBinding - + private val dataModel: DataModel by activityViewModels()//Для передачи данных val prefDoctorSave = SavePref() val prefDoctorConclusion = ConclusionPref() private var Token = "" + var sdf: SimpleDateFormat = SimpleDateFormat("EEEE") + var d: Date = Date() + var dayOfTheWeek: String = sdf.format(d) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - binding = FragmentMainBinding.inflate(layoutInflater,container,false) + binding = FragmentMainBinding.inflate(layoutInflater, container, false) return binding.root } @@ -36,7 +46,68 @@ class MainFragment : Fragment() { super.onViewCreated(view, savedInstanceState) //MainAndAuth() + dataModel.fragmentMenu.observe(viewLifecycleOwner, Observer { + binding.buttonNavigation.selectedItemId = it + }) + + addDate() + fragment_inicializ() + + + } + + private fun addDate() { + val calendar: Calendar = Calendar.getInstance() + val sdf: SimpleDateFormat = SimpleDateFormat("EEEE") + val d: Date = Date() + val DayOfTheWeek: String = sdf.format(d) + val Day = calendar.get(Calendar.DATE) + val Month = calendar.get(Calendar.MONTH).plus(1) + var day = Day.toString() + var month = "" + var date_of_the_week = "" + + when (Month) { + 1 -> month = "Январь" + 2 -> month = "Февраль" + 3 -> month = "Март" + 4 -> month = "Апрель" + 5 -> month = "Май" + 6 -> month = "Июнь" + 7 -> month = "Июль" + 8 -> month = "Август" + 9 -> month = "Сентябрь" + 10 -> month = "Октябрь" + 11 -> month = "Ноябрь" + 12 -> month = "Декабрь" + else -> { // обратите внимание на блок + month = "" + } + } + + when (dayOfTheWeek) { + "Monday" -> date_of_the_week = "Пн" + "Tuesday" -> date_of_the_week = "Вт" + "Wednesday" -> date_of_the_week = "Ср" + "Thursday" -> date_of_the_week = "Чт" + "Friday" -> date_of_the_week = "Пт" + "Saturday" -> date_of_the_week = "Сб" + "Sunday" -> date_of_the_week = "Вс" + "Понедельник" -> date_of_the_week = "Пн" + "Вторник" -> date_of_the_week = "Вт" + "Стреда" -> date_of_the_week = "Ср" + "Четверг" -> date_of_the_week = "Чт" + "Пятница" -> date_of_the_week = "Пт" + "Суббота" -> date_of_the_week = "Сб" + "Воскресенье" -> date_of_the_week = "Вс" + else -> { + date_of_the_week = "" + } + } + + System.out.println(calendar.get(Calendar.DATE)) + binding.txtDate.setText("${day}" + " " + "${month}") } // fun MainAndAuth(){ @@ -60,9 +131,9 @@ class MainFragment : Fragment() { // } - //Инициализация фрагментов fun fragment_inicializ() { + Token = prefDoctorConclusion.conclusionToken(requireContext()) //Вывод фрагмента на активити при первоначальной загрузке activity?.supportFragmentManager?.beginTransaction() @@ -71,29 +142,43 @@ class MainFragment : Fragment() { //Эран который будет выбран по умолчанию(кнопка которая будет прожата по умолчанию) - binding.buttonNavigation.selectedItemId = R.id.home//По умолчанию и так первая, но на всякий случай выберу еще програмным путем первую ячейку + binding.buttonNavigation.selectedItemId = + R.id.home//По умолчанию и так первая, но на всякий случай выберу еще програмным путем первую ячейку //Нажатие на bottom navigation binding.buttonNavigation.setOnItemSelectedListener { when (it.itemId) {//it.itemId - это id нажатого элемента R.id.home -> { - activity?.supportFragmentManager?.beginTransaction() - ?.replace(R.id.CLMainFragment, HomeFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем - } - R.id.patient -> { - activity?.supportFragmentManager?.beginTransaction() - ?.replace(R.id.CLMainFragment, PatientsListFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMainFragment, HomeFragment.newInstance()) + ?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + } } + R.id.patient -> { + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMainFragment, PatientsListFragment.newInstance()) + ?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + } + } R.id.list_check -> {//Если вы не авторизованный пользваотель то вам не будет доступен доступ к данном фрагменту - activity?.supportFragmentManager?.beginTransaction() - ?.replace(R.id.CLMainFragment, AppealsFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMainFragment, AppealsFragment.newInstance()) + ?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + } } + R.id.setting -> {//Если вы не авторизованный пользваотель то вам не будет доступен доступ к данном фрагменту - activity?.supportFragmentManager?.beginTransaction() - ?.replace(R.id.CLMainFragment, SettingFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMainFragment, SettingFragment.newInstance()) + ?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + } } } @@ -101,6 +186,19 @@ class MainFragment : Fragment() { } } + var mLastClickTime = 0L + fun isClickRecently(): Boolean { + if (SystemClock.elapsedRealtime() - mLastClickTime < 500) { + return true + } + mLastClickTime = SystemClock.elapsedRealtime() + return false + } + + + + + companion object { fun newInstance() = MainFragment() diff --git a/app/src/main/java/com/example/doctor/Patients/Adapter/PatientListAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Adapter/PatientListAdapter.kt index 5f2e15f..f611296 100644 --- a/app/src/main/java/com/example/doctor/Patients/Adapter/PatientListAdapter.kt +++ b/app/src/main/java/com/example/doctor/Patients/Adapter/PatientListAdapter.kt @@ -43,7 +43,7 @@ class PatientListAdapter(val listener_patient: Listener) : @SuppressLint("SuspiciousIndentation", "SetTextI18n") fun bind(item: PatientAllModel) = with(binding) {//Productitem - перпедаем данные itemTemp = item - txtNumberCurds.text = item.id.toString() + "." + txtNumberCurds.text = item.number.toString() + "." txtLoginPatient.text = item.login } diff --git a/app/src/main/java/com/example/doctor/Patients/Model/PatientAllModel.kt b/app/src/main/java/com/example/doctor/Patients/Model/PatientAllModel.kt index 65328f9..823d5cb 100644 --- a/app/src/main/java/com/example/doctor/Patients/Model/PatientAllModel.kt +++ b/app/src/main/java/com/example/doctor/Patients/Model/PatientAllModel.kt @@ -3,6 +3,7 @@ package com.example.doctor.Patients.Model import java.util.Date data class PatientAllModel( + val number: Int? = null, val id: Int? = null, val login: String? = null, val email: String? = null, diff --git a/app/src/main/java/com/example/doctor/Patients/Model/PatientIdModel.kt b/app/src/main/java/com/example/doctor/Patients/Model/PatientIdModel.kt new file mode 100644 index 0000000..f3d77a6 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Model/PatientIdModel.kt @@ -0,0 +1,9 @@ +package com.example.doctor.Patients.Model + +import java.util.Date + +data class PatientIdModel( + val id: Int + +) + diff --git a/app/src/main/java/com/example/doctor/Patients/PatientActivity.kt b/app/src/main/java/com/example/doctor/Patients/PatientActivity.kt new file mode 100644 index 0000000..e86ac5f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/PatientActivity.kt @@ -0,0 +1,421 @@ +package com.example.doctor.Patients + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.activity.viewModels +import androidx.core.content.ContentProviderCompat.requireContext +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.databinding.ActivityPatientBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + +class PatientActivity : AppCompatActivity() { + private lateinit var binding: ActivityPatientBinding + private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + private val modelDoctor: DoctorViewModel by viewModels()//Инициализировали класс + var idPatient = 0 + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityPatientBinding.inflate(layoutInflater) + setContentView(binding.root) + supportFragmentManager.beginTransaction().replace(R.id.CLPatientActivity, PatientFragment.newInstance()).commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + idPatient = prefDoctorConclusion.conclusionIdPatient(this) + + + } + + + //Получения списка анкет ДО и ПОСЛЕ для пациента + fun QBAPatientList(id:Int){ + if (enternetCheck.isOnline(this@PatientActivity)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this@PatientActivity) + CoroutineScope(Dispatchers.IO).launch { + val list = doctorApi.GetPatientBAQiestionar("Bearer $Tokens",id) + runOnUiThread { + + //Фиксируем полученные данные + val List = list.body() + val Nice = list.isSuccessful + val Code = list.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if(List?.questionnaire !=null){ + modelDoctor.qbaList.value = List.questionnaire + } + } + } + + //2 + GetPatientID(idPatient) + + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + + } + + } + } else { + finish() + val intetn = Intent(this, EnternetActivity::class.java) + startActivity(intetn) + } + + } + + private fun GetPatientID(idPatient: Int) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listPatient = doctorApi.GetPatientID("Bearer $Tokens", idPatient) + runOnUiThread { + + //Фиксируем полученные данные + val List = listPatient.body() + val Nice = listPatient.isSuccessful + val Code = listPatient.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.patientCurrent.value = List + + } + } + + //3 + GetCoursesAllSport(idPatient) + + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity,Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(this, EnternetActivity::class.java) + + finish() + startActivity(intetn) + } + + } + + //Вывод всех курсов + fun GetCoursesAllSport(idPatient: Int){ + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetCoursAllPatient("Bearer $Tokens",idPatient) + runOnUiThread { + + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursList.value = List.courses + + } + } + + //4 + GetCoursesYouSport(idPatient) + + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(this@PatientActivity, EnternetActivity::class.java) + + finish() + startActivity(intetn) + } + + } + + + //Получения списка курсов созданных доктором + fun GetCoursesYouSport(idPatient:Int) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetCoursesDoctorPatient("Bearer $Tokens",idPatient) + + runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursDoctorList.value = List.courses_doctor + + } + } + + //5 + GetCoursesSportYes(idPatient) + + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(this, EnternetActivity::class.java) + + finish() + startActivity(intetn) + } + + } + + //Получения списка пациентов + fun GetCoursesSportYes(id_patient:Int) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient) + runOnUiThread { + + + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.EditSportListYes.value = List.set_of_sports_exercises_yes + + } + } + //6 + GetCoursesSportNo(idPatient) + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(this, EnternetActivity::class.java) + + finish() + startActivity(intetn) + } + + } + //Получения списка пациентов + fun GetCoursesSportNo(id_patient:Int) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(this) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens",id_patient) + runOnUiThread { + + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + val intetn = Intent(this@PatientActivity, Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.EditSportListNo.value = List.set_of_sports_exercises_no + + } + } + } + else if (Code == 500) { + val intetn = Intent(this@PatientActivity, Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(this@PatientActivity, AuthActivity::class.java) + finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(this, EnternetActivity::class.java) + finish() + + startActivity(intetn) + } + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + override fun onResume() { + super.onResume() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 10000) { + this@PatientActivity?.runOnUiThread { + QBAPatientList(idPatient) + + } + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/PatientsListFragment.kt b/app/src/main/java/com/example/doctor/Patients/PatientsListFragment.kt index a7c044d..1c9934e 100644 --- a/app/src/main/java/com/example/doctor/Patients/PatientsListFragment.kt +++ b/app/src/main/java/com/example/doctor/Patients/PatientsListFragment.kt @@ -1,7 +1,5 @@ package com.example.doctor.Patients -//noinspection SuspiciousImport -import android.R import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -9,16 +7,38 @@ import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import androidx.fragment.app.activityViewModels -import androidx.recyclerview.widget.GridLayoutManager import com.example.doctor.DoctorViewModel -import com.example.doctor.Patients.Adapter.PatientListAdapter import com.example.doctor.Patients.Model.PatientAllModel -import com.example.doctor.Patients.Model.PatientModel import com.example.doctor.Patients.Reports.PatientFragment import com.example.doctor.Pref.ConclusionPref +import android.R +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.os.Handler +import android.util.Log +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.Observer +//import androidx.navigation.fragment.findNavController + +import com.example.doctor.Adapter.VpAdapterPatientList +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.MainActivity +import com.example.doctor.Patients.TabLayoutPatient.ActiveCoursesPatientFragment +import com.example.doctor.Patients.TabLayoutPatient.NotActiveCoursesPatientFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.SavePref import com.example.doctor.Retrofit.DoctorApi import com.example.doctor.databinding.FragmentPatientsListBinding import com.example.user.BottomSheetMenu.NoteBottomSheetMenu +import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -26,17 +46,37 @@ import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.util.Timer +import kotlin.concurrent.fixedRateTimer -class PatientsListFragment : Fragment(), PatientListAdapter.Listener { +class PatientsListFragment : Fragment(){ private lateinit var binding: FragmentPatientsListBinding - private val model: DoctorViewModel by activityViewModels() - lateinit var adapterPatient: PatientListAdapter + private val modelDoctor: DoctorViewModel by activityViewModels() + private val dataModel: DataModel by activityViewModels()//Для передачи данных private lateinit var doctorApi: DoctorApi + private lateinit var timer: Timer + + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + var viewListPAtient = true + var patientListSearch:List?=null + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + private val tList = listOf( + "Активные", + "Без курса", + ) + //Список с фрагментами для переключения + private val flist = listOf( + ActiveCoursesPatientFragment.newInstance(), + NotActiveCoursesPatientFragment.newInstance(), + ) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -47,54 +87,116 @@ class PatientsListFragment : Fragment(), PatientListAdapter.Listener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - initRcViewDay() - patientListCurrent() - GetPatientList() + //Чтобы срабатывала команда 1 раз + if(viewListPAtient){ + GetPatientList() + init() + + //Нажатие на кнопку для добавления пациента + binding.btnAddPatient.setOnClickListener { + val noteBottomSheetMenu = NoteBottomSheetMenu.newInstance() + noteBottomSheetMenu.show( + requireActivity().supportFragmentManager, + "Note Bottom Sheet Fragment" + ) + } - - -// //Swipe down -// binding.refreshLayout.setOnRefreshListener{ -// GetPatientList() -// binding.refreshLayout.isRefreshing = false -// } - - - //Нажатие на кнопку заказать заказ - binding.btnAddPatient.setOnClickListener { - val noteBottomSheetMenu = NoteBottomSheetMenu.newInstance() - noteBottomSheetMenu.show( - requireActivity().supportFragmentManager, - "Note Bottom Sheet Fragment" - ) + } + modelDoctor.patientListSearch.observe(viewLifecycleOwner){ + if(patientListSearch!=it){ + patientListSearch = it + addListSerchPatient(it) + } } } + //Функция подключения переключения + private fun init() = with(binding) { + val adapter = VpAdapterPatientList(activity as FragmentActivity, flist as List) + vpPatient.adapter = adapter + + //Переключения (связываем таблаяут(переключатель) с viewpager, чтобы переключать фрагменты) + TabLayoutMediator(tabLayoutPatient, vpPatient) { tab, pos -> + tab.text = + tList[pos]//tab - нажатая кнопка, pos - позиция кнопки, tList[pos] - передаем название по полученной позиции + }.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран + + //Изменения цвета в зависомости на каком из tabLayout вы находитесь + binding.tabLayoutPatient.setTabTextColors(getResources().getColor(com.example.doctor.R.color.black), + getResources().getColor(com.example.doctor.R.color.white)); + + + } + +// private fun viewPatient() { +// val viewPatient = prefDoctorConclusion.conclusionViewPatient(requireContext()) +// val idPatient = prefDoctorConclusion.conclusionIdPatient(requireContext()) +// Log.i("viewPatient1",viewPatient.toString()) +// Log.i("idPatient1",viewPatient.toString()) +// if(viewPatient ==1 && idPatient !=0){ +// GetPatientID(idPatient) +// prefDoctorClear.clearIdPatient(requireContext()) +// prefDoctorClear.clearViewPatient(requireContext()) +// Log.i("viewPatient2",viewPatient.toString()) +// Log.i("idPatient2",viewPatient.toString()) +// } +// } + //Получения списка пациентов fun GetPatientList() { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listProduct = doctorApi.GetPatientAll("Bearer $Tokens") - requireActivity().runOnUiThread { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listPatientList = doctorApi.GetPatientAll("Bearer $Tokens") - //Фиксируем полученные данные - val patientList = listProduct.body() + requireActivity().runOnUiThread { - //Если нету ошибок - if (patientList != null) { - adapterPatient.submitList(patientList.patient) - //model.patientListList.value = patientList.PatientList - addListSerchPatient(patientList.patient) + //Фиксируем полученные данные + val List = listPatientList.body() + val Nice = listPatientList.isSuccessful + val Code = listPatientList.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.patientListSearch.value = List?.patient + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } } - } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } + + + private fun addListSerchPatient(patient: List) { val listPatient = arrayListOf("") for(i in 0 .. patient.count()-1){ @@ -110,31 +212,31 @@ class PatientsListFragment : Fragment(), PatientListAdapter.Listener { val serpat = binding.searchPatient.text.toString() //Вывод фрагмента на активити при первоначальной загрузке - activity?.supportFragmentManager?.beginTransaction() - ?.replace(com.example.doctor.R.id.CLMainListPatient, PatientFragment.newInstance()) - ?.commit() + +// ///////// activity?.supportFragmentManager?.beginTransaction() +// ///////// ?.replace(com.example.doctor.R.id.CLMainPatient, PatientFragment.newInstance()) +// ///////////// ?.addToBackStack(null) +// /////////// ?.commit() - binding.CLMainListPatient2.visibility = View.GONE + + //binding.CLMainListPatient2.visibility = View.GONE //Ищем пациента по логину for(i in 0 ..patient.count()-1) { if(patient[i].login == serpat){ - model.patientCurrent.value = patient[i] + modelDoctor.patientCurrent.value = patient[i] + prefDoctorSave.saveIdPatient(requireContext(),patient[i].id!!) + prefDoctorSave.saveViewPatient(requireContext(),1) + val intetn = Intent(requireContext(), PatientActivity::class.java) + startActivity(intetn) } } } - } - //Вывод прогресса на один день - private fun patientListCurrent() = with(binding) { -// model.patientListCurrent.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment -// -// } - } //Инициализируем Retrofit private fun initRetrofit() { @@ -147,7 +249,7 @@ class PatientsListFragment : Fragment(), PatientListAdapter.Listener { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -156,27 +258,33 @@ class PatientsListFragment : Fragment(), PatientListAdapter.Listener { } - //Инициализация списка - private fun initRcViewDay() = with(binding) { - rcView.layoutManager = - GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию - adapterPatient = PatientListAdapter(this@PatientsListFragment) - rcView.adapter = adapterPatient - } companion object { fun newInstance() = PatientsListFragment() } - override fun onClickPatient(item: PatientAllModel) { - //Вывод фрагмента на активити при первоначальной загрузке - activity?.supportFragmentManager?.beginTransaction() - ?.replace(com.example.doctor.R.id.CLMainListPatient, PatientFragment.newInstance()) - ?.commit() - //binding.rcView.visibility = View.GONE - binding.CLMainListPatient2.visibility = View.GONE - model.patientCurrent.value = item + override fun onResume() { + super.onResume() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + private fun checkForUpdates(daemonIsTrue: Boolean) { + + timer = fixedRateTimer("default", daemonIsTrue, 0, 10000) { + activity?.runOnUiThread { + GetPatientList() + } + } } + + + } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesAllAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesAllAdapter.kt new file mode 100644 index 0000000..a11ed2f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesAllAdapter.kt @@ -0,0 +1,90 @@ +package com.example.doctor.Patients.Reports.Courses + +import android.annotation.SuppressLint +import android.graphics.Color +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.R +import com.example.doctor.databinding.ItemCardCoursesDoctorBinding +import com.example.doctor.databinding.ItemSportCourseBinding + + +class CoursesAllAdapter(val listener_courses: Listener) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_courses: Listener): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemCardCoursesDoctorBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: SportCoursModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + //timerButtonDoubleButton(itemView) + itemTemp?.let { it1 -> listener_courses.onClickSportCourses(it1) } + + } + } + + + @SuppressLint("SuspiciousIndentation") + fun bind(item: SportCoursModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumberCurds.text = item.number.toString() + "." + txtNameCoursesDoctor.text = item.name + if (item.visibility == 100000) { + CVCours.setCardBackgroundColor(Color.parseColor("#83da83")) + Log.i("11111111111","sasdasdasdasdasadsdasda") + } else { + CVCours.setCardBackgroundColor(Color.parseColor("#b6b6b6")) + Log.i("2222222222222","sasdasdasdasdasadsdasda") + } + } + } + + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_courses_doctor, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_courses)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickSportCourses(item: SportCoursModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesYouAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesYouAdapter.kt new file mode 100644 index 0000000..47df774 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/CoursesYouAdapter.kt @@ -0,0 +1,99 @@ +package com.example.doctor.Patients.Reports.Courses + +import android.annotation.SuppressLint +import android.graphics.Color +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView + +import com.example.doctor.R +import com.example.doctor.Setting.Courses.Model.CoursesDoctorModel +import com.example.doctor.databinding.ItemCardCoursesDoctorBinding + + +class CoursesYouAdapter(val listener: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemCardCoursesDoctorBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: SportCoursModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it1 -> listener.onClickCourses(it1) } + + } + } + + @SuppressLint("SuspiciousIndentation", "SetTextI18n") + fun bind(item: SportCoursModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumberCurds.text = item.number.toString() + "." + txtNameCoursesDoctor.text = item.name + if (item.visibility == 100000) { + CVCours.setCardBackgroundColor(Color.parseColor("#83da83")) + Log.i("11111111111","sasdasdasdasdasadsdasda") + } else { + CVCours.setCardBackgroundColor(Color.parseColor("#b6b6b6")) + Log.i("2222222222222","sasdasdasdasdasadsdasda") + } + } + + + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_card_courses_doctor, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: SportCoursModel, + newItem: SportCoursModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: SportCoursModel, + newItem: SportCoursModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickCourses(item: SportCoursModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursDoctorListModel.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursDoctorListModel.kt new file mode 100644 index 0000000..b22c6af --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursDoctorListModel.kt @@ -0,0 +1,6 @@ +package com.example.doctor.Patients.Reports.Courses + +data class SportCoursDoctorListModel( + val courses_doctor: List + ) + diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/SportCoursListModel.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursListModel.kt similarity index 60% rename from app/src/main/java/com/example/doctor/Patients/Reports/SportCoursListModel.kt rename to app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursListModel.kt index 6e1c7c3..15a4de1 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/SportCoursListModel.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursListModel.kt @@ -1,4 +1,4 @@ -package com.example.doctor.Patients.Reports +package com.example.doctor.Patients.Reports.Courses data class SportCoursListModel( val courses: List diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/SportCoursModel.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursModel.kt similarity index 70% rename from app/src/main/java/com/example/doctor/Patients/Reports/SportCoursModel.kt rename to app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursModel.kt index 3f5c927..3bd8b3c 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/SportCoursModel.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/SportCoursModel.kt @@ -1,11 +1,11 @@ -package com.example.doctor.Patients.Reports +package com.example.doctor.Patients.Reports.Courses data class SportCoursModel( + val number: Int, val id: Int, val name: String, val description: String, val visibility: Int, val created_at: String, val updated_at: String, - ) - +) diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesAllFragment.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesAllFragment.kt new file mode 100644 index 0000000..2a99427 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesAllFragment.kt @@ -0,0 +1,204 @@ +package com.example.doctor.Patients.Reports.Courses.TabLayout + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Reports.Courses.CoursesAllAdapter +import com.example.doctor.Patients.Reports.Courses.SportCoursModel +import com.example.doctor.Patients.Reports.CoursesListAdapter +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentCoursesAllBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class CoursesAllFragment : Fragment(),CoursesAllAdapter.Listener { + private lateinit var binding: FragmentCoursesAllBinding + private val modelDoctor: DoctorViewModel by activityViewModels() + lateinit var adapterCours: CoursesAllAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + var sportCourses:List?=null + var id: Int? = null + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCoursesAllBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcViewCours() + modelDoctor.id_patient.observe(viewLifecycleOwner){ + id = it + GetAllCoursesSport() + } + + modelDoctor.SportCoursList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(sportCourses != it){ + sportCourses = it + adapterCours.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + binding.txtNull.visibility = View.GONE + } + } + } + + //Вывод всех курсов + fun GetAllCoursesSport(){ + if (enternetCheck.isOnline(requireContext())) { + binding.txtNull.visibility = View.VISIBLE + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetCoursAllPatient("Bearer $Tokens",id!!) + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursList.value = List.courses + binding.txtNull.visibility = View.GONE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + //Инициализация списка + private fun initRcViewCours() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterCours = CoursesAllAdapter(this@CoursesAllFragment) + rcView.adapter = adapterCours + } + + companion object { + fun newInstance() = CoursesAllFragment() + } + + override fun onClickSportCourses(item: SportCoursModel) { + AddSportPatient(id!!,item.id,14) + GetAllCoursesSport() + } + + fun AddSportPatient(id_patient:Int,id_course:Int,all_day:Int){ + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val updatePassword= doctorApi.AddSportPatient("Bearer $Tokens",id_patient,id_course,all_day) + requireActivity().runOnUiThread { + //Фиксируем полученные данные + val List = updatePassword.body() + val Nice = updatePassword.isSuccessful + val Code = updatePassword.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetAllCoursesSport() + modelDoctor.BtnSportCoursDoctorCurrent.value = 2 + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesYouFragment.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesYouFragment.kt new file mode 100644 index 0000000..f955a65 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Courses/TabLayout/CoursesYouFragment.kt @@ -0,0 +1,208 @@ +package com.example.doctor.Patients.Reports.Courses.TabLayout + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Reports.Courses.CoursesYouAdapter +import com.example.doctor.Patients.Reports.Courses.SportCoursModel +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.Model.CoursesDoctorModel +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentCoursesYouBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class CoursesYouFragment : Fragment(),CoursesYouAdapter.Listener { + private lateinit var binding:FragmentCoursesYouBinding + private val modelDoctor: DoctorViewModel by activityViewModels() + lateinit var adapterCours: CoursesYouAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + var sportCoursesDoctor:List?=null + var id: Int? = null + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCoursesYouBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcViewCours() + + modelDoctor.id_patient.observe(viewLifecycleOwner){ + id = it + GetCoursesDoctor() + } + + modelDoctor.SportCoursDoctorList.observe(viewLifecycleOwner){ + if(sportCoursesDoctor!=it){ + sportCoursesDoctor = it + adapterCours.submitList(it) + binding.txtNull.visibility = View.GONE + } + } + } + + //Получения списка курсов созданных доктором + fun GetCoursesDoctor() { + if (enternetCheck.isOnline(requireContext())) { + binding.txtNull.visibility = View.VISIBLE + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetCoursesDoctorPatient("Bearer $Tokens",id!!) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursDoctorList.value = List.courses_doctor + binding.txtNull.visibility = View.GONE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + //Инициализация списка + private fun initRcViewCours() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterCours = CoursesYouAdapter(this@CoursesYouFragment) + rcView.adapter = adapterCours + } + + companion object { + fun newInstance() = CoursesYouFragment() + } + + + + override fun onClickCourses(item: SportCoursModel) { + AddSportPatient(id!!,item.id,14) + GetCoursesDoctor() + } + + fun AddSportPatient(id_patient:Int,id_course:Int,all_day:Int){ + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val updatePassword= doctorApi.AddSportPatient("Bearer $Tokens",id_patient,id_course,all_day) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = updatePassword.body() + val Nice = updatePassword.isSuccessful + val Code = updatePassword.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetCoursesDoctor() + modelDoctor.BtnSportCoursDoctorCurrent.value = 2 + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/CoursesAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/CoursesAdapter.kt deleted file mode 100644 index 98d641c..0000000 --- a/app/src/main/java/com/example/doctor/Patients/Reports/CoursesAdapter.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.example.doctor.Patients.Reports - -import android.annotation.SuppressLint -import android.graphics.Color -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import com.example.doctor.Patients.Reports.Edit.EditSportModel -import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter -import com.example.doctor.R -import com.example.doctor.databinding.ItemQbaBinding -import com.example.doctor.databinding.ItemSportCourseBinding - - -class CoursesAdapter(val listener_cours: CoursesAdapter.Listener) : ListAdapter(Comparator()) { - class Holder(view: View,val listener_cours: CoursesAdapter.Listener) : - RecyclerView.ViewHolder(view) { - - val binding = ItemSportCourseBinding.bind(view) - - var itemTemp: SportCoursModel? = - null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия - - //init - дает возможность внутри адаптера обращаться к элементам экрана - init { - itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка - itemTemp?.let { it1 -> listener_cours.onClickCoursAdd(it1) } - } - } - - @SuppressLint("SuspiciousIndentation") - fun bind(item: SportCoursModel) = with(binding) { - txtCoursesSport.text = item.name - if(item.visibility == 1){ - CVCours.setCardBackgroundColor(Color.parseColor("#83da83")) - } - else{ - CVCours.setCardBackgroundColor(Color.parseColor("#b6b6b6")) - } - - } - } - - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { - val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sport_course, parent, false) - return Holder(view,listener_cours) - } - - override fun onBindViewHolder(holder: Holder, position: Int) { - val view = holder.bind(getItem(position)) - } - - class Comparator : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean { - return oldItem == newItem - } - } - - //Интерфейс нажатия на кнопку удалить товар из корзины - interface Listener { - fun onClickCoursAdd(item: SportCoursModel) - } - -} - - - - diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/CoursesListAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/CoursesListAdapter.kt new file mode 100644 index 0000000..3544801 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/Reports/CoursesListAdapter.kt @@ -0,0 +1,90 @@ +package com.example.doctor.Patients.Reports + +import android.annotation.SuppressLint +import android.graphics.Color +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.Patients.Reports.Courses.SportCoursModel +import com.example.doctor.R +import com.example.doctor.databinding.ItemSportCourseBinding + + +class CoursesListAdapter(val listener_courses: Listener) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_courses: Listener): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemSportCourseBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: SportCoursModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + binding.CardViewCourses.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + //timerButtonDoubleButton(itemView) + itemTemp?.let { it1 -> listener_courses.onClickSportCourses(it1) } + + } + } + + + @SuppressLint("SuspiciousIndentation") + fun bind(item: SportCoursModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtCoursesSport.text = item.name + if (item.visibility == 1) { + CVCours.setCardBackgroundColor(Color.parseColor("#83da83")) + Log.i("11111111111","sasdasdasdasdasadsdasda") + } else { + CVCours.setCardBackgroundColor(Color.parseColor("#b6b6b6")) + Log.i("2222222222222","sasdasdasdasdasadsdasda") + } + Log.i("ssadsdasda","sasdasdasdasdasadsdasda") + } + } + + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sport_course, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_courses)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickSportCourses(item: SportCoursModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/EditSportNoAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/EditSportNoAdapter.kt index 77d1744..6973b59 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/EditSportNoAdapter.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/EditSportNoAdapter.kt @@ -30,7 +30,7 @@ class EditSportNoAdapter(val listener_sport: Listener) : //init - дает возможность внутри адаптера обращаться к элементам экрана init { - itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + binding.btnYeyNo.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка itemTemp?.let { it1 -> listener_sport.onClickAppeals(it1) } } } diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportNoFragment.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportNoFragment.kt index d1dcadb..9086db8 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportNoFragment.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportNoFragment.kt @@ -1,5 +1,6 @@ package com.example.doctor.Patients.Reports.Edit.TabLayout +import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -8,7 +9,12 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck import com.example.doctor.Patients.Reports.Edit.EditSportYesAdapter import com.example.doctor.Patients.Reports.Edit.EditSportModel import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter @@ -33,8 +39,11 @@ class EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener { private val model: DoctorViewModel by activityViewModels() var id_patient = 0; + var editNo:List?=null + //Класс проверки интеренета + val enternetCheck = EnternetCheck() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -47,12 +56,29 @@ class EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener { super.onViewCreated(view, savedInstanceState) initRcViewDay() model.EditSportListNo.observe(viewLifecycleOwner){ - adapterNo.submitList(it) + if(it!=null){ + if(editNo!=it){ + editNo = it + adapterNo.submitList(it) + binding.txtNo.visibility = View.GONE + } + } + else{ + binding.txtNo.visibility = View.VISIBLE + } + } model.id_patient.observe(viewLifecycleOwner) {id-> id_patient = id.toInt() GetCoursesSportNo(id_patient) } + + + btnClick() + } + + private fun btnClick()=with(binding) { + CLLoad.setOnClickListener { } } @@ -75,7 +101,7 @@ class EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -86,77 +112,196 @@ class EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener { //Получения списка пациентов - fun GetCoursesSportYes(id_patient:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient) - requireActivity().runOnUiThread { + fun GetCoursesSportYes(id_patient:Int)= with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val sportEditList = sportEdit.body() + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE - //Если нету ошибок - if (sportEditList != null) { - model.EditSportListYes.value = sportEditList.set_of_sports_exercises_yes - //adapterYes.submitList(sportEditList.set_of_sports_exercises_yes) - } - } + val intetn = Intent(requireContext(), Code429Activity::class.java) - } - } - //Получения списка пациентов - fun GetCoursesSportNo(id_patient:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens", id_patient) - requireActivity().runOnUiThread { - - //Фиксируем полученные данные - val sportEditList = sportEdit.body() - - //Если нету ошибок - if (sportEditList != null) { - model.EditSportListNo.value = sportEditList.set_of_sports_exercises_no - //adapterNo.submitList(sportEditList.set_of_sports_exercises_no) - binding.txtNo.visibility = View.GONE - } - else{ - binding.txtNo.visibility = View.VISIBLE - - } - } - - } - } - - - //Получения списка пациентов - fun UpdateBlockSportTasksNo(id:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val NoEdit = doctorApi.UpdateBlockSportTasksNo("Bearer $Tokens", id) - requireActivity().runOnUiThread { - - //Фиксируем полученные данные - val sportNoList= NoEdit.body() - - //Если нету ошибок - if (sportNoList != null) { - Toast(requireContext()).showCustomInfoToast(sportNoList.message, requireActivity()) - GetCoursesSportYes(id_patient) - GetCoursesSportNo(id_patient) - - } - else{ - if (sportNoList != null) { - Toast(requireContext()).showCustomInfoToast(sportNoList.message, requireActivity()) + startActivity(intetn) } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + model.EditSportListYes.value = List.set_of_sports_exercises_yes + + } + + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + + + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Получения списка пациентов + fun GetCoursesSportNo(id_patient:Int)= with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens", id_patient) + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE + + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + model.EditSportListNo.value = List.set_of_sports_exercises_no + binding.txtNo.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + } + else{ + binding.txtNo.visibility = View.VISIBLE + binding.CLLoad.visibility = View.GONE + } + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + //Удаление упражнения из блока + fun UpdateBlockSportTasksNo(id:Int)= with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val NoEdit = doctorApi.UpdateBlockSportTasksNo("Bearer $Tokens", id) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = NoEdit.body() + val Nice = NoEdit.isSuccessful + val Code = NoEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE + + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetCoursesSportYes(id_patient) + GetCoursesSportNo(id_patient) + + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + CLLoad.visibility = View.GONE + } + CLLoad.visibility = View.GONE + } + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + } } + + + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } @@ -165,7 +310,7 @@ class EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener { } override fun onClickAppeals(item: EditSportModel) { - + binding.CLLoad.visibility = View.VISIBLE UpdateBlockSportTasksNo(item.id) } diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportYesFragment.kt b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportYesFragment.kt index 356ff6c..12f44bb 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportYesFragment.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/Edit/TabLayout/EditSportYesFragment.kt @@ -1,5 +1,6 @@ package com.example.doctor.Patients.Reports.Edit.TabLayout +import android.content.Intent import android.os.Bundle import android.util.Log import androidx.fragment.app.Fragment @@ -9,7 +10,12 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck import com.example.doctor.Patients.Reports.Edit.EditSportYesAdapter import com.example.doctor.Patients.Reports.Edit.EditSportModel import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter @@ -33,7 +39,10 @@ class EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener { val prefDoctorConclusion = ConclusionPref() private val model: DoctorViewModel by activityViewModels() var id_patient = 0; + var editYes:List?=null + //Класс проверки интеренета + val enternetCheck = EnternetCheck() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -56,8 +65,24 @@ class EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener { } model.EditSportListYes.observe(viewLifecycleOwner){ - adapterYes.submitList(it) + if(it!=null){ + if(editYes!=it){ + editYes=it + adapterYes.submitList(it) + binding.txtYes.visibility = View.GONE + } + } + else{ + binding.txtYes.visibility = View.GONE + } + + } + btnClick() + } + + private fun btnClick()=with(binding) { + CLLoad.setOnClickListener { } } @@ -82,7 +107,7 @@ class EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -92,73 +117,198 @@ class EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener { } //Получения списка пациентов - fun GetCoursesSportYes(id_patient:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient) - requireActivity().runOnUiThread { + fun GetCoursesSportYes(id_patient:Int)=with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val sportEditList = sportEdit.body() + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE - //Если нету ошибок - if (sportEditList != null) { - model.EditSportListYes.value = sportEditList.set_of_sports_exercises_yes - binding.txtYes.visibility = View.GONE - } - else{ - binding.txtYes.visibility = View.VISIBLE - } - } + val intetn = Intent(requireContext(), Code429Activity::class.java) - } - } - //Получения списка пациентов - fun GetCoursesSportNo(id_patient:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens",id_patient) - requireActivity().runOnUiThread { - - //Фиксируем полученные данные - val sportEditList = sportEdit.body() - - //Если нету ошибок - if (sportEditList != null) { - model.EditSportListNo.value = sportEditList.set_of_sports_exercises_no - //adapterNo.submitList(sportEditList.set_of_sports_exercises_no) - } - } - - } - } - - - //Получения списка пациентов - fun UpdateBlockSportTasksYes(id_pateint:Int,id_sports_tasks:Int) { - initRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val sportEdit = doctorApi.UpdateBlockSportTasksYes("Bearer $Tokens", id_pateint,id_sports_tasks) - requireActivity().runOnUiThread { - - //Фиксируем полученные данные - val sportEditList = sportEdit.body() - - //Если нету ошибок - if (sportEditList != null) { - Toast(requireContext()).showCustomInfoToast(sportEditList.message, requireActivity()) - GetCoursesSportYes(id_patient) - GetCoursesSportNo(id_patient) - } - else{ - if (sportEditList != null) { - Toast(requireContext()).showCustomInfoToast(sportEditList.message, requireActivity()) + startActivity(intetn) } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + model.EditSportListYes.value = List.set_of_sports_exercises_yes + binding.txtYes.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + } + else{ + model.EditSportListYes.value = null + + binding.txtYes.visibility = View.VISIBLE + binding.rcViewEditSportYes.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + } + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + + //Фиксируем полученные данные + val sportEditList = sportEdit.body() + + //Если нету ошибок + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Получения списка пациентов + fun GetCoursesSportNo(id_patient:Int)=with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens",id_patient) + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE + + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + model.EditSportListNo.value = List.set_of_sports_exercises_no + } + CLLoad.visibility = View.GONE + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + //Отключение упражнения + fun UpdateBlockSportTasksYes(id_pateint:Int,id_sports_tasks:Int)=with(binding) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportEdit = doctorApi.UpdateBlockSportTasksYes("Bearer $Tokens", id_pateint,id_sports_tasks) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = sportEdit.body() + val Nice = sportEdit.isSuccessful + val Code = sportEdit.code() + if(Code==429){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200){ + //Если нету ошибок + if(Nice){ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetCoursesSportYes(id_patient) + GetCoursesSportNo(id_patient) + + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + CLLoad.visibility = View.GONE + } + CLLoad.visibility = View.GONE + } + } + else{ + CLLoad.visibility = View.GONE + } + } + else if(Code==500){ + CLLoad.visibility = View.GONE + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + else{ + CLLoad.visibility = View.GONE + } + } } + + + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } } @@ -168,6 +318,7 @@ class EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener { } override fun onClickAppeals(item: EditSportModel) { + binding.CLLoad.visibility = View.VISIBLE UpdateBlockSportTasksYes(id_patient, item.id) } diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/PatientFragment.kt b/app/src/main/java/com/example/doctor/Patients/Reports/PatientFragment.kt index ad66fb0..74a74ca 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/PatientFragment.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/PatientFragment.kt @@ -2,6 +2,7 @@ package com.example.doctor.Patients.Reports import android.graphics.Color import android.os.Bundle +import android.transition.TransitionInflater import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -16,10 +17,29 @@ import com.example.doctor.DoctorViewModel import com.example.doctor.Patients.PatientsListFragment import com.example.doctor.Patients.Reports.Edit.EditSportFragment import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.R as R_D +import android.R +import android.content.Intent +import androidx.fragment.app.FragmentActivity +import com.example.doctor.Adapter.VpAdapter +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Model.PatientAllModel +import com.example.doctor.Patients.Reports.Courses.TabLayout.CoursesAllFragment +import com.example.doctor.Patients.Reports.Courses.TabLayout.CoursesYouFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.SavePref import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.AllSportCoursesDoctorFragment +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.YourSportCoursesDoctorFragment import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.Toast.showCustomNiceToast import com.example.doctor.databinding.FragmentPatientsBinding import com.example.doctor.databinding.ItemQuestionnaireAfterBinding +import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -30,18 +50,42 @@ import retrofit2.converter.gson.GsonConverterFactory import java.time.LocalDate -class PatientFragment : Fragment(),CoursesAdapter.Listener { +class PatientFragment : Fragment() { private lateinit var binding: FragmentPatientsBinding - private val model: DoctorViewModel by activityViewModels() + private val modelDoctor: DoctorViewModel by activityViewModels() lateinit var adapter: QBBAdapter - lateinit var adapterCours: CoursesAdapter + lateinit var adapterCours: CoursesListAdapter private lateinit var doctorApi: DoctorApi val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() var id: Int? = null var block = "" var pause = "" var id_sport = "" + var btnSC = 0; + + var idPatient = 0; + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + //Для 10 сек обновления + var qba:List?=null + var patientAll:PatientAllModel?=null + + private val tList = listOf( + "Все", + "Ваши", + ) + + //Список с фрагментами для переключения + private val flist = listOf( + CoursesAllFragment.newInstance(), + CoursesYouFragment.newInstance(), + ) + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -54,100 +98,205 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { super.onViewCreated(view, savedInstanceState) initRcViewDay() - initRcViewCours() - - model.qbaList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment - adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + init() + modelDoctor.qbaList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(qba != it){ + qba = it + adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + // binding.txtNullQBA.visibility = View.GONE + } } - model.SportCoursList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment - adapterCours.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + idPatient = prefDoctorConclusion.conclusionIdPatient(requireContext()) + + modelDoctor.BtnSportCoursDoctorCurrent.observe(viewLifecycleOwner){ + if(it == 1){ + binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767")) + } + else if(it == 2){ + binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#A9D867")) + } + else{ + binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767")) + } } + + val inflater = TransitionInflater.from(requireContext()) + enterTransition = inflater.inflateTransition(R_D.transition.slide_right) + binding.btnExit.setOnClickListener { - //Вывод фрагмента на активити при первоначальной загрузке - activity?.supportFragmentManager?.beginTransaction() - ?.replace( - com.example.doctor.R.id.CLMainFragment, - PatientsListFragment.newInstance() - ) - ?.commit() + exitTransition = inflater.inflateTransition(R_D.transition.slide_right) + + activity?.finish() } popMenu() - model.patientCurrent.observe(viewLifecycleOwner) { - binding.txtLogin.text = it.login - id = it.id - model.id_patient.value = id - block = it.block.toString() - pause = it.pause.toString() - id_sport = it.id_sport_patient.toString() - //Проверка даты, так как если дата уже прошла, то должно выводится что блока нету - if(block == "null"){ - block(block) - } - else{ - if(LocalDate.parse(block) + tab.text = + tList[pos]//tab - нажатая кнопка, pos - позиция кнопки, tList[pos] - передаем название по полученной позиции + }.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран + + //Изменения цвета в зависомости на каком из tabLayout вы находитесь + binding.tabLayoutCourses.setTabTextColors( + getResources().getColor(com.example.doctor.R.color.black), + getResources().getColor(com.example.doctor.R.color.white) + ); } - private fun GetPatientID() { - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listPatient = doctorApi.GetPatientID("Bearer $Tokens") - requireActivity().runOnUiThread { - - //Фиксируем полученные данные - val patientId = listPatient.body() - - //Если нету ошибок - if (patientId != null) { - model.patientCurrent.value = patientId - } - } + private fun viewPatient() { + val viewPatient = prefDoctorConclusion.conclusionViewPatient(requireContext()) + val idPatient = 23412 + Log.i("viewPatient1",viewPatient.toString()) + Log.i("idPatient1",viewPatient.toString()) + if(viewPatient ==1 && idPatient !=0 && idPatient !=null){ + GetPatientID(idPatient) + prefDoctorClear.clearIdPatient(requireContext()) + prefDoctorClear.clearViewPatient(requireContext()) + Log.i("viewPatient2",viewPatient.toString()) + Log.i("idPatient2",viewPatient.toString()) } } + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + private fun GetPatientID(idPatient: Int) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listPatient = doctorApi.GetPatientID("Bearer $Tokens", idPatient) + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listPatient.body() + val Nice = listPatient.isSuccessful + val Code = listPatient.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.patientCurrent.value = List + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + private fun popMenu() { //Созданиеменю val popMenu = PopupMenu( @@ -182,35 +331,161 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { //Получения списка анкет ДО и ПОСЛЕ для пациента fun ClearSportPaient(){ - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listcsp = doctorApi.ClearPatientSport("Bearer $Tokens",id!!) - requireActivity().runOnUiThread { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listcsp = doctorApi.ClearPatientSport("Bearer $Tokens",id!!) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val csp = listcsp.body() - //Если нету ошибок - if (csp != null) { - id_sport = "null" - binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767")) - Toast(requireContext()).showCustomInfoToast(csp.message, requireActivity()) - } - else{ - Toast(requireContext()).showCustomInfoToast("${csp?.message}", requireActivity()) + //Фиксируем полученные данные + val List = listcsp.body() + val Nice = listcsp.isSuccessful + val Code = listcsp.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + GetAllCoursesSport() + GetCoursesDoctor() + modelDoctor.BtnSportCoursDoctorCurrent.value = 1 + + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + else{ + Toast(requireContext()).showCustomInfoToast("${List?.message}", requireActivity()) + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } } } - + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } - private fun clearSportPatient(id_sport:String) { - if (id_sport == "null") { - binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767")) + //Получения списка курсов созданных доктором + fun GetCoursesDoctor() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetCoursesDoctorPatient("Bearer $Tokens",id!!) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursDoctorList.value = List.courses_doctor + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } } else { - binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#A9D867")) + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Вывод всех курсов + fun GetAllCoursesSport(){ + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetCoursAllPatient("Bearer $Tokens",id!!) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.SportCoursList.value = List.courses + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + private fun btnClearSportPatient(id_sport:String) { + if (id_sport == "null") { + modelDoctor.BtnSportCoursDoctorCurrent.value = 1 + } else { + modelDoctor.BtnSportCoursDoctorCurrent.value = 2 } binding.btnClearSportPatient.setOnClickListener { @@ -220,25 +495,53 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { //Получения списка анкет ДО и ПОСЛЕ для пациента fun QBAPatientList()=with(binding){ - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listProduct = doctorApi.GetPatientBAQiestionar("Bearer $Tokens",id!!) - requireActivity().runOnUiThread { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientBAQiestionar("Bearer $Tokens",id!!) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val qbapatientList = listProduct.body() - //Если нету ошибок - if (qbapatientList != null) { - if(qbapatientList.questionnaire !=null){ - txtNullQBA.visibility = View.GONE - model.qbaList.value = qbapatientList.questionnaire + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if(List.questionnaire !=null){ + txtNullQBA.visibility = View.GONE + modelDoctor.qbaList.value = List.questionnaire + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) } } - } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } @@ -267,156 +570,304 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { //Блокировка пациента fun UpdateBlockPatient(){ - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listProduct = doctorApi.UpdateBlockAccountPatient("Bearer $Tokens", id!!) - requireActivity().runOnUiThread { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.UpdateBlockAccountPatient("Bearer $Tokens", id!!) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val patientList = listProduct.body() - //Если нету ошибок - if (patientList != null) { - if (block == "null") { - block = "true" - binding.CVBlock.setCardBackgroundColor(Color.parseColor("#D86767")) - Toast(requireContext()).showCustomInfoToast("Блок установлен", requireActivity()) - } else { - block = "null" - binding.CVBlock.setCardBackgroundColor(Color.parseColor("#A9D867")) - Toast(requireContext()).showCustomInfoToast("Блок убран", requireActivity()) + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if (block == "null") { + block = "true" + binding.CVBlock.setCardBackgroundColor(Color.parseColor("#D86767")) + Toast(requireContext()).showCustomInfoToast("Блок установлен", requireActivity()) + } else { + block = "null" + binding.CVBlock.setCardBackgroundColor(Color.parseColor("#A9D867")) + Toast(requireContext()).showCustomInfoToast("Блок убран", requireActivity()) + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) } } - } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } //Блокировка пациента fun UpdatePausePatient(){ - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listProduct = doctorApi.UpdatePauseAccountPatient("Bearer $Tokens", id!!) - requireActivity().runOnUiThread { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.UpdatePauseAccountPatient("Bearer $Tokens", id!!) + requireActivity().runOnUiThread { - //Фиксируем полученные данные - val patientList = listProduct.body() - //Если нету ошибок - if (patientList != null) { - if (pause == "null") { - pause = "true" - binding.CVPause.setCardBackgroundColor(Color.parseColor("#D86767")) - Toast(requireContext()).showCustomInfoToast("Пауза установлен", requireActivity()) - } else { - pause = "null" - binding.CVPause.setCardBackgroundColor(Color.parseColor("#A9D867")) - Toast(requireContext()).showCustomInfoToast("Пауза убран", requireActivity()) + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + if (pause == "null") { + pause = "true" + binding.CVPause.setCardBackgroundColor(Color.parseColor("#D86767")) + Toast(requireContext()).showCustomInfoToast("Пауза установлен", requireActivity()) + } else { + pause = "null" + binding.CVPause.setCardBackgroundColor(Color.parseColor("#A9D867")) + Toast(requireContext()).showCustomInfoToast("Пауза убран", requireActivity()) + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) } } } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } + } - //Вывод всех курсов - fun GetAllCoursesSport(){ - CreatRetrofit() - val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) - CoroutineScope(Dispatchers.IO).launch { - val listProduct = doctorApi.GetCoursAllPatient("Bearer $Tokens",id!!) - requireActivity().runOnUiThread { - //Фиксируем полученные данные - val sportCourses = listProduct.body() - //Если нету ошибок - if (sportCourses != null) { - model.SportCoursList.value = sportCourses.courses - binding.CVSport.visibility = View.VISIBLE + //Обновленеи логина + fun UpdatePatientLogin(id:Int,login:String){ + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val updateLogin = doctorApi.UpdatePatientLogin("Bearer $Tokens",id,login) + requireActivity().runOnUiThread { + + + + //Фиксируем полученные данные + val List = updateLogin.body() + val Nice = updateLogin.isSuccessful + val Code = updateLogin.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } } } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) } - } - - //Инициализируем Retrofit - private fun CreatRetrofit() { - val interceptor = HttpLoggingInterceptor() - interceptor.level = HttpLoggingInterceptor.Level.BODY - - val client = OkHttpClient - .Builder() - .addInterceptor(interceptor) - .build() - - val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") - .client(client) - .addConverterFactory(GsonConverterFactory.create()) - .build() - - doctorApi = retrofit.create(DoctorApi::class.java) } + //Обновленеи пароля + fun UpdatePatientPassword(id:Int,password:String){ + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val updatePassword= doctorApi.UpdatePatientPassword("Bearer $Tokens",id,password) + requireActivity().runOnUiThread { +//Фиксируем полученные данные + val List = updatePassword.body() + val Nice = updatePassword.isSuccessful + val Code = updatePassword.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + + + private fun sport() { - binding.btnSport.setOnClickListener { - } } private fun report() = with(binding) { + + + btnExitPatientFragment.setOnClickListener { activity?.supportFragmentManager?.beginTransaction() ?.replace(com.example.doctor.R.id.CLMainListPatient, PatientsListFragment.newInstance()) ?.commit() + //this@PatientFragment.onDestroy() } - binding.btnReport.setOnClickListener { - binding.CVReport.visibility = View.VISIBLE + btnReport.setOnClickListener { + CVReport.visibility = View.VISIBLE QBAPatientList() } - binding.btnSport.setOnClickListener { - GetAllCoursesSport() - - + btnSport.setOnClickListener { + binding.CVSport.visibility = View.VISIBLE } - binding.btnCloseReport.setOnClickListener { - binding.CVReport.visibility = View.GONE + btnCloseReport.setOnClickListener { + CVReport.visibility = View.GONE initRcViewDay() } - binding.btnCloseReport2.setOnClickListener { - binding.CVSport.visibility = View.GONE - } - - - binding.btnCloseBefore.setOnClickListener { - binding.CVQB.visibility = View.GONE - } - binding.btnCloseAfter.setOnClickListener { - binding.CVQA.visibility = View.GONE - } - - - binding.CVReport.setOnClickListener { - binding.CVReport.visibility = View.GONE + btnClouseEditSport.setOnClickListener { + CVEditSport.visibility = View.GONE initRcViewDay() } - binding.CVSport.setOnClickListener { - binding.CVSport.visibility = View.GONE + CVEditSport.setOnClickListener { + CVEditSport.visibility = View.GONE + initRcViewDay() } - binding.CVReportList.setOnClickListener { + CVEditPatient.setOnClickListener{ + CVEditPatient.visibility = View.GONE + initRcViewDay() + } + btnClouseEditPatient.setOnClickListener{ + CVEditPatient.visibility = View.GONE + initRcViewDay() } + btnCloseReport2.setOnClickListener { + CVSport.visibility = View.GONE + } + + + btnCloseBefore.setOnClickListener { + CVQB.visibility = View.GONE + } + btnCloseAfter.setOnClickListener { + CVQA.visibility = View.GONE + } + + + CVReport.setOnClickListener { + CVReport.visibility = View.GONE + initRcViewDay() + } + CVSport.setOnClickListener { + CVSport.visibility = View.GONE + } + + CVReportList.setOnClickListener { + } + + btnEditPatient.setOnClickListener { + CVEditPatient.visibility = View.VISIBLE + } + //Переход на страницу редактирования курса binding.btnEditSport.setOnClickListener{ binding.CVEditSport.visibility = View.VISIBLE @@ -424,26 +875,49 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { activity?.supportFragmentManager?.beginTransaction() ?.replace(com.example.doctor.R.id.CLEditSport, EditSportFragment.newInstance()) ?.commit() + } + //Нажатие на кнопку для обновления логина + btnUpdateLogin.setOnClickListener{ + val login = edLogin.text.toString() + if(login.count() != 0){ + if(login.count() > 3){ + UpdatePatientLogin(id!!,login) + } + else{ + Toast(requireContext()).showCustomInfoToast("Логин слишком короткий", requireActivity()) + } + } + else{ + Toast(requireContext()).showCustomInfoToast("Поле пустое", requireActivity()) + } + } + + //Нажатие на кнопку для обновления пароля + btnUpdatePassword.setOnClickListener{ + val password = edPassword.text.toString() + if(password.count() != 0){ + if(password.count() > 10){ + UpdatePatientPassword(id!!,password) + } + else{ + Toast(requireContext()).showCustomInfoToast("Пароль слишком короткий", requireActivity()) + } + } + else{ + Toast(requireContext()).showCustomInfoToast("Поле пустое", requireActivity()) + } } } //Инициализация списка private fun initRcViewDay() = with(binding) { - RCView.layoutManager = - GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + RCView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию adapter = QBBAdapter() RCView.adapter = adapter } - //Инициализация списка - private fun initRcViewCours() = with(binding) { - rcVieeSportCourses.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию - adapterCours = CoursesAdapter(this@PatientFragment) - rcVieeSportCourses.adapter = adapterCours - } - fun closeViewCard() { binding.txtLogin.text = "" @@ -461,13 +935,11 @@ class PatientFragment : Fragment(),CoursesAdapter.Listener { fun newInstance() = PatientFragment() } - override fun onClickCoursAdd(item: SportCoursModel) { - if(id_sport == "" || id_sport == null){ - Toast(requireContext()).showCustomInfoToast("Сначалоа очистите курс", requireActivity()) - } - else{ - Toast(requireContext()).showCustomInfoToast("Курс добавлен", requireActivity()) - //ТУТ ДОЛЖНА БЫТЬ ФУНКЦИЯ ДЛЯ ДОБАВЛЕНИЯ КУРСА ПАЦИЕНТУ - } - } + + + + + + + } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/QBAModel.kt b/app/src/main/java/com/example/doctor/Patients/Reports/QBAModel.kt index ca522c7..283ae29 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/QBAModel.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/QBAModel.kt @@ -17,8 +17,8 @@ data class QBAModel( val eightb: Int, val nineb: Int, + val statusa: Int, val ida: Int, - //val statusa: Int, val onea: Int, val twoa: Int, val threea: Int, diff --git a/app/src/main/java/com/example/doctor/Patients/Reports/QBBAdapter.kt b/app/src/main/java/com/example/doctor/Patients/Reports/QBBAdapter.kt index dba6de7..3de85ed 100644 --- a/app/src/main/java/com/example/doctor/Patients/Reports/QBBAdapter.kt +++ b/app/src/main/java/com/example/doctor/Patients/Reports/QBBAdapter.kt @@ -16,7 +16,8 @@ class QBBAdapter() : ListAdapter(Comparator()) { class Holder(view: View) : RecyclerView.ViewHolder(view) { - val binding = ItemQbaBinding.bind(view) + val binding = ItemQbaBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + @SuppressLint("SuspiciousIndentation") @@ -42,18 +43,6 @@ class QBBAdapter() : ListAdapter(Comparator()) { CVB.setCardBackgroundColor(Color.parseColor("#ABDA83")) } - if(item.ninea == 1){ - txtStatusA.text = "Плохо" - CVA.setCardBackgroundColor(Color.parseColor("#DA8383")) - } - else if(item.onea >= 6 || item.threea == 1 ||item.sixa == 1 ||item.eighta == 1 ||item.elevena == 1){ - txtStatusA.text = "Средне" - CVA.setCardBackgroundColor(Color.parseColor("#DABA83")) - } - else{ - txtStatusA.text= "Хорошо" - CVA.setCardBackgroundColor(Color.parseColor("#ABDA83")) - } txtB1.text = item.oneb.toString() if(item.oneb==0){ @@ -119,10 +108,10 @@ class QBBAdapter() : ListAdapter(Comparator()) { if (item.eightb == 1) { txtB8.text = "Да" - CLQB8.setBackgroundColor(Color.parseColor("#C6DF8686")) + CLQB8.setBackgroundColor(Color.parseColor("#C686DF8F")) } else { txtB8.text = "Нет" - CLQB8.setBackgroundColor(Color.parseColor("#C686DF8F")) + CLQB8.setBackgroundColor(Color.parseColor("#C6DF8686")) } if (item.nineb == 1) { @@ -133,107 +122,144 @@ class QBBAdapter() : ListAdapter(Comparator()) { CLQB9.setBackgroundColor(Color.parseColor("#C686DF8F")) } + //Если анкета после была заполнена + if(item.statusa == 1){ + if(item.ninea == 1){ + txtStatusA.text = "Плохо" + CVA.setCardBackgroundColor(Color.parseColor("#DA8383")) + } + else if(item.onea >= 6 || item.threea == 1 ||item.sixa == 1 ||item.eighta == 1 ||item.elevena == 1){ + txtStatusA.text = "Средне" + CVA.setCardBackgroundColor(Color.parseColor("#DABA83")) + } + else{ + txtStatusA.text= "Хорошо" + CVA.setCardBackgroundColor(Color.parseColor("#ABDA83")) + } - txtA1.text = item.onea.toString() - if(item.onea==0){ - CLQA1.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - else if(item.onea in 1..5){ - CLQA1.setBackgroundColor(Color.parseColor("#C6DFD386")) + txtA1.text = item.onea.toString() + if(item.onea==0){ + CLQA1.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + else if(item.onea in 1..5){ + CLQA1.setBackgroundColor(Color.parseColor("#C6DFD386")) + } + else{ + CLQA1.setBackgroundColor(Color.parseColor("#C6DF8686")) + } + + if (item.twoa == 1) { + txtA2.text = "Да" + CLQA2.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA2.text = "Нет" + CLQA2.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.threea == 1) { + txtA3.text = "Да" + CLQA3.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA3.text = "Нет" + CLQA3.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.foura == 1) { + txtA4.text = "Да" + CLQA4.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA4.text = "Нет" + CLQA4.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.fivea == 1) { + txtA5.text = "Да" + CLQA5.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA5.text = "Нет" + CLQA5.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.sixa == 1) { + txtA6.text = "Да" + CLQA6.setBackgroundColor(Color.parseColor("#C6DF8686")) + + } else { + txtA6.text = "Нет" + CLQA6.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.sevena == 1) { + txtA7.text = "Да" + CLQA7.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA7.text = "Нет" + CLQA7.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.eighta == 1) { + txtA8.text = "Да" + CLQA8.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA8.text = "Нет" + CLQA8.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.ninea == 1) { + txtA9.text = "Да" + CLQA9.setBackgroundColor(Color.parseColor("#C6DF8686")) + + } else { + txtA9.text = "Нет" + CLQA9.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.tena == 1) { + txtA10.text = "Да" + CLQA10.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA10.text = "Нет" + CLQA10.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.elevena == 1) { + txtA11.text = "Да" + CLQA11.setBackgroundColor(Color.parseColor("#C6DF8686")) + } else { + txtA11.text = "Нет" + CLQA11.setBackgroundColor(Color.parseColor("#C686DF8F")) + } + + if (item.twelvea == 1) { + txtA12.text = "Да" + CLQA12.setBackgroundColor(Color.parseColor("#C686DF8F")) + } else { + txtA12.text = "Нет" + CLQA12.setBackgroundColor(Color.parseColor("#C6DF8686")) + } } else{ - CLQA1.setBackgroundColor(Color.parseColor("#C6DF8686")) + //Если анкета ПОСЛЕ небыла заполнена + txtStatusA.text = "ПУСТО" + txtStatusA.setTextColor(Color.parseColor("#FFFFFF")) + CVA.setCardBackgroundColor(Color.parseColor("#000000")) + CVColorAfter.setCardBackgroundColor(Color.parseColor("#FF8E8E8E")) + + txtA1.text = "" + txtA2.text = "" + txtA3.text = "" + txtA4.text = "" + txtA5.text = "" + txtA6.text = "" + txtA7.text = "" + txtA8.text = "" + txtA9.text = "" + txtA10.text = "" + txtA11.text = "" + txtA12.text = "" } - if (item.twoa == 1) { - txtA2.text = "Да" - CLQA2.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA2.text = "Нет" - CLQA2.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - if (item.threea == 1) { - txtA3.text = "Да" - CLQA3.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA3.text = "Нет" - CLQA3.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.foura == 1) { - txtA4.text = "Да" - CLQA4.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA4.text = "Нет" - CLQA4.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.fivea == 1) { - txtA5.text = "Да" - CLQA5.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA5.text = "Нет" - CLQA5.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.sixa == 1) { - txtA6.text = "Да" - CLQA6.setBackgroundColor(Color.parseColor("#C6DF8686")) - - } else { - txtA6.text = "Нет" - CLQA6.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.sevena == 1) { - txtA7.text = "Да" - CLQA7.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA7.text = "Нет" - CLQA7.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.eighta == 1) { - txtA8.text = "Да" - CLQA8.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA8.text = "Нет" - CLQA8.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.ninea == 1) { - txtA9.text = "Да" - CLQA9.setBackgroundColor(Color.parseColor("#C6DF8686")) - - } else { - txtA9.text = "Нет" - CLQA9.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.tena == 1) { - txtA10.text = "Да" - CLQA10.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA10.text = "Нет" - CLQA10.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.elevena == 1) { - txtA11.text = "Да" - CLQA11.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA11.text = "Нет" - CLQA11.setBackgroundColor(Color.parseColor("#C686DF8F")) - } - - if (item.twelvea == 1) { - txtA12.text = "Да" - CLQA12.setBackgroundColor(Color.parseColor("#C6DF8686")) - } else { - txtA12.text = "Нет" - CLQA12.setBackgroundColor(Color.parseColor("#C686DF8F")) - } } } @@ -259,6 +285,7 @@ class QBBAdapter() : ListAdapter(Comparator()) { + } diff --git a/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/ActiveCoursesPatientFragment.kt b/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/ActiveCoursesPatientFragment.kt new file mode 100644 index 0000000..436742f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/ActiveCoursesPatientFragment.kt @@ -0,0 +1,173 @@ +package com.example.doctor.Patients.TabLayoutPatient + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Adapter.PatientListAdapter +import com.example.doctor.Patients.Model.PatientAllModel +import com.example.doctor.Patients.Model.PatientIdModel +import com.example.doctor.Patients.PatientActivity +import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.databinding.FragmentActiveCoursesPatientBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + + +class ActiveCoursesPatientFragment : Fragment(),PatientListAdapter.Listener { + private lateinit var binding:FragmentActiveCoursesPatientBinding + private val modelDoctor: DoctorViewModel by activityViewModels() + private val dataModel: DataModel by activityViewModels()//Для передачи данных + lateinit var adapterPatient: PatientListAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + var patientYesList:List?=null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentActiveCoursesPatientBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcViewDay() + GetPatientList() + + modelDoctor.PatientActiveList.observe(viewLifecycleOwner){ + if(patientYesList!=it){ + patientYesList=it + adapterPatient.submitList(it) + } + } + } + + //Инициализация списка + private fun initRcViewDay() = with(binding) { + rcView.layoutManager = + GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterPatient = PatientListAdapter(this@ActiveCoursesPatientFragment) + rcView.adapter = adapterPatient + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + //Получения списка пациентов + fun GetPatientList() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientAllActive("Bearer $Tokens") + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + modelDoctor.PatientActiveList.value = List.patient + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + companion object { + fun newInstance() = ActiveCoursesPatientFragment() + } + + override fun onClickPatient(item: PatientAllModel) { + + //Вывод фрагмента на активити при первоначальной загрузке +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(com.example.doctor.R.id.CLMainPatient, PatientFragment.newInstance()) +// ?.commit() +// prefDoctorSave.saveIdPatient(requireContext(),item.id!!) +// prefDoctorSave.saveViewPatient(requireContext(),1) + //modelDoctor.patientId.value = PatientIdModel(item.id!!) + + prefDoctorSave.saveIdPatient(requireContext(),item.id!!) + prefDoctorSave.saveViewPatient(requireContext(),1) + val intetn = Intent(requireContext(), PatientActivity::class.java) + startActivity(intetn) + + + // dataModel.patientList.value = 1 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/NotActiveCoursesPatientFragment.kt b/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/NotActiveCoursesPatientFragment.kt new file mode 100644 index 0000000..53fb183 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Patients/TabLayoutPatient/NotActiveCoursesPatientFragment.kt @@ -0,0 +1,173 @@ +package com.example.doctor.Patients.TabLayoutPatient + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DataModel +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Patients.Adapter.PatientListAdapter +import com.example.doctor.Patients.Model.PatientAllModel +import com.example.doctor.Patients.Model.PatientIdModel +import com.example.doctor.Patients.PatientActivity +import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.databinding.FragmentNotActiveCoursesPatientBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + + +class NotActiveCoursesPatientFragment : Fragment(),PatientListAdapter.Listener { + private lateinit var binding:FragmentNotActiveCoursesPatientBinding + private val model: DoctorViewModel by activityViewModels() + private val dataModel: DataModel by activityViewModels()//Для передачи данных + lateinit var adapterPatient: PatientListAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + //Список не активных пациентов + var patientNoList: List? = null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentNotActiveCoursesPatientBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcViewDay() + GetPatientList() + + model.PatientNotList.observe(viewLifecycleOwner){ + if(patientNoList != it){ + patientNoList = it + adapterPatient.submitList(it) + } + } + } + + //Инициализация списка + private fun initRcViewDay() = with(binding) { + rcView.layoutManager = + GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterPatient = PatientListAdapter(this@NotActiveCoursesPatientFragment) + rcView.adapter = adapterPatient + } + + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + //Получения списка пациентов + fun GetPatientList() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = doctorApi.GetPatientAllNotActive("Bearer $Tokens") + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + model.PatientNotList.value = List.patient + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + override fun onClickPatient(item: PatientAllModel) { + + //Вывод фрагмента на активити при первоначальной загрузке +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(com.example.doctor.R.id.CLMainPatient, PatientFragment.newInstance()) +// ?.commit() + prefDoctorSave.saveIdPatient(requireContext(),item.id!!) + prefDoctorSave.saveViewPatient(requireContext(),1) + //model.patientId.value = PatientIdModel(item.id!!) + + val intetn = Intent(requireContext(), PatientActivity::class.java) + startActivity(intetn) + + + // dataModel.patientList.value = 1 + } + + + + companion object { + + fun newInstance() = NotActiveCoursesPatientFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Pref/ClearPref.kt b/app/src/main/java/com/example/doctor/Pref/ClearPref.kt index 54ca6ef..16c9095 100644 --- a/app/src/main/java/com/example/doctor/Pref/ClearPref.kt +++ b/app/src/main/java/com/example/doctor/Pref/ClearPref.kt @@ -6,7 +6,35 @@ import android.content.SharedPreferences class ClearPref() { fun clearToken(context: Context) { - val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE) + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORtoken", Context.MODE_PRIVATE) + val edit = prefDoctor.edit() + edit?.clear() + edit?.apply() + } + + fun clearViewPatient(context: Context) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORviewPatient", Context.MODE_PRIVATE) + val edit = prefDoctor.edit() + edit?.clear() + edit?.apply() + } + + fun clearIdPatient(context: Context) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORIdPatient", Context.MODE_PRIVATE) + val edit = prefDoctor.edit() + edit?.clear() + edit?.apply() + } + + fun clearIdCourses(context: Context) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORIdCourses", Context.MODE_PRIVATE) + val edit = prefDoctor.edit() + edit?.clear() + edit?.apply() + } + + fun clearIdActivitis(context: Context) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORIdActivitis", Context.MODE_PRIVATE) val edit = prefDoctor.edit() edit?.clear() edit?.apply() diff --git a/app/src/main/java/com/example/doctor/Pref/ConclusionPref.kt b/app/src/main/java/com/example/doctor/Pref/ConclusionPref.kt index cd2a344..1a31981 100644 --- a/app/src/main/java/com/example/doctor/Pref/ConclusionPref.kt +++ b/app/src/main/java/com/example/doctor/Pref/ConclusionPref.kt @@ -6,8 +6,32 @@ import android.content.SharedPreferences class ConclusionPref() { fun conclusionToken(context: Context):String { - val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE) + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORtoken", Context.MODE_PRIVATE) val token = prefDoctor.getString("token", "") return token.toString() } + + fun conclusionViewPatient(context: Context):Int { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORviewPatient", Context.MODE_PRIVATE) + val viewPatient = prefDoctor.getInt("viewPatient", 0) + return viewPatient.toInt() + } + + fun conclusionIdPatient(context: Context):Int { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORidPatient", Context.MODE_PRIVATE) + val idPatient = prefDoctor.getInt("idPatient", 0) + return idPatient.toInt() + } + + fun conclusionIdCourses(context: Context):Int { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORidCourses", Context.MODE_PRIVATE) + val idPatient = prefDoctor.getInt("idCourses", 0) + return idPatient.toInt() + } + + fun conclusionIdActivitis(context: Context):Int { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORIdActivitis", Context.MODE_PRIVATE) + val idPatient = prefDoctor.getInt("idActivitis", 0) + return idPatient.toInt() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Pref/SavePref.kt b/app/src/main/java/com/example/doctor/Pref/SavePref.kt index b7cbf07..689d6f4 100644 --- a/app/src/main/java/com/example/doctor/Pref/SavePref.kt +++ b/app/src/main/java/com/example/doctor/Pref/SavePref.kt @@ -1,15 +1,39 @@ package com.example.doctor.Pref +import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences class SavePref (){ - fun saveToken(context: Context,token: String) { - val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE) - val edit = prefDoctor.edit() + @SuppressLint("CommitPrefEdits") + fun saveToken(context: Context, token: String) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORtoken", Context.MODE_PRIVATE) prefDoctor.edit().putString("token", token).apply() } + + @SuppressLint("CommitPrefEdits") + fun saveViewPatient(context: Context, view_patient: Int) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORviewPatient", Context.MODE_PRIVATE) + prefDoctor.edit().putInt("viewPatient", view_patient).apply() + } + + @SuppressLint("CommitPrefEdits") + fun saveIdPatient(context: Context, view_patient: Int) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORidPatient", Context.MODE_PRIVATE) + prefDoctor.edit().putInt("idPatient", view_patient).apply() + } + + @SuppressLint("CommitPrefEdits") + fun saveIdCourses(context: Context, view_patient: Int) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORidCourses", Context.MODE_PRIVATE) + prefDoctor.edit().putInt("idCourses", view_patient).apply() + } + @SuppressLint("CommitPrefEdits") + fun saveIdActivitis(context: Context, view_patient: Int) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTORIdActivitis", Context.MODE_PRIVATE) + prefDoctor.edit().putInt("idActivitis", view_patient).apply() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Retrofit/DoctorApi.kt b/app/src/main/java/com/example/doctor/Retrofit/DoctorApi.kt index 0ecc9d2..e924ba7 100644 --- a/app/src/main/java/com/example/doctor/Retrofit/DoctorApi.kt +++ b/app/src/main/java/com/example/doctor/Retrofit/DoctorApi.kt @@ -1,24 +1,30 @@ package com.example.doctor.Retrofit +import com.example.doctor.Appeals.TabLayout.Model.AppealsNewListModel +import com.example.doctor.Appeals.TabLayout.Model.AppealsOldListModel import com.example.doctor.Auth.Model.AuthModel import com.example.doctor.Auth.Model.CheckTokenModel import com.example.doctor.Auth.Model.UserModel +import com.example.doctor.Home.HomeInfoModel import com.example.doctor.Patients.Model.MessageModel import com.example.doctor.Patients.Model.CreatePatientModel import com.example.doctor.Patients.Model.PatientAllListModel import com.example.doctor.Patients.Model.PatientAllModel import com.example.doctor.Patients.Model.PatientModel import com.example.doctor.Patients.Model.PauseModel +import com.example.doctor.Patients.Reports.Courses.SportCoursDoctorListModel +import com.example.doctor.Patients.Reports.Courses.SportCoursListModel import com.example.doctor.Patients.Reports.Edit.EditSportListNoModel import com.example.doctor.Patients.Reports.Edit.EditSportListYesModel -import com.example.doctor.Patients.Reports.Edit.UpdateSportTaskNoModel -import com.example.doctor.Patients.Reports.Edit.UpdateSportTaskYesModel import com.example.doctor.Patients.Reports.QBAListModel import com.example.doctor.Patients.Reports.Requests.ClearSportPatientModel -import com.example.doctor.Patients.Reports.SportCoursListModel +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorListAllModel +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorListYourModel +import com.example.doctor.Setting.Courses.Model.CoursesDoctorListModel import com.example.doctor.Sport.AddSportPatientModel import retrofit2.Response import retrofit2.http.Body +import retrofit2.http.DELETE import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.Headers @@ -49,10 +55,20 @@ interface DoctorApi { @GET("GetPatientAll") suspend fun GetPatientAll(@Header("Authorization") token:String):Response + //Вывод пациентов конкретного врача с активным курсом + @Headers("Content-Type: application/json") + @GET("GetPatientAllActive") + suspend fun GetPatientAllActive(@Header("Authorization") token:String):Response + + //Вывод пациентов конкретного врача с не активным курсом + @Headers("Content-Type: application/json") + @GET("GetPatientAllNotActive") + suspend fun GetPatientAllNotActive(@Header("Authorization") token:String):Response + //Вывод всех пациентов @Headers("Content-Type: application/json") @GET("GetPatientID") - suspend fun GetPatientID(@Header("Authorization") token:String):Response + suspend fun GetPatientID(@Header("Authorization") token:String,@Query("id") id:Int):Response //Поиск пациентов @Headers("Content-Type: application/json") @@ -68,6 +84,12 @@ interface DoctorApi { @GET("GetCoursAllPatient") suspend fun GetCoursAllPatient(@Header("Authorization") token:String,@Query("id") id:Int):Response + //Вывод курсов созданных врачем + @Headers("Content-Type: application/json") + @GET("GetCoursesDoctorPatient") + suspend fun GetCoursesDoctorPatient(@Header("Authorization") token:String,@Query("id") id:Int):Response + + //Вывод анкеты пациентов которые сейчас действуют @Headers("Content-Type: application/json") @GET("GetPatientBAQiestionar") @@ -131,6 +153,82 @@ interface DoctorApi { //Отключенных упражнений @Headers("Content-Type: application/json") @PUT("UpdateBlockSportTasksNo") - suspend fun UpdateBlockSportTasksNo(@Header("Authorization") token:String,@Query("id") id:Int,):Response + suspend fun UpdateBlockSportTasksNo(@Header("Authorization") token:String,@Query("id") id:Int):Response + + + //Отключенных упражнений + @Headers("Content-Type: application/json") + @PUT("UpdatePatientLogin") + suspend fun UpdatePatientLogin(@Header("Authorization") token:String,@Query("id") id:Int,@Query("login") login:String):Response + //Отключенных упражнений + @Headers("Content-Type: application/json") + @PUT("UpdatePatientPassword") + suspend fun UpdatePatientPassword(@Header("Authorization") token:String,@Query("id") id:Int,@Query("password") password:String):Response + + //Добавление курса пациенту + @Headers("Content-Type: application/json") + @POST("AddSportPatient") + suspend fun AddSportPatient(@Header("Authorization") token:String,@Query("id_patient") id:Int,@Query("id_course") id_course:Int,@Query("all_day") all_day:Int):Response + + + + + //Вывод необработанных сообщений + @Headers("Content-Type: application/json") + @GET("GetAppealsDoctorNew") + suspend fun GetAppealsDoctorNew(@Header("Authorization") token:String) :Response + + //Вывод необработанных сообщений + @Headers("Content-Type: application/json") + @GET("GetAppealsDoctorOld") + suspend fun GetAppealsDoctorOld(@Header("Authorization") token:String) :Response + + + //Подтверждение необработанных сообщений + @Headers("Content-Type: application/json") + @PUT("UpdateMessageDoctor") + suspend fun UpdateMessageDoctor(@Header("Authorization") token:String,@Query("id") id:Int,@Query("id_patient") id_patient:Int) :Response + + //Отправка сообщения пациенту + @Headers("Content-Type: application/json") + @POST("AddMessageDoctor") + suspend fun AddMessageDoctor(@Header("Authorization") token:String,@Query("login") login:String,@Query("text") text:String) :Response + + //Создание курса врачем + @Headers("Content-Type: application/json") + @POST("AddCoursesName") + suspend fun AddCoursesName(@Header("Authorization") token:String,@Query("name") name:String,@Query("description") description:String) :Response + + //Вывод курсов созданных врачем + @Headers("Content-Type: application/json") + @GET("GetCoursesDoctor") + suspend fun GetCoursesDoctor(@Header("Authorization") token:String) :Response + + //Вывод упражнений которые не входят в курс + @Headers("Content-Type: application/json") + @GET("GetEditCourseDoctorAll") + suspend fun GetEditCourseDoctorAll(@Header("Authorization") token:String,@Query("id_doctor_courses") id_doctor_courses:Int) :Response + + + //Вывод упражнений которые входят в курс + @Headers("Content-Type: application/json") + @GET("GetEditCourseDoctorYour") + suspend fun GetEditCourseDoctorYour(@Header("Authorization") token:String,@Query("id_doctor_courses") id_doctor_courses:Int) :Response + + + //Добавление упражнений в курс + @Headers("Content-Type: application/json") + @POST("AddCoursesCreatingDoctor") + suspend fun AddCoursesCreatingDoctor(@Header("Authorization") token:String,@Query("id_sports_tasks") id_sports_tasks:Int,@Query("id_sets_of_sports_activities") id_sets_of_sports_activities:Int) :Response + + //Удаление упражнений из курса + @Headers("Content-Type: application/json") + @DELETE("ClearCoursesCreatingDoctor") + suspend fun ClearCoursesCreatingDoctor(@Header("Authorization") token:String,@Query("id_sets_of_sports_exercises") id_sets_of_sports_exercises:Int) :Response + + //Вывод данных для первой страницы врача + @Headers("Content-Type: application/json") + @GET("CountPatientAndAppeals") + suspend fun CountPatientAndAppeals(@Header("Authorization") token:String) :Response } \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/Adapter/CoursesDoctorAdapter.kt b/app/src/main/java/com/example/doctor/Setting/Courses/Adapter/CoursesDoctorAdapter.kt new file mode 100644 index 0000000..df1f594 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/Adapter/CoursesDoctorAdapter.kt @@ -0,0 +1,90 @@ +package com.example.doctor.Setting.Courses.Adapter + +import android.annotation.SuppressLint +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView + +import com.example.doctor.R +import com.example.doctor.Setting.Courses.Model.CoursesDoctorModel +import com.example.doctor.databinding.ItemCardCoursesDoctorBinding + + +class CoursesDoctorAdapter(val listener: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemCardCoursesDoctorBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: CoursesDoctorModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it1 -> listener.onClickCourses(it1) } + + } + } + + @SuppressLint("SuspiciousIndentation", "SetTextI18n") + fun bind(item: CoursesDoctorModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumberCurds.text = item.number.toString() + "." + txtNameCoursesDoctor.text = item.name + } + + + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_card_courses_doctor, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: CoursesDoctorModel, + newItem: CoursesDoctorModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: CoursesDoctorModel, + newItem: CoursesDoctorModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickCourses(item: CoursesDoctorModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/CoursesActivity.kt b/app/src/main/java/com/example/doctor/Setting/Courses/CoursesActivity.kt new file mode 100644 index 0000000..2012e23 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/CoursesActivity.kt @@ -0,0 +1,22 @@ +package com.example.doctor.Setting.Courses + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.R +import com.example.doctor.Setting.Courses.EditCourses.CreateCoursesFragment +import com.example.doctor.databinding.ActivityCoursesBinding + +class CoursesActivity : AppCompatActivity() { + private lateinit var binding: ActivityCoursesBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCoursesBinding.inflate(layoutInflater) + setContentView(binding.root) + + binding.apply { + supportFragmentManager.beginTransaction().replace(R.id.CLCoursesActivity, CreateCoursesFragment.newInstance()).commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/CreateCoursesFragment.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/CreateCoursesFragment.kt new file mode 100644 index 0000000..4c29306 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/CreateCoursesFragment.kt @@ -0,0 +1,407 @@ +package com.example.doctor.Setting.Courses.EditCourses + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.FragmentActivity +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Adapter.VpAdapter +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.Adapter.CoursesDoctorAdapter +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.AllSportCoursesDoctorFragment +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.YourSportCoursesDoctorFragment +import com.example.doctor.Setting.Courses.Model.CoursesDoctorModel +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentCreateCoursesBinding +import com.google.android.material.tabs.TabLayoutMediator +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + + +class CreateCoursesFragment : Fragment(),CoursesDoctorAdapter.Listener { + private lateinit var binding: FragmentCreateCoursesBinding + private val model: DoctorViewModel by activityViewModels() + private lateinit var doctorApi: DoctorApi + lateinit var adapter: CoursesDoctorAdapter + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + + + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCreateCoursesBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.apply { + initRcView() + + GetCoursesDoctor() + button() + + CLCreate.visibility = View.GONE + + btnCreateCourses.setOnClickListener{ + CLCreate.visibility = View.VISIBLE + } + + //Закрытие экоана создания названия + CLCreate.setOnClickListener{ + CLCreate.visibility = View.GONE + } + btnExitCreat.setOnClickListener{ + CLCreate.visibility = View.GONE + } + +// CLEditCourses.setOnClickListener { +// CLEditCourses.visibility = View.GONE +// } + + + btnExit.setOnClickListener{ + activity?.finish() + } + + + + + model.CoursesDoctorList.observe(viewLifecycleOwner) { + adapter.submitList(it) + } + + + btnCreateCoursrsDoctor.setOnClickListener{ + CreateCoursesDoctor() + } + + + + } + } + + + + private fun CreateCoursesDoctor() { + val name = binding.edCoursesDoctorName.text.toString() + val description = binding.edCoursesDoctorDescription.text.toString() + if(name!="" && description !=""){ + AddCoursesName(name,description) + } + else{ + Toast(requireContext()).showCustomInfoToast("Не все поля заполнены", requireActivity()) + } + + } + + private fun button() = with(binding){ + CVCardCreateCourses.setOnClickListener { + + } +// CVEditCourses.setOnClickListener { +// +// } + } + + //Получения списка пациентов + fun AddCoursesName(name:String,description:String) { + if (isOnline(requireContext())) { + visibleLoadYes() + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCreateCoursesDoctor = doctorApi.AddCoursesName("Bearer $Tokens",name,description) + + requireActivity().runOnUiThread { + + + + //Фиксируем полученные данные + val List = listCreateCoursesDoctor.body() + val Nice = listCreateCoursesDoctor.isSuccessful + val Code = listCreateCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetCoursesDoctor() + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + visibleLoadNo() + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Получения списка курсов созданных доктором + fun GetCoursesDoctor() { + if (isOnline(requireContext())) { + visibleLoadYes() + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetCoursesDoctor("Bearer $Tokens") + + requireActivity().runOnUiThread { + + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + model.CoursesDoctorList.value = List.sport_courses_doctor + binding.txtNull.visibility = View.GONE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + + visibleLoadNo() + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Инициализация списка + private fun initRcView() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapter = CoursesDoctorAdapter(this@CreateCoursesFragment) + rcView.adapter = adapter + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + + fun visible1()=with(binding){ + constraintLayout2.visibility = View.VISIBLE + CLCreate.visibility = View.GONE + // CLEditCourses.visibility = View.GONE + CLLoad.visibility = View.GONE + } + fun visible2()=with(binding){ + constraintLayout2.visibility = View.GONE + CLCreate.visibility = View.VISIBLE + //CLEditCourses.visibility = View.GONE + CLLoad.visibility = View.GONE + } + + fun visible3()=with(binding){ + constraintLayout2.visibility = View.GONE + CLCreate.visibility = View.GONE + // CLEditCourses.visibility = View.VISIBLE + CLLoad.visibility = View.GONE + } + + fun visibleLoadYes()=with(binding){ + CLLoad.visibility = View.VISIBLE + } + fun visibleLoadNo()=with(binding){ + CLLoad.visibility = View.GONE + } + companion object { + + fun newInstance() = CreateCoursesFragment() + } +// //Получения списка курсов созданных доктором +// fun GetEditCourseDoctorAll(id:Int) { +// if (isOnline(requireContext())) { +// initRetrofit() +// val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) +// CoroutineScope(Dispatchers.IO).launch { +// val listCoursesDoctor = doctorApi.GetEditCourseDoctorAll("Bearer $Tokens",id) +// +// requireActivity().runOnUiThread { +// +// //Фиксируем полученные данные +// val CoursesDoctorList = listCoursesDoctor.body() +// +// //Если нету ошибок +// if (CoursesDoctorList != null) { +// model.EditCoursesDoctorAllList.value = CoursesDoctorList.set_of_sports_exercises_all +// binding.txtNull.visibility = View.GONE +// } +// else{ +// binding.txtNull.visibility = View.VISIBLE +// } +// +// } +// +// } +// } else { +// val intetn = Intent(requireContext(), EnternetActivity::class.java) +// activity?.finish() +// startActivity(intetn) +// } +// +// } +// //Получения списка курсов созданных доктором +// fun GetEditCourseDoctorYour(id:Int) { +// if (isOnline(requireContext())) { +// initRetrofit() +// val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) +// CoroutineScope(Dispatchers.IO).launch { +// val listCoursesDoctor = doctorApi.GetEditCourseDoctorYour("Bearer $Tokens",id) +// +// requireActivity().runOnUiThread { +// +// //Фиксируем полученные данные +// val CoursesDoctorList = listCoursesDoctor.body() +// +// //Если нету ошибок +// if (CoursesDoctorList != null) { +// model.EditCoursesDoctorYourList.value = CoursesDoctorList.set_of_sports_exercises_your +// } +// } +// } +// } else { +// val intetn = Intent(requireContext(), EnternetActivity::class.java) +// activity?.finish() +// startActivity(intetn) +// } +// +// } + + + + //Проверка интернета + fun isOnline(context: Context): Boolean { + if (context == null) return false + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + if (capabilities != null) { + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> { + return true + } + } + } + } else { + val activeNetworkInfo = connectivityManager.activeNetworkInfo + if (activeNetworkInfo != null && activeNetworkInfo.isConnected) { + return true + } + } + return false + } + override fun onClickCourses(item: CoursesDoctorModel){ +// // CLEditCourses.visibility = View.VISIBLE +// prefDoctorSave.saveIdCourses(requireContext(),item.id) +// prefDoctorSave.saveIdActivitis(requireContext(),item.id_activity) +// // model.CoursesDoctorCA.value= CoursesDoctorCA(item.id,item.id_activity) +// GetEditCourseDoctorAll(item.id) +// GetEditCourseDoctorYour(item.id) + + model.CoursesCustomDoctor.value = item + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLCoursesActivity, EditCoursesFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/EditCoursesFragment.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/EditCoursesFragment.kt new file mode 100644 index 0000000..18ac01d --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/EditCoursesFragment.kt @@ -0,0 +1,242 @@ +package com.example.doctor.Setting.Courses.EditCourses + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.FragmentActivity +import androidx.fragment.app.activityViewModels +import com.example.doctor.Adapter.VpAdapter +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.Adapter.CoursesDoctorAdapter +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.AllSportCoursesDoctorFragment +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.YourSportCoursesDoctorFragment +import com.example.doctor.databinding.FragmentEditCoursesBinding +import com.google.android.material.tabs.TabLayoutMediator +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + + +class EditCoursesFragment : Fragment() { + private lateinit var binding:FragmentEditCoursesBinding + private val model: DoctorViewModel by activityViewModels() + private lateinit var doctorApi: DoctorApi + lateinit var adapter: CoursesDoctorAdapter + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + + private val tList = listOf( + "добавленные", + "Все", + ) + + //Список с фрагментами для переключения + private val flist = listOf( + YourSportCoursesDoctorFragment.newInstance(), + AllSportCoursesDoctorFragment.newInstance(), + + ) + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentEditCoursesBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.apply { + init() + + binding.btnBack.setOnClickListener{ + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLCoursesActivity, CreateCoursesFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + + } + + model.CoursesCustomDoctor.observe(viewLifecycleOwner){ + txtNameCourses.text = it.name + GetEditCourseDoctorYour(it.id) + GetEditCourseDoctorAll(it.id) + } + } + } + + //Получения списка упражнений созданных врачем + fun GetEditCourseDoctorYour(id:Int) { + if (isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorYour("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + model.EditCoursesDoctorYourList.value = List.set_of_sports_exercises_your + + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Получения списка курсов созданных доктором + fun GetEditCourseDoctorAll(id:Int) { + if (isOnline(requireContext())) { + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorAll("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val CoursesDoctorList = listCoursesDoctor.body() + + //Если нету ошибок + if (CoursesDoctorList != null) { + model.EditCoursesDoctorAllList.value = CoursesDoctorList.set_of_sports_exercises_all + } + + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + + //Функция подключения переключения + private fun init() = with(binding) { + val adapter = VpAdapter(activity as FragmentActivity, flist) + vpCourses.adapter = adapter + + //Переключения (связываем таблаяут(переключатель) с viewpager, чтобы переключать фрагменты) + TabLayoutMediator(tabLayoutCourses, vpCourses) { tab, pos -> + tab.text = + tList[pos]//tab - нажатая кнопка, pos - позиция кнопки, tList[pos] - передаем название по полученной позиции + }.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран + + //Изменения цвета в зависомости на каком из tabLayout вы находитесь + binding.tabLayoutCourses.setTabTextColors( + getResources().getColor(R.color.black), + getResources().getColor(R.color.white) + ); + + + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + //Проверка интернета + fun isOnline(context: Context): Boolean { + if (context == null) return false + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + if (capabilities != null) { + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> { + return true + } + } + } + } else { + val activeNetworkInfo = connectivityManager.activeNetworkInfo + if (activeNetworkInfo != null && activeNetworkInfo.isConnected) { + return true + } + } + return false + } + + + companion object { + fun newInstance() = EditCoursesFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorAllAdapter.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorAllAdapter.kt new file mode 100644 index 0000000..2b9b13a --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorAllAdapter.kt @@ -0,0 +1,107 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Adapter + +import android.annotation.SuppressLint +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.R +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorModel +import com.example.doctor.databinding.ItemEditSportYesBinding + + +class EditCoursesDoctorAllAdapter(val listener_sport: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_sport: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemEditSportYesBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: EditCoursesDoctorModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + binding.btnYeyYes.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + itemTemp?.let { it1 -> listener_sport.onClickCoursesAll(it1) } + } + } + + @SuppressLint("SuspiciousIndentation") + fun bind(item: EditCoursesDoctorModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumber.text = item.number.toString()+"." + txtNameSport.text = item.name + txtDescriptionSport.text = item.description + + if (item.expand) { + binding.txtDescriptionSport.maxLines = 100 + + } else { + binding.txtDescriptionSport.maxLines = 1 + + } + + binding.CardViewOld.setOnClickListener { + if (item.expand == false) { + binding.txtDescriptionSport.maxLines = 100 + item.expand = true + } else { + binding.txtDescriptionSport.maxLines = 1 + item.expand = false + } + } + + } + + + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_edit_sport_yes, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_sport)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: EditCoursesDoctorModel, + newItem: EditCoursesDoctorModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: EditCoursesDoctorModel, + newItem: EditCoursesDoctorModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickCoursesAll(item: EditCoursesDoctorModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorYourAdapter.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorYourAdapter.kt new file mode 100644 index 0000000..54769d2 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Adapter/EditCoursesDoctorYourAdapter.kt @@ -0,0 +1,107 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Adapter + +import android.annotation.SuppressLint +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.doctor.R +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorModel +import com.example.doctor.databinding.ItemEditSportNoBinding + + +class EditCoursesDoctorYourAdapter(val listener_sport: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_sport: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemEditSportNoBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: EditCoursesDoctorModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + binding.btnYeyNo.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + itemTemp?.let { it1 -> listener_sport.onClickCoursesYour(it1) } + } + } + + @SuppressLint("SuspiciousIndentation") + fun bind(item: EditCoursesDoctorModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumber.text = item.number.toString()+"." + txtNameSport.text = item.name + txtDescriptionSport.text = item.description + + if (item.expand) { + binding.txtDescriptionSport.maxLines = 100 + + } else { + binding.txtDescriptionSport.maxLines = 1 + + } + + binding.CardViewOld.setOnClickListener { + if (item.expand == false) { + binding.txtDescriptionSport.maxLines = 100 + item.expand = true + } else { + binding.txtDescriptionSport.maxLines = 1 + item.expand = false + } + } + + } + + + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_edit_sport_no, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_sport)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: EditCoursesDoctorModel, + newItem: EditCoursesDoctorModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: EditCoursesDoctorModel, + newItem: EditCoursesDoctorModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickCoursesYour(item: EditCoursesDoctorModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/AllSportCoursesDoctorFragment.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/AllSportCoursesDoctorFragment.kt new file mode 100644 index 0000000..3f56817 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/AllSportCoursesDoctorFragment.kt @@ -0,0 +1,292 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetFragment +import com.example.doctor.Pref.ClearPref +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.Pref.SavePref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Adapter.EditCoursesDoctorAllAdapter +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorModel +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentAllSportCoursesDoctorBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class AllSportCoursesDoctorFragment : Fragment(), EditCoursesDoctorAllAdapter.Listener{ + private lateinit var binding:FragmentAllSportCoursesDoctorBinding + lateinit var adapterAll: EditCoursesDoctorAllAdapter + private lateinit var doctorApi: DoctorApi + private val model: DoctorViewModel by activityViewModels() + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + val prefDoctorSave = SavePref() + var id_patient = 0; + var id_courses = 0; + var id_activitis = 0; + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentAllSportCoursesDoctorBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcView() +// id_courses = prefDoctorConclusion.conclusionIdCourses(requireContext()) +// id_activitis = prefDoctorConclusion.conclusionIdActivitis(requireContext()) + + model.CoursesCustomDoctor.observe(viewLifecycleOwner){ + id_courses = it.id + id_activitis = it.id_activity + GetEditCourseDoctorAll(id_courses) + } + + + model.EditCoursesDoctorAllList.observe(viewLifecycleOwner){ + adapterAll.submitList(it) + } +// model.CoursesDoctorCA.observe(viewLifecycleOwner){ +// requireActivity().runOnUiThread { +// id_courses = it.id_courses +// id_activitis = it.id_activitis +// } +// } + Log.i("2sadas","2sadasd") + } + + override fun onResume() { + super.onResume() + Log.i("2sadas","22sadasd") + } + + //Получения списка курсов созданных доктором + fun GetEditCourseDoctorAll(id:Int) { + if (isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorAll("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + model.EditCoursesDoctorAllList.value = List.set_of_sports_exercises_all + binding.txtNull.visibility = View.GONE + } + else{ + binding.txtNull.visibility = View.VISIBLE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + //Получения списка курсов созданных доктором + fun GetEditCourseDoctorYour(id:Int) { + if (isOnline(requireContext())) { + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorYour("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val CoursesDoctorList = listCoursesDoctor.body() + + //Если нету ошибок + if (CoursesDoctorList != null) { + model.EditCoursesDoctorYourList.value = CoursesDoctorList.set_of_sports_exercises_your + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Добавление упражнения в курс + fun AddCoursesCreatingDoctor(id:Int,id_activitis:Int) { + if (isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctorAllAdd = doctorApi.AddCoursesCreatingDoctor("Bearer $Tokens",id,id_activitis) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctorAllAdd.body() + val Nice = listCoursesDoctorAllAdd.isSuccessful + val Code = listCoursesDoctorAllAdd.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetEditCourseDoctorAll(id_courses) + GetEditCourseDoctorYour(id_courses) + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, EnternetFragment.newInstance()) + ?.commit() + } + } + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + //Проверка интернета + fun isOnline(context: Context): Boolean { + if (context == null) return false + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + if (capabilities != null) { + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> { + return true + } + } + } + } else { + val activeNetworkInfo = connectivityManager.activeNetworkInfo + if (activeNetworkInfo != null && activeNetworkInfo.isConnected) { + return true + } + } + return false + } + + + + + //Инициализация списка + private fun initRcView() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterAll = EditCoursesDoctorAllAdapter(this@AllSportCoursesDoctorFragment) + rcView.adapter = adapterAll + } + + companion object { + fun newInstance() = AllSportCoursesDoctorFragment() + } + + + override fun onClickCoursesAll(item: EditCoursesDoctorModel) { + AddCoursesCreatingDoctor(item.id,id_activitis) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/CoursesDoctorCA.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/CoursesDoctorCA.kt new file mode 100644 index 0000000..570ecda --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/CoursesDoctorCA.kt @@ -0,0 +1,8 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model + +data class CoursesDoctorCA( + val id_courses: Int, + val id_activitis: Int, + + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListAllModel.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListAllModel.kt new file mode 100644 index 0000000..6a206c8 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListAllModel.kt @@ -0,0 +1,8 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model + +data class EditCoursesDoctorListAllModel( + val set_of_sports_exercises_all: List + + + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListYourModel.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListYourModel.kt new file mode 100644 index 0000000..2ea8533 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorListYourModel.kt @@ -0,0 +1,8 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model + +data class EditCoursesDoctorListYourModel( + val set_of_sports_exercises_your: List + + + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorModel.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorModel.kt new file mode 100644 index 0000000..6d0a519 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/Model/EditCoursesDoctorModel.kt @@ -0,0 +1,12 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model + +data class EditCoursesDoctorModel( + val number: Int, + val id: Int, + val id_exercises: Int, + val name:String, + val description:String, + val url_image:String, + var expand : Boolean = false, + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/YourSportCoursesDoctorFragment.kt b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/YourSportCoursesDoctorFragment.kt new file mode 100644 index 0000000..37f8e3f --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/EditCourses/TabLayoutEditCourses/YourSportCoursesDoctorFragment.kt @@ -0,0 +1,290 @@ +package com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.doctor.Auth.AuthActivity +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.DoctorViewModel +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetFragment +import com.example.doctor.Pref.ConclusionPref +import com.example.doctor.R +import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Adapter.EditCoursesDoctorYourAdapter +import com.example.doctor.Setting.Courses.EditCourses.TabLayoutEditCourses.Model.EditCoursesDoctorModel +import com.example.doctor.Toast.showCustomInfoToast +import com.example.doctor.databinding.FragmentYourSportCoursesDoctorBinding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class YourSportCoursesDoctorFragment : Fragment(), EditCoursesDoctorYourAdapter.Listener { + private lateinit var binding: FragmentYourSportCoursesDoctorBinding + lateinit var adapterYour: EditCoursesDoctorYourAdapter + private lateinit var doctorApi: DoctorApi + val prefDoctorConclusion = ConclusionPref() + private val model: DoctorViewModel by activityViewModels() + var id_patient = 0; + var id_courses = 0; + var id_activitis = 0; + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentYourSportCoursesDoctorBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initRcView() + + model.CoursesCustomDoctor.observe(viewLifecycleOwner){ + id_courses = it.id + id_activitis = it.id_activity + GetEditCourseDoctorYour(id_courses) + } +// id_courses = prefDoctorConclusion.conclusionIdCourses(requireContext()) +// id_activitis = prefDoctorConclusion.conclusionIdActivitis(requireContext()) + + + model.EditCoursesDoctorYourList.observe(viewLifecycleOwner){ + adapterYour.submitList(it) + } +// model.CoursesDoctorCA.observe(viewLifecycleOwner){ +// id_courses = it.id_courses +// id_activitis = it.id_activitis +// } + Log.i("1sadas","1sadasd") + } + + override fun onResume() { + super.onResume() + Log.i("1sadas","11sadasd") + + } + //Получения списка курсов созданных доктором + fun GetEditCourseDoctorYour(id:Int) { + if (isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorYour("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctor.body() + val Nice = listCoursesDoctor.isSuccessful + val Code = listCoursesDoctor.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + model.EditCoursesDoctorYourList.value = List.set_of_sports_exercises_your + binding.txtNull.visibility = View.GONE + } + else{ + binding.txtNull.visibility = View.VISIBLE + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Получения списка курсов созданных доктором + fun GetEditCourseDoctorAll(id:Int) { + if (isOnline(requireContext())) { + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctor = doctorApi.GetEditCourseDoctorAll("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val CoursesDoctorList = listCoursesDoctor.body() + + //Если нету ошибок + if (CoursesDoctorList != null) { + model.EditCoursesDoctorAllList.value = CoursesDoctorList.set_of_sports_exercises_all + } + + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + //Получения списка курсов созданных доктором + fun ClearCoursesCreatingDoctor(id:Int) { + + if (isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listCoursesDoctorYourClear = doctorApi.ClearCoursesCreatingDoctor("Bearer $Tokens",id) + + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = listCoursesDoctorYourClear.body() + val Nice = listCoursesDoctorYourClear.isSuccessful + val Code = listCoursesDoctorYourClear.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + GetEditCourseDoctorYour(id_courses) + GetEditCourseDoctorAll(id_courses) + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + + } + + //Проверка интернета + fun isOnline(context: Context): Boolean { + if (context == null) return false + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + if (capabilities != null) { + when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { + return true + } + + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> { + return true + } + } + } + } else { + val activeNetworkInfo = connectivityManager.activeNetworkInfo + if (activeNetworkInfo != null && activeNetworkInfo.isConnected) { + return true + } + } + return false + } + + + //Инициализируем Retrofit + private fun initRetrofit() { + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + doctorApi = retrofit.create(DoctorApi::class.java) + + } + + //Инициализация списка + private fun initRcView() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterYour = EditCoursesDoctorYourAdapter(this@YourSportCoursesDoctorFragment) + rcView.adapter = adapterYour + } + companion object { + + fun newInstance() = YourSportCoursesDoctorFragment() + } + + override fun onClickCoursesYour(item: EditCoursesDoctorModel) { + Log.i("sadsadsadasd",item.toString()) + + ClearCoursesCreatingDoctor(item.id_exercises) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorListModel.kt b/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorListModel.kt new file mode 100644 index 0000000..22ef494 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorListModel.kt @@ -0,0 +1,6 @@ +package com.example.doctor.Setting.Courses.Model + +data class CoursesDoctorListModel( + val sport_courses_doctor: List + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorModel.kt b/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorModel.kt new file mode 100644 index 0000000..3898a26 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Setting/Courses/Model/CoursesDoctorModel.kt @@ -0,0 +1,14 @@ +package com.example.doctor.Setting.Courses.Model + +data class CoursesDoctorModel( + val number: Int, + val id: Int, + val name: String, + val description: String, + val visibility: Int, + val user_id: Int, + val id_activity:Int, + val created_at: String, + val updated_at: String, + ) + diff --git a/app/src/main/java/com/example/doctor/Setting/SettingFragment.kt b/app/src/main/java/com/example/doctor/Setting/SettingFragment.kt index 7bd8131..97251f3 100644 --- a/app/src/main/java/com/example/doctor/Setting/SettingFragment.kt +++ b/app/src/main/java/com/example/doctor/Setting/SettingFragment.kt @@ -2,7 +2,9 @@ package com.example.doctor.Setting import android.content.Context import android.content.Intent -import android.content.SharedPreferences +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater @@ -12,12 +14,17 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import com.example.doctor.Auth.AuthActivity import com.example.doctor.Auth.AuthFragment -import com.example.doctor.Patients.Reports.PatientFragment +import com.example.doctor.CodeError.Code429Activity +import com.example.doctor.CodeError.Code500Activity +import com.example.doctor.Enternet.EnternetActivity +import com.example.doctor.Enternet.EnternetCheck +import com.example.doctor.Enternet.EnternetFragment +import com.example.doctor.MainActivity import com.example.doctor.Pref.ClearPref import com.example.doctor.Pref.ConclusionPref -import com.example.doctor.Pref.SavePref import com.example.doctor.R import com.example.doctor.Retrofit.DoctorApi +import com.example.doctor.Setting.Courses.CoursesActivity import com.example.doctor.Toast.showCustomInfoToast import com.example.doctor.databinding.FragmentSettingBinding import kotlinx.coroutines.CoroutineScope @@ -36,6 +43,8 @@ class SettingFragment : Fragment() { private lateinit var doctorApi: DoctorApi val prefDoctorConclusion = ConclusionPref() + //Класс проверки интеренета + val enternetCheck = EnternetCheck() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -59,10 +68,15 @@ class SettingFragment : Fragment() { btnYourData.setOnClickListener{ activity?.supportFragmentManager?.beginTransaction() - ?.replace(com.example.doctor.R.id.CLMainFragment, YourDataFragment.newInstance()) + ?.replace(R.id.CLMainFragment, YourDataFragment.newInstance()) ?.commit() } + binding.btnAddCourses.setOnClickListener{ + val intetn = Intent(requireContext(), CoursesActivity::class.java) + startActivity(intetn) + } + } @@ -86,6 +100,7 @@ class SettingFragment : Fragment() { //Получения списка пациентов fun Logout() { + if (enternetCheck.isOnline(requireContext())) { initRetrofit() val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) CoroutineScope(Dispatchers.IO).launch { @@ -93,22 +108,45 @@ class SettingFragment : Fragment() { activity?.runOnUiThread { + //Фиксируем полученные данные - val visibleviewList = listProduct.body() - val visibleviewListCode = listProduct.isSuccessful() - //Если нету ошибок - if (visibleviewListCode) { - Toast(requireContext()).showCustomInfoToast(visibleviewList?.message.toString(), requireActivity()) - prefDoctorClear.clearToken(requireContext()) - activity?.supportFragmentManager?.beginTransaction() - ?.replace(R.id.CLMain, AuthFragment.newInstance()) - ?.commit() - - + val List = listProduct.body() + val Nice = listProduct.isSuccessful + val Code = listProduct.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List?.message.toString(), requireActivity()) + prefDoctorClear.clearToken(requireContext()) + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, AuthFragment.newInstance()) + ?.commit() + } + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthActivity::class.java) + activity?.finish() + startActivity(intetn) } } } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } } + //Инициализируем Retrofit private fun initRetrofit() { val interceptor = HttpLoggingInterceptor() @@ -120,7 +158,7 @@ class SettingFragment : Fragment() { .build() val retrofit = Retrofit.Builder() - .baseUrl("http://mobileapp.vmeda.org/api/") + .baseUrl("https://rehabilitation.vmeda.org/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -129,6 +167,8 @@ class SettingFragment : Fragment() { } + + companion object { fun newInstance() = SettingFragment() } diff --git a/app/src/main/java/com/example/doctor/Worker/MyWorker.kt b/app/src/main/java/com/example/doctor/Worker/MyWorker.kt new file mode 100644 index 0000000..f3975b1 --- /dev/null +++ b/app/src/main/java/com/example/doctor/Worker/MyWorker.kt @@ -0,0 +1,100 @@ +package com.example.doctor.Worker + +import android.annotation.SuppressLint +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.core.app.NotificationManagerCompat +import androidx.work.Worker +import androidx.work.WorkerParameters +import com.example.doctor.MainActivity +import com.example.doctor.R +import java.nio.file.attribute.AclEntry.Builder + +class MyWorker(context: Context, workerParameters: WorkerParameters): Worker(context,workerParameters) { + companion object{ + const val CHANNEL_ID="channel_id" + const val NOTIFICATION=1 + } + override fun doWork(): Result { + Log.d("doWork","doWork - error") + showNotification() + return Result.success()//Возврощаем результат + } + + @SuppressLint("UnspecifiedImmutableFlag", "MissingPermission", "ObsoleteSdkInt") + private fun showNotification(){ + val intent = Intent(applicationContext,MainActivity::class.java).apply{ + flags=Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } + + val pendingIntetn= PendingIntent.getActivity(applicationContext,0,intent,0) + + val notification = Notification.Builder(applicationContext, CHANNEL_ID) + .setSmallIcon(R.drawable.door) + .setContentTitle("new task") + .setContentText("Сообщение 1")//Сообщение + .setPriority(Notification.PRIORITY_MAX)//Приоритет + .setAutoCancel(true)//Время отмены + .setContentIntent(pendingIntetn)//Ожидание завершения + + + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){ + val channelName = "channel name" + val channelDescription = "channel Description" + val channelImportance=NotificationManager.IMPORTANCE_HIGH + + //Канал + val channel = NotificationChannel(CHANNEL_ID,channelName,channelImportance).apply { + description = channelDescription + } + + //Менеджер уведомлений + val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(channel)//Создаем канал с помошью менеджера уведомлений + + with(NotificationManagerCompat.from(applicationContext)){ + notify(NOTIFICATION,notification.build()) + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..64a46de --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..afab199 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in.xml b/app/src/main/res/anim/slide_in.xml new file mode 100644 index 0000000..8a4a29c --- /dev/null +++ b/app/src/main/res/anim/slide_in.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out.xml b/app/src/main/res/anim/slide_out.xml new file mode 100644 index 0000000..220ef3b --- /dev/null +++ b/app/src/main/res/anim/slide_out.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/add1.png b/app/src/main/res/drawable/add1.png new file mode 100644 index 0000000000000000000000000000000000000000..515d45e1ae14e231d6b596ae4f177295bbcf0a98 GIT binary patch literal 13553 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 Sbr2>80Hmp{N!>;7d;bTjD}J;9 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/loading.gif b/app/src/main/res/drawable/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..8e4be536021095fbe73b12f65f6ba1769a4e682c GIT binary patch literal 35499 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 - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_appeals.xml b/app/src/main/res/layout/activity_appeals.xml new file mode 100644 index 0000000..2563287 --- /dev/null +++ b/app/src/main/res/layout/activity_appeals.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_code429.xml b/app/src/main/res/layout/activity_code429.xml new file mode 100644 index 0000000..297b844 --- /dev/null +++ b/app/src/main/res/layout/activity_code429.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_code500.xml b/app/src/main/res/layout/activity_code500.xml new file mode 100644 index 0000000..0778283 --- /dev/null +++ b/app/src/main/res/layout/activity_code500.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_courses.xml b/app/src/main/res/layout/activity_courses.xml new file mode 100644 index 0000000..9cffebc --- /dev/null +++ b/app/src/main/res/layout/activity_courses.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_enternet.xml b/app/src/main/res/layout/activity_enternet.xml new file mode 100644 index 0000000..d2b6e93 --- /dev/null +++ b/app/src/main/res/layout/activity_enternet.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 48c1732..aa6ed3d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,4 +6,98 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradientv1" - tools:context=".MainActivity" /> \ No newline at end of file + tools:context=".MainActivity" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +