5 Commits
qa ... dev

Author SHA1 Message Date
chandrashekhar reddy
943430af24 latest version of app 1.0.8 2024-07-08 14:33:02 +05:30
Pritimay Sarkar
76b98e8d88 add google services for pipeline 2024-01-20 04:55:01 +00:00
Pritimay Sarkar
f231e9a449 Update .gitlab-ci.yml file 2024-01-08 17:56:48 +00:00
Pritimay Sarkar
d2550ca82b Merge branch 'epoch-id' into 'dev'
add epoch based id

See merge request sminnovations/hpos-registration-app!2
2024-01-08 17:47:02 +00:00
Pritimay Sarkar
466864377a add epoch based id 2024-01-08 23:12:46 +05:30
20 changed files with 429 additions and 117 deletions

88
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,88 @@
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android.gitlab-ci.yml
# Read more about this script on this blog post https://about.gitlab.com/2018/10/24/setting-up-gitlab-ci-for-android-projects/, by Jason Lenny
# If you are interested in using Android with FastLane for publishing take a look at the Android-Fastlane template.
image: eclipse-temurin:17-jdk-jammy
variables:
# ANDROID_COMPILE_SDK is the version of Android you're compiling with.
# It should match compileSdkVersion.
ANDROID_COMPILE_SDK: "34"
# ANDROID_BUILD_TOOLS is the version of the Android build tools you are using.
# It should match buildToolsVersion.
ANDROID_BUILD_TOOLS: "33.0.2"
# It's what version of the command line tools we're going to download from the official site.
# Official Site-> https://developer.android.com/studio/index.html
# There, look down below at the cli tools only, sdk tools package is of format:
# commandlinetools-os_type-ANDROID_SDK_TOOLS_latest.zip
# when the script was last modified for latest compileSdkVersion, it was which is written down below
ANDROID_SDK_TOOLS: "9477386"
# Packages installation before running script
before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget unzip
# Setup path as android_home for moving/exporting the downloaded sdk into it
- export ANDROID_HOME="${PWD}/android-sdk-root"
# Create a new directory at specified location
- install -d $ANDROID_HOME
# Here we are installing androidSDK tools from official source,
# (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well)
# after that unzipping those tools and
# then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build
- wget --no-verbose --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
- unzip -q -d "$ANDROID_HOME/cmdline-tools" "$ANDROID_HOME/cmdline-tools.zip"
- mv -T "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/tools"
- export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/cmdline-tools/tools/bin
# Nothing fancy here, just checking sdkManager version
- sdkmanager --version
# use yes to accept all licenses
- yes | sdkmanager --licenses > /dev/null || true
- sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
- sdkmanager "platform-tools"
- sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}"
# Not necessary, but just for surity
- chmod +x ./gradlew
# Basic android and gradle stuff
# Check linting
lintDebug:
interruptible: true
stage: build
script:
- ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint
artifacts:
paths:
- app/lint/reports/lint-results-debug.html
expose_as: "lint-report"
when: always
# Make Project
assembleDebug:
interruptible: true
stage: build
script:
- ./gradlew assembleDebug
artifacts:
paths:
- app/build/outputs/
# Run all tests, if any fails, interrupt the pipeline(fail it)
debugTests:
needs: [lintDebug, assembleDebug]
interruptible: true
stage: test
script:
- ./gradlew -Pci --console=plain :app:testDebug

5
.idea/gradle.xml generated
View File

@@ -4,17 +4,16 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$USER_HOME$/andriod studio gradle/gradle-7.3" /> <option name="gradleHome" value="$USER_HOME$/andriod studio gradle/gradle-7.3" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
</set> </set>
</option> </option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

View File

