diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8bfc8c0 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Field Agent \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..639c779 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..131e44d --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..bf187d0 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,79 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.hilt) + alias(libs.plugins.ksp) + +} + +android { + namespace = "com.example.fieldagent" + compileSdk = 35 + + defaultConfig { + applicationId = "com.example.fieldagent" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = 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(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.material) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.navigation.fragment.ktx) + implementation(libs.androidx.navigation.ui.ktx) + implementation(libs.androidx.annotation) + implementation(libs.androidx.lifecycle.livedata.ktx) + implementation(libs.androidx.lifecycle.viewmodel.ktx) + implementation(libs.androidx.activity) + implementation(libs.androidx.fragment.ktx) + implementation(libs.androidx.recyclerview) + implementation(libs.timber) + implementation(libs.okhttp) + implementation(libs.logging.interceptor) + implementation(libs.androidx.swiperefreshlayout) + + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + + implementation(libs.hilt.android) + ksp(libs.hilt.compiler) + + //retrofit + implementation(libs.retrofit.core) + implementation(libs.retrofit.gson) + implementation(libs.retrofit.scalars) + implementation(libs.retrofit.rxjava2) + + implementation(libs.kotlinx.coroutines.core) + implementation(libs.retrofit.coroutines.adapter) + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/fieldagent/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/fieldagent/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..b7d9332 --- /dev/null +++ b/app/src/androidTest/java/com/example/fieldagent/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.fieldagent + +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.fieldagent", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..34aa121 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/AgentApplication.kt b/app/src/main/java/com/example/fieldagent/AgentApplication.kt new file mode 100644 index 0000000..e432880 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/AgentApplication.kt @@ -0,0 +1,14 @@ +package com.example.fieldagent + +import android.app.Application +import com.example.fieldagent.utils.PrefsManager +import dagger.hilt.android.HiltAndroidApp +import javax.inject.Inject + + +@HiltAndroidApp +class AgentApplication : Application() { + + @Inject + lateinit var prefsManager: PrefsManager +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/FirstFragment.kt b/app/src/main/java/com/example/fieldagent/FirstFragment.kt new file mode 100644 index 0000000..69c3e2d --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/FirstFragment.kt @@ -0,0 +1,44 @@ +package com.example.fieldagent + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.navigation.fragment.findNavController +import com.example.fieldagent.databinding.FragmentFirstBinding + +/** + * A simple [Fragment] subclass as the default destination in the navigation. + */ +class FirstFragment : Fragment() { + + private var _binding: FragmentFirstBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + + _binding = FragmentFirstBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.buttonFirst.setOnClickListener { + // findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/MainActivity.kt b/app/src/main/java/com/example/fieldagent/MainActivity.kt new file mode 100644 index 0000000..17e7555 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/MainActivity.kt @@ -0,0 +1,59 @@ +package com.example.fieldagent + +import android.os.Bundle +import com.google.android.material.snackbar.Snackbar +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import android.view.Menu +import android.view.MenuItem +import com.example.fieldagent.databinding.ActivityMainBinding + +class MainActivity : AppCompatActivity() { + + private lateinit var appBarConfiguration: AppBarConfiguration + private lateinit var binding: ActivityMainBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + + setSupportActionBar(binding.toolbar) + + val navController = findNavController(R.id.nav_host_fragment_content_main) + appBarConfiguration = AppBarConfiguration(navController.graph) + setupActionBarWithNavController(navController, appBarConfiguration) + + binding.fab.setOnClickListener { view -> + Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) + .setAction("Action", null) + .setAnchorView(R.id.fab).show() + } + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + menuInflater.inflate(R.menu.menu_main, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + return when (item.itemId) { + R.id.action_settings -> true + else -> super.onOptionsItemSelected(item) + } + } + + override fun onSupportNavigateUp(): Boolean { + val navController = findNavController(R.id.nav_host_fragment_content_main) + return navController.navigateUp(appBarConfiguration) + || super.onSupportNavigateUp() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/SecondFragment.kt b/app/src/main/java/com/example/fieldagent/SecondFragment.kt new file mode 100644 index 0000000..0555f7b --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/SecondFragment.kt @@ -0,0 +1,44 @@ +package com.example.fieldagent + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.navigation.fragment.findNavController +import com.example.fieldagent.databinding.FragmentSecondBinding + +/** + * A simple [Fragment] subclass as the second destination in the navigation. + */ +class SecondFragment : Fragment() { + + private var _binding: FragmentSecondBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + + _binding = FragmentSecondBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.buttonSecond.setOnClickListener { + // findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt b/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt new file mode 100644 index 0000000..71a269d --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt @@ -0,0 +1,497 @@ +package com.example.fieldagent.data.apis + +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.data.network.responseUtil.ApiResponse +import retrofit2.http.FieldMap +import retrofit2.http.FormUrlEncoded +import retrofit2.http.POST + +import retrofit2.Call +import retrofit2.http.DELETE +import retrofit2.http.GET +import retrofit2.http.PUT +import retrofit2.http.Path +import retrofit2.http.QueryMap + +interface WebService { + companion object { + + private const val LOGIN = "auth/login" + private const val INSPECTIONS_LIST = "inspections" + private const val CREATE_INSPECTION = "inspections" + private const val DELETE_INSPECTIONS = "subcategories" + private const val UPDATE_INSPECTIONS = "subcategories" + private const val DAMAGES = "Damages" + private const val COUNTRY_DATA = "/api/countrydata" + private const val PREFERENCES = "/api/master/preferences" + private const val UPDATE_NUMBER = "/api/update-phone" + private const val VERIFY_OTP = "/api/verify-otp" + private const val RESEND_OTP = "api/resend-otp" + private const val REGISTER = "/api/register" + private const val FORGOT_PASSWORD = "/api/forgot_password" + private const val CHANGE_PASSWORD = "/api/password-change" + private const val PROFILE_UPDATE = "/api/profile-update" + private const val LOGOUT = "/api/app_logout" + private const val SEND_SMS = "/api/send-sms" + private const val SEND_EMAIL_OTP = "/api/send-email-otp" + private const val EMAIL_VERIFY = "/api/email-verify" + private const val UPDATE_FCM_ID = "/api/update-fcm-id" + private const val CREATE_REQUEST = "/api/create-request" + private const val CONFIRM_REQUEST = "/api/confirm-request" + private const val ADD_CARD = "api/add-card" + private const val UPDATE_CARD = "/api/update-card" + private const val DELETE_CARD = "/api/delete-card" + private const val ADD_MONEY = "/api/add-money" + private const val ADD_REVIEW = "/api/add-review" + private const val REQUEST_USER_APPROVE = "/api/request-user-approve" + private const val COMPLETE_CHAT = "/api/complete-chat" + private const val UPLOAD_IMAGE = "/api/upload-image" + private const val FEEDS = "/api/feeds" + private const val FEEDS_COMMENTS = "/api/feeds/comments/{feed_id}" + private const val VIEW_FEEDS = "/api/feeds/view/{feed_id}" + private const val ADD_FAVORITE = "/api/feeds/add-favorite/{feed_id}" + private const val ADD_LIKE = "/api/feeds/add-like/{feed_id}" + private const val ADD_COMMENT = "/api/feeds/add-comment/{feed_id}" + + private const val REQUESTS = "/api/requests-cs" + private const val REQUEST_DETAIL = "/api/request-detail" + private const val HOME = "/api/home" + private const val CANCEL_REQUEST = "/api/cancel-request" + private const val DOCTOR_LIST = "/api/doctor-list" + private const val BANNERS = "/api/banners" + private const val COUPONS = "/api/coupons" + private const val DOCTOR_DETAIL = "/api/doctor-detail" + private const val REVIEW_LIST = "/api/review-list" + private const val WALLET_HISTORY = "/api/wallet-history" + private const val CARD_LISTING = "/api/cards" + private const val WALLET = "/api/wallet" + private const val REQUEST_CHECK = "/api/request-check" + private const val CHAT_LISTING = "/api/chat-listing" + private const val CHAT_MESSAGES = "/api/chat-messages" + private const val NOTIFICATIONS = "/api/notifications" + private const val CATEGORIES = "/api/categories" + private const val CLASSES = "/api/classes" + private const val CLASS_DETAIL = "/api/class/detail" + private const val ENROLL_USER = "/api/enroll-user" + private const val CLASS_JOIN = "/api/class/join" + private const val ORDER_CREATE = "/api/order/create" + private const val HYPER_PAY_COMPLETE_DONE = "api/webhook/hyperpay" + private const val RAZOR_PAY_WEBHOOK = "/api/razor-pay-webhook" + private const val SERVICES = "/api/services" + private const val GET_FILTERS = "/api/get-filters" + private const val GET_SLOTS = "/api/get-slots" + private const val CALL_STATUS = "/api/call-status" + private const val PAGES = "/api/pages" + private const val PACK_SUB = "/api/pack-sub" + private const val PURCHASE_PACK = "/api/sub-pack" + private const val PACK_DETAIL = "/api/pack-detail" + private const val SUBSCRIPTIONS = "/api/subscriptions" + private const val SUBSCRIPTION_DETAIL = "/api/subscription-detail" + private const val SUBSCRIPTION_PACK = "/api/subscription-pack" + private const val ASK_QUESTIONS = "/api/ask-questions" + private const val ASK_QUESTIONS_DETAIL = "/api/ask-question-detail" + private const val WATER_LIMIT = "/api/water-limit" + private const val PROTEIN_LIMIT = "/api/protein-limit" + private const val DRINK_WATER = "/api/drink-water" + private const val DRINK_PROTEIN = "/api/drink-protein" + private const val ADD_FAMILY = "/api/add-family" + private const val SYMPTOM = "/api/symptoms" + private const val UPDATE_SYMPTOM = "/api/update-request-symptoms" + private const val EXTRA_PAYMENT = "/api/pay-extra-payment" + private const val CARE_PLANS = "/api/care-plans" + private const val TIERS = "/api/tiers" + private const val ADD_BANK = "/api/add-bank" + private const val BANK_ACCOUNTS = "/api/bank-accounts" + private const val GET_MEDICAL_HISTORY = "/api/get-medical-history" + + private const val DIRECTIONS = "https://maps.googleapis.com/maps/api/directions/json" + + private const val WORKING_HOURS = "/api/workingHours" + private const val SPEAKOUT_LIST = "/common/listSpeakouts" + + /*V2 Api*/ + private const val CREATE_REQUEST_V2 = "/api/v2/create-request" + private const val CONFIRM_REQUEST_V2 = "/api/v2/confirm-request" + private const val DOCTOR_LIST_V2 = "/api/v2/doctor-list" + private const val CANCEL_REQUEST_V2 = "/api/v2/cancel-request" + + private const val CONTACT_LIST = "/api/contact-list" + private const val CONTACT_ADD = "/api/contact-add" + private const val CONTACT_DELETE = "/api/contact-delete" + private const val CONTACT_MESSAGE = "/api/contact-message" + + } + + /*POST APIS*/ + @FormUrlEncoded + @POST(LOGIN) + fun login(@FieldMap hashMap: HashMap): Call> + + + @GET(INSPECTIONS_LIST) + fun inspectionsList(@QueryMap hashMap: Map): Call> + + + @POST(CREATE_INSPECTION) + fun createInspections(@QueryMap hashMap: Map): Call> + + + @GET(DAMAGES) + fun damagesList(@QueryMap hashMap: Map): Call> + + + @POST(DAMAGES) + fun createDamage(@QueryMap hashMap: Map): Call> + + + @DELETE("$DELETE_INSPECTIONS/{id}") + fun deleteInspections(@Path("id") id: String): Call> + + @PUT("$UPDATE_INSPECTIONS/{id}") + fun updateInspection(@Path("id") id: String): Call> + + + @DELETE("$DAMAGES/{id}") + fun deleteDamage(@Path("id") id: String): Call> + + @PUT("$DAMAGES/{id}") + fun updateDamage(@Path("id") id: String): Call> + /* + @FormUrlEncoded + @POST(APP_VERSION) + fun appVersion(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(UPDATE_NUMBER) + fun updateNumber(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(VERIFY_OTP) + fun verifyOtp(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(RESEND_OTP) + fun resendOtp(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(REGISTER) + fun register(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(FORGOT_PASSWORD) + fun forgotPassword(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(CHANGE_PASSWORD) + fun changePassword(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(PROFILE_UPDATE) + fun updateProfile(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(COMPLETE_CHAT) + fun completeChat(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(SEND_SMS) + fun sendSMS(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(SEND_EMAIL_OTP) + fun sendEmailOtp(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(EMAIL_VERIFY) + fun emailVerify(@FieldMap hashMap: HashMap): Call> + + @POST(LOGOUT) + fun logout(): Call> + + @FormUrlEncoded + @POST(UPDATE_FCM_ID) + fun updateFcmId(@FieldMap hashMap: HashMap): Call> + + @POST(CREATE_REQUEST) + fun createRequest(@Body createRequest: CreateRequest): Call> + + @POST(CREATE_REQUEST_V2) + fun createRequestV2(@Body createRequest: CreateRequest): Call> + + @POST(CONFIRM_REQUEST) + fun confirmRequest(@Body createRequest: CreateRequest): Call> + + @POST(CONFIRM_REQUEST_V2) + fun confirmRequestV2(@Body createRequest: CreateRequest): Call> + + @FormUrlEncoded + @POST(ADD_CARD) + fun addCard(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(UPDATE_CARD) + fun updateCard(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(DELETE_CARD) + fun deleteCard(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ADD_MONEY) + fun addMoney(@FieldMap hashMap: HashMap): Call> + + @Multipart + @POST(UPLOAD_IMAGE) + fun uploadFile(@PartMap map: HashMap): Call> + + @FormUrlEncoded + @POST(ADD_REVIEW) + fun addReview(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(REQUEST_USER_APPROVE) + fun approveWorkingHour(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ENROLL_USER) + fun enrollUser(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(CLASS_JOIN) + fun joinClass(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ORDER_CREATE) + fun orderCreate(@FieldMap hashMap: HashMap): Call> + + + @FormUrlEncoded + @POST(HYPER_PAY_COMPLETE_DONE) + fun hyperPayCompleteTrans(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(CANCEL_REQUEST_V2) + fun cancelRequest(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(CALL_STATUS) + fun callStatus(@FieldMap hashMap: HashMap): Call> + + @GET(PACK_DETAIL) + fun packDetail(@QueryMap hashMap: Map): Call> + + @GET(SUBSCRIPTION_DETAIL) + fun subscriptionDetail(@QueryMap hashMap: Map): Call> + + @FormUrlEncoded + @POST(PURCHASE_PACK) + fun purchasePack(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(SUBSCRIPTION_PACK) + fun subscriptionPack(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ADD_FAVORITE) + fun addFavorite(@Path("feed_id") feed_id: String, + @FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ADD_LIKE) + fun addLike(@Path("feed_id") feed_id: String, + @FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ADD_COMMENT) + fun addComment(@Path("feed_id") feed_id: String, + @FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(RAZOR_PAY_WEBHOOK) + fun razorPayWebhook(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(ASK_QUESTIONS) + fun askQuestion(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(WATER_LIMIT) + fun setDailyLimit(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(PROTEIN_LIMIT) + fun setProteinDailyLimit(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(DRINK_WATER) + fun setWaterIntake(@FieldMap hashMap: HashMap): Call> + + @FormUrlEncoded + @POST(DRINK_PROTEIN) + fun setProteinIntake(@FieldMap hashMap: HashMap): Call> + + + @FormUrlEncoded + @POST(ADD_FAMILY) + fun addFamily(@FieldMap hashMap: HashMap): Call> + + @POST(UPDATE_SYMPTOM) + fun updateSymptom(@Body updateSymptom: UpdateSymptom): Call> + + @POST(CARE_PLANS) + fun carePlans(@Body updateSymptom: UpdateSymptom): Call> + + @FormUrlEncoded + @POST(ADD_BANK) + fun addBank(@FieldMap hashMap: HashMap): Call> + + + *//*GET*//* + + @GET(CLIENT_DETAILS) + fun clientDetails(@QueryMap hashMap: Map): Call> + + @GET(COUNTRY_DATA) + fun countryData(@QueryMap hashMap: Map): Call> + + @GET(PREFERENCES) + fun preferences(@QueryMap hashMap: Map): Call> + + @GET(HOME) + fun home(): Call> + + @GET(REQUESTS) + fun request(@QueryMap hashMap: Map): Call> + + @GET(REQUEST_DETAIL) + fun requestDetail(@QueryMap hashMap: Map): Call> + + @GET(DOCTOR_LIST) + fun doctorList(@QueryMap hashMap: Map): Call> + + @GET(DOCTOR_LIST_V2) + fun doctorListV2(@QueryMap hashMap: Map): Call> + + @GET(BANNERS) + fun banners(): Call> + + @GET(DOCTOR_DETAIL) + fun doctorDetails(@QueryMap hashMap: Map): Call> + + @GET(REVIEW_LIST) + fun reviewList(@QueryMap hashMap: Map): Call> + + @GET(WALLET_HISTORY) + fun walletHistory(@QueryMap hashMap: Map): Call> + + @GET(CARD_LISTING) + fun cardListing(@QueryMap hashMap: Map): Call> + + @GET(WALLET) + fun wallet(@QueryMap hashMap: Map): Call> + + @GET(CHAT_LISTING) + fun getChatListing(@QueryMap hashMap: Map): Call> + + @GET(CHAT_MESSAGES) + fun getChatMessage(@QueryMap hashMap: Map): Call> + + @GET(NOTIFICATIONS) + fun notifications(@QueryMap hashMap: Map): Call> + + @GET(FEEDS) + fun getFeeds(@QueryMap hashMap: Map): Call> + + @GET(FEEDS_COMMENTS) + fun getFeedsComment(@Path("feed_id") feed_id: String, + @QueryMap hashMap: Map): Call> + + @GET(VIEW_FEEDS) + fun viewFeeds(@Path("feed_id") feed_id: String): Call> + + + @GET(CATEGORIES) + fun categories(@QueryMap hashMap: Map): Call> + + @GET(CLASSES) + fun classesList(@QueryMap hashMap: Map): Call> + + @GET(CLASS_DETAIL) + fun classDetail(@QueryMap hashMap: Map): Call> + + @GET(GET_FILTERS) + fun getFilters(@QueryMap hashMap: Map): Call> + + + @GET(SERVICES) + fun services(@QueryMap hashMap: Map): Call> + + @GET(GET_SLOTS) + fun getSlots(@QueryMap hashMap: Map): Call> + + @GET(PAGES) + fun getPages(): Call> + + @GET(COUPONS) + fun coupons(@QueryMap hashMap: Map): Call> + + @GET(PACK_SUB) + fun packSub(@QueryMap hashMap: Map): Call> + + @GET(SUBSCRIPTIONS) + fun subscriptions(@QueryMap hashMap: Map): Call> + + @GET(DIRECTIONS) + fun directions(@QueryMap hashMap: Map): Call + + @GET(ASK_QUESTIONS) + fun getQuestions(@QueryMap hashMap: Map): Call> + + @GET(ASK_QUESTIONS_DETAIL) + fun getQuestionsDetails(@QueryMap hashMap: Map): Call> + + @GET(WATER_LIMIT) + fun getWaterLimit(@QueryMap hashMap: Map): Call> + + @GET(PROTEIN_LIMIT) + fun getProteinIntake(@QueryMap hashMap: Map): Call> + + @GET(REQUEST_CHECK) + fun requestCheck(@QueryMap hashMap: Map): Call> + + @GET(SYMPTOM) + fun symptom(@QueryMap hashMap: Map): Call> + + @GET(TIERS) + fun carePlanTier(): Call> + + @POST(EXTRA_PAYMENT) + fun payExtra(@Body extraPayment: Extra_payment): Call> + + @GET(BANK_ACCOUNTS) + fun bankAccounts(@QueryMap hashMap: Map): Call> + + @GET(GET_MEDICAL_HISTORY) + fun getMedicalHistory(@QueryMap hashMap: Map): Call> + + + *//*PUT API*//* + @FormUrlEncoded + @PUT(WORKING_HOURS) + fun workingHours(@FieldMap hashMap: HashMap): Call> + + + @GET(CONTACT_LIST) + fun contactList(@QueryMap hashMap: Map): Call> + + @POST(CONTACT_ADD) + fun addContact(@Body contactList: ContactEmergency): Call> + + @FormUrlEncoded + @POST(CONTACT_DELETE) + fun deletContact(@FieldMap hashMap: HashMap): Call> + + @POST(CONTACT_MESSAGE) + fun sendMessage(): Call>*/ + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/AppFeatures.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/AppFeatures.kt new file mode 100644 index 0000000..3e321aa --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/AppFeatures.kt @@ -0,0 +1,29 @@ +package com.consultantapp.data.models.requests + +class AppFeatures { + var needUserDoctorScreen = false + + var needWalkThrough = false + var needLanguageScreen = false + var needPackage = false + + var needClasses = false + + var needLocation = false + + var subCategoryImageCenter = false + + var homeConsultIcons = false + + var needBlogs = false + var needArticles = false + + var needHealthTools = false + + var signUpAddition = false + var needInsuranceDocument = false + + var needHomePatients = false + var needTestimonials = false + var needInviteCode = false +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/CarePlan.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/CarePlan.kt new file mode 100644 index 0000000..2eb9ef7 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/CarePlan.kt @@ -0,0 +1,6 @@ +package com.consultantapp.data.models.requests + +data class CarePlan ( + var id: Int? = null, + var type: Int? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/ConsultTypeModel.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/ConsultTypeModel.kt new file mode 100644 index 0000000..2c75c70 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/ConsultTypeModel.kt @@ -0,0 +1,7 @@ +package com.consultantapp.data.models.requests + +data class ConsultTypeModel ( + var name: String? = null, + var image: Int? = null, + var type: String? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/CreateRequest.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/CreateRequest.kt new file mode 100644 index 0000000..5925441 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/CreateRequest.kt @@ -0,0 +1,23 @@ +package com.consultantapp.data.models.requests + +import java.io.Serializable + +class CreateRequest : Serializable { + var consultant_id: String? = null + var schedule_type: String? = null + var service_id: String? = null + var request_id: String? = null + var category_id: String? = null + var date: String? = null + var time: String? = null + var end_date: String? = null + var end_time: String? = null + var coupon_code: String? = null + + var service_address: String? = null + var lat: Double? = null + var long: Double? = null + + var tier_id: Int? = null + var tier_options:ArrayList?=null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/DatesAvailability.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/DatesAvailability.kt new file mode 100644 index 0000000..0a3aa0c --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/DatesAvailability.kt @@ -0,0 +1,10 @@ +package com.consultantapp.data.models.requests + +class DatesAvailability { + var displayName: String? = null + var date: Long? = null + var isSelected = false + + /*Water intake*/ + var intakeAmount: Int? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/DocImage.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/DocImage.kt new file mode 100644 index 0000000..18fb42f --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/DocImage.kt @@ -0,0 +1,13 @@ +package com.consultantapp.data.models.requests + +import java.io.File +import java.io.Serializable + +class DocImage : Serializable { + var imageFile: File? = null + var type: String? = null + + var image: String? = null + var insuranceNumber: String? = null + var expiry: String? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/SaveAddress.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/SaveAddress.kt new file mode 100644 index 0000000..8c6f67f --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/SaveAddress.kt @@ -0,0 +1,14 @@ +package com.consultantapp.data.models.requests + +import java.io.Serializable + +data class SaveAddress ( + var locationName: String? = null, + var houseNumber: String? = null, + var isDefault :Boolean = false, + var _id: String? = null, + var addressId: String? = null, + + var lat: Double? = null, + var long: Double? = null +): Serializable \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/SetFilter.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/SetFilter.kt new file mode 100644 index 0000000..61b2e55 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/SetFilter.kt @@ -0,0 +1,11 @@ +package com.consultantapp.data.models.requests + +import java.io.Serializable + +class SetFilter :Serializable{ + var filter_id: Int? = null + var filter_option_ids: ArrayList? = null + + var preference_id: Int? = null + var option_ids: ArrayList? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/requests/UpdateSymptom.kt b/app/src/main/java/com/example/fieldagent/data/models/requests/UpdateSymptom.kt new file mode 100644 index 0000000..f79c22b --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/requests/UpdateSymptom.kt @@ -0,0 +1,16 @@ +package com.consultantapp.data.models.requests + + +import java.io.Serializable + + +class UpdateSymptom : Serializable { + var request_id: String? = null + var image: ArrayList? = null + var images: ArrayList? = null + var option_ids: String? = null + var symptom_details: String? = null + + + var type: String? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/responses/UserData.kt b/app/src/main/java/com/example/fieldagent/data/models/responses/UserData.kt new file mode 100644 index 0000000..ff93771 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/responses/UserData.kt @@ -0,0 +1,24 @@ +package com.example.fieldagent.data.models.responses + +data class UserData ( + val status: Long? = null, + val success: Boolean? = null, + val message: String? = null, + val data: Data? = null +) + +data class Data ( + val id: Long? = null, + val name: String? = null, + val email: String? = null, + val phoneNumber: String? = null, + val designation: String? = null, + val createdAt: String? = null, + val updatedAt: String? = null, + val tokens: Tokens? = null +) + +data class Tokens ( + val accessToken: String? = null, + val refreshToken: String? = null +) diff --git a/app/src/main/java/com/example/fieldagent/data/network/ApisRespHandler.kt b/app/src/main/java/com/example/fieldagent/data/network/ApisRespHandler.kt new file mode 100644 index 0000000..73a3783 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/ApisRespHandler.kt @@ -0,0 +1,67 @@ +package com.example.fieldagent.data.network + +import android.app.Activity +import androidx.appcompat.app.AlertDialog +import com.example.fieldagent.data.network.responseUtil.AppError +import com.example.fieldagent.R +object ApisRespHandler { + + private var alertDialog: AlertDialog.Builder? = null + + fun handleError(error: AppError?, activity: Activity,) { + error ?: return + + + when (error) { + is AppError.ApiError -> { + if (alertDialog == null) + errorMessage(activity, error.message) + } + + is AppError.ApiUnauthorized -> { + + + } + + is AppError.ApiAccountBlock -> { + + } + + is AppError.ApiAccountRuleChanged -> { + + } + + is AppError.ApiFailure -> { + if (alertDialog == null) { + if (error.message.contains("Failed to connect to",true) || + error.message.contains("Unable to resolve host",true) || + error.message.contains("No address associated with hostname",true)) + errorMessage(activity, activity.getString(R.string.check_internet)) + else + errorMessage(activity, error.message) + } + } + } + } + + + + + + + private fun errorMessage(activity: Activity, message: String?) { + try { + alertDialog = AlertDialog.Builder(activity) + alertDialog?.setCancelable(false) + alertDialog?.setTitle(activity.getString(R.string.alert)) + alertDialog?.setMessage(message) + alertDialog?.setPositiveButton(activity.getString(R.string.ok)) { _, _ -> + alertDialog = null + } + alertDialog?.show() + + } catch (ignored: Exception) { + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/Config.kt b/app/src/main/java/com/example/fieldagent/data/network/Config.kt new file mode 100644 index 0000000..9dae2a7 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/Config.kt @@ -0,0 +1,10 @@ +package com.example.fieldagent.data.network + + + +object Config { + + var BASE_URL = "https://field-api.dmlabs.in/api/" + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiResponse.kt b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiResponse.kt new file mode 100644 index 0000000..969c0f5 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiResponse.kt @@ -0,0 +1,6 @@ +package com.example.fieldagent.data.network.responseUtil + +data class ApiResponse( + val message: String? = null, + val data: T? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiUtils.kt b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiUtils.kt new file mode 100644 index 0000000..834f4a5 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/ApiUtils.kt @@ -0,0 +1,54 @@ +package com.example.fieldagent.data.network.responseUtil + +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody +import org.json.JSONObject +import retrofit2.Response +import java.io.File + +object ApiUtils { + private fun getErrorMessage(errorJson: String?): String { + if (errorJson.isNullOrBlank()) { + return "" + } + + return try { + val errorJsonObject = JSONObject(errorJson) + errorJsonObject.getString("message") + } catch (exception: Exception) { + "" + } + } + + fun getError(statusCode: Int, errorJson: String?): AppError { + val message = getErrorMessage(errorJson) + return when (statusCode) { + 401 -> { + AppError.ApiUnauthorized(message) + } + 402 -> { + AppError.ApiAccountBlock(message) + } + 403 -> { + AppError.ApiAccountRuleChanged(message) + } + else -> { + AppError.ApiError(statusCode, message) + } + } + } + + fun failure(throwable: Throwable): AppError { + return AppError.ApiFailure(throwable.localizedMessage ?: "") + } + + fun imageToRequestBody(imageFile: File): RequestBody =imageFile.asRequestBody("image/*".toMediaType()) + + fun imageToRequestBodyKey(parameterName: String, fileName: String): String = + "$parameterName\"; filename=\"$fileName" +} + +fun Response.getAppError(): AppError { + return ApiUtils.getError(code(), errorBody()?.string()) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/responseUtil/AppError.kt b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/AppError.kt new file mode 100644 index 0000000..2c10a03 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/AppError.kt @@ -0,0 +1,10 @@ +package com.example.fieldagent.data.network.responseUtil + +sealed class AppError { + data class ApiError(val statusCode: Int, val message: String) : AppError() + data class ApiUnauthorized(val message: String) : AppError() + data class ApiAccountBlock(val message: String) : AppError() + data class ApiAccountRuleChanged(val message: String) : AppError() + data class ApiFailure(val message: String) : AppError() + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Resource.kt b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Resource.kt new file mode 100644 index 0000000..aa9b1c9 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Resource.kt @@ -0,0 +1,24 @@ +package com.example.fieldagent.data.network.responseUtil + +import com.consultantapp.data.network.responseUtil.Status + + +/** + * A generic class that holds a value with its loading status. + * @param + */ +data class Resource(val status: Status, val data: T?, val error: AppError?) { + companion object { + fun success(data: T? = null): Resource { + return Resource(Status.SUCCESS, data, null) + } + + fun error(error: AppError): Resource { + return Resource(Status.ERROR, null, error) + } + + fun loading(): Resource { + return Resource(Status.LOADING, null, null) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Status.kt b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Status.kt new file mode 100644 index 0000000..4f08a93 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/network/responseUtil/Status.kt @@ -0,0 +1,14 @@ +package com.consultantapp.data.network.responseUtil + +/** + * Status of a resource that is provided to the UI. + * + * + * These are usually created by the Repository classes where they return + * `LiveData>` to pass back the latest data to the UI with its fetch status. + */ +enum class Status { + SUCCESS, + ERROR, + LOADING +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/di/AppModule.kt b/app/src/main/java/com/example/fieldagent/di/AppModule.kt new file mode 100644 index 0000000..62b49fe --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/di/AppModule.kt @@ -0,0 +1,42 @@ +package com.example.fieldagent.di + +import android.content.Context +import android.content.SharedPreferences +import android.preference.PreferenceManager + +import com.google.gson.FieldNamingPolicy +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +object AppModule { + + + @Provides + @Singleton + @JvmStatic + fun provideContext(@ApplicationContext app: Context): Context = app + + @Provides + @Singleton + @JvmStatic + fun sharedPreferences(context: Context): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + + @Provides + @Singleton + @JvmStatic + fun provideGson(): Gson { + return GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) + .setPrettyPrinting() + .setLenient() + .create() + } +} diff --git a/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt b/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt new file mode 100644 index 0000000..1188694 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/di/NetworkModule.kt @@ -0,0 +1,83 @@ +package com.example.fieldagent.di + +import com.example.fieldagent.data.apis.WebService +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.data.network.Config +import com.example.fieldagent.utils.PrefsManager +import com.example.fieldagent.utils.USER_DATA +import com.google.gson.Gson +import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.Interceptor +import okhttp3.logging.HttpLoggingInterceptor +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.converter.scalars.ScalarsConverterFactory +import java.util.* +import java.util.concurrent.TimeUnit +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +object NetworkModule { + + @Provides + @Singleton + @JvmStatic + fun okHttpClient(prefsManager: PrefsManager): OkHttpClient { + return OkHttpClient.Builder() + .connectTimeout(100, TimeUnit.SECONDS) + .readTimeout(100, TimeUnit.SECONDS) + .writeTimeout(100, TimeUnit.SECONDS) + .addInterceptor(getHttpLoggingInterceptor()) + .cache(null) + .addInterceptor(getNetworkInterceptor(prefsManager)) + .build() + } + + + @Provides + @Singleton + @JvmStatic + fun retrofit(client: OkHttpClient, gson: Gson): Retrofit { + return Retrofit.Builder() + .baseUrl(Config.BASE_URL) + .client(client) + .addConverterFactory(GsonConverterFactory.create(gson)) + .addConverterFactory(ScalarsConverterFactory.create()) + .addCallAdapterFactory(CoroutineCallAdapterFactory()) + .build() + } + + private fun getNetworkInterceptor(prefsManager: PrefsManager): Interceptor { + return Interceptor { chain -> + var request = chain.request() + + val requestBuilder = request.newBuilder() + + val accessToken = prefsManager.getObject(USER_DATA, UserData::class.java)?.data?.tokens?.accessToken + + if (!accessToken.isNullOrEmpty()) + requestBuilder.addHeader("authorization", "Bearer $accessToken") + + request=requestBuilder.build() + + chain.proceed(request) + } + } + + private fun getHttpLoggingInterceptor(): HttpLoggingInterceptor { + val httpLoggingInterceptor = HttpLoggingInterceptor() + httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY + return httpLoggingInterceptor + } + + @Provides + @Singleton + @JvmStatic + fun webService(retrofit: Retrofit): WebService = retrofit.create(WebService::class.java) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/di/ResourceProvider.kt b/app/src/main/java/com/example/fieldagent/di/ResourceProvider.kt new file mode 100644 index 0000000..94bb932 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/di/ResourceProvider.kt @@ -0,0 +1,20 @@ +package com.example.fieldagent.di + +import android.content.Context +import android.content.res.Resources + +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ResourceProvider @Inject constructor(private val context: Context) { + + fun getStringResource(stringId: Int): String { + // return LocaleHelper.onCreate(context).getString(stringId) + return ""; + } + + fun getResources(): Resources { + return context.resources + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/di/SingleLiveEvent.java b/app/src/main/java/com/example/fieldagent/di/SingleLiveEvent.java new file mode 100644 index 0000000..58afd69 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/di/SingleLiveEvent.java @@ -0,0 +1,58 @@ +package com.example.fieldagent.di; + + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; + +import java.util.concurrent.atomic.AtomicBoolean; + +import timber.log.Timber; + + +/** + * A lifecycle-aware observable that sends only new updates after subscription, used for events USER_LIKE + * navigation and Snackbar messages. + *

+ * This avoids a common problem with events: on configuration change (USER_LIKE rotation) an update + * can be emitted if the observer is active. This LiveData only calls the observable if there's an + * explicit call to setValue() or call(). + *

+ * Note that only one observer is going to be notified of changes. + */ +public class SingleLiveEvent extends MutableLiveData { + private final AtomicBoolean pending = new AtomicBoolean(false); + + @MainThread + public void setObserver(@NonNull LifecycleOwner owner, @NonNull final Observer observer) { + + if (hasActiveObservers()) { + Timber.w("Multiple observers registered but only one will be notified of changes."); + } + + // Observe the internal MutableLiveData + super.observe(owner, t -> { + if (pending.compareAndSet(true, false)) { + observer.onChanged(t); + } + }); + + } + + @MainThread + public void setValue(@Nullable T t) { + pending.set(true); + super.setValue(t); + } + + /** + * Used for cases where T is Void, to make calls cleaner. + */ + @MainThread + public void call() { + setValue(null); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/SplashActivity.kt b/app/src/main/java/com/example/fieldagent/ui/SplashActivity.kt new file mode 100644 index 0000000..6181dee --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/SplashActivity.kt @@ -0,0 +1,56 @@ +package com.example.fieldagent.ui + +import android.content.Intent +import android.os.Bundle +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.lifecycle.lifecycleScope +import com.example.fieldagent.R +import com.example.fieldagent.databinding.ActivityLoginBinding +import com.example.fieldagent.databinding.ActivitySplashBinding +import com.example.fieldagent.ui.homescreen.HomeActivity +import com.example.fieldagent.ui.login.LoginActivity +import com.example.fieldagent.utils.IS_LOGIN +import com.example.fieldagent.utils.PrefsManager +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.time.delay +import javax.inject.Inject + +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class SplashActivity : AppCompatActivity() { + + private lateinit var binding: ActivitySplashBinding + + @Inject + lateinit var prefsManager: PrefsManager + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivitySplashBinding.inflate(layoutInflater) + setContentView(binding.root) + + initialize() + } + + private fun initialize(){ + + lifecycleScope.launch { + delay(1500) + if(prefsManager.getBoolean(IS_LOGIN,false)){ + val intent = Intent(this@SplashActivity, HomeActivity::class.java) + startActivity(intent) + finish() + }else{ + val intent = Intent(this@SplashActivity, LoginActivity::class.java) + startActivity(intent) + finish() + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt b/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt new file mode 100644 index 0000000..a1c2db3 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt @@ -0,0 +1,71 @@ +package com.example.fieldagent.ui.addsite + +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.ArrayAdapter +import androidx.navigation.fragment.findNavController +import com.example.fieldagent.R +import com.example.fieldagent.databinding.FragmentAddSiteBinding +import com.example.fieldagent.databinding.FragmentHomeBinding +import com.example.fieldagent.ui.homescreen.adapter.HomeAdapter + + +class AddSiteFragment : Fragment() { + + private var _binding: FragmentAddSiteBinding? = null + + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentAddSiteBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + + + val options = resources.getStringArray(R.array.availability).toList() + val adapter = ArrayAdapter(requireActivity(), R.layout.dropdown_item, options) + + binding.autoCompleteBuilding.setAdapter(adapter) + + binding.autoCompleteBuilding.setOnClickListener { + + binding.autoCompleteBuilding.showDropDown() + } + + + val options2 = resources.getStringArray(R.array.condition).toList() + val adapter2 = ArrayAdapter(requireActivity(), R.layout.dropdown_item, options2) + + binding.autoCompleteTextView.setAdapter(adapter2) + + binding.autoCompleteTextView.setOnClickListener { + + binding.autoCompleteTextView.showDropDown() + } + + + + binding.ivLeft.setOnClickListener { + + findNavController().popBackStack() + } + } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragment.kt b/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragment.kt new file mode 100644 index 0000000..e7d9346 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragment.kt @@ -0,0 +1,73 @@ +package com.example.fieldagent.ui.damagedetails + +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.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.fieldagent.R +import com.example.fieldagent.databinding.FragmentDamageDetailsBinding +import com.example.fieldagent.databinding.FragmentDamageListBinding +import com.example.fieldagent.ui.damagedetails.adapter.DamageDetailsAdapter +import com.example.fieldagent.ui.homescreen.adapter.HomeAdapter + + +class DamageDetailsFragment : Fragment() { + + + private var _binding: FragmentDamageDetailsBinding? = null + + private val binding get() = _binding!! + private lateinit var adapter: DamageDetailsAdapter + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentDamageDetailsBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + adapter = DamageDetailsAdapter() + binding.rvImage.layoutManager= + LinearLayoutManager(requireActivity(), LinearLayoutManager.HORIZONTAL, false) + binding.rvImage.adapter = adapter + + + val options = resources.getStringArray(R.array.mainItem).toList() + val adapter = ArrayAdapter(requireActivity(), R.layout.dropdown_item, options) + + binding.autoCompleteMain.setAdapter(adapter) + + binding.autoCompleteMain.setOnClickListener { + + binding.autoCompleteMain.showDropDown() + } + + + val options2 = resources.getStringArray(R.array.SubItem).toList() + val adapter2 = ArrayAdapter(requireActivity(), R.layout.dropdown_item, options2) + + binding.autoCompleteSub.setAdapter(adapter2) + + binding.autoCompleteSub.setOnClickListener { + + binding.autoCompleteSub.showDropDown() + } + + + binding.ivLeft.setOnClickListener { + + findNavController().popBackStack() + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/damagedetails/adapter/DamageDetailsAdapter.kt b/app/src/main/java/com/example/fieldagent/ui/damagedetails/adapter/DamageDetailsAdapter.kt new file mode 100644 index 0000000..fdbf26f --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/damagedetails/adapter/DamageDetailsAdapter.kt @@ -0,0 +1,34 @@ +package com.example.fieldagent.ui.damagedetails.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.R + + +class DamageDetailsAdapter() : RecyclerView.Adapter() { + + class DamageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + /* val nameText: TextView = itemView.findViewById(R.id.txtName) + val locationText: TextView = itemView.findViewById(R.id.txtLocation) + val timeText: TextView = itemView.findViewById(R.id.txtTime)*/ + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DamageViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.damage_image_adapter, parent, false) + return DamageViewHolder(view) + } + + override fun onBindViewHolder(holder: DamageViewHolder, position: Int) { + + /* holder.nameText.text =" user.name" + holder.locationText.text =" user.address" + holder.timeText.text = "user.time"*/ + + + } + + override fun getItemCount(): Int = 4 +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt new file mode 100644 index 0000000..3830f54 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt @@ -0,0 +1,51 @@ +package com.example.fieldagent.ui.damagelist + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.fieldagent.R +import com.example.fieldagent.databinding.FragmentAddSiteBinding +import com.example.fieldagent.databinding.FragmentDamageListBinding +import com.example.fieldagent.ui.damagedetails.adapter.DamageDetailsAdapter +import com.example.fieldagent.ui.damagelist.adapter.DamageListAdapter + + +class DamageListFragment : Fragment() { + + private var _binding: FragmentDamageListBinding? = null + + private val binding get() = _binding!! + + private lateinit var adapter: DamageListAdapter + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentDamageListBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + adapter = DamageListAdapter() + binding.rvDamageList.adapter = adapter + + binding.llBtn.setOnClickListener{ + findNavController().navigate(R.id.damageDeatilsFragment) + } + binding.ivLeft.setOnClickListener { + + findNavController().popBackStack() + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/DamageListAdapter.kt b/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/DamageListAdapter.kt new file mode 100644 index 0000000..2755b28 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/DamageListAdapter.kt @@ -0,0 +1,39 @@ +package com.example.fieldagent.ui.damagelist.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.R +import com.example.fieldagent.ui.damagedetails.adapter.DamageDetailsAdapter + +class DamageListAdapter() : RecyclerView.Adapter() { + + class DamageHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val recyclerView: RecyclerView = itemView.findViewById(R.id.rvImage) + //val locationText: TextView = itemView.findViewById(R.id.txtLocation) + // val timeText: TextView = itemView.findViewById(R.id.txtTime) + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DamageHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.damage_view_adapter, parent, false) + return DamageHolder(view) + } + + override fun onBindViewHolder(holder: DamageHolder, position: Int) { + + val adapter = ShowImageAdapter() + holder.recyclerView.layoutManager= + LinearLayoutManager(holder.itemView.context, LinearLayoutManager.HORIZONTAL, false) + holder.recyclerView.adapter = adapter + /* holder.nameText.text =" user.name" + holder.locationText.text =" user.address" + holder.timeText.text = "user.time"*/ + + + } + + override fun getItemCount(): Int = 4 +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/ShowImageAdapter.kt b/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/ShowImageAdapter.kt new file mode 100644 index 0000000..5357f15 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/adapter/ShowImageAdapter.kt @@ -0,0 +1,33 @@ +package com.example.fieldagent.ui.damagelist.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.R + +class ShowImageAdapter() : RecyclerView.Adapter() { + + class ShowImageHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + /* val nameText: TextView = itemView.findViewById(R.id.txtName) + val locationText: TextView = itemView.findViewById(R.id.txtLocation) + val timeText: TextView = itemView.findViewById(R.id.txtTime)*/ + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShowImageHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.fill_image_adapter, parent, false) + return ShowImageHolder(view) + } + + override fun onBindViewHolder(holder: ShowImageHolder, position: Int) { + + /* holder.nameText.text =" user.name" + holder.locationText.text =" user.address" + holder.timeText.text = "user.time"*/ + + + } + + override fun getItemCount(): Int = 4 +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeActivity.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeActivity.kt new file mode 100644 index 0000000..2afabc5 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeActivity.kt @@ -0,0 +1,21 @@ +package com.example.fieldagent.ui.homescreen + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.setupActionBarWithNavController +import com.example.fieldagent.R +import com.example.fieldagent.databinding.ActivityHomeBinding +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class HomeActivity : AppCompatActivity() { + + private lateinit var binding: ActivityHomeBinding + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityHomeBinding.inflate(layoutInflater) + setContentView(binding.root) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt new file mode 100644 index 0000000..d95eb3a --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt @@ -0,0 +1,285 @@ +package com.example.fieldagent.ui.homescreen + +import android.annotation.SuppressLint +import android.content.Intent +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.PopupMenu +import android.widget.PopupWindow +import android.widget.TextView +import androidx.activity.viewModels +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.fieldagent.R +import com.example.fieldagent.databinding.FragmentHomeBinding +import com.example.fieldagent.ui.homescreen.adapter.HomeAdapter +import androidx.core.graphics.drawable.toDrawable +import androidx.fragment.app.viewModels +import com.consultantapp.data.network.responseUtil.Status +import com.example.fieldagent.data.network.ApisRespHandler +import com.example.fieldagent.ui.login.LoginActivity +import com.example.fieldagent.ui.login.LoginViewModel +import com.example.fieldagent.utils.IS_LOGIN +import com.example.fieldagent.utils.PrefsManager +import com.example.fieldagent.utils.USER_DATA +import com.example.fieldagent.utils.dialogs.ProgressDialog +import dagger.hilt.android.AndroidEntryPoint +import java.util.HashMap +import javax.inject.Inject +import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.databinding.PopLayoutBinding +import com.example.fieldagent.utils.AFTER +import com.example.fieldagent.utils.PER_PAGE +import com.example.fieldagent.utils.PER_PAGE_LOAD +import com.example.fieldagent.utils.gone +import com.example.fieldagent.utils.hideShowView +import com.example.fieldagent.utils.isConnectedToInternet +import com.example.fieldagent.utils.visible +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +@AndroidEntryPoint +class HomeFragment : Fragment() { + + private var _binding: FragmentHomeBinding? = null + + private val binding get() = _binding!! + private lateinit var adapter: HomeAdapter + + @Inject + lateinit var prefsManager: PrefsManager + + private val viewModel: HomeViewModel by viewModels() + private lateinit var progressDialog: ProgressDialog + + private var items = ArrayList() + + private var isLastPage = false + + private var isFirstPage = true + + private var isLoadingMoreItems = false + + private var searchJob: Job? = null + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + + _binding = FragmentHomeBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initialize() + bindObservers() + + setAdapter() + listener() + + } + + + private fun initialize(){ + prefsManager.save(IS_LOGIN,true) + + val hashMap = HashMap() + hashMap["limit"] = "10" + hashMap["Page"] = "1" + viewModel.getInspectionList(hashMap); + + } + private fun setAdapter(){ + binding.rvList.layoutManager = LinearLayoutManager(requireActivity()) + adapter = HomeAdapter(this,items) + binding.rvList.adapter = adapter + binding.rvList.itemAnimator = null + } + + private fun listener(){ + + + binding.llBtn.setOnClickListener { + findNavController().navigate(R.id.addSiteFragment) + } + binding.llLogoutBtn.setOnClickListener { + + val intent = Intent(requireActivity(), LoginActivity::class.java) + startActivity(intent) + requireActivity().finish() + } + + binding.ivFilter.setOnClickListener { + + + val inflater = LayoutInflater.from(binding.ivFilter.context) + val parent = binding.root as ViewGroup + val popupView = PopLayoutBinding.inflate(inflater,parent,false) + + val popupWindow = PopupWindow( + popupView.root, + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + true // focusable + ) + + + popupView.txtCompleted.setOnClickListener { + refreshPagination() + hitApi(false) + } + + popupView.txtInProgress.setOnClickListener { + refreshPagination() + hitApi(false) + } + + + popupWindow.setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) + popupWindow.isOutsideTouchable = true + popupWindow.elevation = 40f + + popupWindow.showAsDropDown(binding.ivFilter) + } + + + binding.swipeRefresh.setOnRefreshListener { + hitApi(true) + } + + + + binding.rvList.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + + val layoutManager = binding.rvList.layoutManager as LinearLayoutManager + val totalItemCount = layoutManager.itemCount - 1 + val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition() + + if (!isLoadingMoreItems && !isLastPage && lastVisibleItemPosition >= totalItemCount) { + isLoadingMoreItems = true + hitApi(false) + } + } + }) + + binding.etSearch.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + // Debounce: cancel any previous search job + searchJob?.cancel() + searchJob = lifecycleScope.launch { + delay(300) // wait for user to stop typing (300ms) + val query = s.toString() + if (query.isNotBlank()) { + refreshPagination() + hitApi(false) + } + } + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + }) + + } + + private fun refreshPagination(){ + isLastPage = false + isFirstPage = true + isLoadingMoreItems = false + } + + private fun hitApi(firstHit: Boolean) { + if (isConnectedToInternet(requireContext(), true)) { + if (firstHit) { + isFirstPage = true + isLastPage = false + } + + val hashMap = HashMap() + if (!isFirstPage && items.isNotEmpty()) + // hashMap[AFTER] = items[items.size - 1].id ?: "" + + hashMap[PER_PAGE] = PER_PAGE_LOAD.toString() + + viewModel.getInspectionList(hashMap) + } else + binding.swipeRefresh.isRefreshing = false + } + private fun bindObservers() { + viewModel.inspections.observe(requireActivity(), Observer { + it ?: return@Observer + when (it.status) { + Status.SUCCESS -> { + binding.clLoader.root.gone() + binding.swipeRefresh.isRefreshing = false + + isLoadingMoreItems = false + + // val tempList = it.data?.notifications ?: emptyList() + val tempList=ArrayList() + if (isFirstPage) { + isFirstPage = false + items.clear() + items.addAll(tempList) + + adapter.notifyDataSetChanged() + } else { + val oldSize = items.size + items.addAll(tempList) + + adapter.notifyItemRangeInserted(oldSize, items.size) + } + + isLastPage = tempList.size < PER_PAGE_LOAD + adapter.setAllItemsLoaded(isLastPage) + + + binding.clNoData.rootView.hideShowView(items.isEmpty()) + } + Status.ERROR -> { + isLoadingMoreItems = false + adapter.setAllItemsLoaded(true) + + binding.swipeRefresh.isRefreshing = false + binding.clLoader.root.gone() + ApisRespHandler.handleError(it.error, requireActivity()) + } + Status.LOADING -> { + if (!isLoadingMoreItems && !binding.swipeRefresh.isRefreshing) + binding.clLoader.root.visible() + } + } + }) + } + + + fun clickItem(pos: Int) { + val item = items[pos] + + } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt new file mode 100644 index 0000000..26a5876 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeViewModel.kt @@ -0,0 +1,49 @@ +package com.example.fieldagent.ui.homescreen + +import androidx.lifecycle.ViewModel +import com.example.fieldagent.data.apis.WebService +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.data.network.responseUtil.ApiResponse +import com.example.fieldagent.data.network.responseUtil.ApiUtils +import com.example.fieldagent.data.network.responseUtil.Resource +import com.example.fieldagent.di.SingleLiveEvent +import dagger.hilt.android.lifecycle.HiltViewModel +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import javax.inject.Inject + + +@HiltViewModel +class HomeViewModel @Inject constructor(private val webService: WebService) : ViewModel() { + + val inspections by lazy { SingleLiveEvent>() } + + fun getInspectionList(hashMap: HashMap) { + inspections.value = Resource.loading() + + webService.inspectionsList(hashMap) + .enqueue(object : Callback> { + + override fun onResponse(call: Call>, + response: Response> + ) { + if (response.isSuccessful) { + inspections.value = Resource.success(response.body()?.data) + + } else { + inspections.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call>, throwable: Throwable) { + inspections.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/homescreen/adapter/HomeAdapter.kt b/app/src/main/java/com/example/fieldagent/ui/homescreen/adapter/HomeAdapter.kt new file mode 100644 index 0000000..d204087 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/adapter/HomeAdapter.kt @@ -0,0 +1,101 @@ +package com.example.fieldagent.ui.homescreen.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.RelativeLayout +import android.widget.TextView +import androidx.fragment.app.FragmentActivity +import androidx.navigation.findNavController +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.R +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.databinding.FragmentHomeBinding +import com.example.fieldagent.databinding.HomeAdapterBinding +import com.example.fieldagent.databinding.ItemPagingLoaderBinding +import com.example.fieldagent.ui.homescreen.HomeFragment +import com.example.fieldagent.utils.LoadingStatus.ITEM +import com.example.fieldagent.utils.LoadingStatus.LOADING + +class HomeAdapter(private val fragment: HomeFragment,private val items: ArrayList) : + RecyclerView.Adapter() { + + private var allItemsLoaded = true + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder.itemViewType != LOADING) + (holder as ViewHolder).bind(items[position]) + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return if (viewType == ITEM) { + ViewHolder(HomeAdapterBinding.inflate(LayoutInflater.from(parent.context), parent, false)) + } else { + ViewHolderLoader(ItemPagingLoaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)) + } + } + + override fun getItemCount(): Int = if (allItemsLoaded) items.size else items.size + 1 + + override fun getItemViewType(position: Int) = if (position >= items.size) LOADING else ITEM + + inner class ViewHolder(val binding: HomeAdapterBinding) : + RecyclerView.ViewHolder(binding.root) { + + init { + binding.clMain.setOnClickListener { + fragment.clickItem(bindingAdapterPosition) + } + } + + fun bind(item: UserData) = with(binding) { + /*tvName.text = item.message + + loadImage("tag",binding.ivPic, item.form_user?.profile_image, + R.drawable.image_placeholder) + + tvCallDuration.text = getTimeAgo(item.created_at)*/ + } + } + + inner class ViewHolderLoader(val binding: ItemPagingLoaderBinding) : + RecyclerView.ViewHolder(binding.root) + + fun setAllItemsLoaded(allLoaded: Boolean) { + allItemsLoaded = allLoaded + } +} +/*(var homes: List) : RecyclerView.Adapter() { + + class HomeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val nameText: TextView = itemView.findViewById(R.id.txtName) + val locationText: TextView = itemView.findViewById(R.id.txtLocation) + val timeText: TextView = itemView.findViewById(R.id.txtTime) + val moneyText: TextView = itemView.findViewById(R.id.txtPayment) + val statusText: TextView = itemView.findViewById(R.id.txtStatus) + val viewClick: RelativeLayout = itemView.findViewById(R.id.rlView) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.home_adapter, parent, false) + return HomeViewHolder(view) + } + + override fun onBindViewHolder(holder: HomeViewHolder, position: Int) { + val user = homes[position] + holder.nameText.text = user.name + holder.locationText.text = user.address + holder.timeText.text = user.time + holder.moneyText.text = user.payment + holder.statusText.text = user.status + holder.viewClick.setOnClickListener {view-> + + view.findNavController().navigate(R.id.damageListFragment) + } + + } + + override fun getItemCount(): Int = homes.size +}*/ \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt b/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt new file mode 100644 index 0000000..a3f8aa7 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt @@ -0,0 +1,101 @@ +package com.example.fieldagent.ui.login + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.util.Patterns +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer +import com.consultantapp.data.network.responseUtil.Status +import com.example.fieldagent.R +import com.example.fieldagent.data.network.ApisRespHandler +import com.example.fieldagent.databinding.ActivityLoginBinding +import com.example.fieldagent.ui.homescreen.HomeActivity +import com.example.fieldagent.utils.PrefsManager +import com.example.fieldagent.utils.USER_DATA +import com.example.fieldagent.utils.dialogs.ProgressDialog +import com.example.fieldagent.utils.isConnectedToInternet +import com.example.fieldagent.utils.showSnackBar +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject + + +@AndroidEntryPoint +class LoginActivity : AppCompatActivity() { + + private lateinit var binding: ActivityLoginBinding + + @Inject + lateinit var prefsManager: PrefsManager + private val viewModel: LoginViewModel by viewModels() + private lateinit var progressDialog: ProgressDialog + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityLoginBinding.inflate(layoutInflater) + setContentView(binding.root) + initialise() + listeners() + bindObservers() + + } + private fun initialise() { + progressDialog = ProgressDialog(this) + + } + + private fun listeners(){ + binding.btnSigIn.setOnClickListener { + + + when{ + binding.etEmail.text.toString().isEmpty() -> { + binding.etEmail.showSnackBar(getString(R.string.enter_email)) + } + !Patterns.EMAIL_ADDRESS.matcher(binding.etEmail.text.toString()).matches() -> { + binding.etEmail.showSnackBar(getString(R.string.enter_correct_email)) + } + binding.etPassword.text.toString().length < 6 -> { + binding.etPassword.showSnackBar(getString(R.string.enter_password)) + } + isConnectedToInternet(this, true) -> { + val hashMap = HashMap() + hashMap["email"] = binding.etEmail.text.toString() + hashMap["password"] = binding.etPassword.text.toString() + + viewModel.login(hashMap) + } + } + + + } + } + + private fun bindObservers() { + viewModel.login.observe(this, Observer { + it ?: return@Observer + when (it.status) { + Status.SUCCESS -> { + progressDialog.setLoading(false) + + + prefsManager.save(USER_DATA, it.data) + val intent = Intent(this, HomeActivity::class.java) + startActivity(intent) + finish() + + + } + Status.ERROR -> { + progressDialog.setLoading(false) + ApisRespHandler.handleError(it.error,this) + } + Status.LOADING -> { + progressDialog.setLoading(true) + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/login/LoginViewModel.kt b/app/src/main/java/com/example/fieldagent/ui/login/LoginViewModel.kt new file mode 100644 index 0000000..6c2fe44 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/login/LoginViewModel.kt @@ -0,0 +1,50 @@ +package com.example.fieldagent.ui.login + +import android.content.Intent +import androidx.core.content.ContextCompat.startActivity +import androidx.lifecycle.ViewModel +import com.example.fieldagent.data.apis.WebService +import com.example.fieldagent.data.models.responses.UserData +import com.example.fieldagent.data.network.responseUtil.ApiResponse +import com.example.fieldagent.data.network.responseUtil.ApiUtils +import com.example.fieldagent.data.network.responseUtil.Resource +import com.example.fieldagent.di.SingleLiveEvent +import com.example.fieldagent.ui.homescreen.HomeActivity +import dagger.hilt.android.lifecycle.HiltViewModel +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import javax.inject.Inject + +@HiltViewModel +class LoginViewModel @Inject constructor(private val webService: WebService) : ViewModel() { + + val login by lazy { SingleLiveEvent>() } + + fun login(hashMap: HashMap) { + login.value = Resource.loading() + + webService.login(hashMap) + .enqueue(object : Callback> { + + override fun onResponse(call: Call>, + response: Response> + ) { + if (response.isSuccessful) { + login.value = Resource.success(response.body()?.data) + + } else { + login.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call>, throwable: Throwable) { + login.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt b/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt new file mode 100644 index 0000000..6d1ce3d --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/utils/AppConstant.kt @@ -0,0 +1,18 @@ +package com.example.fieldagent.utils + + + +const val USER_DATA = "userData" +const val IS_LOGIN = "isLogin" + +const val AFTER = "after" +const val BEFORE = "before" +const val PER_PAGE = "per_page" +const val PER_PAGE_LOAD = 10 + + +object LoadingStatus { + const val ITEM = 0 + const val LOADING = 1 +} + diff --git a/app/src/main/java/com/example/fieldagent/utils/ConnectionDetector.kt b/app/src/main/java/com/example/fieldagent/utils/ConnectionDetector.kt new file mode 100644 index 0000000..d18eaf9 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/utils/ConnectionDetector.kt @@ -0,0 +1,48 @@ +package com.example.fieldagent.utils + +import android.Manifest +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.util.Log +import android.widget.Toast +import androidx.annotation.RequiresPermission +import com.example.fieldagent.R + + +/* fun showRetrofitErrorToast() { + Toast.makeText(context, context.getString(R.string.might_problem), Toast.LENGTH_LONG).show() + }*/ + + +fun isConnectedToInternet(context: Context, showAlert: Boolean): Boolean { + val isConnected = isConnectedToInternet(context) + + if (!isConnected) + { + Toast.makeText(context,context.getString(R.string.check_internet),Toast.LENGTH_SHORT).show() + return false + }else{ + return true + } +} + + +private fun isConnectedToInternet(context: Context?): Boolean { + val connectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + val activeNetwork = connectivityManager.activeNetwork ?: return false + val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) + ?: return false + return when { + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true + //for other device how are able to connect with Ethernet + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true + //for check internet over Bluetooth + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true + else -> false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/utils/GeneralFunction.kt b/app/src/main/java/com/example/fieldagent/utils/GeneralFunction.kt new file mode 100644 index 0000000..a36975e --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/utils/GeneralFunction.kt @@ -0,0 +1,51 @@ +package com.example.fieldagent.utils + +import android.content.Context +import android.view.View +import android.widget.TextView +import android.widget.Toast +import androidx.core.content.ContextCompat +import com.example.fieldagent.R +import com.google.android.material.snackbar.Snackbar + + + + +fun View.gone() { + visibility = View.GONE +} + +fun View.visible() { + visibility = View.VISIBLE +} + +fun View.invisible() { + visibility = View.INVISIBLE +} + +fun View.hideShowView(listIsEmpty: Boolean) { + visibility = if (listIsEmpty) View.VISIBLE + else View.GONE +} + + + + +fun View.showSnackBar(msg: String) { + try { + val snackBar = Snackbar.make(this, msg, Snackbar.LENGTH_LONG) + val snackBarView = snackBar.view + val textView = + snackBarView.findViewById(com.google.android.material.R.id.snackbar_text) as TextView + textView.maxLines = 3 + snackBar.setAction(R.string.ok) { snackBar.dismiss() } + snackBarView.setBackgroundColor(ContextCompat.getColor(context, R.color.main_color)) + snackBar.setActionTextColor(ContextCompat.getColor(context, R.color.white)) + snackBar.show() + } catch (e: Exception) { + e.printStackTrace() + } +} +fun Context.longToast(text: CharSequence) { + Toast.makeText(this, text, Toast.LENGTH_LONG).show() +} diff --git a/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt b/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt new file mode 100644 index 0000000..471e697 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt @@ -0,0 +1,72 @@ +package com.example.fieldagent.utils + +import android.content.SharedPreferences +import androidx.annotation.StringDef +import com.google.gson.Gson +import java.util.concurrent.atomic.AtomicBoolean +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class PrefsManager @Inject constructor(private val preferences: SharedPreferences, private val gson: Gson) { + private val sharedPrefName = "ArabLife" + companion object { + annotation class PrefKey + private lateinit var instance: PrefsManager + fun get(): PrefsManager = instance } + + fun save(@PrefKey key: String, value: String) { + preferences.edit().putString(key, value).apply() + } + + fun save(@PrefKey key: String, value: Int) { + preferences.edit().putInt(key, value).apply() + } + + fun save(@PrefKey key: String, value: Boolean) { + preferences.edit().putBoolean(key, value).apply() + } + + fun save(@PrefKey key: String, `object`: Any?) { + if (`object` == null) { + throw IllegalArgumentException("object is null") + } + + // Convert the provided object to JSON string + save(key, gson.toJson(`object`)) + } + + + fun getObject(@PrefKey key: String, objectClass: Class): T? { + val jsonString = preferences.getString(key, null) + return if (jsonString == null) { + null + } else { + try { + gson.fromJson(jsonString, objectClass) + } catch (e: Exception) { + throw IllegalArgumentException("Object stored with key $key is instance of other class") + } + } + } + fun getString(@PrefKey key: String, defValue: String): String = + preferences.getString(key, defValue) ?:"" + + fun getInt(@PrefKey key: String, defValue: Int): Int = preferences.getInt(key, defValue) + + fun getFloat(@PrefKey key: String, defValue: Float): Float = preferences.getFloat(key, defValue) + + fun getBoolean(@PrefKey key: String, defValue: Boolean): Boolean = + preferences.getBoolean(key, defValue) + + + + fun removeAll() { + preferences.edit().clear().apply() + } + + fun remove(key: String) { + preferences.edit().remove(key).apply() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/utils/dialogs/ProgressDialog.kt b/app/src/main/java/com/example/fieldagent/utils/dialogs/ProgressDialog.kt new file mode 100644 index 0000000..d083ceb --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/utils/dialogs/ProgressDialog.kt @@ -0,0 +1,38 @@ +package com.example.fieldagent.utils.dialogs + +import android.app.Activity +import android.app.Dialog +import android.view.View +import android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND + +import com.example.fieldagent.R + +class ProgressDialog() { + + private lateinit var dialog: Dialog + + constructor(context: Activity) : this() { + val dialogView = View.inflate(context, R.layout.dialog_progress, null) + dialog = Dialog(context, R.style.CustomDialog) + dialog.window?.clearFlags(FLAG_DIM_BEHIND) + dialog.setContentView(dialogView) + dialog.setCancelable(false) + } + + private fun show() { + if (!dialog.isShowing) + dialog.show() + } + + private fun dismiss() { + if (dialog.isShowing) + dialog.dismiss() + } + + fun setLoading(isLoading: Boolean) { + if (isLoading) + show() + else + dismiss() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/add.xml b/app/src/main/res/drawable/add.xml new file mode 100644 index 0000000..8caf302 --- /dev/null +++ b/app/src/main/res/drawable/add.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/drawable/app_logo.png b/app/src/main/res/drawable/app_logo.png new file mode 100644 index 0000000..968c466 Binary files /dev/null and b/app/src/main/res/drawable/app_logo.png differ diff --git a/app/src/main/res/drawable/arrow_left.xml b/app/src/main/res/drawable/arrow_left.xml new file mode 100644 index 0000000..9b338ee --- /dev/null +++ b/app/src/main/res/drawable/arrow_left.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/bottom_rounded_background.xml b/app/src/main/res/drawable/bottom_rounded_background.xml new file mode 100644 index 0000000..21d23a6 --- /dev/null +++ b/app/src/main/res/drawable/bottom_rounded_background.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/clock.xml b/app/src/main/res/drawable/clock.xml new file mode 100644 index 0000000..dc8bf9c --- /dev/null +++ b/app/src/main/res/drawable/clock.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/drawable/close_circle.xml b/app/src/main/res/drawable/close_circle.xml new file mode 100644 index 0000000..dbe9a5b --- /dev/null +++ b/app/src/main/res/drawable/close_circle.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/delete.xml b/app/src/main/res/drawable/delete.xml new file mode 100644 index 0000000..1145850 --- /dev/null +++ b/app/src/main/res/drawable/delete.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/dollar_circle.xml b/app/src/main/res/drawable/dollar_circle.xml new file mode 100644 index 0000000..f14d754 --- /dev/null +++ b/app/src/main/res/drawable/dollar_circle.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/drop_down.xml b/app/src/main/res/drawable/drop_down.xml new file mode 100644 index 0000000..97d10b6 --- /dev/null +++ b/app/src/main/res/drawable/drop_down.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/edit.xml b/app/src/main/res/drawable/edit.xml new file mode 100644 index 0000000..0873804 --- /dev/null +++ b/app/src/main/res/drawable/edit.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/filter.xml b/app/src/main/res/drawable/filter.xml new file mode 100644 index 0000000..a6d1018 --- /dev/null +++ b/app/src/main/res/drawable/filter.xml @@ -0,0 +1,48 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/frame_image.xml b/app/src/main/res/drawable/frame_image.xml new file mode 100644 index 0000000..0325d88 --- /dev/null +++ b/app/src/main/res/drawable/frame_image.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/app/src/main/res/drawable/gps.xml b/app/src/main/res/drawable/gps.xml new file mode 100644 index 0000000..7cdceb0 --- /dev/null +++ b/app/src/main/res/drawable/gps.xml @@ -0,0 +1,48 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/home_item.png b/app/src/main/res/drawable/home_item.png new file mode 100644 index 0000000..e158fe9 Binary files /dev/null and b/app/src/main/res/drawable/home_item.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/image_upload.png b/app/src/main/res/drawable/image_upload.png new file mode 100644 index 0000000..ddea12e Binary files /dev/null and b/app/src/main/res/drawable/image_upload.png differ diff --git a/app/src/main/res/drawable/line_space_line_color.xml b/app/src/main/res/drawable/line_space_line_color.xml new file mode 100644 index 0000000..d73799c --- /dev/null +++ b/app/src/main/res/drawable/line_space_line_color.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/line_spce_line.xml b/app/src/main/res/drawable/line_spce_line.xml new file mode 100644 index 0000000..f0abd3d --- /dev/null +++ b/app/src/main/res/drawable/line_spce_line.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/location.xml b/app/src/main/res/drawable/location.xml new file mode 100644 index 0000000..129a9fd --- /dev/null +++ b/app/src/main/res/drawable/location.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/drawable/logout.xml b/app/src/main/res/drawable/logout.xml new file mode 100644 index 0000000..9b4636d --- /dev/null +++ b/app/src/main/res/drawable/logout.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/no_data.png b/app/src/main/res/drawable/no_data.png new file mode 100644 index 0000000..d9bc9fd Binary files /dev/null and b/app/src/main/res/drawable/no_data.png differ diff --git a/app/src/main/res/drawable/pop_menu_white_background.xml b/app/src/main/res/drawable/pop_menu_white_background.xml new file mode 100644 index 0000000..9a168db --- /dev/null +++ b/app/src/main/res/drawable/pop_menu_white_background.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_background.xml b/app/src/main/res/drawable/rounded_background.xml new file mode 100644 index 0000000..0d6e4d8 --- /dev/null +++ b/app/src/main/res/drawable/rounded_background.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_edit_text_background.xml b/app/src/main/res/drawable/rounded_edit_text_background.xml new file mode 100644 index 0000000..c3957cc --- /dev/null +++ b/app/src/main/res/drawable/rounded_edit_text_background.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_image_background.xml b/app/src/main/res/drawable/rounded_image_background.xml new file mode 100644 index 0000000..5434178 --- /dev/null +++ b/app/src/main/res/drawable/rounded_image_background.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_lightest_green_back.xml b/app/src/main/res/drawable/rounded_lightest_green_back.xml new file mode 100644 index 0000000..dce92fe --- /dev/null +++ b/app/src/main/res/drawable/rounded_lightest_green_back.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_main_background.xml b/app/src/main/res/drawable/rounded_main_background.xml new file mode 100644 index 0000000..40fac36 --- /dev/null +++ b/app/src/main/res/drawable/rounded_main_background.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_main_outline.xml b/app/src/main/res/drawable/rounded_main_outline.xml new file mode 100644 index 0000000..bd81bde --- /dev/null +++ b/app/src/main/res/drawable/rounded_main_outline.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_search_background.xml b/app/src/main/res/drawable/rounded_search_background.xml new file mode 100644 index 0000000..98b5e2f --- /dev/null +++ b/app/src/main/res/drawable/rounded_search_background.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/search.xml b/app/src/main/res/drawable/search.xml new file mode 100644 index 0000000..042026b --- /dev/null +++ b/app/src/main/res/drawable/search.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/upper_rounded_background.xml b/app/src/main/res/drawable/upper_rounded_background.xml new file mode 100644 index 0000000..26b7803 --- /dev/null +++ b/app/src/main/res/drawable/upper_rounded_background.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/montserratbold.ttf b/app/src/main/res/font/montserratbold.ttf new file mode 100644 index 0000000..9a425b9 Binary files /dev/null and b/app/src/main/res/font/montserratbold.ttf differ diff --git a/app/src/main/res/font/montserratmedium.ttf b/app/src/main/res/font/montserratmedium.ttf new file mode 100644 index 0000000..db5b1af Binary files /dev/null and b/app/src/main/res/font/montserratmedium.ttf differ diff --git a/app/src/main/res/font/montserratregular.ttf b/app/src/main/res/font/montserratregular.ttf new file mode 100644 index 0000000..2a2b2aa Binary files /dev/null and b/app/src/main/res/font/montserratregular.ttf differ diff --git a/app/src/main/res/font/montserratsemibold.ttf b/app/src/main/res/font/montserratsemibold.ttf new file mode 100644 index 0000000..0ecc667 Binary files /dev/null and b/app/src/main/res/font/montserratsemibold.ttf differ diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml new file mode 100644 index 0000000..1efac61 --- /dev/null +++ b/app/src/main/res/layout/activity_home.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..dea21b4 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + +