diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/CanFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/CanFragment.kt
index 8c028af..cdf9e4e 100644
--- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/CanFragment.kt
+++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/CanFragment.kt
@@ -1,7 +1,6 @@
package com.tarkvaraprojekt.mobileauthapp
import android.app.AlertDialog
-import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -15,7 +14,9 @@ import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
/**
- * Fragment that deals with asking the user for six digit CAN
+ * Fragment that deals with asking the user for a six digit CAN. If the CAN is already saved
+ * then the fragment is skipped immediately and if the CAN is not saved then the user
+ * is asked whether it should be saved for the future or not before continuing.
*/
class CanFragment : Fragment() {
@@ -23,7 +24,10 @@ class CanFragment : Fragment() {
private var binding: FragmentCanBinding? = null
- // Navigation arguments. saving = true means that we are navigating here from the settings menu and must return to the settings
+ // Navigation arguments:
+ // saving = true means that we are navigating here from the settings menu and must return to the settings menu.
+ // reading = true means that we are only reading the information from the ID card that does not need PIN 1,
+ // this information is passed on to the next PinFragment.
private val args: CanFragmentArgs by navArgs()
override fun onCreateView(
@@ -37,62 +41,90 @@ class CanFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (viewModel.userCan.length == 6) {
- skip()
- }
+ checkIfSkip()
+ // If the user arrives from the settings menu then the button should say
+ // save instead of continue.
if (args.saving) {
binding!!.nextButton.text = getString(R.string.save_text)
}
- binding!!.nextButton.setOnClickListener { goToNextFragment() }
+ binding!!.nextButton.setOnClickListener { checkEnteredCan() }
binding!!.cancelButton.setOnClickListener { goToTheStart() }
}
- // If CAN is already set
- private fun skip() {
- findNavController().navigate(R.id.action_canFragment_to_pinFragment)
- }
-
- // Might need some rework, must break it up and make logic better.
- private fun goToNextFragment() {
- val enteredCan = binding!!.canEditText.editText?.text.toString()
- if (enteredCan.length != 6) {
- Toast.makeText(requireContext(), getString(R.string.length_can), Toast.LENGTH_SHORT)
- .show()
- } else {
- viewModel.setUserCan(
- binding!!.canEditText.editText?.text.toString()
- )
- if (args.saving) {
- viewModel.storeCan(requireContext())
- findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
- } else {
- val canStoreQuestion: AlertDialog? = activity?.let { frag ->
- val builder = AlertDialog.Builder(frag)
- builder.apply {
- setPositiveButton(R.string.save_text) { _, _ ->
- viewModel.storeCan(
- requireContext()
- )
- findNavController().navigate(R.id.action_canFragment_to_pinFragment)
- }
- setNegativeButton(R.string.deny_text) { _, _ ->
- findNavController().navigate(R.id.action_canFragment_to_pinFragment)
- }
- }
- builder.setMessage(R.string.can_save_request)
- builder.setTitle(R.string.save_can_title)
- builder.create()
- }
- canStoreQuestion?.show()
- }
+ /**
+ * Checks if the current fragment can be skipped or not.
+ * If the user has CAN saved on the device there is no need to ask it again.
+ */
+ private fun checkIfSkip() {
+ if (viewModel.userCan.length == 6) {
+ goToTheNextFragment()
}
}
+ /**
+ * Takes user to the next fragment, which is PinFragment.
+ */
+ private fun goToTheNextFragment() {
+ val action = CanFragmentDirections.actionCanFragmentToPinFragment(reading = args.reading)
+ findNavController().navigate(action)
+ }
+
+ /**
+ * Checks whether the user has entered a 6 digit can to the input field.
+ * If yes then the user is allowed to continue otherwise the user is
+ * allowed to modify the entered can.
+ */
+ private fun checkEnteredCan() {
+ val enteredCan = binding!!.canEditText.editText?.text.toString()
+ if (enteredCan.length == 6) {
+ viewModel.setUserCan(enteredCan)
+ if (args.saving) {
+ viewModel.storeCan(requireContext())
+ goToTheStart()
+ } else {
+ val storeCanQuestion = getDialog()
+ storeCanQuestion?.show()
+ }
+ } else {
+ Toast.makeText(requireContext(), getString(R.string.length_can), Toast.LENGTH_SHORT)
+ .show()
+ }
+ }
+
+ /**
+ * Builds a dialog that asks the user whether the entered CAN should be saved
+ * on the device or not.
+ */
+ private fun getDialog(): AlertDialog? {
+ return activity?.let { frag ->
+ val builder = AlertDialog.Builder(frag)
+ builder.apply {
+ // If response is positive then save the CAN on the device.
+ setPositiveButton(R.string.save_text) { _, _ ->
+ viewModel.storeCan(
+ requireContext()
+ )
+ goToTheNextFragment()
+ }
+ setNegativeButton(R.string.deny_text) { _, _ ->
+ goToTheNextFragment()
+ }
+ }
+ builder.setMessage(R.string.can_save_request)
+ builder.setTitle(R.string.save_can_title)
+ builder.create()
+ }
+ }
+
+ /**
+ * Navigates the user back to the start depending on where the user arrived.
+ * If the user arrived from the settings menu then the start is the settings menu
+ * not the HomeFragment.
+ */
private fun goToTheStart() {
if (args.saving) {
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
} else {
- viewModel.clearUserInfo()
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
}
}
diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt
index 75a9ebf..77a2552 100644
--- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt
+++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/HomeFragment.kt
@@ -1,7 +1,6 @@
package com.tarkvaraprojekt.mobileauthapp
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -11,6 +10,13 @@ import androidx.navigation.fragment.findNavController
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
+/**
+ * HomeFragment is only shown to the user when then the user launches the application. When the application
+ * is launched by another application or a website then this Fragment will be skipped.
+ * This fragment uses the fields from the MainActivity by casting the activity to MainActivity.
+ * This might not be the best practice, but the application uses a single activity design so it should
+ * always work.
+ */
class HomeFragment : Fragment() {
private val viewModel: SmartCardViewModel by activityViewModels()
@@ -23,18 +29,72 @@ class HomeFragment : Fragment() {
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
+ // Making settings menu active again
+ (activity as MainActivity).menuAvailable = true
return binding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- viewModel.checkCan(requireContext())
- viewModel.checkPin(requireContext())
- binding!!.beginButton.setOnClickListener { goToNextFragment() }
+ initialChecks()
+ binding!!.beginButton.setOnClickListener { goToTheNextFragment() }
}
- private fun goToNextFragment() {
- findNavController().navigate(R.id.action_homeFragment_to_canFragment)
+ /**
+ * Method where all the initial checks that should be done before any user input is accepted should be added.
+ */
+ private fun initialChecks() {
+ viewModel.checkCan(requireContext())
+ viewModel.checkPin(requireContext())
+ displayStates()
+ }
+
+ /**
+ * Starts the process of interacting with the ID card by sending user to the CAN fragment.
+ */
+ private fun goToTheNextFragment() {
+ // Making settings menu inactive
+ (activity as MainActivity).menuAvailable = false
+ // Currently saving is true because the application is not yet integrated with
+ // other applications or websites.
+ val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true)
+ findNavController().navigate(action)
+ }
+
+ /**
+ * Displays texts that inform the user whether the CAN and PIN 1 are saved on the device or not.
+ * This might help the user to save some time as checking menu is not necessary unless the user
+ * wishes to make changes to the saved CAN or PIN 1.
+ */
+ private fun displayStates() {
+ canState()
+ pinState()
+ }
+
+ /**
+ * Checks the state of the CAN, saved or not saved. Updates the text and logo.
+ */
+ private fun canState() {
+ if (viewModel.userCan.length == 6) {
+ binding!!.canStatusText.text = getString(R.string.can_status_saved)
+ binding!!.canStatusLogo.setImageResource(R.drawable.ic_check_logo)
+ } else {
+ binding!!.canStatusText.text = getString(R.string.can_status_negative)
+ binding!!.canStatusLogo.setImageResource(R.drawable.ic_info_logo)
+ }
+ }
+
+ /**
+ * Checks the state of the PIN 1, saved or not saved. Updates the text and logo.
+ */
+ private fun pinState() {
+ if (viewModel.userPin.length in 4..12) {
+ binding!!.pinStatusText.text = getString(R.string.pin_status_saved)
+ binding!!.pinStatusLogo.setImageResource(R.drawable.ic_check_logo)
+ } else {
+ binding!!.pinStatusText.text = getString(R.string.pin_status_negative)
+ binding!!.pinStatusLogo.setImageResource(R.drawable.ic_info_logo)
+ }
}
override fun onDestroyView() {
diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/MainActivity.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/MainActivity.kt
index f1e4353..638d88e 100644
--- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/MainActivity.kt
+++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/MainActivity.kt
@@ -1,22 +1,25 @@
package com.tarkvaraprojekt.mobileauthapp
-import android.nfc.NfcAdapter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
-import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.navigation.NavController
-import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import com.tarkvaraprojekt.mobileauthapp.databinding.ActivityMainBinding
-import java.util.*
+
+/**
+ * The only activity of the application (single activity design).
+ */
class MainActivity : AppCompatActivity() {
private lateinit var navigationController: NavController
+ // If true the settings menu can be accessed from the toolbar in the upper part of the screen.
+ var menuAvailable: Boolean = true
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
@@ -35,10 +38,14 @@ class MainActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.menu_settings_option -> {
- navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
- true
+ if (menuAvailable) {
+ navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
+ true
+ } else {
+ Toast.makeText(this, getString(R.string.unavailable), Toast.LENGTH_SHORT).show()
+ false
+ }
}
else -> super.onOptionsItemSelected(item)
}
-
}
\ No newline at end of file
diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt
index cc9dd30..68b6355 100644
--- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt
+++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/PinFragment.kt
@@ -14,7 +14,9 @@ import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
/**
- * Fragment that deals with asking the user for PIN1
+ * Fragment that deals with asking the user for PIN 1. If the user has already saved the PIN 1 then it is not asked again
+ * and the fragment is skipped and if the PIN 1 is not saved then the user is asked whether it should be saved or
+ * not before continuing.
*/
class PinFragment : Fragment() {
@@ -22,7 +24,10 @@ class PinFragment : Fragment() {
private var binding: FragmentPinBinding? = null
- // Navigation arguments. saving = true means that we are navigating here from the settings menu and must return to the settings
+ // Navigation arguments:
+ // saving = true means that the user must be returned to the settings menu
+ // reading = true means that we are reading information from the ID card that does
+ // not require PIN 1 so it is not necessary to ask it.
private val args: CanFragmentArgs by navArgs()
override fun onCreateView(
@@ -36,48 +41,51 @@ class PinFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (viewModel.userPin.length in 4..12) {
- skip()
- }
+ checkIfSkip()
+ // If the user arrives from the settings menu then the button says
+ // save instead of continue.
if (args.saving) {
binding!!.nextButton.text = getString(R.string.save_text)
}
- binding!!.nextButton.setOnClickListener { goToNextFragment() }
+ binding!!.nextButton.setOnClickListener { checkEnteredPin() }
binding!!.cancelButton.setOnClickListener { goToTheStart() }
}
- private fun skip() {
+ /**
+ * Checks if the current fragment can be skipped or not.
+ * If the user has PIN 1 saved on the device or PIN 1 is not required
+ * then the PIN 1 won't be asked.
+ */
+ private fun checkIfSkip() {
+ if (args.reading) {
+ goToTheNextFragment()
+ } else if (viewModel.userPin.length in 4..12) {
+ goToTheNextFragment()
+ }
+ }
+
+ /**
+ * Takes user to the next fragment, which is AuthFragment.
+ */
+ private fun goToTheNextFragment() {
findNavController().navigate(R.id.action_pinFragment_to_authFragment)
}
- private fun goToNextFragment() {
- val enteredPin1 = binding!!.pinEditText.editText?.text.toString()
- if (enteredPin1.length in 4..12) {
- viewModel.setUserPin(
- binding!!.pinEditText.editText?.text.toString()
- )
+ /**
+ * Checks whether the user has entered a PIN 1 with length between [4, 12] in the
+ * input field. If yes then the user is allowed to continue otherwise the user is
+ * allowed to modify the entered PIN 1.
+ */
+ private fun checkEnteredPin() {
+ val enteredPin = binding!!.pinEditText.editText?.text.toString()
+ if (enteredPin.length in 4..12) {
+ viewModel.setUserPin(enteredPin)
if (args.saving) {
viewModel.storePin(requireContext())
- findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
+ goToTheStart()
} else {
- val canStoreQuestion: AlertDialog? = activity?.let { frag ->
- val builder = AlertDialog.Builder(frag)
- builder.apply {
- setPositiveButton(R.string.save_text) { _, _ ->
- viewModel.storePin(
- requireContext()
- )
- findNavController().navigate(R.id.action_pinFragment_to_authFragment)
- }
- setNegativeButton(R.string.deny_text) { _, _ ->
- findNavController().navigate(R.id.action_pinFragment_to_authFragment)
- }
- }
- builder.setMessage(R.string.pin_save_request)
- builder.setTitle(R.string.save_pin_title)
- builder.create()
- }
- canStoreQuestion?.show()
+ val storePinQuestion = getDialog()
+ storePinQuestion?.show()
}
} else {
Toast.makeText(requireContext(), getString(R.string.length_pin), Toast.LENGTH_SHORT)
@@ -85,6 +93,35 @@ class PinFragment : Fragment() {
}
}
+ /**
+ * Builds a dialog that asks the user whether the entered PIN 1 should be saved
+ * on the device or not.
+ */
+ private fun getDialog(): AlertDialog? {
+ return activity?.let { frag ->
+ val builder = AlertDialog.Builder(frag)
+ builder.apply {
+ // If response is positive save the PIN 1 on the device.
+ setPositiveButton(R.string.save_text) { _, _ ->
+ viewModel.storePin(
+ requireContext()
+ )
+ goToTheNextFragment()
+ }
+ setNegativeButton(R.string.deny_text) { _, _ ->
+ goToTheNextFragment()
+ }
+ }
+ builder.setMessage(R.string.pin_save_request)
+ builder.setTitle(R.string.save_pin_title)
+ builder.create()
+ }
+ }
+
+ /**
+ * Returns user to the start. If the user arrived from the settings menu then the start is
+ * settings menu not the HomeFragment.
+ */
private fun goToTheStart() {
if (args.saving) {
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
diff --git a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/menu/SettingsFragment.kt b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/menu/SettingsFragment.kt
index 7410c3f..87e822c 100644
--- a/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/menu/SettingsFragment.kt
+++ b/MobileAuthApp/app/src/main/java/com/tarkvaraprojekt/mobileauthapp/menu/SettingsFragment.kt
@@ -42,6 +42,7 @@ class SettingsFragment : Fragment() {
binding!!.canMenuAction.setOnClickListener { canAction() }
binding!!.pinMenuAction.setOnClickListener { pinAction() }
binding!!.pinMenuShow.setOnClickListener { togglePin() }
+ binding!!.returnButton.setOnClickListener { backToHome() }
}
/**
@@ -66,7 +67,7 @@ class SettingsFragment : Fragment() {
viewModel.deleteCan(requireContext())
showCanField()
} else {
- val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(true)
+ val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(saving = true)
findNavController().navigate(action)
}
}
@@ -100,7 +101,7 @@ class SettingsFragment : Fragment() {
viewModel.deletePin(requireContext())
showPinField()
} else {
- val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(true)
+ val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(saving = true)
findNavController().navigate(action)
}
}
@@ -125,6 +126,13 @@ class SettingsFragment : Fragment() {
}
}
+ /**
+ * Navigates back to home fragment.
+ */
+ private fun backToHome() {
+ findNavController().navigate(R.id.action_settingsFragment_to_homeFragment)
+ }
+
override fun onDestroy() {
super.onDestroy()
binding = null
diff --git a/MobileAuthApp/app/src/main/res/drawable/ic_check_logo.xml b/MobileAuthApp/app/src/main/res/drawable/ic_check_logo.xml
new file mode 100644
index 0000000..5e111ca
--- /dev/null
+++ b/MobileAuthApp/app/src/main/res/drawable/ic_check_logo.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/MobileAuthApp/app/src/main/res/drawable/ic_info_logo.xml b/MobileAuthApp/app/src/main/res/drawable/ic_info_logo.xml
new file mode 100644
index 0000000..17255b7
--- /dev/null
+++ b/MobileAuthApp/app/src/main/res/drawable/ic_info_logo.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/MobileAuthApp/app/src/main/res/layout/fragment_home.xml b/MobileAuthApp/app/src/main/res/layout/fragment_home.xml
index dc30b64..47396aa 100644
--- a/MobileAuthApp/app/src/main/res/layout/fragment_home.xml
+++ b/MobileAuthApp/app/src/main/res/layout/fragment_home.xml
@@ -7,23 +7,87 @@
android:padding="24dp"
tools:context=".HomeFragment">
-
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/MobileAuthApp/app/src/main/res/layout/fragment_settings.xml b/MobileAuthApp/app/src/main/res/layout/fragment_settings.xml
index 15d09c3..2f66bd6 100644
--- a/MobileAuthApp/app/src/main/res/layout/fragment_settings.xml
+++ b/MobileAuthApp/app/src/main/res/layout/fragment_settings.xml
@@ -33,6 +33,7 @@
@@ -61,4 +64,14 @@
+
+
\ No newline at end of file
diff --git a/MobileAuthApp/app/src/main/res/navigation/nav_graph.xml b/MobileAuthApp/app/src/main/res/navigation/nav_graph.xml
index d7e72ec..39fe753 100644
--- a/MobileAuthApp/app/src/main/res/navigation/nav_graph.xml
+++ b/MobileAuthApp/app/src/main/res/navigation/nav_graph.xml
@@ -42,6 +42,10 @@
android:id="@+id/action_pinFragment_to_authFragment"
app:destination="@id/authFragment"
app:popUpTo="@id/homeFragment" />
+
+
+
\ No newline at end of file
diff --git a/MobileAuthApp/app/src/main/res/values-en/strings.xml b/MobileAuthApp/app/src/main/res/values-en/strings.xml
index 5700cd5..8cd19f3 100644
--- a/MobileAuthApp/app/src/main/res/values-en/strings.xml
+++ b/MobileAuthApp/app/src/main/res/values-en/strings.xml
@@ -4,11 +4,18 @@
NFC authenticationWork in progress
- ALUSTA
+
+ PIN 1 on salvestatud
+ PIN 1 ei ole salvestatud
+ CAN on salvestatud
+ CAN ei ole salvestatud
+
+ LOE ID KAARTIEDASIKATKESTASALVESTAEI
+ TAGASIPalun sisesta PIN 1
@@ -54,4 +61,5 @@
NÄITAPEIDA****
+ Seaded pole hetkel saadaval
\ No newline at end of file
diff --git a/MobileAuthApp/app/src/main/res/values-et/strings.xml b/MobileAuthApp/app/src/main/res/values-et/strings.xml
index 118d5c1..41d7a5f 100644
--- a/MobileAuthApp/app/src/main/res/values-et/strings.xml
+++ b/MobileAuthApp/app/src/main/res/values-et/strings.xml
@@ -3,11 +3,18 @@
NFC authenticationWork in progress
- ALUSTA
+ LOE ID KAARTIEDASIKATKESTASALVESTAEI
+ TAGASI
+
+
+ PIN 1 on salvestatud
+ PIN 1 ei ole salvestatud
+ CAN on salvestatud
+ CAN ei ole salvestatudPalun sisesta PIN 1
@@ -52,4 +59,5 @@
NÄITAPEIDA****
+ Seaded pole hetkel saadaval
\ No newline at end of file
diff --git a/MobileAuthApp/app/src/main/res/values/strings.xml b/MobileAuthApp/app/src/main/res/values/strings.xml
index e795b1c..4b15803 100644
--- a/MobileAuthApp/app/src/main/res/values/strings.xml
+++ b/MobileAuthApp/app/src/main/res/values/strings.xml
@@ -2,11 +2,18 @@
NFC authenticationWork in progress
- ALUSTA
+ LOE ID KAARTIEDASIKATKESTASALVESTAEI
+ TAGASI
+
+
+ PIN 1 on salvestatud
+ PIN 1 ei ole salvestatud
+ CAN on salvestatud
+ CAN ei ole salvestatudPalun sisesta PIN 1
@@ -52,4 +59,5 @@
NÄITAPEIDA****
+ Seaded pole hetkel saadaval
\ No newline at end of file