This commit is contained in:
mohamedkaif356
2023-06-19 16:30:43 +05:30
commit 18333f0d74
88 changed files with 4278 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

3
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
HPOS Registration

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

17
.idea/deploymentTargetDropDown.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\moham\.android\avd\BillPay.avd" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-06-19T10:21:12.395164900Z" />
</component>
</project>

21
.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$PROJECT_DIR$/../../andriod studio gradle/gradle-7.3" />
<option name="gradleJvm" value="17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

6
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.21" />
</component>
</project>

16
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
<component name="VisualizationToolProject">
<option name="state">
<ProjectState>
<option name="scale" value="0.144" />
</ProjectState>
</option>
</component>
</project>

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

100
app/build.gradle Normal file
View File

@@ -0,0 +1,100 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'dagger.hilt.android.plugin'
id 'com.google.gms.google-services'
id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-kapt'
}
android {
namespace 'com.example.hposregistration'
compileSdk 33
defaultConfig {
applicationId "com.example.hposregistration"
minSdk 26
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
buildFeatures {
viewBinding true
}
kotlinOptions {
jvmTarget = '17'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
//firebase
implementation platform('com.google.firebase:firebase-bom:32.1.0')
implementation 'com.google.firebase:firebase-firestore-ktx'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.google.android.gms:play-services-auth:20.5.0'
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
// Coroutine Lifecycle Scopes
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46"
kapt "com.google.dagger:hilt-android-compiler:2.46"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.0-beta01"
implementation "androidx.navigation:navigation-ui-ktx:2.7.0-beta01"
// Retrofit + GSON
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
// Timber
implementation 'com.jakewharton.timber:timber:4.7.1'
// Activity KTX for viewModels()
implementation "androidx.activity:activity-ktx:1.7.2"
//image
implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
//Room
implementation "androidx.room:room-ktx:2.6.0-alpha01"
implementation "androidx.room:room-runtime:2.6.0-alpha01"
kapt ("androidx.room:room-compiler:2.6.0-alpha01")
// Barcode scanner
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
}

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

@@ -0,0 +1,113 @@
{
"project_info": {
"project_number": "650071678820",
"project_id": "hpos-af3cc",
"storage_bucket": "hpos-af3cc.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:9a445bbab80173b96c6471",
"android_client_info": {
"package_name": "com.example.hpos"
}
},
"oauth_client": [
{
"client_id": "650071678820-rvst80rkqd2raoc9pvnp0k9huf3gnp4p.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.hpos",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:74c39c1cfacdc3ae6c6471",
"android_client_info": {
"package_name": "com.example.hposregistration"
}
},
"oauth_client": [
{
"client_id": "650071678820-f0c5dbjpss3av4vrvojpr6qo2h1a0fh1.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.example.hposregistration",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:ca5abf286e5e8a726c6471",
"android_client_info": {
"package_name": "com.example.refactoredapp"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

21
app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,24 @@
package com.example.hposregistration
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.hposregistration", appContext.packageName)
}
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="com.example.hposregistration.HPOSRegistrationApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.HPOSRegistration"
tools:targetApi="31">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.hposregistration.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity
android:name=".ui.activities.MainActivity"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,7 @@
package com.example.hposregistration
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class HPOSRegistrationApplication: Application()

View File

@@ -0,0 +1,49 @@
package com.example.hposregistration.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.UserItemViewBinding
class UserListOfflineAdapter(private val view: View) : RecyclerView.Adapter<UserListOfflineAdapter.CompanyViewHolder>() {
inner class CompanyViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
private val differCallback = object : DiffUtil.ItemCallback<UserData>() {
override fun areItemsTheSame(oldItem: UserData, newItem: UserData): Boolean {
return oldItem.name == newItem.name
}
override fun areContentsTheSame(oldItem: UserData, newItem: UserData): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CompanyViewHolder {
return CompanyViewHolder(
UserItemViewBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun getItemCount(): Int {
return differ.currentList.size
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val userList = differ.currentList[position]
holder.binding.apply {
userName.text = userList.name
userId.text = userList._id
Glide.with(view).load(userList.userImage).into(userImage)
}
}
}

View File

@@ -0,0 +1,35 @@
package com.example.hposregistration.adapters
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.UserItemViewBinding
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
class UserListOnlineAdapter(options: FirestoreRecyclerOptions<UserData>, private val view: View) :
FirestoreRecyclerAdapter<UserData, UserListOnlineAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrderItemViewHolder {
return OrderItemViewHolder(
UserItemViewBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
holder.binding.apply {
userName.text = model.name
userId.text = model._id
Glide.with(view).load(model.userImage).into(userImage)
}
}
}

View File

@@ -0,0 +1,27 @@
package com.example.hposregistration.dao
import androidx.room.TypeConverter
import com.example.hposregistration.data.user.UserData
import com.google.gson.Gson
class Converters {
private val gson = Gson()
@TypeConverter
fun fromString(value: String?): UserData.Location? {
return if (value != null) {
gson.fromJson(value, UserData.Location::class.java)
} else {
null
}
}
@TypeConverter
fun toString(location: UserData.Location?): String? {
return if (location != null) {
gson.toJson(location)
} else {
null
}
}
}

View File

@@ -0,0 +1,12 @@
package com.example.hposregistration.dao
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.example.hposregistration.data.user.UserData
@Database(entities = [UserData::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}

View File

@@ -0,0 +1,23 @@
package com.example.hposregistration.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.example.hposregistration.data.user.UserData
@Dao
interface UserDao {
@Query("SELECT * from user_table")
fun getAll(): LiveData<List<UserData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(userData: UserData)
@Query("SELECT * FROM user_table WHERE _id = :id")
suspend fun getUserByID(id: String): UserData
@Query("DELETE FROM user_table WHERE _id = :id")
suspend fun deleteById(id: String)
}

View File

@@ -0,0 +1,21 @@
package com.example.hposregistration.data
import com.example.hposregistration.data.user.UserData
object Constant {
fun String.fetchYOBFromDOB(): Int {
val startIndex = if (this.length >= 4) this.length - 4 else 0
return this.substring(startIndex).toInt()
}
fun String.mapToGender(): UserData.Gender {
return if (this.lowercase() == "m"|| this.lowercase() == "male") {
UserData.Gender.MALE
} else if (this.lowercase() == "f"|| this.lowercase() == "female") {
UserData.Gender.FEMALE
} else {
UserData.Gender.OTHER
}
}
}

View File

@@ -0,0 +1,58 @@
package com.example.hposregistration.data
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.lifecycle.LiveData
class NetworkStatusLiveData(context: Context) : LiveData<Boolean>() {
private val connectivityManager: ConnectivityManager =
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
postValue(true)
}
override fun onLost(network: Network) {
postValue(false)
}
}
override fun onActive() {
super.onActive()
postValue(isNetworkAvailable())
registerNetworkCallback()
}
override fun onInactive() {
super.onInactive()
unregisterNetworkCallback()
}
private fun registerNetworkCallback() {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}
private fun unregisterNetworkCallback() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
private fun isNetworkAvailable(): Boolean {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
}

View File

@@ -0,0 +1,33 @@
package com.example.hposregistration.data
import androidx.lifecycle.LiveData
import com.example.hposregistration.dao.UserDao
import com.example.hposregistration.data.user.UserData
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MainRepository @Inject constructor(
private val userDao: UserDao,
private val userFireBaseDao: com.example.hposregistration.network.UserDao
) {
val allUsers: LiveData<List<UserData>> = userDao.getAll()
suspend fun insert(userData: UserData){
userDao.insertAll(userData)
}
suspend fun getUserByID(id: String): UserData {
return userDao.getUserByID(id)
}
suspend fun deleteById(id: String) {
return userDao.deleteById(id)
}
suspend fun addDataToFirebase(userData: UserData): Response<String> {
return userFireBaseDao.addUserToDatabase(userData)
}
}

View File

@@ -0,0 +1,6 @@
package com.example.hposregistration.data
sealed class Response<out R> {
data class Success<out T>(val data: T) : Response<T>()
data class Error(val exception: Exception) : Response<Nothing>()
}

View File

@@ -0,0 +1,253 @@
package com.example.hposregistration.data
import com.example.hposregistration.data.aadhar.AadharCard
import com.example.hposregistration.data.aadhar.QrCodeException
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.math.BigInteger
import java.nio.charset.StandardCharsets
import java.util.LinkedList
import java.util.zip.GZIPInputStream
/**
* Class to decode scanned QRcode
*/
open class SecureQrCode(scanData: String?) {
private var emailMobilePresent = 0
private var imageStartIndex = 0
private var imageEndIndex = 0
private var decodedData: ArrayList<String>? = null
private var signature: String? = null
private var email: String? = null
private var mobile: String? = null
var scannedAadharCard: AadharCard = AadharCard()
init {
// 1. Convert Base10 to BigInt
val bigIntScanData = scanData?.let { BigInteger(it, 10) }
// 2. Convert BigInt to Byte Array
val byteScanData = bigIntScanData?.toByteArray()
// 3. Decompress Byte Array
val decompByteScanData = byteScanData?.let { decompressData(it) }
// 4. Split the byte array using delimiter
val parts = decompByteScanData?.let { separateData(it) }
// Throw error if there are no parts
if (parts != null) {
if (parts.isEmpty()) {
throw QrCodeException("Invalid QR Code Data, no parts found after splitting by delimiter")
}
}
// 5. decode extracted data to string
if (parts != null) {
decodeData(parts)
}
// 6. Extract Signature
if (decompByteScanData != null) {
decodeSignature(decompByteScanData)
}
// 7. Email and Mobile number
if (decompByteScanData != null) {
decodeMobileEmail(decompByteScanData)
}
}
/**
* Decompress the byte array, compression used is GZIP
* @param byteScanData compressed byte array
* @return uncompressed byte array
*/
@Throws(QrCodeException::class)
protected fun decompressData(byteScanData: ByteArray): ByteArray {
val bos = ByteArrayOutputStream(byteScanData.size)
val bin = ByteArrayInputStream(byteScanData)
val gis: GZIPInputStream = try {
GZIPInputStream(bin)
} catch (e: IOException) {
throw QrCodeException("Error in opening Gzip byte stream while decompressing QRcode", e)
}
var size = 0
val buf = ByteArray(1024)
while (size >= 0) {
try {
size = gis.read(buf, 0, buf.size)
if (size > 0) {
bos.write(buf, 0, size)
}
} catch (e: IOException) {
throw QrCodeException("Error in writing byte stream while decompressing QRcode", e)
}
}
try {
gis.close()
bin.close()
} catch (e: IOException) {
throw QrCodeException("Error in closing byte stream while decompressing QRcode", e)
}
return bos.toByteArray()
}
/**
* Function to split byte array with delimiter
* @param source source byte array
* @return list of separated byte arrays
*/
private fun separateData(source: ByteArray): List<ByteArray> {
val separatedParts: MutableList<ByteArray> = LinkedList()
var begin = 0
for (i in source.indices) {
if (source[i] == SEPARATOR_BYTE) {
// skip if first or last byte is separator
if (i != 0 && i != source.size - 1) {
separatedParts.add(source.copyOfRange(begin, i))
}
begin = i + 1
// check if we have got all the parts of text data
if (separatedParts.size == VTC_INDEX + 1) {
// this is required to extract image data
imageStartIndex = begin
break
}
}
}
return separatedParts
}
private fun decodeData(encodedData: List<ByteArray>) {
val i = encodedData.iterator()
decodedData = ArrayList()
while (i.hasNext()) {
decodedData!!.add(String(i.next(), StandardCharsets.ISO_8859_1))
}
// set the value of email/mobile present flag
emailMobilePresent = decodedData!![0].toInt()
// populate decoded data
scannedAadharCard.name = decodedData!![2]
scannedAadharCard.dateOfBirth = decodedData!![3]
scannedAadharCard.gender = decodedData!![4]
scannedAadharCard.careOf = decodedData!![5]
scannedAadharCard.district = decodedData!![6]
scannedAadharCard.landmark = decodedData!![7]
scannedAadharCard.house = decodedData!![8]
scannedAadharCard.location = decodedData!![9]
scannedAadharCard.pinCode = decodedData!![10]
scannedAadharCard.postOffice = decodedData!![11]
scannedAadharCard.state = decodedData!![12]
scannedAadharCard.street = decodedData!![13]
scannedAadharCard.subDistrict = decodedData!![14]
scannedAadharCard.vtc = decodedData!![15]
}
/**
* ref : https://uidai.gov.in/2-uncategorised/11320-aadhaar-paperless-offline-e-kyc-3.html
* Hashing logic for Email ID :
* Sha256(Sha256(Email+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
* Example :
* Email: abc@gm.com
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash : Sha256(Sha256(abc@gm.comLock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
* **********************************************************************
* **********************************************************************
* Hashing logic for Mobile Number :
* Sha256(Sha256(Mobile+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
* Example :
* Mobile: 1234567890
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash: Sha256(Sha256(1234567890Lock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
*/
private fun decodeMobileEmail(decompressedData: ByteArray) {
val mobileStartIndex: Int
val mobileEndIndex: Int
val emailStartIndex: Int
val emailEndIndex: Int
when (emailMobilePresent) {
3 -> {
// both email mobile present
mobileStartIndex = decompressedData.size - 289 // length -1 -256 -32
mobileEndIndex = decompressedData.size - 257 // length -1 -256
emailStartIndex = decompressedData.size - 322 // length -1 -256 -32 -1 -32
emailEndIndex = decompressedData.size - 290 // length -1 -256 -32 -1
mobile = bytesToHex(
decompressedData.copyOfRange(mobileStartIndex, mobileEndIndex + 1)
)
email = bytesToHex(
decompressedData.copyOfRange(emailStartIndex, emailEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 323
}
2 -> {
// only mobile
email = ""
mobileStartIndex = decompressedData.size - 289 // length -1 -256 -32
mobileEndIndex = decompressedData.size - 257 // length -1 -256
mobile = bytesToHex(
decompressedData.copyOfRange(mobileStartIndex, mobileEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 290
}
1 -> {
// only email
mobile = ""
emailStartIndex = decompressedData.size - 289 // length -1 -256 -32
emailEndIndex = decompressedData.size - 257 // length -1 -256
email = bytesToHex(
decompressedData.copyOfRange(emailStartIndex, emailEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 290
}
else -> {
// no mobile or email
mobile = ""
email = ""
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 257
}
}
}
private fun decodeSignature(decompressedData: ByteArray) {
// extract 256 bytes from the end of the byte array
val startIndex = decompressedData.size - 257
val noOfBytes = 256
signature = String(decompressedData, startIndex, noOfBytes, StandardCharsets.ISO_8859_1)
}
companion object {
protected const val SEPARATOR_BYTE = 255.toByte()
protected const val VTC_INDEX = 15
/**
* Convert byte array to hex string
*/
fun bytesToHex(bytes: ByteArray): String {
val hexArray = "0123456789ABCDEF".toCharArray()
val hexChars = CharArray(bytes.size * 2)
for (j in bytes.indices) {
val v = bytes[j].toInt() and 0xFF
hexChars[j * 2] = hexArray[v ushr 4]
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
}
return String(hexChars)
}
}
}

View File

@@ -0,0 +1,20 @@
package com.example.hposregistration.data.aadhar
class AadharCard {
var name = ""
var dateOfBirth = ""
var gender = ""
var careOf = ""
var district = ""
var landmark = ""
var house = ""
var location = ""
var pinCode = ""
var postOffice = ""
var state = ""
var street = ""
var subDistrict = ""
var vtc = ""
}

View File

@@ -0,0 +1,6 @@
package com.example.hposregistration.data.aadhar
class QrCodeException : Exception {
constructor(message: String?) : super(message) {}
constructor(message: String?, cause: Throwable?) : super(message, cause) {}
}

View File

@@ -0,0 +1,49 @@
package com.example.hposregistration.data.user
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "user_table")
data class UserData(
@PrimaryKey
var _id: String = "",
var AbhaId: String = "",
var AadharId: String = "",
var name: String = "",
var birthYear: String = "",
var gender: String = "",
var phoneNumber: String = "",
var careOf: String = "",
var maritalStatus: String = "",
var caste: String = "",
var subCaste: String = "",
var house: String = "",
var city: String = "",
var district: String = "",
var state: String = "",
var pinCode: String = "",
var bloodGroup: String = "",
var isUnderMedication: Boolean? = false,
var isUnderTransfusion: Boolean? = false,
var sickleCellHistory: String? = "",
var userImage: String = "",
var location: Location? = null,
var uploadTime: String? = "",
var testStatus: Boolean? = false,
var mobileId: String = "",
var deviceId: String = "",
var kitSerial: String = "",
var csvPath: String = "",
var reportPath: String = ""
){
enum class Gender {
MALE,
FEMALE,
OTHER
}
data class Location(
var latitude: Double? = null,
var longitude: Double? = null
)
}

View File

@@ -0,0 +1,44 @@
package com.example.hposregistration.di
import android.app.Application
import android.content.Context
import androidx.room.Room
import com.example.hposregistration.dao.MyDatabase
import com.example.hposregistration.dao.UserDao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database"
).build()
}
@Provides
@Singleton
fun provideMyDao(myDatabase: MyDatabase): UserDao {
return myDatabase.userDao()
}
@Provides
@Singleton
fun provideMyNetworkDao(): com.example.hposregistration.network.UserDao {
return com.example.hposregistration.network.UserDao()
}
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application.applicationContext
}
}

View File

@@ -0,0 +1,30 @@
package com.example.hposregistration.network
import com.example.hposregistration.data.Response
import com.example.hposregistration.data.user.UserData
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.tasks.await
class UserDao {
private val db: FirebaseFirestore = Firebase.firestore
private val patientCollection = db.collection("patientData")
suspend fun addUserToDatabase(data: UserData): Response<String> {
return try {
patientCollection.document()
.set(data)
.await()
Response.Success(data._id)
} catch (e: Exception) {
Response.Error(e)
}
}
// suspend fun getPatientList(): List<UserData> {
// return patientCollection.get().await().toObjects(UserData::class.java)
// }
}

View File

@@ -0,0 +1,18 @@
package com.example.hposregistration.ui.activities
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.hposregistration.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}

View File

@@ -0,0 +1,50 @@
package com.example.hposregistration.ui.fragments
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.journeyapps.barcodescanner.ScanOptions
open class BaseFragment: Fragment() {
fun hideProgressBar(view: View) {
view.visibility = View.GONE
}
fun showProgressBar(view: View) {
view.visibility = View.VISIBLE
}
// fun hideErrorMessage(view: View) {
// view.visibility = View.GONE
// }
//
// fun showErrorMessage(message: String, errorView: View, errorMessageView: TextView) {
// errorView.visibility = View.VISIBLE
// errorMessageView.text = message
// }
//
// fun markButtonDisable(button: Button) {
// button.isEnabled = false
// }
//
// fun markButtonEnable(button: Button) {
// button.isEnabled = true
// }
fun scanQR(scannerMessage: String): ScanOptions {
val options = ScanOptions()
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
options.setPrompt("Scan a barcode")
options.setCameraId(0)
options.setBeepEnabled(true)
options.setBarcodeImageEnabled(true)
options.setPrompt(scannerMessage)
options.setOrientationLocked(false)
return options
}
}

View File

@@ -0,0 +1,26 @@
package com.example.hposregistration.ui.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.hposregistration.databinding.FragmentProfileBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ProfileFragment : Fragment() {
private lateinit var _binding: FragmentProfileBinding
private val binding get() = _binding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentProfileBinding.inflate(layoutInflater, container, false)
return binding.root
}
}

View File

@@ -0,0 +1,161 @@
package com.example.hposregistration.ui.fragments
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.example.hposregistration.R
import com.example.hposregistration.adapters.UserListOfflineAdapter
import com.example.hposregistration.adapters.UserListOnlineAdapter
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentUserListBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class UserListFragment : BaseFragment() {
private var _binding: FragmentUserListBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private var isOnline = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentUserListBinding.inflate(inflater, container, false)
setupViews()
return binding.root
}
override fun onResume() {
super.onResume()
init()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun setupViews() {
binding.btnRegisterUser.setOnClickListener {
findNavController().navigate(R.id.action_userListFragment_to_registrationFragment)
}
}
private fun init() {
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) {
isOnline = isNetworkAvailable
fetchFromServer()
checkForLocalDBData()
} else {
isOnline = isNetworkAvailable
fetchFromLocalDB()
}
}
binding.uploadData.setOnClickListener {
showUploadDialog(requireContext())
}
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Upload DB Registration")
builder.setMessage("Do you want to upload the local DB Registration to the cloud?")
// Positive button
builder.setPositiveButton("Upload") { dialog, _ ->
uploadLoadDBData(dialog)
}
// Negative button
builder.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}
val dialog = builder.create()
dialog.show()
}
private fun uploadLoadDBData(dialog: DialogInterface) {
viewModel.allUserData.observe(viewLifecycleOwner) {
if (it.isEmpty()) {
dialog.dismiss()
} else {
it.forEach { userData ->
viewModel.addUserToDatabase(userData)
viewModel.deleteById(userData._id)
}
dialog.dismiss()
Toast.makeText(requireContext(), "Upload done successfully", Toast.LENGTH_SHORT)
.show()
}
}
}
private fun checkForLocalDBData() {
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (userDataList.isEmpty()) {
binding.uploadData.visibility = View.GONE
} else {
binding.uploadData.visibility = View.VISIBLE
}
}
}
private fun fetchFromServer() {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
val query = Firebase.firestore.collection("patientData")
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() {
binding.uploadData.visibility = View.GONE
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (isOnline) {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
} else {
if (userDataList.isEmpty()) {
binding.noList.visibility = View.VISIBLE
binding.rvOrder.visibility = View.GONE
} else {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
deteleIncompleteRegistration(userDataList)
val adapter = UserListOfflineAdapter(binding.root)
adapter.differ.submitList(userDataList)
binding.rvOrder.adapter = adapter
}
}
}
}
private fun deteleIncompleteRegistration(userDataList: List<UserData>) {
userDataList.forEach {
if (it.userImage.isEmpty()) {
viewModel.deleteById(it._id)
}
}
}
}

View File

@@ -0,0 +1,204 @@
package com.example.hposregistration.ui.fragments.registration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.hposregistration.data.Constant.fetchYOBFromDOB
import com.example.hposregistration.data.Constant.mapToGender
import com.example.hposregistration.data.SecureQrCode
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentAbhaRegistrationBinding
import com.example.hposregistration.ui.fragments.BaseFragment
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import dagger.hilt.android.AndroidEntryPoint
import org.json.JSONObject
@AndroidEntryPoint
class AbhaRegistrationFragment : BaseFragment() {
private var _binding: FragmentAbhaRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private val args: AbhaRegistrationFragmentArgs by navArgs()
private var userData = UserData()
private val barcodeLauncher =
registerForActivityResult(ScanContract()) { result: ScanIntentResult ->
if (result.contents == null) {
Toast.makeText(
requireContext(), "Cancelled: Unable to scan, Try Again!!", Toast.LENGTH_LONG
).show()
} else {
processScannedData(result.contents)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentAbhaRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
binding.btnScanNow.setOnClickListener {
barcodeLauncher.launch(scanQR("Please Scan the Abha ID/Aadhar ID"))
}
if (args.userId != "null") {
viewModel.getUserByID(args.userId)
}
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
with(binding) {
aadharID.setText(user.AadharId)
etAbhaId.setText(user.AbhaId)
etName.setText(user.name)
}
}
binding.btnProceed.setOnClickListener {
val abhaId = binding.etAbhaId.text.toString()
val userName = binding.etName.text.toString()
val aadharId = binding.aadharID.text.toString()
if (validateInputs(abhaId, aadharId, userName)) {
userData.apply {
name = userName
AadharId = aadharId
AbhaId = abhaId
_id = aadharId + userName.substring(0, 3).uppercase()
}
viewModel.insert(userData)
navigateToUserDetailsFragment(userData._id)
}
}
}
private fun processScannedData(contents: String) {
try {
val obj = JSONObject(contents)
userData.apply {
AbhaId = obj.getString("hidn").replace("-", "")
name = obj.getString("name")
birthYear = obj.getString("dob").fetchYOBFromDOB().toString()
gender = obj.getString("gender").mapToGender().toString()
phoneNumber = obj.getString("mobile")
state = obj.getString("state name")
district = obj.getString("district_name")
house = obj.getString("address")
}
if (userData.AbhaId.isNotEmpty()) {
saveUserDataAsPerAbhaId()
} else {
saveUserDataAsPerAadharId()
}
} catch (e: Exception) {
try {
val decodedData = SecureQrCode(contents)
val aadharData = decodedData.scannedAadharCard
userData.apply {
name = aadharData.name
birthYear = aadharData.dateOfBirth.fetchYOBFromDOB().toString()
gender = aadharData.gender.mapToGender().toString()
state = aadharData.state
district = aadharData.district
house = aadharData.house
}
saveUserDataAsPerAadharId()
} catch (e: Exception) {
Toast.makeText(
requireContext(),
"The QR Code you have scanned is not valid, enter the data manually",
Toast.LENGTH_SHORT
).show()
}
}
}
private fun saveUserDataAsPerAbhaId() {
with(binding) {
tvScanMessage.visibility = View.VISIBLE
tvScanMessage.text = "You have scanned the Abha ID, need to enter Aadhar ID manually"
etAbhaId.setText(userData.AbhaId)
etName.setText(userData.name)
}
Toast.makeText(
requireContext(), "You have scanned the Abha ID", Toast.LENGTH_SHORT
).show()
}
private fun saveUserDataAsPerAadharId() {
with(binding) {
tvScanMessage.text =
"You have scanned the Aadhar ID, need to enter Aadhar ID number you have scan and Abha ID manually"
etName.setText(userData.name)
}
Toast.makeText(
requireContext(), "You have scanned the Aadhar ID", Toast.LENGTH_SHORT
).show()
}
private fun validateInputs(abhaId: String, aadharId: String, userName: String): Boolean {
with(binding) {
if (!checkAbhaIDNumber(abhaId)) {
etAbhaId.error = "Invalid Abha ID"
return false
}
if (!checkAadharIDNumber(aadharId)) {
aadharID.error = "Invalid Aadhar ID"
return false
}
if (!checkUserName(userName)) {
etName.error = "Name field can't be empty or less than 3 characters"
return false
}
}
return true
}
private fun checkAbhaIDNumber(abhaId: String): Boolean {
return abhaId.isNotEmpty() || abhaId.length == 14
}
private fun checkAadharIDNumber(aadharId: String): Boolean {
return aadharId.isNotEmpty() || aadharId.length == 12
}
private fun checkUserName(userName: String): Boolean {
return userName.isNotEmpty() && userName.length >= 3
}
private fun navigateToUserDetailsFragment(userId: String) {
val action =
AbhaRegistrationFragmentDirections.actionRegistrationFragmentToUserDetailsRegistrationFragment(
userId
)
findNavController().navigate(action)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,181 @@
package com.example.hposregistration.ui.fragments.registration
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentCaptureUserImageBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.UUID
@AndroidEntryPoint
class CaptureUserImageFragment : Fragment() {
private var _binding: FragmentCaptureUserImageBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private var userData = UserData()
private lateinit var cameraLauncher: ActivityResultLauncher<Intent>
private val args: CaptureUserImageFragmentArgs by navArgs()
private lateinit var requestPermissionLauncher: ActivityResultLauncher<Array<String>>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCaptureUserImageBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
setupViewModel()
setupCameraLauncher()
setupRequestPermissionLauncher()
checkPermissionsAndPerformCameraOperation()
}
private fun setupViewModel() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
if (userData.userImage.isNotEmpty()) {
binding.userImage.loadImageFromUri(Uri.parse(user.userImage))
}
}
}
private fun setupCameraLauncher() {
cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK && result.data != null) {
val thumbnail: Bitmap = result.data!!.extras!!.get("data") as Bitmap
val uri: Uri = saveImageToInternalStorage(thumbnail)
uri.let {
binding.btnSubmit.isEnabled = true
Glide.with(requireActivity()).load(it).into(binding.userImage)
binding.btnSubmit.setOnClickListener {
submitImage(uri)
}
}
}
}
}
private fun setupRequestPermissionLauncher() {
requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
val grantedPermissions = permissions.filterValues { it }
val deniedPermissions = permissions.filterValues { !it }
if (grantedPermissions.isNotEmpty()) {
binding.userImage.setOnClickListener {
takePicture()
}
}
if (deniedPermissions.isNotEmpty()) {
requestPermissions()
}
}
}
private fun takePicture() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also {
cameraLauncher.launch(it)
}
}
private fun submitImage(uri: Uri) {
userData.userImage = uri.toString()
viewModel.insert(userData)
val action = CaptureUserImageFragmentDirections
.actionCaptureUserImageFragment2ToReviewDetailsRegistrationFragment(args.userId)
findNavController().navigate(action)
}
private fun saveImageToInternalStorage(bitmap: Bitmap): Uri {
val file = File(context?.filesDir, "${UUID.randomUUID()}.jpg")
try {
val stream: OutputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream)
stream.flush()
stream.close()
} catch (e: IOException) {
e.printStackTrace()
}
return Uri.fromFile(file)
}
private fun checkPermissionsAndPerformCameraOperation() {
val cameraPermission = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.CAMERA
)
val storagePermission = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (cameraPermission == PackageManager.PERMISSION_GRANTED &&
storagePermission == PackageManager.PERMISSION_GRANTED
) {
binding.userImage.setOnClickListener {
takePicture()
}
} else {
requestPermissions()
}
}
private fun requestPermissions() {
val permissions = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
requestPermissionLauncher.launch(permissions)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
private fun ImageView.loadImageFromUri(uri: Uri) {
Glide.with(this)
.load(uri)
.into(this)
}

View File

@@ -0,0 +1,154 @@
package com.example.hposregistration.ui.fragments.registration
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.bumptech.glide.Glide
import com.example.hposregistration.R
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentReviewDetailsRegistrationBinding
import com.example.hposregistration.ui.fragments.BaseFragment
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ReviewDetailsRegistrationFragment : BaseFragment() {
private var _binding: FragmentReviewDetailsRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private val args: ReviewDetailsRegistrationFragmentArgs by navArgs()
private var userData = UserData()
private var isOnline = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentReviewDetailsRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
setUserData(user)
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
isOnline = isNetworkAvailable
}
binding.btnSubmit.setOnClickListener {
if (isOnline) {
showProgressBar(binding.progressBarCL)
addDataToFirebase()
} else {
Toast.makeText(
requireContext(),
"Internet not available, Data stored in local DB",
Toast.LENGTH_SHORT
).show()
navigateToUserListFragment()
}
}
binding.btnEdit.setOnClickListener {
val action =
ReviewDetailsRegistrationFragmentDirections.actionReviewDetailsRegistrationFragmentToRegistrationFragment(
args.userId
)
findNavController().navigate(action)
}
viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") {
Toast.makeText(requireContext(), "Registration Done Successfully", Toast.LENGTH_SHORT)
.show()
navigateToUserListFragment()
}
}
}
private fun addDataToFirebase() {
viewModel.addUserToDatabase(userData)
viewModel.deleteById(args.userId)
}
private fun setUserData(userData: UserData) {
with(binding) {
Glide.with(requireActivity()).load(Uri.parse(userData.userImage)).into(userImage)
binding.tvUserID.text = requireContext().getString(R.string.user_id, userData._id)
binding.tvAbhaId.text =
requireContext().getString(R.string.abha_number, userData.AbhaId)
binding.tvAadharId.text =
requireContext().getString(R.string.aadhar_number_details, userData.AadharId)
binding.tvUserName.text = requireContext().getString(R.string.user_name, userData.name)
binding.tvBirthYear.text =
requireContext().getString(R.string.birth_year_details, userData.birthYear)
binding.tvGender.text =
requireContext().getString(R.string.gender_details, userData.gender)
binding.tvPhoneNumber.text =
requireContext().getString(R.string.phone_number_details, userData.phoneNumber)
binding.tvCareOf.text =
requireContext().getString(R.string.care_of_details, userData.careOf)
binding.tvMaritalStatus.text =
requireContext().getString(R.string.marital_status_details, userData.maritalStatus)
binding.tvCaste.text =
requireContext().getString(R.string.caste_details, userData.caste)
binding.tvSubCaste.text =
requireContext().getString(R.string.sub_caste_details, userData.subCaste)
binding.tvHouse.text =
requireContext().getString(R.string.house_details, userData.house)
binding.tvCity.text =
requireContext().getString(R.string.city_town_details, userData.city)
binding.tvDistrict.text =
requireContext().getString(R.string.district_details, userData.district)
binding.tvState.text =
requireContext().getString(R.string.state_details, userData.state)
binding.tvPincode.text =
requireContext().getString(R.string.pincode_details, userData.pinCode)
if (userData.isUnderMedication!!) {
binding.tvIsUnderMedication.text = requireContext().getString(
R.string.is_patient_under_any_medication_details, "Yes"
)
}
if (userData.isUnderTransfusion!!) {
binding.tvIsUnderTransfusion.text = requireContext().getString(
R.string.is_patient_undergoing_any_blood_transfusion_details, "Yes"
)
}
if (userData.sickleCellHistory != "") {
binding.tvSickleCellFamilyHistory.text = requireContext().getString(
R.string.sickle_cell_family_history, userData.sickleCellHistory
)
}
}
}
private fun navigateToUserListFragment() {
hideProgressBar(binding.progressBarCL)
val action =
ReviewDetailsRegistrationFragmentDirections.actionReviewDetailsRegistrationFragmentToUserListFragment()
findNavController().navigate(action)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,221 @@
package com.example.hposregistration.ui.fragments.registration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentUserDetailsRegistrationBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class UserDetailsRegistrationFragment : Fragment() {
private var _binding: FragmentUserDetailsRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private lateinit var userData: UserData
private val args: UserDetailsRegistrationFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentUserDetailsRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
setupViewModel()
setupSubmitButton()
}
private fun setupViewModel() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) {
userData = it
autoFillUserData(userData)
}
}
private fun autoFillUserData(user: UserData) {
with(binding) {
user.birthYear.let { etYob.setText(it) }
user.gender.let { etGenderBlock.setText(it, false) }
user.phoneNumber.let { etMobile.setText(it) }
user.careOf.let { etCareof.setText(it) }
user.maritalStatus.let { etIsMarried.setText(it, false) }
user.caste.let { etCategory.setText(it, false) }
user.subCaste.let { etSubCaste.setText(it) }
user.house.let { etHouse.setText(it) }
user.city.let { etCity.setText(it) }
user.district.let { etDistrict.setText(it) }
user.state.let { etState.setText(it) }
user.pinCode.let { etPincode.setText(it) }
user.bloodGroup.let { etBloodGroup.setText(it, false) }
cbItem1.isChecked = user.isUnderMedication ?: false
cbItem2.isChecked = user.isUnderTransfusion ?: false
}
}
private fun setupSubmitButton() {
binding.btnSubmit.setOnClickListener {
if (verifyUserDetails()) {
userData._id = args.userId
viewModel.insert(userData)
navigateToCaptureUserImageFragment()
} else {
showToast("Please enter all the details properly")
}
}
}
private fun navigateToCaptureUserImageFragment() {
val action = UserDetailsRegistrationFragmentDirections
.actionUserDetailsRegistrationFragmentToCaptureUserImageFragment2(args.userId)
findNavController().navigate(action)
}
private fun verifyUserDetails(): Boolean {
with(binding) {
val yob = etYob.text.toString()
if (yob.isEmpty() || yob.toInt() <= 1900 || yob.toInt() > 2023) {
etYob.error = "Please enter a valid birth year between 1900 and 2023"
return false
} else {
userData.birthYear = yob
}
val gender = etGenderBlock.text.toString()
if (gender.isEmpty()) {
etGenderBlock.error = "Please enter your gender"
return false
} else {
userData.gender = gender
}
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
}
val careOf = etCareof.text.toString()
if (careOf.isEmpty()) {
etCareof.error = "Please enter your name"
return false
} else {
userData.careOf = careOf
}
val maritalStatus = etIsMarried.text.toString()
if (maritalStatus.isEmpty()) {
etIsMarried.error = "Please enter your marital status"
return false
} else {
userData.maritalStatus = maritalStatus
}
val category = etCategory.text.toString()
if (category.isEmpty()) {
etCategory.error = "Please enter your caste"
return false
} else {
userData.caste = category
}
val subCaste = etSubCaste.text.toString()
if (subCaste.isEmpty()) {
etSubCaste.error = "Please enter your sub caste"
return false
} else {
userData.subCaste = subCaste
}
val house = etHouse.text.toString()
if (house.isEmpty()) {
etHouse.error = "Please enter your house address"
return false
} else {
userData.house = house
}
val city = etCity.text.toString()
if (city.isEmpty()) {
etCity.error = "Please enter your city"
return false
} else {
userData.city = city
}
val district = etDistrict.text.toString()
if (district.isEmpty()) {
etDistrict.error = "Please enter your district"
return false
} else {
userData.district = district
}
val state = etState.text.toString()
if (state.isEmpty()) {
etState.error = "Please enter your state"
return false
} else {
userData.state = state
}
val pincode = etPincode.text.toString()
if (pincode.isEmpty() || pincode.length != 6) {
etPincode.error = "Please enter a valid 6-digit pin code"
return false
} else {
userData.pinCode = pincode
}
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.isEmpty()) {
etBloodGroup.error = "Please enter your blood group"
return false
} else {
userData.bloodGroup = bloodGroup
}
userData.isUnderMedication = cbItem1.isChecked
userData.isUnderTransfusion = cbItem2.isChecked
val familyHistory = etFamilyHistory.text.toString()
if (familyHistory.isEmpty()) {
etFamilyHistory.error = "Please enter your family history"
return false
} else {
userData.sickleCellHistory = familyHistory
}
return true
}
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,76 @@
package com.example.hposregistration.ui.viewmodels
import android.content.Context
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hposregistration.data.MainRepository
import com.example.hposregistration.data.NetworkStatusLiveData
import com.example.hposregistration.data.Response
import com.example.hposregistration.data.user.UserData
import com.google.firebase.storage.FirebaseStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class RegistrationViewModel @Inject constructor(
private val mainRepository: MainRepository,
context: Context
) : ViewModel() {
val userData = MutableLiveData<UserData>()
val allUserData = mainRepository.allUsers
val fireBaseUpload = MutableLiveData<String>()
fun addUserToDatabase(userData: UserData) = viewModelScope.launch {
val file = Uri.parse(userData.userImage)
val storageRef = FirebaseStorage.getInstance().reference
val imageRef = storageRef.child("${userData._id}/${file.lastPathSegment}")
val uploadTask = file.let { imageRef.putFile(it) }
uploadTask.continueWithTask { task ->
if (!task.isSuccessful) {
throw task.exception!!
}
imageRef.downloadUrl
}.addOnSuccessListener { uri ->
userData.userImage = uri.toString()
addDataToFirebase(userData)
}.addOnFailureListener { exception ->
}
}
private fun addDataToFirebase(userData: UserData) = viewModelScope.launch {
when (mainRepository.addDataToFirebase(userData)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
else -> {
}
}
}
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
fun insert(userData: UserData) = viewModelScope.launch {
mainRepository.insert(userData)
}
fun getUserByID(userId: String) = viewModelScope.launch {
userData.postValue(mainRepository.getUserByID(id = userId))
}
fun deleteById(userId: String) = viewModelScope.launch {
mainRepository.deleteById(id = userId)
}
}