@@ -13,11 +13,11 @@ android {
compileSdk 34 compileSdk 34
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hposregistration" applicationId "in.sminnovations.hposregistration.iocl"
minSdk 26 minSdk 26
targetSdk 34 targetSdk 34
versionCode 6 versionCode 8
versionName "1.0.6" versionName "1.0.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

67
app/google-services.json Normal file
View File

@@ -0,0 +1,67 @@
{
"project_info": {
"project_number": "243503501547",
"project_id": "iocl-iisc-hpos",
"storage_bucket": "iocl-iisc-hpos.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:243503501547:android:f17de652a3524d047feeae",
"android_client_info": {
"package_name": "com.iocl_iisc.hposqc"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBPxgcDkZfZMr8cFrkMWkVf1a-MstzWC1k"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:243503501547:android:e1bb0f338c8448dd7feeae",
"android_client_info": {
"package_name": "in.sminnovations.hposregistration.iocl"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBPxgcDkZfZMr8cFrkMWkVf1a-MstzWC1k"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:243503501547:android:18b8b33b2dc3776d7feeae",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting.iocl"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBPxgcDkZfZMr8cFrkMWkVf1a-MstzWC1k"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@@ -41,8 +41,9 @@ class UserListOfflineAdapter(private val view: View) : RecyclerView.Adapter<User
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) { override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val userList = differ.currentList[position] val userList = differ.currentList[position]
holder.binding.apply { holder.binding.apply {
userName.text = userList.name userName.text = "Name: ${userList.name}"
userId.text = userList._id userId.text = "Sample ID: ${userList._id}"
timeCreated.text = "Time Created: ${userList.createdAt}"
Glide.with(view).load(userList.userImageURL).into(userImage) Glide.with(view).load(userList.userImageURL).into(userImage)
} }
} }

View File

@@ -28,7 +28,8 @@ class UserListOnlineAdapter(options: FirestoreRecyclerOptions<UserData>, private
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) { override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
holder.binding.apply { holder.binding.apply {
userName.text = "Name: ${model.name}" userName.text = "Name: ${model.name}"
userId.text = "User ID: ${model._id}" userId.text = "Sample ID: ${model._id}"
timeCreated.text = "Time Created: ${model.createdAt}"
Glide.with(view).load(model.userImageURL).into(userImage) Glide.with(view).load(model.userImageURL).into(userImage)
} }
} }

View File

@@ -22,6 +22,9 @@ object Constant {
const val USER_ID = "usernameId" const val USER_ID = "usernameId"
val STATICID = listOf( val STATICID = listOf(
"SMIMYSURU",
"SMIKODAGU",
"SMICHAMARAJA",
"SMIREG1", "SMIREG1",
"SMIREG2", "SMIREG2",
"SMIREG3", "SMIREG3",

View File

@@ -24,40 +24,40 @@ class MainActivity : AppCompatActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val firebaseAppDistribution = FirebaseAppDistribution.getInstance() // val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable() // firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress -> // .addOnProgressListener { updateProgress ->
//
if (updateProgress.apkBytesDownloaded > 0) { // if (updateProgress.apkBytesDownloaded > 0) {
Toast.makeText( // Toast.makeText(
this, // this,
"${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB", // "${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB",
Toast.LENGTH_SHORT // Toast.LENGTH_SHORT
).show() // ).show()
} // }
} // }
.addOnFailureListener { e -> // .addOnFailureListener { e ->
// (Optional) Handle errors. // // (Optional) Handle errors.
if (e is FirebaseAppDistributionException) { // if (e is FirebaseAppDistributionException) {
when (e.errorCode) { // when (e.errorCode) {
FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> { // FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> {
// SDK did nothing. This is expected when building for Play. // // SDK did nothing. This is expected when building for Play.
} // }
//
else -> { // else -> {
// Handle other errors. // // Handle other errors.
Toast.makeText( // Toast.makeText(
this, // this,
"AppDistribution error, status: ${e.errorCode}", // "AppDistribution error, status: ${e.errorCode}",
Toast.LENGTH_SHORT // Toast.LENGTH_SHORT
).show() // ).show()
} // }
} // }
FirebaseCrashlytics.getInstance().recordException(e) // FirebaseCrashlytics.getInstance().recordException(e)
} // }
} // }
.addOnSuccessListener { // .addOnSuccessListener {
// Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show() //// Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show()
} // }
} }
} }

View File

