diff --git a/app/build.gradle b/app/build.gradle index ddce82a..dd91b45 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,8 @@ plugins { id 'com.android.application' id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' } android { @@ -35,6 +37,9 @@ android { } dependencies { + implementation 'com.google.firebase:firebase-crashlytics:18.3.2' + implementation 'com.google.firebase:firebase-analytics:21.2.0' + // Navigation component def nav_version = "2.5.3" diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeApiService.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeApiService.java new file mode 100644 index 0000000..c130d86 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeApiService.java @@ -0,0 +1,20 @@ +package com.ssb.simplitend.welcome.welcomecg; + +import com.ssb.simplitend.welcome.welcomecg.mvvm.CareGiverData; +import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse; + +import java.util.Map; + +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.PartMap; + +public interface WelcomeApiService { + + @Multipart + @POST("api/auth/caregiver-register") + Call> registerCareGiver(@PartMap Map body); + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeContracts.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeContracts.java new file mode 100644 index 0000000..952c60b --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/WelcomeContracts.java @@ -0,0 +1,15 @@ +package com.ssb.simplitend.welcome.welcomecg; + +import com.ssb.simplitend.welcome.welcomecg.mvvm.CareGiverData; + +public interface WelcomeContracts { + + interface RegisterCareGiverCallback{ + + void onCareGiverRegistered(CareGiverData careGiverData); + + void onRegisterFailed(Throwable t, String message); + + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgChangePwdFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgChangePwdFragment.java new file mode 100644 index 0000000..38e9a86 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgChangePwdFragment.java @@ -0,0 +1,29 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.ssb.simplitend.databinding.CgChangePasswordFragmentBinding; + +public class CgChangePwdFragment extends Fragment { + + protected CgChangePasswordFragmentBinding binding; + + public CgChangePwdFragment(){ + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = CgChangePasswordFragmentBinding.inflate(inflater, container, false); + + return binding.getRoot(); + } +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgCheckEmailFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgCheckEmailFragment.java new file mode 100644 index 0000000..706abde --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgCheckEmailFragment.java @@ -0,0 +1,186 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; + +import com.bumptech.glide.Glide; +import com.ssb.simplitend.R; +import com.ssb.simplitend.apputils.AppUtil; +import com.ssb.simplitend.databinding.CgCheckEmailFragmentBinding; + +public class CgCheckEmailFragment extends Fragment { + + protected CgCheckEmailFragmentBinding binding; + + public CgCheckEmailFragment(){ + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = CgCheckEmailFragmentBinding.inflate(inflater, container, false); + + initViews(); + + clickEvents(); + + return binding.getRoot(); + } + + private void clickEvents() { + binding.submit.setOnClickListener(view -> { + Navigation.findNavController(view) + .navigate(R.id.action_cgCheckEmailFragment_to_cgChangePwdFragment); + }); + } + + private void initViews() { + + // showing gif + Glide.with(binding.image) + .asGif() + .load(R.raw.email_sending_anim) + .placeholder(R.drawable.forgot_pin_email_img) + .into(binding.image); + + initOTPBoxes(); + + } + + /* + setting text change listener for every edit text for otp + */ + private void initOTPBoxes() { + + binding.otp1.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (!s.toString().trim().isEmpty()) { + binding.otp2.requestFocus(); + if (checkOTPInputs()){ + AppUtil.closeKeyboard(requireActivity()); + } + } + + // check if all otp boxes are filled + + } + }); + + binding.otp2.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (!s.toString().trim().isEmpty()) { + binding.otp3.requestFocus(); + if (checkOTPInputs()){ + AppUtil.closeKeyboard(requireActivity()); + } + } else { + binding.otp1.requestFocus(); + } + + // check if all otp boxes are filled + + } + }); + + binding.otp3.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (!s.toString().trim().isEmpty()) { + binding.otp4.requestFocus(); + if (checkOTPInputs()){ + AppUtil.closeKeyboard(requireActivity()); + } + } else { + binding.otp2.requestFocus(); + } + + // check if all otp boxes are filled + + } + }); + + binding.otp4.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (!s.toString().trim().isEmpty()) { + // last otp inserted + AppUtil.closeKeyboard(getActivity()); + } else { + binding.otp3.requestFocus(); + } + + // check if all otp boxes are filled + + } + }); + + } + + public boolean checkOTPInputs(){ + + if (binding.otp3.getText().toString().trim().length() != 1){ + return false; + }else if (binding.otp2.getText().toString().trim().length() != 1){ + return false; + }else if (binding.otp3.getText().toString().trim().length() != 1){ + return false; + }else if (binding.otp4.getText().toString().trim().length() != 1){ + return false; + } + + return true; + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgConnectFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgConnectFragment.java new file mode 100644 index 0000000..15ef3b3 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgConnectFragment.java @@ -0,0 +1,43 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.bumptech.glide.Glide; +import com.ssb.simplitend.R; +import com.ssb.simplitend.databinding.ConnectCaregiverFragmentBinding; + +public class CgConnectFragment extends Fragment { + + protected ConnectCaregiverFragmentBinding binding; + + public CgConnectFragment(){ + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = ConnectCaregiverFragmentBinding.inflate(inflater, container, false); + + initViews(); + + return binding.getRoot(); + } + + private void initViews() { + + // showing gif + Glide.with(binding.image) + .asGif() + .load(R.raw.email_sending_anim) + .placeholder(R.drawable.forgot_pin_email_img) + .into(binding.image); + } +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgForgotPasswordFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgForgotPasswordFragment.java new file mode 100644 index 0000000..a70d6f5 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgForgotPasswordFragment.java @@ -0,0 +1,57 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; + +import com.bumptech.glide.Glide; +import com.ssb.simplitend.R; +import com.ssb.simplitend.databinding.CgForgotPasswordBinding; + +public class CgForgotPasswordFragment extends Fragment { + + protected CgForgotPasswordBinding binding; + + public CgForgotPasswordFragment(){ + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = CgForgotPasswordBinding.inflate(inflater, container, false); + + initViews(); + + clickEvents(); + + return binding.getRoot(); + } + + private void clickEvents() { + + binding.submit.setOnClickListener(v -> { + Navigation.findNavController(v) + .navigate(R.id.action_cgForgotPasswordFragment_to_cgCheckEmailFragment); + }); + + } + + private void initViews() { + + // showing gif + Glide.with(binding.image) + .asGif() + .load(R.raw.email_sending_anim) + .placeholder(R.drawable.forgot_pin_email_img) + .into(binding.image); + + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgHowToSetUpFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgHowToSetUpFragment.java index d7e539a..0329e3b 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgHowToSetUpFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgHowToSetUpFragment.java @@ -27,7 +27,7 @@ public class CgHowToSetUpFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = CgHowToSetUpFragmentBinding.inflate(inflater, container, false); - binding.nextBtn.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_howToSetUpFragment_to_registerFragment)); + binding.nextBtn.setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_cgHowToSetUpFragment_to_cgSignInFragment)); return binding.getRoot(); } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java index 2b07175..a373484 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgOnBoardFragment.java @@ -51,6 +51,10 @@ public class CgOnBoardFragment extends Fragment { Navigation.findNavController(v).navigate(R.id.action_cgOnBoardFragment_to_cgHowToSetUpFragment); }); + binding.skip.setOnClickListener(v -> { + Navigation.findNavController(v).navigate(R.id.action_cgOnBoardFragment_to_cgHowToSetUpFragment); + }); + } private void initViews() { diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java new file mode 100644 index 0000000..025025b --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgRegisterFragment.java @@ -0,0 +1,388 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.app.DatePickerDialog; +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.InputFilter; +import android.util.Log; +import android.util.Patterns; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.Navigation; + +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.i18n.phonenumbers.Phonenumber; +import com.ssb.simplitend.apputils.AppUtil; +import com.ssb.simplitend.apputils.EditTextErrorRemover; +import com.ssb.simplitend.databinding.CgRegisterFragmentBinding; +import com.ssb.simplitend.databinding.PasswordPopUpBinding; +import com.ssb.simplitend.welcome.welcomecg.WelcomeContracts; +import com.ssb.simplitend.welcome.welcomecg.mvvm.CareGiverData; +import com.ssb.simplitend.welcome.welcomecg.mvvm.CgWelcomeViewModel; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +public class CgRegisterFragment extends Fragment implements WelcomeContracts.RegisterCareGiverCallback{ + + private static final String TAG = "CgRegisterFragment"; + + protected CgRegisterFragmentBinding binding; + + private ProgressDialog progressDialog; + + private CgWelcomeViewModel viewModel; + + private DatePickerDialog datePickerDialog; + + private ArrayList countryCodeList; + + private PopupWindow passwordWindow; + + private Calendar dob_selected; + + public CgRegisterFragment(){ + // required + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = CgRegisterFragmentBinding.inflate(inflater, container, false); + + // password details 'i' button popup view + PasswordPopUpBinding popUpBinding = PasswordPopUpBinding.inflate(inflater); + passwordWindow = new PopupWindow(popUpBinding.getRoot(), LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT, + true); + + viewModel = new ViewModelProvider(requireActivity()).get(CgWelcomeViewModel.class); + + initViews(); + + clickEvents(); + + return binding.getRoot(); + } + + @Override + public void onStop() { + super.onStop(); + if (getActivity() != null) { + getActivity().getWindow() + .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + } + } + + private void initViews() { + + progressDialog = new ProgressDialog(requireContext()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + datePickerDialog = new DatePickerDialog(requireContext()); + } + + dob_selected = Calendar.getInstance(); + + countryCodeList = viewModel.loadCountryCodeDropDown(requireContext()); + + binding.countryCodes.setLifecycleOwner(this); + + binding.countryCodes.setItems(countryCodeList); + + if (!countryCodeList.contains("+1")){ + countryCodeList.add("+1"); + } + + binding.countryCodes.selectItemByIndex(countryCodeList.indexOf("+1")); + + binding.countryCodes.setDismissWhenNotifiedItemSelected(true); + + binding.countryCodes.setIsFocusable(true); + + setErrorRemovers(); + + setFocusManager(); + + } + + private void clickEvents() { + + binding.backBtn.setOnClickListener(v -> { + Navigation.findNavController(v).popBackStack(); + }); + + binding.submit.setOnClickListener(v -> { + if (allOkay()) { + AppUtil.closeKeyboard(requireActivity()); + + progressDialog.setTitle("Please wait..."); + progressDialog.setMessage("while we verify your entered email."); + progressDialog.setCancelable(false); + progressDialog.show(); + + Map body = new HashMap<>(); + + RequestBody name_body = RequestBody.create(binding.name.getText().toString().trim(), MediaType.parse("text/plain")); + body.put("full_name", name_body); + + RequestBody dob_body = RequestBody.create(binding.dob.getHint().toString(), MediaType.parse("text/plain")); + body.put("date_of_birth", dob_body); + + String phone_number = ""; + + if (binding.countryCodes.getSelectedIndex() != -1){ + phone_number += countryCodeList.get(binding.countryCodes.getSelectedIndex()) + " "; + } + + phone_number += binding.contactNumber.getText().toString(); + + RequestBody contact_body = RequestBody.create(phone_number, MediaType.parse("text/plain")); + body.put("contact_number", contact_body); + + RequestBody email_body = RequestBody.create(binding.email.getText().toString().trim(), MediaType.parse("text/plain")); + body.put("email", email_body); + + RequestBody password_body = RequestBody.create(binding.password.getText().toString().trim(), MediaType.parse("text/plain")); + body.put("password", password_body); + + viewModel.registerCareGiver(body, this); + + } + }); + + binding.dob.setOnClickListener(v -> { + binding.dob.setError(null); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + AppUtil.closeKeyboard(requireActivity()); + + pickDate(); + } + }); + + binding.tncBtn.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://www.google.com")); + startActivity(intent); + }); + + // static thing for lower android versions + // todo should be removed afterwards + binding.dob.setOnLongClickListener(v -> { + binding.dob.setText("12-12-2001"); + return false; + }); + + binding.pwdInfo.setOnClickListener(v -> { + passwordWindow.showAsDropDown(binding.pwdTitle); + }); + + } + + private void setErrorRemovers() { + new EditTextErrorRemover( + binding.name, + binding.contactNumber, + binding.email + ); + + // phone number formatting + // to deal with input pasting in the edit text + InputFilter phoneFilter = (charSequence, i, i1, spanned, i2, i3) -> { + String phone_number_str = charSequence.toString(); + + String country_code; + + if (binding.countryCodes.getSelectedIndex() == -1){ + country_code = "+1"; + }else{ + country_code = countryCodeList.get(binding.countryCodes.getSelectedIndex()); + } + + try { + PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); + Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(charSequence, "US"); + + phone_number_str = String.valueOf(phoneNumber.getNationalNumber()); + country_code = "+" + phoneNumber.getCountryCode(); + } catch (Exception e) { + // nothing + } + + if (!countryCodeList.contains(country_code)){ + countryCodeList.add(country_code); + } + + binding.countryCodes.selectItemByIndex(countryCodeList.indexOf(country_code)); + + if (phone_number_str.length() > 10){ + // pasted number length is greater than 10 + return phone_number_str.substring(0, 10); + } + + String total_phone_number = binding.contactNumber.getText().toString() + phone_number_str; + + if (total_phone_number.length() > 10){ + // max length should be 10 + return ""; + }else{ + return phone_number_str; + } + }; + + binding.contactNumber.setFilters(new InputFilter[]{phoneFilter}); + + } + + private void setFocusManager() { + binding.name.setOnEditorActionListener((textView, i, keyEvent) -> { + AppUtil.closeKeyboard(requireActivity()); + binding.name.clearFocus(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + pickDate(); + } + return true; + }); + } + + @RequiresApi(api = Build.VERSION_CODES.N) + private void pickDate() { + + if (datePickerDialog == null) return; + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 18); + datePickerDialog.getDatePicker().setMaxDate(calendar.getTimeInMillis()); + + datePickerDialog.setOnDateSetListener((view, year, month, dayOfMonth) -> { + setDOB(year, month, dayOfMonth); + + binding.contactNumber.requestFocus(); + + if (getActivity() != null) { + getActivity().getWindow() + .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } + }); + + datePickerDialog.show(); + + } + + private void setDOB(int year, int month, int dayOfMonth) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, month); + cal.set(Calendar.DAY_OF_MONTH, dayOfMonth); + + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault()); + SimpleDateFormat sdf2 = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()); + + String selected_time = sdf.format(cal.getTime()); + binding.dob.setText(selected_time); + + // time in dd-mm-yyyy format in the hint for registering the caregiver + binding.dob.setHint(sdf2.format(cal.getTime())); + } + + private boolean allOkay() { + + boolean allOkay = true; + + if (binding.name.getText().toString().trim().isEmpty()) { + binding.name.setError("Required"); + allOkay = false; + } + + if (binding.dob.getText().toString().trim().isEmpty()) { + binding.dob.setError("Required"); + allOkay = false; + } else { + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault()); + try { + Date selected_date = sdf.parse(binding.dob.getText().toString().trim()); + Calendar selected_calender = Calendar.getInstance(); + + if (selected_date == null) throw new Exception(); + + selected_calender.setTime(selected_date); + + Calendar minAdultAge = Calendar.getInstance(); + minAdultAge.add(Calendar.YEAR, -18); + + if (minAdultAge.before(selected_calender)) { + Toast.makeText(requireContext(), "Age must be above 18+ years", Toast.LENGTH_SHORT).show(); + } + + } catch (Exception e) { + Log.e(TAG, "allOkay: ", e); + // TODO: 17-07-2023 check out this thing + } + } + + if (binding.contactNumber.getText().toString().trim().isEmpty() || + binding.contactNumber.getText().toString().trim().length() <10) { + binding.contactNumber.setError("Invalid"); + allOkay = false; + } else if (!Patterns.PHONE.matcher(binding.contactNumber.getText().toString()).matches()) { + binding.contactNumber.setError("Invalid contact"); + allOkay = false; + } + + if (binding.email.getText().toString().trim().isEmpty()) { + binding.email.setError("Required"); + allOkay = false; + } else if (!Patterns.EMAIL_ADDRESS.matcher(binding.email.getText().toString()).matches()) { + binding.email.setError("Invalid email"); + allOkay = false; + } + + if (!binding.tncCheck.isChecked() && allOkay) { + AppUtil.showAlert(requireContext(), + "Accept terms and conditions", + "Please check terms and conditions to continue.", + "Ok", + ((dialogInterface, i) -> { + // do nothing + }), null, null + ); + allOkay = false; + } + + // TODO: 02-08-2023 password check + + return allOkay; + } + + @Override + public void onCareGiverRegistered(CareGiverData careGiverData) { + + } + + @Override + public void onRegisterFailed(Throwable t, String message) { + + } +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgSignInFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgSignInFragment.java new file mode 100644 index 0000000..e5b8c6f --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/fragments/CgSignInFragment.java @@ -0,0 +1,45 @@ +package com.ssb.simplitend.welcome.welcomecg.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; + +import com.ssb.simplitend.R; +import com.ssb.simplitend.databinding.CgHowToSetUpFragmentBinding; +import com.ssb.simplitend.databinding.CgSignInFragmentBinding; + +public class CgSignInFragment extends Fragment { + + // view binding + protected CgSignInFragmentBinding binding; + + public CgSignInFragment(){ + // required empty const. + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = CgSignInFragmentBinding.inflate(inflater, container, false); + + binding.signInBtn.setOnClickListener(v -> { + }); + + binding.registerBtn.setOnClickListener(v -> { + Navigation.findNavController(v).navigate(R.id.action_cgSignInFragment_to_cgRegisterFragment); + }); + + binding.forgotPassword.setOnClickListener(v -> { + Navigation.findNavController(v) + .navigate(R.id.action_cgSignInFragment_to_cgForgotPasswordFragment); + }); + + return binding.getRoot(); + } +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CareGiverData.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CareGiverData.java new file mode 100644 index 0000000..aef9944 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CareGiverData.java @@ -0,0 +1,36 @@ +package com.ssb.simplitend.welcome.welcomecg.mvvm; + +public class CareGiverData{ + public int id; + public String principal_type_xid; + public String principal_source_xid; + public String user_name; + public String password; + public String first_name; + public String last_name; + public String gender; + public String phone_number; + public String email; + public String date_of_birth; + public String email_verified_at; + public String address_line1; + public String address_line2; + public String city; + public String state; + public String country; + public String post_code; + public String lat; + public String lng; + public String last_login_datetime; + public String profile_photo; + public String active; + public String deleted_at; + public String created_by; + public String updated_by; + public String created_at; + public String updated_at; + public int is_patient; + public int is_caregiver; + public int is_caregiver_account_updated; + public String is_admin; +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeRepository.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeRepository.java new file mode 100644 index 0000000..8f17b6f --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeRepository.java @@ -0,0 +1,67 @@ +package com.ssb.simplitend.welcome.welcomecg.mvvm; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.ssb.simplitend.apputils.RetrofitHelper; +import com.ssb.simplitend.welcome.welcomecg.WelcomeApiService; +import com.ssb.simplitend.welcome.welcomecg.WelcomeContracts; +import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse; + +import java.util.Map; + +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class CgWelcomeRepository { + + private static final String TAG = "CgWelcomeRepository"; + + private static CgWelcomeRepository repository; + + private final WelcomeApiService apiService; + + private CgWelcomeRepository(){ + apiService = RetrofitHelper.getRetrofit().create(WelcomeApiService.class); + } + + public static CgWelcomeRepository getRepository(){ + if (repository == null){ + repository = new CgWelcomeRepository(); + } + + return repository; + } + + public void registerCareGiver(Map body, + @NonNull WelcomeContracts.RegisterCareGiverCallback registerCareGiverCallback){ + + apiService.registerCareGiver(body) + .enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.body() != null){ + if (response.body().status != 200 || response.body().result == null){ + registerCareGiverCallback.onRegisterFailed(new Exception(), response.body().message); + return; + } + + registerCareGiverCallback.onCareGiverRegistered(response.body().result); + }else{ + registerCareGiverCallback.onRegisterFailed(new Exception(), "Please try again later."); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + Log.e(TAG, "onFailure: ", t); + registerCareGiverCallback.onRegisterFailed(t, "Please try again later."); + } + }); + + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeViewModel.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeViewModel.java new file mode 100644 index 0000000..0ff0c21 --- /dev/null +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomecg/mvvm/CgWelcomeViewModel.java @@ -0,0 +1,95 @@ +package com.ssb.simplitend.welcome.welcomecg.mvvm; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModel; + +import com.ssb.simplitend.R; +import com.ssb.simplitend.welcome.welcomecg.WelcomeContracts; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Map; + +import okhttp3.RequestBody; + +public class CgWelcomeViewModel extends ViewModel { + + private static final String TAG = "CgWelcomeViewModel"; + + private final CgWelcomeRepository repository; + + public CgWelcomeViewModel(){ + this.repository = CgWelcomeRepository.getRepository(); + } + + public void registerCareGiver(Map body, + @NonNull WelcomeContracts.RegisterCareGiverCallback registerCareGiverCallback){ + repository.registerCareGiver(body, registerCareGiverCallback); + } + + public ArrayList loadCountryCodeDropDown(Context context) { + + ArrayList countryCodeList = new ArrayList<>(); + + try { + + String countryCodeStr = readCountryCodes(context); + JSONArray jsonArray = new JSONArray(countryCodeStr); + + for (int i = 0; i < jsonArray.length(); i++) { + + JSONObject code = jsonArray.getJSONObject(i); + + countryCodeList.add(code.getString("dial_code")); + + } + + } catch (Exception e) { + + // if cannot load all country codes showing only india's dial code + countryCodeList.add("+91"); + countryCodeList.add("+1"); + + Log.e(TAG, "loadCountryCodeDropDown: ", e); + } + + return countryCodeList; + } + + public String readCountryCodes(Context context) throws IOException { + StringBuilder returnString = new StringBuilder(); + + InputStream fIn = context.getResources().openRawResource(R.raw.country_code); + InputStreamReader isr = new InputStreamReader(fIn); + BufferedReader input = new BufferedReader(isr); + + String line = ""; + + while ((line = input.readLine()) != null) { + returnString.append(line); + } + + try { + isr.close(); + + if (fIn != null) fIn.close(); + + input.close(); + + } catch (Exception e) { + Log.e(TAG, "readCountryCodes: ", e); + } + + return returnString.toString(); + } + +} diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/ChooseRoleFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/ChooseRoleFragment.java index 581ecd0..025a646 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/ChooseRoleFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/ChooseRoleFragment.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -54,7 +55,7 @@ public class ChooseRoleFragment extends Fragment { } - // initialize views + // initialize views1257 private void initViews(Bundle savedInstanceState) { // checking if any previous instance existed if (savedInstanceState != null){ diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListAdapter.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListAdapter.java index 6383b89..92cba1b 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListAdapter.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListAdapter.java @@ -44,7 +44,6 @@ public class ContactListAdapter extends ListAdapter { - Log.d("aditya", "onBindViewHolder: " + getItemCount() + " " + position); if (contactClickListener != null){ contactClickListener.onClick(getItem(position)); } @@ -65,10 +64,18 @@ public class ContactListAdapter extends ListAdapter= 1) + { + binding.initial.setText(contact.first_name.substring(0, 1).toUpperCase()); + } } } diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListFragment.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListFragment.java index 10e7bd0..f77dfc3 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListFragment.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/ContactListFragment.java @@ -158,9 +158,6 @@ public class ContactListFragment extends Fragment { if (granted) { // user granted the READ_CONTACT permission loadContacts(); - } else { - // user denied the permission - // TODO: 28-06-2023 } } ); diff --git a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java index 2dacf06..4538f2e 100644 --- a/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java +++ b/app/src/main/java/com/ssb/simplitend/welcome/welcomepatient/fragments/contacts/mvvm/UserContactRepository.java @@ -37,7 +37,6 @@ public class UserContactRepository { ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, - ContactsContract.CommonDataKinds.Phone.PHOTO_URI }; private static UserContactRepository contactRepository; @@ -172,7 +171,11 @@ public class UserContactRepository { ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); + Cursor cursor = cr.query( + ContactsContract.CommonDataKinds.Phone.CONTENT_URI, + PROJECTION, + null, null, + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); if (cursor != null) { @@ -188,7 +191,7 @@ public class UserContactRepository { name = cursor.getString(nameIndex); number = cursor.getString(numberIndex); - Log.d(TAG, "getContactList: " + number); + if (number == null) continue; if (!mobileNoSet.contains(number)) { try { @@ -198,9 +201,13 @@ public class UserContactRepository { number = String.valueOf(phoneNumber.getNationalNumber()); country_code = "+" + phoneNumber.getCountryCode(); } catch (Exception e) { - number = number.replace("-", ""); - number = number.replace("(", ""); - number = number.replace(")", ""); + try { + number = number.replace("-", ""); + number = number.replace("(", ""); + number = number.replace(")", ""); + }catch (Exception e2){ + // do nothing + } } Contact contact = new Contact(name, number); diff --git a/app/src/main/res/drawable/edit_text_bg_3.xml b/app/src/main/res/drawable/edit_text_bg_3.xml new file mode 100644 index 0000000..8b0af5e --- /dev/null +++ b/app/src/main/res/drawable/edit_text_bg_3.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_text_bg_4.xml b/app/src/main/res/drawable/edit_text_bg_4.xml new file mode 100644 index 0000000..42e61f9 --- /dev/null +++ b/app/src/main/res/drawable/edit_text_bg_4.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml new file mode 100644 index 0000000..63e2edd --- /dev/null +++ b/app/src/main/res/drawable/ic_info.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/cg_change_password_fragment.xml b/app/src/main/res/layout/cg_change_password_fragment.xml new file mode 100644 index 0000000..95b05a4 --- /dev/null +++ b/app/src/main/res/layout/cg_change_password_fragment.xml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cg_check_email_fragment.xml b/app/src/main/res/layout/cg_check_email_fragment.xml new file mode 100644 index 0000000..06a92a3 --- /dev/null +++ b/app/src/main/res/layout/cg_check_email_fragment.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cg_forgot_password.xml b/app/src/main/res/layout/cg_forgot_password.xml new file mode 100644 index 0000000..0a822cb --- /dev/null +++ b/app/src/main/res/layout/cg_forgot_password.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cg_register_fragment.xml b/app/src/main/res/layout/cg_register_fragment.xml new file mode 100644 index 0000000..167a25e --- /dev/null +++ b/app/src/main/res/layout/cg_register_fragment.xml @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cg_sign_in_fragment.xml b/app/src/main/res/layout/cg_sign_in_fragment.xml new file mode 100644 index 0000000..ff92873 --- /dev/null +++ b/app/src/main/res/layout/cg_sign_in_fragment.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/connect_caregiver_fragment.xml b/app/src/main/res/layout/connect_caregiver_fragment.xml new file mode 100644 index 0000000..cb68620 --- /dev/null +++ b/app/src/main/res/layout/connect_caregiver_fragment.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/password_pop_up.xml b/app/src/main/res/layout/password_pop_up.xml new file mode 100644 index 0000000..ae80030 --- /dev/null +++ b/app/src/main/res/layout/password_pop_up.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/welcome_nav_graph.xml b/app/src/main/res/navigation/welcome_nav_graph.xml index cc211dd..c6c8ce2 100644 --- a/app/src/main/res/navigation/welcome_nav_graph.xml +++ b/app/src/main/res/navigation/welcome_nav_graph.xml @@ -235,5 +235,52 @@ + android:label="CgHowToSetUpFragment" > + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7b76354..c846114 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -13,5 +13,6 @@ #C9E0FB #005F9A + #545454 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 68314c7..7e25d97 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -253,7 +253,7 @@ Setup a geofence to\nprotect your loved one. You are always connected and will be notified when your loved ones need you. Application will notify you when it is time for your loved one to take his/her medication. - Be notified if your loved one ventures too far from home or a designated safe area + Be notified if your loved one ventures too far from home or a designated safe area. Skip Get started Create your account @@ -264,5 +264,34 @@ Complete application subscription You are ready! Your phone is linked to your loved one. + Enter email address + Enter password + Enter your password + Forgot password ? + New Here? Register as a Caregiver + Enter your information below + Set login password* + Set your password + Confirm password* + Confirm password + Confirm your password + Enter your email or phone number + Enter code sent on your email + Connect + Didn\'t receive code ? Resend + Enter your code + Forgot password + Change your password + For your security, Please change the temporary password to a new password + New password + Enter your new password + * Has a number + * Has at uppercase letter or symbol + * Has at least 8 characters + Reset password + Send OTP + Enter OTP + + info \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9e4adc6..c0571f0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,10 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + dependencies { + classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.google.gms:google-services:4.3.14' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' + } +}// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { id 'com.android.application' version '7.3.1' apply false id 'com.android.library' version '7.3.1' apply false