commit 0d298ff59786f843617eac291df783bb16d6ce45 Author: InsaneTrashRU Date: Fri Jun 6 16:23:30 2025 +0300 Upload diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..ab502a6 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Rehabilitation \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..7643783 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,123 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..3e1e7f3 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..d65afc5 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..2b8a50f --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7445cf5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..0312e8a --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,714 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..d2494aa --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,83 @@ +plugins { + id 'kotlin-kapt' + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'com.google.gms.google-services' +} + +android { + namespace 'com.example.rehabilitation' + compileSdk 33 + + defaultConfig { + applicationId "com.example.rehabilitation" + minSdk 28 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures{ + viewBinding true + } +} + +dependencies { + implementation 'androidx.room:room-ktx:2.5.2' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1" + + + implementation 'androidx.fragment:fragment-ktx:1.5.5' + + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.1.17' + implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'com.android.car.ui:car-ui-lib:2.0.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + + implementation 'org.apache.poi:poi:5.2.3' + + implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.2.3' + implementation group: 'org.apache.poi', name: 'poi', version: '5.2.3' + + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' + implementation 'com.kizitonwose.calendar:view:2.0.0' + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1" + + //Retrofit + implementation "com.squareup.retrofit2:retrofit:2.9.0" + implementation "com.squareup.retrofit2:converter-gson:2.9.0" + + //OkHttp + implementation "com.squareup.okhttp3:logging-interceptor:4.7.2" + implementation "com.squareup.okhttp3:okhttp:4.7.2" + + implementation 'com.squareup.picasso:picasso:2.71828' + + + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' + implementation 'com.kizitonwose.calendar:view:2.0.0' + +} \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..cb6c3b8 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,69 @@ +{ + "project_info": { + "project_number": "1027818028999", + "firebase_url": "https://rehabilitationtest-default-rtdb.europe-west1.firebasedatabase.app", + "project_id": "rehabilitationtest", + "storage_bucket": "rehabilitationtest.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1027818028999:android:a97724d7840d06fdada3e2", + "android_client_info": { + "package_name": "com.example.rehabilitation" + } + }, + "oauth_client": [ + { + "client_id": "1027818028999-a75qvvvqqb81ber25k6eeq1fqpr60oam.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAHvjzE2QIaIrCD9NOD1f_rShI4eXPyFVo" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1027818028999-a75qvvvqqb81ber25k6eeq1fqpr60oam.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1027818028999:android:1459bab345b4bf66ada3e2", + "android_client_info": { + "package_name": "com.example.user" + } + }, + "oauth_client": [ + { + "client_id": "1027818028999-a75qvvvqqb81ber25k6eeq1fqpr60oam.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAHvjzE2QIaIrCD9NOD1f_rShI4eXPyFVo" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1027818028999-a75qvvvqqb81ber25k6eeq1fqpr60oam.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/rehabilitation/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/rehabilitation/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..959605c --- /dev/null +++ b/app/src/androidTest/java/com/example/rehabilitation/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.rehabilitation + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.rehabilitation", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..63f9d44 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/ReabilitationV5.db b/app/src/main/assets/ReabilitationV5.db new file mode 100644 index 0000000..e69de29 diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..572be4f Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/example/admin/Toast.kt b/app/src/main/java/com/example/admin/Toast.kt new file mode 100644 index 0000000..cf61a0b --- /dev/null +++ b/app/src/main/java/com/example/admin/Toast.kt @@ -0,0 +1,177 @@ +package com.example.admin + +import android.app.Activity +import android.graphics.Color +import android.view.Gravity +import android.view.LayoutInflater +import android.widget.TextView +import android.widget.Toast +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.CustomToastBinding + +/** + * Расширение для класса Toast, добавляющее возможность отображения пользовательских уведомлений + * с кастомным дизайном и анимацией + */ +fun Toast.showCustomInfoToast(message: String, activity: Activity) { + // Создание кастомного layout для Toast + val layout = LayoutInflater.from(activity).inflate(R.layout.custom_toast, null) + + // Настройка текста сообщения + val text = layout.findViewById(R.id.text) + text.text = message + + // Настройка параметров Toast + this.apply { + setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + duration = Toast.LENGTH_LONG + view = layout + } + + // Отображение Toast + show() +} + +/** + * Расширение для класса Toast, добавляющее возможность отображения уведомлений об ошибках + * с красным фоном + */ +fun Toast.showErrorToast(message: String, activity: Activity) { + // Создание кастомного layout для Toast + val layout = LayoutInflater.from(activity).inflate(R.layout.custom_toast, null) + + // Настройка текста сообщения + val text = layout.findViewById(R.id.text) + text.text = message + text.setTextColor(Color.WHITE) + + // Установка красного фона + layout.setBackgroundColor(Color.RED) + + // Настройка параметров Toast + this.apply { + setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + duration = Toast.LENGTH_LONG + view = layout + } + + // Отображение Toast + show() +} + +/** + * Расширение для класса Toast, добавляющее возможность отображения уведомлений об успехе + * с зеленым фоном + */ +fun Toast.showSuccessToast(message: String, activity: Activity) { + // Создание кастомного layout для Toast + val layout = LayoutInflater.from(activity).inflate(R.layout.custom_toast, null) + + // Настройка текста сообщения + val text = layout.findViewById(R.id.text) + text.text = message + text.setTextColor(Color.WHITE) + + // Установка зеленого фона + layout.setBackgroundColor(Color.GREEN) + + // Настройка параметров Toast + this.apply { + setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + duration = Toast.LENGTH_LONG + view = layout + } + + // Отображение Toast + show() +} + +/** + * Объект для отображения кастомных уведомлений + * Расширяет стандартный Toast для отображения уведомлений с анимацией + */ +object Toast { + /** + * Отображение информационного уведомления + * @param context Контекст приложения + * @param message Текст уведомления + */ + fun showCustomInfoToast(context: Context, message: String) { + // Создание и настройка уведомления + val toast = Toast(context) + val binding = CustomToastBinding.inflate(context.layoutInflater) + + // Настройка внешнего вида + binding.root.setBackgroundResource(R.drawable.bg_info_toast) + binding.ivIcon.setImageResource(R.drawable.ic_info) + binding.tvMessage.text = message + + // Настройка параметров отображения + toast.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + toast.duration = Toast.LENGTH_LONG + toast.view = binding.root + + // Добавление анимации + toast.view?.alpha = 0f + toast.view?.animate()?.alpha(1f)?.setDuration(300)?.start() + + // Отображение уведомления + toast.show() + } + + /** + * Отображение уведомления об ошибке + * @param context Контекст приложения + * @param message Текст уведомления + */ + fun showErrorToast(context: Context, message: String) { + // Создание и настройка уведомления + val toast = Toast(context) + val binding = CustomToastBinding.inflate(context.layoutInflater) + + // Настройка внешнего вида + binding.root.setBackgroundResource(R.drawable.bg_error_toast) + binding.ivIcon.setImageResource(R.drawable.ic_error) + binding.tvMessage.text = message + + // Настройка параметров отображения + toast.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + toast.duration = Toast.LENGTH_LONG + toast.view = binding.root + + // Добавление анимации + toast.view?.alpha = 0f + toast.view?.animate()?.alpha(1f)?.setDuration(300)?.start() + + // Отображение уведомления + toast.show() + } + + /** + * Отображение уведомления об успешном выполнении + * @param context Контекст приложения + * @param message Текст уведомления + */ + fun showSuccessToast(context: Context, message: String) { + // Создание и настройка уведомления + val toast = Toast(context) + val binding = CustomToastBinding.inflate(context.layoutInflater) + + // Настройка внешнего вида + binding.root.setBackgroundResource(R.drawable.bg_success_toast) + binding.ivIcon.setImageResource(R.drawable.ic_success) + binding.tvMessage.text = message + + // Настройка параметров отображения + toast.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 100) + toast.duration = Toast.LENGTH_LONG + toast.view = binding.root + + // Добавление анимации + toast.view?.alpha = 0f + toast.view?.animate()?.alpha(1f)?.setDuration(300)?.start() + + // Отображение уведомления + toast.show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Adapter/VpAdapter.kt b/app/src/main/java/com/example/rehabilitation/Adapter/VpAdapter.kt new file mode 100644 index 0000000..e7a3c8e --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Adapter/VpAdapter.kt @@ -0,0 +1,17 @@ +package com.example.rehabilitation.Adapter + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class VpAdapter(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/rehabilitation/Appeals/AppealsFragment.kt b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsFragment.kt new file mode 100644 index 0000000..363a4ff --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsFragment.kt @@ -0,0 +1,245 @@ +package com.example.rehabilitation.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 androidx.fragment.app.FragmentActivity +import androidx.fragment.app.activityViewModels +import com.example.rehabilitation.Adapter.VpAdapter +import com.example.rehabilitation.Appeals.TabLayout.NewAppealsFragment +import com.example.rehabilitation.Appeals.TabLayout.OldAppealsFragment +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.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 val modelPatient: PatientViewModel by activityViewModels() + private lateinit var patientApi: PatientApi + private lateinit var timer: Timer + + val prefPatientConclusion = ConclusionPref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + private val tList = listOf( + "новые", + "обработанные", + ) + + //Список с фрагментами для переключения + private val flist = listOf( + NewAppealsFragment.newInstance(), + OldAppealsFragment.newInstance(), + ) + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentAppealsBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + init() + + binding.btnAddMessage.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLAppeals, CreateMessageFragment.newInstance())?.commit() + binding.ConstrainLayoutProductEdit.visibility = View.GONE + binding.CLAppeals.visibility = View.VISIBLE + } + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + + + private fun getOldAppeals() { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.GetAppealsPatientOld("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){ + modelPatient.appealsOldList.value = List.appeals_old + } + } + + } + getNewAppeals() + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } + + //Получение необработанных сообщений + private fun getNewAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.GetAppealsPatientNew("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){ + modelPatient.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(), AuthorizationActivity::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("http://mobileapp.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + //Функция подключения переключения + private fun init() = with(binding) { + val adapter = VpAdapter(activity as FragmentActivity, flist) + vpProduct.adapter = adapter + + //Переключения (связываем таблаяут(переключатель) с viewpager, чтобы переключать фрагменты) + TabLayoutMediator(tabLayoutProduct, vpProduct) { tab, pos -> + tab.text = + tList[pos]//tab - нажатая кнопка, pos - позиция кнопки, tList[pos] - передаем название по полученной позиции + }.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран + + //Изменения цвета в зависомости на каком из tabLayout вы находитесь + binding.tabLayoutProduct.setTabTextColors(getResources().getColor(R.color.black), + getResources().getColor(R.color.white)); + } + + companion object { + + fun newInstance() = AppealsFragment() + } + + + 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) { + activity?.runOnUiThread { + getOldAppeals() + + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/AppealsNewAdapter.kt b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsNewAdapter.kt new file mode 100644 index 0000000..b38ee1a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsNewAdapter.kt @@ -0,0 +1,118 @@ +package com.example.rehabilitation.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.rehabilitation.Appeals.TabLayout.Model.AppealsNewModel +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.ItemAppealsNewBinding + + +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_check_apeals: Listener, val listener_patient_apeals: Listener2) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = + ItemAppealsNewBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: AppealsNewModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + 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_check_apeals.onClickAppeals(it2) } + } + } + + @SuppressLint("SuspiciousIndentation") + fun bind(item: AppealsNewModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumber.text = item.number.toString()+"." + txtAppeals.text = item.text + txtLoginPatient.text = item.login + + + if (item.expand) { + txtAppeals.maxLines = 30 + } else { + txtAppeals.maxLines = 1 + } + + CardViewNew.setOnClickListener { + if (item.expand == false) { + txtAppeals.maxLines = 100 + + item.expand = true + } else { + txtAppeals.maxLines = 1 + item.expand = false + } + } + + + } + } + + + 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_check_apeals,listener_patient_apeals)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: AppealsNewModel, + newItem: AppealsNewModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: AppealsNewModel, + newItem: AppealsNewModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + + interface Listener { + fun onClickAppeals(item: AppealsNewModel) + } + + + interface Listener2 { + fun onClickAppealsPatient(item: AppealsNewModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/AppealsOldAdapter.kt b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsOldAdapter.kt new file mode 100644 index 0000000..64cb0be --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/AppealsOldAdapter.kt @@ -0,0 +1,110 @@ +package com.example.rehabilitation.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.rehabilitation.Appeals.TabLayout.Model.AppealsOldModel +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.ItemAppealsOldBinding + + +class AppealsOldAdapter(val listener_zakaz: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_zakaz: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = + ItemAppealsOldBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: AppealsOldModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + itemView.setEnabled(false) + itemTemp?.let { it1 -> listener_zakaz.onClickAppeals(it1) } + } + } + + @SuppressLint("SuspiciousIndentation") + fun bind(item: AppealsOldModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumber.text = item.number.toString()+"." + txtAppeals.text = item.text + txtLoginPatient.text = item.login + + if (item.expand) { + binding.txtAppeals.maxLines = 100 + + } else { + binding.txtAppeals.maxLines = 1 + + } + + binding.CardViewOld.setOnClickListener { + if (item.expand == false) { + binding.txtAppeals.maxLines = 100 + item.expand = true + } else { + binding.txtAppeals.maxLines = 1 + item.expand = false + } + } + + } + + + } + + + 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 + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: AppealsOldModel, + newItem: AppealsOldModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: AppealsOldModel, + newItem: AppealsOldModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickAppeals(item: AppealsOldModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/CreateMessageFragment.kt b/app/src/main/java/com/example/rehabilitation/Appeals/CreateMessageFragment.kt new file mode 100644 index 0000000..3d5f51d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/CreateMessageFragment.kt @@ -0,0 +1,153 @@ +package com.example.rehabilitation.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.Toast +import androidx.fragment.app.activityViewModels +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.Pref.ClearPref +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.databinding.FragmentCreateMessageBinding +import com.example.rehabilitation.model_adapter.DataModel +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 CreateMessageFragment : Fragment() { + private lateinit var binding: FragmentCreateMessageBinding + private val dataModel: DataModel by activityViewModels()//Для передачи данных + private lateinit var patientApi: PatientApi + val prefDoctorConclusion = ConclusionPref() + val prefDoctorClear = ClearPref() + + //Класс проверки интеренета + 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) + + + binding.btnAddMessagePatient.setOnClickListener{ + val text = binding.edTextMessagePatient.text.toString() + if(text!=""){ + AddMessageDoctor() + } + else{ + Toast(requireContext()).showCustomInfoToast("Поле пустое", requireActivity()) + + } + } + + binding.btnExit.setOnClickListener{ + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, AppealsFragment.newInstance()) + //?.addToBackStack(null) + ?.commit() + } + } + + + //Отправка сообщения + fun AddMessageDoctor() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefDoctorConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val message = patientApi.AddMessagePatient("Bearer $Tokens",binding.edTextMessagePatient.text.toString()) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = message.body() + val Nice = message.isSuccessful + val Code = message.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 (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + companion object { + + fun newInstance() = CreateMessageFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewListModel.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewListModel.kt new file mode 100644 index 0000000..323469a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewListModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Appeals.TabLayout.Model + +data class AppealsNewListModel( + val appeals_new: List +) + diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewModel.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewModel.kt new file mode 100644 index 0000000..6777bd8 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsNewModel.kt @@ -0,0 +1,16 @@ +package com.example.rehabilitation.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/rehabilitation/Appeals/TabLayout/Model/AppealsOldListModel.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsOldListModel.kt new file mode 100644 index 0000000..2a0bd3d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsOldListModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Appeals.TabLayout.Model + +data class AppealsOldListModel( + val appeals_old: List +) + diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsOldModel.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsOldModel.kt new file mode 100644 index 0000000..4980560 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/Model/AppealsOldModel.kt @@ -0,0 +1,16 @@ +package com.example.rehabilitation.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/rehabilitation/Appeals/TabLayout/NewAppealsFragment.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/NewAppealsFragment.kt new file mode 100644 index 0000000..5ecbe32 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/NewAppealsFragment.kt @@ -0,0 +1,284 @@ +package com.example.rehabilitation.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.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Appeals.AppealsNewAdapter +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsNewModel +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.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, AppealsNewAdapter.Listener2 { + private lateinit var binding: FragmentNewAppealsBinding + private val modelPatient: PatientViewModel by activityViewModels() + lateinit var adapter: AppealsNewAdapter + private lateinit var patientApi: PatientApi + val prefPatientConclusion = ConclusionPref() + + //Список обрашений новых + var appealsNewList: List? = null + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentNewAppealsBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initRcViewAppeals() + patientListCurrent() + modelPatient.appealsNewList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(appealsNewList != it){ + appealsNewList = it + adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + } + } + + getNewAppeals() + } + + //Получение необработанных сообщений + private fun getNewAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.GetAppealsPatientNew("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){ + binding.txtNull.visibility = View.GONE + modelPatient.appealsNewList.value = List.appeals_new + } + else{ + binding.txtNull.visibility = View.VISIBLE + } + } + 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(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + private fun getOldAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.GetAppealsPatientOld("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){ + // binding.txtNull.visibility = View.GONE + modelPatient.appealsOldList.value = List.appeals_old + } + else{ + // binding.txtNull.visibility = View.VISIBLE + } + }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(), AuthorizationActivity::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 = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.UpdateMessagePatient("Bearer $Tokens",id) + 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(), AuthorizationActivity::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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + //Вывод прогресса на один день + private fun patientListCurrent() = with(binding) { +// model.appealsAllCurrent.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment +// +// } + + } + + //Инициализация списка + private fun initRcViewAppeals() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(),1)//По вертикали будет выводить по умолчанию + adapter = AppealsNewAdapter(this@NewAppealsFragment,this@NewAppealsFragment) + rcView.adapter = adapter + } + + companion object { + + fun newInstance() = NewAppealsFragment() + } + + override fun onClickAppeals(item: AppealsNewModel) { + addCheckAppeals(item.id,item.id_patient) + } + + override fun onClickAppealsPatient(item: AppealsNewModel) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/OldAppealsFragment.kt b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/OldAppealsFragment.kt new file mode 100644 index 0000000..ddddd57 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Appeals/TabLayout/OldAppealsFragment.kt @@ -0,0 +1,168 @@ +package com.example.rehabilitation.Appeals.TabLayout + +import android.annotation.SuppressLint +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.rehabilitation.Appeals.AppealsOldAdapter +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsNewModel +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsOldModel +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.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 + + +class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener { + private lateinit var binding: FragmentOldAppealsBinding + private val model: PatientViewModel by activityViewModels() + lateinit var adapter: AppealsOldAdapter + private lateinit var patientApi: PatientApi + val prefPatientConclusion = ConclusionPref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + //Список обрашений старых + var appealsOldList: List? = null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentOldAppealsBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initRcViewAppeals() + appealsAllCurrent() + model.appealsOldList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(appealsOldList != it){ + appealsOldList = it + adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + } + } + + getOldAppeals() + } + + @SuppressLint("SuspiciousIndentation") + private fun getOldAppeals() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listAppeals = patientApi.GetAppealsPatientOld("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){ + binding.txtNull.visibility = View.GONE + model.appealsOldList.value = List.appeals_old + } + else{ + binding.txtNull.visibility = View.VISIBLE + } + }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(), AuthorizationActivity::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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + //Вывод прогресса на один день + private fun appealsAllCurrent() = with(binding) { +// model.appealsAllCurrent.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment +// +// } + + } + + //Инициализация списка + private fun initRcViewAppeals() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(),1)//По вертикали будет выводить по умолчанию + adapter = AppealsOldAdapter(this@OldAppealsFragment) + rcView.adapter = adapter + } + companion object { + + fun newInstance() = OldAppealsFragment() + } + + override fun onClickAppeals(item: AppealsOldModel) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Auth/AuthFragment.kt b/app/src/main/java/com/example/rehabilitation/Auth/AuthFragment.kt new file mode 100644 index 0000000..22b18a4 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/AuthFragment.kt @@ -0,0 +1,175 @@ +package com.example.rehabilitation.Auth + +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 com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Auth.Model.AuthModel +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.MainActivity +import com.example.rehabilitation.databinding.FragmentAuthBinding +import com.example.rehabilitation.UserPatientToken +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.MainFragment +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ClearPref +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Pref.SavePref +import com.example.rehabilitation.Questionnaire.Model.BeforeQuestionnaireModel +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Sport.SceduleFragment +import com.example.sqlitework.dip.MainViewModel +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 AuthFragment : Fragment() { + // Привязка к layout файлу + private lateinit var binding: FragmentAuthBinding + // ViewModel для работы с основными данными + private val model: MainViewModel by activityViewModels() + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + // ViewModel для работы с данными пациента + private val PatientVewModel: PatientViewModel by activityViewModels() + + // Токен авторизации + private var Token = "" + // Классы для работы с настройками + val prefPatientSave = SavePref() + val prefPatientConclusion = ConclusionPref() + val prefPatientClear = ClearPref() + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentAuthBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.txtError.text = "" + Token = prefPatientConclusion.conclusionToken(requireContext()) + + // Обработчик нажатия кнопки авторизации + binding.buttonAuthorizationPatient.setOnClickListener { + val login = binding.editTextLoginPatient.text.toString() + val password = binding.editTextPasswordPatient.text.toString() + if (login != "" || password != "") { + AuthorizationPatient( + AuthModel( + login, + password, + ) + ) + } else { + Toast(requireContext()).showCustomInfoToast( + "Не все поля заполнены", + requireActivity() + ) + } + } + } + + /** + * Инициализация подключения к серверу + * Настройка Retrofit для работы с API + */ + private fun initRetrofit() { + // Настройка логирования + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + // Создание HTTP клиента + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + // Инициализация Retrofit + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + patientApi = retrofit.create(PatientApi::class.java) + } + + /** + * Авторизация пациента + * @param authModel Модель с данными для авторизации (логин и пароль) + */ + private fun AuthorizationPatient(authModel: AuthModel) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + CoroutineScope(Dispatchers.IO).launch { + val response = patientApi.LoginPatient(authModel) + requireActivity().runOnUiThread { + // Обработка ответа от сервера + val List = response.body() + val Nice = response.isSuccessful + val Code = response.code() + + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(requireContext(), Code429Activity::class.java) + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + if (List != null) { + // Сохранение токена и переход на главный экран + prefPatientSave.saveToken(requireContext(), List.token) + val intetn = Intent(requireContext(), MainActivity::class.java) + startActivity(intetn) + } else { + Toast(requireContext()).showCustomInfoToast( + "Такого пользователя нету", + requireActivity() + ) + } + } + } + } + } + } + } else { + // Нет интернет-соединения + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + override fun onDestroy() { + super.onDestroy() + activity?.finish() + } + + companion object { + fun newInstance() = AuthFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Auth/AuthorizationActivity.kt b/app/src/main/java/com/example/rehabilitation/Auth/AuthorizationActivity.kt new file mode 100644 index 0000000..5695cfe --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/AuthorizationActivity.kt @@ -0,0 +1,30 @@ +package com.example.rehabilitation.Auth + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.ActivityAuthorizationBinding + + +class AuthorizationActivity : AppCompatActivity() { + private lateinit var binding: ActivityAuthorizationBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + + binding = ActivityAuthorizationBinding.inflate(layoutInflater) + setContentView(binding.root) + + //Вывод фрагмента на активити при первоначальной загрузке + supportFragmentManager.beginTransaction() + .replace(R.id.CLAuth, AuthFragment.newInstance()) + .commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем + + + } + + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Auth/Model/AuthModel.kt b/app/src/main/java/com/example/rehabilitation/Auth/Model/AuthModel.kt new file mode 100644 index 0000000..8e76370 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/Model/AuthModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.Auth.Model + +data class AuthModel( + val login: String, + val password: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Auth/Model/CheckTokenModel.kt b/app/src/main/java/com/example/rehabilitation/Auth/Model/CheckTokenModel.kt new file mode 100644 index 0000000..fcd6770 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/Model/CheckTokenModel.kt @@ -0,0 +1,5 @@ +package com.example.rehabilitation.Auth.Model + +data class CheckTokenModel( + val status:String, +) diff --git a/app/src/main/java/com/example/rehabilitation/Auth/Model/PatientModel.kt b/app/src/main/java/com/example/rehabilitation/Auth/Model/PatientModel.kt new file mode 100644 index 0000000..4d61dca --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/Model/PatientModel.kt @@ -0,0 +1,14 @@ +package com.example.rehabilitation.Auth.Model + +data class PatientModel( + val id: String, + val name:String, + val surname:String, + val patronymic:String, + val diagnosis:String, + val number_of_courses:String, + //val email:String, + val login:String, + val password:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Auth/Model/UserModel.kt b/app/src/main/java/com/example/rehabilitation/Auth/Model/UserModel.kt new file mode 100644 index 0000000..20619d3 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Auth/Model/UserModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.Auth.Model + +data class UserModel( + val id: String, + val token: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/AuthFragment.kt b/app/src/main/java/com/example/rehabilitation/AuthFragment.kt new file mode 100644 index 0000000..8da8a9d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/AuthFragment.kt @@ -0,0 +1,130 @@ +package com.example.rehabilitation + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import androidx.navigation.fragment.findNavController +import com.example.rehabilitation.databinding.FragmentAuthBinding +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Toast.showErrorToast +import com.example.rehabilitation.Toast.showSuccessToast + +/** + * Фрагмент авторизации пользователя + * Отвечает за вход в систему и сохранение данных авторизации + */ +class AuthFragment : Fragment() { + // ViewBinding для доступа к элементам интерфейса + private var _binding: FragmentAuthBinding? = null + private val binding get() = _binding!! + + // ViewModel для работы с данными авторизации + private lateinit var viewModel: AuthViewModel + + // Класс для работы с настройками + private lateinit var conclusionPref: ConclusionPref + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentAuthBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Инициализация ViewModel и настроек + viewModel = ViewModelProvider(this)[AuthViewModel::class.java] + conclusionPref = ConclusionPref() + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями данных + observeViewModel() + } + + /** + * Настройка обработчиков нажатий + */ + private fun setupClickListeners() { + // Обработка нажатия кнопки входа + binding.btnLogin.setOnClickListener { + val login = binding.etLogin.text.toString() + val password = binding.etPassword.text.toString() + + if (validateInput(login, password)) { + viewModel.login(login, password) + } + } + + // Обработка нажатия кнопки регистрации + binding.btnRegister.setOnClickListener { + findNavController().navigate(R.id.action_authFragment_to_registerFragment) + } + } + + /** + * Проверка введенных данных + * @param login Логин пользователя + * @param password Пароль пользователя + * @return true если данные валидны, false в противном случае + */ + private fun validateInput(login: String, password: String): Boolean { + if (login.isEmpty()) { + showErrorToast(requireContext(), "Введите логин") + return false + } + if (password.isEmpty()) { + showErrorToast(requireContext(), "Введите пароль") + return false + } + return true + } + + /** + * Наблюдение за изменениями данных в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за статусом загрузки + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE + binding.btnLogin.isEnabled = !isLoading + } + + // Наблюдение за результатом авторизации + viewModel.authResult.observe(viewLifecycleOwner) { result -> + result?.let { + if (it.success) { + // Сохранение данных авторизации + conclusionPref.saveToken(requireContext(), it.token) + conclusionPref.saveUserId(requireContext(), it.userId) + conclusionPref.saveLoginStatus(requireContext(), true) + + showSuccessToast(requireContext(), "Успешный вход") + findNavController().navigate(R.id.action_authFragment_to_mainFragment) + } else { + showErrorToast(requireContext(), it.message) + } + } + } + + // Наблюдение за ошибками + viewModel.error.observe(viewLifecycleOwner) { error -> + error?.let { + showErrorToast(requireContext(), it) + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Calendare/CalendarFragment.kt b/app/src/main/java/com/example/rehabilitation/Calendare/CalendarFragment.kt new file mode 100644 index 0000000..612e5dc --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Calendare/CalendarFragment.kt @@ -0,0 +1,251 @@ +package com.example.rehabilitation.Calendare + +import android.annotation.SuppressLint +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.GridLayoutManager +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Sport.DayAdapter +import com.example.rehabilitation.databinding.FragmentCalendarBinding +import com.example.sqlitework.dip.MainViewModel +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.time.LocalDate +import java.util.Timer +import kotlin.concurrent.fixedRateTimer +import kotlin.concurrent.timerTask + + +class CalendarFragment : Fragment(),CalendareListAdapter.Listener { + private lateinit var binding: FragmentCalendarBinding + lateinit var adapterCalendare: CalendareListAdapter + private val modelPatient: PatientViewModel by activityViewModels()//Инициализировали класс + private lateinit var patientApi: PatientApi + private lateinit var timer: Timer + + val prefPatientConclusion = ConclusionPref() + + + + //Календарь + var listCalendare:List? = null + + @SuppressLint("NewApi") + + //Загрузка данных для календаря + var calendare = false + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + var infoVisibleCalendare = false + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCalendarBinding.inflate(layoutInflater, container, false) + return binding.root + } + + @SuppressLint("NewApi") + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + + if(isAdded) { + visibleLoad() + initRcView() + initRetrofit() + APIliveCountCalendareCurrent() + + + modelPatient.calendareList.observe(viewLifecycleOwner){ + if(listCalendare != it){ + listCalendare = it + adapterCalendare.submitList(it) + } + visibleCalendare() + } + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + // Устанавливаем обработчик нажатий на корневой контейнер + binding.root.setOnTouchListener { _, _ -> + if (infoVisibleCalendare) { + infoVisibleCalendare = false + binding.CVInfoCalendare.visibility = View.GONE + } + false // Событие передаётся дальше + } + + // Открытие и закрытие подсказки по кнопке + binding.btnInfoCalendare.setOnClickListener { + if (!infoVisibleCalendare) { + infoVisibleCalendare = true + binding.CVInfoCalendare.visibility = View.VISIBLE + } else { + infoVisibleCalendare = false + binding.CVInfoCalendare.visibility = View.GONE + } + } + } + + + + fun visibleCalendare(){ + binding.CLCalendare.visibility = View.VISIBLE + binding.CLLoad.visibility = View.GONE + } + + fun visibleLoad(){ + binding.CLCalendare.visibility = View.GONE + binding.CLLoad.visibility = View.VISIBLE + + } + + + + + //Инициализация списка + private fun initRcView() = with(binding) { + rcView.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterCalendare = CalendareListAdapter(this@CalendarFragment) + rcView.adapter = adapterCalendare + //binding.rcVIewDayList.smoothScrollToPosition(0); + } + + + + //Инициализация запроса + 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() + patientApi = retrofit.create(PatientApi::class.java)//Экземпляр + } + + //Функция получения данных для заполнения календаря + private fun APIliveCountCalendareCurrent() { + if (enternetCheck.isOnline(requireContext())) { + + initRetrofit() + + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val Calendare = patientApi.GetCalendare("Bearer $Tokens") + + activity?.runOnUiThread { + + + //Фиксируем полученные данные + val List = Calendare.body() + val Nice = Calendare.isSuccessful + val Code = Calendare.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + Log.i("CalendareList_calendare_day", List.calendare_day.toString()) + modelPatient.calendareList.value = List.calendare_day + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + + + + + + + companion object { + + fun newInstance() = CalendarFragment() + } + + override fun onClickCalendare(item: CalendareModel) { + + } + + + 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) { + activity?.runOnUiThread { + APIliveCountCalendareCurrent() + } + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListAdapter.kt b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListAdapter.kt new file mode 100644 index 0000000..94c957c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListAdapter.kt @@ -0,0 +1,123 @@ +package com.example.rehabilitation.Calendare + +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.rehabilitation.R +import com.example.rehabilitation.databinding.ItemCalendareBinding +import java.time.LocalDate + + +class CalendareListAdapter(val listener: Listener) : + ListAdapter( + Comparator() + ) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener: Listener) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ItemCalendareBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: CalendareModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + itemTemp?.let { it1 -> listener.onClickCalendare(it1) } + + } + } + + @SuppressLint("SuspiciousIndentation", "SetTextI18n") + fun bind(item: CalendareModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtDay.text = item.day + val date1 = item.date[8]; + val date2 = item.date[9]; + val date3 = item.date[5]; + val date4 = item.date[6]; + val date5 = item.date[0]; + val date6 = item.date[1]; + val date7 = item.date[2]; + val date8 = item.date[3]; + txtDate.text = date1+""+date2+"."+date3+""+date4+"."+date5+""+date6+""+date7+""+date8 + + + + + if(item.block != null){ + binding.CVBlock.setCardBackgroundColor(Color.parseColor("#FF0000")) + } + else if(item.pause != null){ + binding.CVPause.setCardBackgroundColor(Color.parseColor("#FFA355")) + } + if(item.id_after_questionnaire != null){ + binding.CVDay.setCardBackgroundColor(Color.parseColor("#7FE668")) + } + else{ + if(item.block == null){ + if(item.date >= LocalDate.now().toString()){ + binding.CVDay.setCardBackgroundColor(Color.parseColor("#55B6FF")) + } + else{ + binding.CVDay.setCardBackgroundColor(Color.parseColor("#9C9C9C")) + + } + } + } + } + + + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_calendare, 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: CalendareModel, + newItem: CalendareModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: CalendareModel, + newItem: CalendareModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickCalendare(item: CalendareModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListModel.kt b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListModel.kt new file mode 100644 index 0000000..70937c9 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareListModel.kt @@ -0,0 +1,5 @@ +package com.example.rehabilitation.Calendare + +data class CalendareListModel( + val calendare_day: List +) diff --git a/app/src/main/java/com/example/rehabilitation/Calendare/CalendareModel.kt b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareModel.kt new file mode 100644 index 0000000..346af85 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Calendare/CalendareModel.kt @@ -0,0 +1,19 @@ +package com.example.rehabilitation.Calendare + +data class CalendareModel( + val id: Int, + val id_patient : Int, + val day: String, + val date: String, + val count_workout_max:Int, + val count_workout_make: Int, + val id_sets_of_sports_activities : Int, + val article_sport_for_day: String, + val id_sport_patient :Int, + val block: String, + val pause: String, + val id_before_questionnaire : String, + val id_after_questionnaire : String, + val created_at : String, + val updated_at : String, +) diff --git a/app/src/main/java/com/example/rehabilitation/Code429Activity.kt b/app/src/main/java/com/example/rehabilitation/Code429Activity.kt new file mode 100644 index 0000000..d3cd4b6 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Code429Activity.kt @@ -0,0 +1,68 @@ +package com.example.rehabilitation + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityCode429Binding + +/** + * Активность, отображаемая при получении ошибки 429 (Too Many Requests) + * Информирует пользователя о превышении лимита запросов и предлагает повторить попытку позже + */ +class Code429Activity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityCode429Binding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками (в миллисекундах) + private val CHECK_DELAY = 5000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode429Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки + startRetryCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + finish() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки возможности повторного запроса + */ + private fun startRetryCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + // По истечении задержки возвращаемся к предыдущей активности + finish() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Code500Activity.kt b/app/src/main/java/com/example/rehabilitation/Code500Activity.kt new file mode 100644 index 0000000..8ac5da5 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Code500Activity.kt @@ -0,0 +1,68 @@ +package com.example.rehabilitation + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityCode500Binding + +/** + * Активность, отображаемая при получении ошибки 500 (Internal Server Error) + * Информирует пользователя о внутренней ошибке сервера и предлагает повторить попытку позже + */ +class Code500Activity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityCode500Binding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками (в миллисекундах) + private val CHECK_DELAY = 5000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode500Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки + startRetryCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + finish() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки возможности повторного запроса + */ + private fun startRetryCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + // По истечении задержки возвращаемся к предыдущей активности + finish() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/CodeError/Code429Activity.kt b/app/src/main/java/com/example/rehabilitation/CodeError/Code429Activity.kt new file mode 100644 index 0000000..59a0f51 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/CodeError/Code429Activity.kt @@ -0,0 +1,227 @@ +package com.example.rehabilitation.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.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.MainActivity +import com.example.rehabilitation.Pref.ClearPref +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Pref.SavePref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.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 +import android.widget.Toast +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.R +import android.os.Handler +import android.os.Looper +import android.view.View + +/** + * Активность, отображаемая при превышении лимита запросов к серверу (код ошибки 429) + * Предоставляет пользователю информацию о проблеме и возможность повторить попытку + */ +class Code429Activity : AppCompatActivity() { + // ViewBinding для доступа к элементам интерфейса + private lateinit var binding: ActivityCode429Binding + private lateinit var patientApi: PatientApi + private lateinit var timer: Timer + + // Обработчик для обновления таймера + private val handler = Handler(Looper.getMainLooper()) + + // Время ожидания в секундах + private var remainingTime = 30 + + // Runnable для обновления таймера + private val updateTimerRunnable = object : Runnable { + override fun run() { + updateTimer() + } + } + + val prefPatientConclusion = ConclusionPref() + val prefPatientClear = ClearPref() + val prefPatientSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + var checkClose = false + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode429Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск таймера + startTimer() + } + + /** + * Настройка обработчиков нажатий + */ + private fun setupClickListeners() { + // Обработка нажатия кнопки повтора + binding.btnRetry.setOnClickListener { + // Возвращаемся на главный экран + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + finish() + } + + // Обработка нажатия кнопки выхода + binding.btnExit.setOnClickListener { + // Закрываем приложение + finishAffinity() + } + } + + override fun onBackPressed() { + // Отключаем стандартное поведение кнопки "Назад" + // Пользователь должен явно выбрать действие через кнопки на экране + Toast(this).showCustomInfoToast( + "Пожалуйста, используйте кнопки на экране", + this + ) + } + + @SuppressLint("SuspiciousIndentation") + fun CheckToken()=with(binding){ + if (enternetCheck.isOnline(this@Code429Activity)) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(this@Code429Activity) + CoroutineScope(Dispatchers.IO).launch { + val list = patientApi.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, AuthorizationActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } else { + + val intetn = Intent(this@Code429Activity, 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() + + patientApi = retrofit.create(PatientApi::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() + } + } + + } + + /** + * Запуск таймера обратного отсчета + */ + private fun startTimer() { + binding.apply { + tvTimer.visibility = View.VISIBLE + btnRetry.isEnabled = false + } + + handler.post(updateTimerRunnable) + } + + /** + * Обновление таймера + */ + private fun updateTimer() { + if (remainingTime > 0) { + binding.tvTimer.text = getString(R.string.retry_after_seconds, remainingTime) + remainingTime-- + handler.postDelayed(updateTimerRunnable, 1000) + } else { + binding.apply { + tvTimer.visibility = View.GONE + btnRetry.isEnabled = true + } + } + } + + override fun onDestroy() { + super.onDestroy() + // Остановка таймера при уничтожении активности + handler.removeCallbacks(updateTimerRunnable) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/CodeError/Code500Activity.kt b/app/src/main/java/com/example/rehabilitation/CodeError/Code500Activity.kt new file mode 100644 index 0000000..4119683 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/CodeError/Code500Activity.kt @@ -0,0 +1,235 @@ +package com.example.rehabilitation.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.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.MainActivity +import com.example.rehabilitation.Pref.ClearPref +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Pref.SavePref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.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 +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.R +import com.example.rehabilitation.Toast.showErrorToast +import com.example.rehabilitation.Toast.showSuccessToast + +/** + * Активность, отображаемая при ошибке сервера (HTTP 500) + * Показывает пользователю информацию об ошибке и предоставляет варианты действий + */ +class Code500Activity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityCode500Binding + private lateinit var patientApi: PatientApi + private lateinit var timer: Timer + + val prefPatientConclusion = ConclusionPref() + val prefPatientClear = ClearPref() + val prefPatientSave = SavePref() + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + + var checkClose = false + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode500Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Отображение информации об ошибке + showErrorInfo() + + binding.apply { + val timer = object: CountDownTimer(30000, 1000) { + override fun onTick(millisUntilFinished: Long) { + + } + + override fun onFinish() { + val intetn = Intent(this@Code500Activity, AuthorizationActivity::class.java) + finish() + startActivity(intetn) + } + } + timer.start() + } + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.btnRetry.setOnClickListener { + retryOperation() + } + + // Обработчик нажатия на кнопку "Выход" + binding.btnExit.setOnClickListener { + finishAffinity() + } + + // Обработчик нажатия на кнопку "Отправить отзыв" + binding.btnFeedback.setOnClickListener { + sendFeedback() + } + } + + /** + * Отображение информации об ошибке + */ + private fun showErrorInfo() { + binding.apply { + // Установка иконки ошибки + ivError.setImageResource(R.drawable.ic_server_error) + + // Установка заголовка + tvTitle.text = getString(R.string.server_error_title) + + // Установка описания ошибки + tvDescription.text = getString(R.string.server_error_description) + + // Установка рекомендаций + tvRecommendation.text = getString(R.string.server_error_recommendation) + } + } + + /** + * Повторная попытка выполнения операции + */ + private fun retryOperation() { + binding.apply { + // Показ индикатора загрузки + progressBar.visibility = View.VISIBLE + + // Отключение кнопки повтора + btnRetry.isEnabled = false + + // TODO: Реализовать повторную попытку выполнения операции + + // Скрытие индикатора загрузки + progressBar.visibility = View.GONE + + // Включение кнопки повтора + btnRetry.isEnabled = true + } + } + + /** + * Отправка отзыва об ошибке + */ + private fun sendFeedback() { + // TODO: Реализовать отправку отзыва + showSuccessToast(this, "Спасибо за обратную связь!") + } + + override fun onBackPressed() { + // Отключаем стандартное поведение кнопки "Назад" + // Пользователь должен явно выбрать действие через кнопки на экране + Toast(this).showCustomInfoToast( + "Пожалуйста, используйте кнопки на экране", + this + ) + } + + @SuppressLint("SuspiciousIndentation") + fun CheckToken()=with(binding){ + if (enternetCheck.isOnline(this@Code500Activity)) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(this@Code500Activity) + CoroutineScope(Dispatchers.IO).launch { + val list = patientApi.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, AuthorizationActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(this@Code500Activity, 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() + + patientApi = retrofit.create(PatientApi::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@Code500Activity.runOnUiThread { + CheckToken() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Enternet/EnternetActivity.kt b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetActivity.kt new file mode 100644 index 0000000..9d0f7ed --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetActivity.kt @@ -0,0 +1,76 @@ +package com.example.rehabilitation.Enternet + +import android.content.Intent +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.MainActivity +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.ActivityEnternetBinding + +/** + * Активность, отображаемая при отсутствии интернет-соединения + * Предоставляет пользователю информацию о проблеме и возможность повторить подключение + */ +class EnternetActivity : AppCompatActivity() { + // Привязка к layout файлу + private lateinit var binding: ActivityEnternetBinding + // Класс для проверки интернет-соединения + private val enternetCheck = EnternetCheck() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityEnternetBinding.inflate(layoutInflater) + setContentView(binding.root) + + // Инициализация обработчиков кнопок + initButtons() + } + + /** + * Инициализация обработчиков кнопок + */ + private fun initButtons() { + // Обработчик кнопки повтора подключения + binding.btnRetry.setOnClickListener { + if (enternetCheck.isOnline(this)) { + // Если соединение восстановлено, возвращаемся на главный экран + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + finish() + } else { + // Если соединение все еще отсутствует, показываем сообщение + Toast(this).showCustomInfoToast( + "Проверьте подключение к интернету", + this + ) + } + } + + // Обработчик кнопки выхода + binding.btnExit.setOnClickListener { + // Закрываем приложение + finishAffinity() + } + } + + override fun onResume() { + super.onResume() + // Проверяем состояние соединения при возобновлении активности + checkConnection() + } + + /** + * Проверка состояния интернет-соединения + */ + private fun checkConnection() { + if (enternetCheck.isOnline(this)) { + // Если соединение восстановлено, возвращаемся на главный экран + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + finish() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Enternet/EnternetCheck.kt b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetCheck.kt new file mode 100644 index 0000000..ca25b71 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetCheck.kt @@ -0,0 +1,78 @@ +package com.example.rehabilitation.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 + } + + /** + * Проверяет тип активного интернет-соединения + * @param context Контекст приложения + * @return Строка с описанием типа подключения или "Нет подключения" + */ + fun getConnectionType(context: Context): String { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return "Нет подключения" + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return "Нет подключения" + + return when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> "Wi-Fi" + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "Мобильная сеть" + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> "Ethernet" + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> "Bluetooth" + else -> "Неизвестное подключение" + } + } + + /** + * Проверяет качество интернет-соединения + * @param context Контекст приложения + * @return true если соединение стабильное, false в противном случае + */ + fun isConnectionStable(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && + capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Enternet/EnternetFragment.kt b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetFragment.kt new file mode 100644 index 0000000..29f09b7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Enternet/EnternetFragment.kt @@ -0,0 +1,38 @@ +package com.example.rehabilitation.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.rehabilitation.MainActivity +import com.example.rehabilitation.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/rehabilitation/EnternetActivity.kt b/app/src/main/java/com/example/rehabilitation/EnternetActivity.kt new file mode 100644 index 0000000..90c94b8 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/EnternetActivity.kt @@ -0,0 +1,82 @@ +package com.example.rehabilitation + +import android.content.Intent +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityEnternetBinding +import com.example.rehabilitation.EnternetCheck.ConnectionType +import com.example.rehabilitation.EnternetCheck.getConnectionType +import com.example.rehabilitation.EnternetCheck.isInternetAvailable + +/** + * Активность, отображаемая при отсутствии подключения к интернету + * Предоставляет пользователю информацию о проблеме и возможность повторить проверку + */ +class EnternetActivity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityEnternetBinding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками подключения (в миллисекундах) + private val CHECK_DELAY = 2000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityEnternetBinding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки подключения + startConnectionCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + checkConnection() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки подключения + */ + private fun startConnectionCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + checkConnection() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + /** + * Проверка подключения к интернету + */ + private fun checkConnection() { + if (EnternetCheck.isInternetAvailable(this)) { + // Если подключение восстановлено, возвращаемся к предыдущей активности + finish() + } + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/EnternetCheck.kt b/app/src/main/java/com/example/rehabilitation/EnternetCheck.kt new file mode 100644 index 0000000..c89461c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/EnternetCheck.kt @@ -0,0 +1,90 @@ +package com.example.rehabilitation + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build + +/** + * Объект для проверки состояния сетевого подключения + * Предоставляет методы для проверки доступности интернета и типа подключения + */ +object EnternetCheck { + /** + * Проверка наличия подключения к интернету + * @param context Контекст приложения + * @return true, если есть активное подключение к интернету, false в противном случае + */ + fun isInternetAvailable(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && + capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + } + + /** + * Получение типа подключения к интернету + * @param context Контекст приложения + * @return Тип подключения (WiFi, Cellular, None) + */ + fun getConnectionType(context: Context): ConnectionType { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val network = connectivityManager.activeNetwork ?: return ConnectionType.NONE + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return ConnectionType.NONE + + return when { + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> ConnectionType.WIFI + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> ConnectionType.CELLULAR + else -> ConnectionType.NONE + } + } else { + @Suppress("DEPRECATION") + val networkInfo = connectivityManager.activeNetworkInfo + @Suppress("DEPRECATION") + return when (networkInfo?.type) { + ConnectivityManager.TYPE_WIFI -> ConnectionType.WIFI + ConnectivityManager.TYPE_MOBILE -> ConnectionType.CELLULAR + else -> ConnectionType.NONE + } + } + } + + /** + * Проверка типа подключения (Wi-Fi) + * @param context Контекст приложения + * @return true, если подключение осуществляется через Wi-Fi, false в противном случае + */ + fun isWifiConnection(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) + } + + /** + * Проверка типа подключения (мобильная сеть) + * @param context Контекст приложения + * @return true, если подключение осуществляется через мобильную сеть, false в противном случае + */ + fun isMobileConnection(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) + } + + /** + * Типы подключения к интернету + */ + enum class ConnectionType { + WIFI, // Подключение через WiFi + CELLULAR, // Подключение через мобильную сеть + NONE // Отсутствие подключения + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Feedback/FeedbackFragment.kt b/app/src/main/java/com/example/rehabilitation/Feedback/FeedbackFragment.kt new file mode 100644 index 0000000..26ce897 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Feedback/FeedbackFragment.kt @@ -0,0 +1,81 @@ +package com.example.rehabilitation.Feedback + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Setting.SettingFragment +import com.example.rehabilitation.databinding.FragmentFeedbackBinding + + +class FeedbackFragment : Fragment() { + private lateinit var binding: FragmentFeedbackBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentFeedbackBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if(isAdded()) { + //Выход + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, SettingFragment.newInstance()) + ?.commit() + } + + //Переход по ссылке на сайт + binding.txtUrlVmeda.setOnClickListener { + val i = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.vmeda.org/")) + startActivity(i) + } +// +// //Переход на почту +// binding.txtEmailDoctor.setOnClickListener{ +// val intent = Intent(Intent.ACTION_SEND) +// intent.data = Uri.parse("mailto:") +// intent.type = "text/plain" +// intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(binding.txtEmailDoctor.text.toString()))// herer adresses is already string +// +// try{ +// startActivity(Intent.createChooser(intent,"Choose Email Client...")) +// } +// catch (e:Exception){ +// Toast.makeText(this,e.message, Toast.LENGTH_LONG).show() +// } +// } + +// //Номер врача +// binding.txtNumberDoctor.setOnClickListener{ +// val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + binding.txtNumberDoctor.text.toString())) +// startActivity(intent) +// } + + //Номер регистратуры + binding.txtNumberRegister.setOnClickListener { + val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + "+78122923286")) + startActivity(intent) + } + + //Номер ДМС + binding.txtNumberDMS.setOnClickListener { + val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + "+78122923412")) + startActivity(intent) + } + } + } + + companion object { + + fun newInstance() = FeedbackFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Hranilihe.kt b/app/src/main/java/com/example/rehabilitation/Hranilihe.kt new file mode 100644 index 0000000..637713f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Hranilihe.kt @@ -0,0 +1,142 @@ +package com.example.rehabilitation + +import android.content.SharedPreferences +import com.example.rehabilitation.Calendare.CalendareModel +import com.example.rehabilitation.Sport.Image.ImageSportModel +import com.example.rehabilitation.Progress.AfterListModel +import com.example.rehabilitation.Progress.BeforeListModel +import com.example.rehabilitation.Progress.ProgressModel +import java.io.File +import java.io.FileOutputStream + +//Постоянное хранилище + +var prefUserPatientToken: SharedPreferences? = null +var UserPatientToken:String = "" + +var pref: SharedPreferences? = null + +//Общее количество дней курса +var prefSportCursDayAll: SharedPreferences? = null +var SportCursDayAll :Int = 0 +var prefSportCursDayLast: SharedPreferences? = null +var SportCursDayLast :String = "" + +var prefSportCursNumber: SharedPreferences? = null +var prefCursDay: SharedPreferences? = null +var SportCursDay :Int = 0 + + +//7 дней пройдено +var prefSport7Day: SharedPreferences? = null +var Sport7Day :Int = 0 + +//15 дней пройдено +var prefSport15Day: SharedPreferences? = null +var Sport15Day :Int = 0 + +//15 дней пройдено и отправлен отчет +var prefSport15DayAll: SharedPreferences? = null +var Sport15DayAll :Int = 0 + + +var prefSportCursDayNumber: SharedPreferences? = null +var SportCursDayNumber :Int = 0 + +var prefSport: SharedPreferences? = null +var SportUserTrue = 0 + +var prefCursDangerDayBefore: SharedPreferences? = null +var SportCursDayDangerBefore:Int = 0 +var prefCursDangerDayAfter: SharedPreferences? = null +var SportCursDayDangerAfter:Int = 0 +var prefCursDayNull: SharedPreferences? = null +var CursDayNull:String = "" + +var prefSportPlusCount: SharedPreferences? = null +var SportPlusCount:Int = 0 +var prefSportMaxCount: SharedPreferences? = null +var SportMaxCount:Int = 0 + +var prefDayBefore: SharedPreferences? = null +var DayBefore:String = "" +var prefDayAfter: SharedPreferences? = null +var DayAfter:String = "" + +var prefPauseDay: SharedPreferences? = null +var PauseDay:String = "" +var prefBlock: SharedPreferences? = null +var Block:String = "" + +var prefFIO: SharedPreferences? = null +var FIO:String = "" + +var prefEmailPatient: SharedPreferences? = null +var EmailPatient:String = "" + +//Дата начала тренировки +var prefSportDateStart: SharedPreferences? = null +var SportDateStart:String = "" + + + +var prefUser: SharedPreferences? = null +//Хранилище для анкеты +//var questionnaire: SharedPreferences? = null +var questionnaire_before :String = "" +var questionnaire_after:String = "" + +var nameSport :String = "" +var countSport:Int? = null +var countSportPlus:String = "" +//Ключи для хранилишь + + + +//Для пациента +var tokenClass:String = "" +var counter1:String = "" + +//Для врача +var counter2:String = "" +var tokenClassDoctor:String = "" + +var countCategory:String = "" + + +//Отчет по ребилитации +var listCheckSportDay:String = "" + +//Доктор +var loginDoctor:String = "maxi05092003" +//Пациент +var loginPatient:String = "t.t.maxi05092003@gmail.com" + +//Хранения отчета на время +var checkDaySportString:String = "" + +//Хранения для перехода на страницу +var daySpoartOpen:Int = 0 +var daySpoartOpenDate:String = "" +val daySpoartOpenKey:Int = 12321313 + //var itemDayOpenDate:MonthModel + + +//Анкетирование +var listBefore:List = listOf() +var listAfter:List = listOf() + + +//Прогрес +var listProgressAll:List = listOf() +var listProgressCheck:List = listOf() +var listImageSport:List = listOf() + +var uriFileEF: File? =null +var fileUri2: FileOutputStream? =null +//Переменная для хранения дня, чтобы при нажатие на главной тсранице или в календаре +var dateHomeCalendare:String = "" + + +class Hranilihe { +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/CommonInfoFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/CommonInfoFragment.kt new file mode 100644 index 0000000..9153ef7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/CommonInfoFragment.kt @@ -0,0 +1,50 @@ +package com.example.rehabilitation.fragment.InfoFragment + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InformationFragment +import com.example.rehabilitation.databinding.FragmentCommonInfoBinding + +class CommonInfoFragment : Fragment() { + private lateinit var binding: FragmentCommonInfoBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentCommonInfoBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InformationFragment.newInstance())?.addToBackStack(null)?.commit() + + } + } + +// override fun onResume() { +// super.onResume() +// binding.CLCommonInfo.visibility = View.VISIBLE +// } +// +// override fun onDestroy() { +// super.onDestroy() +// binding.CLCommonInfo.visibility = View.GONE +// +// } + + companion object { + @JvmStatic + fun newInstance() = CommonInfoFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MedicalReabilitationFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MedicalReabilitationFragment.kt new file mode 100644 index 0000000..d29e7b4 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MedicalReabilitationFragment.kt @@ -0,0 +1,49 @@ +package com.example.rehabilitation.fragment.InfoFragment + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InformationFragment +import com.example.rehabilitation.databinding.FragmentMedicalReabilitationBinding + +class MedicalReabilitationFragment : Fragment() { + private lateinit var binding: FragmentMedicalReabilitationBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentMedicalReabilitationBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InformationFragment.newInstance())?.addToBackStack(null)?.commit() + + } + } + +// override fun onResume() { +// super.onResume() +// binding.CLMadicalReabilitation.visibility = View.VISIBLE +// } +// +// override fun onDestroy() { +// super.onDestroy() +// binding.CLMadicalReabilitation.visibility = View.GONE +// +// } + + companion object { + + @JvmStatic + fun newInstance() = MedicalReabilitationFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/BreathingExercisesFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/BreathingExercisesFragment.kt new file mode 100644 index 0000000..1f36dfc --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/BreathingExercisesFragment.kt @@ -0,0 +1,48 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +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 com.example.rehabilitation.R as R_P +import android.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentBreathingExercisesBinding + +class BreathingExercisesFragment : Fragment() { + private lateinit var binding:FragmentBreathingExercisesBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentBreathingExercisesBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R_P.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + val inflater = TransitionInflater.from(requireContext()) + binding.DecongestantTherapy.setOnClickListener { + exitTransition = inflater.inflateTransition(R.transition.slide_top) + activity?.supportFragmentManager?.beginTransaction()?.replace(R_P.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.DecongestantTherapyFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + + //enterTransition = inflater.inflateTransition(R_P.transition.slide_bottom) + + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.BreathingExercisesFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/ContourPreventionFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/ContourPreventionFragment.kt new file mode 100644 index 0000000..0d8fb72 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/ContourPreventionFragment.kt @@ -0,0 +1,42 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentContourPreventionBinding + + +class ContourPreventionFragment : Fragment() { + private lateinit var binding:FragmentContourPreventionBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentContourPreventionBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnPhantomPains.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhantomPainsFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.ContourPreventionFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/DecongestantTherapyFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/DecongestantTherapyFragment.kt new file mode 100644 index 0000000..f323fb6 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/DecongestantTherapyFragment.kt @@ -0,0 +1,41 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentDecongestantTherapyBinding + +class DecongestantTherapyFragment : Fragment() { + private lateinit var binding: FragmentDecongestantTherapyBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentDecongestantTherapyBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnContracturesPrevention.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.ContourPreventionFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.DecongestantTherapyFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/FormationOfTheStumpFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/FormationOfTheStumpFragment.kt new file mode 100644 index 0000000..3e69089 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/FormationOfTheStumpFragment.kt @@ -0,0 +1,42 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentFormationOfTheStumpBinding + + +class FormationOfTheStumpFragment : Fragment() { + private lateinit var binding:FragmentFormationOfTheStumpBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentFormationOfTheStumpBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnPhysicalExercises.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhysicalExercisesFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.FormationOfTheStumpFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/MotorModeFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/MotorModeFragment.kt new file mode 100644 index 0000000..409d598 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/MotorModeFragment.kt @@ -0,0 +1,44 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +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 com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentMotorModeBinding + +class MotorModeFragment : Fragment() { + private lateinit var binding: FragmentMotorModeBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentMotorModeBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } +// val inflater = TransitionInflater.from(requireContext()) +// exitTransition = inflater.inflateTransition(R.transition.slide_bottom) + binding.btnStumpCare.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.StumpCareFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.MotorModeFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDailyRoutineAfterSurgeryFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDailyRoutineAfterSurgeryFragment.kt new file mode 100644 index 0000000..dd1cf10 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDailyRoutineAfterSurgeryFragment.kt @@ -0,0 +1,41 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentOrganizationOfTheDailyRoutineAfterSurgeryBinding + + +class OrganizationOfTheDailyRoutineAfterSurgeryFragment : Fragment() { + private lateinit var binding: FragmentOrganizationOfTheDailyRoutineAfterSurgeryBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentOrganizationOfTheDailyRoutineAfterSurgeryBinding.inflate(layoutInflater,container,false) + return binding.root + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnOrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputation.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDailyRoutineAfterSurgeryFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment.kt new file mode 100644 index 0000000..21a7063 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment.kt @@ -0,0 +1,36 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentOrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationBinding + +class OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment : Fragment() { + private lateinit var binding: FragmentOrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentOrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhantomPainsFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhantomPainsFragment.kt new file mode 100644 index 0000000..0bec47d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhantomPainsFragment.kt @@ -0,0 +1,41 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentPhantomPainsBinding + +class PhantomPainsFragment : Fragment() { + private lateinit var binding:FragmentPhantomPainsBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPhantomPainsBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnSurfaceSensitivity.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.SurfaceSensitivityFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhantomPainsFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhysicalExercisesFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhysicalExercisesFragment.kt new file mode 100644 index 0000000..8de1a6c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/PhysicalExercisesFragment.kt @@ -0,0 +1,41 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentPhysicalExercisesBinding + +class PhysicalExercisesFragment : Fragment() { + private lateinit var binding: FragmentPhysicalExercisesBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPhysicalExercisesBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnOrganizationOfTheDailyRoutineAfterSurgery.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDailyRoutineAfterSurgeryFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhysicalExercisesFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/StumpCareFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/StumpCareFragment.kt new file mode 100644 index 0000000..bf00eff --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/StumpCareFragment.kt @@ -0,0 +1,43 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentStumpCareBinding + + +class StumpCareFragment : Fragment() { + private lateinit var binding: FragmentStumpCareBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentStumpCareBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnBreathingExercises.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.BreathingExercisesFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.StumpCareFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/SurfaceSensitivityFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/SurfaceSensitivityFragment.kt new file mode 100644 index 0000000..20f2648 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriod/SurfaceSensitivityFragment.kt @@ -0,0 +1,42 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentSurfaceSensitivityBinding + +class SurfaceSensitivityFragment : Fragment() { + private lateinit var binding:FragmentSurfaceSensitivityBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentSurfaceSensitivityBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnFormationOfTheStump.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.FormationOfTheStumpFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.SurfaceSensitivityFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriodFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriodFragment.kt new file mode 100644 index 0000000..a5f15df --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/EarlyPostoperativePeriodFragment.kt @@ -0,0 +1,111 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.BreathingExercisesFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.ContourPreventionFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.DecongestantTherapyFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.FormationOfTheStumpFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.MotorModeFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDailyRoutineAfterSurgeryFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhantomPainsFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhysicalExercisesFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.StumpCareFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.SurfaceSensitivityFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment +import com.example.rehabilitation.databinding.FragmentEarlyPostoperativePeriodBinding + +class EarlyPostoperativePeriodFragment : Fragment() { + private lateinit var binding:FragmentEarlyPostoperativePeriodBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentEarlyPostoperativePeriodBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnMotorMode.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.MotorModeFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnStumpCare.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.StumpCareFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnBreathingExercises.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.BreathingExercisesFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.DecongestantTherapy.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.DecongestantTherapyFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnContracturesPrevention.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.ContourPreventionFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnPhantomPains.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhantomPainsFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnFurther.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + + binding.btnSurfaceSensitivity.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.SurfaceSensitivityFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnFormationOfTheStump.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.FormationOfTheStumpFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnPhysicalExercises.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.PhysicalExercisesFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnOrganizationOfTheDailyRoutineAfterSurgery.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDailyRoutineAfterSurgeryFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnOrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputation.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriod.OrganizationOfTheDayRegimeOfTheSecondWeekAfterAmputationFragment.newInstance())?.addToBackStack(null)?.commit() + } + + + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/DecongestantTherapyLateFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/DecongestantTherapyLateFragment.kt new file mode 100644 index 0000000..521065d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/DecongestantTherapyLateFragment.kt @@ -0,0 +1,43 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentDecongestantTherapyLateBinding + +class DecongestantTherapyLateFragment : Fragment() { + private lateinit var binding: FragmentDecongestantTherapyLateBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentDecongestantTherapyLateBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace( + R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnMassageTechniqueLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.MassageTechniqueLateFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.DecongestantTherapyLateFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/MassageTechniqueLateFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/MassageTechniqueLateFragment.kt new file mode 100644 index 0000000..32c3105 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/MassageTechniqueLateFragment.kt @@ -0,0 +1,42 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentMassageTechniqueLateBinding + + +class MassageTechniqueLateFragment : Fragment() { + private lateinit var binding: FragmentMassageTechniqueLateBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentMassageTechniqueLateBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnPreventionOfContracturesLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreventionOfContracturesLateFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.MassageTechniqueLateFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PhantomPainsLateFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PhantomPainsLateFragment.kt new file mode 100644 index 0000000..a91100b --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PhantomPainsLateFragment.kt @@ -0,0 +1,38 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentPhantomPainsLateBinding + + +class PhantomPainsLateFragment : Fragment() { + private lateinit var binding:FragmentPhantomPainsLateBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPhantomPainsLateBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace( + R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PhantomPainsLateFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreparationForProstheticsLateFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreparationForProstheticsLateFragment.kt new file mode 100644 index 0000000..6773678 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreparationForProstheticsLateFragment.kt @@ -0,0 +1,43 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentPreparationForProstheticsLateBinding + + +class PreparationForProstheticsLateFragment : Fragment() { + private lateinit var binding: FragmentPreparationForProstheticsLateBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPreparationForProstheticsLateBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace( + R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnDecongestantTherapyLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.DecongestantTherapyLateFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreparationForProstheticsLateFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreventionOfContracturesLateFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreventionOfContracturesLateFragment.kt new file mode 100644 index 0000000..aadf962 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriod/PreventionOfContracturesLateFragment.kt @@ -0,0 +1,41 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.databinding.FragmentPreventionOfContracturesLateBinding + +class PreventionOfContracturesLateFragment : Fragment() { + private lateinit var binding: FragmentPreventionOfContracturesLateBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentPreventionOfContracturesLateBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnPhantomPainsLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PhantomPainsLateFragment.Companion.newInstance() + )?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreventionOfContracturesLateFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriodFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriodFragment.kt new file mode 100644 index 0000000..59c1a4f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendations/LatePostoperativePeriodFragment.kt @@ -0,0 +1,63 @@ +package com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.DecongestantTherapyLateFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.MassageTechniqueLateFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PhantomPainsLateFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreparationForProstheticsLateFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreventionOfContracturesLateFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment +import com.example.rehabilitation.databinding.FragmentLatePostoperativePeriodBinding + +class LatePostoperativePeriodFragment : Fragment() { + private lateinit var binding: FragmentLatePostoperativePeriodBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentLatePostoperativePeriodBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnPreparationForProstheticsLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreparationForProstheticsLateFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnDecongestantTherapyLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.DecongestantTherapyLateFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnMassageTechniqueLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.MassageTechniqueLateFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnPreventionOfContracturesLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PreventionOfContracturesLateFragment.newInstance())?.addToBackStack(null)?.commit() + } + binding.btnPhantomPainsLate.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriod.PhantomPainsLateFragment.newInstance())?.addToBackStack(null)?.commit() + } + } + + companion object { + + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendationsFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendationsFragment.kt new file mode 100644 index 0000000..611267a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/MethodologicalRecommendationsFragment.kt @@ -0,0 +1,48 @@ +package com.example.rehabilitation.Information.InfoFragment + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment +import com.example.rehabilitation.Information.InformationFragment +import com.example.rehabilitation.databinding.FragmentMethodologicalRecommendationsBinding + +class MethodologicalRecommendationsFragment : Fragment() { + private lateinit var binding: FragmentMethodologicalRecommendationsBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentMethodologicalRecommendationsBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InformationFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnEarlyPostoperativePeriod.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.EarlyPostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + + binding.btnLatePostoperativePeriod.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendations.LatePostoperativePeriodFragment.newInstance())?.addToBackStack(null)?.commit() + } + + } + + companion object { + fun newInstance() = + com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/faqFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/faqFragment.kt new file mode 100644 index 0000000..a7c793c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InfoFragment/faqFragment.kt @@ -0,0 +1,50 @@ +package com.example.rehabilitation.fragment.InfoFragment + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InformationFragment +import com.example.rehabilitation.databinding.FragmentFaqBinding + +class faqFragment : Fragment() { + private lateinit var binding: FragmentFaqBinding + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + + binding = FragmentFaqBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.btnExit.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.CLInformationMain, + com.example.rehabilitation.Information.InformationFragment.newInstance())?.addToBackStack(null)?.commit() + + } + } + +// override fun onResume() { +// super.onResume() +// binding.CLFaq.visibility = View.VISIBLE +// } +// +// override fun onDestroy() { +// super.onDestroy() +// binding.CLFaq.visibility = View.GONE +// +// } + + companion object { + @JvmStatic + fun newInstance() = faqFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InformationFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InformationFragment.kt new file mode 100644 index 0000000..24a1556 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InformationFragment.kt @@ -0,0 +1,118 @@ +package com.example.rehabilitation.Information + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.MainActivity +import com.example.rehabilitation.R +import com.example.rehabilitation.Information.InfoFragment.MethodologicalRecommendationsFragment +import com.example.rehabilitation.MainFragment +import com.example.rehabilitation.Setting.SettingFragment +import com.example.rehabilitation.databinding.FragmentInformationBinding +import com.example.rehabilitation.fragment.InfoFragment.CommonInfoFragment +import com.example.rehabilitation.fragment.InfoFragment.MedicalReabilitationFragment +import com.example.rehabilitation.fragment.InfoFragment.faqFragment + + +class InformationFragment : Fragment() { + private lateinit var binding: FragmentInformationBinding + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentInformationBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if(isAdded()) { + //Выход со страницы + binding.btnExitInformation.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, MainFragment.newInstance()) + ?.commit() + + } + + binding.methodologicalRecommendationsButton.setOnClickListener { +// val infoFrag = activity?.supportFragmentManager?.beginTransaction() +// infoFrag?.replace( +// R.id.CLInformation,MethodologicalRecommendationsFragment.newInstance() +// ) +// infoFrag?.addToBackStack(null) +// infoFrag?.commit() + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLInformationMain, MethodologicalRecommendationsFragment.newInstance()) + ?.commit() + + } + + binding.commonInformationButton.setOnClickListener { +// val infoFrag = activity?.supportFragmentManager?.beginTransaction() +// infoFrag?.replace(R.id.CLInformation, CommonInfoFragment.newInstance()) +// infoFrag?.addToBackStack(null) +// infoFrag?.commit() + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLInformationMain, CommonInfoFragment.newInstance()) + ?.commit() + } + + binding.frequentlyAskedQuestionsButton.setOnClickListener { +// val infoFrag = activity?.supportFragmentManager?.beginTransaction() +// infoFrag?.replace(R.id.CLInformation, faqFragment.newInstance()) +// infoFrag?.addToBackStack(null) +// infoFrag?.commit() + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLInformationMain, faqFragment.newInstance()) + ?.commit() + } + + binding.medicalReabilitationButton.setOnClickListener { +// val infoFrag = activity?.supportFragmentManager?.beginTransaction() +// infoFrag?.replace(R.id.CLInformation, MedicalReabilitationFragment.newInstance()) +// infoFrag?.addToBackStack(null) +// infoFrag?.commit() + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLInformationMain, MedicalReabilitationFragment.newInstance()) + ?.commit() + } + + binding.fondButton.setOnClickListener { + val i = Intent( + Intent.ACTION_VIEW, + Uri.parse("https://фонд-защитники-отечества.рф/filials") + ) + startActivity(i) + } + } + } + +// override fun onDestroy() { +// super.onDestroy() +// activity?.finish() +// +// binding.CLFragmentInformation.visibility = View.GONE +// } +// +// override fun onResume() { +// super.onResume() +// binding.CLFragmentInformation.visibility = View.VISIBLE +// +// } + + + + companion object { + + fun newInstance() = com.example.rehabilitation.Information.InformationFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Information/InformationMainFragment.kt b/app/src/main/java/com/example/rehabilitation/Information/InformationMainFragment.kt new file mode 100644 index 0000000..06fa5f5 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Information/InformationMainFragment.kt @@ -0,0 +1,33 @@ +package com.example.rehabilitation.Information + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.FragmentInformationMainBinding + + +class InformationMainFragment : Fragment() { + private lateinit var binding: FragmentInformationMainBinding + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentInformationMainBinding.inflate(layoutInflater,container,false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLInformationMain, InformationFragment.newInstance()) + ?.commit() + } + + companion object { + fun newInstance() = InformationMainFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/MainActivity.kt b/app/src/main/java/com/example/rehabilitation/MainActivity.kt new file mode 100644 index 0000000..7803c78 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/MainActivity.kt @@ -0,0 +1,190 @@ +package com.example.rehabilitation + +import android.annotation.SuppressLint +import android.view.WindowManager +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.Auth.AuthFragment +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.databinding.ActivityMainBinding +import com.example.sqlitework.dip.MainViewModel +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 MainActivity : AppCompatActivity() { + // Привязка к layout файлу + private lateinit var binding: ActivityMainBinding + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + // ViewModel для работы с данными пациента + private val modelPatient: PatientViewModel by viewModels() + // ViewModel для работы с основными данными + private val model: MainViewModel by viewModels() + + // Токен авторизации + private var Token = "" + // Класс для работы с настройками + val prefPatientConclusion = ConclusionPref() + // Время последнего нажатия кнопки "назад" + var backPressedTime: Long = 0 + + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + @SuppressLint("DiscouragedApi") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + // Установка флага безопасности для предотвращения скриншотов + window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + + MainAndAuth() + } + + /** + * Проверяет наличие токена и инициализирует соответствующий экран + */ + fun MainAndAuth() { + Token = prefPatientConclusion.conclusionToken(this) + Log.i("sadasdsadsd", Token) + if (Token == "") { + Auth() + } else { + CheckTokenAuth(Token) + } + } + + /** + * Показывает экран авторизации + */ + 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() + } + + /** + * Проверяет валидность токена авторизации + * @param token Токен для проверки + */ + @SuppressLint("SuspiciousIndentation") + private fun CheckTokenAuth(token: String) { + if (enternetCheck.isOnline(this)) { + initRetrofit() + CoroutineScope(Dispatchers.IO).launch { + val response = patientApi.CheckToken("Bearer $token") + runOnUiThread { + // Обработка ответа от сервера + val List = response.body() + val Nice = response.isSuccessful + val Code = response.code() + + // Обработка различных кодов ответа + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(this@MainActivity, Code429Activity::class.java) + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + Main() + } else { + Auth() + } + } + 500 -> { + // Ошибка сервера + val intetn = Intent(this@MainActivity, Code500Activity::class.java) + startActivity(intetn) + } + 401 -> { + // Неавторизованный доступ + val intetn = Intent(this@MainActivity, AuthorizationActivity::class.java) + finish() + startActivity(intetn) + } + } + } + } + } else { + // Нет интернет-соединения + val intetn = Intent(this, Code500Activity::class.java) + finish() + startActivity(intetn) + } + } + + /** + * Инициализирует Retrofit для работы с API + */ + private fun initRetrofit() { + // Настройка логирования + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + // Создание HTTP клиента + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + // Инициализация Retrofit + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + patientApi = retrofit.create(PatientApi::class.java) + } + + /** + * Инициализирует главный фрагмент + */ + private fun fragment_inicializ() { + supportFragmentManager.beginTransaction() + .replace(R.id.CLMain, MainFragment.newInstance()) + .commit() + } + + override fun onDestroy() { + super.onDestroy() + finish() + } + + override fun onResume() { + super.onResume() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/MainFragment.kt b/app/src/main/java/com/example/rehabilitation/MainFragment.kt new file mode 100644 index 0000000..6ca882e --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/MainFragment.kt @@ -0,0 +1,482 @@ +package com.example.rehabilitation + +import android.annotation.SuppressLint +import android.content.Intent +import android.icu.text.SimpleDateFormat +import android.icu.util.Calendar +import android.os.Bundle +import android.os.SystemClock +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.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Appeals.AppealsFragment +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.Calendare.CalendarFragment +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.Information.InformationFragment +import com.example.rehabilitation.Information.InformationMainFragment +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Progress.ProgresFragment +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Setting.SettingFragment +import com.example.rehabilitation.Sport.DayAdapter +import com.example.rehabilitation.Sport.SceduleFragment +import com.example.rehabilitation.Sport.SportForDayModel +import com.example.rehabilitation.databinding.FragmentMainBinding +import com.example.rehabilitation.model_adapter.DataModel +import com.example.sqlitework.dip.MainViewModel +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.Date +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + +/** + * Основной фрагмент приложения + * Отвечает за отображение главного экрана и навигацию между разделами + */ +class MainFragment : Fragment() { + // ViewBinding для доступа к элементам интерфейса + private var _binding: FragmentMainBinding? = null + private val binding get() = _binding!! + + // ViewModel для передачи данных между фрагментами + private val dataModel: DataModel by viewModels() + // ViewModel для работы с основными данными + private val model: MainViewModel by activityViewModels() + // ViewModel для работы с данными пациента + private val modelPatient: PatientViewModel by activityViewModels() + + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + // Таймер для обновления данных + private lateinit var timer: Timer + + // Класс для работы с настройками + val prefPatientConclusion = ConclusionPref() + + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + // Форматтер для даты + @SuppressLint("SimpleDateFormat") + 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(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Инициализация ViewModel + viewModel = ViewModelProvider(this)[PatientViewModel::class.java] + + // Настройка обработчиков нажатий на кнопки + setupClickListeners() + + // Наблюдение за изменениями данных + observeViewModel() + + checkForUpdates() + + if (isAdded) { + main_inicializ() + } + // Наблюдение за изменениями в меню + dataModel.fragmentMenu.observe(viewLifecycleOwner, Observer { + binding.buttonNavigation.selectedItemId = it + }) + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Переход к разделу анкет + binding.btnQuestionnaires.setOnClickListener { + findNavController().navigate(R.id.action_mainFragment_to_questionnaireFragment) + } + + // Переход к разделу расписания + binding.btnSchedule.setOnClickListener { + findNavController().navigate(R.id.action_mainFragment_to_sceduleFragment) + } + + // Переход к разделу обращений + binding.btnAppeals.setOnClickListener { + findNavController().navigate(R.id.action_mainFragment_to_appealsFragment) + } + + // Переход к разделу профиля + binding.btnProfile.setOnClickListener { + findNavController().navigate(R.id.action_mainFragment_to_profileFragment) + } + } + + /** + * Наблюдение за изменениями данных в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за статусом загрузки + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE + } + + // Наблюдение за ошибками + viewModel.error.observe(viewLifecycleOwner) { error -> + error?.let { + // Отображение ошибки пользователю + showError(it) + } + } + } + + /** + * Отображение ошибки пользователю + * @param message Сообщение об ошибке + */ + private fun showError(message: String) { + // TODO: Реализовать отображение ошибки + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + /** + * Инициализация главного экрана + */ + fun main_inicializ() { + // Наблюдение за изменениями в меню + dataModel.fragmentMenu.observe(this as LifecycleOwner, { + binding.buttonNavigation.selectedItemId = it + }) + + // Инициализация фрагментов + fragment_inicializ() + + // Обработчик нажатия на кнопку настроек + binding.btnSetting.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, SettingFragment.newInstance()) + ?.commit() + } + + // Обработчик нажатия на кнопку информации + binding.btnInformation.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, InformationMainFragment.newInstance()) + ?.commit() + } + + // Отображение текущей даты + addDate() + } + + /** + * Инициализация навигации между фрагментами + */ + fun fragment_inicializ() { + // Установка начального фрагмента (расписание) + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance()) + ?.commit() + + // Установка выбранного элемента в нижней навигации + binding.buttonNavigation.selectedItemId = R.id.schedule + + // Обработчик выбора элемента в нижней навигации + binding.buttonNavigation.setOnItemSelectedListener { + when (it.itemId) { + R.id.schedule -> { + // Переход к расписанию + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance()) + ?.commit() + } + } + R.id.calendar -> { + // Переход к календарю + val view = prefPatientConclusion.conclusionView(requireContext()) + if(view.toInt()==1 || view.toInt()==2){ + Toast(requireContext()).showCustomInfoToast("У вас отсутсвует курс", requireActivity()) + } else { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, CalendarFragment.newInstance()) + ?.commit() + } + } + R.id.progress -> { + // Переход к прогрессу + val view = prefPatientConclusion.conclusionView(requireContext()) + if(view.toInt()==1 || view.toInt()==2){ + Toast(requireContext()).showCustomInfoToast("У вас отсутсвует курс", requireActivity()) + } else { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, ProgresFragment.newInstance()) + ?.commit() + } + } + R.id.chat -> { + // Переход к чату + if (!isClickRecently()) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, AppealsFragment.newInstance()) + ?.commit() + } + } + } + true + } + } + + /** + * Добавление текущей даты на экран + */ + 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 = "" + + // Преобразование номера месяца в название + month = when (Month) { + 1 -> "Январь" + 2 -> "Февраль" + 3 -> "Март" + 4 -> "Апрель" + 5 -> "Май" + 6 -> "Июнь" + 7 -> "Июль" + 8 -> "Август" + 9 -> "Сентябрь" + 10 -> "Октябрь" + 11 -> "Ноябрь" + 12 -> "Декабрь" + else -> "" + } + + // Преобразование дня недели в сокращенное название + date_of_the_week = when (dayOfTheWeek) { + "Monday" -> "Пн" + "Tuesday" -> "Вт" + "Wednesday" -> "Ср" + "Thursday" -> "Чт" + "Friday" -> "Пт" + "Saturday" -> "Сб" + "Sunday" -> "Вс" + "Понедельник" -> "Пн" + "Вторник" -> "Вт" + "Стреда" -> "Ср" + "Четверг" -> "Чт" + "Пятница" -> "Пт" + "Суббота" -> "Сб" + "Воскресенье" -> "Вс" + else -> "" + } + + // Установка даты в TextView + binding.tvDate.text = "$date_of_the_week, $day $month" + } + + /** + * Проверка частоты нажатий для предотвращения множественных нажатий + */ + private fun isClickRecently(): Boolean { + if (SystemClock.elapsedRealtime() - lastClickTime < 1000) { + return true + } + lastClickTime = SystemClock.elapsedRealtime() + return false + } + + companion object { + private var lastClickTime: Long = 0 + } + + //Получения экрана + fun GetVisibleViewListTimer() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = patientApi.VisibleView3("Bearer $Tokens") + + activity?.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) { + modelPatient.viewCurrent.value = List + } + } + + //Следующий по счету + GetSportDay() + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + val dayAdapter = DayAdapter(object : DayAdapter.Listener { + override fun onClickSport(item: SportForDayModel) { + // Обработка нажатия на элемент + Log.d("Sport", "Clicked: ${item.number}") + } + }) + //Получения списка упражнений + fun GetSportDay() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportDay = patientApi.GetSportDay("Bearer $Tokens") + requireActivity().runOnUiThread { + val listResponse = sportDay.body() + val isSuccess = sportDay.isSuccessful + val responseCode = sportDay.code() + + if (responseCode == 429) { + val intent = Intent(requireContext(), Code429Activity::class.java) + startActivity(intent) + } else if (responseCode == 200) { + if (isSuccess && listResponse != null) { + // Допустим, что упражнение имеет свойство "id" и оно правильно отсортировано + // Мы сортируем упражнения по их идентификатору, чтобы они шли по порядку + val sortedList = listResponse.sport_for_day.sortedBy { it.number.toString() } + model.liveDayList.value = sortedList + } + } else if (responseCode == 500) { + val intent = Intent(requireContext(), Code500Activity::class.java) + startActivity(intent) + } + } + } + } else { + val intent = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intent) + } + } +// fun ProgressPatientCourses() { +// if (enternetCheck.isOnline(requireContext())) { +// initRetrofit() +// val Tokens = prefPatientConclusion.conclusionToken(requireContext()) +// CoroutineScope(Dispatchers.IO).launch { +// val progress = patientApi.ProgressPatientCourses("Bearer $Tokens") +// +// activity?.runOnUiThread { +// +// //Фиксируем полученные данные +// val progressMes = progress.body() +// val progressMesCode = progress.isSuccessful() +// //Если нету ошибок +// if (progressMesCode) { +// model.liveProgressCheckList.value = progressMes?.search_check_sport +// } +// } +// } +// } else { +// val intetn = Intent(requireContext(), EnternetActivity::class.java) +// activity?.finish() +// startActivity(intetn) +// } +// +// } + //Инициализация подлючения к серверу + 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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + override fun onResume() { + super.onResume() + checkForUpdates() + } + + override fun onPause() { + super.onPause() + if (::timer.isInitialized) { // Clean up the Timer + timer.cancel() + timer.purge() + } + } + + private fun checkForUpdates() { + viewLifecycleOwner.lifecycleScope.launch { + while (viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { + GetVisibleViewListTimer() + delay(15000) // 15 seconds delay + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Message/MessageChatFragment.kt b/app/src/main/java/com/example/rehabilitation/Message/MessageChatFragment.kt new file mode 100644 index 0000000..ada7a5d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Message/MessageChatFragment.kt @@ -0,0 +1,27 @@ +package com.example.rehabilitation.Message + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.rehabilitation.R as R_P +import android.R +import com.example.rehabilitation.databinding.FragmentMessageChatBinding + +class MessageChatFragment : Fragment() { + private lateinit var binding:FragmentMessageChatBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentMessageChatBinding.inflate(layoutInflater,container,false) + return binding.root + } + + companion object { + + fun newInstance() = MessageChatFragment() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/MessageModel.kt b/app/src/main/java/com/example/rehabilitation/MessageModel.kt new file mode 100644 index 0000000..db10594 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/MessageModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation + +data class MessageModel( + val message: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Model/ApiService.kt b/app/src/main/java/com/example/rehabilitation/Model/ApiService.kt new file mode 100644 index 0000000..df64c23 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/ApiService.kt @@ -0,0 +1,115 @@ +package com.example.rehabilitation.Model + +import retrofit2.Response +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.* + +/** + * Интерфейс для взаимодействия с API + * Определяет все доступные эндпоинты и методы для работы с данными + */ +interface ApiService { + /** + * Получение списка анкет для пациента + * @param patientId ID пациента + * @return Список анкет + */ + @GET("questionnaires") + suspend fun getQuestionnaires(@Query("patientId") patientId: Int): Response> + + /** + * Сохранение новой анкеты + * @param questionnaire Данные анкеты для сохранения + * @return Сохраненная анкета + */ + @POST("questionnaires") + suspend fun saveQuestionnaire(@Body questionnaire: QuestionnaireRequest): Response + + /** + * Обновление существующей анкеты + * @param id ID анкеты + * @param questionnaire Данные анкеты для обновления + * @return Обновленная анкета + */ + @PUT("questionnaires/{id}") + suspend fun updateQuestionnaire( + @Path("id") id: Int, + @Body questionnaire: QuestionnaireRequest + ): Response + + /** + * Удаление анкеты + * @param id ID анкеты + * @return Пустой ответ при успешном удалении + */ + @DELETE("questionnaires/{id}") + suspend fun deleteQuestionnaire(@Path("id") id: Int): Response + + /** + * Получение анкеты по ID + * @param id ID анкеты + * @return Анкета + */ + @GET("questionnaires/{id}") + suspend fun getQuestionnaire(@Path("id") id: Int): Response + + /** + * Получение списка расписаний для пациента + * @param patientId ID пациента + * @return Список расписаний + */ + @GET("schedules") + suspend fun getSchedules(@Query("patientId") patientId: Int): Response> + + /** + * Сохранение нового расписания + * @param schedule Данные расписания для сохранения + * @return Сохраненное расписание + */ + @POST("schedules") + suspend fun saveSchedule(@Body schedule: ScheduleRequest): Response + + /** + * Обновление существующего расписания + * @param id ID расписания + * @param schedule Данные расписания для обновления + * @return Обновленное расписание + */ + @PUT("schedules/{id}") + suspend fun updateSchedule( + @Path("id") id: Int, + @Body schedule: ScheduleRequest + ): Response + + /** + * Удаление расписания + * @param id ID расписания + * @return Пустой ответ при успешном удалении + */ + @DELETE("schedules/{id}") + suspend fun deleteSchedule(@Path("id") id: Int): Response + + /** + * Получение расписания по ID + * @param id ID расписания + * @return Расписание + */ + @GET("schedules/{id}") + suspend fun getSchedule(@Path("id") id: Int): Response + + companion object { + /** + * Создание экземпляра ApiService + * @param baseUrl Базовый URL API + * @return Экземпляр ApiService + */ + fun create(baseUrl: String = "https://api.example.com/"): ApiService { + return Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(ApiService::class.java) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/Code429Activity.kt b/app/src/main/java/com/example/rehabilitation/Model/Code429Activity.kt new file mode 100644 index 0000000..aa9096f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/Code429Activity.kt @@ -0,0 +1,68 @@ +package com.example.rehabilitation.Model + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityCode429Binding + +/** + * Активность, отображаемая при получении ошибки 429 (Too Many Requests) + * Информирует пользователя о превышении лимита запросов и предлагает повторить попытку позже + */ +class Code429Activity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityCode429Binding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками (в миллисекундах) + private val CHECK_DELAY = 5000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode429Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки + startRetryCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + finish() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки возможности повторного запроса + */ + private fun startRetryCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + // По истечении задержки возвращаемся к предыдущей активности + finish() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/Code500Activity.kt b/app/src/main/java/com/example/rehabilitation/Model/Code500Activity.kt new file mode 100644 index 0000000..f9a4998 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/Code500Activity.kt @@ -0,0 +1,68 @@ +package com.example.rehabilitation.Model + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityCode500Binding + +/** + * Активность, отображаемая при получении ошибки 500 (Internal Server Error) + * Информирует пользователя о внутренней ошибке сервера и предлагает повторить попытку позже + */ +class Code500Activity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityCode500Binding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками (в миллисекундах) + private val CHECK_DELAY = 5000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCode500Binding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки + startRetryCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + finish() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки доступности сервера + */ + private fun startRetryCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + // По истечении задержки возвращаемся к предыдущей активности + finish() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/ConclusionPref.kt b/app/src/main/java/com/example/rehabilitation/Model/ConclusionPref.kt new file mode 100644 index 0000000..89a5d44 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/ConclusionPref.kt @@ -0,0 +1,95 @@ +package com.example.rehabilitation.Model + +import android.content.Context +import android.content.SharedPreferences + +/** + * Класс для работы с настройками приложения + * Обеспечивает сохранение и получение данных через SharedPreferences + */ +class ConclusionPref(context: Context) { + // Имя файла настроек + companion object { + private const val PREFS_NAME = "rehabilitation_prefs" + + // Ключи для хранения данных + private const val KEY_PATIENT_ID = "patient_id" + private const val KEY_API_URL = "api_url" + private const val KEY_TOKEN = "token" + private const val KEY_IS_LOGGED_IN = "is_logged_in" + } + + // Экземпляр SharedPreferences для доступа к настройкам + private val prefs: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + + /** + * Сохранение ID пациента + * @param patientId ID пациента + */ + fun savePatientId(patientId: Int) { + prefs.edit().putInt(KEY_PATIENT_ID, patientId).apply() + } + + /** + * Получение ID пациента + * @return ID пациента или -1, если не сохранен + */ + fun getPatientId(): Int { + return prefs.getInt(KEY_PATIENT_ID, -1) + } + + /** + * Сохранение URL API + * @param apiUrl URL API + */ + fun saveApiUrl(apiUrl: String) { + prefs.edit().putString(KEY_API_URL, apiUrl).apply() + } + + /** + * Получение URL API + * @return URL API или пустую строку, если не сохранен + */ + fun getApiUrl(): String { + return prefs.getString(KEY_API_URL, "") ?: "" + } + + /** + * Сохранение токена авторизации + * @param token Токен авторизации + */ + fun saveToken(token: String) { + prefs.edit().putString(KEY_TOKEN, token).apply() + } + + /** + * Получение токена авторизации + * @return Токен авторизации или пустую строку, если не сохранен + */ + fun getToken(): String { + return prefs.getString(KEY_TOKEN, "") ?: "" + } + + /** + * Сохранение статуса авторизации + * @param isLoggedIn Статус авторизации + */ + fun saveLoginStatus(isLoggedIn: Boolean) { + prefs.edit().putBoolean(KEY_IS_LOGGED_IN, isLoggedIn).apply() + } + + /** + * Проверка статуса авторизации + * @return true если пользователь авторизован, false в противном случае + */ + fun isLoggedIn(): Boolean { + return prefs.getBoolean(KEY_IS_LOGGED_IN, false) + } + + /** + * Очистка всех сохраненных данных + */ + fun clearAll() { + prefs.edit().clear().apply() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/EnternetActivity.kt b/app/src/main/java/com/example/rehabilitation/Model/EnternetActivity.kt new file mode 100644 index 0000000..25f2a9c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/EnternetActivity.kt @@ -0,0 +1,77 @@ +package com.example.rehabilitation.Model + +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.appcompat.app.AppCompatActivity +import com.example.rehabilitation.databinding.ActivityEnternetBinding + +/** + * Активность, отображаемая при отсутствии подключения к интернету + * Предоставляет пользователю информацию о проблеме и возможность повторить проверку + */ +class EnternetActivity : AppCompatActivity() { + // ViewBinding для безопасного доступа к UI элементам + private lateinit var binding: ActivityEnternetBinding + + // Обработчик для обновления UI + private val handler = Handler(Looper.getMainLooper()) + + // Задержка между проверками подключения (в миллисекундах) + private val CHECK_DELAY = 2000L + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityEnternetBinding.inflate(layoutInflater) + setContentView(binding.root) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Запуск периодической проверки подключения + startConnectionCheck() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Повторить" + binding.retryButton.setOnClickListener { + checkConnection() + } + + // Обработчик нажатия на кнопку "Выход" + binding.exitButton.setOnClickListener { + finish() + } + } + + /** + * Запуск периодической проверки подключения + */ + private fun startConnectionCheck() { + handler.postDelayed(object : Runnable { + override fun run() { + checkConnection() + handler.postDelayed(this, CHECK_DELAY) + } + }, CHECK_DELAY) + } + + /** + * Проверка подключения к интернету + */ + private fun checkConnection() { + if (EnternetCheck.isInternetAvailable(this)) { + // Если подключение восстановлено, возвращаемся к предыдущей активности + finish() + } + } + + override fun onDestroy() { + super.onDestroy() + // Останавливаем периодическую проверку при уничтожении активности + handler.removeCallbacksAndMessages(null) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/EnternetCheck.kt b/app/src/main/java/com/example/rehabilitation/Model/EnternetCheck.kt new file mode 100644 index 0000000..916a6f5 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/EnternetCheck.kt @@ -0,0 +1,51 @@ +package com.example.rehabilitation.Model + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities + +/** + * Объект для проверки состояния сетевого подключения + * Предоставляет методы для проверки доступности интернета и типа подключения + */ +object EnternetCheck { + /** + * Проверка наличия подключения к интернету + * @param context Контекст приложения + * @return true, если есть активное подключение к интернету, false в противном случае + */ + fun isInternetAvailable(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && + capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + } + + /** + * Проверка типа подключения (Wi-Fi) + * @param context Контекст приложения + * @return true, если подключение осуществляется через Wi-Fi, false в противном случае + */ + fun isWifiConnection(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) + } + + /** + * Проверка типа подключения (мобильная сеть) + * @param context Контекст приложения + * @return true, если подключение осуществляется через мобильную сеть, false в противном случае + */ + fun isMobileConnection(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/QAfterFragment.kt b/app/src/main/java/com/example/rehabilitation/Model/QAfterFragment.kt new file mode 100644 index 0000000..d36f245 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/QAfterFragment.kt @@ -0,0 +1,96 @@ +package com.example.rehabilitation.Model + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.example.rehabilitation.databinding.FragmentQAfterBinding + +/** + * Фрагмент для отображения и заполнения анкеты после занятий + * Позволяет пользователю оценить свое состояние после реабилитационной сессии + */ +class QAfterFragment : Fragment() { + // ViewBinding для безопасного доступа к UI элементам + private var _binding: FragmentQAfterBinding? = null + private val binding get() = _binding!! + + // ViewModel для управления данными анкеты + private lateinit var viewModel: QuestionnaireViewModel + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentQAfterBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Инициализация ViewModel + viewModel = ViewModelProvider(this)[QuestionnaireViewModel::class.java] + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями в ViewModel + observeViewModel() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Сохранить" + binding.saveButton.setOnClickListener { + saveQuestionnaire() + } + } + + /** + * Сохранение данных анкеты + */ + private fun saveQuestionnaire() { + val questionnaire = Questionnaire( + id = 0, // Новый вопросник + patientId = viewModel.getPatientId(), + date = System.currentTimeMillis(), + painLevel = binding.painLevelSlider.value.toInt(), + moodLevel = binding.moodLevelSlider.value.toInt(), + fatigueLevel = binding.fatigueLevelSlider.value.toInt(), + notes = binding.notesEditText.text.toString() + ) + + viewModel.saveQuestionnaire(questionnaire) + } + + /** + * Наблюдение за изменениями в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за результатом сохранения + viewModel.saveResult.observe(viewLifecycleOwner) { result -> + when (result) { + is SaveResult.Success -> { + Toast.showShort(requireContext(), "Анкета успешно сохранена") + // Возврат к предыдущему экрану + requireActivity().onBackPressed() + } + is SaveResult.Error -> { + Toast.showLong(requireContext(), "Ошибка при сохранении анкеты: ${result.message}") + } + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/QBeforeFragment.kt b/app/src/main/java/com/example/rehabilitation/Model/QBeforeFragment.kt new file mode 100644 index 0000000..36c51f5 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/QBeforeFragment.kt @@ -0,0 +1,8 @@ +package com.example.rehabilitation.Model + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/Questionnaire.kt b/app/src/main/java/com/example/rehabilitation/Model/Questionnaire.kt new file mode 100644 index 0000000..0c14d62 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/Questionnaire.kt @@ -0,0 +1,110 @@ +package com.example.rehabilitation.Model + +/** + * Модель данных анкеты + * Содержит информацию о самочувствии пациента и его оценках + */ +data class Questionnaire( + // Уникальный идентификатор анкеты + val id: Int = 0, + + // Тип анкеты (BEFORE - до занятий, AFTER - после занятий) + val type: String, + + // ID пациента + val patientId: Int, + + // Самочувствие пациента + val wellbeing: String, + + // Уровень боли + val painLevel: String, + + // Уровень усталости (только для анкеты после занятий) + val fatigueLevel: String? = null, + + // Комментарий пациента + val comment: String, + + // Дата и время заполнения анкеты + val timestamp: Long = System.currentTimeMillis() +) { + /** + * Преобразование модели в запрос для API + */ + fun toQuestionnaireRequest(): QuestionnaireRequest { + return QuestionnaireRequest( + type = type, + patientId = patientId, + wellbeing = wellbeing, + painLevel = painLevel, + fatigueLevel = fatigueLevel, + comment = comment + ) + } + + /** + * Проверка валидности данных анкеты + * @return true если данные валидны, false в противном случае + */ + fun isValid(): Boolean { + return type.isNotEmpty() && + patientId > 0 && + wellbeing.isNotEmpty() && + painLevel.isNotEmpty() && + comment.isNotEmpty() && + (type != "AFTER" || fatigueLevel != null) + } + + companion object { + /** + * Создание анкеты до занятий + */ + fun createBefore( + patientId: Int, + wellbeing: String, + painLevel: String, + comment: String + ): Questionnaire { + return Questionnaire( + type = "BEFORE", + patientId = patientId, + wellbeing = wellbeing, + painLevel = painLevel, + comment = comment + ) + } + + /** + * Создание анкеты после занятий + */ + fun createAfter( + patientId: Int, + wellbeing: String, + painLevel: String, + fatigueLevel: String, + comment: String + ): Questionnaire { + return Questionnaire( + type = "AFTER", + patientId = patientId, + wellbeing = wellbeing, + painLevel = painLevel, + fatigueLevel = fatigueLevel, + comment = comment + ) + } + } +} + +/** + * Модель запроса для API + */ +data class QuestionnaireRequest( + val type: String, + val patientId: Int, + val wellbeing: String, + val painLevel: String, + val fatigueLevel: String?, + val comment: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireRepository.kt b/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireRepository.kt new file mode 100644 index 0000000..a8f3dcd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireRepository.kt @@ -0,0 +1,107 @@ +package com.example.rehabilitation.Model + +import com.example.rehabilitation.Network.ApiService +import com.example.rehabilitation.Network.QuestionnaireResponse +import com.example.rehabilitation.Pref.ConclusionPref +import retrofit2.Response + +/** + * Репозиторий для работы с данными анкет + * Обеспечивает взаимодействие с API и локальным хранилищем + */ +class QuestionnaireRepository { + // Сервис для работы с API + private val apiService = ApiService.create() + + // Менеджер настроек приложения + private val prefs = ConclusionPref() + + /** + * Получение списка анкет для пациента + * @param patientId ID пациента + * @return Список анкет + * @throws Exception при ошибке получения данных + */ + suspend fun getQuestionnaires(patientId: Int): List { + val response = apiService.getQuestionnaires(patientId) + if (!response.isSuccessful) { + throw Exception("Ошибка при получении списка анкет: ${response.code()}") + } + return response.body() ?: emptyList() + } + + /** + * Сохранение новой анкеты + * @param questionnaire Анкета для сохранения + * @return Сохраненная анкета + * @throws Exception при ошибке сохранения + */ + suspend fun saveQuestionnaire(questionnaire: Questionnaire): Questionnaire { + val response = apiService.saveQuestionnaire(questionnaire.toRequest()) + if (!response.isSuccessful) { + throw Exception("Ошибка при сохранении анкеты: ${response.code()}") + } + return response.body() ?: throw Exception("Пустой ответ от сервера") + } + + /** + * Обновление существующей анкеты + * @param questionnaire Анкета для обновления + * @return Обновленная анкета + * @throws Exception при ошибке обновления + */ + suspend fun updateQuestionnaire(questionnaire: Questionnaire): Questionnaire { + val response = apiService.updateQuestionnaire(questionnaire.id, questionnaire.toRequest()) + if (!response.isSuccessful) { + throw Exception("Ошибка при обновлении анкеты: ${response.code()}") + } + return response.body() ?: throw Exception("Пустой ответ от сервера") + } + + /** + * Удаление анкеты + * @param id ID анкеты для удаления + * @return true если удаление успешно + * @throws Exception при ошибке удаления + */ + suspend fun deleteQuestionnaire(id: Int): Boolean { + val response = apiService.deleteQuestionnaire(id) + if (!response.isSuccessful) { + throw Exception("Ошибка при удалении анкеты: ${response.code()}") + } + return true + } + + /** + * Получение анкеты по ID + * @param id ID анкеты + * @return Анкета + * @throws Exception при ошибке получения или если анкета не найдена + */ + suspend fun getQuestionnaire(id: Int): Questionnaire { + val response = apiService.getQuestionnaire(id) + if (!response.isSuccessful) { + throw Exception("Ошибка при получении анкеты: ${response.code()}") + } + return response.body() ?: throw Exception("Анкета не найдена") + } + + /** + * Получение ID пациента из настроек + * @return ID пациента + */ + fun getPatientId(): Int { + return prefs.getPatientId() + } + + /** + * Проверка ответа сервера + * @param response Ответ сервера + * @throws Exception если ответ не успешен + */ + private fun checkResponse(response: Response<*>) { + if (!response.isSuccessful) { + throw Exception("Ошибка сервера: ${response.code()}") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireViewModel.kt b/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireViewModel.kt new file mode 100644 index 0000000..f22075d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/QuestionnaireViewModel.kt @@ -0,0 +1,121 @@ +package com.example.rehabilitation.Model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.launch + +/** + * ViewModel для управления данными анкет + * Обрабатывает загрузку, сохранение и обновление анкет + */ +class QuestionnaireViewModel : ViewModel() { + // Репозиторий для работы с данными + private val repository = QuestionnaireRepository() + + // LiveData для списка анкет + private val _questionnaires = MutableLiveData>() + val questionnaires: LiveData> = _questionnaires + + // LiveData для индикации загрузки + private val _isLoading = MutableLiveData() + val isLoading: LiveData = _isLoading + + // LiveData для результата сохранения + private val _saveResult = MutableLiveData() + val saveResult: LiveData = _saveResult + + // LiveData для сообщений об ошибках + private val _error = MutableLiveData() + val error: LiveData = _error + + /** + * Загрузка списка анкет для пациента + * @param patientId ID пациента + */ + fun loadQuestionnaires(patientId: Int) { + viewModelScope.launch { + _isLoading.value = true + try { + val result = repository.getQuestionnaires(patientId) + _questionnaires.value = result + } catch (e: Exception) { + _error.value = "Ошибка при загрузке анкет: ${e.message}" + } finally { + _isLoading.value = false + } + } + } + + /** + * Сохранение новой анкеты + * @param questionnaire Анкета для сохранения + */ + fun saveQuestionnaire(questionnaire: Questionnaire) { + viewModelScope.launch { + _isLoading.value = true + try { + val result = repository.saveQuestionnaire(questionnaire) + _saveResult.value = SaveResult.Success(result) + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Неизвестная ошибка") + } finally { + _isLoading.value = false + } + } + } + + /** + * Обновление существующей анкеты + * @param questionnaire Анкета для обновления + */ + fun updateQuestionnaire(questionnaire: Questionnaire) { + viewModelScope.launch { + _isLoading.value = true + try { + val result = repository.updateQuestionnaire(questionnaire) + _saveResult.value = SaveResult.Success(result) + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Неизвестная ошибка") + } finally { + _isLoading.value = false + } + } + } + + /** + * Удаление анкеты + * @param questionnaireId ID анкеты для удаления + */ + fun deleteQuestionnaire(questionnaireId: Int) { + viewModelScope.launch { + _isLoading.value = true + try { + repository.deleteQuestionnaire(questionnaireId) + // Обновляем список анкет после удаления + loadQuestionnaires(repository.getPatientId()) + } catch (e: Exception) { + _error.value = "Ошибка при удалении анкеты: ${e.message}" + } finally { + _isLoading.value = false + } + } + } + + /** + * Получение ID пациента из репозитория + * @return ID пациента + */ + fun getPatientId(): Int { + return repository.getPatientId() + } +} + +/** + * Результат операции сохранения + */ +sealed class SaveResult { + data class Success(val questionnaire: Questionnaire) : SaveResult() + data class Error(val message: String) : SaveResult() +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/RetrofitClient.kt b/app/src/main/java/com/example/rehabilitation/Model/RetrofitClient.kt new file mode 100644 index 0000000..6bffe20 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/RetrofitClient.kt @@ -0,0 +1,52 @@ +package com.example.rehabilitation.Model + +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.util.concurrent.TimeUnit + +/** + * Клиент для работы с Retrofit + * Отвечает за настройку и создание экземпляра Retrofit с необходимыми параметрами + */ +object RetrofitClient { + // Таймаут для HTTP-запросов (в секундах) + private const val TIMEOUT = 30L + + /** + * Создание экземпляра Retrofit с настройками + * @param baseUrl Базовый URL API + * @return Экземпляр Retrofit + */ + fun create(baseUrl: String): Retrofit { + // Создание логгера для HTTP-запросов + val loggingInterceptor = HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + + // Настройка HTTP-клиента + val okHttpClient = OkHttpClient.Builder() + .addInterceptor(loggingInterceptor) + .connectTimeout(TIMEOUT, TimeUnit.SECONDS) + .readTimeout(TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(TIMEOUT, TimeUnit.SECONDS) + .build() + + // Создание и настройка экземпляра Retrofit + return Retrofit.Builder() + .baseUrl(baseUrl) + .client(okHttpClient) + .addConverterFactory(GsonConverterFactory.create()) + .build() + } + + /** + * Создание сервиса API + * @param baseUrl Базовый URL API + * @return Экземпляр ApiService + */ + fun createService(baseUrl: String): ApiService { + return create(baseUrl).create(ApiService::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/Schedule.kt b/app/src/main/java/com/example/rehabilitation/Model/Schedule.kt new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/Schedule.kt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/ScheduleRepository.kt b/app/src/main/java/com/example/rehabilitation/Model/ScheduleRepository.kt new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/ScheduleRepository.kt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Model/Toast.kt b/app/src/main/java/com/example/rehabilitation/Model/Toast.kt new file mode 100644 index 0000000..b4140c2 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Model/Toast.kt @@ -0,0 +1,28 @@ +package com.example.rehabilitation.Model + +import android.content.Context +import android.widget.Toast + +/** + * Объект для удобного отображения уведомлений Toast + * Предоставляет методы для показа коротких и длинных уведомлений + */ +object Toast { + /** + * Показывает короткое уведомление + * @param context Контекст приложения + * @param message Текст уведомления + */ + fun showShort(context: Context, message: String) { + android.widget.Toast.makeText(context, message, android.widget.Toast.LENGTH_SHORT).show() + } + + /** + * Показывает длинное уведомление + * @param context Контекст приложения + * @param message Текст уведомления + */ + fun showLong(context: Context, message: String) { + android.widget.Toast.makeText(context, message, android.widget.Toast.LENGTH_LONG).show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/PatientViewModel.kt b/app/src/main/java/com/example/rehabilitation/PatientViewModel.kt new file mode 100644 index 0000000..8167f20 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/PatientViewModel.kt @@ -0,0 +1,147 @@ +package com.example.rehabilitation + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.rehabilitation.Model.Patient +import com.example.rehabilitation.Model.PatientRepository +import com.example.rehabilitation.Model.Questionnaire +import com.example.rehabilitation.Model.QuestionnaireRepository +import kotlinx.coroutines.launch +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsNewModel +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsOldModel +import com.example.rehabilitation.Calendare.CalendareModel +import com.example.rehabilitation.Questionnaire.Model.AfterLookModel +import com.example.rehabilitation.Questionnaire.Model.BeforeLookModel +import com.example.rehabilitation.Sport.SportDayOneModel +import com.example.rehabilitation.Sport.ViewVisibleModel + +/** + * ViewModel для управления данными пациента + * Отвечает за загрузку и обновление информации о пациенте и его анкетах + */ +class PatientViewModel : ViewModel() { + // Репозиторий для работы с данными пациента + private val patientRepository = PatientRepository() + // Репозиторий для работы с анкетами + private val questionnaireRepository = QuestionnaireRepository() + + // LiveData для хранения данных пациента + private val _patient = MutableLiveData() + val patient: LiveData = _patient + + // LiveData для хранения списка анкет + private val _questionnaires = MutableLiveData>() + val questionnaires: LiveData> = _questionnaires + + // LiveData для хранения статуса загрузки + private val _isLoading = MutableLiveData() + val isLoading: LiveData = _isLoading + + // LiveData для хранения ошибок + private val _error = MutableLiveData() + val error: LiveData = _error + + // Токен авторизации + val token = MutableLiveData() + + // Данные о спортивных занятиях на день + val liveDaySportOne = MutableLiveData() + + // Данные о новых (необработанных) обращениях + val appealsNewCurrent = MutableLiveData() + val appealsNewList = MutableLiveData>() + + // Данные об обработанных обращениях + val appealsOldCurrent = MutableLiveData() + val appealsOldList = MutableLiveData>() + + // Данные о текущем виде экрана + val viewCurrent = MutableLiveData() + + // Данные календаря + val calendareList = MutableLiveData>() + + // Данные анкетирования после занятий + val afterLook = MutableLiveData() + // Данные анкетирования до занятий + val beforeLook = MutableLiveData() + // val productList = MutableLiveData>() + + /** + * Загрузка данных пациента + * @param patientId ID пациента + */ + fun loadPatient(patientId: Int) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = patientRepository.getPatient(patientId) + _patient.value = result + _error.value = null + } catch (e: Exception) { + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Загрузка списка анкет пациента + * @param patientId ID пациента + */ + fun loadQuestionnaires(patientId: Int) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = questionnaireRepository.getQuestionnaires(patientId) + _questionnaires.value = result + _error.value = null + } catch (e: Exception) { + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Обновление данных пациента + * @param patient Обновленные данные пациента + */ + fun updatePatient(patient: Patient) { + viewModelScope.launch { + try { + _isLoading.value = true + patientRepository.updatePatient(patient) + _patient.value = patient + _error.value = null + } catch (e: Exception) { + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Сохранение новой анкеты + * @param questionnaire Данные анкеты + */ + fun saveQuestionnaire(questionnaire: Questionnaire) { + viewModelScope.launch { + try { + _isLoading.value = true + questionnaireRepository.saveQuestionnaire(questionnaire) + loadQuestionnaires(questionnaire.patientId) + _error.value = null + } catch (e: Exception) { + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/.idea/.gitignore b/app/src/main/java/com/example/rehabilitation/Pref/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/app/src/main/java/com/example/rehabilitation/Pref/.idea/misc.xml b/app/src/main/java/com/example/rehabilitation/Pref/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/.idea/modules.xml b/app/src/main/java/com/example/rehabilitation/Pref/.idea/modules.xml new file mode 100644 index 0000000..07ef4d6 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/.idea/vcs.xml b/app/src/main/java/com/example/rehabilitation/Pref/.idea/vcs.xml new file mode 100644 index 0000000..07117e4 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/ClearPref.kt b/app/src/main/java/com/example/rehabilitation/Pref/ClearPref.kt new file mode 100644 index 0000000..1445fce --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/ClearPref.kt @@ -0,0 +1,14 @@ +package com.example.rehabilitation.Pref + +import android.content.Context +import android.content.SharedPreferences + +class ClearPref() { + + fun clearToken(context: Context) { + val prefDoctor: SharedPreferences = context.getSharedPreferences("PATIENT", Context.MODE_PRIVATE) + val edit = prefDoctor.edit() + edit?.clear() + edit?.apply() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/ConclusionPref.kt b/app/src/main/java/com/example/rehabilitation/Pref/ConclusionPref.kt new file mode 100644 index 0000000..4948861 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/ConclusionPref.kt @@ -0,0 +1,126 @@ +package com.example.rehabilitation.Pref + +import android.content.Context +import android.content.SharedPreferences + +/** + * Класс для работы с настройками приложения + * Предоставляет методы для сохранения и получения данных из SharedPreferences + */ +class ConclusionPref { + // Имя файла настроек + private val PREF_NAME = "rehabilitation_pref" + // Ключ для хранения токена авторизации + private val KEY_TOKEN = "token" + // Ключ для хранения ID пользователя + private val KEY_USER_ID = "user_id" + // Ключ для хранения имени пользователя + private val KEY_USER_NAME = "user_name" + // Ключ для хранения статуса авторизации + private val KEY_IS_LOGGED_IN = "is_logged_in" + + /** + * Получение экземпляра SharedPreferences + * @param context Контекст приложения + * @return Экземпляр SharedPreferences + */ + private fun getPref(context: Context): SharedPreferences { + return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + } + + /** + * Сохранение токена авторизации + * @param context Контекст приложения + * @param token Токен для сохранения + */ + fun saveToken(context: Context, token: String) { + val editor = getPref(context).edit() + editor.putString(KEY_TOKEN, token) + editor.apply() + } + + /** + * Получение токена авторизации + * @param context Контекст приложения + * @return Сохраненный токен или пустую строку, если токен не найден + */ + fun conclusionToken(context: Context): String { + return getPref(context).getString(KEY_TOKEN, "") ?: "" + } + + /** + * Сохранение ID пользователя + * @param context Контекст приложения + * @param userId ID пользователя + */ + fun saveUserId(context: Context, userId: Int) { + val editor = getPref(context).edit() + editor.putInt(KEY_USER_ID, userId) + editor.apply() + } + + /** + * Получение ID пользователя + * @param context Контекст приложения + * @return Сохраненный ID пользователя или -1, если ID не найден + */ + fun getUserId(context: Context): Int { + return getPref(context).getInt(KEY_USER_ID, -1) + } + + /** + * Сохранение имени пользователя + * @param context Контекст приложения + * @param name Имя пользователя + */ + fun saveUserName(context: Context, name: String) { + val editor = getPref(context).edit() + editor.putString(KEY_USER_NAME, name) + editor.apply() + } + + /** + * Получение имени пользователя + * @param context Контекст приложения + * @return Сохраненное имя пользователя или пустую строку, если имя не найдено + */ + fun getUserName(context: Context): String { + return getPref(context).getString(KEY_USER_NAME, "") ?: "" + } + + /** + * Сохранение статуса авторизации + * @param context Контекст приложения + * @param isLoggedIn Статус авторизации + */ + fun saveLoginStatus(context: Context, isLoggedIn: Boolean) { + val editor = getPref(context).edit() + editor.putBoolean(KEY_IS_LOGGED_IN, isLoggedIn) + editor.apply() + } + + /** + * Получение статуса авторизации + * @param context Контекст приложения + * @return true если пользователь авторизован, false в противном случае + */ + fun isLoggedIn(context: Context): Boolean { + return getPref(context).getBoolean(KEY_IS_LOGGED_IN, false) + } + + /** + * Очистка всех сохраненных данных + * @param context Контекст приложения + */ + fun clearAll(context: Context) { + val editor = getPref(context).edit() + editor.clear() + editor.apply() + } + + fun conclusionView(context: Context):String { + val prefDoctor: SharedPreferences = context.getSharedPreferences("VIEW", Context.MODE_PRIVATE) + val view = prefDoctor.getString("view","") + return view.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Pref/SavePref.kt b/app/src/main/java/com/example/rehabilitation/Pref/SavePref.kt new file mode 100644 index 0000000..7f0d8fa --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Pref/SavePref.kt @@ -0,0 +1,20 @@ +package com.example.rehabilitation.Pref + +import android.content.Context +import android.content.SharedPreferences + +class SavePref (){ + + fun saveToken(context: Context,token: String) { + val prefPatient: SharedPreferences = context.getSharedPreferences("PATIENT", Context.MODE_PRIVATE) + val edit = prefPatient.edit() + prefPatient.edit().putString("token", token).apply() + } + + fun saveView(context: Context,view: String) { + val prefPatient: SharedPreferences = context.getSharedPreferences("VIEW", Context.MODE_PRIVATE) + val edit = prefPatient.edit() + prefPatient.edit().putString("view", view).apply() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Progress/AfterListModel.kt b/app/src/main/java/com/example/rehabilitation/Progress/AfterListModel.kt new file mode 100644 index 0000000..fa3f94d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/AfterListModel.kt @@ -0,0 +1,19 @@ +package com.example.rehabilitation.Progress + +data class AfterListModel( + val id: Int, + val one: String, + val two: String, + val thee:String, + val four:String, + val five:String, + val six:String, + val seven:String, + val eight:String, + val nine:String, + val ten:String, + val eleven:String, + val twelve:String, + val date:String, + ) + diff --git a/app/src/main/java/com/example/rehabilitation/Progress/BeforeListModel.kt b/app/src/main/java/com/example/rehabilitation/Progress/BeforeListModel.kt new file mode 100644 index 0000000..07b7cc3 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/BeforeListModel.kt @@ -0,0 +1,18 @@ +package com.example.rehabilitation.Progress + +data class BeforeListModel( + val id: Int, + val one: String, + val two: String, + val thee:String, + val four:String, + val five:String, + val six:String, + val seven:String, + val eight:String, + val nine:String, + val date:String, + + + ) + diff --git a/app/src/main/java/com/example/rehabilitation/Progress/ProgresFragment.kt b/app/src/main/java/com/example/rehabilitation/Progress/ProgresFragment.kt new file mode 100644 index 0000000..3a20ddd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/ProgresFragment.kt @@ -0,0 +1,202 @@ +package com.example.rehabilitation.Progress + +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Sport.SceduleFragment +import com.example.rehabilitation.databinding.FragmentProgresBinding +import com.example.sqlitework.dip.MainViewModel +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 ProgresFragment : Fragment() { + private lateinit var binding: FragmentProgresBinding + private val model: MainViewModel by activityViewModels()//Инициализировали класс + + //Хранинение токена + private var prefToken: SharedPreferences? = null + private var Token = "" + private lateinit var patientApi: PatientApi + lateinit var adapterProgress: ProgressAdapter + var view_progress = false + + val prefPatientConclusion = ConclusionPref() + + var progresList : List? = null + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentProgresBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + prefToken = activity?.getSharedPreferences("token", Context.MODE_PRIVATE) + Token = prefToken?.getString("token", "")!! + + model.liveProgressCheckList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + if(progresList != it){ + progresList = it + if(it.isEmpty()){ + binding.txtLoadProgres.visibility = View.VISIBLE + visible1() + initRCView() + } + else{ + adapterProgress.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter) + binding.txtLoadProgres.visibility = View.GONE + visible1() + } + } + + } + + initRetrofit() + initRCView() + visibleLoad() + ProgressPatientCourses() + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// ProgressPatientCourses() +// } +// } + + binding.button7.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } + } + + + //Функция получения данных для заполнения списка прогресса + + 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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + + + //Вывод прогресса пациента + fun ProgressPatientCourses() { + if (enternetCheck.isOnline(requireContext())) { + Log.i("sdasd2312","312ewqds") + if (view_progress == false) { + view_progress = true + visibleLoad() + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val progress = patientApi.ProgressPatientCourses("Bearer $Tokens") + + activity?.runOnUiThread { + //Фиксируем полученные данные + val List = progress.body() + val Nice = progress.isSuccessful + val Code = progress.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + model.liveProgressCheckList.value = List?.search_check_sport + binding.txtLoadProgres.visibility = View.GONE + } + } + else{ + binding.txtLoadProgres.visibility = View.VISIBLE + visible1() + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + private fun initRCView() = with(binding) { + rcViewProgress.layoutManager = LinearLayoutManager( + requireContext(), + LinearLayoutManager.VERTICAL, + false + )//По вертикали будет выводить по умолчанию + adapterProgress = ProgressAdapter() + rcViewProgress.adapter = adapterProgress + } + + fun visible1() { + binding.CLMainProgres.visibility = View.VISIBLE + binding.CLLoad.visibility = View.GONE + } + + + fun visibleLoad() { + binding.CLMainProgres.visibility = View.GONE + binding.CLLoad.visibility = View.VISIBLE + } + + companion object { + fun newInstance() = ProgresFragment() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Progress/ProgressAdapter.kt b/app/src/main/java/com/example/rehabilitation/Progress/ProgressAdapter.kt new file mode 100644 index 0000000..22a5f0d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/ProgressAdapter.kt @@ -0,0 +1,76 @@ +package com.example.rehabilitation.Progress + +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.rehabilitation.R +import com.example.rehabilitation.databinding.RcItemProgressBinding + + +class ProgressAdapter() : ListAdapter(Comparator()) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View) : + RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = + RcItemProgressBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: ProgressModel? = + null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + @SuppressLint("SuspiciousIndentation", "SetTextI18n") + fun bind(item: ProgressModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + txtNumber.text = item.number.toString()+ ". " + txtDate.text = item.day + " - " +item.count.toString() + "/" + item.count_workout_max.toString() + //txtProgress.text = + if (item.count_workout_max != item.count) { + CardViewDay.setCardBackgroundColor(Color.parseColor("#1993FF")) + } else { + CardViewDay.setCardBackgroundColor(Color.parseColor("#98EA88")) + } + } + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.rc_item_progress, parent, false)//Создаем(надуваем) list_item + return Holder(view)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: ProgressModel, + newItem: ProgressModel + ): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: ProgressModel, + newItem: ProgressModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Progress/ProgressListModel.kt b/app/src/main/java/com/example/rehabilitation/Progress/ProgressListModel.kt new file mode 100644 index 0000000..612a898 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/ProgressListModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Progress + +data class ProgressListModel( + val search_check_sport: List, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Progress/ProgressModel.kt b/app/src/main/java/com/example/rehabilitation/Progress/ProgressModel.kt new file mode 100644 index 0000000..079e6dc --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Progress/ProgressModel.kt @@ -0,0 +1,12 @@ +package com.example.rehabilitation.Progress + +data class ProgressModel( + val number: Int, + val id: Int, + val day: String, + var count_workout_max: Int, + var count: Int, + val finish: Int, + +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterLookModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterLookModel.kt new file mode 100644 index 0000000..9a1fa26 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterLookModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class AfterLookModel( + val after_look: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireMessage.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireMessage.kt new file mode 100644 index 0000000..2bf1b6f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireMessage.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class AfterQuestionnaireMessage( + val message: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireModel.kt new file mode 100644 index 0000000..8f2648d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/AfterQuestionnaireModel.kt @@ -0,0 +1,17 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class AfterQuestionnaireModel( + 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/rehabilitation/Questionnaire/Model/BeforeLookModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeLookModel.kt new file mode 100644 index 0000000..bc124f5 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeLookModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class BeforeLookModel( + val before_look: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireMessage.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireMessage.kt new file mode 100644 index 0000000..0bb1392 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireMessage.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class BeforeQuestionnaireMessage( + val message: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireModel.kt new file mode 100644 index 0000000..8936b1b --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/BeforeQuestionnaireModel.kt @@ -0,0 +1,14 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class BeforeQuestionnaireModel( + 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, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireModel.kt new file mode 100644 index 0000000..b2249ff --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Questionnaire.Model + +data class QuestionnaireModel( + val massage: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireViewModel.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireViewModel.kt new file mode 100644 index 0000000..88ba36a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/Model/QuestionnaireViewModel.kt @@ -0,0 +1,107 @@ +package com.example.rehabilitation.Questionnaire.Model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.rehabilitation.Model.Questionnaire +import com.example.rehabilitation.Model.QuestionnaireRepository +import kotlinx.coroutines.launch + +/** + * ViewModel для управления данными анкет + * Отвечает за загрузку, сохранение и обновление анкет + */ +class QuestionnaireViewModel : ViewModel() { + // Репозиторий для работы с данными анкет + private val repository = QuestionnaireRepository() + + // LiveData для хранения списка анкет + private val _questionnaires = MutableLiveData>() + val questionnaires: LiveData> = _questionnaires + + // LiveData для хранения статуса загрузки + private val _isLoading = MutableLiveData() + val isLoading: LiveData = _isLoading + + // LiveData для хранения результата сохранения + private val _saveResult = MutableLiveData() + val saveResult: LiveData = _saveResult + + // LiveData для хранения ошибок + private val _error = MutableLiveData() + val error: LiveData = _error + + /** + * Загрузка списка анкет для пациента + * @param patientId ID пациента + */ + fun loadQuestionnaires(patientId: Int) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.getQuestionnaires(patientId) + _questionnaires.value = result + } catch (e: Exception) { + _error.value = e.message ?: "Ошибка при загрузке анкет" + } finally { + _isLoading.value = false + } + } + } + + /** + * Сохранение новой анкеты + * @param questionnaire Анкета для сохранения + */ + fun saveQuestionnaire(questionnaire: Questionnaire) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.saveQuestionnaire(questionnaire) + _saveResult.value = SaveResult.Success(result) + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Ошибка при сохранении анкеты") + } finally { + _isLoading.value = false + } + } + } + + /** + * Обновление существующей анкеты + * @param questionnaire Анкета для обновления + */ + fun updateQuestionnaire(questionnaire: Questionnaire) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.updateQuestionnaire(questionnaire) + _saveResult.value = SaveResult.Success(result) + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Ошибка при обновлении анкеты") + } finally { + _isLoading.value = false + } + } + } + + /** + * Получение ID пациента + * @return ID пациента + */ + fun getPatientId(): Int { + return repository.getPatientId() + } + + /** + * Класс для хранения результата операции сохранения + */ + sealed class SaveResult { + data class Success(val questionnaire: Questionnaire) : SaveResult() + data class Error(val error: String) : SaveResult() + + val isSuccess: Boolean + get() = this is Success + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/QAfterFragment.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/QAfterFragment.kt new file mode 100644 index 0000000..0540160 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/QAfterFragment.kt @@ -0,0 +1,133 @@ +package com.example.rehabilitation.Questionnaire + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.example.rehabilitation.Model.Questionnaire +import com.example.rehabilitation.Model.QuestionnaireViewModel +import com.example.rehabilitation.databinding.FragmentQAfterBinding + +/** + * Фрагмент для отображения и заполнения анкеты после занятий + * Позволяет пользователю оценить свое состояние после реабилитационных упражнений + */ +class QAfterFragment : Fragment() { + // ViewBinding для безопасного доступа к UI элементам + private var _binding: FragmentQAfterBinding? = null + private val binding get() = _binding!! + + // ViewModel для управления данными анкеты + private val viewModel: QuestionnaireViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentQAfterBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями в ViewModel + observeViewModel() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Сохранить" + binding.saveButton.setOnClickListener { + saveQuestionnaire() + } + } + + /** + * Наблюдение за изменениями в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за статусом загрузки + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE + binding.saveButton.isEnabled = !isLoading + } + + // Наблюдение за результатом сохранения + viewModel.saveResult.observe(viewLifecycleOwner) { result -> + when (result) { + is QuestionnaireViewModel.SaveResult.Success -> { + // При успешном сохранении очищаем поля ввода + clearInputs() + } + is QuestionnaireViewModel.SaveResult.Error -> { + // При ошибке показываем сообщение + Toast.showShort(requireContext(), result.message) + } + } + } + } + + /** + * Сохранение анкеты + */ + private fun saveQuestionnaire() { + // Получение данных из полей ввода + val painLevel = binding.painLevelInput.text.toString().toIntOrNull() + val mobilityLevel = binding.mobilityLevelInput.text.toString().toIntOrNull() + val fatigueLevel = binding.fatigueLevelInput.text.toString().toIntOrNull() + val notes = binding.notesInput.text.toString() + + // Проверка валидности данных + if (painLevel == null || painLevel !in 0..10) { + Toast.showShort(requireContext(), "Уровень боли должен быть от 0 до 10") + return + } + + if (mobilityLevel == null || mobilityLevel !in 0..10) { + Toast.showShort(requireContext(), "Уровень подвижности должен быть от 0 до 10") + return + } + + if (fatigueLevel == null || fatigueLevel !in 0..10) { + Toast.showShort(requireContext(), "Уровень усталости должен быть от 0 до 10") + return + } + + // Создание объекта анкеты + val questionnaire = Questionnaire( + painLevel = painLevel, + mobilityLevel = mobilityLevel, + fatigueLevel = fatigueLevel, + notes = notes, + type = "AFTER" + ) + + // Сохранение анкеты через ViewModel + viewModel.saveQuestionnaire(questionnaire) + } + + /** + * Очистка полей ввода + */ + private fun clearInputs() { + binding.painLevelInput.text?.clear() + binding.mobilityLevelInput.text?.clear() + binding.fatigueLevelInput.text?.clear() + binding.notesInput.text?.clear() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/QBeforeFragment.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/QBeforeFragment.kt new file mode 100644 index 0000000..44090a6 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/QBeforeFragment.kt @@ -0,0 +1,125 @@ +package com.example.rehabilitation.Questionnaire + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.example.rehabilitation.Model.Questionnaire +import com.example.rehabilitation.Model.QuestionnaireViewModel +import com.example.rehabilitation.databinding.FragmentQBeforeBinding + +/** + * Фрагмент для отображения и заполнения анкеты до начала занятий + * Позволяет пользователю ввести информацию о своем состоянии перед началом реабилитации + */ +class QBeforeFragment : Fragment() { + // ViewBinding для безопасного доступа к UI элементам + private var _binding: FragmentQBeforeBinding? = null + private val binding get() = _binding!! + + // ViewModel для управления данными анкеты + private val viewModel: QuestionnaireViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentQBeforeBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями в ViewModel + observeViewModel() + } + + /** + * Настройка обработчиков нажатий на кнопки + */ + private fun setupClickListeners() { + // Обработчик нажатия на кнопку "Сохранить" + binding.saveButton.setOnClickListener { + saveQuestionnaire() + } + } + + /** + * Наблюдение за изменениями в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за статусом загрузки + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE + binding.saveButton.isEnabled = !isLoading + } + + // Наблюдение за результатом сохранения + viewModel.saveResult.observe(viewLifecycleOwner) { result -> + when (result) { + is QuestionnaireViewModel.SaveResult.Success -> { + // При успешном сохранении очищаем поля ввода + clearInputs() + } + is QuestionnaireViewModel.SaveResult.Error -> { + // При ошибке показываем сообщение + Toast.showShort(requireContext(), result.message) + } + } + } + } + + /** + * Сохранение анкеты + */ + private fun saveQuestionnaire() { + // Получение данных из полей ввода + val painLevel = binding.painLevelInput.text.toString().toIntOrNull() + val mobilityLevel = binding.mobilityLevelInput.text.toString().toIntOrNull() + val notes = binding.notesInput.text.toString() + + // Проверка валидности данных + if (painLevel == null || painLevel !in 0..10) { + Toast.showShort(requireContext(), "Уровень боли должен быть от 0 до 10") + return + } + + if (mobilityLevel == null || mobilityLevel !in 0..10) { + Toast.showShort(requireContext(), "Уровень подвижности должен быть от 0 до 10") + return + } + + // Создание объекта анкеты + val questionnaire = Questionnaire( + painLevel = painLevel, + mobilityLevel = mobilityLevel, + notes = notes, + type = "BEFORE" + ) + + // Сохранение анкеты через ViewModel + viewModel.saveQuestionnaire(questionnaire) + } + + /** + * Очистка полей ввода + */ + private fun clearInputs() { + binding.painLevelInput.text?.clear() + binding.mobilityLevelInput.text?.clear() + binding.notesInput.text?.clear() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QAfterFragment.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QAfterFragment.kt new file mode 100644 index 0000000..b28ab6b --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QAfterFragment.kt @@ -0,0 +1,682 @@ +package com.example.rehabilitation.Questionnaire.QuestionnaireFragment + +import android.app.Activity +import android.app.AlertDialog +import android.content.Intent +import android.graphics.Color +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 com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Questionnaire.Model.AfterLookModel +import com.example.rehabilitation.Questionnaire.Model.AfterQuestionnaireModel +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Sport.SceduleFragment +import com.example.rehabilitation.databinding.FragmentQAfterBinding +import com.example.sqlitework.dip.MainViewModel +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 QAfterFragment : Fragment() { + // ViewBinding для доступа к элементам интерфейса + private var _binding: FragmentQAfterBinding? = null + private val binding get() = _binding!! + + // ViewModel для работы с данными анкеты + private lateinit var viewModel: QuestionnaireViewModel + + // ViewModel для работы с основными данными + private val model: MainViewModel by activityViewModels() + // ViewModel для работы с данными пациента + private val modelPatient: PatientViewModel by activityViewModels() + + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + // Таймер для обновления данных + private lateinit var timer: Timer + + // Класс для работы с настройками + val prefPatientConclusion = ConclusionPref() + + // Переменные для хранения ответов на вопросы анкеты + var one = 100 // Уровень боли + var two = 100 // Уровень усталости + var three = 100 // Качество сна + var four = 100 // Наличие температуры + var five = 100 // Наличие кашля + var six = 100 // Наличие насморка + var seven = 100 // Наличие головной боли + var eight = 100 // Наличие тошноты + var nine = 100 // Наличие других симптомов + var ten =100 + var eleven = 100 + var twelve = 100 + + // Флаги для проверки даты + var calendareDate = false + var countDay = 0 + + // Флаг для проверки максимального количества дней + var lookDateSportMax = false + + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + // Модель для хранения результатов анкетирования + var AfterLook: AfterLookModel? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentQAfterBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Инициализация ViewModel + viewModel = activityViewModels()[QuestionnaireViewModel::class.java] + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями данных + observeViewModel() + + viewVisible() + if (isAdded()) { + LookAfter() + modelPatient.afterLook.observe(viewLifecycleOwner) { + if( AfterLook != it){ + if(it.after_look == 1){ + AfterLook = it + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } + else{ + AfterLook = it + After() + } + } + } + } + } + + /** + * Настройка обработчиков нажатий + */ + private fun setupClickListeners() { + // Обработка нажатия кнопки сохранения + binding.btnSaveQuestionnaire.setOnClickListener { + if (validateInput()) { + saveQuestionnaire() + } + } + + // Обработка нажатия кнопки отмены + binding.btnBack.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } + } + + /** + * Проверка введенных данных + * @return true если данные валидны, false в противном случае + */ + private fun validateInput(): Boolean { + // Проверка выбора самочувствия + if (binding.rgWellbeing.checkedRadioButtonId == -1) { + showErrorToast(requireContext(), "Выберите ваше самочувствие") + return false + } + + // Проверка выбора уровня боли + if (binding.rgPain.checkedRadioButtonId == -1) { + showErrorToast(requireContext(), "Выберите уровень боли") + return false + } + + // Проверка выбора уровня усталости + if (binding.rgFatigue.checkedRadioButtonId == -1) { + showErrorToast(requireContext(), "Выберите уровень усталости") + return false + } + + // Проверка ввода комментария + if (binding.etComment.text.toString().trim().isEmpty()) { + showErrorToast(requireContext(), "Введите комментарий") + return false + } + + return true + } + + /** + * Сохранение данных анкеты + */ + private fun saveQuestionnaire() { + val questionnaire = Questionnaire( + type = "AFTER", + wellbeing = when (binding.rgWellbeing.checkedRadioButtonId) { + binding.rbWellbeingGood.id -> "GOOD" + binding.rbWellbeingNormal.id -> "NORMAL" + binding.rbWellbeingBad.id -> "BAD" + else -> "NORMAL" + }, + painLevel = when (binding.rgPain.checkedRadioButtonId) { + binding.rbPainNone.id -> "NONE" + binding.rbPainLow.id -> "LOW" + binding.rbPainMedium.id -> "MEDIUM" + binding.rbPainHigh.id -> "HIGH" + else -> "NONE" + }, + fatigueLevel = when (binding.rgFatigue.checkedRadioButtonId) { + binding.rbFatigueNone.id -> "NONE" + binding.rbFatigueLow.id -> "LOW" + binding.rbFatigueMedium.id -> "MEDIUM" + binding.rbFatigueHigh.id -> "HIGH" + else -> "NONE" + }, + comment = binding.etComment.text.toString().trim() + ) + + viewModel.saveQuestionnaire(questionnaire) + } + + /** + * Наблюдение за изменениями данных в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за статусом загрузки + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + binding.progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE + binding.btnSaveQuestionnaire.isEnabled = !isLoading + } + + // Наблюдение за результатом сохранения + viewModel.saveResult.observe(viewLifecycleOwner) { result -> + result?.let { + if (it.success) { + showSuccessToast(requireContext(), "Анкета успешно сохранена") + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } else { + showErrorToast(requireContext(), it.message) + } + } + } + + // Наблюдение за ошибками + viewModel.error.observe(viewLifecycleOwner) { error -> + error?.let { + showErrorToast(requireContext(), it) + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + /** + * Инициализация обработчиков кнопок анкеты + */ + private fun After() { + viewMainAfter() + buttenAdd() + } + + /** + * Инициализация подключения к серверу + */ + 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() + + patientApi = retrofit.create(PatientApi::class.java) + } + + /** + * Отправка анкеты на сервер + * @param item Модель с данными анкеты + */ + fun AfterQuestionnaire(item:AfterQuestionnaireModel) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val QA = patientApi.AddAfterQuestionnaire2("Bearer $Tokens",item) + requireActivity().runOnUiThread { + // Обработка ответа от сервера + val List = QA.body() + val Nice = QA.isSuccessful + val Code = QA.code() + + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(requireContext(), Code429Activity::class.java) + activity?.finish() + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + viewVisible() + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + } + } + } + } + 500 -> { + // Ошибка сервера + val intetn = Intent(requireContext(), Code500Activity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + fun viewMainAfter(){ + binding.CLLoad.visibility = View.GONE + binding.CLMainAfter.visibility = View.VISIBLE + } + + fun viewVisible(){ + binding.CLLoad.visibility = View.VISIBLE + binding.CLMainAfter.visibility = View.GONE + } + + /** + * Инициализация обработчиков кнопок для всех вопросов анкеты + */ + private fun buttenAdd() { + buttenAdd1() + buttenAdd2() + buttenAdd3() + buttenAdd4() + buttenAdd5() + buttenAdd6() + buttenAdd7() + buttenAdd8() + buttenAdd9() + buttenAdd10() + buttenAdd11() + buttenAdd12() + } + + /** + * Инициализация обработчиков кнопок для первого вопроса (уровень боли) + */ + private fun buttenAdd1() { + binding.CVQ10.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 0 + } + binding.CVQ11.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 1 + } + binding.CVQ12.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 2 + } + binding.CVQ13.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 3 + } + binding.CVQ14.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 4 + + } + binding.CVQ15.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 5 + } + binding.CVQ16.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 6 + } + binding.CVQ17.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 7 + } + binding.CVQ18.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 8 + } + binding.CVQ19.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + one = 9 + } + binding.CVQ110.setOnClickListener { + binding.CVQ10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 10 + } + } + + private fun buttenAdd2() { + binding.CVQyes2.setOnClickListener { + binding.CVQyes2.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno2.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + two = 1 + } + binding.CVQno2.setOnClickListener { + binding.CVQyes2.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno2.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + two = 0 + } + } + + private fun buttenAdd3() { + binding.CVQyes3.setOnClickListener { + Log.d("CVQyes3", "CVQyes3") + binding.CVQyes3.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno3.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + three = 1 + } + binding.CVQno3.setOnClickListener { + binding.CVQyes3.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno3.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + three = 0 + } + } + + private fun buttenAdd4() { + binding.CVQyes4.setOnClickListener { + binding.CVQyes4.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno4.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + four = 1 + } + binding.CVQno4.setOnClickListener { + binding.CVQyes4.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno4.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + four = 0 + } + } + + private fun buttenAdd5() { + binding.CVQyes5.setOnClickListener { + binding.CVQyes5.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno5.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + five = 1 + } + binding.CVQno5.setOnClickListener { + binding.CVQyes5.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno5.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + five = 0 + } + } + + private fun buttenAdd6() { + binding.CVQyes6.setOnClickListener { + binding.CVQyes6.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno6.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + six = 1 + } + binding.CVQno6.setOnClickListener { + binding.CVQyes6.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno6.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + six =0 + } + } + + private fun buttenAdd7() { + binding.CVQyes7.setOnClickListener { + binding.CVQyes7.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno7.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + seven = 1 + } + binding.CVQno7.setOnClickListener { + binding.CVQyes7.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno7.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + seven =0 + } + } + + private fun buttenAdd8() { + binding.CVQyes8.setOnClickListener { + binding.CVQyes8.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno8.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + eight = 1 + } + binding.CVQno8.setOnClickListener { + binding.CVQyes8.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno8.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + eight = 0 + } + } + + private fun buttenAdd9() { + binding.CVQyes9.setOnClickListener { + binding.CVQyes9.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno9.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + nine = 1 + } + binding.CVQno9.setOnClickListener { + binding.CVQyes9.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno9.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + nine = 0 + } + } + + private fun buttenAdd10() { + binding.CVQyes10.setOnClickListener { + binding.CVQyes10.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + ten = 1 + } + binding.CVQno10.setOnClickListener { + binding.CVQyes10.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno10.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + ten = 0 + } + } + + private fun buttenAdd11() { + binding.CVQyes11.setOnClickListener { + binding.CVQyes11.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + eleven = 1 + } + binding.CVQno11.setOnClickListener { + binding.CVQyes11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno11.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + eleven = 0 + } + } + + private fun buttenAdd12() { + binding.CVQyes12.setOnClickListener { + binding.CVQyes12.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + twelve = 1 + } + binding.CVQno12.setOnClickListener { + binding.CVQyes12.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno12.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + twelve = 0 + } + } + + override fun onStart() { + super.onStart() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + timer.purge() + } + + /** + * Запуск таймера для периодического обновления данных + * @param daemonIsTrue Флаг для запуска таймера в фоновом режиме + */ + private fun checkForUpdates(daemonIsTrue: Boolean) { + timer = fixedRateTimer("default", daemonIsTrue, 0, 15000) { + activity?.runOnUiThread { + LookAfter() + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QBeforeFragment.kt b/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QBeforeFragment.kt new file mode 100644 index 0000000..3ac7906 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Questionnaire/QuestionnaireFragment/QBeforeFragment.kt @@ -0,0 +1,538 @@ +package com.example.rehabilitation.Questionnaire.QuestionnaireFragment + +import android.app.AlertDialog +import android.content.Intent +import android.graphics.Color +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 com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Questionnaire.Model.AfterLookModel +import com.example.rehabilitation.Questionnaire.Model.BeforeLookModel +import com.example.rehabilitation.Questionnaire.Model.BeforeQuestionnaireModel +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.Sport.SceduleFragment +import com.example.rehabilitation.databinding.FragmentQBeforeBinding +import com.example.sqlitework.dip.MainViewModel +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 QBeforeFragment : Fragment() { + // ViewBinding для доступа к элементам интерфейса + private var _binding: FragmentQBeforeBinding? = null + private val binding get() = _binding!! + + // ViewModel для работы с основными данными + private val model: MainViewModel by activityViewModels() + // ViewModel для работы с данными пациента + private val modelPatient: PatientViewModel by activityViewModels() + + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + // Таймер для обновления данных + private lateinit var timer: Timer + + // Класс для работы с настройками + val prefPatientConclusion = ConclusionPref() + + // Переменные для хранения ответов на вопросы анкеты + var one = 100 // Уровень боли + var two = 100 // Уровень усталости + var three = 100 // Качество сна + var four = 100 // Наличие температуры + var five = 100 // Наличие кашля + var six = 100 // Наличие насморка + var seven = 100 // Наличие головной боли + var eight = 100 // Наличие тошноты + var nine = 100 // Наличие других симптомов + + // Флаги для проверки даты + var calendareDate = false + var countDay = 0 + + // Флаг для проверки максимального количества дней + var lookDateSportMax = false + + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + // Модель для хранения результатов анкетирования + var BeforeLook: BeforeLookModel? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentQBeforeBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Настройка обработчиков нажатий + setupClickListeners() + + // Наблюдение за изменениями данных + observeViewModel() + } + + /** + * Настройка обработчиков нажатий + */ + private fun setupClickListeners() { + // Обработка нажатия кнопки сохранения + binding.btnSaveQuestionnaire.setOnClickListener { + if (validateInput()) { + saveQuestionnaire() + } + } + + // Обработка нажатия кнопки выхода + binding.btnExitQB.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } + } + + /** + * Проверка введенных данных + * @return true если данные валидны, false в противном случае + */ + private fun validateInput(): Boolean { + // Проверка заполнения всех полей + if (one != 100 && two != 100 && three != 100 && four != 100 && + five != 100 && six != 100 && seven != 100 && eight != 100 && nine != 100) { + + if (one >= 6) { + // Предупреждение о блокировке при высоком уровне боли + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к блокировке комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + saveQuestionnaire() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + }.show() + } else if (four == 1 && five == 1 && six == 1 && seven == 1 && nine == 1) { + // Предупреждение о паузе при наличии симптомов + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к паузе комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + saveQuestionnaire() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + }.show() + } else { + // Отправка анкеты без предупреждений + saveQuestionnaire() + } + } else { + // Предупреждение о незаполненных полях + Toast(requireContext()).showCustomInfoToast( + "Не все пункты выбраны", + requireActivity() + ) + } + return false + } + + /** + * Сохранение данных анкеты + */ + private fun saveQuestionnaire() { + val item = BeforeQuestionnaireModel( + one, + two, + three, + four, + five, + six, + seven, + eight, + nine, + ) + BeforeQuestionnaire(item) + } + + /** + * Наблюдение за изменениями данных в ViewModel + */ + private fun observeViewModel() { + // Наблюдение за результатом сохранения + modelPatient.saveResult.observe(viewLifecycleOwner) { result -> + result?.let { + if (it.success) { + showSuccessToast(requireContext(), it.message) + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } else { + showErrorToast(requireContext(), it.message) + } + } + } + + // Наблюдение за ошибками + modelPatient.error.observe(viewLifecycleOwner) { error -> + error?.let { + showErrorToast(requireContext(), it) + } + } + } + + /** + * Инициализация подключения к серверу + */ + private fun initRetrofit() { + // Настройка логирования + val interceptor = HttpLoggingInterceptor() + interceptor.level = HttpLoggingInterceptor.Level.BODY + + // Создание HTTP клиента + val client = OkHttpClient + .Builder() + .addInterceptor(interceptor) + .build() + + // Инициализация Retrofit + val retrofit = Retrofit.Builder() + .baseUrl("https://rehabilitation.vmeda.org/api/") + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + patientApi = retrofit.create(PatientApi::class.java) + } + + /** + * Отправка анкеты на сервер + * @param item Модель с данными анкеты + */ + fun BeforeQuestionnaire(item: BeforeQuestionnaireModel) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val QA = patientApi.AddBeforeQuestionnaire2("Bearer $Tokens", item) + requireActivity().runOnUiThread { + // Обработка ответа от сервера + val List = QA.body() + val Nice = QA.isSuccessful + val Code = QA.code() + + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(requireContext(), Code429Activity::class.java) + activity?.finish() + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + if (List != null) { + showSuccessToast(requireContext(), List.message) + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + } else { + showErrorToast(requireContext(), "Ошибка при отправке") + } + } + } + 500 -> { + // Ошибка сервера + val intetn = Intent(requireContext(), Code500Activity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } + } else { + // Нет интернет-соединения + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + /** + * Проверка результатов предыдущего анкетирования + */ + fun LookBefore() { + if (enternetCheck.isOnline(requireActivity())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listBefore = patientApi.LookBeforeQuestionnaire2("Bearer $Tokens") + requireActivity().runOnUiThread { + // Обработка ответа от сервера + val List = listBefore.body() + val Nice = listBefore.isSuccessful + val Code = listBefore.code() + + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(requireContext(), Code429Activity::class.java) + activity?.finish() + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + if (List != null) { + modelPatient.beforeLook.value = List + } + } + } + 500 -> { + // Ошибка сервера + val intetn = Intent(requireContext(), Code500Activity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } + } else { + // Нет интернет-соединения + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + /** + * Инициализация обработчиков кнопок для всех вопросов анкеты + */ + private fun buttenAdd() { + buttenAdd1() + buttenAdd2() + buttenAdd3() + buttenAdd4() + buttenAdd5() + buttenAdd6() + buttenAdd7() + buttenAdd8() + buttenAdd9() + } + + /** + * Инициализация обработчиков кнопок для первого вопроса (уровень боли) + */ + private fun buttenAdd1() { + binding.CVQ11.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#FFFFFF")) + one = 1 + } + binding.CVQ12.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 2 + } + binding.CVQ13.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 3 + } + binding.CVQ14.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 4 + } + binding.CVQ15.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 5 + } + binding.CVQ16.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 6 + } + binding.CVQ17.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 7 + } + binding.CVQ18.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 8 + } + binding.CVQ19.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 9 + } + binding.CVQ110.setOnClickListener { + binding.CVQ11.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + one = 10 + } + } + + private fun buttenAdd2() { + binding.CVQyes2.setOnClickListener { + binding.CVQyes2.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno2.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + two = 1 + } + binding.CVQno2.setOnClickListener { + binding.CVQyes2.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno2.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + two = 0 + } + } + + private fun buttenAdd3() { + binding.CVQyes3.setOnClickListener { + binding.CVQyes3.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno3.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + three = 1 + } + binding.CVQno3.setOnClickListener { + binding.CVQyes3.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno3.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + three = 0 + } + } + + private fun buttenAdd4() { + binding.CVQyes4.setOnClickListener { + binding.CVQyes4.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno4.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + four = 1 + } + binding.CVQno4.setOnClickListener { + binding.CVQyes4.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno4.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + four = 0 + } + } + + private fun buttenAdd5() { + binding.CVQyes5.setOnClickListener { + binding.CVQyes5.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno5.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + five = 1 + } + binding.CVQno5.setOnClickListener { + binding.CVQyes5.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno5.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + five = 0 + } + } + + private fun buttenAdd6() { + binding.CVQyes6.setOnClickListener { + binding.CVQyes6.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno6.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + six = 1 + } + binding.CVQno6.setOnClickListener { + binding.CVQyes6.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno6.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + six = 0 + } + } + + private fun buttenAdd7() { + binding.CVQyes7.setOnClickListener { + binding.CVQyes7.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno7.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + seven = 1 + } + binding.CVQno7.setOnClickListener { + binding.CVQyes7.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno7.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + seven = 0 + } + } + + private fun buttenAdd8() { + binding.CVQyes8.setOnClickListener { + binding.CVQyes8.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno8.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + eight = 1 + } + binding.CVQno8.setOnClickListener { + binding.CVQyes8.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno8.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + eight = 0 + } + } + + private fun buttenAdd9() { + binding.CVQyes9.setOnClickListener { + binding.CVQyes9.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno9.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + nine = 1 + } + binding.CVQno9.setOnClickListener { + binding.CVQyes9.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno9.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + nine = 0 + } + } + + override fun onStart() { + super.onStart() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + } + + /** + * Запуск таймера для периодического обновления данных + * @param daemonIsTrue Флаг для запуска таймера в фоновом режиме + */ + private fun checkForUpdates(daemonIsTrue: Boolean) { + timer = fixedRateTimer("default", daemonIsTrue, 0, 15000) { + activity?.runOnUiThread { + LookBefore() + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Retrofit/PatientApi.kt b/app/src/main/java/com/example/rehabilitation/Retrofit/PatientApi.kt new file mode 100644 index 0000000..e5230e7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Retrofit/PatientApi.kt @@ -0,0 +1,178 @@ +package com.example.rehabilitation.Retrofit + +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsNewListModel +import com.example.rehabilitation.Appeals.TabLayout.Model.AppealsOldListModel +import com.example.rehabilitation.Auth.Model.AuthModel +import com.example.rehabilitation.Auth.Model.CheckTokenModel +import com.example.rehabilitation.Auth.Model.UserModel +import com.example.rehabilitation.Calendare.CalendareListModel +import com.example.rehabilitation.Calendare.CalendareModel +import com.example.rehabilitation.MessageModel +import com.example.rehabilitation.Progress.ProgressListModel +import com.example.rehabilitation.Progress.ProgressModel +import com.example.rehabilitation.Questionnaire.Model.AfterLookModel +import com.example.rehabilitation.Questionnaire.Model.AfterQuestionnaireMessage +import com.example.rehabilitation.Questionnaire.Model.AfterQuestionnaireModel +import com.example.rehabilitation.Questionnaire.Model.BeforeLookModel +import com.example.rehabilitation.Questionnaire.Model.BeforeQuestionnaireMessage +import com.example.rehabilitation.Questionnaire.Model.BeforeQuestionnaireModel +import com.example.rehabilitation.Questionnaire.Model.QuestionnaireModel +import com.example.rehabilitation.Sport.DayListModel +import com.example.rehabilitation.Sport.DayModel +import com.example.rehabilitation.Sport.SportDayOneModel +import com.example.rehabilitation.Sport.SportForDayListModel +import com.example.rehabilitation.Sport.SportForDayModel +import com.example.rehabilitation.Sport.SportListModel +import com.example.rehabilitation.Sport.UpdateSportTrueFalseModel +import com.example.rehabilitation.Sport.ViewFragmentModel +import com.example.rehabilitation.Sport.ViewVisibleModel +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Headers +import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Query + +interface PatientApi { + + //Проверка токена + @Headers("Content-Type: application/json") + @GET("CheckTokenPatient") + suspend fun CheckToken(@Header("Authorization") token:String) :Response + + //Авторизация + @Headers("Content-Type: application/json") + @POST("LoginPatient") + suspend fun LoginPatient(@Body authModel: AuthModel): Response + + //Выход из аккаунта + @Headers("Content-Type: application/json") + @POST("LogoutPatient") + suspend fun LogoutPatient(@Header("Authorization") token:String):Response + + //Заполнение анкеты ДО + @Headers("Content-Type: application/json") + @POST("AddBeforeQuestionnaire2") + suspend fun AddBeforeQuestionnaire2(@Header("Authorization") token:String,@Body beforeQuestionnaireModel: BeforeQuestionnaireModel): Response + + //Заполнение анкеты ПОСЛЕ + @Headers("Content-Type: application/json") + @POST("AddAfterQuestionnaire2") + suspend fun AddAfterQuestionnaire2(@Header("Authorization") token:String,@Body afterQuestionnaireModel: AfterQuestionnaireModel) : Response + + //Добавление курса на сегодня + @Headers("Content-Type: application/json") + @POST("AddCourses2") + suspend fun AddCourses2(@Header("Authorization") token:String) + + //Вывод списка спортивных задания на 1 день + @Headers("Content-Type: application/json") + @GET("CoutSportCourses") + suspend fun CoutSportCourses(@Header("Authorization") token:String) + + //Вывод нужного экрана + @Headers("Content-Type: application/json") + @GET("VisibleView3") + suspend fun VisibleView3(@Header("Authorization") token:String) :Response + + //Вывод календаря + @Headers("Content-Type: application/json") + @GET("PatientCalendareDay") + suspend fun PatientCalendareDay(@Header("Authorization") token:String):Response + + //Вывод списка упражнений + @Headers("Content-Type: application/json") + @GET("GetSportDay") + suspend fun GetSportDay(@Header("Authorization") token:String):Response + + //Вывод определенного упражнения + @Headers("Content-Type: application/json") + @GET("GetSportDayOne") + suspend fun GetSportDayOne(@Header("Authorization") token:String,@Query("id") id:Int):Response + + //Подтвержденеи упражнения + @Headers("Content-Type: application/json") + @PUT("AddSportCheck") + suspend fun AddSportCheck(@Header("Authorization") token:String,@Query("id") id:Int, @Query("check") check:Int):Response + + //Список прогресса по дням + @Headers("Content-Type: application/json") + @GET("ProgressPatientCourses") + suspend fun ProgressPatientCourses(@Header("Authorization") token:String):Response + + //Вывод необработанных сообщений + @Headers("Content-Type: application/json") + @GET("GetAppealsPatientNew") + suspend fun GetAppealsPatientNew(@Header("Authorization") token:String) :Response + + //Вывод необработанных сообщений + @Headers("Content-Type: application/json") + @GET("GetAppealsPatientOld") + suspend fun GetAppealsPatientOld(@Header("Authorization") token:String) :Response + + + //Подтверждение необработанных сообщений + @Headers("Content-Type: application/json") + @PUT("UpdateMessagePatient") + suspend fun UpdateMessagePatient(@Header("Authorization") token:String,@Query("id") id:Int) :Response + + //Отправка сообщения пациенту + @Headers("Content-Type: application/json") + @POST("AddMessagePatient") + suspend fun AddMessagePatient(@Header("Authorization") token:String, @Query("text") text:String) :Response + + //Вывод есть ли анкета ДО + @Headers("Content-Type: application/json") + @GET("LookBefore") + suspend fun LookBefore(@Header("Authorization") token:String) :Response + + //Вывод есть ли анкета ПОСЛЕ + @Headers("Content-Type: application/json") + @GET("LookAfter") + suspend fun LookAfter(@Header("Authorization") token:String) :Response + + + //Вывод есть ли анкета ПОСЛЕ + @Headers("Content-Type: application/json") + @GET("GetCalendare") + suspend fun GetCalendare(@Header("Authorization") token:String) :Response + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Setting/SettingFragment.kt b/app/src/main/java/com/example/rehabilitation/Setting/SettingFragment.kt new file mode 100644 index 0000000..a0e54bd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Setting/SettingFragment.kt @@ -0,0 +1,173 @@ +package com.example.rehabilitation.Setting + +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.appcompat.app.AlertDialog +import com.example.admin.Toast.showCustomInfoToast +import com.example.rehabilitation.Auth.AuthFragment +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.Feedback.FeedbackFragment +import com.example.rehabilitation.MainFragment +import com.example.rehabilitation.Pref.ClearPref +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.R +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.databinding.FragmentSettingBinding +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 SettingFragment : Fragment() { + private lateinit var binding: FragmentSettingBinding + private var Token = "" + val prefPatientClear = ClearPref() + val prefPatientConclusion = ConclusionPref() + private lateinit var patientApi: PatientApi + + //Класс проверки интеренета + val enternetCheck = EnternetCheck() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentSettingBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if (isAdded()) { + binding.btnExitSetting.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, MainFragment.newInstance()) + //?.addToBackStack(null) + ?.commit() + } + + binding.cvFeedback.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.CLMain, FeedbackFragment.newInstance()) + //?.addToBackStack(null) + ?.commit() + } + + //Выход из аккаунта + binding.cvExitPatient.setOnClickListener { + createAlеrtDialogExitAuth() + } + } + } + + //Диалоговое окно + private fun createAlеrtDialogExitAuth() { + val builder = AlertDialog.Builder(requireContext()) + builder.setTitle("Выход") + builder.setMessage("Вы уверены что хотите выйти из аккаунта") + builder.setNegativeButton("Назад") { dialogInterface, i -> + + } + builder.setPositiveButton("Подтвердить") { dialogInterface, i -> + + Logout() + + } + builder.show() + } + + + //Инициализация подлючения к серверу + 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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + //Получения списка пациентов + fun Logout() { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = patientApi.LogoutPatient("Bearer $Tokens") + + activity?.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) { + Toast(requireContext()).showCustomInfoToast(List?.message.toString(), requireActivity()) + prefPatientClear.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(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + companion object { + fun newInstance() = SettingFragment() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Sport/DayAdapter.kt b/app/src/main/java/com/example/rehabilitation/Sport/DayAdapter.kt new file mode 100644 index 0000000..1c1fefa --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/DayAdapter.kt @@ -0,0 +1,122 @@ +package com.example.rehabilitation.Sport + +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.rehabilitation.R +import com.example.rehabilitation.databinding.RcItemDayBinding + + +class DayAdapter(val listener_zakaz: Listener) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + fun updateData(newList: List) { + val sortedList = newList.sortedBy { it.finish.toInt() } // Сортировка по завершенности + submitList(sortedList) // Обновление списка в адаптере + } + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_zakaz: Listener): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = RcItemDayBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: SportForDayModel? = null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemView.setEnabled(false) + //timerButtonDoubleButton(itemView) + itemTemp?.let { it1 -> listener_zakaz.onClickSport(it1) } + + } + } + +// //Функция bind для заполнения +// +// //ЗАдержка нажатия на кнопку +// private fun timerButtonDoubleButton(btn: View){ +// val updateHandler = Handler() +// +// val runnable = Runnable { +// btn.setEnabled(true) +// } +// +// updateHandler.postDelayed(runnable, 5000) +// } + @SuppressLint("SuspiciousIndentation") + fun bind(item: SportForDayModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + //txtName.text = item.name + //txtCount.text = item.count + //txtImage.text = item.image + txtName.text = item.number.toString() + //txtDay.text = item.day + Log.i("asdasdasd",item.category[0].toString()) + val category = item.category[0].toString() + if (category == "c"){ + binding.imageSport.setImageResource(R.drawable.c_sport) + } + else if (category == "b"){ + binding.imageSport.setImageResource(R.drawable.b_sport) + } + else if (category == "j"){ + binding.imageSport.setImageResource(R.drawable.j_sport) + } + + if(item.finish.toInt() == 0){ + binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + } + else if(item.finish.toInt() == 1) { + binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#98EA88")) + } + else if(item.finish.toInt() == 2){ + binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#A68C78")) + } + + } + + + } + + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.rc_item_day, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_zakaz)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SportForDayModel, newItem: SportForDayModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame(oldItem: SportForDayModel, newItem: SportForDayModel): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickSport(item: SportForDayModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/DayListModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/DayListModel.kt new file mode 100644 index 0000000..ac017ff --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/DayListModel.kt @@ -0,0 +1,11 @@ +package com.example.rehabilitation.Sport + +data class DayListModel( + val id: Int, + val number: String, + val day: String, + val category: String, + val check:String, + //val categoryAlf: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/DayListOneModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/DayListOneModel.kt new file mode 100644 index 0000000..de92fbd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/DayListOneModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Sport + +data class DayListOneModel( + val day: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/DayModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/DayModel.kt new file mode 100644 index 0000000..0e00c4a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/DayModel.kt @@ -0,0 +1,14 @@ +package com.example.rehabilitation.Sport + +data class DayModel( + val id: String, + val name: String, + val desc:String, + val day: String, + val number: String, + // val count: String, + val category: String, + // val image: String, + val check:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountCategoryModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountCategoryModel.kt new file mode 100644 index 0000000..c9bd0de --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountCategoryModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Sport.Image.Category + +data class CountCategoryModel( + val count: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryArticleModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryArticleModel.kt new file mode 100644 index 0000000..32f810f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryArticleModel.kt @@ -0,0 +1,8 @@ +package com.example.rehabilitation.Sport.Image.Category + +data class CountNameCategoryArticleModel( + val count: String, + val name: String, + val article: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryModel.kt new file mode 100644 index 0000000..64eb4de --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/Category/CountNameCategoryModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.Sport.Image.Category + +data class CountNameCategoryModel( + val count: String, + val name: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/Doctor/DoctorModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/Doctor/DoctorModel.kt new file mode 100644 index 0000000..3a84aaa --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/Doctor/DoctorModel.kt @@ -0,0 +1,12 @@ +package com.example.rehabilitation.Sport.Image.Doctor + +data class DoctorModel( + val id: String, + val name:String, + val surname:String, + val patronymic:String, + //val email:String, + val login:String, + val password:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportAdapter.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportAdapter.kt new file mode 100644 index 0000000..c3066b7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportAdapter.kt @@ -0,0 +1,80 @@ +package com.example.rehabilitation.Sport.Image + +import android.annotation.SuppressLint +import android.content.ClipData +import android.content.Context +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 androidx.recyclerview.widget.RecyclerView.ViewHolder +import com.example.rehabilitation.R +import com.example.rehabilitation.databinding.ImageSportCardsBinding +import com.squareup.picasso.Picasso + + +class ImageSportAdapter(val contextF:Context) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View,val contextF:Context): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = ImageSportCardsBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: ImageSportModel? = null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + //itemTemp?.let { it1 -> listener_zakaz.onClickDay(it1) } + + } + } + + //Функция bind для заполнения + @SuppressLint("DiscouragedApi") + fun bind(item: ImageSportModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + Picasso.get().load("https://rehabilitation.vmeda.org"+item.url_image).into(imageSport) + + + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.image_sport_cards, parent, false)//Создаем(надуваем) list_item + return Holder(view, contextF)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ImageSportModel, newItem: ImageSportModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame(oldItem: ImageSportModel, newItem: ImageSportModel): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportModel.kt new file mode 100644 index 0000000..a070c06 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Image/ImageSportModel.kt @@ -0,0 +1,11 @@ +package com.example.rehabilitation.Sport.Image + +data class ImageSportModel( + val id: Int, + val name: String, + val url_image: String, + val article: String, + val created_at: String, + val updated_at: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/Model/ScheduleViewModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/Model/ScheduleViewModel.kt new file mode 100644 index 0000000..176d5cf --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/Model/ScheduleViewModel.kt @@ -0,0 +1,124 @@ +package com.example.rehabilitation.Sport.Model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.rehabilitation.Model.Schedule +import com.example.rehabilitation.Model.ScheduleRepository +import kotlinx.coroutines.launch + +/** + * ViewModel для управления данными расписания + * Отвечает за загрузку, сохранение и обновление занятий + */ +class ScheduleViewModel : ViewModel() { + // Репозиторий для работы с данными + private val repository = ScheduleRepository() + + // LiveData для хранения списка занятий + private val _schedules = MutableLiveData>() + val schedules: LiveData> = _schedules + + // LiveData для хранения статуса загрузки + private val _isLoading = MutableLiveData() + val isLoading: LiveData = _isLoading + + // LiveData для хранения результата сохранения + private val _saveResult = MutableLiveData() + val saveResult: LiveData = _saveResult + + // LiveData для хранения ошибок + private val _error = MutableLiveData() + val error: LiveData = _error + + /** + * Загрузка списка занятий для пациента + * @param patientId ID пациента + */ + fun loadSchedule(patientId: Int = repository.getPatientId()) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.getSchedules(patientId) + _schedules.value = result + _error.value = null + } catch (e: Exception) { + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Сохранение нового занятия + * @param schedule Занятие для сохранения + */ + fun saveSchedule(schedule: Schedule) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.saveSchedule(schedule) + _saveResult.value = SaveResult.Success(result) + _error.value = null + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Ошибка сохранения") + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Обновление существующего занятия + * @param schedule Занятие для обновления + */ + fun updateSchedule(schedule: Schedule) { + viewModelScope.launch { + try { + _isLoading.value = true + val result = repository.updateSchedule(schedule) + _saveResult.value = SaveResult.Success(result) + _error.value = null + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Ошибка обновления") + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Удаление занятия + * @param scheduleId ID занятия + */ + fun deleteSchedule(scheduleId: Int) { + viewModelScope.launch { + try { + _isLoading.value = true + repository.deleteSchedule(scheduleId) + _saveResult.value = SaveResult.Success(null) + _error.value = null + } catch (e: Exception) { + _saveResult.value = SaveResult.Error(e.message ?: "Ошибка удаления") + _error.value = e.message + } finally { + _isLoading.value = false + } + } + } + + /** + * Класс для хранения результата операции сохранения + */ + sealed class SaveResult { + data class Success(val schedule: Schedule?) : SaveResult() + data class Error(val error: String) : SaveResult() + + val isSuccess: Boolean + get() = this is Success + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SceduleAdapter.kt b/app/src/main/java/com/example/rehabilitation/Sport/SceduleAdapter.kt new file mode 100644 index 0000000..3028609 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SceduleAdapter.kt @@ -0,0 +1,103 @@ +package com.example.rehabilitation.Sport + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.example.rehabilitation.Questionnaire.Model.Scedule +import com.example.rehabilitation.databinding.ItemSceduleBinding +import java.text.SimpleDateFormat +import java.util.Locale + +/** + * Адаптер для отображения списка мероприятий в расписании + * Использует DiffUtil для эффективного обновления списка + */ +class SceduleAdapter( + private val onItemClick: (Scedule) -> Unit, + private val onJoinClick: (Scedule) -> Unit +) : ListAdapter(SceduleDiffCallback()) { + + /** + * Создание нового ViewHolder для элемента списка + * @param parent Родительский ViewGroup + * @param viewType Тип представления + * @return Новый экземпляр SceduleViewHolder + */ + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SceduleViewHolder { + val binding = ItemSceduleBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + return SceduleViewHolder(binding) + } + + /** + * Привязка данных к ViewHolder + * @param holder ViewHolder для привязки + * @param position Позиция элемента в списке + */ + override fun onBindViewHolder(holder: SceduleViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + /** + * ViewHolder для элемента расписания + * Содержит привязку к layout файлу и методы для отображения данных + */ + inner class SceduleViewHolder(private val binding: ItemSceduleBinding) : + RecyclerView.ViewHolder(binding.root) { + + private val dateFormat = SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.getDefault()) + + /** + * Привязка данных расписания к элементам интерфейса + * @param scedule Модель данных расписания + */ + fun bind(scedule: Scedule) { + binding.apply { + // Отображение времени занятия + tvTime.text = scedule.time + // Отображение названия занятия + tvName.text = scedule.name + // Отображение описания занятия + tvDescription.text = scedule.description + // Отображение статуса занятия + tvStatus.text = scedule.status + + // Настройка кнопки присоединения + btnJoin.apply { + isEnabled = !scedule.isFull && !scedule.isJoined + text = when { + scedule.isFull -> "Мест нет" + scedule.isJoined -> "Вы участвуете" + else -> "Присоединиться" + } + setOnClickListener { + onJoinClick(scedule) + } + } + + // Обработка нажатия на элемент + root.setOnClickListener { + onItemClick(scedule) + } + } + } + } + + /** + * Callback для сравнения элементов списка + */ + private class SceduleDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Scedule, newItem: Scedule): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: Scedule, newItem: Scedule): Boolean { + return oldItem == newItem + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SceduleFragment.kt b/app/src/main/java/com/example/rehabilitation/Sport/SceduleFragment.kt new file mode 100644 index 0000000..6ec629a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SceduleFragment.kt @@ -0,0 +1,1946 @@ +package com.example.rehabilitation.Sport + +import android.annotation.SuppressLint +import android.app.AlertDialog +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.graphics.Color +import android.media.MediaPlayer +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.admin.Toast.showCustomInfoToast +import com.example.admin.Toast.showCustomNiceToast +import com.example.rehabilitation.Auth.AuthorizationActivity +import com.example.rehabilitation.Block +import com.example.rehabilitation.CodeError.Code429Activity +import com.example.rehabilitation.CodeError.Code500Activity +import com.example.rehabilitation.DayAfter +import com.example.rehabilitation.DayBefore +import com.example.rehabilitation.Enternet.EnternetActivity +import com.example.rehabilitation.Enternet.EnternetCheck +import com.example.rehabilitation.PatientViewModel +import com.example.rehabilitation.PauseDay +import com.example.rehabilitation.Pref.ConclusionPref +import com.example.rehabilitation.Pref.SavePref +import com.example.rehabilitation.Questionnaire.Model.AfterQuestionnaireModel +import com.example.rehabilitation.Questionnaire.Model.BeforeQuestionnaireModel +import com.example.rehabilitation.R +import com.example.rehabilitation.SportMaxCount +import com.example.rehabilitation.SportPlusCount +import com.example.rehabilitation.Questionnaire.QuestionnaireFragment.QAfterFragment +import com.example.rehabilitation.Questionnaire.QuestionnaireFragment.QBeforeFragment +import com.example.rehabilitation.Retrofit.PatientApi +import com.example.rehabilitation.databinding.FragmentSceduleBinding +import com.example.rehabilitation.model_adapter.DataModel +import com.example.rehabilitation.Sport.Image.ImageSportAdapter +import com.example.sqlitework.dip.MainViewModel +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.time.LocalDate +import java.util.Timer +import kotlin.concurrent.fixedRateTimer + +/** + * Фрагмент расписания занятий + * Отвечает за отображение и управление спортивными упражнениями + */ +class SceduleFragment() : Fragment(), DayAdapter.Listener { + // Привязка к layout файлу + private lateinit var binding: FragmentSceduleBinding + + // ViewModel для работы с основными данными + private val model: MainViewModel by activityViewModels() + // ViewModel для работы с данными пациента + private val modelPatient: PatientViewModel by activityViewModels() + // ViewModel для передачи данных между фрагментами + private val dataModel: DataModel by activityViewModels() + + // Адаптеры для списков + lateinit var adapterDay: DayAdapter + lateinit var adapterImage: ImageSportAdapter + + // ID для подтверждения упражнения + var idDaySport = 0 + var idCheckDay = 0 + + // Текущая дата + var date = LocalDate.now().toString() + + // Медиаплеер для метронома + var mMediaPlayer: MediaPlayer? = null + var metronom = false + + // Таймер для открытия упражнения + var time: Long = 0 + var times = 0 + + // Настройки для хранения токена + private var prefToken: SharedPreferences? = null + private var Token = "" + + // API для работы с данными пациента + private lateinit var patientApi: PatientApi + + // Классы для работы с настройками + val prefPatientConclusion = ConclusionPref() + val prefPatientSave = SavePref() + + // Интервал обновления данных (10 секунд) + var viewVisible = 0 + + // Список упражнений на день + var daySportList: List? = null + + // Класс для проверки интернет-соединения + val enternetCheck = EnternetCheck() + + // Переменные для анкеты ДО занятий + var oneB = 100 + var twoB = 100 + var threeB = 100 + var fourB = 100 + var fiveB = 100 + var sixB = 100 + var sevenB = 100 + var eightB = 100 + var nineB = 100 + + // Переменные для анкеты ПОСЛЕ занятий + var oneA = 100 + var twoA = 100 + var threeA = 100 + var fourA = 100 + var fiveA = 100 + var sixA = 100 + var sevenA = 100 + var eightA = 100 + var nineA = 100 + var tenA = 100 + var elevenA = 100 + var twelveA = 100 + + // Таймер для обновления данных + private lateinit var timer: Timer + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentSceduleBinding.inflate(layoutInflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if (isAdded()) { + binding.also { + // Инициализация UI элементов + binding.txtNullSportList.visibility = View.VISIBLE + + // Обработчики нажатий на кнопки анкетирования + binding.button4.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, QAfterFragment.newInstance())?.commit() + } + + // Получение токена из настроек + prefToken = activity?.getSharedPreferences("token", Context.MODE_PRIVATE) + Token = prefToken?.getString("token", "")!! + + // Обработчики нажатий на кнопки анкетирования + binding.button2.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, QBeforeFragment.newInstance())?.commit() + } + + binding.button3.setOnClickListener { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, QAfterFragment.newInstance())?.commit() + } + + // Инициализация списков и загрузка данных + initRcViewDay() + initRcViewImage() + liveReadOrderCurrent() + liveDaySportOne() + + // Наблюдение за изменениями списка дней + model.liveDayList.observe(viewLifecycleOwner) { + if(daySportList != it) { + initRcViewDay() + daySportList = it + adapterDay.submitList(it) + binding.txtNullSportList.visibility = View.GONE + } + } + + // Наблюдение за изменениями списка изображений + model.liveImageList.observe(viewLifecycleOwner) { + adapterImage.submitList(it) + binding.LoadImage.visibility = View.GONE + } + + // Обработчик включения/выключения метронома + binding.btnMp3.setOnClickListener { + if (metronom == true) { + metronom = false + stopSound() + binding.btnMp3.setBackgroundResource(android.R.drawable.ic_media_play) + } else { + metronom = true + playSound() + binding.btnMp3.setBackgroundResource(android.R.drawable.ic_media_pause) + } + } + + // Инициализация кнопок + addButton() + + // Очистка списка + binding.button5.setOnClickListener { + ClearRCView() + } + + // Загрузка данных о видимости элементов + GetVisibleViewList() + + // Наблюдение за изменениями видимости элементов + modelPatient.viewCurrent.observe(viewLifecycleOwner) { + if(viewVisible != it.view) { + viewVisible = it.view + prefPatientSave.saveView(requireContext(), viewVisible.toString()) + VisibleView(it.view, it.text) + } + } + + // Инициализация обработчиков кнопок + clButton() + } + } + + // Инициализация кнопок анкетирования + Before() + After() + + // Проверка расписания + LookScedule() + // Наблюдение за изменениями расписания + modelPatient.sceduleLook.observe(viewLifecycleOwner) { + if (SceduleLook != it) { + SceduleLook = it + Scedule() + } + } + } + + /** + * Инициализация обработчиков кнопок + */ + private fun clButton() = with(binding) { + CLFinal.setOnClickListener {} + CLPaus.setOnClickListener {} + CLBlock.setOnClickListener {} + CLYesNoSport.setOnClickListener {} + CLFinalDay.setOnClickListener {} + CLFinal.setOnClickListener {} + } + + override fun onResume() { + super.onResume() + GetVisibleViewList() + } + + //Инициализация подлючения к серверу + 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() + + patientApi = retrofit.create(PatientApi::class.java) + + } + + + + //Получения экрана + fun GetVisibleViewList() { + if (enternetCheck.isOnline(requireActivity())) { + visibleLoadYes() + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listProduct = patientApi.VisibleView3("Bearer $Tokens") + + activity?.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) { + modelPatient.viewCurrent.value = List + visibleLoadNo() + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + // } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + + } + + + private fun VisibleView(view: Int, text:String) { + Log.i("123asda213s","a123sdasd123") + when (view) { + 1 -> visibleNoSport() + 2 -> visibleFinel() + 3 -> visibleYesNoSport() + 4 -> visibleAfterQ() + 5 -> visibleDayList() + 6 -> visibleFinalDay() + 7 -> visibleAfterQ() + 8 -> visibleBeforeQ() + 9 -> visibleBlock(text) + 10 -> visiblePause(text) + //616-> + else ->{ + visibleLoadYes() + } + + } + + + } + + + //Выводим экран с фразой готовы ли вы начать тренировку + private fun visibleYesNoSport() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.VISIBLE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + //binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + binding.btnYesStartSport.setOnClickListener { +// if (SportUserTrue == 0) { +// Toast(requireContext()).showCustomInfoToast( +// "Попросите врача создать вам курс", +// requireActivity() +// ) +// } else { + visibleBeforeQ() + // } + } + } + + + //Выводим списка тренировок + private fun visibleDayList() { + GetSportDay() + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + //binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + + + + // binding.rcVIewDayList.smoothScrollToPosition(0); + } + + + //Выводим карточку тренировок + private fun visibleDayCard() { + Log.i("1231432", "45678978665") + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.GONE + binding.CLCardSport.visibility = View.VISIBLE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + + } + + + //Выводим экран паузы + private fun visiblePause(text:String) { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.VISIBLE + binding.CLBlock.visibility = View.GONE + binding.txtDatePause.setText("${text}") + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + + //Выводим экран блока + private fun visibleBlock(text:String) { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.txtDateBlock.setText("${text}") + binding.CLBlock.visibility = View.VISIBLE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + + } + + //Выводим сообщенеи от отправке отчета на 7 день + private fun visible7day() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.VISIBLE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + //Выводим сообщенеи от отправке отчета на 15 день + private fun visible15day() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.VISIBLE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + //Выводим экрана окончания курса + private fun visibleFinel() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.VISIBLE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + //Выводим экрана о том что курса нету + private fun visibleNoSport() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.VISIBLE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + //Выводим финал дня тренировок + private fun visibleFinalDay() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.VISIBLE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.GONE + } + + //Переход на накету ДО + private fun visibleBeforeQ() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.VISIBLE + binding.CLAfter.visibility = View.GONE + } + + + + //Переход на накету ПОСЛЕ + private fun visibleAfterQ() { + binding.CLListSport.visibility = View.GONE + binding.CLDayList.visibility = View.VISIBLE + binding.CLCardSport.visibility = View.GONE + binding.CLLoad.visibility = View.GONE + binding.CLYesNoSport.visibility = View.GONE + binding.CLPaus.visibility = View.GONE + binding.CLBlock.visibility = View.GONE + // binding.CL7day.visibility = View.GONE + // binding.CL15day.visibility = View.GONE + binding.CLFinal.visibility = View.GONE + binding.CLNoSport.visibility = View.GONE + binding.CLFinalDay.visibility = View.GONE + binding.CLBefore.visibility = View.GONE + binding.CLAfter.visibility = View.VISIBLE + } + + //Включение загрузки + private fun visibleLoadYes() { + viewVisible = 100 + binding.CLLoad.visibility = View.VISIBLE + } + //Отключение загрузки + private fun visibleLoadNo() { + binding.CLLoad.visibility = View.GONE + } + + + //Получения списка упражнений + fun GetSportDay() { + + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportDay = patientApi.GetSportDay("Bearer $Tokens") + requireActivity().runOnUiThread { + + + //Фиксируем полученные данные + val List = sportDay.body() + val Nice = sportDay.isSuccessful + val Code = sportDay.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + model.liveDayList.value = List?.sport_for_day + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } +// else{ +// Log.i("asdasdasdasd22222222","23231x2wswqxsxsas") +// Handler().postDelayed({ +// GetSportDay() +// }, 5000) +// } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + + } + + //Подтверждение упражнения + fun AddCheckView(id: Int, check: Int) { + if (enternetCheck.isOnline(requireContext())) { + visibleLoadYes() + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val checkSport = patientApi.AddSportCheck("Bearer $Tokens",id,check) + + activity?.runOnUiThread { + + //Фиксируем полученные данные + val List = checkSport.body() + val Nice = checkSport.isSuccessful + val Code = checkSport.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + if(check == 1){ + addCheckYes() + } + else if(check == 2){ + addCheckNo() + } + visibleDayList() + visibleLoadNo() + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + } + + //Функция активации кнпок + fun addButton() { + + //Закрытие карточки определенного дня + binding.btnExitCardSport.setOnClickListener { + //visibleLoad() + stopSound() + binding.btnMp3.setBackgroundResource(android.R.drawable.ic_media_play) + //binding.txtNameCard.setText("") + binding.txtDescCard.setText("") + visibleDayList() + } + + binding.btnAddDayCategoryCheck.setOnClickListener { + AddCheckView(idCheckDay,1) + Log.i("btnAddDayCategoryCheck1","btnAddDayCategoryCheck1") + + + } + + binding.btnNoAddDayCategoryCheck.setOnClickListener { + AddCheckView(idCheckDay,2) + Log.i("btnAddDayCategoryCheck2","btnAddDayCategoryCheck2") + + } + } + + private fun addCheckNo() { + stopSound() + binding.btnMp3.setBackgroundResource(android.R.drawable.ic_media_play) + + visibleLoadYes() + + binding.btnNoAddDayCategoryCheck.isEnabled = false + binding.btnNoAddDayCategoryCheck.isClickable = false + binding.btnNoAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#A3B8A1")) + Toast(requireContext()).showCustomInfoToast( + "Упражнение было пропушено", + requireActivity() + ) + + + + if (SportPlusCount == SportMaxCount && DayBefore == LocalDate.now() + .toString() && DayAfter == "" + ) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, QAfterFragment.newInstance())?.commit() + } + + binding.txtDescCard.setText("") + visibleDayList() + } + + private fun addCheckYes() { + stopSound() + binding.btnMp3.setBackgroundResource(android.R.drawable.ic_media_play) + + visibleLoadYes() + + + binding.btnAddDayCategoryCheck.isEnabled = false + binding.btnAddDayCategoryCheck.isClickable = false + binding.btnAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#A68C78")) + Toast(requireContext()).showCustomNiceToast( + "Упражнение выполнено", + requireActivity() + ) + + + + if (SportPlusCount == SportMaxCount && DayBefore == LocalDate.now() + .toString() && DayAfter == "" + ) { + activity?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.placeHolderFragment, QAfterFragment.newInstance())?.commit() + } + binding.txtDescCard.setText("") + + visibleDayList() + } + + + + companion object { + fun newInstance() = SceduleFragment() + } + + //Функция запускающая отслеживания за списком, чтобы вовремя обновлять основную карточку продукта + private fun liveReadOrderCurrent() = with(binding) { + model.liveListCurrent.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment + visibleDayList() + } + } + + + + //Инициализация списка + private fun initRcViewDay() = with(binding) { + rcVIewDayList.layoutManager = + GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию + adapterDay = DayAdapter(this@SceduleFragment) + rcVIewDayList.adapter = adapterDay + //binding.rcVIewDayList.smoothScrollToPosition(0); + } + + //Инициализация списка для фотографий + private fun initRcViewImage() = with(binding) { + rcViewImage.layoutManager = LinearLayoutManager( + requireContext(), + LinearLayoutManager.HORIZONTAL, + false + )//По вертикали будет выводить по умолчанию + adapterImage = ImageSportAdapter(requireContext()) + rcViewImage.adapter = adapterImage + + } + + @SuppressLint("NotifyDataSetChanged") + fun ClearRCView() { + adapterImage.notifyDataSetChanged() + adapterDay.notifyDataSetChanged() + initRcViewImage() + initRcViewDay() + + } + + override fun onDestroy() { + super.onDestroy() + ClearRCView() + } + + + //Звуковая часть + // 1. Plays the water sound + fun playSound() { + if (mMediaPlayer == null) { + mMediaPlayer = MediaPlayer.create(requireContext(), R.raw.sec1_metronom) + mMediaPlayer!!.isLooping = true + mMediaPlayer!!.start() + } else mMediaPlayer!!.start() + } + + // 2. Pause playback + fun pauseSound() { + if (mMediaPlayer?.isPlaying == true) mMediaPlayer?.pause() + } + + // 3. Stops playback + fun stopSound() { + if (mMediaPlayer != null) { + mMediaPlayer!!.stop() + mMediaPlayer!!.release() + mMediaPlayer = null + } + } + + // 4. Destroys the MediaPlayer instance when the app is closed + override fun onStop() { + super.onStop() + if (mMediaPlayer != null) { + mMediaPlayer!!.release() + mMediaPlayer = null + } + println("super.onStop triggered") + + } + + override fun onClickSport(item: SportForDayModel) { + GetSportDayOne(item.id) + idCheckDay=item.id + + Log.i("GetSportDayOne", item.id.toString()) + Log.i("111111111", "12312312312321312312") + } + + //Получения списка пациентов + fun GetSportDayOne(id: Int) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val sportDayOne = patientApi.GetSportDayOne("Bearer $Tokens", id) + requireActivity().runOnUiThread { + + //Фиксируем полученные данные + val List = sportDayOne.body() + val Nice = sportDayOne.isSuccessful + val Code = sportDayOne.code() + if(Code==429){ + val intetn = Intent(requireContext(), Code429Activity::class.java) + + startActivity(intetn) + } + else if(Code==200) { + //Если нету ошибок + if (Nice) { + //Если нету ошибок + if (List != null) { + modelPatient.liveDaySportOne.value = List + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + + } + + private fun liveDaySportOne() = with(binding) { + modelPatient.liveDaySportOne.observe(viewLifecycleOwner) { + visibleLoadYes() + + //Фиксируем id + idDaySport = it.id.toInt() + Log.i("idDaySport",it.id.toString()) + + //Отключаем нажатие на кнопку подтверждения, если упражнени уже выполнено, для того чтобы не тыкали + if (it.finish.toInt() == 1 || it.finish.toInt() == 2) { + binding.btnAddDayCategoryCheck.isEnabled = false + binding.btnAddDayCategoryCheck.isClickable = false + binding.btnAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#A3B8A1")) + + binding.btnNoAddDayCategoryCheck.isEnabled = false + binding.btnNoAddDayCategoryCheck.isClickable = false + binding.btnNoAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#A68C78")) + + } else { + + binding.btnAddDayCategoryCheck.isEnabled = true + binding.btnAddDayCategoryCheck.isClickable = true + binding.btnAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#53D54A")) + + binding.btnNoAddDayCategoryCheck.isEnabled = true + binding.btnNoAddDayCategoryCheck.isClickable = true + binding.btnNoAddDayCategoryCheck.setCardBackgroundColor(Color.parseColor("#EDAA76")) + } + + Log.i("asdas", it.image_url.toString()) + model.liveImageList.value = it.image_url + + + //binding.txtNameCard.setText("") + binding.txtDescCard.setText("") + binding.txtTitle.setText("") + binding.txtTitle.setText("Упражнение " + it.id) + //binding.txtNameCard.setText(it.name) + binding.txtDescCard.setText(binding.txtDescCard.text.toString() + it.description) + + + //Выводим экран + visibleDayCard() + + } + } + + + + //АНКЕТА ДО + + private fun Before() { + //Выход +// binding.btnExitQB.setOnClickListener { +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() +// } + buttenAddBefore() + //Сохраняем результат + binding.btnSaveQuestionnaireB.setOnClickListener { + + if (oneB != 100 && twoB != 100 && threeB != 100 && fourB != 100 && fiveB != 100 && sixB != 100 && sevenB != 100 && eightB != 100 && nineB != 100) { + if(oneB >= 6) { + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к блокировке комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + addQuestionnaireB() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + }.show() + } + else if(fourB == 1 && fiveB == 1 && sixB == 1 && sevenB == 1 && nineB == 1){ + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к паузе комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + addQuestionnaireB() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + }.show() + } + else{ + addQuestionnaireB() + } + + } else { + Toast(requireContext()).showCustomInfoToast( + "Не все пункты выбраны", + requireActivity() + ) + } + } + +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + + //Функция + fun addQuestionnaireB(){ + + val item = BeforeQuestionnaireModel( + oneB, + twoB, + threeB, + fourB, + fiveB, + sixB, + sevenB, + eightB, + nineB, + ) + BeforeQuestionnaire(item) + + } + + private fun buttenAddBefore() { + + buttenAdd1B() + buttenAdd1_2B() + buttenAdd2B() + buttenAdd3B() + buttenAdd4B() + buttenAdd5B() + buttenAdd6B() + buttenAdd7B() + buttenAdd8B() + buttenAdd9B() + + } + + //Отправка запроса + fun BeforeQuestionnaire(item: BeforeQuestionnaireModel) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val QA = patientApi.AddBeforeQuestionnaire2("Bearer $Tokens",item) + requireActivity().runOnUiThread { + + + + //Фиксируем полученные данные + val List = QA.body() + val Nice = QA.isSuccessful + val Code = QA.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()) +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() + // GetVisibleViewList() + + visibleLoadYes() + } + else{ + Toast(requireContext()).showCustomInfoToast("Ошибка при отправке", requireActivity()) + // GetVisibleViewList() + visibleLoadYes() + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + + } + + private fun buttenAdd1B() { + binding.CVQyes1B.setOnClickListener { + binding.CLQ112B.visibility = View.VISIBLE + binding.CVQyes1B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno1B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + + } + binding.CVQno1B.setOnClickListener { + binding.CLQ112B.visibility = View.GONE + binding.CVQyes1B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno1B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + oneB = 0 + } + } + + + private fun buttenAdd1_2B() { + binding.CVQ10B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 0 + } + binding.CVQ11B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 1 + } + binding.CVQ12B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 2 + } + binding.CVQ13B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 3 + } + binding.CVQ14B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 4 + + } + binding.CVQ15B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 5 + } + binding.CVQ16B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 6 + } + binding.CVQ17B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 7 + } + binding.CVQ18B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 8 + } + binding.CVQ19B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneB = 9 + } + binding.CVQ110B.setOnClickListener { + binding.CVQ10B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + oneB = 10 + } + } + + private fun buttenAdd2B() { + binding.CVQyes2B.setOnClickListener { + binding.CVQyes2B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno2B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + twoB = 1 + } + binding.CVQno2B.setOnClickListener { + binding.CVQyes2B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno2B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + twoB = 0 + } + } + + private fun buttenAdd3B() { + binding.CVQyes3B.setOnClickListener { + binding.CVQyes3B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno3B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + threeB = 1 + } + binding.CVQno3B.setOnClickListener { + binding.CVQyes3B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno3B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + threeB = 0 + } + } + + private fun buttenAdd4B() { + binding.CVQyes4B.setOnClickListener { + binding.CVQyes4B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno4B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + fourB = 1 + } + binding.CVQno4B.setOnClickListener { + binding.CVQyes4B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno4B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + fourB = 0 + } + } + + private fun buttenAdd5B() { + binding.CVQyes5B.setOnClickListener { + binding.CVQyes5B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno5B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + fiveB = 1 + } + binding.CVQno5B.setOnClickListener { + binding.CVQyes5B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno5B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + fiveB = 0 + } + } + + private fun buttenAdd6B() { + binding.CVQyes6B.setOnClickListener { + binding.CVQyes6B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno6B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + sixB = 1 + } + binding.CVQno6B.setOnClickListener { + binding.CVQyes6B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno6B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + sixB = 0 + } + } + + private fun buttenAdd7B() { + binding.CVQyes7B.setOnClickListener { + binding.CVQyes7B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno7B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + sevenB = 1 + } + binding.CVQno7B.setOnClickListener { + binding.CVQyes7B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno7B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + sevenB = 0 + } + } + + private fun buttenAdd8B() { + binding.CVQyes8B.setOnClickListener { + binding.CVQyes8B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno8B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + eightB = 1 + } + binding.CVQno8B.setOnClickListener { + binding.CVQyes8B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno8B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + eightB = 0 + } + } + + private fun buttenAdd9B() { + binding.CVQyes9B.setOnClickListener { + binding.CVQyes9B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno9B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + nineB = 1 + } + binding.CVQno9B.setOnClickListener { + binding.CVQyes9B.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno9B.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + nineB = 0 + } + } + + + //Анкета ПОСЛЕ + private fun After() { + buttenAddAfter() + //Выход +// binding.btnBackA.setOnClickListener { +// activity?.supportFragmentManager?.beginTransaction() +// ?.replace(R.id.placeHolderFragment, SceduleFragment.newInstance())?.commit() +// } + + //Сохраняем результат + binding.btnSaveQuestionnaireA.setOnClickListener { + if (oneA != 100 && twoA != 100 && threeA != 100 && fourA != 100 && fiveA != 100 && sixA != 100 && sevenA != 100 && eightA != 100 && nineA != 100 && tenA != 100 && elevenA != 100 && twelveA != 100) { + + if(nineA == 1){ + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к блокировке комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + addQuestionAfter() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + + } + .show() + } + else if(oneA >=6 && threeA == 0 && sixA == 1 && eightA == 1 && elevenA == 1){ + AlertDialog.Builder(requireContext()) + .setTitle("Анкета") + .setMessage("Уверены ли Вы в выбранных ответах на вопросы анкеты? Халатное отношение к вопросам анкеты приведет к паузе комплекса") + .setNeutralButton("Подтвердить") { dialog, whichButton -> + addQuestionAfter() + } + .setNegativeButton("Отмена") { dialog, whichButton -> + + } + .show() + } + else{ + addQuestionAfter() + } + } else { + Toast(requireContext()).showCustomInfoToast( + "Не все пункты выбраны", + requireActivity() + ) + } + } +// fixedRateTimer("timer", false, 0, 10000) { +// activity?.runOnUiThread { +// +// } +// } + } + fun addQuestionAfter() { + + + val item = AfterQuestionnaireModel( + oneA, + twoA, + threeA, + fourA, + fiveA, + sixA, + sevenA, + eightA, + nineA, + tenA, + elevenA, + twelveA, + ) + + AfterQuestionnaire(item) + } + + //Отправка анкеты ПОСЛЕ + fun AfterQuestionnaire(item:AfterQuestionnaireModel) { + if (enternetCheck.isOnline(requireContext())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val QA = patientApi.AddAfterQuestionnaire2("Bearer $Tokens",item) + requireActivity().runOnUiThread { + + + + //Фиксируем полученные данные + val List = QA.body() + val Nice = QA.isSuccessful + val Code = QA.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()) + //viewVisible() + //GetVisibleViewList() + visibleLoadYes() + } + else{ + if (List != null) { + Toast(requireContext()).showCustomInfoToast(List.message, requireActivity()) + // GetVisibleViewList() + visibleLoadYes() + } + } + + } + } + else if (Code == 500) { + val intetn = Intent(requireContext(), Code500Activity::class.java) + + startActivity(intetn) + } + else if (Code == 401) { + val intetn = Intent(requireContext(), AuthorizationActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + } + } else { + val intetn = Intent(requireContext(), EnternetActivity::class.java) + + startActivity(intetn) + } + + } + + private fun buttenAddAfter() { + buttenAdd1A() + buttenAdd2A() + buttenAdd3A() + buttenAdd4A() + buttenAdd5A() + buttenAdd6A() + buttenAdd7A() + buttenAdd8A() + buttenAdd9A() + buttenAdd10A() + buttenAdd11A() + buttenAdd12A() + } + + private fun buttenAdd1A() { + binding.CVQ10A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 0 + } + binding.CVQ11A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 1 + } + binding.CVQ12A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 2 + } + binding.CVQ13A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 3 + } + binding.CVQ14A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 4 + + } + binding.CVQ15A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 5 + } + binding.CVQ16A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 6 + } + binding.CVQ17A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 7 + } + binding.CVQ18A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 8 + } + binding.CVQ19A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + oneA = 9 + } + binding.CVQ110A.setOnClickListener { + binding.CVQ10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ13A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ14A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ15A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ16A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ17A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ18A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ19A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQ110A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + oneA = 10 + } + } + + private fun buttenAdd2A() { + binding.CVQyes2A.setOnClickListener { + binding.CVQyes2A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno2A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + twoA = 1 + } + binding.CVQno2A.setOnClickListener { + binding.CVQyes2A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno2A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + twoA = 0 + } + } + + private fun buttenAdd3A() { + binding.CVQyes3A.setOnClickListener { + Log.d("CVQyes3", "CVQyes3") + binding.CVQyes3A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno3A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + threeA = 1 + } + binding.CVQno3A.setOnClickListener { + binding.CVQyes3A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno3A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + threeA = 0 + } + } + + private fun buttenAdd4A() { + binding.CVQyes4A.setOnClickListener { + binding.CVQyes4A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno4A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + fourA = 1 + } + binding.CVQno4A.setOnClickListener { + binding.CVQyes4A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno4A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + fourA = 0 + } + } + + private fun buttenAdd5A() { + binding.CVQyes5A.setOnClickListener { + binding.CVQyes5A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno5A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + fiveA = 1 + } + binding.CVQno5A.setOnClickListener { + binding.CVQyes5A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno5A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + fiveA = 0 + } + } + + private fun buttenAdd6A() { + binding.CVQyes6A.setOnClickListener { + binding.CVQyes6A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno6A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + sixA = 1 + } + binding.CVQno6A.setOnClickListener { + binding.CVQyes6A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno6A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + sixA =0 + } + } + + private fun buttenAdd7A() { + binding.CVQyes7A.setOnClickListener { + binding.CVQyes7A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno7A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + sevenA = 1 + } + binding.CVQno7A.setOnClickListener { + binding.CVQyes7A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno7A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + sevenA =0 + } + } + + private fun buttenAdd8A() { + binding.CVQyes8A.setOnClickListener { + binding.CVQyes8A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno8A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + eightA = 1 + } + binding.CVQno8A.setOnClickListener { + binding.CVQyes8A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno8A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + eightA = 0 + } + } + + private fun buttenAdd9A() { + binding.CVQyes9A.setOnClickListener { + binding.CVQyes9A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno9A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + nineA = 1 + } + binding.CVQno9A.setOnClickListener { + binding.CVQyes9A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno9A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + nineA = 0 + } + } + + private fun buttenAdd10A() { + binding.CVQyes10A.setOnClickListener { + binding.CVQyes10A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + tenA = 1 + } + binding.CVQno10A.setOnClickListener { + binding.CVQyes10A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno10A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + tenA = 0 + } + } + + private fun buttenAdd11A() { + binding.CVQyes11A.setOnClickListener { + binding.CVQyes11A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + elevenA = 1 + } + binding.CVQno11A.setOnClickListener { + binding.CVQyes11A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno11A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + elevenA = 0 + } + } + + private fun buttenAdd12A() { + binding.CVQyes12A.setOnClickListener { + binding.CVQyes12A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + binding.CVQno12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + twelveA = 1 + } + binding.CVQno12A.setOnClickListener { + binding.CVQyes12A.setCardBackgroundColor(Color.parseColor("#A8A8A8")) + binding.CVQno12A.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + twelveA = 0 + } + } + + /** + * Проверка расписания на сервере + */ + fun LookScedule() { + if (enternetCheck.isOnline(requireActivity())) { + initRetrofit() + val Tokens = prefPatientConclusion.conclusionToken(requireContext()) + CoroutineScope(Dispatchers.IO).launch { + val listScedule = patientApi.LookScedule2("Bearer $Tokens") + requireActivity().runOnUiThread { + // Обработка ответа от сервера + val List = listScedule.body() + val Nice = listScedule.isSuccessful + val Code = listScedule.code() + + when (Code) { + 429 -> { + // Слишком много запросов + val intetn = Intent(requireContext(), Code429Activity::class.java) + activity?.finish() + startActivity(intetn) + } + 200 -> { + // Успешный ответ + if (Nice) { + if (List != null) { + modelPatient.sceduleLook.value = List + } + } + } + 500 -> { + // Ошибка сервера + val intetn = Intent(requireContext(), Code500Activity::class.java) + activity?.finish() + startActivity(intetn) + } + } + } + } + } else { + // Нет интернет-соединения + val intetn = Intent(requireContext(), EnternetActivity::class.java) + activity?.finish() + startActivity(intetn) + } + } + + override fun onStart() { + super.onStart() + checkForUpdates(true) + } + + override fun onStop() { + super.onStop() + timer.cancel() + } + + /** + * Запуск таймера для периодического обновления данных + * @param daemonIsTrue Флаг для запуска таймера в фоновом режиме + */ + private fun checkForUpdates(daemonIsTrue: Boolean) { + timer = fixedRateTimer("default", daemonIsTrue, 0, 15000) { + activity?.runOnUiThread { + LookScedule() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SportDayOneModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/SportDayOneModel.kt new file mode 100644 index 0000000..71e1b76 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SportDayOneModel.kt @@ -0,0 +1,15 @@ +package com.example.rehabilitation.Sport + +import com.example.rehabilitation.Sport.Image.ImageSportModel + +data class SportDayOneModel( + val id: Int, + val name: String, + val description: String, + val count: Int, + val image_url:List, + val finish:Int, + val created_at:String, + val updated_at:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SportForDayListModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/SportForDayListModel.kt new file mode 100644 index 0000000..b9bd398 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SportForDayListModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.Sport + +data class SportForDayListModel( + val sport_for_day: List +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SportForDayModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/SportForDayModel.kt new file mode 100644 index 0000000..c135c72 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SportForDayModel.kt @@ -0,0 +1,15 @@ +package com.example.rehabilitation.Sport + +data class SportForDayModel( + val number:Int, + val id: Int, + val article: String, + val category: String, + val id_patient:Int, + val id_sports_tasks: Int, + val id_sport_patient: Int, + val finish: Int, + val created_at:String, + val updated_at:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/SportListModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/SportListModel.kt new file mode 100644 index 0000000..1e34699 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/SportListModel.kt @@ -0,0 +1,5 @@ +package com.example.rehabilitation.Sport + +data class SportListModel( + val day: List +) diff --git a/app/src/main/java/com/example/rehabilitation/Sport/UpdateSportTrueFalseModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/UpdateSportTrueFalseModel.kt new file mode 100644 index 0000000..7860647 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/UpdateSportTrueFalseModel.kt @@ -0,0 +1,5 @@ +package com.example.rehabilitation.Sport + +data class UpdateSportTrueFalseModel( + val massage: String +) diff --git a/app/src/main/java/com/example/rehabilitation/Sport/ViewFragmentModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/ViewFragmentModel.kt new file mode 100644 index 0000000..e3016bd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/ViewFragmentModel.kt @@ -0,0 +1,5 @@ +package com.example.rehabilitation.Sport + +data class ViewFragmentModel ( + val view:Int +) \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Sport/ViewModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/ViewModel.kt new file mode 100644 index 0000000..a49995f --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/ViewModel.kt @@ -0,0 +1,8 @@ +package com.example.rehabilitation.Sport + +data class ViewModel( + val view: Int, + val text: String, + +) + diff --git a/app/src/main/java/com/example/rehabilitation/Sport/ViewVisibleModel.kt b/app/src/main/java/com/example/rehabilitation/Sport/ViewVisibleModel.kt new file mode 100644 index 0000000..f9eece2 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Sport/ViewVisibleModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.Sport + +data class ViewVisibleModel( + val view: Int, + val text: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/Toast.kt b/app/src/main/java/com/example/rehabilitation/Toast.kt new file mode 100644 index 0000000..f906bf0 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Toast.kt @@ -0,0 +1,28 @@ +package com.example.rehabilitation + +import android.content.Context +import android.widget.Toast + +/** + * Объект для удобного отображения уведомлений + * Предоставляет методы для показа коротких и длинных сообщений + */ +object Toast { + /** + * Показать короткое уведомление + * @param context Контекст приложения + * @param message Текст сообщения + */ + fun showShort(context: Context, message: String) { + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + } + + /** + * Показать длинное уведомление + * @param context Контекст приложения + * @param message Текст сообщения + */ + fun showLong(context: Context, message: String) { + Toast.makeText(context, message, Toast.LENGTH_LONG).show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/Toast/Notification.kt b/app/src/main/java/com/example/rehabilitation/Toast/Notification.kt new file mode 100644 index 0000000..1d6ad55 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Toast/Notification.kt @@ -0,0 +1,67 @@ +package com.example.rehabilitation.Toast + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import androidx.core.app.NotificationCompat +import com.example.rehabilitation.R + +const val notificationID = 1 +const val channelID= "channel1" +const val titleExtra = "titleExtra" +const val messageExtra = "messageExtra" + +open class Notification:BroadcastReceiver() { + + + var manager_: NotificationManager? = null + + override fun onReceive(context: Context?, intent: Intent?) { + + val notification = context?.let { + NotificationCompat.Builder(it,channelID) + .setSmallIcon(R.drawable.basket_24) + .setContentTitle(intent?.getStringExtra(titleExtra)) + .setContentText(intent?.getStringExtra(messageExtra)) + .build() + } + val manager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + manager.notify(notificationID,notification) + manager_ = manager + + } + + //Удаление + fun cancel_notification(notificationID:Int){ + manager_?.cancel(notificationID) + } + + + +} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/example/rehabilitation/Toast/WrapToast.kt b/app/src/main/java/com/example/rehabilitation/Toast/WrapToast.kt new file mode 100644 index 0000000..f18055d --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/Toast/WrapToast.kt @@ -0,0 +1,103 @@ +package com.example.admin.Toast + +import android.app.Activity +import android.view.Gravity +import android.widget.TextView +import android.widget.Toast +import com.example.rehabilitation.R + + +fun Toast.showCustomToast(message: String, activity: Activity) +{ + + val layout = activity.layoutInflater.inflate ( + R.layout.custom_toast_layout, + activity.findViewById(R.id.toast_container) + ) + + + // set the text of the TextView of the message + val textView = layout.findViewById(R.id.toast_text) + //Передача текста который мы введем + textView.text = message + + //Если добавить кнопку то можно сделать некую функцию, к примеру при добавление товара в корзину, можно сверху выводить перейти в корзину и по нажатию мы переходим в корзину + /* textView.setOnClickListener{ + setToolbarTitle.perehods() + Log.d("dsfsd","111111111111111111111111111") + }*/ + // use the application extension function + this.apply { + //setGravity(Gravity.BOTTOM, 0, 40) + duration = Toast.LENGTH_SHORT + view = layout.rootView + show() + } + + +} fun Toast.showCustomDangerToast(message: String, activity: Activity) +{ + val layout = activity.layoutInflater.inflate ( + R.layout.custom_toast_layout_danger, + activity.findViewById(R.id.toast_container) + ) + + // set the text of the TextView of the message + val textView = layout.findViewById(R.id.toast_text) + //Передача текста который мы введем + textView.text = message + + //Если добавить кнопку то можно сделать некую функцию, к примеру при добавление товара в корзину, можно сверху выводить перейти в корзину и по нажатию мы переходим в корзину + + // use the application extension function + this.apply { + setGravity(Gravity.BOTTOM, 0, 40) + duration = Toast.LENGTH_SHORT + view = layout.rootView + show() + } +} + +fun Toast.showCustomInfoToast(message: String, activity: Activity) { + val layout = activity.layoutInflater.inflate( + R.layout.custom_toast_layout_info, + activity.findViewById(R.id.toast_container) + ) + + // set the text of the TextView of the message + val textView = layout.findViewById(R.id.toast_text) + //Передача текста который мы введем + textView.text = message + + //Если добавить кнопку то можно сделать некую функцию, к примеру при добавление товара в корзину, можно сверху выводить перейти в корзину и по нажатию мы переходим в корзину + + // use the application extension function + this.apply { + setGravity(Gravity.BOTTOM, 0, 40) + duration = Toast.LENGTH_SHORT + view = layout.rootView + show() + } +} + +fun Toast.showCustomNiceToast(message: String, activity: Activity) { + val layout = activity.layoutInflater.inflate( + R.layout.custom_toast_layout_nice, + activity.findViewById(R.id.toast_container) + ) + + // set the text of the TextView of the message + val textView = layout.findViewById(R.id.toast_text) + //Передача текста который мы введем + textView.text = message + + //Если добавить кнопку то можно сделать некую функцию, к примеру при добавление товара в корзину, можно сверху выводить перейти в корзину и по нажатию мы переходим в корзину + + // use the application extension function + this.apply { + setGravity(Gravity.BOTTOM, 0, 40) + duration = Toast.LENGTH_SHORT + view = layout.rootView + show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/DataModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/DataModel.kt new file mode 100644 index 0000000..8aef7db --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/DataModel.kt @@ -0,0 +1,28 @@ +package com.example.rehabilitation.model_adapter + +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 addZakaz: 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/rehabilitation/model_adapter/Edit/EditSportAdapter.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/EditSportAdapter.kt new file mode 100644 index 0000000..58940de --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/EditSportAdapter.kt @@ -0,0 +1,119 @@ +package com.example.rehabilitation.model_adapter.Edit + +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.rehabilitation.R +import com.example.rehabilitation.databinding.RcItemBinding +import com.example.rehabilitation.databinding.RcItemDayBinding +import com.example.rehabilitation.databinding.RcItemDayEditBinding +import java.time.LocalDate + + +class EditSportAdapter(val listener_zakaz: Listener,val visible_card: ListenerEdit) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_zakaz: Listener,val visible_card: ListenerEdit): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = RcItemDayEditBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: EditSportModel? = null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + itemTemp?.let { it1 -> listener_zakaz.onClickExceptionOrder(it1) } + } + binding.btnVisibleCardEdit.setOnClickListener { + itemTemp?.let { it2 -> visible_card.onClickEditCard(it2) } + } + } + + //Функция bind для заполнения + @SuppressLint("SuspiciousIndentation") + fun bind(item: EditSportModel) = with(binding) {//Productitem - перпедаем данные + itemTemp = item + //txtName.text = item.name + //txtCount.text = item.count + //txtImage.text = item.image + txtName.text = item.id.toString() + txtDay.text = item.category + txtDescSport.text = item.desc + binding.CLMainPluss.visibility = if (item.expand) View.VISIBLE else View.GONE + binding.CLMainEdit.setOnClickListener{ + if(item.expand == false){ + binding.CLMainPluss.visibility = View.VISIBLE + item.expand = true + }else{ + + binding.CLMainPluss.visibility = View.GONE + item.expand = false + } + } + if(item.visible == 1){ + binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#3AB0FF")) + } + else{ + binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#99ADBA")) + + } + +// if(item.check.toInt() == 0){ +// binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#3AB0FF")) +// } +// else{ +// binding.CardViewDay.setCardBackgroundColor(Color.parseColor("#33BC0E")) +// } + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.rc_item_day_edit, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_zakaz,visible_card)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: EditSportModel, newItem: EditSportModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: EditSportModel, + newItem: EditSportModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Открытие подробного описания спортивного упражнения + interface Listener { + fun onClickExceptionOrder(item: EditSportModel) + } + //Интерфейс нажатия на кнопку отключить карточку + interface ListenerEdit { + fun onClickEditCard(item: EditSportModel) + } + + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/EditSportModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/EditSportModel.kt new file mode 100644 index 0000000..ade517c --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/EditSportModel.kt @@ -0,0 +1,13 @@ +package com.example.rehabilitation.model_adapter.Edit + +data class EditSportModel( + val id: Int, + val day: String, + val category: String, + val check:Int, + val visible:Int, + val desc:String, + val categoryImage:String, + var expand : Boolean = false +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/Email.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/Email.kt new file mode 100644 index 0000000..d7a1666 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/Email.kt @@ -0,0 +1,33 @@ +package com.example.rehabilitation.model_adapter.Edit.adapterFirebase + +import android.annotation.SuppressLint +import android.content.Intent +import android.net.Uri +import android.os.Environment +import android.text.Html +import android.text.Spanned +import androidx.core.content.FileProvider +import androidx.core.net.toFile +import java.io.File + +class Email { + + fun getSendIntent(recipient: String, + subject: String, + text: String, + uri: Uri): Intent{ + + val emailIntent = Intent(Intent.ACTION_SEND) + + emailIntent.type = "application/excel" + emailIntent.putExtra(Intent.EXTRA_STREAM, uri) + emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) + emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(recipient)) + emailIntent.putExtra(Intent.EXTRA_TEXT, text) + emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + emailIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + emailIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + + return emailIntent + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/ExcelFile.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/ExcelFile.kt new file mode 100644 index 0000000..25521bd --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/ExcelFile.kt @@ -0,0 +1,341 @@ +package com.example.rehabilitation.model_adapter.Edit.adapterFirebase + +import android.os.Environment +import android.util.Log +import com.example.rehabilitation.fileUri2 +import com.example.rehabilitation.Progress.AfterListModel +import com.example.rehabilitation.Progress.BeforeListModel +import com.example.rehabilitation.uriFileEF +import org.apache.poi.ss.usermodel.BorderStyle +import org.apache.poi.ss.usermodel.CellStyle +import org.apache.poi.ss.usermodel.FillPatternType +import org.apache.poi.ss.usermodel.HorizontalAlignment +import org.apache.poi.ss.usermodel.IndexedColors +import org.apache.poi.ss.usermodel.Row +import org.apache.poi.ss.usermodel.Sheet +import org.apache.poi.ss.usermodel.VerticalAlignment +import org.apache.poi.ss.usermodel.Workbook +import org.apache.poi.ss.util.CellRangeAddress +import org.apache.poi.xssf.usermodel.XSSFWorkbook +import java.io.File +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.io.IOException + +class ExcelFile(private val FIO: String, private val numDaysB: Int, private val numDaysA: Int, private val nameFile:String, private val BQDate: List, private val AQDate: List) { + + private lateinit var sheetAfter: Sheet + private lateinit var sheetBefore: Sheet + private lateinit var ourWorkbook: Workbook + private lateinit var cs: CellStyle + private lateinit var csRed: CellStyle + private lateinit var csGreen: CellStyle + private val filesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + init { + //Check whether it exists or not, and create one if it does not exist. + if (filesDir != null && !filesDir.exists()) { + filesDir.mkdirs() + } + ourWorkbook = createWorkbook() + Log.i("1", "1") + } + + fun saveTable(){ + + val excelFile = File(filesDir, "/"+nameFile+".xlsx") + uriFileEF = excelFile + Log.i("excelFile","${excelFile}") + try { + val fileOut = FileOutputStream(excelFile) + fileUri2 = fileOut + Log.i("fileOut","${fileOut}") + ourWorkbook.write(fileOut) + fileOut.close() + Log.i("File", "Done") + } catch (e: FileNotFoundException) { + Log.e("File", e.message, e) + } catch (e: IOException) { + Log.e("File", e.message, e) + } + } + + private fun createWorkbook(): Workbook { + Log.i("2", "2") + // Creating a workbook object from the XSSFWorkbook() class + ourWorkbook = XSSFWorkbook() + + csRed = ourWorkbook.createCellStyle() + csRed.fillForegroundColor = IndexedColors.RED.index + csRed.fillPattern = FillPatternType.SOLID_FOREGROUND + csRed.verticalAlignment = VerticalAlignment.CENTER + csRed.alignment = HorizontalAlignment.CENTER + + csRed.borderTop = BorderStyle.THIN; + csRed.borderBottom = BorderStyle.THIN; + csRed.borderLeft = BorderStyle.THIN; + csRed.borderRight = BorderStyle.THIN; + + csRed.topBorderColor = IndexedColors.BLACK.index; + csRed.bottomBorderColor = IndexedColors.BLACK.index; + csRed.rightBorderColor = IndexedColors.BLACK.index; + csRed.leftBorderColor = IndexedColors.BLACK.index; + + csGreen = ourWorkbook.createCellStyle() + csGreen.fillForegroundColor = IndexedColors.GREEN.index + csGreen.fillPattern = FillPatternType.SOLID_FOREGROUND + csGreen.verticalAlignment = VerticalAlignment.CENTER + csGreen.alignment = HorizontalAlignment.CENTER + + csGreen.borderTop = BorderStyle.THIN; + csGreen.borderBottom = BorderStyle.THIN; + csGreen.borderLeft = BorderStyle.THIN; + csGreen.borderRight = BorderStyle.THIN; + + csGreen.topBorderColor = IndexedColors.BLACK.index; + csGreen.bottomBorderColor = IndexedColors.BLACK.index; + csGreen.rightBorderColor = IndexedColors.BLACK.index; + csGreen.leftBorderColor = IndexedColors.BLACK.index; + + cs = ourWorkbook.createCellStyle() + cs.verticalAlignment = VerticalAlignment.CENTER + cs.alignment = HorizontalAlignment.CENTER + cs.borderTop = BorderStyle.THIN; + cs.borderBottom = BorderStyle.THIN; + cs.borderLeft = BorderStyle.THIN; + cs.borderRight = BorderStyle.THIN; + cs.topBorderColor = IndexedColors.BLACK.index; + cs.bottomBorderColor = IndexedColors.BLACK.index; + cs.rightBorderColor = IndexedColors.BLACK.index; + cs.leftBorderColor = IndexedColors.BLACK.index; + + sheetBefore = ourWorkbook.createSheet("Перед занятием") + sheetAfter = ourWorkbook.createSheet("После занятия") + addBeforeData() + addAfterData() + + return ourWorkbook + } + + private fun createCell(sheetRow: Row, columnIndex: Int, cellValue: String?, cellStyle: CellStyle?) { + Log.i("4", "4") + //create a cell at a passed in index + val ourCell = sheetRow.createCell(columnIndex) + //add the value to it + //a cell can be empty. That's why its nullable + ourCell?.setCellValue(cellValue) + if (cellStyle != null){ + ourCell?.cellStyle = cellStyle + } + } + + + private fun addBeforeData() { + Log.i("31", "31") + Log.i("BQDate", "${BQDate[0].date.substring(5)}") + + val row1 = sheetBefore.createRow(0) + val row2 = sheetBefore.createRow(1) + val row3 = sheetBefore.createRow(2) + val row4 = sheetBefore.createRow(3) + val row5 = sheetBefore.createRow(4) + val row6 = sheetBefore.createRow(5) + val row7 = sheetBefore.createRow(6) + val row8 = sheetBefore.createRow(7) + val row9 = sheetBefore.createRow(8) + val row10 = sheetBefore.createRow(9) + val row11 = sheetBefore.createRow(10) + val row12 = sheetBefore.createRow(11) + val row13 = sheetBefore.createRow(12) + + sheetBefore.setColumnWidth(1, 25000) + sheetBefore.addMergedRegion(CellRangeAddress.valueOf("A1:${'B'+numDaysB}1")) + sheetBefore.addMergedRegion(CellRangeAddress.valueOf("B2:B3")) + sheetBefore.addMergedRegion(CellRangeAddress.valueOf("A2:A3")) + sheetBefore.addMergedRegion(CellRangeAddress.valueOf("C2:${'B'+numDaysB}2")) + + createCell(row1, 0, "Анкета для контроля состояния пациента $FIO перед занятием", cs) + createCell(row2, 0, "№ п/п", cs) + createCell(row2, 1, "Вопрос", cs) + createCell(row2, 2, "День", cs) + for (i in 1..BQDate.count()){ + Log.i("311", "311") + val date = BQDate[i-1].date.substring(5) + val day = "${date[3]}"+"${date[4]}"//День + val mount = "${date[0]}"+"${date[1]}"//Месяц + createCell(row3, 1+i, "${day}.${mount}", cs) + } + + createCell(row4, 0, "1", cs) + createCell(row4, 1, "Есть ли у Вас фантомные боли?", cs) + + createCell(row5, 0, "1.2", cs) + createCell(row5, 1, "Интенсивность фантомных болей?", cs) + + createCell(row6, 0, "3", cs) + createCell(row6, 1, "Есть отек в области культи?", cs) + + createCell(row7, 0, "4", cs) + createCell(row7, 1, "Есть ли покраснения в области культи?", cs) + + createCell(row8, 0, "5", cs) + row8.height = 1000 + createCell(row8, 1, "Есть ли покраснения в области культи?\n Есть ли локальное повышение температуры в области культи?", cs) + + + createCell(row9, 0, "6", cs) + createCell(row9, 1, "Есть ли выделения (кровь, сукровица) из области шва?", cs) + + + createCell(row10, 0, "7", cs) + createCell(row10, 1, "Есть ли повышение температуры (общее) выше 37,5?", cs) + + + createCell(row11, 0, "8", cs) + createCell(row11, 1, "Было ли ухудшение состояния после предыдущего занятия?", cs) + + + createCell(row12, 0, "9", cs) + createCell(row12, 1, "Удалось ли полностью восстановиться после предыдущего занятия?", cs) + + + createCell(row13, 0, "10", cs) + createCell(row13, 1, "Были ухудшения самочувствия?", cs) + + } + + private fun addAfterData() { + Log.i("32", "32") + val row1 = sheetAfter.createRow(0) + val row2 = sheetAfter.createRow(1) + val row3 = sheetAfter.createRow(2) + val row4 = sheetAfter.createRow(3) + val row5 = sheetAfter.createRow(4) + val row6 = sheetAfter.createRow(5) + val row7 = sheetAfter.createRow(6) + val row8 = sheetAfter.createRow(7) + val row9 = sheetAfter.createRow(8) + val row10 = sheetAfter.createRow(9) + val row11 = sheetAfter.createRow(10) + val row12 = sheetAfter.createRow(11) + val row13 = sheetAfter.createRow(12) + val row14 = sheetAfter.createRow(13) + val row15 = sheetAfter.createRow(14) + + sheetAfter.setColumnWidth(1, 25000) + sheetAfter.addMergedRegion(CellRangeAddress.valueOf("A1:${'B'+numDaysA}1")) + sheetAfter.addMergedRegion(CellRangeAddress.valueOf("B2:B3")) + sheetAfter.addMergedRegion(CellRangeAddress.valueOf("A2:A3")) + sheetAfter.addMergedRegion(CellRangeAddress.valueOf("C2:${'B'+numDaysA}2")) + + createCell(row1, 0, "Анкета для контроля состояния пациента $FIO после занятия", cs) + createCell(row2, 0, "№ п/п", cs) + createCell(row2, 1, "Вопрос", cs) + createCell(row2, 2, "День", cs) + + for (i in 1..AQDate.count()){ + val date = AQDate[i-1].date.substring(5) + val day = "${date[3]}"+"${date[4]}"//День + val mount = "${date[0]}"+"${date[1]}"//Месяц + + createCell(row3, 1+(i), "${day}.${mount}", cs) + + } + + createCell(row4, 0, "1", cs) + createCell(row4, 1, "Интенсивность фантомных болей?", cs) + + createCell(row5, 0, "2", cs) + createCell(row5, 1, "Было ли усиление болевого синдрома во время занятий? ", cs) + + createCell(row6, 0, "3", cs) + row6.height = 1000 + createCell(row6, 1, "При прекращении упражнения, которое вызвало усиление болевого синдрома,\n боль купируется (или возвращается к уровню до занятия) в течение 2 минут? ", cs) + + createCell(row7, 0, "4", cs) + createCell(row7, 1, "Интенсивность болевого синдрома до занятия и после одинаковая? ", cs) + + createCell(row8, 0, "5", cs) + createCell(row8, 1, "Есть отек в области культи? ", cs) + + createCell(row9, 0, "6", cs) + createCell(row9, 1, "По сравнению с состояние перед занятием увеличился ли отек культи?", cs) + + createCell(row10, 0, "7", cs) + createCell(row10, 1, "Есть ли покраснения в области культи? ", cs) + + createCell(row11, 0, "8", cs) + createCell(row11, 1, "Есть ли локальное повышение температуры в области культи?", cs) + + createCell(row12, 0, "9", cs) + createCell(row12, 1, "Есть ли выделения (кровь, сукровица) из области шва?", cs) + + createCell(row13, 0, "10", cs) + createCell(row13, 1, "Выделения из области шва усилились/изменили характер?", cs) + + createCell(row14, 0, "11", cs) + createCell(row14, 1, "Есть ли общее ощущение слабости, чрезмерной усталости, «разбитости»?", cs) + + createCell(row15, 0, "12", cs) + createCell(row15, 1, "Все ли упражнения удалось выполнить?", cs) + + } + + fun addBeforeDay(day: Int, question: Int, data: Int){ + if ((day > numDaysB) or (question > 10)){ + throw ArrayIndexOutOfBoundsException("Выход за пределы таблицы") + } + val row = sheetBefore.getRow(question+2) + if (question == 2){ + if (data > 5){ + createCell(row, day+1, data.toString(), csRed) + } + else { + createCell(row, day+1, data.toString(), csGreen) + } + } + else{ + if (question == 9){ + when(data){ + 0 -> createCell(row, day+1, "Нет", csRed) + else -> createCell(row, day+1, "Да", csGreen) + } + } + else { + when(data){ + 0 -> createCell(row, day+1, "Нет", csGreen) + else -> createCell(row, day+1, "Да", csRed) + } + } + } + } + + fun addAfterDay(day: Int, question: Int, data: Int){ + if ((day > numDaysA) or (question > 12)){ + throw ArrayIndexOutOfBoundsException("Выход за пределы таблицы") + } + val row = sheetAfter.getRow(question+2) + if (question == 1){ + if (data > 5){ + createCell(row, day+1, data.toString(), csRed) + } + else { + createCell(row, day+1, data.toString(), csGreen) + } + } + else{ + if (question in listOf(3, 4, 12)){ + when(data){ + 0 -> createCell(row, day+1, "Нет", csRed) + else -> createCell(row, day+1, "Да", csGreen) + } + } + else { + when(data){ + 0 -> createCell(row, day+1, "Нет", csGreen) + else -> createCell(row, day+1, "Да", csRed) + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/MyFirebaseMessagingService.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/MyFirebaseMessagingService.kt new file mode 100644 index 0000000..6982957 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/MyFirebaseMessagingService.kt @@ -0,0 +1,83 @@ +package com.example.rehabilitation.model_adapter.Edit.adapterFirebase + +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.widget.RemoteViews +import androidx.core.app.NotificationCompat +//import com.google.firebase.messaging.FirebaseMessagingService +//import com.google.firebase.messaging.RemoteMessage + +const val channel_id = "channel_id" +const val channel_name = "user" + +@SuppressLint("MissingFirebaseInstanceTokenRefresh") +//class MyFirebaseMessagingService:FirebaseMessagingService() { + class MyFirebaseMessagingService { +/* + //Вывод уведомления + override fun onMessageReceived(remoteMessage: RemoteMessage) { + if(remoteMessage.notification != null){ + + try { + generateNotification( + remoteMessage.notification!!.title!!, + remoteMessage.notification!!.body!! + ) + } + catch (e: Exception){ + + } + + } + } + + + fun generateNotification(title:String, message:String){ + + val intent = Intent(this, MainActivity::class.java) + //Вывод уведомления поверх всех экранов + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + + //Удаляем уведомление по нажатию на него 1 раз + val pendingIntent = PendingIntent.getActivity(this, 0,intent,PendingIntent.FLAG_ONE_SHOT) + + // + var builder=NotificationCompat.Builder(applicationContext, channel_id) + .setSmallIcon(R.drawable.cart_24)//Изображение + .setAutoCancel(true) + .setVibrate(longArrayOf(1000,1000,1000,1000))//Вибрации 1 секунда вибрации 1 секунда бе и повтор + .setContentIntent(pendingIntent)//Создалии строитель + + builder = builder.setContent(getRemoteView(title, message)) + + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + //Если версия выше или равна oreo + if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){ + val notificationChannel = NotificationChannel(channel_id, channel_name,NotificationManager.IMPORTANCE_HIGH) + notificationManager.createNotificationChannel(notificationChannel) + } + + //Отправляем уведомление + notificationManager.notify(0,builder.build()) + + } + + private fun getRemoteView(title: String, message: String): RemoteViews? { + //Разметка + val remoteView = RemoteViews("com.example.get_post_zaprose.Chat.firebase",R.layout.push_notification) + + //Присваиваем значения + remoteView.setTextViewText(R.id.txtTitle,title) + remoteView.setTextViewText(R.id.txtTitle2,message) + remoteView.setImageViewResource(R.id.imLogo,R.drawable.cart_24) + + return remoteView + + }*/ +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/User.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/User.kt new file mode 100644 index 0000000..d0ff9f7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/User.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.model_adapter.Edit.adapterFirebase + +//Класс с помошью которого мы будем хранить информацию на Firebase +data class ReportPatient( + val name:String? = null,//? - так как может быть равен null + val message:String? = null, +) diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/sample.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/sample.kt new file mode 100644 index 0000000..b13d685 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Edit/adapterFirebase/sample.kt @@ -0,0 +1,11 @@ +package com.example.rehabilitation.model_adapter.Edit.adapterFirebase + +import org.apache.poi.xssf.usermodel.XSSFWorkbook +import java.io.File +import java.io.FileOutputStream + +class sample { + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/MainViewModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/MainViewModel.kt new file mode 100644 index 0000000..2ca4d53 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/MainViewModel.kt @@ -0,0 +1,104 @@ +package com.example.sqlitework.dip + +import android.app.Application +import androidx.lifecycle.* +import com.example.rehabilitation.Sport.Image.Category.CountCategoryModel +import com.example.rehabilitation.Sport.DayListModel +import com.example.rehabilitation.Sport.DayListOneModel +import com.example.rehabilitation.Sport.DayModel +import com.example.rehabilitation.Sport.Image.Doctor.DoctorModel +import com.example.rehabilitation.model_adapter.Edit.EditSportModel +import com.example.rehabilitation.Sport.Image.Category.CountNameCategoryModel +import com.example.rehabilitation.Sport.Image.ImageSportModel +import com.example.rehabilitation.model_adapter.Month.MonthModel +import com.example.rehabilitation.Auth.Model.PatientModel +import com.example.rehabilitation.Calendare.CalendareModel +import com.example.rehabilitation.Progress.AfterListModel +import com.example.rehabilitation.Progress.BeforeListModel +import com.example.rehabilitation.Progress.ProgressModel +import com.example.rehabilitation.Sport.SportForDayModel +import com.example.rehabilitation.model_adapter.Questionnair.AfterModel +import com.example.rehabilitation.model_adapter.Questionnair.BeforeModel +import com.example.rehabilitation.model_adapter.Questionnair.CountSportModel +import com.example.rehabilitation.model_adapter.Questionnair.CountSportPlusModel +import com.example.rehabilitation.model_adapter.Questionnair.NameSportModel +import com.example.rehabilitation.model_adapter.SportCategory.SportCategoryModel +import com.example.rehabilitation.model_adapter.modelCount.CountDayModel +import com.example.rehabilitation.model_adapter.modelCount.CountMonthModel + + +//Тут будут обновлятся данные, следим за списками если что-то обновилось, то уведомлякм и потом ProductAdapter обновит +class MainViewModel(application: Application) :AndroidViewModel(application){ + + + //Объявления + val liveListCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + val liveListList= MutableLiveData>()//Сюда передается новая информация на один день(для все продукции - всего списка) + + val liveDayCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + val liveDayList= MutableLiveData>()//Сюда передается новая информация на один день(для все продукции - всего списка) + val liveDayListProgres= MutableLiveData>()//Сюда передается новая информация на один день(для все продукции - всего списка) + val liveDayListProgres2= MutableLiveData>()//Сюда передается новая информация на один день(для все продукции - всего списка) + + + val liveImageCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + val liveImageList= MutableLiveData>()//Сюда передается новая информация на один день(для все продукции - всего списка) + + + val liveCountCategoryCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + val liveCountNameCategoryCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + + val liveAuthPatientCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + val liveAuthDoctorCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + + + //Количество дней прошедших + val liveCountMonthCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + //Количество пройденых тренировок + val liveCountDayCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + + val liveCountDaySceduleCurrent = MutableLiveData()//Сюда передается новая информация на один день(для слайдера) + + //Информация пациента + val liveSettingPatientCurrent = MutableLiveData() + val liveLookPatientCurrent = MutableLiveData() + val liveSettingDoctorCurrent = MutableLiveData() + + + //Информация для анкетирования + val liveAfterCurrent = MutableLiveData() + val liveBeforeCurrent = MutableLiveData() + val liveCountSportCurrent = MutableLiveData() + val liveCountSportPlusCurrent = MutableLiveData() + val liveNameSportCurrent = MutableLiveData() + val liveCountDaySportandPlusCurrent = MutableLiveData() + + + //Список для редактирвоания + val liveEditSportCurrent = MutableLiveData() + val liveEditSportList= MutableLiveData>() + + //Список для редактирвоания + val liveListDaySportOneCurrent = MutableLiveData() + + + //АНКЕТИРОВАНИЕ + //Список для редактирвоания + val liveListProgresBeforeList = MutableLiveData>() + val liveListProgresAfterList = MutableLiveData>() + + + //ПРОГРЕСС + val liveProgressAllList = MutableLiveData>() + val liveProgressCheckList = MutableLiveData>() + + //Количество упражнений + val liveCountSportCategoryCurrent = MutableLiveData() + val liveSportCategoryAllArticleList = MutableLiveData>() + + //Календарь + val liveCountCalendareCurrent = MutableLiveData() + val liveCountCalendareCurrent2 = MutableLiveData() + val liveAllCalendareList = MutableLiveData>() + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthAdapter.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthAdapter.kt new file mode 100644 index 0000000..cceac25 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthAdapter.kt @@ -0,0 +1,95 @@ +package com.example.rehabilitation.model_adapter.Month + +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.rehabilitation.CursDayNull +import com.example.rehabilitation.R +import com.example.rehabilitation.SportCursDay +import com.example.rehabilitation.databinding.RcItemBinding +import java.time.LocalDate + + +class MonthAdapter(val listener_zakaz: Listener) : ListAdapter( + Comparator() +) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку + + + //В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку + class Holder(view: View, val listener_zakaz: Listener): RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д. + //Для передачи данных + + val binding = RcItemBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки + + var itemTemp: MonthModel? = null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия + + //init - дает возможность внутри адаптера обращаться к элементам экрана + init { + itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка + itemTemp?.let { it1 -> listener_zakaz.onClickExceptionOrder(it1) } + + } + } + + //Функция bind для заполнения + @SuppressLint("SuspiciousIndentation") + fun bind(item: MonthModel) = with(binding) {//Productitem - перпедаем данные + var data = SportCursDay + var dataLocalDate = LocalDate.now().toString() + itemTemp = item + txtDay.text = item.day + txtTitle.text = "День "+item.date + + if(data.toString() == item.date || item.day == CursDayNull){ + binding.cardViewMonth.setCardBackgroundColor(Color.parseColor("#A7DCFF")) + } + else if(dataLocalDate < item.day || item.day == "" && item.day !=CursDayNull ){ + binding.cardViewMonth.setCardBackgroundColor(Color.parseColor("#5DA6E1")) + } + else{ + binding.cardViewMonth.setCardBackgroundColor(Color.parseColor("#98EA88")) + } + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.rc_item, parent, false)//Создаем(надуваем) list_item + return Holder(view, listener_zakaz)//Через Holder возврощаем view + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + val view = holder.bind(getItem(position))//Заполняем по позиции карточку + } + + + //Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает + class Comparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: MonthModel, newItem: MonthModel): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет + return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id) + } + + override fun areContentsTheSame( + oldItem: MonthModel, + newItem: MonthModel + ): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых + return oldItem == newItem//Сравниваем полностью весь список новы и старый + } + } + + //Интерфейс нажатия на кнопку удалить товар из корзины + interface Listener { + fun onClickExceptionOrder(item: MonthModel) + } + + +} + + + + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthModel.kt new file mode 100644 index 0000000..c317fd7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Month/MonthModel.kt @@ -0,0 +1,9 @@ +package com.example.rehabilitation.model_adapter.Month + +data class MonthModel( + val id: String, + val day: String, + val date: String, + val check:String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/AfterModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/AfterModel.kt new file mode 100644 index 0000000..3986f13 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/AfterModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.model_adapter.Questionnair + +data class AfterModel( + val date: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/BeforeModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/BeforeModel.kt new file mode 100644 index 0000000..eadc09b --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/BeforeModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.model_adapter.Questionnair + +data class BeforeModel( + val date: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportModel.kt new file mode 100644 index 0000000..34d7878 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.model_adapter.Questionnair + +data class CountSportModel( + val count: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportPlusModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportPlusModel.kt new file mode 100644 index 0000000..d0d8a1a --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/CountSportPlusModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.model_adapter.Questionnair + +data class CountSportPlusModel( + val count: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/NameSportModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/NameSportModel.kt new file mode 100644 index 0000000..d3cc195 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/Questionnair/NameSportModel.kt @@ -0,0 +1,6 @@ +package com.example.rehabilitation.model_adapter.Questionnair + +data class NameSportModel( + val name: String, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/SportCategory/SportCategoryModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/SportCategory/SportCategoryModel.kt new file mode 100644 index 0000000..757cdc8 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/SportCategory/SportCategoryModel.kt @@ -0,0 +1,13 @@ +package com.example.rehabilitation.model_adapter.SportCategory + +data class SportCategoryModel( + val id: String, + val name: String, + val desc:String, + val count: String, + val image: String, + val category: String, + val article:String, + val check:Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountDayModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountDayModel.kt new file mode 100644 index 0000000..c9540bf --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountDayModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.model_adapter.modelCount + +data class CountDayModel( + val countDown: Int, + val countAll: Int, +) + diff --git a/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountMonthModel.kt b/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountMonthModel.kt new file mode 100644 index 0000000..203aeb7 --- /dev/null +++ b/app/src/main/java/com/example/rehabilitation/model_adapter/modelCount/CountMonthModel.kt @@ -0,0 +1,7 @@ +package com.example.rehabilitation.model_adapter.modelCount + +data class CountMonthModel( + val countDown: Int, + val countAll: Int, +) + diff --git a/app/src/main/res/color/bottom_menu.xml b/app/src/main/res/color/bottom_menu.xml new file mode 100644 index 0000000..3c6b0cf --- /dev/null +++ b/app/src/main/res/color/bottom_menu.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ 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 0000000..515d45e Binary files /dev/null and b/app/src/main/res/drawable/add1.png differ diff --git a/app/src/main/res/drawable/amputation.png b/app/src/main/res/drawable/amputation.png new file mode 100644 index 0000000..369a3c1 Binary files /dev/null and b/app/src/main/res/drawable/amputation.png differ diff --git a/app/src/main/res/drawable/arrow.xml b/app/src/main/res/drawable/arrow.xml new file mode 100644 index 0000000..2e30840 --- /dev/null +++ b/app/src/main/res/drawable/arrow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/arrow_24.xml b/app/src/main/res/drawable/arrow_24.xml new file mode 100644 index 0000000..8452791 --- /dev/null +++ b/app/src/main/res/drawable/arrow_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/b_sport.png b/app/src/main/res/drawable/b_sport.png new file mode 100644 index 0000000..f17315a Binary files /dev/null and b/app/src/main/res/drawable/b_sport.png differ diff --git a/app/src/main/res/drawable/basket_24.xml b/app/src/main/res/drawable/basket_24.xml new file mode 100644 index 0000000..7a0a3eb --- /dev/null +++ b/app/src/main/res/drawable/basket_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/c_sport.png b/app/src/main/res/drawable/c_sport.png new file mode 100644 index 0000000..95fdc17 Binary files /dev/null and b/app/src/main/res/drawable/c_sport.png differ diff --git a/app/src/main/res/drawable/calendar24.xml b/app/src/main/res/drawable/calendar24.xml new file mode 100644 index 0000000..b89360f --- /dev/null +++ b/app/src/main/res/drawable/calendar24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/calendar_day_legend_container.xml b/app/src/main/res/drawable/calendar_day_legend_container.xml new file mode 100644 index 0000000..3edf338 --- /dev/null +++ b/app/src/main/res/drawable/calendar_day_legend_container.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/calendar_day_legend_text.xml b/app/src/main/res/drawable/calendar_day_legend_text.xml new file mode 100644 index 0000000..522eb03 --- /dev/null +++ b/app/src/main/res/drawable/calendar_day_legend_text.xml @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/calendar_view_activity.xml b/app/src/main/res/drawable/calendar_view_activity.xml new file mode 100644 index 0000000..d001e1a --- /dev/null +++ b/app/src/main/res/drawable/calendar_view_activity.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/calendar_view_options_item_view.xml b/app/src/main/res/drawable/calendar_view_options_item_view.xml new file mode 100644 index 0000000..9d08b7d --- /dev/null +++ b/app/src/main/res/drawable/calendar_view_options_item_view.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/calendarv2.png b/app/src/main/res/drawable/calendarv2.png new file mode 100644 index 0000000..84ae4fb Binary files /dev/null and b/app/src/main/res/drawable/calendarv2.png differ diff --git a/app/src/main/res/drawable/cart_24.xml b/app/src/main/res/drawable/cart_24.xml new file mode 100644 index 0000000..ba0b471 --- /dev/null +++ b/app/src/main/res/drawable/cart_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/check.png b/app/src/main/res/drawable/check.png new file mode 100644 index 0000000..ede32da Binary files /dev/null and b/app/src/main/res/drawable/check.png differ diff --git a/app/src/main/res/drawable/check_24.xml b/app/src/main/res/drawable/check_24.xml new file mode 100644 index 0000000..bc136f2 --- /dev/null +++ b/app/src/main/res/drawable/check_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_1.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_1.jpg new file mode 100644 index 0000000..cff3fdb Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_1.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_10.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_10.jpg new file mode 100644 index 0000000..0ab0b0b Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_10.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_11.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_11.jpg new file mode 100644 index 0000000..572c461 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_11.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_12.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_12.jpg new file mode 100644 index 0000000..8073da7 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_12.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_13.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_13.jpg new file mode 100644 index 0000000..137b36d Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_13.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_14.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_14.jpg new file mode 100644 index 0000000..d9276cb Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_14.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_2.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_2.jpg new file mode 100644 index 0000000..af88fb0 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_2.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_3.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_3.jpg new file mode 100644 index 0000000..67339a4 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_3.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_4.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_4.jpg new file mode 100644 index 0000000..974c794 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_4.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_5.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_5.jpg new file mode 100644 index 0000000..ba37678 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_5.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_6.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_6.jpg new file mode 100644 index 0000000..6baa009 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_6.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_7.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_7.jpg new file mode 100644 index 0000000..d6c8f3d Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_7.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_8.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_8.jpg new file mode 100644 index 0000000..28e12b6 Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_8.jpg differ diff --git a/app/src/main/res/drawable/decongestant_therapy_late_img_9.jpg b/app/src/main/res/drawable/decongestant_therapy_late_img_9.jpg new file mode 100644 index 0000000..a3d6c2f Binary files /dev/null and b/app/src/main/res/drawable/decongestant_therapy_late_img_9.jpg differ diff --git a/app/src/main/res/drawable/door_24.xml b/app/src/main/res/drawable/door_24.xml new file mode 100644 index 0000000..21f5a54 --- /dev/null +++ b/app/src/main/res/drawable/door_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/elastic_bandage.jpg b/app/src/main/res/drawable/elastic_bandage.jpg new file mode 100644 index 0000000..93c30ba Binary files /dev/null and b/app/src/main/res/drawable/elastic_bandage.jpg differ diff --git a/app/src/main/res/drawable/example_5_selected_bg.xml b/app/src/main/res/drawable/example_5_selected_bg.xml new file mode 100644 index 0000000..3619ce8 --- /dev/null +++ b/app/src/main/res/drawable/example_5_selected_bg.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/folder.png b/app/src/main/res/drawable/folder.png new file mode 100644 index 0000000..a7f15a2 Binary files /dev/null and b/app/src/main/res/drawable/folder.png differ diff --git a/app/src/main/res/drawable/formation_of_the_stump.jpg b/app/src/main/res/drawable/formation_of_the_stump.jpg new file mode 100644 index 0000000..71d0045 Binary files /dev/null and b/app/src/main/res/drawable/formation_of_the_stump.jpg differ diff --git a/app/src/main/res/drawable/gradientv1.xml b/app/src/main/res/drawable/gradientv1.xml new file mode 100644 index 0000000..2b00d72 --- /dev/null +++ b/app/src/main/res/drawable/gradientv1.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/home_24.xml b/app/src/main/res/drawable/home_24.xml new file mode 100644 index 0000000..5a870f5 --- /dev/null +++ b/app/src/main/res/drawable/home_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/homev2.png b/app/src/main/res/drawable/homev2.png new file mode 100644 index 0000000..c184f1d Binary files /dev/null and b/app/src/main/res/drawable/homev2.png differ diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml new file mode 100644 index 0000000..0258249 --- /dev/null +++ b/app/src/main/res/drawable/ic_add.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_image.xml b/app/src/main/res/drawable/ic_add_image.xml new file mode 100644 index 0000000..8232c4d --- /dev/null +++ b/app/src/main/res/drawable/ic_add_image.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_airplane_landing.xml b/app/src/main/res/drawable/ic_airplane_landing.xml new file mode 100644 index 0000000..21fc0c9 --- /dev/null +++ b/app/src/main/res/drawable/ic_airplane_landing.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_airplane_takeoff.xml b/app/src/main/res/drawable/ic_airplane_takeoff.xml new file mode 100644 index 0000000..c0f531a --- /dev/null +++ b/app/src/main/res/drawable/ic_airplane_takeoff.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml new file mode 100644 index 0000000..6541ee3 --- /dev/null +++ b/app/src/main/res/drawable/ic_check.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_chevron_left.xml b/app/src/main/res/drawable/ic_chevron_left.xml new file mode 100644 index 0000000..e6bb3ca --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml new file mode 100644 index 0000000..2483512 --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml new file mode 100644 index 0000000..ede4b71 --- /dev/null +++ b/app/src/main/res/drawable/ic_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/information.png b/app/src/main/res/drawable/information.png new file mode 100644 index 0000000..b4cf9c3 Binary files /dev/null and b/app/src/main/res/drawable/information.png differ diff --git a/app/src/main/res/drawable/informationv2.png b/app/src/main/res/drawable/informationv2.png new file mode 100644 index 0000000..9b942ea Binary files /dev/null and b/app/src/main/res/drawable/informationv2.png differ diff --git a/app/src/main/res/drawable/j_sport.png b/app/src/main/res/drawable/j_sport.png new file mode 100644 index 0000000..20aef0c Binary files /dev/null and b/app/src/main/res/drawable/j_sport.png differ diff --git a/app/src/main/res/drawable/loading.gif b/app/src/main/res/drawable/loading.gif new file mode 100644 index 0000000..8e4be53 Binary files /dev/null and b/app/src/main/res/drawable/loading.gif differ diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000..7ef0b34 Binary files /dev/null and b/app/src/main/res/drawable/logo.png differ diff --git a/app/src/main/res/drawable/logovm.png b/app/src/main/res/drawable/logovm.png new file mode 100644 index 0000000..13ed986 Binary files /dev/null and b/app/src/main/res/drawable/logovm.png differ diff --git a/app/src/main/res/drawable/logovmed.jpg b/app/src/main/res/drawable/logovmed.jpg new file mode 100644 index 0000000..9b95fbb Binary files /dev/null and b/app/src/main/res/drawable/logovmed.jpg differ diff --git a/app/src/main/res/drawable/logovmedi.png b/app/src/main/res/drawable/logovmedi.png new file mode 100644 index 0000000..dceaea1 Binary files /dev/null and b/app/src/main/res/drawable/logovmedi.png differ diff --git a/app/src/main/res/drawable/logovmediv2.jpg b/app/src/main/res/drawable/logovmediv2.jpg new file mode 100644 index 0000000..43cceb6 Binary files /dev/null and b/app/src/main/res/drawable/logovmediv2.jpg differ diff --git a/app/src/main/res/drawable/logovmediv3d.png b/app/src/main/res/drawable/logovmediv3d.png new file mode 100644 index 0000000..7484068 Binary files /dev/null and b/app/src/main/res/drawable/logovmediv3d.png differ diff --git a/app/src/main/res/drawable/logovmvmedi.png b/app/src/main/res/drawable/logovmvmedi.png new file mode 100644 index 0000000..6a1e105 Binary files /dev/null and b/app/src/main/res/drawable/logovmvmedi.png differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_1.jpg b/app/src/main/res/drawable/massage_technique_late_img_1.jpg new file mode 100644 index 0000000..1c1432d Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_1.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_2.jpg b/app/src/main/res/drawable/massage_technique_late_img_2.jpg new file mode 100644 index 0000000..fdd1274 Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_2.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_3.jpg b/app/src/main/res/drawable/massage_technique_late_img_3.jpg new file mode 100644 index 0000000..61cce49 Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_3.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_4.jpg b/app/src/main/res/drawable/massage_technique_late_img_4.jpg new file mode 100644 index 0000000..091bf15 Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_4.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_5.jpg b/app/src/main/res/drawable/massage_technique_late_img_5.jpg new file mode 100644 index 0000000..9fb195f Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_5.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_6.jpg b/app/src/main/res/drawable/massage_technique_late_img_6.jpg new file mode 100644 index 0000000..69b4d5b Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_6.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_7.jpg b/app/src/main/res/drawable/massage_technique_late_img_7.jpg new file mode 100644 index 0000000..000aacb Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_7.jpg differ diff --git a/app/src/main/res/drawable/massage_technique_late_img_8.jpg b/app/src/main/res/drawable/massage_technique_late_img_8.jpg new file mode 100644 index 0000000..d15e490 Binary files /dev/null and b/app/src/main/res/drawable/massage_technique_late_img_8.jpg differ diff --git a/app/src/main/res/drawable/medac.jpg b/app/src/main/res/drawable/medac.jpg new file mode 100644 index 0000000..b4ec44c Binary files /dev/null and b/app/src/main/res/drawable/medac.jpg differ diff --git a/app/src/main/res/drawable/message_24.xml b/app/src/main/res/drawable/message_24.xml new file mode 100644 index 0000000..c20e247 --- /dev/null +++ b/app/src/main/res/drawable/message_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/motor_mode.jpg b/app/src/main/res/drawable/motor_mode.jpg new file mode 100644 index 0000000..019050b Binary files /dev/null and b/app/src/main/res/drawable/motor_mode.jpg differ diff --git a/app/src/main/res/drawable/patient.png b/app/src/main/res/drawable/patient.png new file mode 100644 index 0000000..d225a6d Binary files /dev/null and b/app/src/main/res/drawable/patient.png differ diff --git a/app/src/main/res/drawable/prevention_of_contractures.jpg b/app/src/main/res/drawable/prevention_of_contractures.jpg new file mode 100644 index 0000000..2b5ba65 Binary files /dev/null and b/app/src/main/res/drawable/prevention_of_contractures.jpg differ diff --git a/app/src/main/res/drawable/prevention_of_contractures1.jpg b/app/src/main/res/drawable/prevention_of_contractures1.jpg new file mode 100644 index 0000000..8f79a90 Binary files /dev/null and b/app/src/main/res/drawable/prevention_of_contractures1.jpg differ diff --git a/app/src/main/res/drawable/prevention_of_contractures2.jpg b/app/src/main/res/drawable/prevention_of_contractures2.jpg new file mode 100644 index 0000000..690ad9e Binary files /dev/null and b/app/src/main/res/drawable/prevention_of_contractures2.jpg differ diff --git a/app/src/main/res/drawable/prevention_of_contractures3.jpg b/app/src/main/res/drawable/prevention_of_contractures3.jpg new file mode 100644 index 0000000..3b2c5af Binary files /dev/null and b/app/src/main/res/drawable/prevention_of_contractures3.jpg differ diff --git a/app/src/main/res/drawable/progres.png b/app/src/main/res/drawable/progres.png new file mode 100644 index 0000000..5f5ff84 Binary files /dev/null and b/app/src/main/res/drawable/progres.png differ diff --git a/app/src/main/res/drawable/progresv2.png b/app/src/main/res/drawable/progresv2.png new file mode 100644 index 0000000..b7a6d62 Binary files /dev/null and b/app/src/main/res/drawable/progresv2.png differ diff --git a/app/src/main/res/drawable/rectangle.xml b/app/src/main/res/drawable/rectangle.xml new file mode 100644 index 0000000..10bb072 --- /dev/null +++ b/app/src/main/res/drawable/rectangle.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/schedule.png b/app/src/main/res/drawable/schedule.png new file mode 100644 index 0000000..378c8c9 Binary files /dev/null and b/app/src/main/res/drawable/schedule.png differ diff --git a/app/src/main/res/drawable/schedulev2.png b/app/src/main/res/drawable/schedulev2.png new file mode 100644 index 0000000..45206ff Binary files /dev/null and b/app/src/main/res/drawable/schedulev2.png differ diff --git a/app/src/main/res/drawable/setting.png b/app/src/main/res/drawable/setting.png new file mode 100644 index 0000000..2c4818e Binary files /dev/null and b/app/src/main/res/drawable/setting.png differ diff --git a/app/src/main/res/drawable/settings_24.xml b/app/src/main/res/drawable/settings_24.xml new file mode 100644 index 0000000..298a5a1 --- /dev/null +++ b/app/src/main/res/drawable/settings_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/silicone_case.jpg b/app/src/main/res/drawable/silicone_case.jpg new file mode 100644 index 0000000..dd4f567 Binary files /dev/null and b/app/src/main/res/drawable/silicone_case.jpg differ diff --git a/app/src/main/res/drawable/sportshebuleicon.png b/app/src/main/res/drawable/sportshebuleicon.png new file mode 100644 index 0000000..56f4b86 Binary files /dev/null and b/app/src/main/res/drawable/sportshebuleicon.png differ diff --git a/app/src/main/res/drawable/stump_care.jpg b/app/src/main/res/drawable/stump_care.jpg new file mode 100644 index 0000000..0c28360 Binary files /dev/null and b/app/src/main/res/drawable/stump_care.jpg differ diff --git a/app/src/main/res/drawable/surface_sensitivity1.jpg b/app/src/main/res/drawable/surface_sensitivity1.jpg new file mode 100644 index 0000000..fb7ecc4 Binary files /dev/null and b/app/src/main/res/drawable/surface_sensitivity1.jpg differ diff --git a/app/src/main/res/drawable/surface_sensitivity2.jpg b/app/src/main/res/drawable/surface_sensitivity2.jpg new file mode 100644 index 0000000..190493b Binary files /dev/null and b/app/src/main/res/drawable/surface_sensitivity2.jpg differ diff --git a/app/src/main/res/drawable/surface_sensitivity3.jpg b/app/src/main/res/drawable/surface_sensitivity3.jpg new file mode 100644 index 0000000..81c7562 Binary files /dev/null and b/app/src/main/res/drawable/surface_sensitivity3.jpg differ diff --git a/app/src/main/res/drawable/surface_sensitivity_2.jpg b/app/src/main/res/drawable/surface_sensitivity_2.jpg new file mode 100644 index 0000000..aa012e9 Binary files /dev/null and b/app/src/main/res/drawable/surface_sensitivity_2.jpg differ diff --git a/app/src/main/res/drawable/tab_indicator.xml b/app/src/main/res/drawable/tab_indicator.xml new file mode 100644 index 0000000..c88a992 --- /dev/null +++ b/app/src/main/res/drawable/tab_indicator.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/treatment_by_position.jpg b/app/src/main/res/drawable/treatment_by_position.jpg new file mode 100644 index 0000000..47f9866 Binary files /dev/null and b/app/src/main/res/drawable/treatment_by_position.jpg differ diff --git a/app/src/main/res/drawable/unchecked_24.xml b/app/src/main/res/drawable/unchecked_24.xml new file mode 100644 index 0000000..f3733bf --- /dev/null +++ b/app/src/main/res/drawable/unchecked_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/visible_aes.png b/app/src/main/res/drawable/visible_aes.png new file mode 100644 index 0000000..62dc80a Binary files /dev/null and b/app/src/main/res/drawable/visible_aes.png differ diff --git a/app/src/main/res/drawable/visible_eas_false.png b/app/src/main/res/drawable/visible_eas_false.png new file mode 100644 index 0000000..62dc80a Binary files /dev/null and b/app/src/main/res/drawable/visible_eas_false.png differ diff --git a/app/src/main/res/drawable/visible_eas_true.png b/app/src/main/res/drawable/visible_eas_true.png new file mode 100644 index 0000000..59c30d9 Binary files /dev/null and b/app/src/main/res/drawable/visible_eas_true.png differ diff --git a/app/src/main/res/font/roboto_bold.ttf b/app/src/main/res/font/roboto_bold.ttf new file mode 100644 index 0000000..43da14d Binary files /dev/null and b/app/src/main/res/font/roboto_bold.ttf differ diff --git a/app/src/main/res/font/roboto_medium.ttf b/app/src/main/res/font/roboto_medium.ttf new file mode 100644 index 0000000..ac0f908 Binary files /dev/null and b/app/src/main/res/font/roboto_medium.ttf differ diff --git a/app/src/main/res/layout/activity_auth_doctor.xml b/app/src/main/res/layout/activity_auth_doctor.xml new file mode 100644 index 0000000..8e656e5 --- /dev/null +++ b/app/src/main/res/layout/activity_auth_doctor.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_authorization.xml b/app/src/main/res/layout/activity_authorization.xml new file mode 100644 index 0000000..6eef837 --- /dev/null +++ b/app/src/main/res/layout/activity_authorization.xml @@ -0,0 +1,79 @@ + + + + + + + +