patient
Clogon 2023-11-03 09:59:18 +03:00
commit 819a66dcad
169 changed files with 10338 additions and 0 deletions

15
.gitignore vendored 100644
View File

@ -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

3
.idea/.gitignore vendored 100644
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

20
.idea/gradle.xml 100644
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.0" />
</component>
</project>

9
.idea/misc.xml 100644
View File

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml 100644
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

1
app/.gitignore vendored 100644
View File

@ -0,0 +1 @@
/build

96
app/build.gradle 100644
View File

@ -0,0 +1,96 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.example.doctor'
compileSdk 33
defaultConfig {
applicationId "com.example.doctor"
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'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures{
viewBinding true
}
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "com.mikepenz:materialdrawer:7.0.0"
implementation "com.mikepenz:materialdrawer-nav:7.0.0"
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.1.17'
implementation platform('com.google.firebase:firebase-bom:31.2.0')
implementation 'com.google.firebase:firebase-database-ktx:20.1.0'
implementation 'com.google.firebase:firebase-auth-ktx:21.1.0'
implementation 'com.android.volley:volley:1.2.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'androidx.fragment:fragment-ktx:1.5.5'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.test:core-ktx:1.4.0'
implementation 'androidx.games:games-activity:1.1.0'
implementation 'com.google.mlkit:common:18.1.0'
implementation 'com.google.firebase:firebase-messaging-ktx:23.1.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
implementation 'com.kizitonwose.calendar:view:2.0.0'
//Lifecycle
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
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'
//Свайп
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
}

21
app/proguard-rules.pro vendored 100644
View File

@ -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

View File

@ -0,0 +1,24 @@
package com.example.doctor
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.doctor", appContext.packageName)
}
}

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Doctor"
tools:targetApi="31">
<activity
android:name=".Auth.AuthActivity"
android:exported="false" />
<activity
android:name="MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustPan|stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>

View File

@ -0,0 +1,17 @@
package com.example.doctor.Adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class VpAdapter(fr_act:FragmentActivity, private val list:List<Fragment>):FragmentStateAdapter(fr_act) {//private val list:List<Fragment> - список с фрагментами сюда передастся, тоесть с двумя фрагментами
//Возврощаем для createFragment количество элементов(фрагментов) в листе(List)
override fun getItemCount(): Int {
return list.size//возврощаем количество фрагметов
}
//Позиция фрагмента или 1 или 2, то есть 0 или 1. И по позиции будут выводится фрагмент.
override fun createFragment(position: Int): Fragment {
return list[position]//Возврощаем фрагмент из листа по позиции
}
}

View File

@ -0,0 +1,17 @@
package com.example.doctor.Adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class VpEditSportAdapter(fr_act:FragmentActivity, private val list: List<Any>):FragmentStateAdapter(fr_act) {//private val list:List<Fragment> - список с фрагментами сюда передастся, тоесть с двумя фрагментами
//Возврощаем для createFragment количество элементов(фрагментов) в листе(List)
override fun getItemCount(): Int {
return list.size//возврощаем количество фрагметов
}
//Позиция фрагмента или 1 или 2, то есть 0 или 1. И по позиции будут выводится фрагмент.
override fun createFragment(position: Int): Fragment {
return list[position] as Fragment//Возврощаем фрагмент из листа по позиции
}
}

View File

@ -0,0 +1,65 @@
package com.example.doctor.Appeals
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 com.example.doctor.Adapter.VpAdapter
import com.example.doctor.R
import com.example.doctor.Appeals.TabLayout.OldAppealsFragment
import com.example.doctor.Appeals.TabLayout.NewAppealsFragment
import com.example.doctor.databinding.FragmentAppealsBinding
import com.google.android.material.tabs.TabLayoutMediator
class AppealsFragment : Fragment() {
private lateinit var binding:FragmentAppealsBinding
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()
}
//Функция подключения переключения
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()
}
}

View File

@ -0,0 +1,112 @@
package com.example.doctor.Appeals
import android.annotation.SuppressLint
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemAppealsBinding
import com.example.doctor.databinding.ItemAppealsNewBinding
class AppealsNewAdapter(val listener_zakaz: Listener) :
ListAdapter<AppealsNewModel, AppealsNewAdapter.Holder>(
Comparator()
) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку
//В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку
class Holder(view: View, val listener_zakaz: Listener) :
RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д.
//Для передачи данных
val binding =
ItemAppealsNewBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки
var itemTemp: AppealsNewModel? =
null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия
//init - дает возможность внутри адаптера обращаться к элементам экрана
init {
itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка
itemView.setEnabled(false)
itemTemp?.let { it1 -> listener_zakaz.onClickAppeals(it1) }
}
}
@SuppressLint("SuspiciousIndentation")
fun bind(item: AppealsNewModel) = with(binding) {//Productitem - перпедаем данные
itemTemp = item
txtNumber.text = item.id.toString()+"."
txtAppeals.text = item.text
txtLoginPatient.text = item.login
if (item.expand) {
txtAppeals.maxLines = 100
} else {
txtAppeals.maxLines = 1
}
CardViewNew.setOnClickListener {
if (item.expand == false) {
txtAppeals.maxLines = 100
item.expand = true
} else {
txtAppeals.maxLines = 1
item.expand = false
}
}
btnAdd.setOnClickListener{
CardViewNew.visibility = View.GONE
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_appeals_new, parent, false)//Создаем(надуваем) list_item
return Holder(view, listener_zakaz)//Через Holder возврощаем view
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))//Заполняем по позиции карточку
}
//Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает
class Comparator : DiffUtil.ItemCallback<AppealsNewModel>() {
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)
}
}

View File

@ -0,0 +1,10 @@
package com.example.doctor.Appeals
data class AppealsNewModel(
val id: Int,
val login: String,
val text: String,
val id_user:Int,
var expand : Boolean = false
)

View File

@ -0,0 +1,109 @@
package com.example.doctor.Appeals
import android.annotation.SuppressLint
import android.opengl.Visibility
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemAppealsOldBinding
class AppealsOldAdapter(val listener_zakaz: Listener) :
ListAdapter<AppealsOldModel, AppealsOldAdapter.Holder>(
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.id.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<AppealsOldModel>() {
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)
}
}

View File

@ -0,0 +1,10 @@
package com.example.doctor.Appeals
data class AppealsOldModel(
val id: Int,
val login: String,
val text: String,
val id_user:Int,
var expand : Boolean = false
)

View File

@ -0,0 +1,81 @@
package com.example.doctor.Appeals.TabLayout
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.Appeals.AppealsNewAdapter
import com.example.doctor.Appeals.AppealsNewModel
import com.example.doctor.DoctorViewModel
import com.example.doctor.databinding.FragmentNewAppealsBinding
class NewAppealsFragment : Fragment(), AppealsNewAdapter.Listener {
private lateinit var binding:FragmentNewAppealsBinding
private val model: DoctorViewModel by activityViewModels()
lateinit var adapter: AppealsNewAdapter
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()
model.appealsNewList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment
adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter)
}
addNewAppeals()
}
private fun addNewAppeals() {
val list = ArrayList<AppealsNewModel>()
for (i in 1..5){
val itemPatient = AppealsNewModel(
i,
"Patient_$i",
"asdasds adnas kjhdkl ashdlkashdkjalks hdjlkasjdlk ajldkhas j djask hsfldksjfksdf",
i,
)
list.add(itemPatient)//Передали заполненый список
}
model.appealsNewList.value = list
}
//Вывод прогресса на один день
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)
rcView.adapter = adapter
}
companion object {
fun newInstance() = NewAppealsFragment()
}
override fun onClickAppeals(item: AppealsNewModel) {
}
}

View File

@ -0,0 +1,78 @@
package com.example.doctor.Appeals.TabLayout
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.Appeals.AppealsOldAdapter
import com.example.doctor.Appeals.AppealsOldModel
import com.example.doctor.DoctorViewModel
import com.example.doctor.databinding.FragmentOldAppealsBinding
class OldAppealsFragment : Fragment(), AppealsOldAdapter.Listener {
private lateinit var binding:FragmentOldAppealsBinding
private val model: DoctorViewModel by activityViewModels()
lateinit var adapter: AppealsOldAdapter
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.appealsAllList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment
adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter)
}
addAllAppeals()
}
private fun addAllAppeals() {
val list = ArrayList<AppealsOldModel>()
for (i in 1..7){
val itemPatient = AppealsOldModel(
i,
"Patient_$i",
" 81 23891 23812 37817411 sdasds adnas kjhdkl ashdlk ashdkjalks ashdlkashdkjalks hdjlkasjdlk ajldkhas hdjlkasjdlk ajldkhasas hdlkashdkjalks hdjlkasjdlk ajldkhasashdlkashdkjalks hdjlkasjdlk ajldkhas j djask hsfldksjfksdf",
i,
)
list.add(itemPatient)//Передали заполненый список
}
model.appealsAllList.value = list
}
//Вывод прогресса на один день
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) {
}
}

View File

@ -0,0 +1,22 @@
package com.example.doctor.Auth
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.doctor.R
import com.example.doctor.databinding.ActivityAuthBinding
class AuthActivity : AppCompatActivity() {
private lateinit var binding:ActivityAuthBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAuthBinding.inflate(layoutInflater)
setContentView(binding.root)
//Вывод фрагмента на активити при первоначальной загрузке
supportFragmentManager.beginTransaction()
.replace(R.id.CLAuth, AuthFragment.newInstance())
.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
}

View File