View File

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/black" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M9.5,6.5v3h-3v-3H9.5M11,5H5v6h6V5L11,5zM9.5,14.5v3h-3v-3H9.5M11,13H5v6h6V13L11,13zM17.5,6.5v3h-3v-3H17.5M19,5h-6v6h6V5L19,5zM13,13h1.5v1.5H13V13zM14.5,14.5H16V16h-1.5V14.5zM16,13h1.5v1.5H16V13zM13,16h1.5v1.5H13V16zM14.5,17.5H16V19h-1.5V17.5zM16,16h1.5v1.5H16V16zM17.5,14.5H19V16h-1.5V14.5zM17.5,17.5H19V19h-1.5V17.5zM22,7h-2V4h-3V2h5V7zM22,22v-5h-2v3h-3v2H22zM2,22h5v-2H4v-3H2V22zM2,2v5h2V4h3V2H2z"/>
</vector>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360">
<shape
android:shape="ring"
android:innerRadiusRatio="3"
android:thicknessRatio="8"
android:useLevel="false">
<size
android:width="76dip"
android:height="76dip" />
<gradient
android:type="sweep"
android:useLevel="false"
android:startColor="@color/primary"
android:endColor="#00ffffff"
android:angle="0"/>
</shape>
</rotate>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="@color/primary"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/primary" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z"/>
</vector>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ui.activities.MainActivity">
<fragment
android:id="@+id/homeFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/main_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,295 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ui.fragments.registration.AbhaRegistrationFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/scan_person_abha_id_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_scan_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/scan_now"
android:textColor="@color/black"
app:backgroundTint="@color/primary_light"
app:cornerRadius="100dp"
app:icon="@drawable/ic_qr_code_scanner"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/seperator1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_scan_now">
<TextView
android:id="@+id/tvText1"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/or"
android:textColor="@color/gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_margin="5dp"
android:background="@color/gray"
app:layout_constraintBottom_toBottomOf="@id/tvText1"
app:layout_constraintEnd_toStartOf="@id/tvText1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tvText1" />
<View
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_margin="5dp"
android:background="@color/gray"
app:layout_constraintBottom_toBottomOf="@id/tvText1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tvText1"
app:layout_constraintTop_toTopOf="@id/tvText1" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_title2"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/enter_abha_number_manualy"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator1" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_name"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title2">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/person_s_name" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_abhaId_holder"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_name">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etAbhaId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/abha_id"
android:inputType="number"
android:maxLength="14" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_aadharID"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_abhaId_holder">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/aadharID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/aadhaar_number"
android:inputType="number"
android:maxLength="12" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tv_scanMessage"
style="@style/title2"
android:visibility="gone"
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_aadharID" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnProceed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/proceed"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_scanMessage" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/seperator2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnProceed">
<TextView
android:id="@+id/tvText2"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/or"
android:textColor="@color/gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view3"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_margin="5dp"
android:background="@color/gray"
app:layout_constraintBottom_toBottomOf="@id/tvText2"
app:layout_constraintEnd_toStartOf="@id/tvText2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tvText2" />
<View
android:id="@+id/view4"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_margin="5dp"
android:background="@color/gray"
app:layout_constraintBottom_toBottomOf="@id/tvText2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tvText2"
app:layout_constraintTop_toTopOf="@id/tvText2" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_title3"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/create_abha_id_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator2" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_click_here"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/click_here"
android:textColor="@color/black"
app:backgroundTint="@color/primary_light"
app:cornerRadius="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/errorMessageCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/itemErrorMessage"
layout="@layout/item_error_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/progressBarCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:visibility="gone">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/progressbar_costume_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:padding="24dp"
tools:context=".ui.fragments.registration.CaptureUserImageFragment">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/capture_user_image"
app:layout_constraintBottom_toTopOf="@+id/userImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/userImage"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
style="@style/title1_1"
android:layout_width="258dp"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:enabled="false"
android:text="@string/review"
app:cornerRadius="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,10 @@
<?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"
tools:context=".ui.fragments.ProfileFragment"
android:padding="24dp">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,301 @@
<?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"
tools:context=".ui.fragments.registration.ReviewDetailsRegistrationFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="24dp">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/user_details"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/userImage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<TextView
android:id="@+id/tvUserID"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage" />
<TextView
android:id="@+id/tvAbhaId"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvUserID" />
<TextView
android:id="@+id/tvAadharId"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAbhaId" />
<TextView
android:id="@+id/tvUserName"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAadharId" />
<TextView
android:id="@+id/tvBirthYear"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvUserName" />
<TextView
android:id="@+id/tvGender"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvBirthYear" />
<TextView
android:id="@+id/tvPhoneNumber"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvGender" />
<TextView
android:id="@+id/tvCareOf"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPhoneNumber" />
<TextView
android:id="@+id/tvMaritalStatus"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCareOf" />
<TextView
android:id="@+id/tvCaste"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvMaritalStatus" />
<TextView
android:id="@+id/tvSubCaste"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaste" />
<TextView
android:id="@+id/tvHouse"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSubCaste" />
<TextView
android:id="@+id/tvCity"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvHouse" />
<TextView
android:id="@+id/tvDistrict"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCity" />
<TextView
android:id="@+id/tvState"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDistrict" />
<TextView
android:id="@+id/tvPincode"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvState" />
<TextView
android:id="@+id/tvIsUnderMedication"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPincode" />
<TextView
android:id="@+id/tvIsUnderTransfusion"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvIsUnderMedication" />
<TextView
android:id="@+id/tvSickleCellFamilyHistory"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvIsUnderTransfusion" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/proceed"
app:cornerRadius="100dp"
app:layout_constraintStart_toEndOf="@id/btn_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvSickleCellFamilyHistory" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_edit"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/edit"
app:cornerRadius="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_submit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvSickleCellFamilyHistory" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/errorMessageCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="@+id/itemErrorMessage"
layout="@layout/item_error_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/progressBarCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:visibility="gone">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/progressbar_costume_view"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,374 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ui.fragments.registration.UserDetailsRegistrationFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/enter_person_s_details"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_yob"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_yob"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/birth_year"
android:inputType="number"
android:maxLength="4" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_gender"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_yob">
<AutoCompleteTextView
android:id="@+id/et_gender_block"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/gender"
android:inputType="none"
android:labelFor="@id/til_gender"
app:simpleItems="@array/gender" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_mobile"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_gender">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_mobile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/mobile_number_10_digits"
android:inputType="number"
android:maxLength="10" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_careof"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_mobile">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_careof"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/father_s_husband_s_name" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_is_married"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_careof">
<AutoCompleteTextView
android:id="@+id/et_is_married"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/marital_status"
android:inputType="none"
android:labelFor="@id/til_is_married"
app:simpleItems="@array/marital_status" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_category"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_is_married">
<AutoCompleteTextView
android:id="@+id/et_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/caste"
android:inputType="none"
android:labelFor="@id/til_category"
app:simpleItems="@array/category" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_subCaste"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_category">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_subCaste"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/sub_caste" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tv_title2"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:text="@string/person_s_address_details"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_subCaste" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_house"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title2">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_house"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/house" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_city"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_house">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/city_town" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_district"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_city">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_district"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/district" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_state"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_district">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/state" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_pincode"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_state">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_pincode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/pincode"
android:inputType="number"
android:maxLength="6" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tv_title3"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:text="@string/patient_medical_records"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_pincode" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title3">
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/cb_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/is_patient_under_any_medication"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_blood_group" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/cb_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:text="@string/is_patient_undergoing_any_blood_transfusion"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cb_item1" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_familyHistory"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cb_item2">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_familyHistory"
android:layout_width="match_parent"
android:layout_height="90dp"
android:hint="@string/family_history_of_sickle_cell"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/proceed"
android:focusable="false"
app:cornerRadius="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_familyHistory" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,67 @@
<?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"
tools:context=".ui.fragments.UserListFragment"
android:padding="24dp">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_details"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/noList"
style="@style/title1"
android:visibility="gone"
android:gravity="center"
android:text="@string/internet_is_not_available_and_there_is_no_data_available_in_local_db"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/uploadData"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/upload_data"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:listitem="@layout/user_item_view"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnRegisterUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:elevation="1dp"
android:layout_margin="8dp"
android:src="@drawable/ic_add"
android:backgroundTint="@color/primary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/register_user" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp"
app:cardCornerRadius="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tvErrorMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_weight="2"
android:gravity="center_horizontal"
android:textSize="22sp"
android:textColor="@color/primary"
android:text="@string/failed_to_connect"
android:textAlignment="center" />
<Button
android:id="@+id/btnRetry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_weight="1"
android:text="@string/retry" />
<Button
android:id="@+id/btnCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_weight="1"
android:text="@string/cancel" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,60 @@
<?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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/newPaperCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/primary_light"
app:cardCornerRadius="25dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp">
<ImageView
android:id="@+id/userImage"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/userName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage" />
<TextView
android:id="@+id/userId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userName" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/main_nav_graph"
app:startDestination="@id/userListFragment">
<fragment
android:id="@+id/registrationFragment"
android:name="com.example.hposregistration.ui.fragments.registration.AbhaRegistrationFragment"
android:label="fragment_registration"
tools:layout="@layout/fragment_abha_registration" >
<action
android:id="@+id/action_registrationFragment_to_userDetailsRegistrationFragment"
app:destination="@id/userDetailsRegistrationFragment" />
<argument
android:name="userId"
app:argType="string"
android:defaultValue="null" />
</fragment>
<fragment
android:id="@+id/userListFragment"
android:name="com.example.hposregistration.ui.fragments.UserListFragment"
android:label="fragment_user_list"
tools:layout="@layout/fragment_user_list" >
<action
android:id="@+id/action_userListFragment_to_registrationFragment"
app:destination="@id/registrationFragment" />
</fragment>
<fragment
android:id="@+id/profileFragment"
android:name="com.example.hposregistration.ui.fragments.ProfileFragment"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
<fragment
android:id="@+id/userDetailsRegistrationFragment"
android:name="com.example.hposregistration.ui.fragments.registration.UserDetailsRegistrationFragment"
android:label="fragment_user_details_registration"
tools:layout="@layout/fragment_user_details_registration" >
<argument
android:name="userId"
app:argType="string" />
<action
android:id="@+id/action_userDetailsRegistrationFragment_to_captureUserImageFragment2"
app:destination="@id/captureUserImageFragment2" />
</fragment>
<fragment
android:id="@+id/reviewDetailsRegistrationFragment"
android:name="com.example.hposregistration.ui.fragments.registration.ReviewDetailsRegistrationFragment"
android:label="fragment_review_details_registration"
tools:layout="@layout/fragment_review_details_registration" >
<argument
android:name="userId"
app:argType="string" />
<action
android:id="@+id/action_reviewDetailsRegistrationFragment_to_userListFragment"
app:destination="@id/userListFragment"
app:popUpTo="@id/main_nav_graph"
app:popUpToInclusive="true"/>
<action
android:id="@+id/action_reviewDetailsRegistrationFragment_to_registrationFragment"
app:destination="@id/registrationFragment"
app:popUpTo="@id/main_nav_graph"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="@+id/captureUserImageFragment2"
android:name="com.example.hposregistration.ui.fragments.registration.CaptureUserImageFragment"
android:label="fragment_capture_user_image"
tools:layout="@layout/fragment_capture_user_image" >
<action
android:id="@+id/action_captureUserImageFragment2_to_reviewDetailsRegistrationFragment"
app:destination="@id/reviewDetailsRegistrationFragment" />
<argument
android:name="userId"
app:argType="string"
android:defaultValue="null" />
</fragment>
</navigation>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#4daaff</color>
<color name="primary_dark">#005db3</color>
<color name="primary_light">#e5f3ff</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="gray">#808080</color>
<color name="red">#FF0000</color>
</resources>

