From baf0c5cbca0065d20c95e2ed87d108466e061f89 Mon Sep 17 00:00:00 2001 From: Aryankc2 Date: Tue, 29 Apr 2025 18:29:10 +0530 Subject: [PATCH] added profiel section --- .../fieldagent/data/apis/WebService.kt | 447 +----------------- .../data/models/responses/ItemList.kt | 6 + .../models/responses/SelectCategoryData.kt | 40 ++ .../data/models/responses/UserData.kt | 9 +- .../fieldagent/ui/addsite/AddSiteFragment.kt | 2 +- .../ui/damagedetails/DamageDetailsFragment.kt | 145 +++++- .../damagedetails/DamageDetailsFragmentVM.kt | 43 +- .../adapter/DamageDetailsAdapter.kt | 22 +- .../ui/damagelist/DamageListFragment.kt | 71 ++- .../ui/damagelist/DamageListFragmentVM.kt | 28 ++ .../damagelist/adapter/DamageListAdapter.kt | 14 +- .../fieldagent/ui/homescreen/HomeFragment.kt | 7 +- .../fieldagent/ui/login/LoginActivity.kt | 9 +- .../fieldagent/ui/profile/ProfileFragment.kt | 160 +++++++ .../ui/profile/ProfileFragmentVM.kt | 53 +++ .../fieldagent/utils/GeneralFunction.kt | 39 ++ .../example/fieldagent/utils/PrefsManager.kt | 6 +- app/src/main/res/drawable/profile.xml | 5 + .../res/layout/fragment_damage_details.xml | 4 +- .../main/res/layout/fragment_damage_list.xml | 32 ++ app/src/main/res/layout/fragment_home.xml | 33 +- app/src/main/res/layout/fragment_profile.xml | 338 +++++++++++++ app/src/main/res/navigation/nav_graph.xml | 5 + app/src/main/res/values/strings.xml | 13 + 24 files changed, 1016 insertions(+), 515 deletions(-) create mode 100644 app/src/main/java/com/example/fieldagent/data/models/responses/SelectCategoryData.kt create mode 100644 app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragment.kt create mode 100644 app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragmentVM.kt create mode 100644 app/src/main/res/drawable/profile.xml create mode 100644 app/src/main/res/layout/fragment_profile.xml 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 index 4d0f933..b00e5c1 100644 --- a/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt +++ b/app/src/main/java/com/example/fieldagent/data/apis/WebService.kt @@ -3,6 +3,7 @@ package com.example.fieldagent.data.apis import com.example.fieldagent.data.models.responses.* import com.example.fieldagent.data.network.responseUtil.ApiResponse +import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Call import retrofit2.http.* @@ -12,108 +13,14 @@ interface WebService { private const val LOGIN = "auth/login" private const val INSPECTIONS = "inspections" - private const val DAMAGES = "Damages" + private const val DAMAGES = "damages" private const val RESTROOM_LIST = "restroom-conditions" private const val ITEM_LIST = "combined-list" private const val CATEGORY = "categories" private const val SELECT_CATEGORY = "categories" private const val SUB_CATEGORY = "subcategories" - 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 USER = "users" - 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" } @@ -140,7 +47,7 @@ interface WebService { @Multipart @POST(DAMAGES) - fun createDamage(@PartMap map: HashMap): Call + fun createDamage(@PartMap map: HashMap,@Part images: List): Call @DELETE("$INSPECTIONS/{id}") @@ -153,8 +60,9 @@ interface WebService { @DELETE("$DAMAGES/{id}") fun deleteDamage(@Path("id") id: String): Call + @Multipart @PUT("$DAMAGES/{id}") - fun updateDamage(@Path("id") id: String): Call> + fun updateDamage(@Path("id") id: String,@PartMap map: HashMap,@Part images: List): Call @GET(RESTROOM_LIST) @@ -164,346 +72,9 @@ interface WebService { fun getCategoryList(): Call @GET(SELECT_CATEGORY) - fun getSelectCategoryList(@QueryMap hashMap: Map): Call + fun getSelectCategoryList(@QueryMap hashMap: Map): Call - @GET(SUB_CATEGORY) - fun getSubCategoryList(@QueryMap hashMap: Map): 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>*/ + @PUT(USER) + fun updateProfile(@FieldMap hashMap: HashMap): Call } \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/data/models/responses/ItemList.kt b/app/src/main/java/com/example/fieldagent/data/models/responses/ItemList.kt index 4d369a7..7e2841a 100644 --- a/app/src/main/java/com/example/fieldagent/data/models/responses/ItemList.kt +++ b/app/src/main/java/com/example/fieldagent/data/models/responses/ItemList.kt @@ -1,5 +1,7 @@ package com.example.fieldagent.data.models.responses +import com.google.gson.annotations.SerializedName + data class ItemList ( val status: Long? = null, @@ -10,6 +12,8 @@ data class ItemList ( data class DataItem ( val categories: List? = null, + + @SerializedName("sub_categories") val subCategories: List? = null, val units: List? = null ) @@ -21,6 +25,8 @@ data class Category ( data class SubCategory ( val id: Long? = null, + + @SerializedName("category_id") val categoryID: Long? = null, val name: String? = null, val unit: String? = null diff --git a/app/src/main/java/com/example/fieldagent/data/models/responses/SelectCategoryData.kt b/app/src/main/java/com/example/fieldagent/data/models/responses/SelectCategoryData.kt new file mode 100644 index 0000000..0169e84 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/data/models/responses/SelectCategoryData.kt @@ -0,0 +1,40 @@ +package com.example.fieldagent.data.models.responses + +import com.google.gson.annotations.SerializedName + +data class SelectCategoryData ( + val status: Long? = null, + val success: Boolean? = null, + val message: String? = null, + val data: CategoryData? = null +) + +data class CategoryData ( + val categories: List? = null, +) + +data class CategoryFlow ( + val id: Long? = null, + val name: String? = null, + val isActive: Boolean? = null, + val isDeleted: Boolean? = null, + val createdAt: String? = null, + val updatedAt: String? = null, + val subCategories: List? = null +) + +data class SubCategoryData ( + val id: Long? = null, + val categoryID: Long? = null, + val name: String? = null, + val unit: String? = null, + val price: Long? = null, + val specifications: String? = null, + val isActive: Boolean? = null, + val isDeleted: Boolean? = null, + val createdAt: String? = null, + val updatedAt: String? = null +) + + + 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 index 47fe443..7bea051 100644 --- 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 @@ -1,5 +1,6 @@ package com.example.fieldagent.data.models.responses +import com.google.gson.annotations.SerializedName import java.io.Serializable data class UserData ( @@ -7,20 +8,22 @@ data class UserData ( val success: Boolean? = null, val message: String? = null, val data: Data? = null -):Serializable +) data class Data ( val id: Long? = null, val name: String? = null, val email: String? = null, + + @SerializedName("phone_number") val phoneNumber: String? = null, val designation: String? = null, val createdAt: String? = null, val updatedAt: String? = null, val tokens: Tokens? = null -):Serializable +) data class Tokens ( val accessToken: String? = null, val refreshToken: String? = null -):Serializable +) 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 index 3a0ad57..00814b7 100644 --- a/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/addsite/AddSiteFragment.kt @@ -295,7 +295,7 @@ class AddSiteFragment : Fragment() { binding.etApproximateNumber.showSnackBar(getString(R.string.please_enter_approximate_number_worshippers)) } binding.etNumberRestroom.text.toString().isEmpty() -> { - binding.etApproximateNumber.showSnackBar(getString(R.string.please_number_of_restrooms)) + binding.etNumberRestroom.showSnackBar(getString(R.string.please_number_of_restrooms)) } imageUri==null -> { binding.rvImage.showSnackBar(getString(R.string.please_select_image)) 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 index 33adf2a..70bac60 100644 --- a/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragment.kt @@ -9,6 +9,7 @@ import android.os.Bundle import android.os.Environment import android.text.Editable import android.text.TextWatcher +import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View @@ -19,6 +20,7 @@ import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.FileProvider +import androidx.core.net.toUri import androidx.fragment.app.viewModels import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController @@ -26,18 +28,30 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.consultantapp.data.network.responseUtil.Status import com.example.fieldagent.R import com.example.fieldagent.data.models.responses.Category -import com.example.fieldagent.data.models.responses.SubCategory +import com.example.fieldagent.data.models.responses.Damage +import com.example.fieldagent.data.models.responses.SubCategoryData import com.example.fieldagent.data.network.ApisRespHandler import com.example.fieldagent.databinding.FragmentDamageDetailsBinding import com.example.fieldagent.databinding.SelectPhotoBinding import com.example.fieldagent.ui.damagedetails.adapter.DamageDetailsAdapter +import com.example.fieldagent.utils.IMAGE_BASE_URL import com.example.fieldagent.utils.PrefsManager import com.example.fieldagent.utils.dialogs.ProgressDialog +import com.example.fieldagent.utils.getRequestBody import com.example.fieldagent.utils.gone import com.example.fieldagent.utils.isConnectedToInternet import com.example.fieldagent.utils.showSnackBar +import com.example.fieldagent.utils.uriToFile import com.example.fieldagent.utils.visible +import com.google.gson.Gson import dagger.hilt.android.AndroidEntryPoint +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MultipartBody +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import org.json.JSONArray +import org.json.JSONObject import java.io.File import java.text.SimpleDateFormat import java.util.Date @@ -65,15 +79,18 @@ class DamageDetailsFragment : Fragment() { private lateinit var permissionLauncher: ActivityResultLauncher> private var imageUri: Uri? = null - private var imageList= ArrayList() + private var imageList= ArrayList() private var categoryList=ArrayList() - private var subCategoryList=ArrayList() + private var subCategoryList=ArrayList() private var unitList=ArrayList() private var inspectionId=""; + private var selectSubId=""; + private var from="add"; private var clickPosition=-1; + private var damageId:String=""; override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -97,23 +114,59 @@ class DamageDetailsFragment : Fragment() { private fun initialize(){ progressDialog = ProgressDialog(requireActivity()) - inspectionId = arguments?.getString("id").toString() - viewModel.getCategoryList() + + if(arguments?.getString("from")=="add") + { + inspectionId = arguments?.getString("id").toString() + viewModel.getCategoryList() + }else{ + from="edit" + val jsonString = arguments?.getString("damageData") + val damageData = Gson().fromJson(jsonString, Damage::class.java) + inspectionId = arguments?.getString("id").toString() + viewModel.getCategoryList() + + Log.e("CheckkkkDama==>","${damageData}") + binding.etItemValue.setText(damageData.itemValue.toString()) + binding.etItemValue.setSelection(damageData.itemValue.toString().length) + binding.etItemQuantity.setText(damageData.itemQuantity.toString()) + binding.autoCompleteMain.setText(damageData.categoryName,false) + damageId=damageData.id.toString() + if(damageData.images!=null) + { + if(damageData.images.isNotEmpty()) + { + + for ((index, item) in damageData.images.withIndex()) { + + imageList.add(IMAGE_BASE_URL +item) + } + } + } + val hashMap = HashMap() + hashMap["id"] = damageData.categoryID.toString() + viewModel.getSelectCategoryList(hashMap) + } + } private fun setAdapter() { - for (i in 0 until 5) { - imageList.add(null) // Add empty slots (or use placeholder URIs) + if(imageList.isNotEmpty()){ + for (i in 0 until 5-imageList.size) { + imageList.add(null) // Add empty slots (or use placeholder URIs) + } + }else{ + for (i in 0 until 5) { + imageList.add(null) // Add empty slots (or use placeholder URIs) + } } + adapter = DamageDetailsAdapter(imageList,this) binding.rvImage.layoutManager= LinearLayoutManager(requireActivity(), LinearLayoutManager.HORIZONTAL, false) binding.rvImage.adapter = adapter - - - } @@ -140,7 +193,7 @@ class DamageDetailsFragment : Fragment() { imageUri?.let { val positionToReplace = imageList.indexOfFirst { it == null } if (positionToReplace != -1) { - imageList[positionToReplace] = imageUri + imageList[positionToReplace] = imageUri.toString() adapter.notifyItemChanged(positionToReplace) } @@ -155,8 +208,12 @@ class DamageDetailsFragment : Fragment() { val positionToReplace = imageList.indexOfFirst { it == null } if (positionToReplace != -1) { - imageList[positionToReplace] = uri + imageList[positionToReplace] = uri.toString() adapter.notifyItemChanged(positionToReplace) + + + val currentFocus = requireActivity().currentFocus + currentFocus?.clearFocus() } } @@ -192,6 +249,10 @@ class DamageDetailsFragment : Fragment() { }) binding.btnReport.setOnClickListener { when{ + + binding.autoCompleteMain.text.toString()==getString(R.string.please_select_category) -> { + binding.etItemQuantity.showSnackBar(getString(R.string.please_select_category)) + } binding.etItemQuantity.text.toString().isEmpty() -> { binding.etItemQuantity.showSnackBar(getString(R.string.please_enter_item_quantity)) } @@ -200,15 +261,63 @@ class DamageDetailsFragment : Fragment() { binding.etItemValue.showSnackBar(getString(R.string.please_enter_item_value)) } - imageList.isEmpty() -> { + imageList.all { it == null }->{ binding.rvImage.showSnackBar(getString(R.string.please_upload_at_least_one_image)) } isConnectedToInternet(requireActivity(), true) -> { + val hashMap = HashMap() + hashMap["inspection_id"] = getRequestBody(inspectionId) + hashMap["subCategory_id"] = getRequestBody(selectSubId) + hashMap["item_quantity"] = getRequestBody(binding.etItemQuantity.text) + hashMap["item_value"] = getRequestBody(binding.etItemValue.text.toString().replace(Regex("[^\\d.]"), "")) + + val imageParts = ArrayList() + + val uriList=ArrayList(); + val urlList=ArrayList(); + for ((index, data) in imageList.withIndex()) { + if (data != null) { + if (data.startsWith("content://") || data.startsWith("file://")) { + uriList.add(data.toUri()) + } else if(data.startsWith("https://")){ + val cleaned = data.removePrefix(IMAGE_BASE_URL) + urlList.add(cleaned) + } + } + } + + + for ((index, uri) in uriList.withIndex()) { + val file = + uri?.let { it1 -> uriToFile(it1, requireContext()) } + val requestFile = file?.asRequestBody("image/*".toMediaType()) + val part = requestFile?.let { it1 -> + MultipartBody.Part.createFormData( + name = "attachment", + filename = file.name, + body = it1 + ) + } + if (part != null) { + imageParts.add(part) + } + } + + + if (from=="edit") + { + val jsonArray = JSONArray(urlList) + hashMap["images"] = jsonArray.toString().toRequestBody("application/json".toMediaType()) + viewModel.editDamage(damageId,hashMap,imageParts) + }else{ + viewModel.addDamage(hashMap,imageParts) + } + + } } - } binding.autoCompleteMain.setOnItemClickListener { parent, view, position, id -> @@ -221,6 +330,7 @@ class DamageDetailsFragment : Fragment() { binding.autoCompleteSub.setOnItemClickListener { parent, view, position, id -> binding.autoCompleteUnits.setText(subCategoryList[position].unit, false) + selectSubId=subCategoryList[position].id.toString() } @@ -294,13 +404,11 @@ class DamageDetailsFragment : Fragment() { val tempData=it.data?.data - - if(tempData?.subCategories!!.isNotEmpty()) + if(tempData?.categories!=null && tempData.categories.isNotEmpty() && tempData.categories[0].subCategories!=null && tempData.categories[0].subCategories!!.isNotEmpty()) { - tempData.subCategories.let { it1 -> subCategoryList.addAll(it1) } + tempData.categories[0].subCategories?.let { it1 -> subCategoryList.addAll(it1) } binding.llUnits.visible() binding.llSubItem.visible() - val subCategoryNames = subCategoryList.map { it.name } val adapter2 = ArrayAdapter(requireActivity(), R.layout.dropdown_item, subCategoryNames) @@ -312,6 +420,7 @@ class DamageDetailsFragment : Fragment() { } binding.autoCompleteSub.setText(subCategoryNames.first(), false) binding.autoCompleteUnits.setText(subCategoryList[0].unit, false) + selectSubId=subCategoryList[0].id.toString() }else{ binding.llUnits.gone() binding.llSubItem.gone() diff --git a/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragmentVM.kt b/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragmentVM.kt index 1e01934..4fb2b2d 100644 --- a/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragmentVM.kt +++ b/app/src/main/java/com/example/fieldagent/ui/damagedetails/DamageDetailsFragmentVM.kt @@ -3,11 +3,13 @@ package com.example.fieldagent.ui.damagedetails import androidx.lifecycle.ViewModel import com.example.fieldagent.data.apis.WebService import com.example.fieldagent.data.models.responses.ItemList +import com.example.fieldagent.data.models.responses.SelectCategoryData import com.example.fieldagent.data.models.responses.SimpleResponseData 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 okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.Call import retrofit2.Callback @@ -20,13 +22,40 @@ class DamageDetailsFragmentVM @Inject constructor(private val webService: WebSe val addDamage by lazy { SingleLiveEvent>() } val categoryList by lazy { SingleLiveEvent>() } - val selectCategoryList by lazy { SingleLiveEvent>() } + val selectCategoryList by lazy { SingleLiveEvent>() } - fun addDamage(hashMap: HashMap) { + fun addDamage(hashMap: HashMap, imageParts: ArrayList) { addDamage.value = Resource.loading() - webService.createDamage(hashMap) + webService.createDamage(hashMap,imageParts) + .enqueue(object : Callback { + + override fun onResponse(call: Call, + response: Response + ) { + if (response.isSuccessful) { + addDamage.value = Resource.success(response.body()) + + } else { + addDamage.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call, throwable: Throwable) { + addDamage.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + + + fun editDamage(id: String,hashMap: HashMap, imageParts: ArrayList,) { + addDamage.value = Resource.loading() + + webService.updateDamage(id,hashMap,imageParts) .enqueue(object : Callback { override fun onResponse(call: Call, @@ -80,10 +109,10 @@ class DamageDetailsFragmentVM @Inject constructor(private val webService: WebSe selectCategoryList.value = Resource.loading() webService.getSelectCategoryList(hashMap) - .enqueue(object : Callback { + .enqueue(object : Callback { - override fun onResponse(call: Call, - response: Response + override fun onResponse(call: Call, + response: Response ) { if (response.isSuccessful) { selectCategoryList.value = Resource.success(response.body()) @@ -95,7 +124,7 @@ class DamageDetailsFragmentVM @Inject constructor(private val webService: WebSe } } - override fun onFailure(call: Call, throwable: Throwable) { + override fun onFailure(call: Call, throwable: Throwable) { selectCategoryList.value = Resource.error(ApiUtils.failure(throwable)) } 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 index 278dd69..25178b6 100644 --- 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 @@ -10,22 +10,34 @@ import com.example.fieldagent.databinding.DamageImageAdapterBinding import com.example.fieldagent.ui.damagedetails.DamageDetailsFragment import com.example.fieldagent.utils.gone import com.example.fieldagent.utils.visible +import androidx.core.net.toUri class DamageDetailsAdapter( - val imageList: ArrayList, + val imageList: ArrayList, val damageDetailsFragment: DamageDetailsFragment ) : RecyclerView.Adapter() { class DamageViewHolder(val binding: DamageImageAdapterBinding) : RecyclerView.ViewHolder(binding.root) { - fun bind(imageUrl: Uri) { + fun bind(imageUrl: String) { binding.rlUploadImage.gone() binding.cardImage.visible() binding.ivCloseImage.visible() - Glide.with(binding.root.context) - .load(imageUrl) - .into(binding.ivSetImage) // Assuming you have an ImageView with id ivDamageImage in your layout + + + val context = binding.root.context + + val uri = if (imageUrl.startsWith("content://") || imageUrl.startsWith("file://")) { + imageUrl.toUri() + } else { + imageUrl + } + + Glide.with(context) + .load(uri) + .into(binding.ivSetImage) + } } 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 index d3e27bd..6709f6a 100644 --- a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragment.kt @@ -15,7 +15,11 @@ import com.example.fieldagent.databinding.FragmentDamageListBinding import com.example.fieldagent.ui.damagelist.adapter.DamageListAdapter import com.example.fieldagent.utils.PrefsManager import com.example.fieldagent.utils.dialogs.ProgressDialog +import com.example.fieldagent.utils.gone +import com.example.fieldagent.utils.hideShowView import com.example.fieldagent.utils.showConfirmDialog +import com.example.fieldagent.utils.visible +import com.google.gson.Gson import dagger.hilt.android.AndroidEntryPoint import java.util.HashMap import javax.inject.Inject @@ -61,7 +65,7 @@ class DamageListFragment : Fragment() { private fun initialize(){ progressDialog = ProgressDialog(requireActivity()) - adapter = DamageListAdapter() + adapter = DamageListAdapter(this) binding.rvDamageList.adapter = adapter inspectionId = arguments?.getString("id").toString() @@ -87,6 +91,15 @@ class DamageListFragment : Fragment() { val tempList = it.data?.data?.inspections ?: emptyList() + if(tempList[0].damages==null || tempList[0].damages!!.isEmpty()) + { + + binding.clNoData.visible() + binding.btnExportPdf.gone() + }else{ + binding.clNoData.gone() + binding.btnExportPdf.visible() + } tempList[0].damages?.let { it1 -> adapter.submitList(it1) binding.damageCount.text=String.format("%02d", it1.size) @@ -104,6 +117,43 @@ class DamageListFragment : Fragment() { } } }) + + viewModel.deleteDamage.observe(requireActivity(), Observer { + it ?: return@Observer + when (it.status) { + Status.SUCCESS -> { + progressDialog.setLoading(false) + if(clickDeletePos!=-1){ + + adapter.mainList.removeAt(clickDeletePos) + adapter.notifyDataSetChanged() + + clickDeletePos=-1 + + if(adapter.mainList.isEmpty()) + { + binding.clNoData.visible() + binding.btnExportPdf.gone() + }else{ + binding.clNoData.gone() + binding.btnExportPdf.visible() + } + + binding.damageCount.text=String.format("%02d", adapter.mainList.size) + + } + + } + Status.ERROR -> { + + progressDialog.setLoading(false) + ApisRespHandler.handleError(it.error, requireActivity()) + } + Status.LOADING -> { + progressDialog.setLoading(true) + } + } + }) } private fun listener(){ @@ -113,6 +163,7 @@ class DamageListFragment : Fragment() { val bundle = Bundle().apply { putString("id", inspectionId) + putString("from", "add") } findNavController().navigate(R.id.damageDeatilsFragment, bundle) } @@ -125,12 +176,19 @@ class DamageListFragment : Fragment() { fun clickItem(pos: Int) { - // findNavController().navigate(R.id.damageListFragment, bundle) + val gson = Gson() + val jsonString = gson.toJson(adapter.mainList[pos]) + val bundle = Bundle().apply { + putString("damageData", jsonString) + putString("id", inspectionId) + putString("from", "edit") + } + findNavController().navigate(R.id.damageDeatilsFragment, bundle) } - fun clickDeleteItem(pos: Int,) { + fun clickDeleteItem(pos: Int, id: String,) { - /* if (pos < 0 || pos >= items.size) { + if (pos < 0 ) { return } clickDeletePos=pos @@ -139,9 +197,10 @@ class DamageListFragment : Fragment() { requireContext().showConfirmDialog( title = getString(R.string.are_you_sure_you_want_to_delete) ) { - viewModel.deleteInspection(items[pos].id.toString()) + viewModel.deleteInspection(id) } -*/ + + } override fun onDestroyView() { diff --git a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragmentVM.kt b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragmentVM.kt index f6612ff..7769bee 100644 --- a/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragmentVM.kt +++ b/app/src/main/java/com/example/fieldagent/ui/damagelist/DamageListFragmentVM.kt @@ -5,6 +5,7 @@ import com.example.fieldagent.data.apis.WebService import com.example.fieldagent.data.models.responses.InspectionData import com.example.fieldagent.data.models.responses.InspectionList import com.example.fieldagent.data.models.responses.RoomConditionData +import com.example.fieldagent.data.models.responses.SimpleResponseData import com.example.fieldagent.data.network.responseUtil.ApiUtils import com.example.fieldagent.data.network.responseUtil.Resource import com.example.fieldagent.di.SingleLiveEvent @@ -20,6 +21,7 @@ import javax.inject.Inject class DamageListFragmentVM @Inject constructor(private val webService: WebService) : ViewModel() { val damages by lazy { SingleLiveEvent>() } + val deleteDamage by lazy { SingleLiveEvent>() } fun getDamagesList(hashMap: HashMap) { @@ -48,5 +50,31 @@ class DamageListFragmentVM @Inject constructor(private val webService: WebServi }) } + fun deleteInspection(id:String) { + deleteDamage.value = Resource.loading() + + webService.deleteDamage(id) + .enqueue(object : Callback { + + override fun onResponse(call: Call, + response: Response + ) { + if (response.isSuccessful) { + deleteDamage.value = Resource.success(response.body()) + + } else { + deleteDamage.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call, throwable: Throwable) { + deleteDamage.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + } \ 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 index f2e27a0..9ff19cf 100644 --- 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 @@ -1,14 +1,15 @@ package com.example.fieldagent.ui.damagelist.adapter -import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.example.fieldagent.R import com.example.fieldagent.data.models.responses.Damage import com.example.fieldagent.databinding.DamageViewAdapterBinding +import com.example.fieldagent.ui.damagelist.DamageListFragment -class DamageListAdapter() : RecyclerView.Adapter() { +class DamageListAdapter(val damageListFragment: DamageListFragment) : RecyclerView.Adapter() { var mainList = ArrayList() @@ -40,6 +41,15 @@ class DamageListAdapter() : RecyclerView.Adapter holder.binding.txtTotal.text="$ "+total.toString() holder.binding.txtImage.text=damage.images?.size.toString() + holder.binding.ivDelete.setOnClickListener { + damageListFragment.clickDeleteItem(position,damage.id.toString()) + } + holder.binding.txtDamage.setText(holder.binding.root.context.getString(R.string.damage)+" ${position+1}") + + holder.binding.ivEdit.setOnClickListener { + damageListFragment.clickItem(position) + } + } 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 index 47947b7..d1b2c5d 100644 --- a/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt +++ b/app/src/main/java/com/example/fieldagent/ui/homescreen/HomeFragment.kt @@ -136,12 +136,9 @@ class HomeFragment : Fragment() { binding.llBtn.setOnClickListener { findNavController().navigate(R.id.addSiteFragment) } - binding.llLogoutBtn.setOnClickListener { + binding.ivProfile.setOnClickListener { + findNavController().navigate(R.id.profileFragment) - prefsManager.removeAll() - val intent = Intent(requireActivity(), LoginActivity::class.java) - startActivity(intent) - requireActivity().finish() } 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 index f28684f..da49db6 100644 --- a/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt +++ b/app/src/main/java/com/example/fieldagent/ui/login/LoginActivity.kt @@ -21,6 +21,7 @@ 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 com.google.gson.Gson import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -82,10 +83,16 @@ class LoginActivity : AppCompatActivity() { when (it.status) { Status.SUCCESS -> { progressDialog.setLoading(false) - // prefsManager.save(USER_DATA, it.data?.data) + + val gson = Gson() + val jsonString = gson.toJson(it.data?.data) + prefsManager.saveString(USER_DATA,jsonString) + prefsManager.saveString(TOKEN,it.data?.data?.tokens?.accessToken.toString()) + + val intent = Intent(this, HomeActivity::class.java) startActivity(intent) finish() diff --git a/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragment.kt b/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragment.kt new file mode 100644 index 0000000..b8c070f --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragment.kt @@ -0,0 +1,160 @@ +package com.example.fieldagent.ui.profile + +import android.app.AlertDialog +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer +import androidx.navigation.fragment.findNavController +import com.consultantapp.data.network.responseUtil.Status +import com.example.fieldagent.R +import com.example.fieldagent.data.models.responses.Data +import com.example.fieldagent.data.network.ApisRespHandler +import com.example.fieldagent.databinding.FragmentDamageListBinding +import com.example.fieldagent.databinding.FragmentProfileBinding +import com.example.fieldagent.ui.damagelist.DamageListFragmentVM +import com.example.fieldagent.ui.damagelist.adapter.DamageListAdapter +import com.example.fieldagent.ui.login.LoginActivity +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.gone +import com.example.fieldagent.utils.isConnectedToInternet +import com.example.fieldagent.utils.showConfirmDialog +import com.example.fieldagent.utils.showSnackBar +import com.example.fieldagent.utils.showUpdateDialog +import com.example.fieldagent.utils.visible +import com.google.gson.Gson +import dagger.hilt.android.AndroidEntryPoint +import java.util.HashMap +import javax.inject.Inject + + +@AndroidEntryPoint +class ProfileFragment : Fragment() { + + + private var _binding: FragmentProfileBinding? = null + + private val binding get() = _binding!! + + private val viewModel: ProfileFragmentVM by viewModels() + + @Inject + lateinit var prefsManager: PrefsManager + private lateinit var progressDialog: ProgressDialog + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProfileBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + + initialize() + listener() + bindObservers() + + } + + private fun initialize(){ + val jsonString = prefsManager.getString(USER_DATA, "") + val userData = Gson().fromJson(jsonString, Data::class.java) + + binding.etName.setText(userData.name) + binding.etEmail.setText(userData.email) + binding.etPhone.setText(userData.phoneNumber) + } + + + + private fun listener(){ + + binding.llLogoutBtn.setOnClickListener { + + + prefsManager.removeAll() + + val intent = Intent(requireContext(), LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + + } + + binding.btnAdd.setOnClickListener { + + when{ + binding.etName.text.isEmpty()->{ + binding.etName.showSnackBar(getString(R.string.please_enter_agent_name)) + } + binding.etPassword.text.toString().isEmpty()->{ + binding.etPassword.showSnackBar(getString(R.string.please_enter_password)) + } + + binding.etConfirmPassword.text.toString().isEmpty()->{ + binding.etConfirmPassword.showSnackBar(getString(R.string.please_enter_confirm_password)) + } + binding.etPassword.text.toString() != binding.etConfirmPassword.text.toString()->{ + binding.etConfirmPassword.showSnackBar(getString(R.string.password_and_confirm_password_not_match)) + } + isConnectedToInternet(requireActivity(), true) -> { + val hashMap = HashMap() + hashMap["name"] = binding.etName.text.toString() + hashMap["password"] = binding.etPassword.text.toString() + + viewModel.updateProfile(hashMap) + } + + + } + } + } + + + private fun bindObservers(){ + viewModel.profile.observe(requireActivity(), Observer { + it ?: return@Observer + when (it.status) { + Status.SUCCESS -> { + progressDialog.setLoading(false) + + requireContext().showUpdateDialog( + title = getString(R.string.profile_updated_successfully) + ) { + prefsManager.removeAll() + + val intent = Intent(requireContext(), LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + } + + } + Status.ERROR -> { + progressDialog.setLoading(false) + ApisRespHandler.handleError(it.error, requireActivity()) + } + Status.LOADING -> { + progressDialog.setLoading(true) + } + } + }) + + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragmentVM.kt b/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragmentVM.kt new file mode 100644 index 0000000..a2ce770 --- /dev/null +++ b/app/src/main/java/com/example/fieldagent/ui/profile/ProfileFragmentVM.kt @@ -0,0 +1,53 @@ +package com.example.fieldagent.ui.profile + +import androidx.lifecycle.ViewModel +import com.example.fieldagent.data.apis.WebService +import com.example.fieldagent.data.models.responses.InspectionData +import com.example.fieldagent.data.models.responses.SimpleResponseData +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 java.util.HashMap +import javax.inject.Inject + + +@HiltViewModel +class ProfileFragmentVM @Inject constructor(private val webService: WebService) : ViewModel() { + + val profile by lazy { SingleLiveEvent>() } + + + fun updateProfile(hashMap: HashMap) { + profile.value = Resource.loading() + + webService.updateProfile(hashMap) + .enqueue(object : Callback { + + override fun onResponse(call: Call, + response: Response + ) { + if (response.isSuccessful) { + profile.value = Resource.success(response.body()) + + } else { + profile.value = Resource.error( + ApiUtils.getError(response.code(), + response.errorBody()?.string())) + } + } + + override fun onFailure(call: Call, throwable: Throwable) { + profile.value = Resource.error(ApiUtils.failure(throwable)) + } + + }) + } + + + + +} \ 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 index 385f536..8916c08 100644 --- a/app/src/main/java/com/example/fieldagent/utils/GeneralFunction.kt +++ b/app/src/main/java/com/example/fieldagent/utils/GeneralFunction.kt @@ -20,6 +20,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.File +import androidx.core.net.toUri fun View.gone() { @@ -74,6 +75,17 @@ fun uriToFile(uri: Uri, context: Context): File? { return tempFile } +fun stringUriToFile(uri: String, context: Context): File? { + val uri = uri.toUri() + val inputStream = context.contentResolver.openInputStream(uri) ?: return null + val fileName = "temp_image_${System.currentTimeMillis()}.jpg" + val tempFile = File(context.cacheDir, fileName) + tempFile.outputStream().use { fileOut -> + inputStream.copyTo(fileOut) + } + return tempFile +} + fun Context.showConfirmDialog( title: String, @@ -101,6 +113,33 @@ fun Context.showConfirmDialog( } +fun Context.showUpdateDialog( + title: String, + onConfirm: () -> Unit +) { + val dialog = Dialog(this) + dialog.setCancelable(false) + dialog.setCanceledOnTouchOutside(false) + val binding = ConfirmDeleteDialogBinding.inflate(LayoutInflater.from(this)) + + binding.btnNo.gone() + binding.btnYes.setText(getString(R.string.ok)) + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) + dialog.setContentView(binding.root) + dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + + binding.tvTitle.text = title + + binding.btnYes.setOnClickListener { + onConfirm() + dialog.dismiss() + } + + + dialog.show() +} + + fun hideKeyboard(fragment: Fragment) { val inputMethodManager = fragment.requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val currentFocusView = fragment.activity?.currentFocus diff --git a/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt b/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt index ff9dde7..718b0dd 100644 --- a/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt +++ b/app/src/main/java/com/example/fieldagent/utils/PrefsManager.kt @@ -1,6 +1,7 @@ package com.example.fieldagent.utils import android.content.SharedPreferences +import android.util.Log import androidx.annotation.StringDef import com.google.gson.Gson import java.util.concurrent.atomic.AtomicBoolean @@ -29,11 +30,12 @@ class PrefsManager @Inject constructor(private val preferences: SharedPreference fun save(@PrefKey key: String, `object`: Any?) { if (`object` == null) { + Log.e("PrefsSave", "Attempted to save null object for key: $key") throw IllegalArgumentException("object is null") } - // Convert the provided object to JSON string - save(key, gson.toJson(`object`)) + + save(key, gson.toJson(`object`)) } diff --git a/app/src/main/res/drawable/profile.xml b/app/src/main/res/drawable/profile.xml new file mode 100644 index 0000000..12e714e --- /dev/null +++ b/app/src/main/res/drawable/profile.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_damage_details.xml b/app/src/main/res/layout/fragment_damage_details.xml index f2c8cf6..ab27899 100644 --- a/app/src/main/res/layout/fragment_damage_details.xml +++ b/app/src/main/res/layout/fragment_damage_details.xml @@ -224,8 +224,7 @@ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:layout_width="match_parent" android:layout_height="wrap_content" - app:endIconMode="custom" - app:endIconDrawable="@drawable/drop_down"> + > + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 30d4739..96eafd7 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -43,36 +43,19 @@ - - + android:id="@+id/ivProfile" + android:layout_width="@dimen/sp_50" + android:layout_height="@dimen/sp_40" + android:paddingTop="@dimen/dp_4" + android:paddingBottom="@dimen/dp_4" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:src="@drawable/profile"/> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +