added profiel section

This commit is contained in:
Aryankc2 2025-04-29 18:29:10 +05:30
parent e22ee1471e
commit baf0c5cbca
24 changed files with 1016 additions and 515 deletions

View file

@ -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<String, RequestBody>): Call<SimpleResponseData>
fun createDamage(@PartMap map: HashMap<String, RequestBody>,@Part images: List<MultipartBody.Part>): Call<SimpleResponseData>
@DELETE("$INSPECTIONS/{id}")
@ -153,8 +60,9 @@ interface WebService {
@DELETE("$DAMAGES/{id}")
fun deleteDamage(@Path("id") id: String): Call<SimpleResponseData>
@Multipart
@PUT("$DAMAGES/{id}")
fun updateDamage(@Path("id") id: String): Call<ApiResponse<UserData>>
fun updateDamage(@Path("id") id: String,@PartMap map: HashMap<String, RequestBody>,@Part images: List<MultipartBody.Part>): Call<SimpleResponseData>
@GET(RESTROOM_LIST)
@ -164,346 +72,9 @@ interface WebService {
fun getCategoryList(): Call<ItemList>
@GET(SELECT_CATEGORY)
fun getSelectCategoryList(@QueryMap hashMap: Map<String, String>): Call<ItemList>
fun getSelectCategoryList(@QueryMap hashMap: Map<String, String>): Call<SelectCategoryData>
@GET(SUB_CATEGORY)
fun getSubCategoryList(@QueryMap hashMap: Map<String, String>): Call<ItemList>
/*
@FormUrlEncoded
@POST(APP_VERSION)
fun appVersion(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<AppVersion>>
@FormUrlEncoded
@POST(UPDATE_NUMBER)
fun updateNumber(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(VERIFY_OTP)
fun verifyOtp(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(RESEND_OTP)
fun resendOtp(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(REGISTER)
fun register(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(FORGOT_PASSWORD)
fun forgotPassword(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(CHANGE_PASSWORD)
fun changePassword(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(PROFILE_UPDATE)
fun updateProfile(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(COMPLETE_CHAT)
fun completeChat(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(SEND_SMS)
fun sendSMS(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(SEND_EMAIL_OTP)
fun sendEmailOtp(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(EMAIL_VERIFY)
fun emailVerify(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@POST(LOGOUT)
fun logout(): Call<ApiResponse<UserData>>
@FormUrlEncoded
@POST(UPDATE_FCM_ID)
fun updateFcmId(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<UserData>>
@POST(CREATE_REQUEST)
fun createRequest(@Body createRequest: CreateRequest): Call<ApiResponse<CommonDataModel>>
@POST(CREATE_REQUEST_V2)
fun createRequestV2(@Body createRequest: CreateRequest): Call<ApiResponse<CommonDataModel>>
@POST(CONFIRM_REQUEST)
fun confirmRequest(@Body createRequest: CreateRequest): Call<ApiResponse<CommonDataModel>>
@POST(CONFIRM_REQUEST_V2)
fun confirmRequestV2(@Body createRequest: CreateRequest): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_CARD)
fun addCard(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(UPDATE_CARD)
fun updateCard(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(DELETE_CARD)
fun deleteCard(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_MONEY)
fun addMoney(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@Multipart
@POST(UPLOAD_IMAGE)
fun uploadFile(@PartMap map: HashMap<String, RequestBody>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_REVIEW)
fun addReview(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<Any>>
@FormUrlEncoded
@POST(REQUEST_USER_APPROVE)
fun approveWorkingHour(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<Any>>
@FormUrlEncoded
@POST(ENROLL_USER)
fun enrollUser(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(CLASS_JOIN)
fun joinClass(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ORDER_CREATE)
fun orderCreate(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(HYPER_PAY_COMPLETE_DONE)
fun hyperPayCompleteTrans(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<Any>>
@FormUrlEncoded
@POST(CANCEL_REQUEST_V2)
fun cancelRequest(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(CALL_STATUS)
fun callStatus(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(PACK_DETAIL)
fun packDetail(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(SUBSCRIPTION_DETAIL)
fun subscriptionDetail(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(PURCHASE_PACK)
fun purchasePack(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(SUBSCRIPTION_PACK)
fun subscriptionPack(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_FAVORITE)
fun addFavorite(@Path("feed_id") feed_id: String,
@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_LIKE)
fun addLike(@Path("feed_id") feed_id: String,
@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_COMMENT)
fun addComment(@Path("feed_id") feed_id: String,
@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(RAZOR_PAY_WEBHOOK)
fun razorPayWebhook(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ASK_QUESTIONS)
fun askQuestion(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(WATER_LIMIT)
fun setDailyLimit(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<WaterIntake>>
@FormUrlEncoded
@POST(PROTEIN_LIMIT)
fun setProteinDailyLimit(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<WaterIntake>>
@FormUrlEncoded
@POST(DRINK_WATER)
fun setWaterIntake(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<WaterIntake>>
@FormUrlEncoded
@POST(DRINK_PROTEIN)
fun setProteinIntake(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<WaterIntake>>
@FormUrlEncoded
@POST(ADD_FAMILY)
fun addFamily(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@POST(UPDATE_SYMPTOM)
fun updateSymptom(@Body updateSymptom: UpdateSymptom): Call<ApiResponse<CommonDataModel>>
@POST(CARE_PLANS)
fun carePlans(@Body updateSymptom: UpdateSymptom): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(ADD_BANK)
fun addBank(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<CommonDataModel>>
*//*GET*//*
@GET(CLIENT_DETAILS)
fun clientDetails(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<AppVersion>>
@GET(COUNTRY_DATA)
fun countryData(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(PREFERENCES)
fun preferences(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(HOME)
fun home(): Call<ApiResponse<CommonDataModel>>
@GET(REQUESTS)
fun request(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(REQUEST_DETAIL)
fun requestDetail(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(DOCTOR_LIST)
fun doctorList(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(DOCTOR_LIST_V2)
fun doctorListV2(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(BANNERS)
fun banners(): Call<ApiResponse<CommonDataModel>>
@GET(DOCTOR_DETAIL)
fun doctorDetails(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(REVIEW_LIST)
fun reviewList(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(WALLET_HISTORY)
fun walletHistory(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(CARD_LISTING)
fun cardListing(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(WALLET)
fun wallet(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(CHAT_LISTING)
fun getChatListing(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(CHAT_MESSAGES)
fun getChatMessage(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(NOTIFICATIONS)
fun notifications(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(FEEDS)
fun getFeeds(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(FEEDS_COMMENTS)
fun getFeedsComment(@Path("feed_id") feed_id: String,
@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(VIEW_FEEDS)
fun viewFeeds(@Path("feed_id") feed_id: String): Call<ApiResponse<CommonDataModel>>
@GET(CATEGORIES)
fun categories(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(CLASSES)
fun classesList(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(CLASS_DETAIL)
fun classDetail(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<ClassData>>
@GET(GET_FILTERS)
fun getFilters(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(SERVICES)
fun services(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(GET_SLOTS)
fun getSlots(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(PAGES)
fun getPages(): Call<ApiResponse<CommonDataModel>>
@GET(COUPONS)
fun coupons(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(PACK_SUB)
fun packSub(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(SUBSCRIPTIONS)
fun subscriptions(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(DIRECTIONS)
fun directions(@QueryMap hashMap: Map<String, String>): Call<Direction>
@GET(ASK_QUESTIONS)
fun getQuestions(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(ASK_QUESTIONS_DETAIL)
fun getQuestionsDetails(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(WATER_LIMIT)
fun getWaterLimit(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<WaterIntake>>
@GET(PROTEIN_LIMIT)
fun getProteinIntake(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<WaterIntake>>
@GET(REQUEST_CHECK)
fun requestCheck(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(SYMPTOM)
fun symptom(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(TIERS)
fun carePlanTier(): Call<ApiResponse<CommonDataModel>>
@POST(EXTRA_PAYMENT)
fun payExtra(@Body extraPayment: Extra_payment): Call<ApiResponse<CommonDataModel>>
@GET(BANK_ACCOUNTS)
fun bankAccounts(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@GET(GET_MEDICAL_HISTORY)
fun getMedicalHistory(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
*//*PUT API*//*
@FormUrlEncoded
@PUT(WORKING_HOURS)
fun workingHours(@FieldMap hashMap: HashMap<String, String>): Call<ApiResponse<Any>>
@GET(CONTACT_LIST)
fun contactList(@QueryMap hashMap: Map<String, String>): Call<ApiResponse<CommonDataModel>>
@POST(CONTACT_ADD)
fun addContact(@Body contactList: ContactEmergency): Call<ApiResponse<CommonDataModel>>
@FormUrlEncoded
@POST(CONTACT_DELETE)
fun deletContact(@FieldMap hashMap: HashMap<String, Any>): Call<ApiResponse<CommonDataModel>>
@POST(CONTACT_MESSAGE)
fun sendMessage(): Call<ApiResponse<CommonDataModel>>*/
@PUT(USER)
fun updateProfile(@FieldMap hashMap: HashMap<String, String>): Call<SimpleResponseData>
}

View file

@ -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<Category>? = null,
@SerializedName("sub_categories")
val subCategories: List<SubCategory>? = null,
val units: List<String>? = 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

View file

@ -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<CategoryFlow>? = 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<SubCategoryData>? = 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
)

View file

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

View file

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

View file

@ -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<Array<String>>
private var imageUri: Uri? = null
private var imageList= ArrayList<Uri?>()
private var imageList= ArrayList<String?>()
private var categoryList=ArrayList<Category>()
private var subCategoryList=ArrayList<SubCategory>()
private var subCategoryList=ArrayList<SubCategoryData>()
private var unitList=ArrayList<String>()
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<String, String>()
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<String, RequestBody>()
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<MultipartBody.Part>()
val uriList=ArrayList<Uri>();
val urlList=ArrayList<String>();
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()

View file

@ -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<Resource<SimpleResponseData>>() }
val categoryList by lazy { SingleLiveEvent<Resource<ItemList>>() }
val selectCategoryList by lazy { SingleLiveEvent<Resource<ItemList>>() }
val selectCategoryList by lazy { SingleLiveEvent<Resource<SelectCategoryData>>() }
fun addDamage(hashMap: HashMap<String, RequestBody>) {
fun addDamage(hashMap: HashMap<String, RequestBody>, imageParts: ArrayList<MultipartBody.Part>) {
addDamage.value = Resource.loading()
webService.createDamage(hashMap)
webService.createDamage(hashMap,imageParts)
.enqueue(object : Callback<SimpleResponseData> {
override fun onResponse(call: Call<SimpleResponseData>,
response: Response<SimpleResponseData>
) {
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<SimpleResponseData>, throwable: Throwable) {
addDamage.value = Resource.error(ApiUtils.failure(throwable))
}
})
}
fun editDamage(id: String,hashMap: HashMap<String, RequestBody>, imageParts: ArrayList<MultipartBody.Part>,) {
addDamage.value = Resource.loading()
webService.updateDamage(id,hashMap,imageParts)
.enqueue(object : Callback<SimpleResponseData> {
override fun onResponse(call: Call<SimpleResponseData>,
@ -80,10 +109,10 @@ class DamageDetailsFragmentVM @Inject constructor(private val webService: WebSe
selectCategoryList.value = Resource.loading()
webService.getSelectCategoryList(hashMap)
.enqueue(object : Callback<ItemList> {
.enqueue(object : Callback<SelectCategoryData> {
override fun onResponse(call: Call<ItemList>,
response: Response<ItemList>
override fun onResponse(call: Call<SelectCategoryData>,
response: Response<SelectCategoryData>
) {
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<ItemList>, throwable: Throwable) {
override fun onFailure(call: Call<SelectCategoryData>, throwable: Throwable) {
selectCategoryList.value = Resource.error(ApiUtils.failure(throwable))
}

View file

@ -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<Uri?>,
val imageList: ArrayList<String?>,
val damageDetailsFragment: DamageDetailsFragment
) : RecyclerView.Adapter<DamageDetailsAdapter.DamageViewHolder>() {
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)
}
}

View file

@ -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() {

View file

@ -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<Resource<InspectionData>>() }
val deleteDamage by lazy { SingleLiveEvent<Resource<SimpleResponseData>>() }
fun getDamagesList(hashMap: HashMap<String, String>) {
@ -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<SimpleResponseData> {
override fun onResponse(call: Call<SimpleResponseData>,
response: Response<SimpleResponseData>
) {
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<SimpleResponseData>, throwable: Throwable) {
deleteDamage.value = Resource.error(ApiUtils.failure(throwable))
}
})
}
}

View file

@ -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<DamageListAdapter.DamageHolder>() {
class DamageListAdapter(val damageListFragment: DamageListFragment) : RecyclerView.Adapter<DamageListAdapter.DamageHolder>() {
var mainList = ArrayList<Damage>()
@ -40,6 +41,15 @@ class DamageListAdapter() : RecyclerView.Adapter<DamageListAdapter.DamageHolder>
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)
}
}

View file

@ -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()
}

View file

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

View file

@ -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<String, String>()
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
}
}

View file

@ -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<Resource<SimpleResponseData>>() }
fun updateProfile(hashMap: HashMap<String, String>) {
profile.value = Resource.loading()
webService.updateProfile(hashMap)
.enqueue(object : Callback<SimpleResponseData> {
override fun onResponse(call: Call<SimpleResponseData>,
response: Response<SimpleResponseData>
) {
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<SimpleResponseData>, throwable: Throwable) {
profile.value = Resource.error(ApiUtils.failure(throwable))
}
})
}
}

View file

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

View file

@ -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`))
}

View file

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#285747" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z"/>
</vector>

View file

@ -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">
>
<AutoCompleteTextView
android:id="@+id/autoCompleteUnits"
@ -270,6 +269,7 @@
app:layout_constraintTop_toBottomOf="@id/txtApproximateNumber"
android:layout_marginTop="@dimen/dp_4"
android:text=""
android:hint="@string/please_enter_item_quantity"
android:maxLines="1"
android:singleLine="true"

View file

@ -162,9 +162,41 @@
android:text="@string/export_pdf"
android:paddingTop="@dimen/dp_10"
android:paddingBottom="@dimen/dp_10"
android:visibility="gone"
android:fontFamily="@font/montserratsemibold"
android:background="@drawable/rounded_background"
android:layout_marginBottom="@dimen/dp_40"
android:textColor="#FFFFFF"/>
<LinearLayout
android:id="@+id/clNoData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/dp_120"
android:src="@drawable/no_data"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_14"
android:fontFamily="@font/montserratmedium"
android:paddingEnd="@dimen/dp_8"
android:paddingStart="@dimen/dp_4"
android:layout_gravity="center"
android:text="@string/no_inspection_data"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -43,36 +43,19 @@
<LinearLayout
android:id="@+id/llLogoutBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/dp_16"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_12"
android:fontFamily="@font/montserratregular"
android:paddingEnd="@dimen/dp_8"
android:paddingStart="@dimen/dp_4"
android:layout_gravity="center"
android:text="@string/logout"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/logout"/>
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"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"

View file

@ -0,0 +1,338 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/white"
tools:context=".ui.profile.ProfileFragment">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/leftGuide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="@dimen/dp_16" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/rightGuide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="@dimen/dp_16" />
<RelativeLayout
android:id="@+id/rlTop"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_64"
>
<ImageView
android:id="@+id/ivLeft"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/dp_16"
android:layout_centerVertical="true"
android:paddingEnd="@dimen/dp_8"
android:src="@drawable/arrow_left"/>
<TextView
android:id="@+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_profile"
android:textColor="@color/black"
android:textSize="@dimen/sp_18"
android:fontFamily="@font/montserratmedium"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/dp_8"
android:layout_toEndOf="@+id/ivLeft"
/>
<LinearLayout
android:id="@+id/llLogoutBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/dp_16"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_12"
android:fontFamily="@font/montserratregular"
android:paddingEnd="@dimen/dp_8"
android:paddingStart="@dimen/dp_4"
android:layout_gravity="center"
android:text="@string/logout"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/logout"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:background="@color/view_line"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="@id/leftGuide"
app:layout_constraintEnd_toStartOf="@id/rightGuide"
app:layout_constraintTop_toBottomOf="@+id/rlTop"
app:layout_constraintBottom_toBottomOf="parent"
android:scrollbars="none"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/llName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_16"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/agent_name"
android:fontFamily="@font/montserratregular"
android:layout_marginTop="@dimen/dp_16"
android:textSize="@dimen/sp_14"
/>
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_background"
android:layout_marginTop="@dimen/dp_4"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="end"
android:hint="@string/please_enter_agent_name"
android:fontFamily="@font/montserratregular"
android:textSize="@dimen/sp_14"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/llPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/phone_number"
android:fontFamily="@font/montserratregular"
android:layout_marginTop="@dimen/dp_16"
android:textSize="@dimen/sp_14"
/>
<EditText
android:id="@+id/etPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_background"
android:layout_marginTop="@dimen/dp_4"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="end"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:fontFamily="@font/montserratregular"
android:textSize="@dimen/sp_14"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/llEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/email_id"
android:fontFamily="@font/montserratregular"
android:layout_marginTop="@dimen/dp_16"
android:textSize="@dimen/sp_14"
/>
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_background"
android:layout_marginTop="@dimen/dp_4"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="end"
android:editable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:fontFamily="@font/montserratregular"
android:textSize="@dimen/sp_14"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/llPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/password"
android:fontFamily="@font/montserratregular"
android:layout_marginTop="@dimen/dp_16"
android:textSize="@dimen/sp_14"
/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilPassword"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endIconMode="password_toggle"
android:layout_marginTop="@dimen/dp_8"
app:hintEnabled="false"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:textColor="@color/edit_text_color"
android:textSize="@dimen/sp_14"
android:maxLines="1"
android:singleLine="true"
android:hint="@string/password"
android:imeOptions="actionDone"
android:fontFamily="@font/montserratregular"
android:background="@drawable/rounded_background" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/llConfirmPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/confirm_password"
android:fontFamily="@font/montserratregular"
android:layout_marginTop="@dimen/dp_16"
android:textSize="@dimen/sp_14"
/>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endIconMode="password_toggle"
android:layout_marginTop="@dimen/dp_16"
app:hintEnabled="false"
>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etConfirmPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:textColor="@color/edit_text_color"
android:textSize="@dimen/sp_14"
android:maxLines="1"
android:singleLine="true"
android:hint="@string/password"
android:imeOptions="actionDone"
android:fontFamily="@font/montserratregular"
android:background="@drawable/rounded_background" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<Button
android:id="@+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_16"
android:layout_marginTop="@dimen/dp_56"
android:text="@string/save"
android:paddingTop="@dimen/dp_10"
android:paddingBottom="@dimen/dp_10"
android:fontFamily="@font/montserratsemibold"
android:background="@drawable/rounded_background"
android:textColor="#FFFFFF"/>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -25,4 +25,9 @@
android:name="com.example.fieldagent.ui.damagedetails.DamageDetailsFragment"
android:label="DamageDetails"
/>
<fragment
android:id="@+id/profileFragment"
android:name="com.example.fieldagent.ui.profile.ProfileFragment"
android:label="Profile"
/>
</navigation>

View file

@ -145,7 +145,18 @@
<string name="piece">piece(s)</string>
<string name="liter">liter(s)</string>
<string name="kg">kg</string>
<string name="user_profile">User Profile</string>
<string name="agent_name">Agent Name</string>
<string name="please_enter_agent_name">Please enter agent name</string>
<string name="phone_number">Phone Number</string>
<string name="email_id">Email ID</string>
<string name="please_enter_password">Please enter password</string>
<string name="confirm_password">Confirm Password</string>
<string name="please_enter_confirm_password">Please enter confirm password</string>
<string name="please_select_category">Please select category</string>
<string name="password_and_confirm_password_not_match">Password and confirm password do not match</string>
<string name="save">Save</string>
<string name="profile_updated_successfully">Profile updated successfully</string>
<string name="are_you_sure_you_want_to_delete">Are you sure you want to delete?</string>
@ -194,4 +205,6 @@
<item>@string/liter</item>
<item>@string/kg</item>
</string-array>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>