added localization

This commit is contained in:
Aryankc2 2025-04-30 16:10:44 +05:30
parent f1d2895202
commit 236c8ef970
21 changed files with 549 additions and 276 deletions

View file

@ -21,6 +21,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:localeConfig="@xml/locales_config"
android:theme="@style/Theme.FieldAgent" android:theme="@style/Theme.FieldAgent"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity

View file

@ -1,8 +1,11 @@
package com.example.fieldagent package com.example.fieldagent
import android.app.Application import android.app.Application
import android.content.Context
import com.example.fieldagent.utils.LocaleManager
import com.example.fieldagent.utils.PrefsManager import com.example.fieldagent.utils.PrefsManager
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@ -11,4 +14,17 @@ class AgentApplication : Application() {
@Inject @Inject
lateinit var prefsManager: PrefsManager lateinit var prefsManager: PrefsManager
@Inject
lateinit var localeManager: LocaleManager
override fun attachBaseContext(base: Context?) {
val localeManager = LocaleManager()
val supportedLanguages = listOf("en", "ar")
val systemLang = Locale.getDefault().language
val langToUse = if (systemLang in supportedLanguages) systemLang else "en"
val newContext = localeManager.setLocale(base!!, langToUse)
super.attachBaseContext(newContext)
}
} }

View file

@ -74,7 +74,9 @@ interface WebService {
@GET(SELECT_CATEGORY) @GET(SELECT_CATEGORY)
fun getSelectCategoryList(@QueryMap hashMap: Map<String, String>): Call<SelectCategoryData> fun getSelectCategoryList(@QueryMap hashMap: Map<String, String>): Call<SelectCategoryData>
@PUT(USER)
fun updateProfile(@FieldMap hashMap: HashMap<String, String>): Call<SimpleResponseData> @FormUrlEncoded
@PUT("$USER/{id}")
fun updateProfile(@Path("id") id: String,@FieldMap hashMap: HashMap<String, String>): Call<SimpleResponseData>
} }

View file

@ -3,6 +3,7 @@ package com.example.fieldagent.di
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.preference.PreferenceManager import android.preference.PreferenceManager
import com.example.fieldagent.utils.LocaleManager
import com.google.gson.FieldNamingPolicy import com.google.gson.FieldNamingPolicy
import com.google.gson.Gson import com.google.gson.Gson
@ -18,6 +19,9 @@ import javax.inject.Singleton
@Module @Module
object AppModule { object AppModule {
@Provides
@Singleton
fun provideLocaleManager(): LocaleManager = LocaleManager()
@Provides @Provides
@Singleton @Singleton

View file

@ -1,6 +1,8 @@
package com.example.fieldagent.ui.damagelist package com.example.fieldagent.ui.damagelist
import android.content.ContentValues import android.content.ContentValues
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
@ -8,6 +10,7 @@ import android.graphics.pdf.PdfDocument
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import android.view.Gravity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -36,6 +39,9 @@ import java.util.Date
import java.util.HashMap import java.util.HashMap
import java.util.Locale import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
import androidx.core.graphics.toColorInt
import androidx.core.graphics.createBitmap
import androidx.core.text.layoutDirection
@AndroidEntryPoint @AndroidEntryPoint
@ -56,6 +62,7 @@ class DamageListFragment : Fragment() {
private var inspectionId="" private var inspectionId=""
private var clickDeletePos=-1 private var clickDeletePos=-1
private var vatValue=""
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@ -110,6 +117,7 @@ class DamageListFragment : Fragment() {
binding.clNoData.visible() binding.clNoData.visible()
binding.btnExportPdf.gone() binding.btnExportPdf.gone()
}else{ }else{
vatValue=tempList[0].vat.toString()
binding.clNoData.gone() binding.clNoData.gone()
binding.btnExportPdf.visible() binding.btnExportPdf.visible()
} }
@ -120,6 +128,7 @@ class DamageListFragment : Fragment() {
} }
Status.ERROR -> { Status.ERROR -> {
progressDialog.setLoading(false) progressDialog.setLoading(false)
@ -192,99 +201,308 @@ class DamageListFragment : Fragment() {
} }
private fun setUpPdf(){ private fun setUpPdf(){
val pdfDocument = PdfDocument()
val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
val borderPaint = Paint().apply {
color = Color.BLACK try {
style = Paint.Style.STROKE
strokeWidth = 1f val pdfDocument = PdfDocument()
val currentLocale = Resources.getSystem().configuration.locales[0]
if (currentLocale.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
val borderPaint = Paint().apply {
color = Color.BLACK
style = Paint.Style.STROKE
strokeWidth = 1f
}
val textPaint = Paint().apply {
textSize = 12f
color = Color.BLACK
style = Paint.Style.FILL
isAntiAlias = true
textAlign = Paint.Align.RIGHT // Important for Arabic
}
val whiteTextPaint = Paint(textPaint).apply {
color = Color.WHITE
}
val fillPaint = Paint().apply {
style = Paint.Style.FILL
}
val colWidths = listOf(120f, 100f, 120f, 60f, 100f, 40f) // Reversed for RTL
val rowHeight = 40f
val startX = 40f
var startY = 60f
val title = getString(R.string.damage_report_table)
val headers = listOf(
getString(R.string.total_cost_in_riyals),
getString(R.string.unit),
getString(R.string.individual_cost),
getString(R.string.number),
getString(R.string.item),
getString(R.string.no_)
)
val initialRow = adapter.mainList.mapIndexed { index, damage ->
val no = (index + 1).toString()
val item = damage.subcategoryName ?: "-"
val number = damage.itemQuantity.toString()
val individualCost = damage.itemValue.toString()
val unit = damage.unit ?: "-"
val total = (damage.itemQuantity * damage.itemValue).toString()
listOf(total, unit, individualCost, number, item, no) // Reversed
}
val vatRate = vatValue.toDoubleOrNull() ?: 0.0
val totalAmount = adapter.mainList.sumOf { it.itemQuantity * it.itemValue }
val vatAmount = (totalAmount * (vatRate / 100)).toLong()
val vatRow = listOf(vatAmount.toString(), "", "", "", getString(R.string.vat), "")
val totalRow = listOf((totalAmount + vatAmount).toString(), "", "", "", getString(R.string.total_cost), "")
val rows = initialRow + listOf(vatRow, totalRow)
val centerAlignedColumns = setOf(0, 2, 3, 5)
// Title
fillPaint.color = "#285747".toColorInt()
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, fillPaint)
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, borderPaint)
val titleX = startX + colWidths.sum() - (colWidths.sum() / 2f) // RTL title center
canvas.drawText(title, titleX, startY + 25f, whiteTextPaint)
startY += rowHeight
fillPaint.color = "#8AA29A".toColorInt()
var x = startX
for ((i, header) in headers.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
canvas.drawText(header, x + width - 5f, startY + 25f, textPaint)
x += width
}
startY += rowHeight
for ((index, row) in rows.withIndex()) {
fillPaint.color = if (index % 2 == 0) Color.WHITE else "#DDE4E2".toColorInt()
x = startX
val tempCanvas = Canvas(createBitmap(1, 1))
val heights = row.mapIndexed { i, text ->
drawWrappedTextRTL(tempCanvas, text, 0f, 0f, colWidths[i], textPaint,index in centerAlignedColumns)
}
val actualRowHeight = heights.maxOrNull()?.coerceAtLeast(rowHeight) ?: rowHeight
x = startX
for ((i, cell) in row.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + actualRowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + actualRowHeight, borderPaint)
drawWrappedTextRTL(canvas, cell, x, startY + 20f, width, textPaint,i in centerAlignedColumns)
x += width
}
startY += actualRowHeight
}
pdfDocument.finishPage(page)
} else {
val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
val borderPaint = Paint().apply {
color = Color.BLACK
style = Paint.Style.STROKE
strokeWidth = 1f
}
val textPaint = Paint().apply {
textSize = 12f
color = Color.BLACK
style = Paint.Style.FILL
isAntiAlias = true
}
val whiteTextPaint = Paint(textPaint).apply { color = Color.WHITE }
val fillPaint = Paint().apply {
style = Paint.Style.FILL
}
val colWidths = listOf(40f, 100f, 60f, 120f, 100f, 120f)
val rowHeight = 40f
val startX = 40f
var startY = 60f
val title = getString(R.string.damage_report_table)
val headers = listOf(getString(R.string.no_), getString(R.string.item), getString(R.string.number), getString(R.string.individual_cost), getString(R.string.unit), getString(R.string.total_cost_in_riyals))
val initialRow = adapter.mainList.mapIndexed { index, damage ->
val no = (index + 1).toString()
val item = damage.subcategoryName ?: "-"
val number = damage.itemQuantity.toString()
val individualCost = damage.itemValue.toString()
val unit = damage.unit ?: "-"
val total = (damage.itemQuantity * damage.itemValue).toString()
listOf(no, item, number, individualCost, unit, total)
}
val vatRate = vatValue.toDoubleOrNull() ?: 0.0
val totalAmount = adapter.mainList.sumOf { it.itemQuantity * it.itemValue }
val vatAmount = (totalAmount * (vatRate / 100)).toLong()
val vatRow = listOf("", getString(R.string.vat), "", "", "", vatAmount.toString())
val totalRow = listOf("", getString(R.string.total_cost), "", "", "", (totalAmount + vatAmount).toString())
val rows = initialRow + listOf(vatRow, totalRow)
val centerAlignedColumns = setOf(0, 2, 3, 5)
fillPaint.color = "#285747".toColorInt() // dark green
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, fillPaint)
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, borderPaint)
val titleX = startX + (colWidths.sum() / 2f) - (whiteTextPaint.measureText(title) / 2f)
canvas.drawText(title, titleX, startY + 25f, whiteTextPaint)
startY += rowHeight
fillPaint.color = "#8AA29A".toColorInt() // light green
var x = startX
for ((i, header) in headers.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
canvas.drawText(header, x + 5f, startY + 25f, textPaint)
x += width
}
startY += rowHeight
for ((index, row) in rows.withIndex()) {
fillPaint.color = if (index % 2 == 0) Color.WHITE else "#DDE4E2".toColorInt()
x = startX
val tempCanvas = Canvas(createBitmap(1, 1))
val heights = row.mapIndexed { i, text ->
drawWrappedText(tempCanvas, text, 0f, 0f, colWidths[i], textPaint,index in centerAlignedColumns)
}
val actualRowHeight = heights.maxOrNull()?.coerceAtLeast(rowHeight) ?: rowHeight
x = startX
for ((i, cell) in row.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + actualRowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + actualRowHeight, borderPaint)
drawWrappedText(canvas, cell, x, startY + 20f, width, textPaint,i in centerAlignedColumns)
x += width
}
startY += actualRowHeight
}
pdfDocument.finishPage(page)
}
val fileName = "damage_report_" + SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(
Date()
)
savePdfToDocuments(pdfDocument, fileName)
}
catch (e:Exception)
{
e.printStackTrace()
} }
val textPaint = Paint().apply {
textSize = 12f }
color = Color.BLACK
style = Paint.Style.FILL fun drawWrappedTextRTL(
isAntiAlias = true canvas: Canvas,
text: String,
x: Float,
y: Float,
width: Float,
paint: Paint,
center: Boolean = false
): Float {
val words = text.split(" ")
val lineHeight = paint.textSize + 4f
var currentLine = ""
var currentY = y
val maxWidth = width - 10f
val lines = mutableListOf<String>()
for (word in words) {
val testLine = if (currentLine.isEmpty()) word else "$currentLine $word"
if (paint.measureText(testLine) > maxWidth) {
lines.add(currentLine)
currentLine = word
} else {
currentLine = testLine
}
}
if (currentLine.isNotEmpty()) lines.add(currentLine)
for (line in lines) {
val drawX = if (center) x + (width / 2f) + (paint.measureText(line) / 2f) else x + width - 5f
canvas.drawText(line, drawX, currentY, paint)
currentY += lineHeight
} }
val whiteTextPaint = Paint(textPaint).apply { color = Color.WHITE } return currentY - y
}
fun drawWrappedText(
canvas: Canvas,
text: String,
x: Float,
y: Float,
width: Float,
paint: Paint,
center: Boolean = false
): Float {
val words = text.split(" ")
val lineHeight = paint.textSize + 4f
var currentLine = ""
var currentY = y
val maxWidth = width - 10f
val lines = mutableListOf<String>()
val fillPaint = Paint().apply { for (word in words) {
style = Paint.Style.FILL val testLine = if (currentLine.isEmpty()) word else "$currentLine $word"
if (paint.measureText(testLine) > maxWidth) {
lines.add(currentLine)
currentLine = word
} else {
currentLine = testLine
}
}
if (currentLine.isNotEmpty()) {
lines.add(currentLine)
} }
// Column layout for (line in lines) {
val colWidths = listOf(40f, 100f, 60f, 100f, 60f, 120f)
val rowHeight = 40f
val startX = 40f
var startY = 60f
val title = "Damage Report Table"
val headers = listOf("No.", "Item", "Number", "Individual Cost", "Unit", "Total Cost (Riyals)")
val rows = listOf(
listOf("1", "Chair", "4", "50", "pcs", "200"),
listOf("2", "Table", "2", "150", "pcs", "300"),
listOf("3", "مكتب", "1", "500", "قطعة", "500"),
listOf("4", "Desk", "1", "450", "pcs", "450")
)
val centerAlignedColumns = setOf(0, 2, 3, 5) // columns to center text
fun drawCellText(canvas: Canvas, text: String, x: Float, y: Float, width: Float, paint: Paint, center: Boolean) {
val drawX = if (center) { val drawX = if (center) {
x + (width / 2f) - (paint.measureText(text) / 2f) x + (width / 2f) - (paint.measureText(line) / 2f)
} else { } else {
x + 5f x + 5f
} }
canvas.drawText(text, drawX, y, paint) canvas.drawText(line, drawX, currentY, paint)
currentY += lineHeight
} }
// --- Draw title row --- return currentY - y
fillPaint.color = Color.parseColor("#006400") // dark green
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, fillPaint)
canvas.drawRect(startX, startY, startX + colWidths.sum(), startY + rowHeight, borderPaint)
val titleX = startX + (colWidths.sum() / 2f) - (whiteTextPaint.measureText(title) / 2f)
canvas.drawText(title, titleX, startY + 25f, whiteTextPaint)
startY += rowHeight
// --- Draw header row ---
fillPaint.color = Color.parseColor("#90EE90") // light green
var x = startX
for ((i, header) in headers.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
drawCellText(canvas, header, x, startY + 25f, width, textPaint, i in centerAlignedColumns)
x += width
}
startY += rowHeight
// --- Draw data rows ---
for ((index, row) in rows.withIndex()) {
fillPaint.color = if (index % 2 == 0) Color.WHITE else Color.parseColor("#E6FFE6")
x = startX
for ((i, cell) in row.withIndex()) {
val width = colWidths[i]
canvas.drawRect(x, startY, x + width, startY + rowHeight, fillPaint)
canvas.drawRect(x, startY, x + width, startY + rowHeight, borderPaint)
drawCellText(canvas, cell, x, startY + 25f, width, textPaint, i in centerAlignedColumns)
x += width
}
startY += rowHeight
}
pdfDocument.finishPage(page)
val fileName = "damage_report_" + SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(
Date()
)
savePdfToDocuments(pdfDocument, fileName)
} }
fun savePdfToDocuments( pdfDocument: PdfDocument, fileName: String) { fun savePdfToDocuments( pdfDocument: PdfDocument, fileName: String) {
val contentValues = ContentValues().apply { val contentValues = ContentValues().apply {
@ -307,9 +525,9 @@ class DamageListFragment : Fragment() {
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0) contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
resolver.update(uri, contentValues, null, null) resolver.update(uri, contentValues, null, null)
Toast.makeText(context, "PDF saved to Documents!", Toast.LENGTH_LONG).show() Toast.makeText(context, getString(R.string.pdf_saved), Toast.LENGTH_LONG).show()
} ?: run { } ?: run {
Toast.makeText(context, "Failed to save PDF", Toast.LENGTH_SHORT).show() Toast.makeText(context, getString(R.string.pdf_failed), Toast.LENGTH_SHORT).show()
} }
} }
@ -326,7 +544,7 @@ class DamageListFragment : Fragment() {
findNavController().navigate(R.id.damageDeatilsFragment, bundle) findNavController().navigate(R.id.damageDeatilsFragment, bundle)
} }
fun clickDeleteItem(pos: Int, id: String,) { fun clickDeleteItem(pos: Int, id: String) {
if (pos < 0 ) { if (pos < 0 ) {
return return

View file

@ -15,7 +15,9 @@ import android.view.ViewGroup
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.PopupWindow import android.widget.PopupWindow
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.example.fieldagent.R import com.example.fieldagent.R
@ -52,7 +54,9 @@ import com.example.fieldagent.utils.gone
import com.example.fieldagent.utils.hideShowView import com.example.fieldagent.utils.hideShowView
import com.example.fieldagent.utils.isConnectedToInternet import com.example.fieldagent.utils.isConnectedToInternet
import com.example.fieldagent.utils.showConfirmDialog import com.example.fieldagent.utils.showConfirmDialog
import com.example.fieldagent.utils.showSnackBar
import com.example.fieldagent.utils.visible import com.example.fieldagent.utils.visible
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -138,7 +142,6 @@ class HomeFragment : Fragment() {
} }
binding.ivProfile.setOnClickListener { binding.ivProfile.setOnClickListener {
findNavController().navigate(R.id.profileFragment) findNavController().navigate(R.id.profileFragment)
} }
@ -183,7 +186,7 @@ class HomeFragment : Fragment() {
binding.swipeRefresh.setOnRefreshListener { binding.swipeRefresh.setOnRefreshListener {
Log.e("hckkkk===>","swipes");
hitApi(true) hitApi(true)
} }
@ -195,7 +198,6 @@ class HomeFragment : Fragment() {
val layoutManager = binding.rvList.layoutManager as LinearLayoutManager val layoutManager = binding.rvList.layoutManager as LinearLayoutManager
val totalItemCount = layoutManager.itemCount - 1 val totalItemCount = layoutManager.itemCount - 1
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition() val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
Log.e("Chekckkkkss","bb")
if (!isLoadingMoreItems && !isLastPage && lastVisibleItemPosition >= totalItemCount) { if (!isLoadingMoreItems && !isLastPage && lastVisibleItemPosition >= totalItemCount) {
isLoadingMoreItems = true isLoadingMoreItems = true
hitApi(false) hitApi(false)

View file

@ -2,11 +2,15 @@ package com.example.fieldagent.ui.login
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.util.Patterns import android.util.Patterns
import android.view.Gravity
import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.layoutDirection
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.consultantapp.data.network.responseUtil.Status import com.consultantapp.data.network.responseUtil.Status
import com.example.fieldagent.R import com.example.fieldagent.R
@ -48,6 +52,20 @@ class LoginActivity : AppCompatActivity() {
prefsManager.removeAll() prefsManager.removeAll()
progressDialog = ProgressDialog(this) progressDialog = ProgressDialog(this)
val currentLocale = Resources.getSystem().configuration.locales[0]
if (currentLocale.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
binding.etPassword.textDirection = View.TEXT_DIRECTION_RTL
binding.etPassword.layoutDirection = View.LAYOUT_DIRECTION_RTL
binding.etPassword.gravity = Gravity.END
} else {
binding.etPassword.textDirection = View.TEXT_DIRECTION_LTR
binding.etPassword.layoutDirection = View.LAYOUT_DIRECTION_LTR
binding.etPassword.gravity = Gravity.START
}
} }
private fun listeners(){ private fun listeners(){

View file

@ -2,8 +2,11 @@ package com.example.fieldagent.ui.profile
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Intent import android.content.Intent
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.Gravity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -33,6 +36,7 @@ import com.google.gson.Gson
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import java.util.HashMap import java.util.HashMap
import javax.inject.Inject import javax.inject.Inject
import androidx.core.text.layoutDirection
@AndroidEntryPoint @AndroidEntryPoint
@ -49,6 +53,7 @@ class ProfileFragment : Fragment() {
lateinit var prefsManager: PrefsManager lateinit var prefsManager: PrefsManager
private lateinit var progressDialog: ProgressDialog private lateinit var progressDialog: ProgressDialog
private var userId="";
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -68,18 +73,43 @@ class ProfileFragment : Fragment() {
} }
private fun initialize(){ private fun initialize(){
progressDialog=ProgressDialog(requireActivity())
val jsonString = prefsManager.getString(USER_DATA, "") val jsonString = prefsManager.getString(USER_DATA, "")
val userData = Gson().fromJson(jsonString, Data::class.java) val userData = Gson().fromJson(jsonString, Data::class.java)
userId=userData.id.toString()
binding.etName.setText(userData.name) binding.etName.setText(userData.name)
binding.etEmail.setText(userData.email) binding.etEmail.setText(userData.email)
binding.etPhone.setText(userData.phoneNumber) binding.etPhone.setText(userData.phoneNumber)
val currentLocale = Resources.getSystem().configuration.locales[0]
if (currentLocale.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
binding.etPassword.textDirection = View.TEXT_DIRECTION_RTL
binding.etPassword.layoutDirection = View.LAYOUT_DIRECTION_RTL
binding.etPassword.gravity = Gravity.END
binding.etConfirmPassword.textDirection = View.TEXT_DIRECTION_RTL
binding.etConfirmPassword.layoutDirection = View.LAYOUT_DIRECTION_RTL
binding.etConfirmPassword.gravity = Gravity.END
} else {
binding.etPassword.textDirection = View.TEXT_DIRECTION_LTR
binding.etPassword.layoutDirection = View.LAYOUT_DIRECTION_LTR
binding.etPassword.gravity = Gravity.START
binding.etConfirmPassword.textDirection = View.TEXT_DIRECTION_LTR
binding.etConfirmPassword.layoutDirection = View.LAYOUT_DIRECTION_LTR
binding.etConfirmPassword.gravity = Gravity.START
}
} }
private fun listener(){ private fun listener(){
binding.ivLeft.setOnClickListener {
findNavController().popBackStack()
}
binding.llLogoutBtn.setOnClickListener { binding.llLogoutBtn.setOnClickListener {
@ -101,6 +131,10 @@ class ProfileFragment : Fragment() {
binding.etPassword.showSnackBar(getString(R.string.please_enter_password)) binding.etPassword.showSnackBar(getString(R.string.please_enter_password))
} }
!binding.etPassword.text.toString().matches(Regex("^(?=.*[A-Z])(?=.*\\d)(?=.*[@#\$%^&+=!]).{6,}$"))->{
binding.etPassword.showSnackBar(getString(R.string.please_enter_valid_password))
}
binding.etConfirmPassword.text.toString().isEmpty()->{ binding.etConfirmPassword.text.toString().isEmpty()->{
binding.etConfirmPassword.showSnackBar(getString(R.string.please_enter_confirm_password)) binding.etConfirmPassword.showSnackBar(getString(R.string.please_enter_confirm_password))
} }
@ -112,7 +146,7 @@ class ProfileFragment : Fragment() {
hashMap["name"] = binding.etName.text.toString() hashMap["name"] = binding.etName.text.toString()
hashMap["password"] = binding.etPassword.text.toString() hashMap["password"] = binding.etPassword.text.toString()
viewModel.updateProfile(hashMap) viewModel.updateProfile(userId,hashMap)
} }

View file

@ -21,10 +21,10 @@ class ProfileFragmentVM @Inject constructor(private val webService: WebService)
val profile by lazy { SingleLiveEvent<Resource<SimpleResponseData>>() } val profile by lazy { SingleLiveEvent<Resource<SimpleResponseData>>() }
fun updateProfile(hashMap: HashMap<String, String>) { fun updateProfile(id:String,hashMap: HashMap<String, String>) {
profile.value = Resource.loading() profile.value = Resource.loading()
webService.updateProfile(hashMap) webService.updateProfile(id,hashMap)
.enqueue(object : Callback<SimpleResponseData> { .enqueue(object : Callback<SimpleResponseData> {
override fun onResponse(call: Call<SimpleResponseData>, override fun onResponse(call: Call<SimpleResponseData>,

View file

@ -53,7 +53,7 @@ fun View.showSnackBar(msg: String) {
snackBarView.findViewById<View>(com.google.android.material.R.id.snackbar_text) as TextView snackBarView.findViewById<View>(com.google.android.material.R.id.snackbar_text) as TextView
textView.maxLines = 3 textView.maxLines = 3
snackBar.setAction(R.string.ok) { snackBar.dismiss() } snackBar.setAction(R.string.ok) { snackBar.dismiss() }
snackBarView.setBackgroundColor(ContextCompat.getColor(context, R.color.main_color)) snackBar.setBackgroundTint(ContextCompat.getColor(context, R.color.main_color))
snackBar.setActionTextColor(ContextCompat.getColor(context, R.color.white)) snackBar.setActionTextColor(ContextCompat.getColor(context, R.color.white))
snackBar.show() snackBar.show()
} catch (e: Exception) { } catch (e: Exception) {

View file

@ -0,0 +1,20 @@
package com.example.fieldagent.utils
import android.content.Context
import android.content.res.Configuration
import android.os.Build
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class LocaleManager @Inject constructor() {
fun setLocale(context: Context, language: String): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val config = Configuration(context.resources.configuration)
config.setLocale(locale)
return context.createConfigurationContext(config)
}
}

View file

@ -125,6 +125,7 @@
android:maxLines="1" android:maxLines="1"
android:singleLine="true" android:singleLine="true"
android:hint="@string/password" android:hint="@string/password"
android:gravity="start"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:fontFamily="@font/montserratregular" android:fontFamily="@font/montserratregular"
android:background="@drawable/rounded_background" /> android:background="@drawable/rounded_background" />

View file

@ -85,7 +85,7 @@
android:id="@+id/txtMain" android:id="@+id/txtMain"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/structure" android:text=""
android:layout_weight="0.5" android:layout_weight="0.5"
android:textAlignment="textEnd" android:textAlignment="textEnd"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -124,7 +124,7 @@
android:id="@+id/txtSub" android:id="@+id/txtSub"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/wall_paint" android:text=""
android:layout_weight="0.5" android:layout_weight="0.5"
android:textAlignment="textEnd" android:textAlignment="textEnd"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"

View file

@ -183,7 +183,7 @@
android:inputType="none" android:inputType="none"
android:focusable="false" android:focusable="false"
android:clickable="true" android:clickable="true"
android:text="@string/walls" android:text=""
android:textSize="@dimen/sp_12" android:textSize="@dimen/sp_12"
android:fontFamily="@font/montserratregular" android:fontFamily="@font/montserratregular"
/> />

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next"
app:layout_constraintBottom_toTopOf="@id/textview_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/lorem_ipsum"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_first" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -261,6 +261,7 @@
android:singleLine="true" android:singleLine="true"
android:hint="@string/password" android:hint="@string/password"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:gravity="start"
android:fontFamily="@font/montserratregular" android:fontFamily="@font/montserratregular"
android:background="@drawable/rounded_background" /> android:background="@drawable/rounded_background" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -310,6 +311,8 @@
android:hint="@string/password" android:hint="@string/password"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:fontFamily="@font/montserratregular" android:fontFamily="@font/montserratregular"
android:gravity="start"
android:background="@drawable/rounded_background" /> android:background="@drawable/rounded_background" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toTopOf="@id/textview_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/lorem_ipsum"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_second" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Field Agent</string>
<string name="action_settings">إعدادات</string>
<string name="prompt_email">بريد إلكتروني</string>
<string name="prompt_password">كلمة المرور</string>
<string name="action_sign_in">تسجيل الدخول أو التسجيل</string>
<string name="action_sign_in_short">تسجيل الدخول</string>
<string name="welcome">مرحباً !</string>
<string name="invalid_username">اسم مستخدم غير صالح</string>
<string name="invalid_password">يجب أن تكون كلمة المرور أكثر من 5 أحرف</string>
<string name="login_failed">فشل تسجيل الدخول</string>
<string name="sign_in">تسجيل الدخول</string>
<string name="sign_in_to_continue">قم بتسجيل الدخول للمتابعة</string>
<string name="email_address">عنوان البريد الإلكتروني</string>
<string name="password">كلمة المرور</string>
<string name="inspections">عمليات التفتيش</string>
<string name="add_site">أضف موقع</string>
<string name="add">يضيف</string>
<string name="search">يبحث</string>
<string name="status">حالة</string>
<string name="in_progress">في تَقَدم</string>
<string name="completed">مكتمل</string>
<string name="site_detail">تفاصيل الموقع</string>
<string name="name">اسم</string>
<string name="please_enter_your_name">الرجاء إدخال اسمك</string>
<string name="location">موقع</string>
<string name="please_enter_your_location">الرجاء إدخال موقعك</string>
<string name="supervisor_contact_number">رقم الاتصال بالمشرف</string>
<string name="please_enter_supervisor_contact_number">الرجاء إدخال رقم الاتصال بالمشرف</string>
<string name="supervisor_authority_mosque">الجهة المشرفة على المسجد</string>
<string name="please_enter_supervisor_authority_mosque">الرجاء إدخال الجهة المشرفة على المسجد</string>
<string name="building_condition">حالة البناء</string>
<string name="please_enter_building_condition">الرجاء إدخال حالة المبنى</string>
<string name="mosque_area">منطقة المسجد</string>
<string name="please_enter_mosque_area">الرجاء إدخال منطقة المسجد</string>
<string name="availability_women_prayer_area">توفر مكان للصلاة للنساء</string>
<string name="yes">نعم</string>
<string name="no">لا</string>
<string name="approximate_number_worshippers">عدد تقريبي للمصلين</string>
<string name="please_enter_approximate_number_worshippers">الرجاء إدخال العدد التقريبي للمصلين</string>
<string name="number_of_restrooms">عدد دورات المياه</string>
<string name="please_number_of_restrooms">الرجاء إدخال عدد دورات المياه</string>
<string name="condition_of_restrooms">حالة المراحيض</string>
<string name="restrooms">دورات المياه</string>
<string name="ok_condition">حالة جيدة</string>
<string name="good_condition">حالة جيدة</string>
<string name="need_repair">بحاجة إلى إصلاح</string>
<string name="add_image">إضافة صورة</string>
<string name="upload_image">تحميل الصورة</string>
<string name="add_to_sites">أضف إلى المواقع</string>
<string name="damage_list">قائمة الأضرار</string>
<string name="damage">ضرر</string>
<string name="export_pdf">تصدير قوات الدفاع الشعبي</string>
<string name="main_item">العنصر الرئيسي</string>
<string name="sub_item">البند الفرعي</string>
<string name="item_quantity">كمية السلعة</string>
<string name="please_enter_item_quantity">الرجاء إدخال كمية البند</string>
<string name="item_value">قيمة السلعة</string>
<string name="please_enter_item_value">الرجاء إدخال قيمة السلعة</string>
<string name="total_value">القيمة الإجمالية</string>
<string name="images">الصور</string>
<string name="add_to_report">إضافة إلى التقرير</string>
<string name="damage_detail">تفاصيل الضرر</string>
<string name="ok">نعم</string>
<string name="check_internet">لا يوجد اتصال بالإنترنت!</string>
<string name="enter_email">الرجاء إدخال البريد الإلكتروني</string>
<string name="enter_correct_email">الرجاء إدخال البريد الإلكتروني الصحيح</string>
<string name="enter_password">الرجاء إدخال كلمة المرور</string>
<string name="alert">يُحذًِر</string>
<string name="logout">تسجيل الخروج</string>
<string name="no_inspection_data">لا توجد بيانات تفتيش</string>
<string name="please_select_image">الرجاء اختيار الصورة</string>
<string name="please_upload_at_least_one_image">الرجاء تحميل صورة واحدة على الأقل</string>
<string name="select">يختار</string>
<string name="gallery">معرض</string>
<string name="camera">آلة تصوير</string>
<string name="location_permission_denied">تم رفض إذن تحديد الموقع</string>
<string name="could_not_fetch_location">لم أتمكن من جلب الموقع</string>
<string name="seconds_ago">قبل ثواني</string>
<string name="minutes_ago">قبل دقائق</string>
<string name="hours_ago">منذ ساعات</string>
<string name="days_ago">منذ أيام</string>
<string name="units">الوحدات</string>
<string name="user_profile">ملف تعريف المستخدم</string>
<string name="agent_name">اسم الوكيل</string>
<string name="please_enter_agent_name">الرجاء إدخال اسم الوكيل</string>
<string name="phone_number">رقم التليفون</string>
<string name="email_id">معرف البريد الإلكتروني</string>
<string name="please_enter_password">الرجاء إدخال كلمة المرور</string>
<string name="confirm_password">تأكيد كلمة المرور</string>
<string name="please_enter_confirm_password">الرجاء إدخال تأكيد كلمة المرور</string>
<string name="please_select_category">الرجاء تحديد الفئة</string>
<string name="password_and_confirm_password_not_match">كلمة المرور وتأكيد كلمة المرور غير متطابقتين</string>
<string name="save">يحفظ</string>
<string name="profile_updated_successfully">تم تحديث الملف الشخصي بنجاح</string>
<string name="are_you_sure_you_want_to_delete">هل أنت متأكد أنك تريد الحذف؟</string>
<string name="damage_report_table">جدول تقرير الأضرار</string>
<string name="no.">لا.</string>
<string name="item">غرض</string>
<string name="number">رقم</string>
<string name="unit">وحدة</string>
<string name="total_cost_in_riyals">التكلفة الإجمالية بالريال</string>
<string name="total_cost">التكلفة الإجمالية</string>
<string name="individual_cost">التكلفة الفردية بالريال</string>
<string name="vat">ضريبة القيمة المضافة</string>
<string name="pdf_saved">تم حفظ ملف PDF في المستندات!</string>
<string name="pdf_failed">فشل في حفظ ملف PDF!</string>
<string name="please_enter_valid_password">يجب أن تتكون كلمة المرور من 6 أحرف على الأقل وتتضمن حرفًا كبيرًا واحدًا ورقمًا واحدًا وحرفًا خاصًا واحدًا</string>
<string-array name="availability">
<item>@string/yes</item>
<item>@string/no</item>
</string-array>
<string-array name="status">
<item>@string/in_progress</item>
<item>@string/completed</item>
</string-array>
<string-array name="condition">
<item>@string/ok_condition</item>
<item>@string/good_condition</item>
<item>@string/need_repair</item>
</string-array>
</resources>

View file

@ -1,49 +1,6 @@
<resources> <resources>
<string name="app_name">Field Agent</string> <string name="app_name">Field Agent</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<!-- Strings used for fragments for navigation -->
<string name="first_fragment_label">First Fragment</string>
<string name="second_fragment_label">Second Fragment</string>
<string name="next">Next</string>
<string name="previous">Previous</string>
<string name="lorem_ipsum">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
bibendum, vel congue leo egestas.\n\n
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
est.\n\n
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
convallis.\n\n
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
</string>
<string name="title_activity_login">LoginActivity</string>
<string name="prompt_email">Email</string> <string name="prompt_email">Email</string>
<string name="prompt_password">Password</string> <string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string> <string name="action_sign_in">Sign in or register</string>
@ -104,23 +61,6 @@
<string name="images">Images</string> <string name="images">Images</string>
<string name="add_to_report">Add to report</string> <string name="add_to_report">Add to report</string>
<string name="damage_detail">Damage Detail</string> <string name="damage_detail">Damage Detail</string>
<string name="structure">Structure</string>
<string name="electronics">Electronics</string>
<string name="electrical">Electrical</string>
<string name="furniture">Furniture</string>
<string name="plumbing">Plumbing</string>
<string name="HVAC">HVAC</string>
<string name="landscaping">Landscaping</string>
<string name="Beams">Beams</string>
<string name="framing">Framing</string>
<string name="flooring">Flooring</string>
<string name="paneling">Paneling</string>
<string name="walls">Walls</string>
<string name="wall_paint">Wall paint</string>
<string name="ceilings">Ceilings</string>
<string name="roofing">Roofing</string>
<string name="windows">Windows</string>
<string name="doors">Doors</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="check_internet">No Internet Connection!</string> <string name="check_internet">No Internet Connection!</string>
<string name="enter_email">Please enter email</string> <string name="enter_email">Please enter email</string>
@ -141,16 +81,13 @@
<string name="hours_ago">hours ago</string> <string name="hours_ago">hours ago</string>
<string name="days_ago">days ago</string> <string name="days_ago">days ago</string>
<string name="units">Units</string> <string name="units">Units</string>
<string name="meter_square">m2(meter square)</string>
<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="user_profile">User Profile</string>
<string name="agent_name">Agent Name</string> <string name="agent_name">Agent Name</string>
<string name="please_enter_agent_name">Please enter agent name</string> <string name="please_enter_agent_name">Please enter agent name</string>
<string name="phone_number">Phone Number</string> <string name="phone_number">Phone Number</string>
<string name="email_id">Email ID</string> <string name="email_id">Email ID</string>
<string name="please_enter_password">Please enter password</string> <string name="please_enter_password">Please enter password</string>
<string name="please_enter_valid_password">Password must be at least 6 characters and include 1 capital letter, 1 number, and 1 special character</string>
<string name="confirm_password">Confirm Password</string> <string name="confirm_password">Confirm Password</string>
<string name="please_enter_confirm_password">Please enter 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="please_select_category">Please select category</string>
@ -165,8 +102,10 @@
<string name="unit">Unit</string> <string name="unit">Unit</string>
<string name="total_cost_in_riyals">Total Cost in Riyals</string> <string name="total_cost_in_riyals">Total Cost in Riyals</string>
<string name="total_cost">Total Cost</string> <string name="total_cost">Total Cost</string>
<string name="individual_cost">Individual Cost in Riyals</string> <string name="individual_cost">Individual Cost</string>
<string name="vat">VAT</string>
<string name="pdf_saved">PDF saved to Documents!</string>
<string name="pdf_failed">Failed to save PDF!</string>
<string-array name="availability"> <string-array name="availability">
<item>@string/yes</item> <item>@string/yes</item>
@ -185,32 +124,5 @@
</string-array> </string-array>
<string-array name="mainItem">
<item>@string/structure</item>
<item>@string/electronics</item>
<item>@string/electrical</item>
<item>@string/furniture</item>
<item>@string/plumbing</item>
<item>@string/HVAC</item>
<item>@string/landscaping</item>
</string-array>
<string-array name="SubItem">
<item>@string/Beams</item>
<item>@string/framing</item>
<item>@string/flooring</item>
<item>@string/paneling</item>
<item>@string/walls</item>
<item>@string/ceilings</item>
<item>@string/roofing</item>
<item>@string/windows</item>
<item>@string/doors</item>
</string-array>
<string-array name="units">
<item>@string/meter_square</item>
<item>@string/piece</item>
<item>@string/liter</item>
<item>@string/kg</item>
</string-array>
</resources> </resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="ar" />
</locale-config>