Modified project to use our utils on areas we arnt to manage code

This commit is contained in:
Alex
2026-04-12 17:49:24 -06:00
parent 7cdab36f5d
commit 4eaf98834d
9 changed files with 49 additions and 88 deletions

View File

@@ -16,6 +16,7 @@ import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.databinding.ActivityMainBinding; import com.example.petstoremobile.databinding.ActivityMainBinding;
import com.example.petstoremobile.viewmodels.AuthViewModel; import com.example.petstoremobile.viewmodels.AuthViewModel;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.UIUtils;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@@ -105,14 +106,14 @@ public class MainActivity extends AppCompatActivity {
switch (resource.status) { switch (resource.status) {
case LOADING: case LOADING:
binding.btnLogin.setEnabled(false); UIUtils.setViewsEnabled(false, binding.btnLogin);
binding.tvLoginStatus.setText("Logging in..."); binding.tvLoginStatus.setText("Logging in...");
break; break;
case SUCCESS: case SUCCESS:
if (resource.data != null) { if (resource.data != null) {
String role = resource.data.getRole(); String role = resource.data.getRole();
if ("CUSTOMER".equalsIgnoreCase(role)) { if ("CUSTOMER".equalsIgnoreCase(role)) {
binding.btnLogin.setEnabled(true); UIUtils.setViewsEnabled(true, binding.btnLogin);
binding.tvLoginStatus.setText("Customers are not allowed to log in"); binding.tvLoginStatus.setText("Customers are not allowed to log in");
Toast.makeText(this, "Access denied: Customers are not allowed to log in.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Access denied: Customers are not allowed to log in.", Toast.LENGTH_LONG).show();
} else { } else {
@@ -122,7 +123,7 @@ public class MainActivity extends AppCompatActivity {
} }
break; break;
case ERROR: case ERROR:
binding.btnLogin.setEnabled(true); UIUtils.setViewsEnabled(true, binding.btnLogin);
binding.tvLoginStatus.setText(resource.message); binding.tvLoginStatus.setText(resource.message);
Toast.makeText(this, resource.message, Toast.LENGTH_LONG).show(); Toast.makeText(this, resource.message, Toast.LENGTH_LONG).show();
break; break;

View File

@@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.dtos.ActivityLogDTO; import com.example.petstoremobile.dtos.ActivityLogDTO;
import com.example.petstoremobile.utils.DateTimeUtils;
import java.util.List; import java.util.List;
@@ -35,10 +36,9 @@ public class ActivityLogAdapter extends RecyclerView.Adapter<ActivityLogAdapter.
holder.tvUser.setText(log.getFullName() + " (" + log.getUsername() + ")"); holder.tvUser.setText(log.getFullName() + " (" + log.getUsername() + ")");
holder.tvMeta.setText(log.getStoreName() + " · " + log.getRole()); holder.tvMeta.setText(log.getStoreName() + " · " + log.getRole());
String timestamp = log.getLogTimestamp(); String timestamp = log.getLogTimestamp();
if (timestamp != null && timestamp.length() >= 16) { String date = DateTimeUtils.extractDate(timestamp);
timestamp = timestamp.substring(0, 10) + " " + timestamp.substring(11, 16); String time = (timestamp != null && timestamp.length() >= 16) ? timestamp.substring(11, 16) : null;
} holder.tvTimestamp.setText(date != null && time != null ? date + " " + time : date);
holder.tvTimestamp.setText(timestamp);
} }
@Override @Override

View File

@@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.dtos.CouponDTO; import com.example.petstoremobile.dtos.CouponDTO;
import com.example.petstoremobile.utils.DateTimeUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashSet; import java.util.HashSet;
@@ -57,7 +58,7 @@ public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.ViewHolder
holder.tvCouponMinOrder.setText("Min order: $" + coupon.getMinOrderAmount().stripTrailingZeros().toPlainString()); holder.tvCouponMinOrder.setText("Min order: $" + coupon.getMinOrderAmount().stripTrailingZeros().toPlainString());
if (coupon.getEndsAt() != null) { if (coupon.getEndsAt() != null) {
holder.tvCouponExpiry.setText("Expires: " + coupon.getEndsAt().substring(0, 10)); holder.tvCouponExpiry.setText("Expires: " + DateTimeUtils.extractDate(coupon.getEndsAt()));
holder.tvCouponExpiry.setVisibility(View.VISIBLE); holder.tvCouponExpiry.setVisibility(View.VISIBLE);
} else { } else {
holder.tvCouponExpiry.setVisibility(View.GONE); holder.tvCouponExpiry.setVisibility(View.GONE);

View File

@@ -115,24 +115,13 @@ public class AdoptionDetailFragment extends Fragment {
private void setupSpinners() { private void setupSpinners() {
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerAdoptionStatus, new String[]{}); SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerAdoptionStatus, new String[]{});
binding.spinnerAdoptionCustomer.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { SpinnerUtils.setOnIndexSelectedListener(binding.spinnerAdoptionCustomer, p -> {
@Override if (isUpdatingUI) return;
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { viewModel.onCustomerSelected(p);
if (isUpdatingUI) return;
viewModel.onCustomerSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerAdoptionStore, p -> {
binding.spinnerAdoptionStore.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { if (isUpdatingUI) return;
@Override viewModel.onStoreSelected(p);
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (isUpdatingUI) return;
viewModel.onStoreSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerAdoptionPet, p -> viewModel.onPetSelected(p)); SpinnerUtils.setOnIndexSelectedListener(binding.spinnerAdoptionPet, p -> viewModel.onPetSelected(p));

View File

@@ -4,7 +4,6 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -91,24 +90,13 @@ public class AppointmentDetailFragment extends Fragment {
UIUtils.setViewsEnabled(false, binding.spinnerPet, binding.spinnerStaff); UIUtils.setViewsEnabled(false, binding.spinnerPet, binding.spinnerStaff);
binding.spinnerCustomer.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { SpinnerUtils.setOnIndexSelectedListener(binding.spinnerCustomer, p -> {
@Override if (isUpdatingUI) return;
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { viewModel.onCustomerSelected(p);
if (isUpdatingUI) return;
viewModel.onCustomerSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerStore, p -> {
binding.spinnerStore.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { if (isUpdatingUI) return;
@Override viewModel.onStoreSelected(p);
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (isUpdatingUI) return;
viewModel.onStoreSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerService, p -> viewModel.onServiceSelected(p)); SpinnerUtils.setOnIndexSelectedListener(binding.spinnerService, p -> viewModel.onServiceSelected(p));

View File

@@ -1,11 +1,9 @@
package com.example.petstoremobile.fragments.listfragments.detailfragments; package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.app.DatePickerDialog;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
@@ -19,6 +17,7 @@ import com.example.petstoremobile.dtos.CouponDTO;
import com.example.petstoremobile.utils.DateTimeUtils; import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils; import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.CouponDetailViewModel; import com.example.petstoremobile.viewmodels.CouponDetailViewModel;
@@ -76,10 +75,7 @@ public class CouponDetailFragment extends Fragment {
} }
private void setupDiscountTypeSpinner() { private void setupDiscountTypeSpinner() {
String[] types = {"FIXED", "PERCENT"}; SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerDiscountTypeDetail, new String[]{"FIXED", "PERCENT"});
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, types);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
binding.spinnerDiscountTypeDetail.setAdapter(adapter);
} }
private void setupDatePicker(android.widget.EditText editText, android.widget.EditText dependOn, Runnable onDateSet) { private void setupDatePicker(android.widget.EditText editText, android.widget.EditText dependOn, Runnable onDateSet) {
@@ -109,8 +105,8 @@ public class CouponDetailFragment extends Fragment {
binding.etUsageLimitDetail.setText(coupon.getUsageLimit() != null ? String.valueOf(coupon.getUsageLimit()) : ""); binding.etUsageLimitDetail.setText(coupon.getUsageLimit() != null ? String.valueOf(coupon.getUsageLimit()) : "");
binding.cbActiveDetail.setChecked(Boolean.TRUE.equals(coupon.getActive())); binding.cbActiveDetail.setChecked(Boolean.TRUE.equals(coupon.getActive()));
if (coupon.getStartsAt() != null) binding.etStartsAtDetail.setText(coupon.getStartsAt().substring(0, 10)); if (coupon.getStartsAt() != null) binding.etStartsAtDetail.setText(DateTimeUtils.extractDate(coupon.getStartsAt()));
if (coupon.getEndsAt() != null) binding.etEndsAtDetail.setText(coupon.getEndsAt().substring(0, 10)); if (coupon.getEndsAt() != null) binding.etEndsAtDetail.setText(DateTimeUtils.extractDate(coupon.getEndsAt()));
} }
}); });
} }

View File

@@ -12,7 +12,6 @@ import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@@ -280,43 +279,20 @@ public class PetDetailFragment extends Fragment {
viewModel.onSpeciesSelected(p); viewModel.onSpeciesSelected(p);
}); });
binding.spinnerCustomer.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { SpinnerUtils.setOnIndexSelectedListener(binding.spinnerCustomer, p -> {
@Override if (isUpdatingUI) return;
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { viewModel.onCustomerSelected(p);
if (isUpdatingUI) return;
viewModel.onCustomerSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerStore, p -> {
binding.spinnerStore.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { if (isUpdatingUI) return;
@Override viewModel.onStoreSelected(p);
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (isUpdatingUI) return;
viewModel.onStoreSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}); });
SpinnerUtils.setOnIndexSelectedListener(binding.spinnerPetStatus, p -> {
binding.spinnerPetStatus.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { if (isUpdatingUI) return;
@Override String status = binding.spinnerPetStatus.getItemAtPosition(p).toString();
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { clearSpinnerError(binding.spinnerCustomer);
if (isUpdatingUI) return; clearSpinnerError(binding.spinnerStore);
String status = parent.getItemAtPosition(position).toString(); viewModel.onStatusSelected(status);
clearSpinnerError(binding.spinnerCustomer);
clearSpinnerError(binding.spinnerStore);
viewModel.onStatusSelected(status);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}); });
} }

View File

@@ -14,6 +14,7 @@ import com.example.petstoremobile.dtos.SaleDTO;
import com.example.petstoremobile.viewmodels.RefundViewModel; import com.example.petstoremobile.viewmodels.RefundViewModel;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.SpinnerUtils; import com.example.petstoremobile.utils.SpinnerUtils;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -123,7 +124,7 @@ public class RefundFragment extends Fragment {
binding.tvSaleInfo.setVisibility(View.VISIBLE); binding.tvSaleInfo.setVisibility(View.VISIBLE);
binding.tvSaleInfo.setText("Sale #" + currentSale.getSaleId() binding.tvSaleInfo.setText("Sale #" + currentSale.getSaleId()
+ " | " + (currentSale.getSaleDate() != null + " | " + (currentSale.getSaleDate() != null
? currentSale.getSaleDate().substring(0, 10) : "") ? DateTimeUtils.extractDate(currentSale.getSaleDate()) : "")
+ " | Employee: " + (currentSale.getEmployeeName() != null + " | Employee: " + (currentSale.getEmployeeName() != null
? currentSale.getEmployeeName() : "") ? currentSale.getEmployeeName() : "")
+ " | Total: $" + currentSale.getTotalAmount() + " | Total: $" + currentSale.getTotalAmount()

View File

@@ -129,6 +129,15 @@ public class DateTimeUtils {
return String.format(Locale.getDefault(), "%02d:%02d", hour, minute); return String.format(Locale.getDefault(), "%02d:%02d", hour, minute);
} }
/**
* Extracts the date portion (YYYY-MM-DD) from timestamp string.
* Returns null if the input is null or too short.
*/
public static String extractDate(String timestamp) {
if (timestamp == null || timestamp.length() < 10) return null;
return timestamp.substring(0, 10);
}
/** /**
* Formats an ID for display (e.g., "ID: 123"). * Formats an ID for display (e.g., "ID: 123").
*/ */