@ -0,0 +1,173 @@
package com.example.doctor.Auth
import android.annotation.SuppressLint
import android.content.Intent
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.doctor.Auth.Model.AuthModel
import com.example.doctor.Auth.Model.UserModel
import com.example.doctor.DoctorViewModel
import com.example.doctor.MainActivity
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.R
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Pref.SavePref
import com.example.doctor.Toast.showCustomDangerToast
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.FragmentAuthBinding
import com.squareup.picasso.Picasso
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
class AuthFragment : Fragment() {
private lateinit var binding: FragmentAuthBinding
private lateinit var doctorApi: DoctorApi
private val DoctorviewModel: DoctorViewModel by activityViewModels()
//private var prefToken: SharedPreferences? = null
private var Token = ""
val prefDoctorSave = SavePref()
val prefDoctorConclusion = ConclusionPref()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAuthBinding.inflate(layoutInflater, container, false)
return binding.root
}
@SuppressLint("SuspiciousIndentation")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRetrofit()
Token = prefDoctorConclusion.conclusionToken(requireContext())
binding.apply {
binding.textError.text = ""
//Авторизоваться
binding.btnAuth.setOnClickListener {
if(edLogin.text.toString() == ""||edPassword.text.toString() == ""){
Toast(requireContext()).showCustomInfoToast(
"Не все поля заполнены",
requireActivity()
)
}
else{
Auth(
AuthModel(
edLogin.text.toString(),
edPassword.text.toString(),
)
)
}
}
}
}
// private fun Auth(authModel: AuthModel) {
// CoroutineScope(Dispatchers.IO).launch {
// val response = doctorApi.Auth(authModel)
// val errorMessage = response.errorBody()?.string()
// ?.let { JSONObject(it).getString("message") }//JSONObject(response.errorBody()?.string())
// requireActivity().runOnUiThread {
// binding.textError.text = errorMessage
// val user = response.body()
//
// //Если есть такой пользователь
// if (user != null) {
// DoctorviewModel.token.value = user.token
// prefDoctor.saveToken(user.token)
// val intetn = Intent(requireContext(), MainActivity::class.java)
// startActivity(intetn)
// activity?.finish()
// }
// }
// }
//
// }
//
// private fun Auth(authModel: AuthModel) {
// //Если есть такой пользователь
// if (authModel.login == "asd" && authModel.password == "asd" ) {
// DoctorviewModel.token.value = "sdadssdasdaasdad434fk3ioj9"
// prefDoctorSave.saveToken(requireContext(),"sdadssdasdaasdad434fk3ioj9")
// val intetn = Intent(requireContext(), MainActivity::class.java)
// startActivity(intetn)
// activity?.finish()
// }
//
// }
private fun Auth(authModel: AuthModel) {
CoroutineScope(Dispatchers.IO).launch {
val response = doctorApi.LoginDoctor(authModel)
val errorMessage = response.errorBody()?.string()
?.let { JSONObject(it).getString("error") }//JSONObject(response.errorBody()?.string())
requireActivity().runOnUiThread {
Log.i("errorMessage",errorMessage.toString())
val user = response.body()
//Если есть такой пользователь
if (user != null) {
DoctorviewModel.token.value = user.token
prefDoctorSave.saveToken(requireContext(), user.token)
val intetn = Intent(requireContext(), MainActivity::class.java)
startActivity(intetn)
activity?.finish()
}
else{
Toast(requireContext()).showCustomInfoToast(
"Такого пользователя нету",
requireActivity()
)
}
}
}
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
companion object {
fun newInstance() = AuthFragment()
}
}

View File

@ -0,0 +1,7 @@
package com.example.doctor.Auth.Model
data class AuthModel(
//val login:String,
val login:String,
val password:String,
)

View File

@ -0,0 +1,5 @@
package com.example.doctor.Auth.Model
data class CheckTokenModel(
val status:String,
)

View File

@ -0,0 +1,7 @@
package com.example.doctor.Auth.Model
data class UserModel(
val id:String,
val token:String,
)

View File

@ -0,0 +1,171 @@
//package com.example.doctor.BottomSheetMenu
//
//import android.annotation.SuppressLint
//import android.app.Dialog
//import android.graphics.Color
//import android.os.Bundle
//import android.support.annotation.Nullable
//import android.view.KeyEvent
//import android.view.LayoutInflater
//import android.view.View
//import android.view.ViewGroup
//import android.widget.FrameLayout
//import android.widget.Toast
//import androidx.coordinatorlayout.widget.CoordinatorLayout
//import androidx.fragment.app.activityViewModels
//import com.example.doctor.DoctorViewModel
//import com.example.doctor.R
//import com.example.doctor.databinding.ItemButtomMenu2Binding
//import com.google.android.material.bottomsheet.BottomSheetBehavior
//import com.google.android.material.bottomsheet.BottomSheetDialogFragment
//
//class AccountBottomSheetMenu: BottomSheetDialogFragment() {
// private lateinit var binding: ItemButtomMenu2Binding
// private val model: DoctorViewModel by activityViewModels()//Инициализировали класс
//
// @SuppressLint("RestrictedApi")
// override fun setupDialog(dialog: Dialog, style: Int) {
// super.setupDialog(dialog, style)
//
// val view = LayoutInflater.from(context).inflate(R.layout.item_buttom_menu, null)
// dialog.setContentView(view)
//
// val param = (view.parent as View).layoutParams as CoordinatorLayout.LayoutParams
//
// val behavior = param.behavior
//
// if(behavior is BottomSheetBehavior<*>){
// behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback(){
// override fun onStateChanged(bottomSheet: View, newState: Int) {
// var state = ""
// when(newState){
// BottomSheetBehavior.STATE_DRAGGING->{
// state = "DRAGGING"
// }
// BottomSheetBehavior.STATE_SETTLING->{
// state = "SETTLING"
// }
// BottomSheetBehavior.STATE_EXPANDED->{
// state = "EXPANDED"
// }
// BottomSheetBehavior.STATE_COLLAPSED->{
// state = "COLLAPSED"
// }
// BottomSheetBehavior.STATE_HIDDEN->{
// state = "HIDDEN"
// dismiss()
// behavior.state = BottomSheetBehavior.STATE_COLLAPSED
// }
//
// }
// }
//
// override fun onSlide(bottomSheet: View, slideOffset: Float) {
//
// }
//
// })
// }
// }
//
// //Данная функция необходима чтобы убрать белый фон в нижнем всплывающем меню
// override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
//
// return super.onCreateDialog(savedInstanceState).apply {
// // window?.setDimAmount(0.2f) // Set dim amount here
// setOnShowListener {
// val bottomSheet = findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
// bottomSheet.setBackgroundResource(android.R.color.transparent)
// }
// }
// }
//
//
// override fun onCreateView(
// inflater: LayoutInflater,
// container: ViewGroup?,
// savedInstanceState: Bundle?
// ): View? {
// binding = ItemButtomMenu2Binding.inflate(inflater,container,false)
// return binding.root
// }
//
//
//
//
// companion object {
//
// fun newInstance(): AccountBottomSheetMenu {
// val args = Bundle()
// val fragment = AccountBottomSheetMenu()
// fragment.arguments = args
// return fragment
// }
// }
//
//
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// super.onViewCreated(view, savedInstanceState)
//
// /* //Ввод адреса вручную
// binding.btnAdresAdd.setOnClickListener{
// binding.CardViewStart.visibility = View.GONE
// binding.CardView1.visibility = View.VISIBLE
// }
// //Вернутся из ввода адреса
// binding.btnBack.setOnClickListener{
// binding.CardViewStart.visibility = View.VISIBLE
// binding.CardView1.visibility = View.GONE
// }*/
// //Оформления заказа по введенному адресу
// /* binding.btnAddZakaz.setOnClickListener{
// setListener()
// }*/
// /*//Оформления заказа по адресу из профиля
// binding.btnZakazAdresUserProfile.setOnClickListener{
// setListener()
// }*/
// //Вызов фунции
// setListener()
//
//
// //binding.textView34.setText(binding.editTextAdres.getText().toString())
// }
//
// //Функция оформления заказа
// private fun setListener(){
// /* binding.btnAddZakaz.setOnClickListener{
// adresUser = binding.editTextAdres.text.toString()
// if(adresUser == ""){
// Toast.makeText(requireContext(), "Нужен адрес", Toast.LENGTH_SHORT).show()
// }
// else{
// //Данная модель нужна только для того чтобы передать сигнал для BasketFragmen и в случае если true, то он вызовет запрос и прогрузочный экран
// val itemStatus = StatusModel(true)
// model.addZakaz.value = itemStatus
// dismiss()//После нажатия закрываем
// }
// //requestWithSomeHttpHeadersZakaz(requireContext(), adresUser)
// }
// binding.editTextAdres.setOnKeyListener { v, keyCode, event ->
//
// when {
// //Проверяем нажалили мы на "ввод"
// //Check if it is the Enter-Key, Check if the Enter Key was pressed down
// ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.action == KeyEvent.ACTION_DOWN)) -> {
//
// //Если да, то выполняем нажати на кнопку отправки сообщения
// binding.btnAddZakaz.performClick()
//
// //return true
// return@setOnKeyListener true
// }
// else -> false
// }
//
//
// }*/
//
// }
//
//}

View File

@ -0,0 +1,176 @@
package com.example.user.BottomSheetMenu
import android.annotation.SuppressLint
import android.app.Dialog
import android.graphics.Color
import android.os.Bundle
import android.support.annotation.Nullable
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.activityViewModels
import com.example.doctor.DoctorViewModel
import com.example.doctor.Patients.Model.CreatePatientModel
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.R
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.ItemButtomMenuBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
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 NoteBottomSheetMenu: BottomSheetDialogFragment() {
private lateinit var binding: ItemButtomMenuBinding
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
@SuppressLint("RestrictedApi")
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
val view = LayoutInflater.from(context).inflate(R.layout.item_buttom_menu, null)
dialog.setContentView(view)
val param = (view.parent as View).layoutParams as CoordinatorLayout.LayoutParams
val behavior = param.behavior
if(behavior is BottomSheetBehavior<*>){
behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback(){
override fun onStateChanged(bottomSheet: View, newState: Int) {
var state = ""
when(newState){
BottomSheetBehavior.STATE_DRAGGING->{
state = "DRAGGING"
}
BottomSheetBehavior.STATE_SETTLING->{
state = "SETTLING"
}
BottomSheetBehavior.STATE_EXPANDED->{
state = "EXPANDED"
}
BottomSheetBehavior.STATE_COLLAPSED->{
state = "COLLAPSED"
}
BottomSheetBehavior.STATE_HIDDEN->{
state = "HIDDEN"
dismiss()
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
}
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
}
}
//Данная функция необходима чтобы убрать белый фон в нижнем всплывающем меню
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
// window?.setDimAmount(0.2f) // Set dim amount here
setOnShowListener {
val bottomSheet = findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
bottomSheet.setBackgroundResource(android.R.color.transparent)
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = ItemButtomMenuBinding.inflate(inflater,container,false)
return binding.root
}
companion object {
fun newInstance(): NoteBottomSheetMenu {
val args = Bundle()
val fragment = NoteBottomSheetMenu()
fragment.arguments = args
return fragment
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnAddPatient.setOnClickListener{
if(binding.edEmail.text.toString() == "" && binding.edPassword.text.toString() == ""){
Toast(requireContext()).showCustomInfoToast("Не все поля заполнены", requireActivity())
}
else{
CreateAccountPatient(CreatePatientModel(binding.edEmail.text.toString(),binding.edPassword.text.toString()))
}
}
}
fun CreateAccountPatient(createPatientModel: CreatePatientModel) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.CreateAccountPatient("Bearer $Tokens",createPatientModel)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val patientList = listProduct.body()
//Если нету ошибок
if (patientList != null) {
Toast(requireContext()).showCustomInfoToast("Аккаунт для пациента создан", requireActivity())
dismiss()//После нажатия закрываем
}
else{
Toast(requireContext()).showCustomInfoToast("Ошибка валидации", requireActivity())
}
}
}
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
}

View File

@ -0,0 +1,5 @@
package com.example.doctor.BottomSheetMenu
data class StatusModel(
val status: Boolean = false
)

View File

@ -0,0 +1,56 @@
package com.example.doctor
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.doctor.Appeals.AppealsOldModel
import com.example.doctor.Appeals.AppealsNewModel
import com.example.doctor.Patients.Model.PatientAllModel
import com.example.doctor.Patients.Model.PatientModel
import com.example.doctor.Patients.Reports.Edit.EditSportListNoModel
import com.example.doctor.Patients.Reports.Edit.EditSportListYesModel
import com.example.doctor.Patients.Reports.Edit.EditSportModel
import com.example.doctor.Patients.Reports.QBAModel
import com.example.doctor.Patients.Reports.SportCoursModel
//import com.example.retrofit.model.Product
class DoctorViewModel: ViewModel() {
//Токен
val token = MutableLiveData<String>()
//Пациенты
val patientCurrent = MutableLiveData<PatientAllModel>()
val patientListList= MutableLiveData<PatientAllModel>()
//Обращения новые
val appealsNewCurrent = MutableLiveData<AppealsNewModel>()
val appealsNewList= MutableLiveData<List<AppealsNewModel>>()
//Обращения все
val appealsAllCurrent = MutableLiveData<AppealsOldModel>()
val appealsAllList= MutableLiveData<List<AppealsOldModel>>()
//val productList = MutableLiveData<List<Product>>()
val patientOneCurrent = MutableLiveData<PatientModel>()
//Отчеты
val qbaCurrent = MutableLiveData<QBAModel>()
val qbaList= MutableLiveData<List<QBAModel>>()
//КУрсы
val SportCoursCurrent = MutableLiveData<SportCoursModel>()
val SportCoursList= MutableLiveData<List<SportCoursModel>>()
//Редактирование занятий
val EditSportCurrentYes = MutableLiveData<EditSportModel>()
val EditSportListYes= MutableLiveData<List<EditSportModel>>()
//Редактирование занятий
val EditSportCurrentNO = MutableLiveData<EditSportModel>()
val EditSportListNo= MutableLiveData<List<EditSportModel>>()
//id пациента
val id_patient = MutableLiveData<Int>()
}

View File

@ -0,0 +1,31 @@
package com.example.doctor.Home
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.doctor.databinding.FragmentHomeBinding
class HomeFragment : Fragment() {
private lateinit var binding: FragmentHomeBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(layoutInflater,container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
companion object {
fun newInstance() = HomeFragment()
}
}

View File

@ -0,0 +1,146 @@
package com.example.doctor
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import com.example.doctor.Auth.AuthActivity
import com.example.doctor.Auth.AuthFragment
import com.example.doctor.Auth.Model.AuthModel
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Pref.SavePref
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.ActivityMainBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var doctorApi: DoctorApi
//Токен
private var Token = ""
val prefDoctorSave = SavePref()
val prefDoctorConclusion = ConclusionPref()
var backPressedTime: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initRetrofit()
MainAndAuth()
}
fun MainAndAuth() {
Token = prefDoctorConclusion.conclusionToken(this)
//CheckTokenAuth(Token)
if (Token == "") {
Auth()
} else {
CheckTokenAuth(Token)
}
}
fun Auth() {
supportFragmentManager.beginTransaction()
.replace(R.id.CLMain, AuthFragment.newInstance())
.commit()
}
fun Main() {
fragment_inicializ()
}
@SuppressLint("SuspiciousIndentation")
private fun CheckTokenAuth(token: String) {
CoroutineScope(Dispatchers.IO).launch {
val response = doctorApi.CheckToken("Bearer $token")
runOnUiThread {
val checkToken = response.body()
val user1 = response.code()
Log.i("12213213213", user1.toString())
if (user1.toString() == "200") {
Main()
} else {
Auth()
}
}
}
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
private fun fragment_inicializ() {
//Вывод фрагмента на активити при первоначальной загрузке
supportFragmentManager.beginTransaction()
.replace(R.id.CLMain, MainFragment.newInstance())
.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
// override fun onBackPressed() {
// if (backPressedTime + 3000 > System.currentTimeMillis()) {
// super.onBackPressed()
// finish()
// } else {
// AlertDialog.Builder(this@MainActivity)
// .setTitle("Выйти")
// .setMessage("Вы точно хотите выйти из приложения?")
// .setPositiveButton("Да") { dialog, whichButton ->
// super.onBackPressed()
// }
// .setNegativeButton("Нет") { dialog, whichButton ->
//
// }
// .show()
// }
// backPressedTime = System.currentTimeMillis()
// }
override fun onResume() {
super.onResume()
}
}

View File

@ -0,0 +1,108 @@
package com.example.doctor
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.doctor.Appeals.AppealsFragment
import com.example.doctor.Home.HomeFragment
import com.example.doctor.Patients.PatientsListFragment
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Pref.SavePref
import com.example.doctor.Setting.SettingFragment
import com.example.doctor.databinding.FragmentMainBinding
class MainFragment : Fragment() {
private lateinit var binding: FragmentMainBinding
val prefDoctorSave = SavePref()
val prefDoctorConclusion = ConclusionPref()
private var Token = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentMainBinding.inflate(layoutInflater,container,false)
return binding.root
}
@SuppressLint("ResourceType")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//MainAndAuth()
fragment_inicializ()
}
// fun MainAndAuth(){
//
// //Token = prefDoctorConclusion.conclusionToken()
// if(Token == ""){
// Auth()
// }
// else{
// Main()
// }
// }
// fun Auth(){
// val intetn = Intent(requireContext(), AuthActivity::class.java)
// startActivity(intetn)
// activity?.finish()
// }
// fun Main(){
// fragment_inicializ()
// }
//Инициализация фрагментов
fun fragment_inicializ() {
Token = prefDoctorConclusion.conclusionToken(requireContext())
//Вывод фрагмента на активити при первоначальной загрузке
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, HomeFragment.newInstance())
?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
//Эран который будет выбран по умолчанию(кнопка которая будет прожата по умолчанию)
binding.buttonNavigation.selectedItemId = R.id.home//По умолчанию и так первая, но на всякий случай выберу еще програмным путем первую ячейку
//Нажатие на bottom navigation
binding.buttonNavigation.setOnItemSelectedListener {
when (it.itemId) {//it.itemId - это id нажатого элемента
R.id.home -> {
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, HomeFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
R.id.patient -> {
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, PatientsListFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
R.id.list_check -> {//Если вы не авторизованный пользваотель то вам не будет доступен доступ к данном фрагменту
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, AppealsFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
R.id.setting -> {//Если вы не авторизованный пользваотель то вам не будет доступен доступ к данном фрагменту
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, SettingFragment.newInstance())?.commit()//Заменяем наш экран на фрагмент (используем наш экран как основу)//R.id.placeHolder - куда всталяем //MainFragment.newInstance() - это то что мы вставляем
}
}
true
}
}
companion object {
fun newInstance() = MainFragment()
}
}

View File

@ -0,0 +1,92 @@
package com.example.doctor.Patients.Adapter
import android.annotation.SuppressLint
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.Patients.Model.PatientAllModel
import com.example.doctor.Patients.Model.PatientModel
import com.example.doctor.R
import com.example.doctor.databinding.ItemCardPatientBinding
class PatientListAdapter(val listener_patient: Listener) :
ListAdapter<PatientAllModel, PatientListAdapter.Holder>(
Comparator()
) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку
//В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку
class Holder(view: View, val listener_patient: Listener) :
RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д.
//Для передачи данных
val binding =
ItemCardPatientBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки
var itemTemp: PatientAllModel? =
null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия
//init - дает возможность внутри адаптера обращаться к элементам экрана
init {
itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка
//itemView.setEnabled(false)
itemTemp?.let { it1 -> listener_patient.onClickPatient(it1) }
}
}
@SuppressLint("SuspiciousIndentation", "SetTextI18n")
fun bind(item: PatientAllModel) = with(binding) {//Productitem - перпедаем данные
itemTemp = item
txtNumberCurds.text = item.id.toString() + "."
txtLoginPatient.text = item.login
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_card_patient, parent, false)//Создаем(надуваем) list_item
return Holder(view, listener_patient)//Через Holder возврощаем view
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))//Заполняем по позиции карточку
}
//Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает
class Comparator : DiffUtil.ItemCallback<PatientAllModel>() {
override fun areItemsTheSame(
oldItem: PatientAllModel,
newItem: PatientAllModel
): Boolean {//Тут лучше всего сравнивать по id//oldItem - элементы старого списка, newItem - элементы нового списка//Возврощает Boolean, тоесть есть изменения или нет
return oldItem.id == newItem.id//Сравниваем полностью весь список новы и старый, по очередно по одной карточке и по элементно, то есть нулевой элемент, первый, второй и т.д.. Но лучше сравнивать по id списки, а не просто весь список, так как это эфективнее, так как id уникальный(oldItem.id == newItem.id)
}
override fun areContentsTheSame(
oldItem: PatientAllModel,
newItem: PatientAllModel
): Boolean {//Утут нужно сравнивать весь спсок старых элементов и новых
return oldItem == newItem//Сравниваем полностью весь список новы и старый
}
}
//Интерфейс нажатия на кнопку удалить товар из корзины
interface Listener {
fun onClickPatient(item: PatientAllModel)
}
}

View File

