added forget password

This commit is contained in:
Alex
2026-04-14 21:13:57 -06:00
parent 67d3cb2c7f
commit 44b7fcbba2
4 changed files with 89 additions and 48 deletions

View File

@@ -1,6 +1,7 @@
package com.example.petstoremobile.activities;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
@@ -9,14 +10,26 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.example.petstoremobile.api.auth.AuthApi;
import com.example.petstoremobile.databinding.ActivityForgotPasswordBinding;
import com.example.petstoremobile.utils.InputValidator;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@AndroidEntryPoint
public class ForgotPasswordActivity extends AppCompatActivity {
@Inject
AuthApi authApi;
private ActivityForgotPasswordBinding binding;
@Override
@@ -33,14 +46,39 @@ public class ForgotPasswordActivity extends AppCompatActivity {
});
binding.btnSubmit.setOnClickListener(v -> {
if (InputValidator.isValidEmail(binding.etEmail)) {
if (!InputValidator.isValidEmail(binding.etEmail)) return;
String email = binding.etEmail.getText().toString().trim();
// TODO: Implement password reset logic here
Toast.makeText(this, "If this email is linked, a reset email will be sent.", Toast.LENGTH_LONG).show();
finish();
}
sendResetLink(email);
});
binding.btnBackToLogin.setOnClickListener(v -> finish());
}
private void sendResetLink(String email) {
binding.btnSubmit.setEnabled(false);
Map<String, String> body = new HashMap<>();
body.put("usernameOrEmail", email);
authApi.forgotPassword(body).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
if (binding == null) return;
binding.btnSubmit.setEnabled(true);
Toast.makeText(ForgotPasswordActivity.this,
"If this email is registered, a reset link will be sent.",
Toast.LENGTH_LONG).show();
finish();
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
if (binding == null) return;
binding.btnSubmit.setEnabled(true);
Toast.makeText(ForgotPasswordActivity.this,
"Could not send reset link. Please try again.",
Toast.LENGTH_LONG).show();
}
});
}
}

View File

@@ -43,4 +43,8 @@ public interface AuthApi {
@DELETE("api/v1/auth/me/avatar")
Call<Void> deleteAvatar();
//forgot password endpoint
@POST("api/v1/auth/forgot-password")
Call<Void> forgotPassword(@Body Map<String, String> body);
}

View File

@@ -28,8 +28,6 @@ public class StaffDetailFragment extends Fragment {
private FragmentStaffDetailBinding binding;
private StaffDetailViewModel viewModel;
private final String[] ROLES = {"STAFF", "ADMIN"};
private final String[] STAFF_ROLES = {"STORE_MANAGER", "SALES_ASSOCIATE", "GROOMER", "VETERINARIAN"};
private final String[] STATUSES = {"Active", "Inactive"};
private long preselectedStoreId = -1;
@@ -59,8 +57,6 @@ public class StaffDetailFragment extends Fragment {
}
private void setupSpinners() {
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffRole, ROLES);
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffType, STAFF_ROLES);
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffStatus, STATUSES);
}
@@ -112,8 +108,6 @@ public class StaffDetailFragment extends Fragment {
binding.etStaffEmail.setText(e.getEmail());
binding.etStaffPhone.setText(e.getPhone());
SpinnerUtils.setSelectionByValue(binding.spinnerStaffRole, e.getRole());
SpinnerUtils.setSelectionByValue(binding.spinnerStaffType, e.getStaffRole());
binding.spinnerStaffStatus.setSelection(Boolean.TRUE.equals(e.getActive()) ? 0 : 1);
preselectedStoreId = e.getPrimaryStoreId() != null ? e.getPrimaryStoreId() : -1;
@@ -132,14 +126,32 @@ public class StaffDetailFragment extends Fragment {
private void save() {
if (!InputValidator.isNotEmpty(binding.etStaffUsername, "Username")) return;
String password = binding.etStaffPassword.getText().toString().trim();
String confirmPassword = binding.etStaffConfirmPassword.getText().toString().trim();
if (!viewModel.isEditing()) {
if (!InputValidator.isNotEmpty(binding.etStaffPassword, "Password")) return;
String pass = binding.etStaffPassword.getText().toString();
if (pass.length() < 6) {
if (password.length() < 6) {
binding.etStaffPassword.setError("At least 6 characters");
binding.etStaffPassword.requestFocus();
return;
}
if (!password.equals(confirmPassword)) {
binding.etStaffConfirmPassword.setError("Passwords do not match");
binding.etStaffConfirmPassword.requestFocus();
return;
}
} else if (!password.isEmpty()) {
if (password.length() < 6) {
binding.etStaffPassword.setError("At least 6 characters");
binding.etStaffPassword.requestFocus();
return;
}
if (!password.equals(confirmPassword)) {
binding.etStaffConfirmPassword.setError("Passwords do not match");
binding.etStaffConfirmPassword.requestFocus();
return;
}
}
if (!InputValidator.isNotEmpty(binding.etStaffFirstName, "First Name")) return;
@@ -149,13 +161,12 @@ public class StaffDetailFragment extends Fragment {
if (!InputValidator.isSpinnerSelected(binding.spinnerStaffStore, "Primary Store")) return;
String username = binding.etStaffUsername.getText().toString().trim();
String password = binding.etStaffPassword.getText().toString().trim();
String firstName = binding.etStaffFirstName.getText().toString().trim();
String lastName = binding.etStaffLastName.getText().toString().trim();
String email = binding.etStaffEmail.getText().toString().trim();
String phone = binding.etStaffPhone.getText().toString().trim();
String role = ROLES[binding.spinnerStaffRole.getSelectedItemPosition()];
String staffRole = STAFF_ROLES[binding.spinnerStaffType.getSelectedItemPosition()];
String role = "STAFF";
String staffRole = null;
boolean active = binding.spinnerStaffStatus.getSelectedItemPosition() == 0;
List<DropdownDTO> stores = viewModel.getStoreList().getValue();

View File

@@ -101,6 +101,23 @@
android:inputType="textPassword"
android:layout_marginBottom="16dp"/>
<!-- Confirm Password -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Confirm Password"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etStaffConfirmPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Re-enter password"
android:inputType="textPassword"
android:layout_marginBottom="16dp"/>
<!-- First Name -->
<TextView
android:layout_width="wrap_content"
@@ -169,35 +186,6 @@
android:inputType="phone"
android:layout_marginBottom="16dp"/>
<!-- Role -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="User Role"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStaffRole"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Staff Role"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStaffType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"