View File

@@ -0,0 +1,109 @@
<resources>
<string name="app_name">HPOS Registration</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
//Error message
<string name="retry">Retry</string>
<string name="failed_to_connect">Failed to connect</string>
<string name="cancel">Cancel</string>
//Registration Screens
<string name="scan_person_abha_id_card">Scan Person ABHA ID/Aadhar ID Card</string>
<string name="scan_now">Scan Now</string>
<string name="or">OR</string>
<string name="enter_abha_number_manualy">Enter ABHA and Aadhar Number</string>
<string name="abha_id">ABHA Number</string>
<string name="create_abha_id_card">Create ABHA ID card</string>
<string name="click_here">Click Here</string>
<string name="scan_person_s_aadhaar_card">Scan Person\'s Aadhaar Card</string>
<string name="proceed">Proceed</string>
<string name="enter_aadhaar_number_manualy">Enter Aadhaar number manualy</string>
<string name="aadhaar_number">Aadhaar Number</string>
<string name="enter_person_s_details">Enter Person\'s Details</string>
<string name="person_s_name">Person\'s Name</string>
<string name="age">Age in years</string>
<string name="gender">Gender</string>
<string name="name_error">Name can\'t be empty</string>
<string name="age_error">Age can\'t be empty</string>
<string name="gender_error">Gender can\'t be empty</string>
<string name="age_error_out_of_bound">Age should be valid</string>
<string name="birth_year">Birth Year</string>
<string name="marital_status">Marital status</string>
<string name="father_s_husband_s_name">Father\'s/Husband\'s Name</string>
<string name="caste">Caste</string>
<string name="person_s_address_details">Person\'s Address Details</string>
<string name="district">District</string>
<string name="city_town">City / Town</string>
<string name="state">State</string>
<string name="pincode">Pincode</string>
<string name="patient_medical_records">Patient Medical Records</string>
<string name="review">Review</string>
<string name="blood_group">Blood Group</string>
<string name="house">House</string>
<string name="is_patient_under_any_medication">Is user under any medication or treatment?</string>
<string name="is_patient_undergoing_any_blood_transfusion">Is user undergoing any blood transfusion?</string>
<string name="user_list">User List</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="family_history_of_sickle_cell">Family History of Sickle Cell</string>
<string name="mobile_number_10_digits">Mobile Number (10 digits)</string>
<string name="sub_caste">Sub Caste</string>
<string name="capture_user_image">Capture User Image</string>
<string name="mobile_number">Mobile Number</string>
<string name="edit">Edit</string>
<string name="user_details">User Details</string>
<string name="internet_is_not_available_and_there_is_no_data_available_in_local_db">Internet is not available and there is no Data available in Local DB</string>
<string name="user_id">User ID: %1$s</string>
<string name="abha_number">Abha Number: %1$s</string>
<string name="aadhar_number_details">Aadhar Number: %1$s</string>
<string name="user_name">Person\'s Name: %1$s</string>
<string name="birth_year_details">Birth Year: %1$s</string>
<string name="gender_details">Gender: %1$s</string>
<string name="phone_number_details">Mobile Number: %1$s</string>
<string name="care_of_details">Father\'s/Husband\'s Name: %1$s</string>
<string name="marital_status_details">Marital Status: %1$s</string>
<string name="caste_details">Caste: %1$s</string>
<string name="sub_caste_details">Sub Caste: %1$s</string>
<string name="house_details">House: %1$s</string>
<string name="city_town_details">City/Town: %1$s</string>
<string name="district_details">District: %1$s</string>
<string name="state_details">State: %1$s</string>
<string name="pincode_details">Pincode: %1$s</string>
<string name="is_patient_under_any_medication_details">Is Under Medication: %1$s</string>
<string name="is_patient_undergoing_any_blood_transfusion_details">Is Under Blood Transfusion: %1$s</string>
<string name="sickle_cell_family_history">Sickle cell Family History: %1$s</string>
<string-array name="category">
<item>GEN</item>
<item>OBC</item>
<item>SC</item>
<item>ST</item>
</string-array>
<string-array name="marital_status">
<item>Married</item>
<item>Single</item>
<item>Divorce</item>
</string-array>
<string-array name="blood_group">
<item>O+ve</item>
<item>O-ve</item>
<item>A+ve</item>
<item>A-ve</item>
<item>B+ve</item>
<item>B-ve</item>
<item>AB+ve</item>
<item>AB-ve</item>
</string-array>
<string-array name="gender">
<item>Male</item>
<item>Female</item>
<item>Other</item>
</string-array>
</resources>