@ -0,0 +1,7 @@
package com.example.doctor.Patients.Model
data class CreatePatientModel(
//val login:String,
val login:String,
val password:String,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Model
data class MessageModel(
val message: String,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Model
data class PatientAllListModel(
val patient: List<PatientAllModel>
)

View File

@ -0,0 +1,21 @@
package com.example.doctor.Patients.Model
import java.util.Date
data class PatientAllModel(
val id: Int? = null,
val login: String? = null,
val email: String? = null,
val loginDoctor: String? = null,
val emailDoctor: String? = null,
val pause: String? = null,
val block: String? = null,
val report7day: String? = null,
val report15day: String? = null,
val id_sport_patient: Int? = null,
val total_days_sports: Int? = null,
val now_days_sports: Int? = null,
val created_at: String? = null,
val updated_at: String? = null,
)

View File

@ -0,0 +1,8 @@
package com.example.doctor.Patients.Model
data class PatientModel(
val id: Int,
val login: String,
//val email:String,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Model
data class PauseModel(
val message: String,
)

View File

@ -0,0 +1,182 @@
package com.example.doctor.Patients
//noinspection SuspiciousImport
import android.R
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.DoctorViewModel
import com.example.doctor.Patients.Adapter.PatientListAdapter
import com.example.doctor.Patients.Model.PatientAllModel
import com.example.doctor.Patients.Model.PatientModel
import com.example.doctor.Patients.Reports.PatientFragment
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.databinding.FragmentPatientsListBinding
import com.example.user.BottomSheetMenu.NoteBottomSheetMenu
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 PatientsListFragment : Fragment(), PatientListAdapter.Listener {
private lateinit var binding: FragmentPatientsListBinding
private val model: DoctorViewModel by activityViewModels()
lateinit var adapterPatient: PatientListAdapter
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentPatientsListBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRcViewDay()
patientListCurrent()
GetPatientList()
// //Swipe down
// binding.refreshLayout.setOnRefreshListener{
// GetPatientList()
// binding.refreshLayout.isRefreshing = false
// }
//Нажатие на кнопку заказать заказ
binding.btnAddPatient.setOnClickListener {
val noteBottomSheetMenu = NoteBottomSheetMenu.newInstance()
noteBottomSheetMenu.show(
requireActivity().supportFragmentManager,
"Note Bottom Sheet Fragment"
)
}
}
//Получения списка пациентов
fun GetPatientList() {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.GetPatientAll("Bearer $Tokens")
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val patientList = listProduct.body()
//Если нету ошибок
if (patientList != null) {
adapterPatient.submitList(patientList.patient)
//model.patientListList.value = patientList.PatientList
addListSerchPatient(patientList.patient)
}
}
}
}
private fun addListSerchPatient(patient: List<PatientAllModel>) {
val listPatient = arrayListOf("")
for(i in 0 .. patient.count()-1){
listPatient.add(patient[i].login.toString())
}
val adapter = ArrayAdapter(requireContext(), R.layout.simple_list_item_1, listPatient)
binding.searchPatient.threshold = 1
binding.searchPatient.setAdapter(adapter)
binding.searchPatient.setOnItemClickListener { parent, arg1, pos, id ->
//val list = ArrayList<PatientModel>()
val serpat = binding.searchPatient.text.toString()
//Вывод фрагмента на активити при первоначальной загрузке
activity?.supportFragmentManager?.beginTransaction()
?.replace(com.example.doctor.R.id.CLMainListPatient, PatientFragment.newInstance())
?.commit()
binding.CLMainListPatient2.visibility = View.GONE
//Ищем пациента по логину
for(i in 0 ..patient.count()-1) {
if(patient[i].login == serpat){
model.patientCurrent.value = patient[i]
}
}
}
}
//Вывод прогресса на один день
private fun patientListCurrent() = with(binding) {
// model.patientListCurrent.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment
//
// }
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
//Инициализация списка
private fun initRcViewDay() = with(binding) {
rcView.layoutManager =
GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
adapterPatient = PatientListAdapter(this@PatientsListFragment)
rcView.adapter = adapterPatient
}
companion object {
fun newInstance() = PatientsListFragment()
}
override fun onClickPatient(item: PatientAllModel) {
//Вывод фрагмента на активити при первоначальной загрузке
activity?.supportFragmentManager?.beginTransaction()
?.replace(com.example.doctor.R.id.CLMainListPatient, PatientFragment.newInstance())
?.commit()
//binding.rcView.visibility = View.GONE
binding.CLMainListPatient2.visibility = View.GONE
model.patientCurrent.value = item
}
}

View File

@ -0,0 +1,76 @@
package com.example.doctor.Patients.Reports
import android.annotation.SuppressLint
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.Patients.Reports.Edit.EditSportModel
import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter
import com.example.doctor.R
import com.example.doctor.databinding.ItemQbaBinding
import com.example.doctor.databinding.ItemSportCourseBinding
class CoursesAdapter(val listener_cours: CoursesAdapter.Listener) : ListAdapter<SportCoursModel, CoursesAdapter.Holder>(Comparator()) {
class Holder(view: View,val listener_cours: CoursesAdapter.Listener) :
RecyclerView.ViewHolder(view) {
val binding = ItemSportCourseBinding.bind(view)
var itemTemp: SportCoursModel? =
null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия
//init - дает возможность внутри адаптера обращаться к элементам экрана
init {
itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка
itemTemp?.let { it1 -> listener_cours.onClickCoursAdd(it1) }
}
}
@SuppressLint("SuspiciousIndentation")
fun bind(item: SportCoursModel) = with(binding) {
txtCoursesSport.text = item.name
if(item.visibility == 1){
CVCours.setCardBackgroundColor(Color.parseColor("#83da83"))
}
else{
CVCours.setCardBackgroundColor(Color.parseColor("#b6b6b6"))
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sport_course, parent, false)
return Holder(view,listener_cours)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))
}
class Comparator : DiffUtil.ItemCallback<SportCoursModel>() {
override fun areItemsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: SportCoursModel, newItem: SportCoursModel): Boolean {
return oldItem == newItem
}
}
//Интерфейс нажатия на кнопку удалить товар из корзины
interface Listener {
fun onClickCoursAdd(item: SportCoursModel)
}
}

View File

@ -0,0 +1,76 @@
package com.example.doctor.Patients.Reports.Edit
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 com.example.doctor.Adapter.VpEditSportAdapter
import com.example.doctor.Patients.Reports.Edit.TabLayout.EditSportNoFragment
import com.example.doctor.Patients.Reports.Edit.TabLayout.EditSportYesFragment
import com.example.doctor.R
import com.example.doctor.databinding.FragmentEditSportBinding
import com.google.android.material.tabs.TabLayoutMediator
class EditSportFragment : Fragment() {
private lateinit var binding: FragmentEditSportBinding
private val tListSport = listOf(
"Активные",
"Отключенные",
)
//Список с фрагментами для переключения
private val flistSport = listOf(
EditSportYesFragment.newInstance(),
EditSportNoFragment.newInstance(),
)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentEditSportBinding.inflate(layoutInflater,container,false)
return binding.root
}
companion object {
fun newInstance() = EditSportFragment()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
//Функция подключения переключения
private fun init() = with(binding) {
val adapter = VpEditSportAdapter(activity as FragmentActivity, flistSport)
vpEditSport.adapter = adapter
//Переключения (связываем таблаяут(переключатель) с viewpager, чтобы переключать фрагменты)
TabLayoutMediator(tabLayoutSport, vpEditSport) { tab, pos ->
tab.text =
tListSport[pos]//tab - нажатая кнопка, pos - позиция кнопки, tList[pos] - передаем название по полученной позиции
}.attach()// attach() - чтобы все переключалось, а не вывадило постоянно один экран
//Изменения цвета в зависомости на каком из tabLayout вы находитесь
binding.tabLayoutSport.setTabTextColors(getResources().getColor(R.color.black),
getResources().getColor(R.color.white));
}
// //Инициализация списка
// private fun initRcViewDay() = with(binding) {
// rcView.layoutManager =
// GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
// adapterPatient = PatientListAdapter(this@PatientsListFragment)
// rcView.adapter = adapterPatient
// }
}

View File

@ -0,0 +1,8 @@
package com.example.doctor.Patients.Reports.Edit
data class EditSportListNoModel(
val set_of_sports_exercises_no: List<EditSportModel>
)

View File

@ -0,0 +1,10 @@
package com.example.doctor.Patients.Reports.Edit
import com.example.doctor.Patients.Reports.QBAModel
data class EditSportListYesModel(
val set_of_sports_exercises_yes: List<EditSportModel>
)

View File

@ -0,0 +1,11 @@
package com.example.doctor.Patients.Reports.Edit
data class EditSportModel(
val number: Int,
val id: Int,
val name:String,
val description:String,
val url_image:String,
var expand : Boolean = false,
)

View File

@ -0,0 +1,107 @@
package com.example.doctor.Patients.Reports.Edit
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemEditSportNoBinding
import com.example.doctor.databinding.ItemEditSportYesBinding
class EditSportNoAdapter(val listener_sport: Listener) :
ListAdapter<EditSportModel, EditSportNoAdapter.Holder>(
Comparator()
) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку
//В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку
class Holder(view: View, val listener_sport: Listener) :
RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д.
//Для передачи данных
val binding = ItemEditSportNoBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки
var itemTemp: EditSportModel? =
null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия
//init - дает возможность внутри адаптера обращаться к элементам экрана
init {
itemView.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка
itemTemp?.let { it1 -> listener_sport.onClickAppeals(it1) }
}
}
@SuppressLint("SuspiciousIndentation")
fun bind(item: EditSportModel) = with(binding) {//Productitem - перпедаем данные
itemTemp = item
txtNumber.text = item.number.toString()+"."
txtNameSport.text = item.name
txtDescriptionSport.text = item.description
if (item.expand) {
binding.txtDescriptionSport.maxLines = 100
} else {
binding.txtDescriptionSport.maxLines = 1
}
binding.CardViewOld.setOnClickListener {
if (item.expand == false) {
binding.txtDescriptionSport.maxLines = 100
item.expand = true
} else {
binding.txtDescriptionSport.maxLines = 1
item.expand = false
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_edit_sport_no, parent, false)//Создаем(надуваем) list_item
return Holder(view, listener_sport)//Через Holder возврощаем view
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))//Заполняем по позиции карточку
}
//Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает
class Comparator : DiffUtil.ItemCallback<EditSportModel>() {
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 onClickAppeals(item: EditSportModel)
}
}