@@ -8,6 +8,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.SearchView
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
@@ -25,13 +26,15 @@ import `in`.sminnovations.hposregistration.R
import `in`.sminnovations.hposregistration.databinding.FragmentUserListBinding import `in`.sminnovations.hposregistration.databinding.FragmentUserListBinding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale
@AndroidEntryPoint @AndroidEntryPoint
class UserListFragment : BaseFragment() { class UserListFragment : BaseFragment() {
private lateinit var userId:String
private var district:String ="Mysuru"
private var _binding: FragmentUserListBinding? = null private var _binding: FragmentUserListBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private lateinit var offlineAdapter:UserListOfflineAdapter
private val viewModel by viewModels<RegistrationViewModel>() private val viewModel by viewModels<RegistrationViewModel>()
private var isOnline = false private var isOnline = false
@@ -43,6 +46,14 @@ class UserListFragment : BaseFragment() {
): View { ): View {
_binding = FragmentUserListBinding.inflate(inflater, container, false) _binding = FragmentUserListBinding.inflate(inflater, container, false)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
userId = sharedPreference.getString(Constant.USER_ID, "").toString()
if(userId=="SMIMYSURU"){
district = "Mysuru"
}else if(userId=="SMIKODAGU"){
district = "Kodagu"
}else if(userId=="SMICHAMARAJA"){
district = "Chamarajanagar"
}
setupViews() setupViews()
return binding.root return binding.root
} }
@@ -66,12 +77,15 @@ class UserListFragment : BaseFragment() {
binding.btnRegisterUser.setOnClickListener { binding.btnRegisterUser.setOnClickListener {
findNavController().navigate(R.id.action_userListFragment_to_registrationFragment) findNavController().navigate(R.id.action_userListFragment_to_registrationFragment)
} }
binding.btnLogout.setOnClickListener { binding.btnLogout.setOnClickListener {
logoutUser(requireContext()) logoutUser(requireContext())
} }
} }
private fun init() { private fun init() {
binding.searchUser.isIconified = false
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) { if (isNetworkAvailable) {
isOnline = isNetworkAvailable isOnline = isNetworkAvailable
@@ -83,6 +97,28 @@ class UserListFragment : BaseFragment() {
} }
} }
binding.searchUser.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
// Perform the final search
if(isOnline){
fetchFromServer(query)
}else{
filterList(query)
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
// Perform search as the user types
if(isOnline){
fetchFromServer(newText)
}else{
filterList(newText)
}
return true
}
})
binding.uploadData.setOnClickListener { binding.uploadData.setOnClickListener {
showUploadDialog(requireContext()) showUploadDialog(requireContext())
} }
@@ -91,6 +127,12 @@ class UserListFragment : BaseFragment() {
deteleIncompleteRegistration(userDataList) deteleIncompleteRegistration(userDataList)
} }
} }
private fun filterList(query: String?) {
val filteredList = viewModel.allUserData.value?.filter { userData ->
userData.name.contains(query ?: "", ignoreCase = true)
}
offlineAdapter.differ.submitList(filteredList)
}
private fun logoutUser(context: Context) { private fun logoutUser(context: Context) {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
@@ -163,28 +205,88 @@ class UserListFragment : BaseFragment() {
} }
} }
} }
// private fun fetchFromServer(searchTerm: String? = null) {
private fun fetchFromServer() { // binding.noList.visibility = View.GONE
// binding.rvOrder.visibility = View.VISIBLE
// val dateFormat = SimpleDateFormat("yyyy-MM-dd")
// val currentDate = Date()
// val today = dateFormat.format(currentDate)
//
// // Base query to fetch patient data created today
// var query = Firebase.firestore.collection("patientData")
// .whereGreaterThanOrEqualTo("createdAt", today)
// .orderBy("createdAt", Query.Direction.DESCENDING)
//
// // If a search term is provided, add it to the query
// if (!searchTerm.isNullOrEmpty()) {
// query = query.whereEqualTo("aadharId", searchTerm)
// }
//
// query.get().addOnSuccessListener {
// if (it.documents.isEmpty() && isOnline) {
// binding.emptyRegistrations.visibility = View.VISIBLE
// }
// }
//
// val recyclerViewOptions =
// FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
// .build()
// val adapter = UserListOnlineAdapter(recyclerViewOptions, binding.root)
// binding.rvOrder.adapter = adapter
// adapter.startListening()
// }
private fun fetchFromServer(searchTerm: String? = null) {
binding.noList.visibility = View.GONE binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE binding.rvOrder.visibility = View.VISIBLE
val dateFormat = SimpleDateFormat("yyyy-MM-dd") val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val currentDate = Date() val currentDate = Date()
val today = dateFormat.format(currentDate) val today = dateFormat.format(currentDate)
val query = Firebase.firestore.collection("patientData")
.whereGreaterThanOrEqualTo("createdAt", today) // Base query to fetch patient data created today and from the specified district
var query = Firebase.firestore.collection("patientData")
// .whereGreaterThanOrEqualTo("createdAt", today)
.whereEqualTo("district", district)
.orderBy("createdAt", Query.Direction.DESCENDING) .orderBy("createdAt", Query.Direction.DESCENDING)
// If a search term is provided, add it to the query
if (!searchTerm.isNullOrEmpty()) {
query = query.whereEqualTo("_id", searchTerm)
}
query.get().addOnSuccessListener { query.get().addOnSuccessListener {
if (it.documents.isEmpty() && isOnline) { if (it.documents.isEmpty() && isOnline) {
binding.emptyRegistrations.visibility = View.VISIBLE binding.emptyRegistrations.visibility = View.VISIBLE
} }
} }
val recyclerViewOptions = val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java) FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build() .build()
val adapter = UserListOnlineAdapter(recyclerViewOptions, binding.root) val adapter = UserListOnlineAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = adapter binding.rvOrder.adapter = adapter
adapter.startListening() adapter.startListening()
} }
// private fun fetchFromServer() {
// binding.noList.visibility = View.GONE
// binding.rvOrder.visibility = View.VISIBLE
// val dateFormat = SimpleDateFormat("yyyy-MM-dd")
// val currentDate = Date()
// val today = dateFormat.format(currentDate)
// val query = Firebase.firestore.collection("patientData")
// .whereGreaterThanOrEqualTo("createdAt", today)
// .orderBy("createdAt", Query.Direction.DESCENDING)
// query.get().addOnSuccessListener {
// if (it.documents.isEmpty() && isOnline) {
// binding.emptyRegistrations.visibility = View.VISIBLE
// }
// }
// val recyclerViewOptions =
// FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
// .build()
// val adapter = UserListOnlineAdapter(recyclerViewOptions, binding.root)
// binding.rvOrder.adapter = adapter
// adapter.startListening()
// }
private fun fetchFromLocalDB() { private fun fetchFromLocalDB() {
binding.uploadData.visibility = View.GONE binding.uploadData.visibility = View.GONE
@@ -201,9 +303,9 @@ class UserListFragment : BaseFragment() {
binding.noList.visibility = View.GONE binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE binding.rvOrder.visibility = View.VISIBLE
deteleIncompleteRegistration(userDataList) deteleIncompleteRegistration(userDataList)
val adapter = UserListOfflineAdapter(binding.root) offlineAdapter = UserListOfflineAdapter(binding.root)
adapter.differ.submitList(userDataList) offlineAdapter.differ.submitList(userDataList)
binding.rvOrder.adapter = adapter binding.rvOrder.adapter = offlineAdapter
} }
} }
} }