View File

@@ -0,0 +1,55 @@
<resources>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
<item name="colorControlNormal">@color/white</item>
</style>
<style name="title1">
<item name="android:textSize">20sp</item>
<item name="android:letterSpacing">-0.01</item>
<item name="android:textColor">@color/black</item>
<item name="fontFamily">@font/poppins_bold</item>
<item name="android:translationY">-0.62sp</item>
</style>
<style name="title1_1">
<item name="android:textSize">18sp</item>
<item name="android:letterSpacing">-0.01</item>
<item name="android:textColor">@color/black</item>
<item name="fontFamily">@font/poppins_semi_bold</item>
<item name="android:translationY">-0.62sp</item>
</style>
<style name="title1_2">
<item name="android:textSize">16sp</item>
<item name="android:letterSpacing">-0.01</item>
<item name="android:textColor">@color/black</item>
<item name="fontFamily">@font/poppins_medium</item>
<item name="android:translationY">-0.62sp</item>
</style>
<style name="title2">
<item name="android:textSize">14sp</item>
<item name="android:letterSpacing">-0.01</item>
<item name="android:textColor">@color/black</item>
<item name="fontFamily">@font/poppins_regular</item>
<item name="android:translationY">-0.62sp</item>
</style>
<style name="title2_5">
<item name="android:textSize">12sp</item>
<item name="android:letterSpacing">-0.01</item>
<item name="android:textColor">@color/black</item>
<item name="fontFamily">@font/poppins_light</item>
<item name="android:translationY">-0.62sp</item>
</style>
</resources>

View File

@@ -0,0 +1,13 @@
<resources>
<!-- Base application theme. -->
<style name="Theme.HPOSRegistration" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryVariant">@color/black</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" >@color/white</item>
<item name="android:windowLightStatusBar">true</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="photos" path="." />
</paths>

View File

@@ -0,0 +1,17 @@
package com.example.hposregistration
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

9
build.gradle Normal file
View File

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

25
gradle.properties Normal file
View File

@@ -0,0 +1,25 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Wed Jun 14 15:14:47 IST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

16
settings.gradle Normal file
View File

@@ -0,0 +1,16 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "HPOS Registration"
include ':app'