View File

@ -0,0 +1,8 @@
package com.example.doctor.Patients.Reports.Edit
data class EditSportSearchModel(
val id_patient: Int,
val id_sports_courses_patient: Int,
)

View File

@ -0,0 +1,106 @@
package com.example.doctor.Patients.Reports.Edit
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemEditSportYesBinding
class EditSportYesAdapter(val listener_sport: Listener) :
ListAdapter<EditSportModel, EditSportYesAdapter.Holder>(
Comparator()
) {//Productitem - по этой форме будем заполнять.//ProductAdapter.holder - это создаваемый holder который хранит логику как нужно заполнять карточку
//В holder создаетс код с помошью которого мы будем заполнять и сохронять разметку
class Holder(view: View, val listener_sport: Listener) :
RecyclerView.ViewHolder(view) {//Класс который будет хранить сссылки на элементы, и отвечает за один элемент за 1 раз, то есть сначсало нулевой элемент заполнит, потом первый, потом второй и т.д.
//Для передачи данных
val binding = ItemEditSportYesBinding.bind(view)//view - здесь храянтся элементы и мы их bind заполним в ListItemBinding//ListItemBinding - это клласс даннйо разметки(карточки) которую мы будем заполнять, а нужна дання переменная(binding), чтобы мжно было при заполнение обращатся к элементам карточки
var itemTemp: EditSportModel? =
null//Глобальная переменная для нашего item, чтобы можно было передать данные для нажатия
//init - дает возможность внутри адаптера обращаться к элементам экрана
init {
binding.btnYeyYes.setOnClickListener {//Нажатие на ячейку//itemView - это весь элемент карточки из списка
itemTemp?.let { it1 -> listener_sport.onClickAppeals(it1) }
}
}
@SuppressLint("SuspiciousIndentation")
fun bind(item: EditSportModel) = with(binding) {//Productitem - перпедаем данные
itemTemp = item
txtNumber.text = item.number.toString()+"."
txtNameSport.text = item.name
txtDescriptionSport.text = item.description
if (item.expand) {
binding.txtDescriptionSport.maxLines = 100
} else {
binding.txtDescriptionSport.maxLines = 1
}
binding.CardViewOld.setOnClickListener {
if (item.expand == false) {
binding.txtDescriptionSport.maxLines = 100
item.expand = true
} else {
binding.txtDescriptionSport.maxLines = 1
item.expand = false
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_edit_sport_yes, parent, false)//Создаем(надуваем) list_item
return Holder(view, listener_sport)//Через Holder возврощаем view
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))//Заполняем по позиции карточку
}
//Comparator - сравнивает старый список и новый и если что-то изменилось, то работает с конкретным изменением списке, а не весь список переписывает
class Comparator : DiffUtil.ItemCallback<EditSportModel>() {
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 onClickAppeals(item: EditSportModel)
}
}

View File

@ -0,0 +1,172 @@
package com.example.doctor.Patients.Reports.Edit.TabLayout
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.DoctorViewModel
import com.example.doctor.Patients.Reports.Edit.EditSportYesAdapter
import com.example.doctor.Patients.Reports.Edit.EditSportModel
import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.FragmentEditSportNoBinding
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 EditSportNoFragment : Fragment(),EditSportNoAdapter.Listener {
private lateinit var binding:FragmentEditSportNoBinding
lateinit var adapterNo: EditSportNoAdapter
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
private val model: DoctorViewModel by activityViewModels()
var id_patient = 0;
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentEditSportNoBinding.inflate(layoutInflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRcViewDay()
model.EditSportListNo.observe(viewLifecycleOwner){
adapterNo.submitList(it)
}
model.id_patient.observe(viewLifecycleOwner) {id->
id_patient = id.toInt()
GetCoursesSportNo(id_patient)
}
}
//Инициализация списка
private fun initRcViewDay() = with(binding) {
rcViewEditSportNo.layoutManager =
GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
adapterNo = EditSportNoAdapter(this@EditSportNoFragment)
rcViewEditSportNo.adapter = adapterNo
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
//Получения списка пациентов
fun GetCoursesSportYes(id_patient:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportEditList = sportEdit.body()
//Если нету ошибок
if (sportEditList != null) {
model.EditSportListYes.value = sportEditList.set_of_sports_exercises_yes
//adapterYes.submitList(sportEditList.set_of_sports_exercises_yes)
}
}
}
}
//Получения списка пациентов
fun GetCoursesSportNo(id_patient:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens", id_patient)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportEditList = sportEdit.body()
//Если нету ошибок
if (sportEditList != null) {
model.EditSportListNo.value = sportEditList.set_of_sports_exercises_no
//adapterNo.submitList(sportEditList.set_of_sports_exercises_no)
binding.txtNo.visibility = View.GONE
}
else{
binding.txtNo.visibility = View.VISIBLE
}
}
}
}
//Получения списка пациентов
fun UpdateBlockSportTasksNo(id:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val NoEdit = doctorApi.UpdateBlockSportTasksNo("Bearer $Tokens", id)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportNoList= NoEdit.body()
//Если нету ошибок
if (sportNoList != null) {
Toast(requireContext()).showCustomInfoToast(sportNoList.message, requireActivity())
GetCoursesSportYes(id_patient)
GetCoursesSportNo(id_patient)
}
else{
if (sportNoList != null) {
Toast(requireContext()).showCustomInfoToast(sportNoList.message, requireActivity())
}
}
}
}
}
companion object {
fun newInstance() = EditSportNoFragment()
}
override fun onClickAppeals(item: EditSportModel) {
UpdateBlockSportTasksNo(item.id)
}
}

View File

@ -0,0 +1,174 @@
package com.example.doctor.Patients.Reports.Edit.TabLayout
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.DoctorViewModel
import com.example.doctor.Patients.Reports.Edit.EditSportYesAdapter
import com.example.doctor.Patients.Reports.Edit.EditSportModel
import com.example.doctor.Patients.Reports.Edit.EditSportNoAdapter
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.FragmentEditSportYesBinding
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 EditSportYesFragment : Fragment(), EditSportYesAdapter.Listener {
private lateinit var binding:FragmentEditSportYesBinding
lateinit var adapterYes: EditSportYesAdapter
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
private val model: DoctorViewModel by activityViewModels()
var id_patient = 0;
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentEditSportYesBinding.inflate(layoutInflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRcViewDay()
model.id_patient.observe(viewLifecycleOwner) {id->
id_patient = id.toInt()
Log.i("id_patient",id_patient.toString())
Log.i("id",id.toString())
GetCoursesSportYes(id_patient)
}
model.EditSportListYes.observe(viewLifecycleOwner){
adapterYes.submitList(it)
}
}
//Инициализация списка
private fun initRcViewDay() = with(binding) {
rcViewEditSportYes.layoutManager =
GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
adapterYes = EditSportYesAdapter(this@EditSportYesFragment)
rcViewEditSportYes.adapter = adapterYes
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
//Получения списка пациентов
fun GetCoursesSportYes(id_patient:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val sportEdit = doctorApi.GetCoursesSportYes("Bearer $Tokens", id_patient)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportEditList = sportEdit.body()
//Если нету ошибок
if (sportEditList != null) {
model.EditSportListYes.value = sportEditList.set_of_sports_exercises_yes
binding.txtYes.visibility = View.GONE
}
else{
binding.txtYes.visibility = View.VISIBLE
}
}
}
}
//Получения списка пациентов
fun GetCoursesSportNo(id_patient:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val sportEdit = doctorApi.GetCoursesSportNo("Bearer $Tokens",id_patient)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportEditList = sportEdit.body()
//Если нету ошибок
if (sportEditList != null) {
model.EditSportListNo.value = sportEditList.set_of_sports_exercises_no
//adapterNo.submitList(sportEditList.set_of_sports_exercises_no)
}
}
}
}
//Получения списка пациентов
fun UpdateBlockSportTasksYes(id_pateint:Int,id_sports_tasks:Int) {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val sportEdit = doctorApi.UpdateBlockSportTasksYes("Bearer $Tokens", id_pateint,id_sports_tasks)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportEditList = sportEdit.body()
//Если нету ошибок
if (sportEditList != null) {
Toast(requireContext()).showCustomInfoToast(sportEditList.message, requireActivity())
GetCoursesSportYes(id_patient)
GetCoursesSportNo(id_patient)
}
else{
if (sportEditList != null) {
Toast(requireContext()).showCustomInfoToast(sportEditList.message, requireActivity())
}
}
}
}
}
companion object {
fun newInstance() = EditSportYesFragment()
}
override fun onClickAppeals(item: EditSportModel) {
UpdateBlockSportTasksYes(id_patient, item.id)
}
}

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Reports.Edit
data class UpdateSportTaskNoModel(
val id: Int,
)

View File

@ -0,0 +1,7 @@
package com.example.doctor.Patients.Reports.Edit
data class UpdateSportTaskYesModel(
val id_sport_patient: Int,
val id_sports_tasks: Int,
)

View File

@ -0,0 +1,473 @@
package com.example.doctor.Patients.Reports
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.widget.PopupMenu
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.example.doctor.DoctorViewModel
import com.example.doctor.Patients.PatientsListFragment
import com.example.doctor.Patients.Reports.Edit.EditSportFragment
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.databinding.FragmentPatientsBinding
import com.example.doctor.databinding.ItemQuestionnaireAfterBinding
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
class PatientFragment : Fragment(),CoursesAdapter.Listener {
private lateinit var binding: FragmentPatientsBinding
private val model: DoctorViewModel by activityViewModels()
lateinit var adapter: QBBAdapter
lateinit var adapterCours: CoursesAdapter
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
var id: Int? = null
var block = ""
var pause = ""
var id_sport = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentPatientsBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRcViewDay()
initRcViewCours()
model.qbaList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment
adapter.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter)
}
model.SportCoursList.observe(viewLifecycleOwner) {//viewLifecycleOwner - следит за циклом жизни fragment
adapterCours.submitList(it)//Напрямую переадем созданный список в adapter(ProductAdapter)
}
binding.btnExit.setOnClickListener {
//Вывод фрагмента на активити при первоначальной загрузке
activity?.supportFragmentManager?.beginTransaction()
?.replace(
com.example.doctor.R.id.CLMainFragment,
PatientsListFragment.newInstance()
)
?.commit()
}
popMenu()
model.patientCurrent.observe(viewLifecycleOwner) {
binding.txtLogin.text = it.login
id = it.id
model.id_patient.value = id
block = it.block.toString()
pause = it.pause.toString()
id_sport = it.id_sport_patient.toString()
//Проверка даты, так как если дата уже прошла, то должно выводится что блока нету
if(block == "null"){
block(block)
}
else{
if(LocalDate.parse(block)<LocalDate.now()){
block("null")
}
else{
block(block)
}
}
//Проверка даты, так как если дата уже прошла, то должно выводится что паузы нету
if(pause == "null"){
pause(pause)
}
else{
if(LocalDate.parse(pause)<LocalDate.now()){
pause("null")
}
else{
pause(pause)
}
}
Log.i("id_sport","$id_sport")
Log.i("id_sport123","$it")
//Проверка есть ли курс
clearSportPatient(id_sport)
sport()
report()
}
// //Swipe down
// binding.refreshLayout.setOnRefreshListener{
// GetPatientID()
// binding.refreshLayout.isRefreshing = false
// }
}
private fun GetPatientID() {
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listPatient = doctorApi.GetPatientID("Bearer $Tokens")
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val patientId = listPatient.body()
//Если нету ошибок
if (patientId != null) {
model.patientCurrent.value = patientId
}
}
}
}
private fun popMenu() {
//Созданиеменю
val popMenu = PopupMenu(
requireContext(),
binding.btnQBA
)
//Кнопуи
popMenu.menu.add(Menu.NONE, 0, 0, "Анкета ДО")
popMenu.menu.add(Menu.NONE, 1, 1, "Анкета ПОСЛЕ")
popMenu.setOnMenuItemClickListener {
val id = it.itemId
//Ситуции при нажатие на один из пунктов
if (id == 0) {
binding.CVQB.visibility = View.VISIBLE
} else if (id == 1) {
binding.CVQA.visibility = View.VISIBLE
} else {
Toast.makeText(requireContext(), "Ошибка", Toast.LENGTH_SHORT).show()
}
false
}
binding.btnQBA.setOnClickListener {
//Активируем меню
popMenu.show()
}
}
//Получения списка анкет ДО и ПОСЛЕ для пациента
fun ClearSportPaient(){
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listcsp = doctorApi.ClearPatientSport("Bearer $Tokens",id!!)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val csp = listcsp.body()
//Если нету ошибок
if (csp != null) {
id_sport = "null"
binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767"))
Toast(requireContext()).showCustomInfoToast(csp.message, requireActivity())
}
else{
Toast(requireContext()).showCustomInfoToast("${csp?.message}", requireActivity())
}
}
}
}
private fun clearSportPatient(id_sport:String) {
if (id_sport == "null") {
binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#D86767"))
} else {
binding.btnClearSportPatient.setCardBackgroundColor(Color.parseColor("#A9D867"))
}
binding.btnClearSportPatient.setOnClickListener {
ClearSportPaient()
}
}
//Получения списка анкет ДО и ПОСЛЕ для пациента
fun QBAPatientList()=with(binding){
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.GetPatientBAQiestionar("Bearer $Tokens",id!!)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val qbapatientList = listProduct.body()
//Если нету ошибок
if (qbapatientList != null) {
if(qbapatientList.questionnaire !=null){
txtNullQBA.visibility = View.GONE
model.qbaList.value = qbapatientList.questionnaire
}
}
}
}
}
private fun pause(pause:String) {
if (pause == "null") {
binding.CVPause.setCardBackgroundColor(Color.parseColor("#A9D867"))
} else {
binding.CVPause.setCardBackgroundColor(Color.parseColor("#D86767"))
}
binding.btnPause.setOnClickListener {
UpdatePausePatient()
}
}
private fun block(block:String) {
if (block == "null") {
binding.CVBlock.setCardBackgroundColor(Color.parseColor("#A9D867"))
} else {
binding.CVBlock.setCardBackgroundColor(Color.parseColor("#D86767"))
}
binding.btnBlock.setOnClickListener {
UpdateBlockPatient()
}
}
//Блокировка пациента
fun UpdateBlockPatient(){
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.UpdateBlockAccountPatient("Bearer $Tokens", id!!)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val patientList = listProduct.body()
//Если нету ошибок
if (patientList != null) {
if (block == "null") {
block = "true"
binding.CVBlock.setCardBackgroundColor(Color.parseColor("#D86767"))
Toast(requireContext()).showCustomInfoToast("Блок установлен", requireActivity())
} else {
block = "null"
binding.CVBlock.setCardBackgroundColor(Color.parseColor("#A9D867"))
Toast(requireContext()).showCustomInfoToast("Блок убран", requireActivity())
}
}
}
}
}
//Блокировка пациента
fun UpdatePausePatient(){
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.UpdatePauseAccountPatient("Bearer $Tokens", id!!)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val patientList = listProduct.body()
//Если нету ошибок
if (patientList != null) {
if (pause == "null") {
pause = "true"
binding.CVPause.setCardBackgroundColor(Color.parseColor("#D86767"))
Toast(requireContext()).showCustomInfoToast("Пауза установлен", requireActivity())
} else {
pause = "null"
binding.CVPause.setCardBackgroundColor(Color.parseColor("#A9D867"))
Toast(requireContext()).showCustomInfoToast("Пауза убран", requireActivity())
}
}
}
}
}
//Вывод всех курсов
fun GetAllCoursesSport(){
CreatRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.GetCoursAllPatient("Bearer $Tokens",id!!)
requireActivity().runOnUiThread {
//Фиксируем полученные данные
val sportCourses = listProduct.body()
//Если нету ошибок
if (sportCourses != null) {
model.SportCoursList.value = sportCourses.courses
binding.CVSport.visibility = View.VISIBLE
}
}
}
}
//Инициализируем Retrofit
private fun CreatRetrofit() {
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient
.Builder()
.addInterceptor(interceptor)
.build()
val retrofit = Retrofit.Builder()
.baseUrl("http://mobileapp.vmeda.org/api/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
doctorApi = retrofit.create(DoctorApi::class.java)
}
private fun sport() {
binding.btnSport.setOnClickListener {
}
}
private fun report() = with(binding) {
btnExitPatientFragment.setOnClickListener {
activity?.supportFragmentManager?.beginTransaction()
?.replace(com.example.doctor.R.id.CLMainListPatient, PatientsListFragment.newInstance())
?.commit()
}
binding.btnReport.setOnClickListener {
binding.CVReport.visibility = View.VISIBLE
QBAPatientList()
}
binding.btnSport.setOnClickListener {
GetAllCoursesSport()
}
binding.btnCloseReport.setOnClickListener {
binding.CVReport.visibility = View.GONE
initRcViewDay()
}
binding.btnCloseReport2.setOnClickListener {
binding.CVSport.visibility = View.GONE
}
binding.btnCloseBefore.setOnClickListener {
binding.CVQB.visibility = View.GONE
}
binding.btnCloseAfter.setOnClickListener {
binding.CVQA.visibility = View.GONE
}
binding.CVReport.setOnClickListener {
binding.CVReport.visibility = View.GONE
initRcViewDay()
}
binding.CVSport.setOnClickListener {
binding.CVSport.visibility = View.GONE
}
binding.CVReportList.setOnClickListener {
}
//Переход на страницу редактирования курса
binding.btnEditSport.setOnClickListener{
binding.CVEditSport.visibility = View.VISIBLE
//Вывод фрагмента на активити при первоначальной загрузке
activity?.supportFragmentManager?.beginTransaction()
?.replace(com.example.doctor.R.id.CLEditSport, EditSportFragment.newInstance())
?.commit()
}
}
//Инициализация списка
private fun initRcViewDay() = with(binding) {
RCView.layoutManager =
GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
adapter = QBBAdapter()
RCView.adapter = adapter
}
//Инициализация списка
private fun initRcViewCours() = with(binding) {
rcVieeSportCourses.layoutManager = GridLayoutManager(requireContext(), 1)//По вертикали будет выводить по умолчанию
adapterCours = CoursesAdapter(this@PatientFragment)
rcVieeSportCourses.adapter = adapterCours
}
fun closeViewCard() {
binding.txtLogin.text = ""
binding.CVReport.visibility = View.GONE
initRcViewDay()
}
override fun onDestroy() {
super.onDestroy()
closeViewCard()
}
companion object {
fun newInstance() = PatientFragment()
}
override fun onClickCoursAdd(item: SportCoursModel) {
if(id_sport == "" || id_sport == null){
Toast(requireContext()).showCustomInfoToast("Сначалоа очистите курс", requireActivity())
}
else{
Toast(requireContext()).showCustomInfoToast("Курс добавлен", requireActivity())
//ТУТ ДОЛЖНА БЫТЬ ФУНКЦИЯ ДЛЯ ДОБАВЛЕНИЯ КУРСА ПАЦИЕНТУ
}
}
}

View File

@ -0,0 +1,129 @@
package com.example.doctor.Patients.Reports
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemQuestionnaireAfterBinding
class QAAdapter() : ListAdapter<QAModel, QAAdapter.Holder>(Comparator()) {
class Holder(view: View) :
RecyclerView.ViewHolder(view) {
val binding = ItemQuestionnaireAfterBinding.bind(view)
@SuppressLint("SuspiciousIndentation")
fun bind(item: QAModel) = with(binding) {
// if (item.one == 1) {
// txtB1.text = "Да"
// } else {
// txtB1.text = "Нет"
// }
// txtA1.text = item.one.toString()
//
// if (item.two == 2) {
// txtA2.text = "Да"
// } else {
// txtA2.text = "Нет"
// }
//
// if (item.three == 3) {
// txtA3.text = "Да"
// } else {
// txtA3.text = "Нет"
// }
//
// if (item.four == 4) {
// txtA4.text = "Да"
// } else {
// txtA4.text = "Нет"
// }
//
// if (item.five == 5) {
// txtA5.text = "Да"
// } else {
// txtA5.text = "Нет"
// }
//
// if (item.six == 6) {
// txtA6.text = "Да"
// } else {
// txtA6.text = "Нет"
// }
//
// if (item.seven == 7) {
// txtA7.text = "Да"
// } else {
// txtA7.text = "Нет"
// }
//
// if (item.eight == 8) {
// txtA8.text = "Да"
// } else {
// txtA8.text = "Нет"
// }
//
// if (item.nine == 9) {
// txtA9.text = "Да"
// } else {
// txtA9.text = "Нет"
// }
//
// if (item.ten == 10) {
// txtA10.text = "Да"
// } else {
// txtA10.text = "Нет"
// }
//
// if (item.eleven == 11) {
// txtA11.text = "Да"
// } else {
// txtA11.text = "Нет"
// }
//
// if (item.twelve == 12) {
// txtA12.text = "Да"
// } else {
// txtA12.text = "Нет"
// }
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_questionnaire_after, parent, false)
return Holder(view)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))
}
class Comparator : DiffUtil.ItemCallback<QAModel>() {
override fun areItemsTheSame(
oldItem: QAModel,
newItem: QAModel
): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(
oldItem: QAModel,
newItem: QAModel
): Boolean {
return oldItem == newItem
}
}
}

View File

@ -0,0 +1,19 @@
package com.example.doctor.Patients.Reports
data class QAModel(
val id: Int,
val status: String,
val one: Int,
val two: Int,
val three: Int,
val four: Int,
val five: Int,
val six: Int,
val seven: Int,
val eight: Int,
val nine: Int,
val ten: Int,
val eleven: Int,
val twelve: Int,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Reports
data class QBAListModel(
val questionnaire: List<QBAModel>
)

View File

@ -0,0 +1,35 @@
package com.example.doctor.Patients.Reports
data class QBAModel(
val id: Int,
val date: String,
val idb: Int,
//val statusb: Int,
val oneb: Int,
val twob: Int,
val threeb: Int,
val fourb: Int,
val fiveb: Int,
val sixb: Int,
val sevenb: Int,
val eightb: Int,
val nineb: Int,
val ida: Int,
//val statusa: Int,
val onea: Int,
val twoa: Int,
val threea: Int,
val foura: Int,
val fivea: Int,
val sixa: Int,
val sevena: Int,
val eighta: Int,
val ninea: Int,
val tena: Int,
val elevena: Int,
val twelvea: Int,
)

View File

@ -0,0 +1,112 @@
package com.example.doctor.Patients.Reports
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemQuestionnaireBeforeBinding
class QBAdapter() : ListAdapter<QBModel, QBAdapter.Holder>(Comparator()) {
class Holder(view: View) :
RecyclerView.ViewHolder(view) {
val binding = ItemQuestionnaireBeforeBinding.bind(view)
@SuppressLint("SuspiciousIndentation")
fun bind(item: QBModel) = with(binding) {
// if (item.one == 1) {
// txtB1.text = "Да"
// } else {
// txtB1.text = "Нет"
// }
// txtB1.text = item.one.toString()
//
// if (item.two == 2) {
// txtB2.text = "Да"
// } else {
// txtB2.text = "Нет"
// }
//
// if (item.three == 3) {
// txtB3.text = "Да"
// } else {
// txtB3.text = "Нет"
// }
//
// if (item.four == 4) {
// txtB4.text = "Да"
// } else {
// txtB4.text = "Нет"
// }
//
// if (item.five == 5) {
// txtB5.text = "Да"
// } else {
// txtB5.text = "Нет"
// }
//
// if (item.six == 6) {
// txtB6.text = "Да"
// } else {
// txtB6.text = "Нет"
// }
//
// if (item.seven == 7) {
// txtB7.text = "Да"
// } else {
// txtB7.text = "Нет"
// }
//
// if (item.eight == 8) {
// txtB8.text = "Да"
// } else {
// txtB8.text = "Нет"
// }
//
// if (item.nine == 9) {
// txtB9.text = "Да"
// } else {
// txtB9.text = "Нет"
// }
//
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_questionnaire_before, parent, false)
return Holder(view)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))
}
class Comparator : DiffUtil.ItemCallback<QBModel>() {
override fun areItemsTheSame(oldItem: QBModel, newItem: QBModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: QBModel, newItem: QBModel): Boolean {
return oldItem == newItem
}
}
}

View File

@ -0,0 +1,266 @@
package com.example.doctor.Patients.Reports
import android.annotation.SuppressLint
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.doctor.R
import com.example.doctor.databinding.ItemQbaBinding
class QBBAdapter() : ListAdapter<QBAModel, QBBAdapter.Holder>(Comparator()) {
class Holder(view: View) :
RecyclerView.ViewHolder(view) {
val binding = ItemQbaBinding.bind(view)
@SuppressLint("SuspiciousIndentation")
fun bind(item: QBAModel) = with(binding) {
// if (item.one == 1) {
// txtB1.text = "Да"
// } else {
// txtB1.text = "Нет"
// }
txtDate.text = item.date
if(item.oneb >= 6){
txtStatusB.text = "Плохо"
CVB.setCardBackgroundColor(Color.parseColor("#DA8383"))
}
else if(item.fourb == 1 || item.fiveb == 1 ||item.sixb == 1 ||item.sevenb == 1 ||item.nineb == 1){
txtStatusB.text = "Средне"
CVB.setCardBackgroundColor(Color.parseColor("#DABA83"))
}
else{
txtStatusB.text = "Хорошо"
CVB.setCardBackgroundColor(Color.parseColor("#ABDA83"))
}
if(item.ninea == 1){
txtStatusA.text = "Плохо"
CVA.setCardBackgroundColor(Color.parseColor("#DA8383"))
}
else if(item.onea >= 6 || item.threea == 1 ||item.sixa == 1 ||item.eighta == 1 ||item.elevena == 1){
txtStatusA.text = "Средне"
CVA.setCardBackgroundColor(Color.parseColor("#DABA83"))
}
else{
txtStatusA.text= "Хорошо"
CVA.setCardBackgroundColor(Color.parseColor("#ABDA83"))
}
txtB1.text = item.oneb.toString()
if(item.oneb==0){
CLQB1.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
else if(item.oneb in 1..5){
CLQB1.setBackgroundColor(Color.parseColor("#C6DFD386"))
}
else{
CLQB1.setBackgroundColor(Color.parseColor("#C6DF8686"))
}
//Красный - "#C6DF8686"
//Зеленый - "#C686DF8F"
//Желтый - "#C6DFD386"
if (item.twob == 1) {
txtB2.text = "Да"
CLQB2.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB2.text = "Нет"
CLQB2.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.threeb == 1) {
txtB3.text = "Да"
CLQB3.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB3.text = "Нет"
CLQB3.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.fourb == 1) {
txtB4.text = "Да"
CLQB4.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB4.text = "Нет"
CLQB4.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.fiveb == 1) {
txtB5.text = "Да"
CLQB5.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB5.text = "Нет"
CLQB5.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.sixb == 1) {
txtB6.text = "Да"
CLQB6.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB6.text = "Нет"
CLQB6.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.sevenb == 1) {
txtB7.text = "Да"
CLQB7.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB7.text = "Нет"
CLQB7.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.eightb == 1) {
txtB8.text = "Да"
CLQB8.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB8.text = "Нет"
CLQB8.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.nineb == 1) {
txtB9.text = "Да"
CLQB9.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtB9.text = "Нет"
CLQB9.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
txtA1.text = item.onea.toString()
if(item.onea==0){
CLQA1.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
else if(item.onea in 1..5){
CLQA1.setBackgroundColor(Color.parseColor("#C6DFD386"))
}
else{
CLQA1.setBackgroundColor(Color.parseColor("#C6DF8686"))
}
if (item.twoa == 1) {
txtA2.text = "Да"
CLQA2.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA2.text = "Нет"
CLQA2.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.threea == 1) {
txtA3.text = "Да"
CLQA3.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA3.text = "Нет"
CLQA3.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.foura == 1) {
txtA4.text = "Да"
CLQA4.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA4.text = "Нет"
CLQA4.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.fivea == 1) {
txtA5.text = "Да"
CLQA5.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA5.text = "Нет"
CLQA5.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.sixa == 1) {
txtA6.text = "Да"
CLQA6.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA6.text = "Нет"
CLQA6.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.sevena == 1) {
txtA7.text = "Да"
CLQA7.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA7.text = "Нет"
CLQA7.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.eighta == 1) {
txtA8.text = "Да"
CLQA8.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA8.text = "Нет"
CLQA8.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.ninea == 1) {
txtA9.text = "Да"
CLQA9.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA9.text = "Нет"
CLQA9.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.tena == 1) {
txtA10.text = "Да"
CLQA10.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA10.text = "Нет"
CLQA10.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.elevena == 1) {
txtA11.text = "Да"
CLQA11.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA11.text = "Нет"
CLQA11.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
if (item.twelvea == 1) {
txtA12.text = "Да"
CLQA12.setBackgroundColor(Color.parseColor("#C6DF8686"))
} else {
txtA12.text = "Нет"
CLQA12.setBackgroundColor(Color.parseColor("#C686DF8F"))
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_qba, parent, false)
return Holder(view)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val view = holder.bind(getItem(position))
}
class Comparator : DiffUtil.ItemCallback<QBAModel>() {
override fun areItemsTheSame(oldItem: QBAModel, newItem: QBAModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: QBAModel, newItem: QBAModel): Boolean {
return oldItem == newItem
}
}
}

View File

@ -0,0 +1,16 @@
package com.example.doctor.Patients.Reports
data class QBModel(
val id: Int,
val status: String,
val one: Int,
val two: Int,
val three: Int,
val four: Int,
val five: Int,
val six: Int,
val seven: Int,
val eight: Int,
val nine: Int,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Reports.Requests
data class ClearSportPatientModel(
val message: String,
)

View File

@ -0,0 +1,6 @@
package com.example.doctor.Patients.Reports
data class SportCoursListModel(
val courses: List<SportCoursModel>
)

View File

@ -0,0 +1,11 @@
package com.example.doctor.Patients.Reports
data class SportCoursModel(
val id: Int,
val name: String,
val description: String,
val visibility: Int,
val created_at: String,
val updated_at: String,
)

View File

@ -0,0 +1,14 @@
package com.example.doctor.Pref
import android.content.Context
import android.content.SharedPreferences
class ClearPref() {
fun clearToken(context: Context) {
val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE)
val edit = prefDoctor.edit()
edit?.clear()
edit?.apply()
}
}

View File

@ -0,0 +1,13 @@
package com.example.doctor.Pref
import android.content.Context
import android.content.SharedPreferences
class ConclusionPref() {
fun conclusionToken(context: Context):String {
val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE)
val token = prefDoctor.getString("token", "")
return token.toString()
}
}

View File

@ -0,0 +1,15 @@
package com.example.doctor.Pref
import android.content.Context
import android.content.SharedPreferences
class SavePref (){
fun saveToken(context: Context,token: String) {
val prefDoctor: SharedPreferences = context.getSharedPreferences("DOCTOR", Context.MODE_PRIVATE)
val edit = prefDoctor.edit()
prefDoctor.edit().putString("token", token).apply()
}
}

View File

@ -0,0 +1,136 @@
package com.example.doctor.Retrofit
import com.example.doctor.Auth.Model.AuthModel
import com.example.doctor.Auth.Model.CheckTokenModel
import com.example.doctor.Auth.Model.UserModel
import com.example.doctor.Patients.Model.MessageModel
import com.example.doctor.Patients.Model.CreatePatientModel
import com.example.doctor.Patients.Model.PatientAllListModel
import com.example.doctor.Patients.Model.PatientAllModel
import com.example.doctor.Patients.Model.PatientModel
import com.example.doctor.Patients.Model.PauseModel
import com.example.doctor.Patients.Reports.Edit.EditSportListNoModel
import com.example.doctor.Patients.Reports.Edit.EditSportListYesModel
import com.example.doctor.Patients.Reports.Edit.UpdateSportTaskNoModel
import com.example.doctor.Patients.Reports.Edit.UpdateSportTaskYesModel
import com.example.doctor.Patients.Reports.QBAListModel
import com.example.doctor.Patients.Reports.Requests.ClearSportPatientModel
import com.example.doctor.Patients.Reports.SportCoursListModel
import com.example.doctor.Sport.AddSportPatientModel
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 DoctorApi {
//Проверка токена
@Headers("Content-Type: application/json")
@GET("CheckTokenDoctor")
suspend fun CheckToken(@Header("Authorization") token:String): Response<CheckTokenModel>
//Выход из аккаунта
@Headers("Content-Type: application/json")
@POST("LoginDoctor")
suspend fun LoginDoctor(@Body authModel: AuthModel): Response<UserModel>
//Выход из аккаунта
@Headers("Content-Type: application/json")
@POST("LogoutDoctor")
suspend fun LogoutDoctor(@Header("Authorization") token:String):Response<MessageModel>
//Вывод всех пациентов
@Headers("Content-Type: application/json")
@GET("GetPatientAll")
suspend fun GetPatientAll(@Header("Authorization") token:String):Response<PatientAllListModel>
//Вывод всех пациентов
@Headers("Content-Type: application/json")
@GET("GetPatientID")
suspend fun GetPatientID(@Header("Authorization") token:String):Response<PatientAllModel>
//Поиск пациентов
@Headers("Content-Type: application/json")
@GET("GetPatientSearch")
suspend fun GetPatientSearch(@Header("Authorization") token:String,@Query("login") login:String):PatientModel
//Вывод всех курсов
@Headers("Content-Type: application/json")
@GET("GetCoursAll")
suspend fun GetCoursAll(@Header("Authorization") token:String):Response<SportCoursListModel>
//Вывод всех курсов
@Headers("Content-Type: application/json")
@GET("GetCoursAllPatient")
suspend fun GetCoursAllPatient(@Header("Authorization") token:String,@Query("id") id:Int):Response<SportCoursListModel>
//Вывод анкеты пациентов которые сейчас действуют
@Headers("Content-Type: application/json")
@GET("GetPatientBAQiestionar")
suspend fun GetPatientBAQiestionar(@Header("Authorization") token:String,@Query("id") id:Int):Response<QBAListModel>
//Создание аккаунта
@Headers("Content-Type: application/json")
@POST("CreateAccountPatient")
suspend fun CreateAccountPatient(@Header("Authorization") token:String,@Body createPatientModel: CreatePatientModel):Response<MessageModel>
//Обновление данных пользователя
@Headers("Content-Type: application/json")
@PUT("UpdateAccountPatient")
suspend fun UpdateAccountPatient(@Header("Authorization") token:String,@Query("id") id:String, @Query("login") login:String,@Query("password") password:String)
//Добавление блокировки
@Headers("Content-Type: application/json")
@PUT("UpdateBlockAccountPatient")
suspend fun UpdateBlockAccountPatient(@Header("Authorization") token:String,@Query("id") id:Int):Response<MessageModel>
//Добавление паузы
@Headers("Content-Type: application/json")
@PUT("UpdatePauseAccountPatient")
suspend fun UpdatePauseAccountPatient(@Header("Authorization") token:String,@Query("id") id:Int):Response<PauseModel>
//Получения курса пациента в зависимости от того сколько дней пройдено
@Headers("Content-Type: application/json")
@GET("GetCours")
suspend fun GetCours(@Header("Authorization") token:String,@Query("name") name:String,@Query("day") day:String)
//Добавление курса пациенту
@Headers("Content-Type: application/json")
@POST("AddSportPatient")
suspend fun AddSportPatient(@Header("Authorization") token:String,@Body addSportPatientModel: AddSportPatientModel)
//Очистка курса у пациента
@Headers("Content-Type: application/json")
@PUT("ClearPatientSport")
suspend fun ClearPatientSport(@Header("Authorization") token:String,@Query("id_patient") id_patient:Int):Response<ClearSportPatientModel>
//Вывод всех курсов
@Headers("Content-Type: application/json")
@GET("GetCoursesSport")
suspend fun GetCoursesSport(@Header("Authorization") token:String,@Query("id_patient") id_patient:Int,@Query("id_sports_courses_patient") id_sports_courses_patient:Int):Response<EditSportListNoModel>
//Вывод всех включенных упражненйи
@Headers("Content-Type: application/json")
@GET("GetCoursesSportYes")
suspend fun GetCoursesSportYes(@Header("Authorization") token:String,@Query("id_patient") id_patient:Int):Response<EditSportListYesModel>
//Вывод всех отключенных упражнений
@Headers("Content-Type: application/json")
@GET("GetCoursesSportNo")
suspend fun GetCoursesSportNo(@Header("Authorization") token:String,@Query("id_patient") id_patient:Int):Response<EditSportListNoModel>
//Отключенных упражнений
@Headers("Content-Type: application/json")
@PUT("UpdateBlockSportTasksYes")
suspend fun UpdateBlockSportTasksYes(@Header("Authorization") token:String,@Query("id_patient") id_patient:Int,@Query("id_sports_tasks") id_sports_tasks:Int):Response<MessageModel>
//Отключенных упражнений
@Headers("Content-Type: application/json")
@PUT("UpdateBlockSportTasksNo")
suspend fun UpdateBlockSportTasksNo(@Header("Authorization") token:String,@Query("id") id:Int,):Response<MessageModel>
}

View File

@ -0,0 +1,135 @@
package com.example.doctor.Setting
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
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.doctor.Auth.AuthActivity
import com.example.doctor.Auth.AuthFragment
import com.example.doctor.Patients.Reports.PatientFragment
import com.example.doctor.Pref.ClearPref
import com.example.doctor.Pref.ConclusionPref
import com.example.doctor.Pref.SavePref
import com.example.doctor.R
import com.example.doctor.Retrofit.DoctorApi
import com.example.doctor.Toast.showCustomInfoToast
import com.example.doctor.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 prefDoctorClear= ClearPref()
private lateinit var doctorApi: DoctorApi
val prefDoctorConclusion = ConclusionPref()
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)
button()
}
private fun button() = with(binding) {
btnLogout.setOnClickListener{
createAlеrtDialogExitAuth()
}
btnYourData.setOnClickListener{
activity?.supportFragmentManager?.beginTransaction()
?.replace(com.example.doctor.R.id.CLMainFragment, YourDataFragment.newInstance())
?.commit()
}
}
//Диалоговое окно
private fun createAlеrtDialogExitAuth() {
val builder = AlertDialog.Builder(requireContext())
builder.setTitle("Выход")
builder.setMessage("Вы уверены что хотите выйти из аккаунта")
builder.setNegativeButton("Назад") { dialogInterface, i ->
}
builder.setPositiveButton("Подтвердить") { dialogInterface, i ->
Logout()
}
builder.show()
}
//Получения списка пациентов
fun Logout() {
initRetrofit()
val Tokens = prefDoctorConclusion.conclusionToken(requireContext())
CoroutineScope(Dispatchers.IO).launch {
val listProduct = doctorApi.LogoutDoctor("Bearer $Tokens")
activity?.runOnUiThread {
//Фиксируем полученные данные
val visibleviewList = listProduct.body()
val visibleviewListCode = listProduct.isSuccessful()
//Если нету ошибок
if (visibleviewListCode) {
Toast(requireContext()).showCustomInfoToast(visibleviewList?.message.toString(), requireActivity())
prefDoctorClear.clearToken(requireContext())
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMain, AuthFragment.newInstance())
?.commit()
}
}
}
}
//Инициализируем 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()
doctorApi = retrofit.create(DoctorApi::class.java)
}
companion object {
fun newInstance() = SettingFragment()
}
}

View File

@ -0,0 +1,44 @@
package com.example.doctor.Setting
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.doctor.R
import com.example.doctor.databinding.FragmentYourDataBinding
class YourDataFragment : Fragment() {
private lateinit var binding:FragmentYourDataBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentYourDataBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
button()
}
private fun button()= with(binding) {
btnExitYorData.setOnClickListener{
activity?.supportFragmentManager?.beginTransaction()
?.replace(R.id.CLMainFragment, SettingFragment.newInstance())
?.commit()
}
}
companion object {
fun newInstance() = YourDataFragment()
}
}

View File

@ -0,0 +1,8 @@
package com.example.doctor.Sport
data class AddSportPatientModel(
val id_patient: Int,
val id_course: Int,
val all_day: Int,
)

View File

@ -0,0 +1,103 @@
package com.example.doctor.Toast
import android.app.Activity
import android.view.Gravity
import android.widget.TextView
import android.widget.Toast
import com.example.doctor.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<TextView>(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<TextView>(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<TextView>(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<TextView>(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()
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@color/white" />
<item android:color="@android:color/darker_gray" />
</selector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient android:angle="90"
android:startColor="#FFFFFF"
android:centerColor="#F1F1F1"
android:endColor="#F6F1F1"
android:type="linear" />
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#004F7B"/>
<corners android:radius="100dp" />
</shape>

Some files were not shown because too many files have changed in this diff Show More