added Activitylogs andriod
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package com.example.petstoremobile.adapters;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.dtos.ActivityLogDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityLogAdapter extends RecyclerView.Adapter<ActivityLogAdapter.ViewHolder> {
|
||||
private final List<ActivityLogDTO> items;
|
||||
|
||||
public ActivityLogAdapter(List<ActivityLogDTO> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_activity_log, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
ActivityLogDTO log = items.get(position);
|
||||
holder.tvActivity.setText(log.getActivity());
|
||||
holder.tvUser.setText(log.getFullName() + " (" + log.getUsername() + ")");
|
||||
holder.tvMeta.setText(log.getStoreName() + " · " + log.getRole());
|
||||
String timestamp = log.getLogTimestamp();
|
||||
if (timestamp != null && timestamp.length() >= 16) {
|
||||
timestamp = timestamp.substring(0, 10) + " " + timestamp.substring(11, 16);
|
||||
}
|
||||
holder.tvTimestamp.setText(timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() { return items.size(); }
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvActivity, tvUser, tvMeta, tvTimestamp;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvActivity = itemView.findViewById(R.id.tvLogActivity);
|
||||
tvUser = itemView.findViewById(R.id.tvLogUser);
|
||||
tvMeta = itemView.findViewById(R.id.tvLogMeta);
|
||||
tvTimestamp = itemView.findViewById(R.id.tvLogTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.petstoremobile.api;
|
||||
|
||||
import com.example.petstoremobile.dtos.ActivityLogDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
|
||||
public interface ActivityLogApi {
|
||||
|
||||
@GET("api/v1/activity-logs")
|
||||
Call<List<ActivityLogDTO>> getActivityLogs();
|
||||
}
|
||||
@@ -197,4 +197,10 @@ public class NetworkModule {
|
||||
public static CouponApi provideCouponApi(Retrofit retrofit) {
|
||||
return retrofit.create(CouponApi.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public static ActivityLogApi provideActivityLogApi(Retrofit retrofit) {
|
||||
return retrofit.create(ActivityLogApi.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
public class ActivityLogDTO {
|
||||
private Long logId;
|
||||
private String activity;
|
||||
private String fullName;
|
||||
private String fullNameSnapshot;
|
||||
private String logTimestamp;
|
||||
private String role;
|
||||
private String roleSnapshot;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
private String storeNameSnapshot;
|
||||
private Long userId;
|
||||
private String username;
|
||||
private String usernameSnapshot;
|
||||
|
||||
public Long getLogId() { return logId; }
|
||||
public String getActivity() { return activity; }
|
||||
public String getFullName() { return fullName; }
|
||||
public String getFullNameSnapshot() { return fullNameSnapshot; }
|
||||
public String getLogTimestamp() { return logTimestamp; }
|
||||
public String getRole() { return role; }
|
||||
public String getRoleSnapshot() { return roleSnapshot; }
|
||||
public Long getStoreId() { return storeId; }
|
||||
public String getStoreName() { return storeName; }
|
||||
public String getStoreNameSnapshot() { return storeNameSnapshot; }
|
||||
public Long getUserId() { return userId; }
|
||||
public String getUsername() { return username; }
|
||||
public String getUsernameSnapshot() { return usernameSnapshot; }
|
||||
}
|
||||
@@ -92,6 +92,7 @@ public class ListFragment extends Fragment {
|
||||
binding.drawerCustomers.setOnClickListener(v -> navigateTo(R.id.nav_customer));
|
||||
binding.drawerAnalytics.setOnClickListener(v -> navigateTo(R.id.nav_analytics));
|
||||
binding.drawerCoupons.setOnClickListener(v -> navigateTo(R.id.nav_coupon));
|
||||
binding.drawerActivityLogs.setOnClickListener(v -> navigateTo(R.id.nav_activity_log));
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.example.petstoremobile.fragments.listfragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.example.petstoremobile.adapters.ActivityLogAdapter;
|
||||
import com.example.petstoremobile.databinding.FragmentActivityLogBinding;
|
||||
import com.example.petstoremobile.dtos.ActivityLogDTO;
|
||||
import com.example.petstoremobile.utils.SpinnerUtils;
|
||||
import com.example.petstoremobile.utils.UIUtils;
|
||||
import com.example.petstoremobile.viewmodels.ActivityLogListViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ActivityLogFragment extends Fragment {
|
||||
private FragmentActivityLogBinding binding;
|
||||
private ActivityLogListViewModel viewModel;
|
||||
private ActivityLogAdapter adapter;
|
||||
private final List<ActivityLogDTO> logList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
binding = FragmentActivityLogBinding.inflate(inflater, container, false);
|
||||
viewModel = new ViewModelProvider(this).get(ActivityLogListViewModel.class);
|
||||
|
||||
setupRecyclerView();
|
||||
setupFilters();
|
||||
observeViewModel();
|
||||
|
||||
binding.swipeRefreshActivityLog.setOnRefreshListener(() -> viewModel.loadLogs());
|
||||
UIUtils.setupHamburgerMenu(binding.btnHamburgerActivityLog, this);
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
viewModel.loadLogs();
|
||||
}
|
||||
|
||||
private void setupRecyclerView() {
|
||||
adapter = new ActivityLogAdapter(logList);
|
||||
binding.recyclerViewActivityLog.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
binding.recyclerViewActivityLog.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void setupFilters() {
|
||||
UIUtils.setupFilterToggle(binding.btnToggleFilter, binding.layoutFilter,
|
||||
binding.etSearchLog, binding.spinnerRoleFilter, binding.spinnerStoreFilter);
|
||||
|
||||
UIUtils.attachSearch(binding.etSearchLog, () ->
|
||||
viewModel.setSearchQuery(binding.etSearchLog.getText().toString()));
|
||||
|
||||
String[] roles = {"All Roles", "ADMIN", "STAFF"};
|
||||
SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerRoleFilter, roles, () ->
|
||||
viewModel.setRoleFilter(binding.spinnerRoleFilter.getSelectedItem() != null
|
||||
? binding.spinnerRoleFilter.getSelectedItem().toString() : "All Roles"));
|
||||
}
|
||||
|
||||
private void observeViewModel() {
|
||||
viewModel.getLogs().observe(getViewLifecycleOwner(), list -> {
|
||||
logList.clear();
|
||||
logList.addAll(list);
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
|
||||
viewModel.getStoreOptions().observe(getViewLifecycleOwner(), options -> {
|
||||
String[] arr = options.toArray(new String[0]);
|
||||
SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerStoreFilter, arr, () ->
|
||||
viewModel.setStoreFilter(binding.spinnerStoreFilter.getSelectedItem() != null
|
||||
? binding.spinnerStoreFilter.getSelectedItem().toString() : "All Stores"));
|
||||
});
|
||||
|
||||
viewModel.getIsLoading().observe(getViewLifecycleOwner(), loading -> {
|
||||
binding.swipeRefreshActivityLog.setRefreshing(loading);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,7 @@ public class AppointmentDetailFragment extends Fragment {
|
||||
if (staff != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff,
|
||||
staff, DropdownDTO::getLabel, "-- Select Staff --", state.selectedStaffId, DropdownDTO::getId);
|
||||
|
||||
if (isStaff()) binding.spinnerStore.setEnabled(false);
|
||||
if (isStaff()) UIUtils.setViewsEnabled(false, binding.spinnerStore);
|
||||
|
||||
isUpdatingUI = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.petstoremobile.repositories;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import com.example.petstoremobile.api.ActivityLogApi;
|
||||
import com.example.petstoremobile.dtos.ActivityLogDTO;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class ActivityLogRepository extends BaseRepository {
|
||||
private final ActivityLogApi activityLogApi;
|
||||
|
||||
@Inject
|
||||
public ActivityLogRepository(ActivityLogApi activityLogApi) {
|
||||
super("ActivityLogRepository");
|
||||
this.activityLogApi = activityLogApi;
|
||||
}
|
||||
|
||||
public LiveData<Resource<List<ActivityLogDTO>>> getActivityLogs() {
|
||||
return executeCall(activityLogApi.getActivityLogs());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.example.petstoremobile.viewmodels;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.example.petstoremobile.dtos.ActivityLogDTO;
|
||||
import com.example.petstoremobile.repositories.ActivityLogRepository;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||
|
||||
@HiltViewModel
|
||||
public class ActivityLogListViewModel extends ViewModel {
|
||||
private final ActivityLogRepository repository;
|
||||
|
||||
private final List<ActivityLogDTO> allLogs = new ArrayList<>();
|
||||
private final MutableLiveData<List<ActivityLogDTO>> logs = new MutableLiveData<>(new ArrayList<>());
|
||||
private final MutableLiveData<List<String>> storeOptions = new MutableLiveData<>(new ArrayList<>());
|
||||
private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
|
||||
|
||||
private String searchQuery = "";
|
||||
private String roleFilter = "All Roles";
|
||||
private String storeFilter = "All Stores";
|
||||
|
||||
@Inject
|
||||
public ActivityLogListViewModel(ActivityLogRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public LiveData<List<ActivityLogDTO>> getLogs() { return logs; }
|
||||
public LiveData<List<String>> getStoreOptions() { return storeOptions; }
|
||||
public LiveData<Boolean> getIsLoading() { return isLoading; }
|
||||
|
||||
public void loadLogs() {
|
||||
isLoading.setValue(true);
|
||||
observeOnce(repository.getActivityLogs(), resource -> {
|
||||
if (resource != null) {
|
||||
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
allLogs.clear();
|
||||
allLogs.addAll(resource.data);
|
||||
buildStoreOptions();
|
||||
applyFilters();
|
||||
isLoading.setValue(false);
|
||||
} else if (resource.status == Resource.Status.ERROR) {
|
||||
isLoading.setValue(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setSearchQuery(String query) {
|
||||
searchQuery = query == null ? "" : query.trim();
|
||||
applyFilters();
|
||||
}
|
||||
|
||||
public void setRoleFilter(String role) {
|
||||
roleFilter = role == null ? "All Roles" : role;
|
||||
applyFilters();
|
||||
}
|
||||
|
||||
public void setStoreFilter(String store) {
|
||||
storeFilter = store == null ? "All Stores" : store;
|
||||
applyFilters();
|
||||
}
|
||||
|
||||
private void buildStoreOptions() {
|
||||
LinkedHashSet<String> names = new LinkedHashSet<>();
|
||||
for (ActivityLogDTO log : allLogs) {
|
||||
String name = log.getStoreNameSnapshot() != null ? log.getStoreNameSnapshot() : log.getStoreName();
|
||||
if (name != null && !name.isEmpty()) names.add(name);
|
||||
}
|
||||
List<String> options = new ArrayList<>();
|
||||
options.add("All Stores");
|
||||
options.addAll(names);
|
||||
storeOptions.setValue(options);
|
||||
}
|
||||
|
||||
private void applyFilters() {
|
||||
List<ActivityLogDTO> filtered = new ArrayList<>();
|
||||
String query = searchQuery.toLowerCase(Locale.ROOT);
|
||||
|
||||
for (ActivityLogDTO log : allLogs) {
|
||||
// Role filter
|
||||
if (!"All Roles".equals(roleFilter)) {
|
||||
String role = log.getRoleSnapshot() != null ? log.getRoleSnapshot() : log.getRole();
|
||||
if (!roleFilter.equalsIgnoreCase(role)) continue;
|
||||
}
|
||||
|
||||
// Store filter
|
||||
if (!"All Stores".equals(storeFilter)) {
|
||||
String store = log.getStoreNameSnapshot() != null ? log.getStoreNameSnapshot() : log.getStoreName();
|
||||
if (!storeFilter.equals(store)) continue;
|
||||
}
|
||||
|
||||
// Search filter
|
||||
if (!query.isEmpty()) {
|
||||
String activity = log.getActivity() != null ? log.getActivity().toLowerCase(Locale.ROOT) : "";
|
||||
String fullName = log.getFullNameSnapshot() != null
|
||||
? log.getFullNameSnapshot().toLowerCase(Locale.ROOT)
|
||||
: (log.getFullName() != null ? log.getFullName().toLowerCase(Locale.ROOT) : "");
|
||||
String username = log.getUsernameSnapshot() != null
|
||||
? log.getUsernameSnapshot().toLowerCase(Locale.ROOT)
|
||||
: (log.getUsername() != null ? log.getUsername().toLowerCase(Locale.ROOT) : "");
|
||||
if (!activity.contains(query) && !fullName.contains(query) && !username.contains(query)) continue;
|
||||
}
|
||||
|
||||
filtered.add(log);
|
||||
}
|
||||
|
||||
logs.setValue(filtered);
|
||||
}
|
||||
|
||||
private <T> void observeOnce(LiveData<Resource<T>> liveData, Observer<Resource<T>> handler) {
|
||||
liveData.observeForever(new Observer<Resource<T>>() {
|
||||
@Override
|
||||
public void onChanged(Resource<T> resource) {
|
||||
if (resource == null || resource.status != Resource.Status.LOADING) {
|
||||
liveData.removeObserver(this);
|
||||
}
|
||||
handler.onChanged(resource);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
139
android/app/src/main/res/layout/fragment_activity_log.xml
Normal file
139
android/app/src/main/res/layout/fragment_activity_log.xml
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/background_grey">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="@color/primary_dark"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnHamburgerActivityLog"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:src="@drawable/baseline_menu_36"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:tint="@color/white"
|
||||
android:contentDescription="Menu"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Activity Logs"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnToggleFilter"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:src="@android:drawable/ic_menu_search"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:tint="@color/white"
|
||||
android:contentDescription="Toggle filter"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Collapsible filter panel -->
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutFilter"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:visibility="gone"
|
||||
android:background="@color/primary_dark"
|
||||
android:elevation="4dp">
|
||||
|
||||
<!-- Search bar -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="44dp"
|
||||
android:background="@drawable/bg_search_bar"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:src="@android:drawable/ic_menu_search"
|
||||
android:alpha="0.6"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etSearchLog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="Search activity or user..."
|
||||
android:inputType="text"
|
||||
android:background="@android:color/transparent"
|
||||
android:textColor="@color/text_dark"
|
||||
android:textColorHint="#99000000"
|
||||
android:textSize="14sp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Role and Store spinners -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerRoleFilter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_spinner"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="8dp"/>
|
||||
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="0dp"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerStoreFilter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_spinner"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshActivityLog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerViewActivityLog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:clipToPadding="false"/>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -363,6 +363,23 @@
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerActivityLogs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Activity Logs"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
53
android/app/src/main/res/layout/item_activity_log.xml
Normal file
53
android/app/src/main/res/layout/item_activity_log.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/rounded_card"
|
||||
android:padding="12dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLogActivity"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textSize="13sp"
|
||||
android:textColor="@color/text_dark"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="monospace"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLogTimestamp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="11sp"
|
||||
android:textColor="@color/text_light"
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLogUser"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_dark"
|
||||
android:layout_marginBottom="2dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLogMeta"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="11sp"
|
||||
android:textColor="@color/text_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -175,6 +175,12 @@
|
||||
android:label="Coupons"
|
||||
tools:layout="@layout/fragment_coupon" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_activity_log"
|
||||
android:name="com.example.petstoremobile.fragments.listfragments.ActivityLogFragment"
|
||||
android:label="Activity Logs"
|
||||
tools:layout="@layout/fragment_activity_log" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/couponDetailFragment"
|
||||
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.CouponDetailFragment"
|
||||
|
||||
Reference in New Issue
Block a user