cleaning code

This commit is contained in:
Alex
2026-04-09 21:16:11 -06:00
parent fea01ba8ec
commit a8b5ee361e
35 changed files with 3600 additions and 3279 deletions

View File

@@ -214,9 +214,11 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
Toast.makeText(requireContext(), "Downloading " + message.getAttachmentName() + "...", Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), "Downloading " + message.getAttachmentName() + "...", Toast.LENGTH_SHORT).show();
viewModel.downloadAttachment(message.getId()).observe(getViewLifecycleOwner(), resource -> { viewModel.downloadAttachment(message.getId()).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
saveFileToDownloads(resource.data, message.getAttachmentName(), message.getAttachmentMimeType()); saveFileToDownloads(resource.data, message.getAttachmentName(), message.getAttachmentMimeType());
} else if (resource != null && resource.status == Resource.Status.ERROR) { } else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(requireContext(), "Download failed: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), "Download failed: " + resource.message, Toast.LENGTH_SHORT).show();
} }
}); });
@@ -285,9 +287,13 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
scrollToBottom(); scrollToBottom();
}); });
viewModel.getIsLoading().observe(getViewLifecycleOwner(), loading -> { viewModel.getIsLoading().observe(getViewLifecycleOwner(), this::setLoading);
// Can show a progress bar if needed }
});
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
} }
private void updateTitleAndStateIfActive(List<Chat> list) { private void updateTitleAndStateIfActive(List<Chat> list) {
@@ -324,15 +330,12 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
activeConversationId = getActivity().getIntent().getLongExtra("conversation_id", -1); activeConversationId = getActivity().getIntent().getLongExtra("conversation_id", -1);
getActivity().getIntent().removeExtra("conversation_id"); getActivity().getIntent().removeExtra("conversation_id");
} else { } else {
// Restore last active conversation if any
activeConversationId = viewModel.getLastActiveConversationId(); activeConversationId = viewModel.getLastActiveConversationId();
} }
viewModel.loadCustomers(); viewModel.loadCustomers();
//
if (activeConversationId != null) { if (activeConversationId != null) {
// Re-subscribe and load history if there is an active conversation ID
if (stompChatManager != null) stompChatManager.subscribeToConversation(activeConversationId); if (stompChatManager != null) stompChatManager.subscribeToConversation(activeConversationId);
viewModel.loadMessageHistory(activeConversationId); viewModel.loadMessageHistory(activeConversationId);
} else { } else {
@@ -360,7 +363,9 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
binding.etMessage.setText(""); binding.etMessage.setText("");
viewModel.sendMessage(activeConversationId, text).observe(getViewLifecycleOwner(), resource -> { viewModel.sendMessage(activeConversationId, text).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.addMessageLocally(resource.data); viewModel.addMessageLocally(resource.data);
viewModel.loadConversations(); viewModel.loadConversations();
} }
@@ -416,10 +421,12 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
removeAttachment(); removeAttachment();
viewModel.sendMessageWithAttachment(activeConversationId, contentPart, filePart).observe(getViewLifecycleOwner(), resource -> { viewModel.sendMessageWithAttachment(activeConversationId, contentPart, filePart).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.addMessageLocally(resource.data); viewModel.addMessageLocally(resource.data);
viewModel.loadConversations(); viewModel.loadConversations();
} else if (resource != null && resource.status == Resource.Status.ERROR) { } else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(requireContext(), "Failed to send attachment: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(requireContext(), "Failed to send attachment: " + resource.message, Toast.LENGTH_SHORT).show();
} }
}); });

View File

@@ -172,6 +172,12 @@ public class ProfileFragment extends Fragment {
return binding.getRoot(); return binding.getRoot();
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -184,6 +190,7 @@ public class ProfileFragment extends Fragment {
private void loadProfileData() { private void loadProfileData() {
viewModel.getMe().observe(getViewLifecycleOwner(), resource -> { viewModel.getMe().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
currentUser = resource.data; currentUser = resource.data;
@@ -229,6 +236,7 @@ public class ProfileFragment extends Fragment {
//Call the backend to upload the avatar //Call the backend to upload the avatar
viewModel.uploadAvatar(body).observe(getViewLifecycleOwner(), resource -> { viewModel.uploadAvatar(body).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Avatar updated successfully", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Avatar updated successfully", Toast.LENGTH_SHORT).show();
loadProfileData(); loadProfileData();
@@ -247,6 +255,7 @@ public class ProfileFragment extends Fragment {
private void deleteAvatar() { private void deleteAvatar() {
viewModel.deleteAvatar().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteAvatar().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
hasImage = false; hasImage = false;
binding.imgProfile.setImageResource(R.drawable.placeholder); binding.imgProfile.setImageResource(R.drawable.placeholder);
@@ -266,6 +275,7 @@ public class ProfileFragment extends Fragment {
viewModel.updateMe(updates).observe(getViewLifecycleOwner(), resource -> { viewModel.updateMe(updates).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
currentUser = resource.data; currentUser = resource.data;
Toast.makeText(getContext(), "Profile updated successfully", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Profile updated successfully", Toast.LENGTH_SHORT).show();

View File

@@ -41,6 +41,7 @@ public class AnalyticsFragment extends Fragment {
viewModel.getAnalyticsData().observe(getViewLifecycleOwner(), this::computeAndDisplay); viewModel.getAnalyticsData().observe(getViewLifecycleOwner(), this::computeAndDisplay);
viewModel.getIsLoading().observe(getViewLifecycleOwner(), loading -> { viewModel.getIsLoading().observe(getViewLifecycleOwner(), loading -> {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
if (loading) { if (loading) {
binding.tvTotalRevenue.setText("Loading..."); binding.tvTotalRevenue.setText("Loading...");
binding.tvTotalTransactions.setText("..."); binding.tvTotalTransactions.setText("...");
@@ -117,8 +118,6 @@ public class AnalyticsFragment extends Fragment {
if (data.employeePerformance != null && !data.employeePerformance.isEmpty()) { if (data.employeePerformance != null && !data.employeePerformance.isEmpty()) {
BigDecimal maxEmp = data.employeePerformance.get(data.employeePerformance.size() - 1).getValue(); BigDecimal maxEmp = data.employeePerformance.get(data.employeePerformance.size() - 1).getValue();
if (maxEmp.compareTo(BigDecimal.ZERO) == 0) maxEmp = BigDecimal.ONE; if (maxEmp.compareTo(BigDecimal.ZERO) == 0) maxEmp = BigDecimal.ONE;
// Sorting is ascending from VM for some reason? Let's check VM... it says b.getValue().compareTo(a.getValue()) which is DESC.
// Wait, computeAnalytics sorts them... let's assume DESC as per VM code.
maxEmp = data.employeePerformance.get(0).getValue(); maxEmp = data.employeePerformance.get(0).getValue();
if (maxEmp.compareTo(BigDecimal.ZERO) == 0) maxEmp = BigDecimal.ONE; if (maxEmp.compareTo(BigDecimal.ZERO) == 0) maxEmp = BigDecimal.ONE;

View File

@@ -1,6 +1,5 @@
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.*; import android.view.*;
import android.widget.*; import android.widget.*;
@@ -12,7 +11,9 @@ import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.databinding.FragmentAdoptionDetailBinding; import com.example.petstoremobile.databinding.FragmentAdoptionDetailBinding;
import com.example.petstoremobile.dtos.*; import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
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.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils; import com.example.petstoremobile.utils.UIUtils;
@@ -73,6 +74,12 @@ public class AdoptionDetailFragment extends Fragment {
viewModel.getEmployeeList().observe(getViewLifecycleOwner(), list -> refreshEmployeeSpinner()); viewModel.getEmployeeList().observe(getViewLifecycleOwner(), list -> refreshEmployeeSpinner());
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -116,29 +123,27 @@ public class AdoptionDetailFragment extends Fragment {
} }
private void setupDatePicker() { private void setupDatePicker() {
binding.etAdoptionDate.setOnClickListener(v -> { binding.etAdoptionDate.setOnClickListener(v -> UIUtils.showDatePicker(requireContext(), binding.etAdoptionDate, null));
Calendar c = Calendar.getInstance();
new DatePickerDialog(requireContext(),
(dp, y, m, d) -> binding.etAdoptionDate.setText(
String.format("%04d-%02d-%02d", y, m + 1, d)),
c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH)).show();
});
} }
private void loadSpinnersData() { private void loadSpinnersData() {
viewModel.loadPets().observe(getViewLifecycleOwner(), resource -> { viewModel.loadPets().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setPetList(resource.data); viewModel.setPetList(resource.data);
} }
}); });
viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> { viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setCustomerList(resource.data); viewModel.setCustomerList(resource.data);
} }
}); });
viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> { viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setStoreList(resource.data); viewModel.setStoreList(resource.data);
} }
@@ -165,7 +170,9 @@ public class AdoptionDetailFragment extends Fragment {
private void loadEmployees(Long storeId) { private void loadEmployees(Long storeId) {
viewModel.loadEmployees(storeId).observe(getViewLifecycleOwner(), resource -> { viewModel.loadEmployees(storeId).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setEmployeeList(resource.data); viewModel.setEmployeeList(resource.data);
} }
}); });
@@ -183,7 +190,7 @@ public class AdoptionDetailFragment extends Fragment {
long adoptionId = a.getLong("adoptionId"); long adoptionId = a.getLong("adoptionId");
viewModel.setAdoptionId(adoptionId); viewModel.setAdoptionId(adoptionId);
binding.tvAdoptionMode.setText("Edit Adoption"); binding.tvAdoptionMode.setText("Edit Adoption");
binding.tvAdoptionId.setText("ID: " + adoptionId); binding.tvAdoptionId.setText(DateTimeUtils.formatId(adoptionId));
binding.tvAdoptionId.setVisibility(View.VISIBLE); binding.tvAdoptionId.setVisibility(View.VISIBLE);
binding.btnDeleteAdoption.setVisibility(View.VISIBLE); binding.btnDeleteAdoption.setVisibility(View.VISIBLE);
loadAdoptionData(); loadAdoptionData();
@@ -199,6 +206,7 @@ public class AdoptionDetailFragment extends Fragment {
private void loadAdoptionData() { private void loadAdoptionData() {
viewModel.loadAdoption().observe(getViewLifecycleOwner(), resource -> { viewModel.loadAdoption().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
AdoptionDTO a = resource.data; AdoptionDTO a = resource.data;
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1; preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
@@ -224,29 +232,16 @@ public class AdoptionDetailFragment extends Fragment {
} }
private void saveAdoption() { private void saveAdoption() {
if (binding.spinnerAdoptionCustomer.getSelectedItemPosition() == 0) { if (!InputValidator.isSpinnerSelected(binding.spinnerAdoptionCustomer, "Customer")) return;
Toast.makeText(getContext(), "Select a customer", Toast.LENGTH_SHORT).show(); return; if (!InputValidator.isSpinnerSelected(binding.spinnerAdoptionPet, "Pet")) return;
} if (!InputValidator.isSpinnerSelected(binding.spinnerAdoptionStore, "Store")) return;
if (binding.spinnerAdoptionPet.getSelectedItemPosition() == 0) { if (!InputValidator.isNotEmpty(binding.etAdoptionDate, "Adoption Date")) return;
Toast.makeText(getContext(), "Select a pet", Toast.LENGTH_SHORT).show(); return;
}
if (binding.spinnerAdoptionStore.getSelectedItemPosition() == 0) {
Toast.makeText(getContext(), "Select a store", Toast.LENGTH_SHORT).show(); return;
}
String date = binding.etAdoptionDate.getText().toString().trim();
if (date.isEmpty()) {
Toast.makeText(getContext(), "Select a date", Toast.LENGTH_SHORT).show(); return;
}
BigDecimal fee = BigDecimal.ZERO; BigDecimal fee = BigDecimal.ZERO;
String feeStr = binding.etAdoptionFee.getText().toString().trim(); String feeStr = binding.etAdoptionFee.getText().toString().trim();
if (!feeStr.isEmpty()) { if (!feeStr.isEmpty()) {
try { if (!InputValidator.isPositiveDecimal(binding.etAdoptionFee, "Adoption Fee")) return;
fee = new BigDecimal(feeStr); fee = new BigDecimal(feeStr);
} catch (NumberFormatException e) {
Toast.makeText(getContext(), "Invalid fee format", Toast.LENGTH_SHORT).show();
return;
}
} }
DropdownDTO customer = viewModel.getCustomerList().getValue().get(binding.spinnerAdoptionCustomer.getSelectedItemPosition() - 1); DropdownDTO customer = viewModel.getCustomerList().getValue().get(binding.spinnerAdoptionCustomer.getSelectedItemPosition() - 1);
@@ -258,6 +253,7 @@ public class AdoptionDetailFragment extends Fragment {
employeeId = viewModel.getEmployeeList().getValue().get(binding.spinnerAdoptionEmployee.getSelectedItemPosition() - 1).getId(); employeeId = viewModel.getEmployeeList().getValue().get(binding.spinnerAdoptionEmployee.getSelectedItemPosition() - 1).getId();
} }
String adoptionDate = binding.etAdoptionDate.getText().toString().trim();
String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()]; String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()];
AdoptionDTO dto = new AdoptionDTO( AdoptionDTO dto = new AdoptionDTO(
@@ -265,12 +261,14 @@ public class AdoptionDetailFragment extends Fragment {
customer.getId(), customer.getId(),
employeeId, employeeId,
store.getId(), store.getId(),
date, adoptionDate,
status, status,
fee fee
); );
viewModel.saveAdoption(dto).observe(getViewLifecycleOwner(), resource -> { viewModel.saveAdoption(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), viewModel.isEditing() ? "Updated" : "Saved", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), viewModel.isEditing() ? "Updated" : "Saved", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();
@@ -281,8 +279,10 @@ public class AdoptionDetailFragment extends Fragment {
} }
private void confirmDelete() { private void confirmDelete() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Adoption", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Adoption Record", () ->
viewModel.deleteAdoption().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteAdoption().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();

View File

@@ -19,6 +19,7 @@ import com.example.petstoremobile.dtos.DropdownDTO;
import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.utils.DateTimeUtils; import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
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.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils; import com.example.petstoremobile.utils.UIUtils;
@@ -140,6 +141,12 @@ public class AppointmentDetailFragment extends Fragment {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff, list, DropdownDTO::getLabel, "-- Select Staff --", preselectedStaffId, DropdownDTO::getId)); SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff, list, DropdownDTO::getLabel, "-- Select Staff --", preselectedStaffId, DropdownDTO::getId));
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void applyViewState(AppointmentDetailViewModel.ViewState state) { private void applyViewState(AppointmentDetailViewModel.ViewState state) {
isUpdatingUI = true; isUpdatingUI = true;
@@ -189,22 +196,25 @@ public class AppointmentDetailFragment extends Fragment {
private void loadAppointmentData() { private void loadAppointmentData() {
viewModel.loadAppointment().observe(getViewLifecycleOwner(), resource -> { viewModel.loadAppointment().observe(getViewLifecycleOwner(), resource -> {
if (resource == null || resource.status != Resource.Status.SUCCESS || resource.data == null) return; if (resource == null) return;
AppointmentDTO a = resource.data; setLoading(resource.status == Resource.Status.LOADING);
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1; if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
preselectedServiceId = a.getServiceId() != null ? a.getServiceId() : -1; AppointmentDTO a = resource.data;
preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1; preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
preselectedStoreId = a.getStoreId() != null ? a.getStoreId() : -1; preselectedServiceId = a.getServiceId() != null ? a.getServiceId() : -1;
preselectedStaffId = a.getEmployeeId() != null ? a.getEmployeeId() : -1; preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
preselectedStoreId = a.getStoreId() != null ? a.getStoreId() : -1;
preselectedStaffId = a.getEmployeeId() != null ? a.getEmployeeId() : -1;
binding.etAppointmentDate.setText(a.getAppointmentDate()); binding.etAppointmentDate.setText(a.getAppointmentDate());
parseAndSetTimeSpinners(a.getAppointmentTime() != null ? a.getAppointmentTime() : "09:00"); parseAndSetTimeSpinners(a.getAppointmentTime() != null ? a.getAppointmentTime() : "09:00");
String status = a.getAppointmentStatus(); String status = a.getAppointmentStatus();
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, DateTimeUtils.formatStatusFromBackend(status)); SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, DateTimeUtils.formatStatusFromBackend(status));
}
notifyDateTimeStatusChange();
} }
notifyDateTimeStatusChange();
}); });
} }
@@ -221,6 +231,8 @@ public class AppointmentDetailFragment extends Fragment {
} }
viewModel.saveAppointment(date, time, status).observe(getViewLifecycleOwner(), resource -> { viewModel.saveAppointment(date, time, status).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue(); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
String message = (state != null && state.isEditing) ? "Updated" : "Saved"; String message = (state != null && state.isEditing) ? "Updated" : "Saved";
@@ -233,11 +245,11 @@ public class AppointmentDetailFragment extends Fragment {
} }
private boolean validateRequiredFields() { private boolean validateRequiredFields() {
if (binding.spinnerCustomer.getSelectedItemPosition() == 0) return UIUtils.showToast(getContext(), "Select a customer"); if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Customer")) return false;
if (binding.spinnerStore.getSelectedItemPosition() == 0) return UIUtils.showToast(getContext(), "Select a store"); if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return false;
if (binding.spinnerPet.getSelectedItemPosition() == 0) return UIUtils.showToast(getContext(), "Select a pet"); if (!InputValidator.isSpinnerSelected(binding.spinnerPet, "Pet")) return false;
if (binding.spinnerService.getSelectedItemPosition() == 0) return UIUtils.showToast(getContext(), "Select a service"); if (!InputValidator.isSpinnerSelected(binding.spinnerService, "Service")) return false;
if (binding.etAppointmentDate.getText().toString().trim().isEmpty()) return UIUtils.showToast(getContext(), "Select a date"); if (!InputValidator.isNotEmpty(binding.etAppointmentDate, "Appointment Date")) return false;
return true; return true;
} }
@@ -261,6 +273,8 @@ public class AppointmentDetailFragment extends Fragment {
private void confirmDelete() { private void confirmDelete() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Appointment", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Appointment", () ->
viewModel.deleteAppointment().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteAppointment().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) navigateBack(); if (resource.status == Resource.Status.SUCCESS) navigateBack();
})); }));
} }

View File

@@ -8,7 +8,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
@@ -17,9 +16,11 @@ import com.example.petstoremobile.databinding.FragmentInventoryDetailBinding;
import com.example.petstoremobile.dtos.DropdownDTO; import com.example.petstoremobile.dtos.DropdownDTO;
import com.example.petstoremobile.dtos.InventoryDTO; import com.example.petstoremobile.dtos.InventoryDTO;
import com.example.petstoremobile.dtos.ProductDTO; import com.example.petstoremobile.dtos.ProductDTO;
import com.example.petstoremobile.utils.DialogUtils;
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.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.InventoryDetailViewModel; import com.example.petstoremobile.viewmodels.InventoryDetailViewModel;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
@@ -67,6 +68,12 @@ public class InventoryDetailFragment extends Fragment {
viewModel.getProductList().observe(getViewLifecycleOwner(), list -> refreshProductSpinner()); viewModel.getProductList().observe(getViewLifecycleOwner(), list -> refreshProductSpinner());
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -75,11 +82,15 @@ public class InventoryDetailFragment extends Fragment {
private void loadSpinnersData() { private void loadSpinnersData() {
viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> { viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setStoreList(resource.data); viewModel.setStoreList(resource.data);
} }
}); });
viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> { viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setProductList(resource.data.getContent()); viewModel.setProductList(resource.data.getContent());
} }
@@ -123,6 +134,7 @@ public class InventoryDetailFragment extends Fragment {
private void loadInventoryData() { private void loadInventoryData() {
viewModel.loadInventory().observe(getViewLifecycleOwner(), resource -> { viewModel.loadInventory().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
InventoryDTO inv = resource.data; InventoryDTO inv = resource.data;
binding.etQuantity.setText(String.valueOf(inv.getQuantity())); binding.etQuantity.setText(String.valueOf(inv.getQuantity()));
@@ -138,19 +150,9 @@ public class InventoryDetailFragment extends Fragment {
} }
private void saveInventory() { private void saveInventory() {
if (binding.spinnerInventoryStore.getSelectedItemPosition() == 0) { if (!InputValidator.isSpinnerSelected(binding.spinnerInventoryStore, "Store")) return;
Toast.makeText(getContext(), "Please select a store", Toast.LENGTH_SHORT).show(); if (!InputValidator.isSpinnerSelected(binding.spinnerInventoryProduct, "Product")) return;
return; if (!InputValidator.isPositiveInteger(binding.etQuantity, "Quantity")) return;
}
if (binding.spinnerInventoryProduct.getSelectedItemPosition() == 0) {
Toast.makeText(getContext(), "Please select a product", Toast.LENGTH_SHORT).show();
return;
}
if (!InputValidator.isNotEmpty(binding.etQuantity, "Quantity") ||
!InputValidator.isPositiveInteger(binding.etQuantity, "Quantity")) {
return;
}
int quantity = Integer.parseInt(binding.etQuantity.getText().toString().trim()); int quantity = Integer.parseInt(binding.etQuantity.getText().toString().trim());
DropdownDTO store = viewModel.getStoreList().getValue().get(binding.spinnerInventoryStore.getSelectedItemPosition() - 1); DropdownDTO store = viewModel.getStoreList().getValue().get(binding.spinnerInventoryStore.getSelectedItemPosition() - 1);
@@ -160,34 +162,37 @@ public class InventoryDetailFragment extends Fragment {
setButtonsEnabled(false); setButtonsEnabled(false);
viewModel.saveInventory(request).observe(getViewLifecycleOwner(), resource -> { viewModel.saveInventory(request).observe(getViewLifecycleOwner(), resource -> {
setButtonsEnabled(true); if (resource == null) return;
if (resource.status == Resource.Status.SUCCESS) { setLoading(resource.status == Resource.Status.LOADING);
Toast.makeText(getContext(), viewModel.isEditing() ? "Inventory updated" : "Inventory created", Toast.LENGTH_SHORT).show(); if (resource.status != Resource.Status.LOADING) {
navigateBack(); setButtonsEnabled(true);
} else if (resource.status == Resource.Status.ERROR) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), viewModel.isEditing() ? "Inventory updated" : "Inventory created", Toast.LENGTH_SHORT).show();
navigateBack();
} else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_SHORT).show();
}
} }
}); });
} }
private void confirmDelete() { private void confirmDelete() {
new AlertDialog.Builder(requireContext()) DialogUtils.showDeleteConfirmDialog(requireContext(), "Inventory Item", this::deleteInventory);
.setTitle("Delete inventory item?")
.setMessage("This cannot be undone.")
.setPositiveButton("Delete", (d, w) -> deleteInventory())
.setNegativeButton("Cancel", null)
.show();
} }
private void deleteInventory() { private void deleteInventory() {
setButtonsEnabled(false); setButtonsEnabled(false);
viewModel.deleteInventory().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteInventory().observe(getViewLifecycleOwner(), resource -> {
setButtonsEnabled(true); if (resource == null) return;
if (resource.status == Resource.Status.SUCCESS) { setLoading(resource.status == Resource.Status.LOADING);
Toast.makeText(getContext(), "Inventory deleted", Toast.LENGTH_SHORT).show(); if (resource.status != Resource.Status.LOADING) {
navigateBack(); setButtonsEnabled(true);
} else if (resource.status == Resource.Status.ERROR) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Inventory deleted", Toast.LENGTH_SHORT).show();
navigateBack();
} else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
}
} }
}); });
} }
@@ -197,8 +202,6 @@ public class InventoryDetailFragment extends Fragment {
} }
private void setButtonsEnabled(boolean enabled) { private void setButtonsEnabled(boolean enabled) {
binding.btnSaveInventory.setEnabled(enabled); UIUtils.setViewsEnabled(enabled, binding.btnSaveInventory, binding.btnDeleteInventory, binding.btnInventoryBack);
binding.btnDeleteInventory.setEnabled(enabled);
binding.btnInventoryBack.setEnabled(enabled);
} }
} }

View File

@@ -21,6 +21,7 @@ import com.example.petstoremobile.databinding.FragmentPetDetailBinding;
import com.example.petstoremobile.dtos.DropdownDTO; import com.example.petstoremobile.dtos.DropdownDTO;
import com.example.petstoremobile.dtos.PetDTO; import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.utils.ActivityLogger; import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
@@ -65,7 +66,6 @@ public class PetDetailFragment extends Fragment {
observeViewModel(); observeViewModel();
handleArguments(); handleArguments();
//set button click listeners
binding.btnBack.setOnClickListener(v -> navigateBack()); binding.btnBack.setOnClickListener(v -> navigateBack());
binding.btnSavePet.setOnClickListener(v -> savePet()); binding.btnSavePet.setOnClickListener(v -> savePet());
binding.btnDeletePet.setOnClickListener(v -> deletePet()); binding.btnDeletePet.setOnClickListener(v -> deletePet());
@@ -76,36 +76,41 @@ public class PetDetailFragment extends Fragment {
viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> updateStoreSpinnerSelection()); viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> updateStoreSpinnerSelection());
viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> { viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setCustomerList(resource.data); viewModel.setCustomerList(resource.data);
} }
}); });
viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> { viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setStoreList(resource.data); viewModel.setStoreList(resource.data);
} }
}); });
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
binding = null; binding = null;
} }
/**
* Handles the saving of pet data (adding/updating).
*/
private void savePet() { private void savePet() {
// Validates all fields using InputValidator
if (!InputValidator.isNotEmpty(binding.etPetName, "Pet Name")) return; if (!InputValidator.isNotEmpty(binding.etPetName, "Pet Name")) return;
if (!InputValidator.isNotEmpty(binding.etPetSpecies, "Species")) return; if (!InputValidator.isNotEmpty(binding.etPetSpecies, "Species")) return;
if (!InputValidator.isNotEmpty(binding.etPetBreed, "Breed")) return; if (!InputValidator.isNotEmpty(binding.etPetBreed, "Breed")) return;
if (!InputValidator.isPositiveInteger(binding.etPetAge, "Age")) return; if (!InputValidator.isPositiveInteger(binding.etPetAge, "Age")) return;
if (!InputValidator.isPositiveDecimal(binding.etPetPrice, "Price")) return; if (!InputValidator.isPositiveDecimal(binding.etPetPrice, "Price")) return;
//get all the values from the fields
String name = binding.etPetName.getText().toString().trim(); String name = binding.etPetName.getText().toString().trim();
String species = binding.etPetSpecies.getText().toString().trim(); String species = binding.etPetSpecies.getText().toString().trim();
String breed = binding.etPetBreed.getText().toString().trim(); String breed = binding.etPetBreed.getText().toString().trim();
@@ -113,37 +118,27 @@ public class PetDetailFragment extends Fragment {
double price = Double.parseDouble(binding.etPetPrice.getText().toString().trim()); double price = Double.parseDouble(binding.etPetPrice.getText().toString().trim());
String status = binding.spinnerPetStatus.getSelectedItem().toString(); String status = binding.spinnerPetStatus.getSelectedItem().toString();
// Get selected customer
Long customerId = null; Long customerId = null;
int customerPos = binding.spinnerCustomer.getSelectedItemPosition(); if (binding.spinnerCustomer.getSelectedItemPosition() > 0) {
if (customerPos > 0) { // 0 means no customer for pet customerId = viewModel.getCustomerList().getValue().get(binding.spinnerCustomer.getSelectedItemPosition() - 1).getId();
customerId = viewModel.getCustomerList().getValue().get(customerPos - 1).getId();
} }
// Get selected store
Long storeId = null; Long storeId = null;
int storePos = binding.spinnerStore.getSelectedItemPosition(); if (binding.spinnerStore.getSelectedItemPosition() > 0) {
if (storePos > 0) { storeId = viewModel.getStoreList().getValue().get(binding.spinnerStore.getSelectedItemPosition() - 1).getId();
storeId = viewModel.getStoreList().getValue().get(storePos - 1).getId();
} }
// Validation: If status is Available, a store must be selected
if ("Available".equalsIgnoreCase(status)) { if ("Available".equalsIgnoreCase(status)) {
if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return; if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return;
} }
// Validation: If status is Owned, an owner must be selected
if ("Owned".equalsIgnoreCase(status)) { if ("Owned".equalsIgnoreCase(status)) {
if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return; if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return;
} }
// Validation: If status is Adopted, an owner and store must be selected
if ("Adopted".equalsIgnoreCase(status)) { if ("Adopted".equalsIgnoreCase(status)) {
if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return; if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return;
if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return; if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return;
} }
//create a pet object to send to the API
PetDTO petDTO = new PetDTO(); PetDTO petDTO = new PetDTO();
petDTO.setPetName(name); petDTO.setPetName(name);
petDTO.setPetSpecies(species); petDTO.setPetSpecies(species);
@@ -155,6 +150,8 @@ public class PetDetailFragment extends Fragment {
petDTO.setStoreId(storeId); petDTO.setStoreId(storeId);
viewModel.savePet(petDTO).observe(getViewLifecycleOwner(), resource -> { viewModel.savePet(petDTO).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
if (viewModel.isEditing()) { if (viewModel.isEditing()) {
ActivityLogger.logChange(requireContext(), "Pet", "UPDATED", (int) viewModel.getPetId()); ActivityLogger.logChange(requireContext(), "Pet", "UPDATED", (int) viewModel.getPetId());
@@ -170,12 +167,11 @@ public class PetDetailFragment extends Fragment {
}); });
} }
/**
* Displays a confirmation dialog and handles the deletion of a pet.
*/
private void deletePet() { private void deletePet() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Pet", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Pet", () -> {
viewModel.deletePet().observe(getViewLifecycleOwner(), resource -> { viewModel.deletePet().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
ActivityLogger.logChange(requireContext(), "Pet", "DELETED", (int) viewModel.getPetId()); ActivityLogger.logChange(requireContext(), "Pet", "DELETED", (int) viewModel.getPetId());
Toast.makeText(getContext(), "Pet deleted successfully!", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Pet deleted successfully!", Toast.LENGTH_SHORT).show();
@@ -183,32 +179,24 @@ public class PetDetailFragment extends Fragment {
} else if (resource.status == Resource.Status.ERROR) { } else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
} }
})); });
});
} }
/**
* Navigates back to the pet list screen.
*/
private void navigateToPetList() { private void navigateToPetList() {
NavHostFragment.findNavController(this).popBackStack(R.id.nav_pet, false); NavHostFragment.findNavController(this).popBackStack(R.id.nav_pet, false);
} }
/**
* Navigates back to the previous screen.
*/
private void navigateBack() { private void navigateBack() {
NavHostFragment.findNavController(this).popBackStack(); NavHostFragment.findNavController(this).popBackStack();
} }
/**
* Handles arguments passed to the fragment to determine if it's in edit or add mode.
*/
private void handleArguments() { private void handleArguments() {
if (getArguments() != null && getArguments().containsKey("petId")) { if (getArguments() != null && getArguments().containsKey("petId")) {
long petId = getArguments().getLong("petId"); long petId = getArguments().getLong("petId");
viewModel.setPetId(petId); viewModel.setPetId(petId);
binding.tvMode.setText("Edit Pet"); binding.tvMode.setText("Edit Pet");
binding.tvPetId.setText("ID: " + petId); binding.tvPetId.setText(DateTimeUtils.formatId(petId));
binding.tvPetId.setVisibility(View.VISIBLE); binding.tvPetId.setVisibility(View.VISIBLE);
binding.btnDeletePet.setVisibility(View.VISIBLE); binding.btnDeletePet.setVisibility(View.VISIBLE);
@@ -225,12 +213,10 @@ public class PetDetailFragment extends Fragment {
} }
} }
/**
* Fetches specific pet details from the backend using the ID.
*/
private void loadPetData() { private void loadPetData() {
viewModel.loadPet().observe(getViewLifecycleOwner(), resource -> { viewModel.loadPet().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
PetDTO p = resource.data; PetDTO p = resource.data;
binding.etPetName.setText(p.getPetName()); binding.etPetName.setText(p.getPetName());
@@ -253,9 +239,6 @@ public class PetDetailFragment extends Fragment {
}); });
} }
/**
* Updates the customer spinner with the current list and sets the selection if needed.
*/
private void updateCustomerSpinnerSelection() { private void updateCustomerSpinnerSelection() {
SpinnerUtils.populateSpinner( SpinnerUtils.populateSpinner(
requireContext(), requireContext(),
@@ -268,9 +251,6 @@ public class PetDetailFragment extends Fragment {
); );
} }
/**
* Updates the store spinner with the current list and sets the selection if needed.
*/
private void updateStoreSpinnerSelection() { private void updateStoreSpinnerSelection() {
SpinnerUtils.populateSpinner( SpinnerUtils.populateSpinner(
requireContext(), requireContext(),
@@ -283,9 +263,6 @@ public class PetDetailFragment extends Fragment {
); );
} }
/**
* Initializes the spinner for pet status selection.
*/
private void setupSpinner() { private void setupSpinner() {
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerPetStatus, SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerPetStatus,
new String[]{"Available", "Adopted", "Owned"}); new String[]{"Available", "Adopted", "Owned"});

View File

@@ -18,6 +18,7 @@ import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.databinding.FragmentProductDetailBinding; import com.example.petstoremobile.databinding.FragmentProductDetailBinding;
import com.example.petstoremobile.dtos.*; import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.viewmodels.ProductDetailViewModel; import com.example.petstoremobile.viewmodels.ProductDetailViewModel;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.FileUtils; import com.example.petstoremobile.utils.FileUtils;
import com.example.petstoremobile.utils.GlideUtils; import com.example.petstoremobile.utils.GlideUtils;
@@ -111,12 +112,20 @@ public class ProductDetailFragment extends Fragment {
viewModel.getCategoryList().observe(getViewLifecycleOwner(), list -> updateCategorySpinner()); viewModel.getCategoryList().observe(getViewLifecycleOwner(), list -> updateCategorySpinner());
viewModel.loadCategories().observe(getViewLifecycleOwner(), resource -> { viewModel.loadCategories().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setCategoryList(resource.data.getContent()); viewModel.setCategoryList(resource.data.getContent());
} }
}); });
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void updateCategorySpinner() { private void updateCategorySpinner() {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerProductCategory, viewModel.getCategoryList().getValue(), SpinnerUtils.populateSpinner(requireContext(), binding.spinnerProductCategory, viewModel.getCategoryList().getValue(),
CategoryDTO::getCategoryName, "-- Select Category --", CategoryDTO::getCategoryName, "-- Select Category --",
@@ -135,7 +144,7 @@ public class ProductDetailFragment extends Fragment {
long prodId = a.getLong("prodId"); long prodId = a.getLong("prodId");
viewModel.setProdId(prodId); viewModel.setProdId(prodId);
binding.tvProductMode.setText("Edit Product"); binding.tvProductMode.setText("Edit Product");
binding.tvProductId.setText("ID: " + prodId); binding.tvProductId.setText(DateTimeUtils.formatId(prodId));
binding.tvProductId.setVisibility(View.VISIBLE); binding.tvProductId.setVisibility(View.VISIBLE);
binding.btnDeleteProduct.setVisibility(View.VISIBLE); binding.btnDeleteProduct.setVisibility(View.VISIBLE);
loadProductData(); loadProductData();
@@ -152,6 +161,7 @@ public class ProductDetailFragment extends Fragment {
private void loadProductData() { private void loadProductData() {
viewModel.loadProduct().observe(getViewLifecycleOwner(), resource -> { viewModel.loadProduct().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
ProductDTO p = resource.data; ProductDTO p = resource.data;
binding.etProductName.setText(p.getProdName()); binding.etProductName.setText(p.getProdName());
@@ -185,7 +195,9 @@ public class ProductDetailFragment extends Fragment {
private void performPendingImageActions(String successMsg) { private void performPendingImageActions(String successMsg) {
if (isImageRemoved) { if (isImageRemoved) {
viewModel.deleteProductImage().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteProductImage().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status != Resource.Status.LOADING) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status != Resource.Status.LOADING) {
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
} else { } else {
@@ -214,7 +226,9 @@ public class ProductDetailFragment extends Fragment {
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile); MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
viewModel.uploadProductImage(body).observe(getViewLifecycleOwner(), resource -> { viewModel.uploadProductImage(body).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status != Resource.Status.LOADING) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status != Resource.Status.LOADING) {
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
} else { } else {
@@ -227,15 +241,8 @@ public class ProductDetailFragment extends Fragment {
private void saveProduct() { private void saveProduct() {
if (!InputValidator.isNotEmpty(binding.etProductName, "Product Name")) return; if (!InputValidator.isNotEmpty(binding.etProductName, "Product Name")) return;
if (!InputValidator.isSpinnerSelected(binding.spinnerProductCategory, "Category")) return;
if (binding.spinnerProductCategory.getSelectedItemPosition() == 0) { if (!InputValidator.isPositiveDecimal(binding.etProductPrice, "Price")) return;
Toast.makeText(getContext(), "Select a category", Toast.LENGTH_SHORT).show(); return;
}
if (!InputValidator.isNotEmpty(binding.etProductPrice, "Price") ||
!InputValidator.isPositiveDecimal(binding.etProductPrice, "Price")) {
return;
}
String name = binding.etProductName.getText().toString().trim(); String name = binding.etProductName.getText().toString().trim();
String desc = binding.etProductDesc.getText().toString().trim(); String desc = binding.etProductDesc.getText().toString().trim();
@@ -245,7 +252,9 @@ public class ProductDetailFragment extends Fragment {
ProductDTO dto = new ProductDTO(name, category.getCategoryId(), desc, price); ProductDTO dto = new ProductDTO(name, category.getCategoryId(), desc, price);
viewModel.saveProduct(dto).observe(getViewLifecycleOwner(), resource -> { viewModel.saveProduct(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status != Resource.Status.LOADING) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status != Resource.Status.LOADING) {
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
if (resource.data != null) { if (resource.data != null) {
viewModel.setProdId(resource.data.getProdId()); viewModel.setProdId(resource.data.getProdId());
@@ -261,9 +270,11 @@ public class ProductDetailFragment extends Fragment {
private void confirmDelete() { private void confirmDelete() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Product", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Product", () ->
viewModel.deleteProduct().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteProduct().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) {
navigateBack(); navigateBack();
} else if (resource != null && resource.status == Resource.Status.ERROR) { } else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
} }
})); }));

View File

@@ -15,6 +15,7 @@ import com.example.petstoremobile.utils.DialogUtils;
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.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.ProductSupplierDetailViewModel; import com.example.petstoremobile.viewmodels.ProductSupplierDetailViewModel;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -64,6 +65,12 @@ public class ProductSupplierDetailFragment extends Fragment {
viewModel.getSupplierList().observe(getViewLifecycleOwner(), list -> refreshSupplierSpinner()); viewModel.getSupplierList().observe(getViewLifecycleOwner(), list -> refreshSupplierSpinner());
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -72,11 +79,15 @@ public class ProductSupplierDetailFragment extends Fragment {
private void loadSpinnersData() { private void loadSpinnersData() {
viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> { viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setProductList(resource.data.getContent()); viewModel.setProductList(resource.data.getContent());
} }
}); });
viewModel.loadSuppliers().observe(getViewLifecycleOwner(), resource -> { viewModel.loadSuppliers().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setSupplierList(resource.data.getContent()); viewModel.setSupplierList(resource.data.getContent());
} }
@@ -113,17 +124,9 @@ public class ProductSupplierDetailFragment extends Fragment {
} }
private void save() { private void save() {
if (binding.spinnerPSProduct.getSelectedItemPosition() == 0) { if (!InputValidator.isSpinnerSelected(binding.spinnerPSProduct, "Product")) return;
Toast.makeText(getContext(), "Select a product", Toast.LENGTH_SHORT).show(); return; if (!InputValidator.isSpinnerSelected(binding.spinnerPSSupplier, "Supplier")) return;
} if (!InputValidator.isPositiveDecimal(binding.etPSCost, "Cost")) return;
if (binding.spinnerPSSupplier.getSelectedItemPosition() == 0) {
Toast.makeText(getContext(), "Select a supplier", Toast.LENGTH_SHORT).show(); return;
}
if (!InputValidator.isNotEmpty(binding.etPSCost, "Cost") ||
!InputValidator.isPositiveDecimal(binding.etPSCost, "Cost")) {
return;
}
ProductDTO product = viewModel.getProductList().getValue().get(binding.spinnerPSProduct.getSelectedItemPosition() - 1); ProductDTO product = viewModel.getProductList().getValue().get(binding.spinnerPSProduct.getSelectedItemPosition() - 1);
SupplierDTO supplier = viewModel.getSupplierList().getValue().get(binding.spinnerPSSupplier.getSelectedItemPosition() - 1); SupplierDTO supplier = viewModel.getSupplierList().getValue().get(binding.spinnerPSSupplier.getSelectedItemPosition() - 1);
@@ -132,6 +135,8 @@ public class ProductSupplierDetailFragment extends Fragment {
ProductSupplierDTO dto = new ProductSupplierDTO(product.getProdId(), supplier.getSupId(), cost); ProductSupplierDTO dto = new ProductSupplierDTO(product.getProdId(), supplier.getSupId(), cost);
viewModel.saveProductSupplier(dto).observe(getViewLifecycleOwner(), resource -> { viewModel.saveProductSupplier(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), viewModel.isEditing() ? "Updated" : "Saved", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), viewModel.isEditing() ? "Updated" : "Saved", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();
@@ -142,8 +147,10 @@ public class ProductSupplierDetailFragment extends Fragment {
} }
private void confirmDelete() { private void confirmDelete() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Product Supplier", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Product Supplier Relationship", () ->
viewModel.deleteProductSupplier().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteProductSupplier().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();

View File

@@ -66,9 +66,16 @@ public class PurchaseOrderDetailFragment extends Fragment {
} }
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void loadPurchaseOrderData() { private void loadPurchaseOrderData() {
viewModel.loadPurchaseOrder(purchaseOrderId).observe(getViewLifecycleOwner(), resource -> { viewModel.loadPurchaseOrder(purchaseOrderId).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
PurchaseOrderDTO po = resource.data; PurchaseOrderDTO po = resource.data;
binding.tvPODetailId.setText("PO #" + po.getPurchaseOrderId()); binding.tvPODetailId.setText("PO #" + po.getPurchaseOrderId());

View File

@@ -1,6 +1,5 @@
package com.example.petstoremobile.fragments.listfragments.detailfragments; package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.app.AlertDialog;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.*; import android.view.*;
@@ -13,7 +12,9 @@ import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.FragmentRefundBinding; import com.example.petstoremobile.databinding.FragmentRefundBinding;
import com.example.petstoremobile.dtos.SaleDTO; 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.Resource; import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.SpinnerUtils;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@@ -50,8 +51,7 @@ public class RefundFragment extends Fragment {
} }
private void setupSpinner() { private void setupSpinner() {
binding.spinnerRefundPayment.setAdapter(new ArrayAdapter<>(requireContext(), SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerRefundPayment, PAYMENT_METHODS);
android.R.layout.simple_spinner_item, PAYMENT_METHODS));
} }
private void observeViewModel() { private void observeViewModel() {
@@ -63,9 +63,17 @@ public class RefundFragment extends Fragment {
}); });
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void loadAllSales() { private void loadAllSales() {
viewModel.loadAllSales().observe(getViewLifecycleOwner(), resource -> { viewModel.loadAllSales().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setAllSales(resource.data.getContent()); viewModel.setAllSales(resource.data.getContent());
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null && args.containsKey("saleId")) { if (args != null && args.containsKey("saleId")) {
@@ -122,11 +130,7 @@ public class RefundFragment extends Fragment {
+ " | Payment: " + currentSale.getPaymentMethod()); + " | Payment: " + currentSale.getPaymentMethod());
if (currentSale.getPaymentMethod() != null) { if (currentSale.getPaymentMethod() != null) {
for (int i = 0; i < PAYMENT_METHODS.length; i++) { SpinnerUtils.setSelectionByValue(binding.spinnerRefundPayment, currentSale.getPaymentMethod());
if (PAYMENT_METHODS[i].equalsIgnoreCase(currentSale.getPaymentMethod())) {
binding.spinnerRefundPayment.setSelection(i); break;
}
}
} }
if (viewModel.getAvailableItems().getValue() == null || viewModel.getAvailableItems().getValue().isEmpty()) { if (viewModel.getAvailableItems().getValue() == null || viewModel.getAvailableItems().getValue().isEmpty()) {
@@ -263,39 +267,37 @@ public class RefundFragment extends Fragment {
} }
private void showQuantityDialog(RefundViewModel.RefundItem item, int available) { private void showQuantityDialog(RefundViewModel.RefundItem item, int available) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setTitle("Refund Quantity");
builder.setMessage("Product: " + item.productName + "\nAvailable: " + available);
EditText input = new EditText(getContext()); EditText input = new EditText(getContext());
input.setInputType(android.text.InputType.TYPE_CLASS_NUMBER); input.setInputType(android.text.InputType.TYPE_CLASS_NUMBER);
input.setText(String.valueOf(available)); input.setText(String.valueOf(available));
input.setSelectAllOnFocus(true); input.setSelectAllOnFocus(true);
builder.setView(input); input.setPadding(40, 40, 40, 40);
builder.setPositiveButton("Add to Refund", (d, w) -> { new androidx.appcompat.app.AlertDialog.Builder(requireContext())
String val = input.getText().toString().trim(); .setTitle("Refund Quantity")
if (val.isEmpty()) return; .setMessage("Product: " + item.productName + "\nAvailable: " + available)
int qty; .setView(input)
try { qty = Integer.parseInt(val); } .setPositiveButton("Add to Refund", (d, w) -> {
catch (Exception e) { String val = input.getText().toString().trim();
Toast.makeText(getContext(), "Invalid quantity", Toast.LENGTH_SHORT).show(); if (val.isEmpty()) return;
return; int qty;
} try { qty = Integer.parseInt(val); }
if (qty <= 0) { catch (Exception e) {
Toast.makeText(getContext(), "Quantity must be at least 1", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Invalid quantity", Toast.LENGTH_SHORT).show();
return; return;
} }
if (qty > available) { if (qty <= 0) {
Toast.makeText(getContext(), "Cannot exceed " + available, Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Quantity must be at least 1", Toast.LENGTH_SHORT).show();
return; return;
} }
if (qty > available) {
viewModel.addToCart(item, qty); Toast.makeText(getContext(), "Cannot exceed " + available, Toast.LENGTH_SHORT).show();
}); return;
}
builder.setNegativeButton("Cancel", null); viewModel.addToCart(item, qty);
builder.show(); })
.setNegativeButton("Cancel", null)
.show();
} }
private void updateRefundTotal() { private void updateRefundTotal() {
@@ -322,18 +324,16 @@ public class RefundFragment extends Fragment {
for (RefundViewModel.RefundItem item : viewModel.getRefundCart().getValue()) total = total.add(item.getTotal()); for (RefundViewModel.RefundItem item : viewModel.getRefundCart().getValue()) total = total.add(item.getTotal());
final BigDecimal finalTotal = total; final BigDecimal finalTotal = total;
new AlertDialog.Builder(requireContext()) DialogUtils.showConfirmDialog(requireContext(), "Confirm Refund",
.setTitle("Confirm Refund") "Process refund for Sale #" + viewModel.getCurrentSale().getSaleId()
.setMessage("Process refund for Sale #" + viewModel.getCurrentSale().getSaleId() + "?\nRefund amount: $" + finalTotal.setScale(2, RoundingMode.HALF_UP),
+ "?\nRefund amount: $" + finalTotal.setScale(2, RoundingMode.HALF_UP)) () -> submitRefund(payment));
.setPositiveButton("Yes", (d, w) -> submitRefund(payment))
.setNegativeButton("No", null)
.show();
} }
private void submitRefund(String payment) { private void submitRefund(String payment) {
viewModel.submitRefund(payment).observe(getViewLifecycleOwner(), resource -> { viewModel.submitRefund(payment).observe(getViewLifecycleOwner(), resource -> {
if (resource != null) { if (resource != null) {
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Refund processed successfully!", Toast.LENGTH_LONG).show(); Toast.makeText(getContext(), "Refund processed successfully!", Toast.LENGTH_LONG).show();
navigateBack(); navigateBack();

View File

@@ -14,6 +14,7 @@ import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.viewmodels.SaleDetailViewModel; import com.example.petstoremobile.viewmodels.SaleDetailViewModel;
import com.example.petstoremobile.utils.SpinnerUtils; import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.UIUtils; import com.example.petstoremobile.utils.UIUtils;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
@@ -107,21 +108,35 @@ public class SaleDetailFragment extends Fragment {
} }
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void loadData() { private void loadData() {
viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> { viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setStoreList(resource.data); if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setStoreList(resource.data);
}); });
viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> { viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setCustomerList(resource.data); if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setCustomerList(resource.data);
}); });
viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> { viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setProductList(resource.data.getContent()); if (resource.status == Resource.Status.SUCCESS && resource.data != null) viewModel.setProductList(resource.data.getContent());
}); });
} }
private void loadSaleDetails() { private void loadSaleDetails() {
viewModel.loadSaleDetails().observe(getViewLifecycleOwner(), resource -> { viewModel.loadSaleDetails().observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
SaleDTO sale = resource.data; SaleDTO sale = resource.data;
binding.tvSaleDetailTotal.setText("Total: $" + sale.getTotalAmount()); binding.tvSaleDetailTotal.setText("Total: $" + sale.getTotalAmount());
binding.tvSaleSubtotal.setText("$" + (sale.getSubtotalAmount() != null ? sale.getSubtotalAmount() : sale.getTotalAmount())); binding.tvSaleSubtotal.setText("$" + (sale.getSubtotalAmount() != null ? sale.getSubtotalAmount() : sale.getTotalAmount()));
@@ -157,22 +172,10 @@ public class SaleDetailFragment extends Fragment {
private void setupAddItem() { private void setupAddItem() {
binding.btnAddItem.setOnClickListener(v -> { binding.btnAddItem.setOnClickListener(v -> {
if (binding.spinnerSaleProduct.getSelectedItemPosition() == 0) { if (!InputValidator.isSpinnerSelected(binding.spinnerSaleProduct, "Product")) return;
Toast.makeText(getContext(), "Select a product", Toast.LENGTH_SHORT).show(); if (!InputValidator.isPositiveInteger(binding.etSaleQuantity, "Quantity")) return;
return;
}
String qtyStr = binding.etSaleQuantity.getText().toString().trim();
if (qtyStr.isEmpty()) {
binding.etSaleQuantity.setError("Enter quantity");
return;
}
int qty;
try { qty = Integer.parseInt(qtyStr); }
catch (Exception e) {
binding.etSaleQuantity.setError("Invalid quantity");
return;
}
int qty = Integer.parseInt(binding.etSaleQuantity.getText().toString().trim());
ProductDTO product = viewModel.getProductList().getValue().get(binding.spinnerSaleProduct.getSelectedItemPosition() - 1); ProductDTO product = viewModel.getProductList().getValue().get(binding.spinnerSaleProduct.getSelectedItemPosition() - 1);
for (SaleDTO.SaleItemDTO existing : viewModel.getCartItems().getValue()) { for (SaleDTO.SaleItemDTO existing : viewModel.getCartItems().getValue()) {
@@ -238,10 +241,8 @@ public class SaleDetailFragment extends Fragment {
} }
private void saveSale() { private void saveSale() {
if (binding.spinnerSaleStore.getSelectedItemPosition() == 0) { if (!InputValidator.isSpinnerSelected(binding.spinnerSaleStore, "Store")) return;
Toast.makeText(getContext(), "Select a store", Toast.LENGTH_SHORT).show();
return;
}
if (viewModel.getCartItems().getValue() == null || viewModel.getCartItems().getValue().isEmpty()) { if (viewModel.getCartItems().getValue() == null || viewModel.getCartItems().getValue().isEmpty()) {
Toast.makeText(getContext(), "Add at least one item", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Add at least one item", Toast.LENGTH_SHORT).show();
return; return;
@@ -259,6 +260,7 @@ public class SaleDetailFragment extends Fragment {
viewModel.createSale(dto).observe(getViewLifecycleOwner(), resource -> { viewModel.createSale(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource != null) { if (resource != null) {
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), "Sale saved!", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Sale saved!", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();

View File

@@ -17,6 +17,7 @@ import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.FragmentServiceDetailBinding; import com.example.petstoremobile.databinding.FragmentServiceDetailBinding;
import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.utils.ActivityLogger; import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils; import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
@@ -57,6 +58,12 @@ public class ServiceDetailFragment extends Fragment {
binding.btnDeleteService.setOnClickListener(v -> deleteService()); binding.btnDeleteService.setOnClickListener(v -> deleteService());
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -81,6 +88,8 @@ public class ServiceDetailFragment extends Fragment {
serviceDTO.setServicePrice(price); serviceDTO.setServicePrice(price);
viewModel.saveService(serviceDTO).observe(getViewLifecycleOwner(), resource -> { viewModel.saveService(serviceDTO).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
if (viewModel.isEditing()) { if (viewModel.isEditing()) {
ActivityLogger.logChange(requireContext(), "Service", "UPDATED", (int) viewModel.getServiceId()); ActivityLogger.logChange(requireContext(), "Service", "UPDATED", (int) viewModel.getServiceId());
@@ -99,6 +108,8 @@ public class ServiceDetailFragment extends Fragment {
private void deleteService() { private void deleteService() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Service", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Service", () ->
viewModel.deleteService().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteService().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
ActivityLogger.logChange(requireContext(), "Service", "DELETED", (int) viewModel.getServiceId()); ActivityLogger.logChange(requireContext(), "Service", "DELETED", (int) viewModel.getServiceId());
Toast.makeText(getContext(), "Service deleted successfully!", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Service deleted successfully!", Toast.LENGTH_SHORT).show();
@@ -118,7 +129,7 @@ public class ServiceDetailFragment extends Fragment {
long serviceId = getArguments().getLong("serviceId"); long serviceId = getArguments().getLong("serviceId");
viewModel.setServiceId(serviceId); viewModel.setServiceId(serviceId);
binding.tvMode.setText("Edit Service"); binding.tvMode.setText("Edit Service");
binding.tvServiceId.setText("ID: " + serviceId); binding.tvServiceId.setText(DateTimeUtils.formatId(serviceId));
binding.btnDeleteService.setVisibility(View.VISIBLE); binding.btnDeleteService.setVisibility(View.VISIBLE);
loadServiceData(); loadServiceData();
} else { } else {
@@ -133,6 +144,7 @@ public class ServiceDetailFragment extends Fragment {
private void loadServiceData() { private void loadServiceData() {
viewModel.loadService().observe(getViewLifecycleOwner(), resource -> { viewModel.loadService().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
ServiceDTO s = resource.data; ServiceDTO s = resource.data;
binding.etServiceName.setText(s.getServiceName()); binding.etServiceName.setText(s.getServiceName());

View File

@@ -4,13 +4,16 @@ import android.os.Bundle;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.FragmentStaffDetailBinding; import com.example.petstoremobile.databinding.FragmentStaffDetailBinding;
import com.example.petstoremobile.dtos.EmployeeDTO; import com.example.petstoremobile.dtos.EmployeeDTO;
import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.StaffDetailViewModel; import com.example.petstoremobile.viewmodels.StaffDetailViewModel;
import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.utils.Resource;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
@@ -36,14 +39,15 @@ public class StaffDetailFragment extends Fragment {
binding.btnStaffBack.setOnClickListener(v -> navigateBack()); binding.btnStaffBack.setOnClickListener(v -> navigateBack());
binding.btnSaveStaff.setOnClickListener(v -> save()); binding.btnSaveStaff.setOnClickListener(v -> save());
binding.btnDeleteStaff.setOnClickListener(v -> confirmDelete()); binding.btnDeleteStaff.setOnClickListener(v -> confirmDelete());
UIUtils.formatPhoneInput(binding.etStaffPhone);
return binding.getRoot(); return binding.getRoot();
} }
private void setupSpinners() { private void setupSpinners() {
binding.spinnerStaffRole.setAdapter(new ArrayAdapter<>(requireContext(), SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffRole, ROLES);
android.R.layout.simple_spinner_item, ROLES)); SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffStatus, STATUSES);
binding.spinnerStaffStatus.setAdapter(new ArrayAdapter<>(requireContext(),
android.R.layout.simple_spinner_item, STATUSES));
} }
private void handleArguments() { private void handleArguments() {
@@ -62,16 +66,8 @@ public class StaffDetailFragment extends Fragment {
binding.etStaffPhone.setText(a.getString("phone", "")); binding.etStaffPhone.setText(a.getString("phone", ""));
binding.btnDeleteStaff.setVisibility(View.VISIBLE); binding.btnDeleteStaff.setVisibility(View.VISIBLE);
String role = a.getString("role", "STAFF"); SpinnerUtils.setSelectionByValue(binding.spinnerStaffRole, a.getString("role", "STAFF"));
for (int i = 0; i < ROLES.length; i++) { binding.spinnerStaffStatus.setSelection(a.getBoolean("active", true) ? 0 : 1);
if (ROLES[i].equals(role)) {
binding.spinnerStaffRole.setSelection(i);
break;
}
}
boolean active = a.getBoolean("active", true);
binding.spinnerStaffStatus.setSelection(active ? 0 : 1);
} else { } else {
viewModel.setEmployeeId(-1, false); viewModel.setEmployeeId(-1, false);
@@ -81,29 +77,39 @@ public class StaffDetailFragment extends Fragment {
} }
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
private void save() { private void save() {
String username = binding.etStaffUsername.getText() != null ? binding.etStaffUsername.getText().toString().trim() : ""; if (!InputValidator.isNotEmpty(binding.etStaffUsername, "Username")) return;
String password = binding.etStaffPassword.getText() != null ? binding.etStaffPassword.getText().toString().trim() : "";
String firstName = binding.etStaffFirstName.getText() != null ? binding.etStaffFirstName.getText().toString().trim() : ""; if (!viewModel.isEditing()) {
String lastName = binding.etStaffLastName.getText() != null ? binding.etStaffLastName.getText().toString().trim() : ""; if (!InputValidator.isNotEmpty(binding.etStaffPassword, "Password")) return;
String email = binding.etStaffEmail.getText() != null ? binding.etStaffEmail.getText().toString().trim() : ""; String pass = binding.etStaffPassword.getText().toString();
String phone = binding.etStaffPhone.getText() != null ? binding.etStaffPhone.getText().toString().trim() : ""; if (pass.length() < 6) {
binding.etStaffPassword.setError("At least 6 characters");
binding.etStaffPassword.requestFocus();
return;
}
}
if (!InputValidator.isNotEmpty(binding.etStaffFirstName, "First Name")) return;
if (!InputValidator.isNotEmpty(binding.etStaffLastName, "Last Name")) return;
if (!InputValidator.isValidEmail(binding.etStaffEmail)) return;
if (!InputValidator.isValidPhone(binding.etStaffPhone)) 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 role = ROLES[binding.spinnerStaffRole.getSelectedItemPosition()];
boolean active = binding.spinnerStaffStatus.getSelectedItemPosition() == 0; boolean active = binding.spinnerStaffStatus.getSelectedItemPosition() == 0;
if (username.isEmpty()) { binding.etStaffUsername.setError("Required"); return; }
if (!viewModel.isEditing() && password.isEmpty()) {
binding.etStaffPassword.setError("Required for new account"); return;
}
if (!viewModel.isEditing() && password.length() < 6) {
binding.etStaffPassword.setError("At least 6 characters"); return;
}
if (firstName.isEmpty()) { binding.etStaffFirstName.setError("Required"); return; }
if (lastName.isEmpty()) { binding.etStaffLastName.setError("Required"); return; }
if (email.isEmpty()) { binding.etStaffEmail.setError("Required"); return; }
if (phone.isEmpty()) { binding.etStaffPhone.setError("Required"); return; }
EmployeeDTO dto = new EmployeeDTO( EmployeeDTO dto = new EmployeeDTO(
username, username,
password.isEmpty() ? null : password, password.isEmpty() ? null : password,
@@ -117,6 +123,7 @@ public class StaffDetailFragment extends Fragment {
viewModel.saveEmployee(dto).observe(getViewLifecycleOwner(), resource -> { viewModel.saveEmployee(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource != null) { if (resource != null) {
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
Toast.makeText(getContext(), viewModel.isEditing() ? "Updated successfully" : "Staff account created", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), viewModel.isEditing() ? "Updated successfully" : "Staff account created", Toast.LENGTH_SHORT).show();
navigateBack(); navigateBack();
@@ -128,21 +135,18 @@ public class StaffDetailFragment extends Fragment {
} }
private void confirmDelete() { private void confirmDelete() {
new AlertDialog.Builder(requireContext()) DialogUtils.showDeleteConfirmDialog(requireContext(), "Staff Account", () ->
.setTitle("Delete Staff Account?") viewModel.deleteEmployee().observe(getViewLifecycleOwner(), resource -> {
.setMessage("This will permanently delete this staff account.") if (resource != null) {
.setPositiveButton("Yes", (d, w) -> setLoading(resource.status == Resource.Status.LOADING);
viewModel.deleteEmployee().observe(getViewLifecycleOwner(), resource -> { if (resource.status == Resource.Status.SUCCESS) {
if (resource != null) { navigateBack();
if (resource.status == Resource.Status.SUCCESS) { } else if (resource.status == Resource.Status.ERROR) {
navigateBack(); Toast.makeText(getContext(), "Delete failed: " + resource.message,
} else if (resource.status == Resource.Status.ERROR) { Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), "Delete failed: " + resource.message, }
Toast.LENGTH_SHORT).show(); }
} }));
}
}))
.setNegativeButton("No", null).show();
} }
private void navigateBack() { private void navigateBack() {

View File

@@ -58,6 +58,12 @@ public class SupplierDetailFragment extends Fragment {
binding.btnDeleteSupplier.setOnClickListener(v -> deleteSupplier()); binding.btnDeleteSupplier.setOnClickListener(v -> deleteSupplier());
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -85,6 +91,8 @@ public class SupplierDetailFragment extends Fragment {
supplierDTO.setSupPhone(phone); supplierDTO.setSupPhone(phone);
viewModel.saveSupplier(supplierDTO).observe(getViewLifecycleOwner(), resource -> { viewModel.saveSupplier(supplierDTO).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
if (viewModel.isEditing()) { if (viewModel.isEditing()) {
ActivityLogger.logChange(requireContext(), "Supplier", "UPDATED", (int) viewModel.getSupId()); ActivityLogger.logChange(requireContext(), "Supplier", "UPDATED", (int) viewModel.getSupId());
@@ -103,6 +111,8 @@ public class SupplierDetailFragment extends Fragment {
private void deleteSupplier() { private void deleteSupplier() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Supplier", () -> DialogUtils.showDeleteConfirmDialog(requireContext(), "Supplier", () ->
viewModel.deleteSupplier().observe(getViewLifecycleOwner(), resource -> { viewModel.deleteSupplier().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS) { if (resource.status == Resource.Status.SUCCESS) {
ActivityLogger.logChange(requireContext(), "Supplier", "DELETED", (int) viewModel.getSupId()); ActivityLogger.logChange(requireContext(), "Supplier", "DELETED", (int) viewModel.getSupId());
Toast.makeText(getContext(), "Supplier deleted successfully!", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Supplier deleted successfully!", Toast.LENGTH_SHORT).show();
@@ -138,6 +148,7 @@ public class SupplierDetailFragment extends Fragment {
private void loadSupplierData() { private void loadSupplierData() {
viewModel.loadSupplier().observe(getViewLifecycleOwner(), resource -> { viewModel.loadSupplier().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
SupplierDTO s = resource.data; SupplierDTO s = resource.data;
binding.etSupCompany.setText(s.getSupCompany()); binding.etSupCompany.setText(s.getSupCompany());

View File

@@ -95,6 +95,12 @@ public class PetProfileFragment extends Fragment {
return binding.getRoot(); return binding.getRoot();
} }
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -104,6 +110,7 @@ public class PetProfileFragment extends Fragment {
private void loadPetData() { private void loadPetData() {
viewModel.getPetById(petId).observe(getViewLifecycleOwner(), resource -> { viewModel.getPetById(petId).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return; if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
PetDTO pet = resource.data; PetDTO pet = resource.data;
binding.tvPetName.setText(pet.getPetName()); binding.tvPetName.setText(pet.getPetName());
@@ -172,13 +179,13 @@ public class PetProfileFragment extends Fragment {
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile); MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
viewModel.uploadPetImage(petId, body).observe(getViewLifecycleOwner(), resource -> { viewModel.uploadPetImage(petId, body).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status != Resource.Status.LOADING) { if (resource == null) return;
if (resource.status == Resource.Status.SUCCESS) { setLoading(resource.status == Resource.Status.LOADING);
Toast.makeText(getContext(), "Pet photo updated successfully", Toast.LENGTH_SHORT).show(); if (resource.status == Resource.Status.SUCCESS) {
loadPetImage((int) petId); Toast.makeText(getContext(), "Pet photo updated successfully", Toast.LENGTH_SHORT).show();
} else { loadPetImage((int) petId);
Toast.makeText(getContext(), "Upload failed: " + resource.message, Toast.LENGTH_SHORT).show(); } else if (resource.status == Resource.Status.ERROR) {
} Toast.makeText(getContext(), "Upload failed: " + resource.message, Toast.LENGTH_SHORT).show();
} }
}); });
} catch (Exception e) { } catch (Exception e) {
@@ -188,14 +195,14 @@ public class PetProfileFragment extends Fragment {
private void deletePetImage() { private void deletePetImage() {
viewModel.deletePetImage(petId).observe(getViewLifecycleOwner(), resource -> { viewModel.deletePetImage(petId).observe(getViewLifecycleOwner(), resource -> {
if (resource != null && resource.status != Resource.Status.LOADING) { if (resource == null) return;
if (resource.status == Resource.Status.SUCCESS) { setLoading(resource.status == Resource.Status.LOADING);
Toast.makeText(getContext(), "Pet photo removed", Toast.LENGTH_SHORT).show(); if (resource.status == Resource.Status.SUCCESS) {
hasImage = false; Toast.makeText(getContext(), "Pet photo removed", Toast.LENGTH_SHORT).show();
binding.imgPet.setImageResource(R.drawable.placeholder); hasImage = false;
} else { binding.imgPet.setImageResource(R.drawable.placeholder);
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show(); } else if (resource.status == Resource.Status.ERROR) {
} Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
} }
}); });
} }

View File

@@ -61,12 +61,15 @@ public class ChatListViewModel extends ViewModel {
} }
public void loadCustomers() { public void loadCustomers() {
isLoading.setValue(true);
customerRepository.getAllCustomers(0, 100).observeForever(resource -> { customerRepository.getAllCustomers(0, 100).observeForever(resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
for (CustomerDTO c : resource.data.getContent()) { for (CustomerDTO c : resource.data.getContent()) {
customerNames.put(c.getCustomerId(), c.getFullName()); customerNames.put(c.getCustomerId(), c.getFullName());
} }
loadConversations(); loadConversations();
} else if (resource != null && resource.status == Resource.Status.ERROR) {
isLoading.setValue(false);
} }
}); });
} }
@@ -96,6 +99,7 @@ public class ChatListViewModel extends ViewModel {
} }
public void loadMessageHistory(Long conversationId) { public void loadMessageHistory(Long conversationId) {
isLoading.setValue(true);
chatRepository.getMessages(conversationId).observeForever(resource -> { chatRepository.getMessages(conversationId).observeForever(resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
List<Message> messages = new ArrayList<>(); List<Message> messages = new ArrayList<>();
@@ -103,6 +107,9 @@ public class ChatListViewModel extends ViewModel {
messages.add(dtoToModel(dto)); messages.add(dtoToModel(dto));
} }
messageList.setValue(messages); messageList.setValue(messages);
isLoading.setValue(false);
} else if (resource != null && resource.status == Resource.Status.ERROR) {
isLoading.setValue(false);
} }
}); });
} }

View File

@@ -27,6 +27,7 @@ public class PetDetailViewModel extends ViewModel {
private final MutableLiveData<PetDTO> petState = new MutableLiveData<>(); private final MutableLiveData<PetDTO> petState = new MutableLiveData<>();
private final MutableLiveData<List<DropdownDTO>> customerList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData<List<DropdownDTO>> customerList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<DropdownDTO>> storeList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData<List<DropdownDTO>> storeList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
private long petId = -1; private long petId = -1;
private boolean isEditing = false; private boolean isEditing = false;
@@ -91,4 +92,12 @@ public class PetDetailViewModel extends ViewModel {
public LiveData<List<DropdownDTO>> getStoreList() { public LiveData<List<DropdownDTO>> getStoreList() {
return storeList; return storeList;
} }
public LiveData<Boolean> getIsLoading() {
return isLoading;
}
public void setLoading(boolean loading) {
isLoading.setValue(loading);
}
} }

View File

@@ -35,6 +35,7 @@ public class SaleDetailViewModel extends ViewModel {
private final MutableLiveData<List<DropdownDTO>> customerList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData<List<DropdownDTO>> customerList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<ProductDTO>> productList = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData<List<ProductDTO>> productList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<SaleDTO.SaleItemDTO>> cartItems = new MutableLiveData<>(new ArrayList<>()); private final MutableLiveData<List<SaleDTO.SaleItemDTO>> cartItems = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
@Inject @Inject
public SaleDetailViewModel(SaleRepository saleRepository, StoreRepository storeRepository, public SaleDetailViewModel(SaleRepository saleRepository, StoreRepository storeRepository,
@@ -106,4 +107,12 @@ public class SaleDetailViewModel extends ViewModel {
} }
return total; return total;
} }
public LiveData<Boolean> getIsLoading() {
return isLoading;
}
public void setLoading(boolean loading) {
isLoading.setValue(loading);
}
} }

View File

@@ -1,214 +1,228 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvAdoptionMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Adoption"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteAdoption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvAdoptionMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Adoption"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteAdoption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvAdoptionId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<!-- Customer -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Customer"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAdoptionCustomer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<!-- Pet --> <TextView
<TextView android:id="@+id/tvAdoptionId"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Pet" android:text="ID: #0"
android:textColor="@color/text_dark" android:textColor="@color/text_light"
android:textSize="12sp" android:textSize="11sp"
android:layout_marginBottom="4dp"/> android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<Spinner <!-- Customer -->
android:id="@+id/spinnerAdoptionPet" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:text="Customer"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Employee --> <Spinner
<TextView android:id="@+id/spinnerAdoptionCustomer"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Handled By (Staff)" android:layout_marginBottom="16dp"/>
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner <!-- Pet -->
android:id="@+id/spinnerAdoptionEmployee" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:text="Pet"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<TextView <Spinner
android:layout_width="wrap_content" android:id="@+id/spinnerAdoptionPet"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Source Store" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:layout_marginBottom="16dp"/>
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner <!-- Employee -->
android:id="@+id/spinnerAdoptionStore" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:text="Handled By (Staff)"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Adoption Date --> <Spinner
<TextView android:id="@+id/spinnerAdoptionEmployee"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Adoption Date" android:layout_marginBottom="16dp"/>
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText <TextView
android:id="@+id/etAdoptionDate" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Source Store"
android:hint="Tap to select date" android:textColor="@color/text_dark"
android:inputType="none" android:textSize="12sp"
android:focusable="false" android:layout_marginBottom="4dp"/>
android:clickable="true"
android:drawableEnd="@android:drawable/ic_menu_my_calendar"
android:layout_marginBottom="16dp"/>
<!-- Adoption Fee --> <Spinner
<TextView android:id="@+id/spinnerAdoptionStore"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Adoption Fee" android:layout_marginBottom="16dp"/>
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText <!-- Adoption Date -->
android:id="@+id/etAdoptionFee" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="0.00" android:text="Adoption Date"
android:inputType="numberDecimal" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Status --> <EditText
<TextView android:id="@+id/etAdoptionDate"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Status" android:hint="Tap to select date"
android:textColor="@color/text_dark" android:inputType="none"
android:textSize="12sp" android:focusable="false"
android:layout_marginBottom="4dp"/> android:clickable="true"
android:drawableEnd="@android:drawable/ic_menu_my_calendar"
android:layout_marginBottom="16dp"/>
<Spinner <!-- Adoption Fee -->
android:id="@+id/spinnerAdoptionStatus" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/> android:text="Adoption Fee"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etAdoptionFee"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="0.00"
android:inputType="numberDecimal"
android:layout_marginBottom="16dp"/>
<!-- Status -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAdoptionStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnAdoptionBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveAdoption"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnAdoptionBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveAdoption"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,318 +1,332 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<ImageButton
android:id="@+id/btnHamburgerAnalytics"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/baseline_menu_36"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Open menu"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Analytics"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnRefreshAnalytics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="16dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<!-- Summary Cards Row 1 --> <ImageButton
<LinearLayout android:id="@+id/btnHamburgerAnalytics"
android:layout_width="match_parent" android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/baseline_menu_36"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Open menu"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_weight="1"
android:layout_marginBottom="8dp"> android:text="Analytics"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<LinearLayout <Button
android:layout_width="0dp" android:id="@+id/btnRefreshAnalytics"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Revenue"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalRevenue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"
android:textColor="@color/accent_coral"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Transactions"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalTransactions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
<!-- Summary Cards Row 2 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:text="Refresh"
android:layout_marginBottom="16dp"> android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Avg Transaction"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvAvgTransaction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items Sold"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalItems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
<!-- Top Products by Revenue -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Products by Revenue"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llTopRevenue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Top Products by Quantity -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Products by Quantity"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llTopQuantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Payment Methods -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Methods"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llPaymentMethods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Employee Performance -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Employee Performance"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llEmployeePerformance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Daily Revenue -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Daily Revenue (Last 7 Days)"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llDailyRevenue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> <ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Summary Cards Row 1 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Revenue"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalRevenue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"
android:textColor="@color/accent_coral"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Transactions"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalTransactions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
<!-- Summary Cards Row 2 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Avg Transaction"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvAvgTransaction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items Sold"
android:textColor="@color/text_light"
android:textSize="11sp"/>
<TextView
android:id="@+id/tvTotalItems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/primary_dark"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
<!-- Top Products by Revenue -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Products by Revenue"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llTopRevenue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Top Products by Quantity -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Products by Quantity"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llTopQuantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Payment Methods -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Methods"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llPaymentMethods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Employee Performance -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Employee Performance"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llEmployeePerformance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Daily Revenue -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Daily Revenue (Last 7 Days)"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llDailyRevenue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,268 +1,282 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvApptMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Appointment"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteAppointment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvApptMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Appointment"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteAppointment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:id="@+id/tvAppointmentId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<!-- Customer -->
<TextView
android:id="@+id/tvLabelCustomer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Customer"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerCustomer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Pet -->
<TextView
android:id="@+id/tvLabelPet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pet"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerPet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Store -->
<TextView
android:id="@+id/tvLabelStore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Staff -->
<TextView
android:id="@+id/tvLabelStaff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Staff"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStaff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Service -->
<TextView
android:id="@+id/tvLabelService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Service"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Appointment Date -->
<TextView
android:id="@+id/tvLabelDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Appointment Date"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etAppointmentDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Tap to select date"
android:inputType="none"
android:focusable="false"
android:clickable="true"
android:drawableEnd="@android:drawable/ic_menu_my_calendar"
android:layout_marginBottom="16dp"/>
<!-- Appointment Time-->
<TextView
android:id="@+id/tvLabelTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Appointment Time"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="vertical"
android:layout_marginBottom="16dp" android:background="@drawable/rounded_card"
android:gravity="center_vertical"> android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <TextView
android:id="@+id/tvAppointmentId"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hour:" android:text="ID: #0"
android:textColor="@color/text_dark" android:textColor="@color/text_light"
android:textSize="13sp" android:textSize="11sp"
android:layout_marginEnd="6dp"/> android:textStyle="italic"
android:layout_gravity="end"
<Spinner android:layout_marginBottom="8dp"/>
android:id="@+id/spinnerHour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="16dp"/>
<!-- Customer -->
<TextView <TextView
android:id="@+id/tvLabelCustomer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Min:" android:text="Customer"
android:textColor="@color/text_dark" android:textColor="@color/text_dark"
android:textSize="13sp" android:textSize="12sp"
android:layout_marginEnd="6dp"/> android:layout_marginBottom="4dp"/>
<Spinner <Spinner
android:id="@+id/spinnerMinute" android:id="@+id/spinnerCustomer"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"/> android:layout_marginBottom="16dp"/>
<!-- Pet -->
<TextView
android:id="@+id/tvLabelPet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pet"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerPet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Store -->
<TextView
android:id="@+id/tvLabelStore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Staff -->
<TextView
android:id="@+id/tvLabelStaff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Staff"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStaff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Service -->
<TextView
android:id="@+id/tvLabelService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Service"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Appointment Date -->
<TextView
android:id="@+id/tvLabelDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Appointment Date"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etAppointmentDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Tap to select date"
android:inputType="none"
android:focusable="false"
android:clickable="true"
android:drawableEnd="@android:drawable/ic_menu_my_calendar"
android:layout_marginBottom="16dp"/>
<!-- Appointment Time-->
<TextView
android:id="@+id/tvLabelTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Appointment Time"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hour:"
android:textColor="@color/text_dark"
android:textSize="13sp"
android:layout_marginEnd="6dp"/>
<Spinner
android:id="@+id/spinnerHour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Min:"
android:textColor="@color/text_dark"
android:textSize="13sp"
android:layout_marginEnd="6dp"/>
<Spinner
android:id="@+id/spinnerMinute"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
<!-- Status -->
<TextView
android:id="@+id/tvLabelStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAppointmentStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</LinearLayout> </LinearLayout>
<!-- Status -->
<TextView
android:id="@+id/tvLabelStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAppointmentStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnApptBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveAppointment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnApptBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveAppointment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -6,125 +6,139 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background_grey"> android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical">
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<ImageButton <LinearLayout
android:id="@+id/btnHamburger" android:layout_width="match_parent"
android:layout_width="48dp" android:layout_height="56dp"
android:layout_height="48dp" android:background="@color/primary_dark"
android:src="@drawable/baseline_menu_36" android:gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless" android:paddingStart="16dp"
android:contentDescription="Open menu"/> android:paddingEnd="16dp">
<TextView <ImageButton
android:id="@+id/tvChatTitle" android:id="@+id/btnHamburger"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/baseline_menu_36"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Open menu"/>
<TextView
android:id="@+id/tvChatTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Customer Chat"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
android:paddingStart="8dp"
android:paddingEnd="8dp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvMessages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="8dp"
android:clipToPadding="false" />
<LinearLayout
android:id="@+id/layoutAttachmentPreview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Customer Chat" android:orientation="horizontal"
android:textColor="@color/white" android:padding="8dp"
android:textSize="20sp" android:background="#E0E0E0"
android:textStyle="bold" android:gravity="center_vertical"
android:paddingStart="8dp" android:visibility="gone">
android:paddingEnd="8dp"/>
<ImageView
android:id="@+id/ivPreview"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerCrop"
android:layout_marginEnd="8dp"
android:visibility="gone"/>
<TextView
android:id="@+id/tvPreviewName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="middle"
android:singleLine="true"
android:textColor="@color/text_dark"/>
<ImageButton
android:id="@+id/btnRemoveAttachment"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Remove attachment"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center_vertical"
android:background="@color/white">
<ImageButton
android:id="@+id/btnAttach"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@android:drawable/ic_menu_add"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Attach file"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/etMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type a message..."
android:inputType="text"
android:imeOptions="actionSend"
android:layout_marginEnd="8dp"
android:textColor="@color/text_dark"/>
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <ProgressBar
android:id="@+id/rvMessages" android:id="@+id/progressBar"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="8dp"
android:clipToPadding="false" />
<LinearLayout
android:id="@+id/layoutAttachmentPreview"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_centerInParent="true"
android:padding="8dp" android:visibility="gone"
android:background="#E0E0E0" android:indeterminateTint="@color/accent_coral"/>
android:gravity="center_vertical"
android:visibility="gone">
<ImageView </RelativeLayout>
android:id="@+id/ivPreview"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerCrop"
android:layout_marginEnd="8dp"
android:visibility="gone"/>
<TextView
android:id="@+id/tvPreviewName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="middle"
android:singleLine="true"
android:textColor="@color/text_dark"/>
<ImageButton
android:id="@+id/btnRemoveAttachment"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Remove attachment"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center_vertical"
android:background="@color/white">
<ImageButton
android:id="@+id/btnAttach"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@android:drawable/ic_menu_add"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Attach file"
android:layout_marginEnd="4dp"/>
<EditText
android:id="@+id/etMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type a message..."
android:inputType="text"
android:imeOptions="actionSend"
android:layout_marginEnd="8dp"
android:textColor="@color/text_dark"/>
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
</LinearLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/chatListDrawer" android:id="@+id/chatListDrawer"

View File

@@ -1,155 +1,169 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<!-- Header -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvInventoryMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Inventory"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteInventory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"
android:visibility="gone"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- Header -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvInventoryMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Inventory"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteInventory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"
android:visibility="gone"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp">
<!-- Inventory ID — edit mode only --> <LinearLayout
<TextView
android:id="@+id/tvInventoryId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Inventory ID: —"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="12dp"
android:visibility="gone"/>
<!-- Store selection label -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Store Spinner -->
<Spinner
android:id="@+id/spinnerInventoryStore"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp">
<!-- Product selection label --> <!-- Inventory ID — edit mode only -->
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvInventoryId"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Product" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:text="Inventory ID: —"
android:textSize="12sp" android:textColor="@color/text_light"
android:layout_marginBottom="4dp"/> android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="12dp"
android:visibility="gone"/>
<!-- Product Spinner --> <!-- Store selection label -->
<Spinner <TextView
android:id="@+id/spinnerInventoryProduct" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Store"
android:layout_marginBottom="16dp"/> android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Quantity label --> <!-- Store Spinner -->
<TextView <Spinner
android:layout_width="wrap_content" android:id="@+id/spinnerInventoryStore"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Quantity" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:layout_marginBottom="16dp"/>
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Quantity input --> <!-- Product selection label -->
<EditText <TextView
android:id="@+id/etQuantity" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Product"
android:hint="Enter quantity" android:textColor="@color/text_dark"
android:inputType="number"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Product Spinner -->
<Spinner
android:id="@+id/spinnerInventoryProduct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Quantity label -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quantity"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Quantity input -->
<EditText
android:id="@+id/etQuantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter quantity"
android:inputType="number"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<!-- Bottom buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnInventoryBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveInventory"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<!-- Bottom buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnInventoryBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveInventory"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,229 +1,244 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout 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_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Pet"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnDeletePet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Pet"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnDeletePet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvPetId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pet ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pet Name"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etPetName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter pet name" android:orientation="vertical"
android:inputType="text" android:background="@drawable/rounded_card"
android:layout_marginBottom="16dp" android:padding="16dp"
android:textColor="@color/text_dark"/> android:layout_marginBottom="16dp">
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvPetId"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Species" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:text="Pet ID: #0"
android:textSize="12sp" android:textColor="@color/text_light"
android:layout_marginBottom="4dp"/> android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<EditText <TextView
android:id="@+id/etPetSpecies" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Pet Name"
android:hint="e.g. Dog, Cat, Bird" android:textColor="@color/text_dark"
android:inputType="text" android:textSize="12sp"
android:layout_marginBottom="16dp" android:layout_marginBottom="4dp"/>
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etPetName"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Breed" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter pet name"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<EditText <TextView
android:id="@+id/etPetBreed" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Species"
android:hint="Enter breed" android:textColor="@color/text_dark"
android:inputType="text" android:textSize="12sp"
android:layout_marginBottom="16dp" android:layout_marginBottom="4dp"/>
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etPetSpecies"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Age" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="e.g. Dog, Cat, Bird"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<EditText <TextView
android:id="@+id/etPetAge" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Breed"
android:hint="Enter age" android:textColor="@color/text_dark"
android:inputType="number" android:textSize="12sp"
android:layout_marginBottom="16dp" android:layout_marginBottom="4dp"/>
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etPetBreed"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Price" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter breed"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<EditText <TextView
android:id="@+id/etPetPrice" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Age"
android:hint="Enter price" android:textColor="@color/text_dark"
android:inputType="numberDecimal" android:textSize="12sp"
android:layout_marginBottom="16dp" android:layout_marginBottom="4dp"/>
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etPetAge"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Status" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter age"
android:textSize="12sp" android:inputType="number"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<Spinner <TextView
android:id="@+id/spinnerPetStatus" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Price"
android:layout_marginBottom="16dp"/> android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etPetPrice"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Owner" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter price"
android:textSize="12sp" android:inputType="numberDecimal"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<Spinner <TextView
android:id="@+id/spinnerCustomer" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Status"
android:layout_marginBottom="16dp"/> android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<TextView <Spinner
android:layout_width="wrap_content" android:id="@+id/spinnerPetStatus"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Store" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:layout_marginBottom="16dp"/>
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner <TextView
android:id="@+id/spinnerStore" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content"/> android:text="Owner"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerCustomer"
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="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSavePet"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:backgroundTint="@color/accent_coral"
android:text="Save"
android:textColor="@color/white" />
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSavePet"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:backgroundTint="@color/accent_coral"
android:text="Save"
android:textColor="@color/white" />
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,306 +1,320 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" android:orientation="vertical"
android:background="@color/primary_dark"> android:background="@color/background_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Pet Profile"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnEditPet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center"> android:background="@color/primary_dark">
<ImageView <LinearLayout
android:id="@+id/imgPet" android:layout_width="match_parent"
android:layout_width="146dp" android:layout_height="56dp"
android:layout_height="140dp" android:orientation="horizontal"
android:layout_marginBottom="12dp" android:gravity="center_vertical"
android:background="@drawable/circle_image" android:paddingStart="16dp"
android:clipToOutline="true" android:paddingEnd="16dp">
android:scaleType="centerCrop"
android:src="@drawable/placeholder" />
<Button <TextView
android:id="@+id/btnChangePhoto" android:layout_width="0dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1"
android:text="Change Photo" android:text="Pet Profile"
style="@style/Widget.Material3.Button.TextButton" android:textColor="@color/white"
android:textColor="@color/text_light" android:textSize="20sp"
android:layout_marginBottom="8dp"/> android:textStyle="bold"/>
<TextView <Button
android:id="@+id/tvPetName" android:id="@+id/btnEditPet"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="NAME" android:text="Edit"
android:textColor="@color/white" android:backgroundTint="@color/accent_coral"
android:textSize="26sp" android:textColor="@color/white"/>
android:textStyle="bold"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/imgPet"
android:layout_width="146dp"
android:layout_height="140dp"
android:layout_marginBottom="12dp"
android:background="@drawable/circle_image"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/placeholder" />
<Button
android:id="@+id/btnChangePhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Photo"
style="@style/Widget.Material3.Button.TextButton"
android:textColor="@color/text_light"
android:layout_marginBottom="8dp"/>
<TextView
android:id="@+id/tvPetName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NAME"
android:textColor="@color/white"
android:textSize="26sp"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> <ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ScrollView <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="wrap_content"
android:layout_weight="1"> android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginEnd="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SPECIES"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetSpecies"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dog"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BREED"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetBreed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Labrador"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginEnd="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AGE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 yr(s)"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PRICE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$500.00"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/accent_coral"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/layoutPetOwner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginTop="16dp"
android:padding="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OWNER"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetOwner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Owner"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/layoutPetStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginTop="16dp"
android:padding="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STORE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetStore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Store"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal"
android:padding="16dp"> android:padding="16dp">
<LinearLayout <Button
android:layout_width="match_parent" android:id="@+id/btnBack"
android:layout_height="120dp"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginEnd="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SPECIES"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetSpecies"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dog"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BREED"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetBreed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Labrador"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginEnd="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AGE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 yr(s)"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginStart="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PRICE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$500.00"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/accent_coral"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/layoutPetOwner"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:text="Back"
android:gravity="center" android:backgroundTint="@color/primary_medium"
android:background="@color/white" android:textColor="@color/white"/>
android:layout_marginTop="16dp"
android:padding="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OWNER"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetOwner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Owner"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/layoutPetStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:background="@color/white"
android:layout_marginTop="16dp"
android:padding="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STORE"
android:textSize="11sp"
android:textColor="#888888"
android:textAllCaps="true"
android:layout_marginBottom="4dp"/>
<TextView
android:id="@+id/tvPetStore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Store"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_dark"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,195 +1,209 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvProductMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Product"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteProduct"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvProductMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Product"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteProduct"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvProductId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<!-- Product Image -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Image"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dp" android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"> android:layout_marginBottom="16dp">
<ImageView <TextView
android:id="@+id/ivProductImage" android:id="@+id/tvProductId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<!-- Product Image -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Image"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="200dp"
android:scaleType="centerCrop" android:layout_marginBottom="16dp">
android:src="@drawable/placeholder2"
android:background="@color/text_light"
android:clickable="true"
android:focusable="true"/>
</FrameLayout> <ImageView
android:id="@+id/ivProductImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/placeholder2"
android:background="@color/text_light"
android:clickable="true"
android:focusable="true"/>
<!-- Product Name --> </FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product Name"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText <!-- Product Name -->
android:id="@+id/etProductName" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter product name" android:text="Product Name"
android:inputType="text" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Category --> <EditText
<TextView android:id="@+id/etProductName"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Category" android:hint="Enter product name"
android:textColor="@color/text_dark" android:inputType="text"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<Spinner <!-- Category -->
android:id="@+id/spinnerProductCategory" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:text="Category"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Description --> <Spinner
<TextView android:id="@+id/spinnerProductCategory"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Description" android:layout_marginBottom="16dp"/>
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText <!-- Description -->
android:id="@+id/etProductDesc" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter description" android:text="Description"
android:inputType="textMultiLine" android:textColor="@color/text_dark"
android:minLines="2" android:textSize="12sp"
android:layout_marginBottom="16dp"/> android:layout_marginBottom="4dp"/>
<!-- Price --> <EditText
<TextView android:id="@+id/etProductDesc"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Price" android:hint="Enter description"
android:textColor="@color/text_dark" android:inputType="textMultiLine"
android:textSize="12sp" android:minLines="2"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"/>
<EditText <!-- Price -->
android:id="@+id/etProductPrice" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="0.00" android:text="Price"
android:inputType="numberDecimal" android:textColor="@color/text_dark"
android:layout_marginBottom="8dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etProductPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="0.00"
android:inputType="numberDecimal"
android:layout_marginBottom="8dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnProductBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveProduct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnProductBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveProduct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,138 +1,152 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvPSMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Product Supplier"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeletePS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvPSMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Product Supplier"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeletePS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<!-- Product --> <LinearLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Product"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerPSProduct"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<!-- Supplier --> <!-- Product -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Supplier" android:text="Product"
android:textColor="@color/text_dark" android:textColor="@color/text_dark"
android:textSize="12sp" android:textSize="12sp"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="4dp"/>
<Spinner <Spinner
android:id="@+id/spinnerPSSupplier" android:id="@+id/spinnerPSProduct"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:layout_marginBottom="16dp"/>
<!-- Cost --> <!-- Supplier -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Cost" android:text="Supplier"
android:textColor="@color/text_dark" android:textColor="@color/text_dark"
android:textSize="12sp" android:textSize="12sp"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="4dp"/>
<EditText <Spinner
android:id="@+id/etPSCost" android:id="@+id/spinnerPSSupplier"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="0.00" android:layout_marginBottom="16dp"/>
android:inputType="numberDecimal"
android:layout_marginBottom="8dp"/> <!-- Cost -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cost"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etPSCost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="0.00"
android:inputType="numberDecimal"
android:layout_marginBottom="8dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnPSBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSavePS"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnPSBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSavePS"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,200 +1,214 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:background="@color/background_grey">
<LinearLayout <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical"> android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical">
android:background="@color/primary_dark"
android:gravity="center_horizontal"
android:paddingTop="32dp"
android:paddingBottom="32dp">
<ImageView <LinearLayout
android:id="@+id/imgProfile" android:layout_width="match_parent"
android:layout_width="171dp" android:layout_height="wrap_content"
android:layout_height="166dp" android:orientation="vertical"
android:layout_marginBottom="8dp" android:background="@color/primary_dark"
android:background="@drawable/circle_image" android:gravity="center_horizontal"
android:clipToOutline="true" android:paddingTop="32dp"
android:scaleType="centerCrop" android:paddingBottom="32dp">
android:src="@drawable/placeholder" />
<ImageView
android:id="@+id/imgProfile"
android:layout_width="171dp"
android:layout_height="166dp"
android:layout_marginBottom="8dp"
android:background="@drawable/circle_image"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/placeholder" />
<Button
android:id="@+id/btnChangePhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Photo"
style="@style/Widget.Material3.Button.TextButton"
android:textColor="@color/text_light"/>
<TextView
android:id="@+id/tvProfileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="First Last"
android:textColor="@color/white"
android:textSize="22sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfileEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No email loaded"
android:textColor="@color/text_dark"
android:textSize="16sp" />
</LinearLayout>
<Button
android:id="@+id/btnEditEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:textColor="@color/accent_coral"
style="@style/Widget.Material3.Button.TextButton"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfilePhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No phone loaded"
android:textColor="@color/text_dark"
android:textSize="16sp" />
</LinearLayout>
<Button
android:id="@+id/btnEditPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:textColor="@color/accent_coral"
style="@style/Widget.Material3.Button.TextButton"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingTop="12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Role"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfileRole"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No role loaded"
android:textSize="16sp"
android:textColor="@color/accent_coral"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<Button <Button
android:id="@+id/btnChangePhoto" android:id="@+id/btnLogout"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Change Photo" android:layout_marginStart="16dp"
style="@style/Widget.Material3.Button.TextButton" android:layout_marginEnd="16dp"
android:textColor="@color/text_light"/> android:layout_marginBottom="24dp"
android:text="Log Out"
<TextView android:backgroundTint="@color/accent_coral"
android:id="@+id/tvProfileName" android:textColor="@color/white"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="First Last"
android:textColor="@color/white"
android:textSize="22sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<LinearLayout </ScrollView>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:padding="16dp">
<LinearLayout <ProgressBar
android:layout_width="match_parent" android:id="@+id/progressBar"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:orientation="horizontal" android:layout_height="wrap_content"
android:gravity="center_vertical" android:layout_gravity="center"
android:paddingBottom="12dp"> android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
<LinearLayout </FrameLayout>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfileEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No email loaded"
android:textColor="@color/text_dark"
android:textSize="16sp" />
</LinearLayout>
<Button
android:id="@+id/btnEditEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:textColor="@color/accent_coral"
style="@style/Widget.Material3.Button.TextButton"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfilePhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No phone loaded"
android:textColor="@color/text_dark"
android:textSize="16sp" />
</LinearLayout>
<Button
android:id="@+id/btnEditPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:textColor="@color/accent_coral"
style="@style/Widget.Material3.Button.TextButton"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingTop="12dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Role"
android:textSize="12sp"
android:textColor="#888888"/>
<TextView
android:id="@+id/tvProfileRole"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No role loaded"
android:textSize="16sp"
android:textColor="@color/accent_coral"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<Button
android:id="@+id/btnLogout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="24dp"
android:text="Log Out"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
</ScrollView>

View File

@@ -1,140 +1,154 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Purchase Order Details"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Purchase Order Details"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvPODetailId" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/text_light" android:orientation="vertical"
android:textSize="11sp" android:background="@drawable/rounded_card"
android:textStyle="italic" android:padding="16dp"
android:layout_gravity="end" android:layout_marginBottom="16dp">
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvPODetailId"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Supplier" android:layout_height="wrap_content"
android:textColor="@color/text_light" android:textColor="@color/text_light"
android:textSize="12sp"/> android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:id="@+id/tvPODetailSupplier" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Supplier"
android:textColor="@color/text_dark" android:textColor="@color/text_light"
android:textSize="16sp" android:textSize="12sp"/>
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvPODetailSupplier"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Store" android:layout_height="wrap_content"
android:textColor="@color/text_light" android:textColor="@color/text_dark"
android:textSize="12sp"/> android:textSize="16sp"
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:id="@+id/tvPODetailStore" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Store"
android:textColor="@color/text_dark" android:textColor="@color/text_light"
android:textSize="16sp" android:textSize="12sp"/>
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvPODetailStore"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Order Date" android:layout_height="wrap_content"
android:textColor="@color/text_light" android:textColor="@color/text_dark"
android:textSize="12sp"/> android:textSize="16sp"
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:id="@+id/tvPODetailDate" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Order Date"
android:textColor="@color/text_dark" android:textColor="@color/text_light"
android:textSize="15sp" android:textSize="12sp"/>
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvPODetailDate"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Status" android:layout_height="wrap_content"
android:textColor="@color/text_light" android:textColor="@color/text_dark"
android:textSize="12sp"/> android:textSize="15sp"
android:layout_marginBottom="16dp"/>
<TextView <TextView
android:id="@+id/tvPODetailStatus" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Status"
android:textSize="15sp" android:textColor="@color/text_light"
android:layout_marginBottom="16dp"/> android:textSize="12sp"/>
<TextView
android:id="@+id/tvPODetailStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginBottom="16dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </ScrollView>
</ScrollView> <LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnPOBack"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Back" android:background="@color/white"
android:backgroundTint="@color/primary_medium" android:padding="16dp">
android:textColor="@color/white"/>
<Button
android:id="@+id/btnPOBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,222 +1,236 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Process Refund"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="16dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<!-- Load Sale Card --> <TextView
<LinearLayout android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_weight="1"
android:background="@drawable/rounded_card" android:text="Process Refund"
android:padding="16dp" android:textColor="@color/white"
android:layout_marginBottom="16dp"> android:textSize="20sp"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load Original Sale"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<EditText
android:id="@+id/etRefundSaleId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Enter Sale ID"
android:inputType="number"
android:layout_marginEnd="8dp"/>
<Button
android:id="@+id/btnLoadSale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_light"
android:textSize="12sp"
android:layout_marginTop="8dp"
android:visibility="gone"/>
</LinearLayout>
<!-- Original Sale Items Card -->
<LinearLayout
android:id="@+id/cardOriginalItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Original Sale Items"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:id="@+id/llOriginalItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Refund Items Card -->
<LinearLayout
android:id="@+id/cardRefundItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items to Refund"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:id="@+id/llRefundItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<TextView
android:id="@+id/tvRefundTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund Total: $0.00"
android:textColor="@color/accent_coral"
android:textSize="16sp"
android:textStyle="bold"
android:layout_gravity="end"
android:layout_marginTop="12dp"/>
</LinearLayout>
<!-- Payment Method Card -->
<LinearLayout
android:id="@+id/cardPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund Payment Method"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<Spinner
android:id="@+id/spinnerRefundPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> <ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- Bottom Buttons --> <LinearLayout
<LinearLayout android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:orientation="vertical"
android:orientation="horizontal" android:padding="16dp">
android:background="@color/white"
android:padding="16dp">
<Button <!-- Load Sale Card -->
android:id="@+id/btnRefundBack" <LinearLayout
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load Original Sale"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<EditText
android:id="@+id/etRefundSaleId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Enter Sale ID"
android:inputType="number"
android:layout_marginEnd="8dp"/>
<Button
android:id="@+id/btnLoadSale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_light"
android:textSize="12sp"
android:layout_marginTop="8dp"
android:visibility="gone"/>
</LinearLayout>
<!-- Original Sale Items Card -->
<LinearLayout
android:id="@+id/cardOriginalItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Original Sale Items"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:id="@+id/llOriginalItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<!-- Refund Items Card -->
<LinearLayout
android:id="@+id/cardRefundItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items to Refund"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<LinearLayout
android:id="@+id/llRefundItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<TextView
android:id="@+id/tvRefundTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund Total: $0.00"
android:textColor="@color/accent_coral"
android:textSize="16sp"
android:textStyle="bold"
android:layout_gravity="end"
android:layout_marginTop="12dp"/>
</LinearLayout>
<!-- Payment Method Card -->
<LinearLayout
android:id="@+id/cardPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund Payment Method"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<Spinner
android:id="@+id/spinnerRefundPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<!-- Bottom Buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:orientation="horizontal"
android:layout_marginEnd="8dp" android:background="@color/white"
android:text="Back" android:padding="16dp">
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button <Button
android:id="@+id/btnProcessRefund" android:id="@+id/btnRefundBack"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginStart="8dp" android:layout_marginEnd="8dp"
android:text="Process Refund" android:text="Back"
android:backgroundTint="@color/accent_coral" android:backgroundTint="@color/primary_medium"
android:textColor="@color/white" android:textColor="@color/white"/>
android:visibility="gone"/>
<Button
android:id="@+id/btnProcessRefund"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Process Refund"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,333 +1,347 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView <LinearLayout
android:id="@+id/tvSaleMode" android:layout_width="match_parent"
android:layout_width="0dp" android:layout_height="56dp"
android:layout_height="wrap_content" android:background="@color/primary_dark"
android:layout_weight="1" android:gravity="center_vertical"
android:text="New Sale" android:paddingStart="16dp"
android:textColor="@color/white" android:paddingEnd="16dp"
android:textSize="20sp" android:orientation="horizontal">
android:textStyle="bold"/>
<Button <TextView
android:id="@+id/btnRefundSale" android:id="@+id/tvSaleMode"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Refund" android:layout_weight="1"
android:backgroundTint="@color/accent_coral" android:text="New Sale"
android:textColor="@color/white" android:textColor="@color/white"
android:visibility="gone"/> android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout> <Button
android:id="@+id/btnRefundSale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"
android:visibility="gone"/>
<ScrollView </LinearLayout>
android:layout_width="match_parent"
android:layout_height="0dp" <ScrollView
android:layout_weight="1"> android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:id="@+id/tvSaleDetailId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerSaleStore"
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="Customer (Optional)"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerSaleCustomer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Payment Method -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Method"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerPaymentMethod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<LinearLayout
android:id="@+id/llExtraInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Channel"
android:textColor="@color/text_dark"
android:textSize="12sp"/>
<TextView
android:id="@+id/tvSaleChannel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="—"
android:textSize="14sp"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Points Earned"
android:textColor="@color/text_dark"
android:textSize="12sp"/>
<TextView
android:id="@+id/tvSalePoints"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="14sp"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Items Card -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llAddItemRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<Spinner
android:id="@+id/spinnerSaleProduct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_marginEnd="8dp"/>
<EditText
android:id="@+id/etSaleQuantity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Qty"
android:inputType="number"
android:layout_marginEnd="8dp"/>
<Button
android:id="@+id/btnAddItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llSaleItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#EEEEEE"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Subtotal:"/>
<TextView
android:id="@+id/tvSaleSubtotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llCouponDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Coupon Discount:"/>
<TextView
android:id="@+id/tvSaleCouponDiscount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-$0.00"
android:textColor="@color/status_adopted"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llEmployeeDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Employee Discount:"/>
<TextView
android:id="@+id/tvSaleEmployeeDiscount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-$0.00"
android:textColor="@color/status_adopted"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleDetailTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total: $0.00"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/accent_coral"
android:layout_gravity="end"
android:layout_marginTop="12dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal"
android:padding="24dp"> android:background="@color/white"
android:padding="16dp">
<LinearLayout <Button
android:layout_width="match_parent" android:id="@+id/btnSaleBack"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_weight="1"
android:background="@drawable/rounded_card" android:layout_marginEnd="8dp"
android:padding="16dp" android:text="Back"
android:layout_marginBottom="16dp"> android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<TextView <Button
android:id="@+id/tvSaleDetailId" android:id="@+id/btnSaveSale"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerSaleStore"
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="Customer (Optional)"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerSaleCustomer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Payment Method -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Method"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerPaymentMethod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<LinearLayout
android:id="@+id/llExtraInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Channel"
android:textColor="@color/text_dark"
android:textSize="12sp"/>
<TextView
android:id="@+id/tvSaleChannel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="—"
android:textSize="14sp"
android:layout_marginTop="4dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Points Earned"
android:textColor="@color/text_dark"
android:textSize="12sp"/>
<TextView
android:id="@+id/tvSalePoints"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="14sp"
android:layout_marginTop="4dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- Items Card -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_weight="1"
android:background="@drawable/rounded_card" android:layout_marginStart="8dp"
android:padding="16dp" android:text="Save"
android:layout_marginBottom="16dp"> android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Items"
android:textColor="@color/text_dark"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:id="@+id/llAddItemRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
<Spinner
android:id="@+id/spinnerSaleProduct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_marginEnd="8dp"/>
<EditText
android:id="@+id/etSaleQuantity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Qty"
android:inputType="number"
android:layout_marginEnd="8dp"/>
<Button
android:id="@+id/btnAddItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llSaleItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#EEEEEE"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Subtotal:"/>
<TextView
android:id="@+id/tvSaleSubtotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$0.00"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llCouponDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Coupon Discount:"/>
<TextView
android:id="@+id/tvSaleCouponDiscount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-$0.00"
android:textColor="@color/status_adopted"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llEmployeeDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Employee Discount:"/>
<TextView
android:id="@+id/tvSaleEmployeeDiscount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-$0.00"
android:textColor="@color/status_adopted"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleDetailTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total: $0.00"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/accent_coral"
android:layout_gravity="end"
android:layout_marginTop="12dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnSaleBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveSale"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,171 +1,185 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Service"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnDeleteService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Service"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnDeleteService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvServiceId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Service Name"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etServiceName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter service name" android:orientation="vertical"
android:inputType="text" android:background="@drawable/rounded_card"
android:layout_marginBottom="16dp" android:padding="16dp"
android:textColor="@color/text_dark"/> android:layout_marginBottom="16dp">
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvServiceId"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Description" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:text="ID: #0"
android:textSize="12sp" android:textColor="@color/text_light"
android:layout_marginBottom="4dp"/> android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<EditText <TextView
android:id="@+id/etServiceDesc" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Service Name"
android:layout_marginBottom="16dp" android:textColor="@color/text_dark"
android:hint="Enter description" android:textSize="12sp"
android:inputType="textMultiLine" android:layout_marginBottom="4dp"/>
android:minLines="1"
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etServiceName"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Duration (minutes)" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter service name"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<EditText <TextView
android:id="@+id/etServiceDuration" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Description"
android:hint="Enter duration in minutes" android:textColor="@color/text_dark"
android:inputType="number" android:textSize="12sp"
android:layout_marginBottom="16dp" android:layout_marginBottom="4dp"/>
android:textColor="@color/text_dark"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etServiceDesc"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Price" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:layout_marginBottom="16dp"
android:textSize="12sp" android:hint="Enter description"
android:layout_marginBottom="4dp"/> android:inputType="textMultiLine"
android:minLines="1"
android:textColor="@color/text_dark"/>
<EditText <TextView
android:id="@+id/etServicePrice" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Duration (minutes)"
android:hint="Enter price" android:textColor="@color/text_dark"
android:inputType="numberDecimal" android:textSize="12sp"
android:textColor="@color/text_dark"/> android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etServiceDuration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter duration in minutes"
android:inputType="number"
android:layout_marginBottom="16dp"
android:textColor="@color/text_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Price"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etServicePrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter price"
android:inputType="numberDecimal"
android:textColor="@color/text_dark"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveService"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveService"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,233 +1,247 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvStaffMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Staff Account"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteStaff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvStaffMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Staff Account"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteStaff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvStaffId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<!-- Username -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etStaffUsername"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter username" android:orientation="vertical"
android:inputType="text" android:background="@drawable/rounded_card"
android:layout_marginBottom="16dp"/> android:padding="16dp"
android:layout_marginBottom="16dp">
<!-- Password --> <TextView
<TextView android:id="@+id/tvStaffId"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Password" android:textColor="@color/text_light"
android:textColor="@color/text_dark" android:textSize="11sp"
android:textSize="12sp" android:textStyle="italic"
android:layout_marginBottom="4dp"/> android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<EditText <!-- Username -->
android:id="@+id/etStaffPassword" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter password (leave blank to keep current)" android:text="Username"
android:inputType="textPassword" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- First Name --> <EditText
<TextView android:id="@+id/etStaffUsername"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="First Name" android:hint="Enter username"
android:textColor="@color/text_dark" android:inputType="text"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<EditText <!-- Password -->
android:id="@+id/etStaffFirstName" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter first name" android:text="Password"
android:inputType="textPersonName" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Last Name --> <EditText
<TextView android:id="@+id/etStaffPassword"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Last Name" android:hint="Enter password (leave blank to keep current)"
android:textColor="@color/text_dark" android:inputType="textPassword"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<EditText <!-- First Name -->
android:id="@+id/etStaffLastName" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter last name" android:text="First Name"
android:inputType="textPersonName" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Email --> <EditText
<TextView android:id="@+id/etStaffFirstName"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Email" android:hint="Enter first name"
android:textColor="@color/text_dark" android:inputType="textPersonName"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<EditText <!-- Last Name -->
android:id="@+id/etStaffEmail" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter email" android:text="Last Name"
android:inputType="textEmailAddress" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Phone --> <EditText
<TextView android:id="@+id/etStaffLastName"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Phone" android:hint="Enter last name"
android:textColor="@color/text_dark" android:inputType="textPersonName"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<EditText <!-- Email -->
android:id="@+id/etStaffPhone" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter phone number" android:text="Email"
android:inputType="phone" android:textColor="@color/text_dark"
android:layout_marginBottom="16dp"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Role --> <EditText
<TextView android:id="@+id/etStaffEmail"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Role" android:hint="Enter email"
android:textColor="@color/text_dark" android:inputType="textEmailAddress"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<Spinner <!-- Phone -->
android:id="@+id/spinnerStaffRole" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/> android:text="Phone"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<!-- Status --> <EditText
<TextView android:id="@+id/etStaffPhone"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Status" android:hint="Enter phone number"
android:textColor="@color/text_dark" android:inputType="phone"
android:textSize="12sp" android:layout_marginBottom="16dp"/>
android:layout_marginBottom="4dp"/>
<Spinner <!-- Role -->
android:id="@+id/spinnerStaffStatus" <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/> android:text="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"/>
<!-- Status -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerStaffStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnStaffBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveStaff"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnStaffBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveStaff"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>

View File

@@ -1,182 +1,196 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="match_parent"
android:background="@color/primary_dark" android:orientation="vertical"
android:gravity="center_vertical" android:background="@color/background_grey">
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Supplier"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteSupplier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:orientation="vertical" android:background="@color/primary_dark"
android:padding="24dp"> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Add Supplier"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
<Button
android:id="@+id/btnDeleteSupplier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:backgroundTint="@color/accent_coral"
android:text="Delete"
android:textColor="@color/white" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/rounded_card" android:padding="24dp">
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <LinearLayout
android:id="@+id/tvSupId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ID: #0"
android:textColor="@color/text_light"
android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Company Name"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etSupCompany"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Enter company name" android:orientation="vertical"
android:inputType="text" android:background="@drawable/rounded_card"
android:layout_marginBottom="16dp"/> android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvSupId"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="Contact First Name" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:text="ID: #0"
android:textSize="12sp" android:textColor="@color/text_light"
android:layout_marginBottom="4dp"/> android:textSize="11sp"
android:textStyle="italic"
android:layout_gravity="end"
android:layout_marginBottom="8dp"/>
<EditText <TextView
android:id="@+id/etSupContactFirstName" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Company Name"
android:hint="Enter first name" android:textColor="@color/text_dark"
android:inputType="text" android:textSize="12sp"
android:layout_marginBottom="16dp"/> android:layout_marginBottom="4dp"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etSupCompany"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Contact Last Name" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter company name"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"/>
<EditText <TextView
android:id="@+id/etSupContactLastName" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Contact First Name"
android:hint="Enter last name" android:textColor="@color/text_dark"
android:inputType="text" android:textSize="12sp"
android:layout_marginBottom="16dp"/> android:layout_marginBottom="4dp"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etSupContactFirstName"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Email" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter first name"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"/>
<EditText <TextView
android:id="@+id/etSupEmail" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Contact Last Name"
android:hint="Enter email" android:textColor="@color/text_dark"
android:inputType="textEmailAddress" android:textSize="12sp"
android:layout_marginBottom="16dp"/> android:layout_marginBottom="4dp"/>
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/etSupContactLastName"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Phone" android:layout_height="wrap_content"
android:textColor="@color/text_dark" android:hint="Enter last name"
android:textSize="12sp" android:inputType="text"
android:layout_marginBottom="4dp"/> android:layout_marginBottom="16dp"/>
<EditText <TextView
android:id="@+id/etSupPhone" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:text="Email"
android:hint="Enter phone number" android:textColor="@color/text_dark"
android:inputType="phone"/> android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etSupEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter email"
android:inputType="textEmailAddress"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etSupPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter phone number"
android:inputType="phone"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveSupplier"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnSaveSupplier"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Save"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout> </LinearLayout>
</LinearLayout> <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminateTint="@color/accent_coral"/>
</FrameLayout>