View File

@@ -1,5 +1,7 @@
package com.example.hposregistration.ui.fragments.registration package com.example.hposregistration.ui.fragments.registration
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -19,11 +21,15 @@ import com.journeyapps.barcodescanner.ScanIntentResult
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hposregistration.databinding.FragmentAbhaRegistrationBinding import `in`.sminnovations.hposregistration.databinding.FragmentAbhaRegistrationBinding
import org.json.JSONObject import org.json.JSONObject
import java.time.Instant
import java.util.Random
@AndroidEntryPoint @AndroidEntryPoint
class AbhaRegistrationFragment : BaseFragment() { class AbhaRegistrationFragment : BaseFragment() {
private var _binding: FragmentAbhaRegistrationBinding? = null private var _binding: FragmentAbhaRegistrationBinding? = null
private lateinit var sharedPreference: SharedPreferences
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>() private val viewModel by viewModels<RegistrationViewModel>()
@@ -45,6 +51,8 @@ class AbhaRegistrationFragment : BaseFragment() {
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentAbhaRegistrationBinding.inflate(inflater, container, false) _binding = FragmentAbhaRegistrationBinding.inflate(inflater, container, false)
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root return binding.root
} }
@@ -78,22 +86,30 @@ class AbhaRegistrationFragment : BaseFragment() {
val userName = binding.etName.text.toString() val userName = binding.etName.text.toString()
val aadharIdInput = binding.aadharID.text.toString() val aadharIdInput = binding.aadharID.text.toString()
val centerName = binding.centerName.text.toString() val centerName = binding.centerName.text.toString()
val currentUnixTime = Instant.now().epochSecond
if (validateInputs(abhaIdInput, aadharIdInput, userName, centerName)) { if (validateInputs(abhaIdInput, aadharIdInput, userName, centerName)) {
userData.apply { userData.apply {
name = userName name = userName.lowercase()
aadharId = aadharIdInput aadharId = aadharIdInput
abhaId = abhaIdInput abhaId = abhaIdInput
registrationCenterName = centerName registrationCenterName = centerName
_id = aadharId + userName.substring(0, 3).uppercase() + centerName.substring(0, 3).uppercase() // _id = centerName.substring(0, 3).uppercase() + name.substring(0, 4) +
_id = userName.substring(0, 3).uppercase() + generateFourDigitNumber() +centerName.substring(0, 3).uppercase()
} }
viewModel.insert(userData) viewModel.insert(userData)
Toast.makeText(requireActivity(),"ID"+userData._id,Toast.LENGTH_SHORT).show()
navigateToUserDetailsFragment(userData._id) navigateToUserDetailsFragment(userData._id)
} }
} }
} }
private fun generateFourDigitNumber(): String {
val random = Random()
val number: Int = 1000 + random.nextInt(9000) // Ensures a 4-digit number
return number.toString()
}
private fun processScannedData(contents: String) { private fun processScannedData(contents: String) {
try { try {
@@ -167,14 +183,14 @@ class AbhaRegistrationFragment : BaseFragment() {
abhaId: String, aadharId: String, userName: String, centerName: String abhaId: String, aadharId: String, userName: String, centerName: String
): Boolean { ): Boolean {
with(binding) { with(binding) {
if (!checkAbhaIDNumber(abhaId)) { // if (!checkAbhaIDNumber(abhaId)) {
etAbhaId.error = "Invalid Abha ID" // etAbhaId.error = "Invalid Abha ID"
return false // return false
} // }
if (!checkAadharIDNumber(aadharId)) { // if (!checkAadharIDNumber(aadharId)) {
aadharID.error = "Invalid Aadhar ID" // aadharID.error = "Invalid Aadhar ID"
return false // return false
} // }
if (!checkUserName(userName)) { if (!checkUserName(userName)) {
etName.error = "Name field can't be empty or less than 3 characters" etName.error = "Name field can't be empty or less than 3 characters"
return false return false

View File

@@ -111,7 +111,7 @@ class ReviewDetailsRegistrationFragment : BaseFragment() {
requireContext().getString(R.string.abha_number, userData.abhaId) requireContext().getString(R.string.abha_number, userData.abhaId)
binding.tvAadharId.text = binding.tvAadharId.text =
requireContext().getString(R.string.aadhar_number_details, userData.aadharId) requireContext().getString(R.string.aadhar_number_details, userData.aadharId)
binding.tvUserName.text = requireContext().getString(R.string.user_name, userData.name) binding.tvUserName.text = requireContext().getString(R.string.user_name, userData.name.lowercase())
binding.tvBirthYear.text = binding.tvBirthYear.text =
requireContext().getString(R.string.birth_year_details, userData.birthYear) requireContext().getString(R.string.birth_year_details, userData.birthYear)
binding.tvGender.text = binding.tvGender.text =

View File

@@ -71,13 +71,12 @@ class UserDetailsRegistrationFragment : Fragment() {
user.phoneNumber.let { etMobile.setText(it) } user.phoneNumber.let { etMobile.setText(it) }
user.careOf.let { etCareof.setText(it) } user.careOf.let { etCareof.setText(it) }
user.maritalStatus.let { etIsMarried.setText(it, false) } user.maritalStatus.let { etIsMarried.setText(it, false) }
user.caste.let { etCaste.setText(it, false) } user.caste.let { etCaste.setText(it) }
user.category.let { etCategory.setText(it, false) } user.category.let { etCategory.setText(it, false) }
user.subCaste.let { etSubCaste.setText(it) } user.subCaste.let { etSubCaste.setText(it) }
user.house.let { etHouse.setText(it) } user.house.let { etHouse.setText(it) }
user.city.let { etCity.setText(it) } user.city.let { etCity.setText(it) }
user.district.let { etDistrict.setText(it) } user.district.let { etDistrict.setText(it, false) }
user.state.let { etState.setText(it) }
user.pinCode.let { etPincode.setText(it) } user.pinCode.let { etPincode.setText(it) }
user.isUnderMedication.let { user.isUnderMedication.let {
if (it != null) { if (it != null) {
@@ -137,8 +136,8 @@ class UserDetailsRegistrationFragment : Fragment() {
private fun verifyUserDetails(): Boolean { private fun verifyUserDetails(): Boolean {
with(binding) { with(binding) {
val yob = etYob.text.toString() val yob = etYob.text.toString()
if (yob.isEmpty() || yob.toInt() <= 1900 || yob.toInt() > 2023) { if (yob.isEmpty() || yob.toInt() <= 1900 || yob.toInt() > 2020) {
etYob.error = "Please enter a valid birth year between 1900 and 2023" etYob.error = "Please enter a valid birth year between 1900 and 2020"
return false return false
} else { } else {
userData.birthYear = yob userData.birthYear = yob
@@ -153,12 +152,13 @@ class UserDetailsRegistrationFragment : Fragment() {
} }
val mobile = etMobile.text.toString() val mobile = etMobile.text.toString()
if (mobile.isEmpty() || mobile.length != 10) {
etMobile.error = "Please enter a valid 10-digit mobile number"
return false
} else {
userData.phoneNumber = mobile userData.phoneNumber = mobile
} // if (mobile.isEmpty() || mobile.length != 10) {
// etMobile.error = "Please enter a valid 10-digit mobile number"
// return false
// } else {
// userData.phoneNumber = mobile
// }
val careOf = etCareof.text.toString() val careOf = etCareof.text.toString()
if (careOf.isEmpty()) { if (careOf.isEmpty()) {

View File

@@ -18,6 +18,7 @@
<TextView <TextView
android:id="@+id/tv_title" android:id="@+id/tv_title"
style="@style/title1" style="@style/title1"
android:visibility="gone"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@@ -31,6 +32,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/scan_now" android:text="@string/scan_now"
android:visibility="gone"
android:textColor="@color/black" android:textColor="@color/black"
app:backgroundTint="@color/primary_light" app:backgroundTint="@color/primary_light"
app:cornerRadius="100dp" app:cornerRadius="100dp"
@@ -45,6 +47,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_scan_now"> app:layout_constraintTop_toBottomOf="@id/btn_scan_now">
@@ -93,7 +96,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:text="@string/enter_abha_number_manualy" android:text="Enter Details to proceed\n(ABHA and Aadhar are optional)"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator1" /> app:layout_constraintTop_toBottomOf="@id/seperator1" />
@@ -111,6 +114,7 @@
android:id="@+id/et_name" android:id="@+id/et_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLength="24"
android:hint="@string/person_s_name" /> android:hint="@string/person_s_name" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -168,6 +172,7 @@
android:id="@+id/centerName" android:id="@+id/centerName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLength="24"
android:hint="@string/center_name" android:hint="@string/center_name"
android:inputType="text" /> android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -189,6 +194,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/proceed" android:text="@string/proceed"
android:textColor="@color/white"
app:cornerRadius="16dp" app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -200,6 +206,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnProceed"> app:layout_constraintTop_toBottomOf="@id/btnProceed">
@@ -246,6 +253,7 @@
style="@style/title1" style="@style/title1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:text="@string/create_abha_id_card" android:text="@string/create_abha_id_card"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -254,6 +262,7 @@
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_click_here" android:id="@+id/btn_click_here"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/click_here" android:text="@string/click_here"

View File

@@ -4,8 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="24dp" android:padding="24dp">
tools:context=".ui.fragments.registration.CaptureUserImageFragment">
<TextView <TextView
android:id="@+id/tv_title" android:id="@+id/tv_title"

View File

@@ -168,23 +168,19 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_caste" android:id="@+id/til_caste"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp" android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_category"> app:layout_constraintTop_toBottomOf="@id/til_category">
<com.google.android.material.textfield.TextInputEditText
<AutoCompleteTextView
android:id="@+id/et_Caste" android:id="@+id/et_Caste"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/caste" android:hint="@string/caste" />
android:inputType="none"
android:labelFor="@id/til_is_married"
app:simpleItems="@array/caste" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -234,7 +230,7 @@
android:id="@+id/et_house" android:id="@+id/et_house"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/house" /> android:hint="Address" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -256,23 +252,25 @@
android:hint="@string/city_town" /> android:hint="@string/city_town" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_district" android:id="@+id/til_district"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_city"> app:layout_constraintTop_toBottomOf="@id/til_city">
<com.google.android.material.textfield.TextInputEditText <AutoCompleteTextView
android:id="@+id/et_district" android:id="@+id/et_district"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/district" /> android:hint="@string/district"
android:inputType="none"
android:labelFor="@id/til_district"
app:simpleItems="@array/district" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -291,6 +289,7 @@
android:id="@+id/et_state" android:id="@+id/et_state"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Karnataka"
android:hint="@string/state" /> android:hint="@string/state" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>

View File

@@ -89,6 +89,15 @@
app:layout_constraintEnd_toStartOf="@+id/uploadData" app:layout_constraintEnd_toStartOf="@+id/uploadData"
app:layout_constraintTop_toTopOf="@+id/tv_title" /> app:layout_constraintTop_toTopOf="@+id/tv_title" />
<SearchView
android:id="@+id/searchUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order" android:id="@+id/rv_order"
android:layout_width="0dp" android:layout_width="0dp"
@@ -97,7 +106,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" app:layout_constraintTop_toBottomOf="@+id/searchUser"
tools:listitem="@layout/user_item_view" /> tools:listitem="@layout/user_item_view" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton

View File

@@ -56,6 +56,20 @@
app:layout_constraintStart_toEndOf="@+id/userImage" app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userName" app:layout_constraintTop_toBottomOf="@id/userName"
tools:text="UserID: MohamedKaif" /> tools:text="UserID: MohamedKaif" />
<TextView
android:id="@+id/timeCreated"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userId"
tools:text="time" />
<TextView <TextView
android:id="@+id/teststatus" android:id="@+id/teststatus"
@@ -69,7 +83,7 @@
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage" app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userId" app:layout_constraintTop_toBottomOf="@id/timeCreated"
tools:text="Test Status: Completed"/> tools:text="Test Status: Completed"/>

View File

@@ -48,7 +48,7 @@
<string name="register_user">Register User</string> <string name="register_user">Register User</string>
<string name="is_user_having_any_family_history_for_sickle_cell">Is user having any family history for Sickle Cell</string> <string name="is_user_having_any_family_history_for_sickle_cell">Is user having any family history for Sickle Cell</string>
<string name="family_history_of_sickle_cell">Family History of Sickle Cell</string> <string name="family_history_of_sickle_cell">Family History of Sickle Cell</string>
<string name="mobile_number_10_digits">Mobile Number (10 digits)</string> <string name="mobile_number_10_digits">Mobile Number(Optional)</string>
<string name="sub_caste">Sub Caste</string> <string name="sub_caste">Sub Caste</string>
<string name="capture_user_image">Capture User Image</string> <string name="capture_user_image">Capture User Image</string>
<string name="mobile_number">Mobile Number</string> <string name="mobile_number">Mobile Number</string>
@@ -156,5 +156,10 @@
<item>Female</item> <item>Female</item>
<item>Other</item> <item>Other</item>
</string-array> </string-array>
<string-array name="district">
<item>Mysuru</item>
<item>Kodagu</item>
<item>Chamarajanagar</item>
</string-array>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '8.0.2' apply false id 'com.android.application' version '8.4.0' apply false
id 'com.android.library' version '8.0.2' apply false id 'com.android.library' version '8.4.0' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
id 'androidx.navigation.safeargs' version '2.7.0-beta02' apply false id 'androidx.navigation.safeargs' version '2.7.0-beta02' apply false
id 'com.google.dagger.hilt.android' version '2.46' apply false id 'com.google.dagger.hilt.android' version '2.46' apply false

View File

@@ -1,6 +1,6 @@
#Wed Jul 12 14:05:11 IST 2023 #Wed Jul 12 14:05:11 IST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists