Connected to the backend
-Connected to backend using retrofit -Added TokenManager and AuthInterceptor for the application to login and make calls with authentication to access some backend calls that need authentication
This commit is contained in:
@@ -36,6 +36,12 @@ dependencies {
|
||||
implementation(libs.material)
|
||||
implementation(libs.activity)
|
||||
implementation(libs.constraintlayout)
|
||||
|
||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.9.1")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
|
||||
implementation("com.google.android.material:material:1.11.0")
|
||||
implementation("androidx.viewpager2:viewpager2:1.1.0")
|
||||
implementation("com.google.android.material:material:1.11.0")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
@@ -13,6 +14,7 @@
|
||||
android:required="false" />
|
||||
|
||||
<application
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.example.petstoremobile.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
@@ -14,7 +15,16 @@ import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.api.Auth.AuthApi;
|
||||
import com.example.petstoremobile.api.Auth.TokenManager;
|
||||
import com.example.petstoremobile.api.RetrofitClient;
|
||||
import com.example.petstoremobile.dtos.AuthDTO;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
//The login screen activity
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private EditText etUser;
|
||||
@@ -56,17 +66,47 @@ public class MainActivity extends AppCompatActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
//check if username and password are correct TODO: Replace with actual login
|
||||
if (username.equals("admin") && password.equals("admin")) {
|
||||
Intent intent = new Intent(this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
Toast.makeText(this, "Login successful", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, "Login failed", Toast.LENGTH_SHORT).show();
|
||||
tvLoginStatus.setText("Login failed");
|
||||
}
|
||||
AuthApi authApi = RetrofitClient.getAuthApi(this);
|
||||
|
||||
//Call login from api and get response
|
||||
authApi.login(new AuthDTO.LoginRequest(username,password)).enqueue(new Callback<AuthDTO.LoginResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<AuthDTO.LoginResponse> call, Response<AuthDTO.LoginResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
//save login data in shared preferences
|
||||
TokenManager.getInstance(MainActivity.this).saveLoginData(
|
||||
response.body().getToken(),
|
||||
response.body().getUsername(),
|
||||
response.body().getRole()
|
||||
);
|
||||
//go to home activity after login
|
||||
Intent intent = new Intent(MainActivity.this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
} else {
|
||||
// Toast.makeText(MainActivity.this, "Login failed", Toast.LENGTH_SHORT).show();
|
||||
// tvLoginStatus.setText("Login failed");
|
||||
|
||||
try {
|
||||
String errorBody = response.errorBody().string();
|
||||
Log.e("LOGIN", "Code: " + response.code() + " Error: " + errorBody);
|
||||
} catch (Exception e) {
|
||||
Log.e("LOGIN", "Code: " + response.code());
|
||||
}
|
||||
Toast.makeText(MainActivity.this,
|
||||
"Login failed: " + response.code(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
tvLoginStatus.setText("Login failed: " + response.code());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) {
|
||||
Toast.makeText(MainActivity.this, "Login failed", Toast.LENGTH_SHORT).show();
|
||||
tvLoginStatus.setText("Login failed");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.example.petstoremobile.api.Auth;
|
||||
|
||||
import com.example.petstoremobile.dtos.AuthDTO;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.POST;
|
||||
|
||||
//Api for logging in
|
||||
public interface AuthApi {
|
||||
@POST("v1/auth/login")
|
||||
Call<AuthDTO.LoginResponse> login(@Body AuthDTO.LoginRequest loginRequest);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.example.petstoremobile.api.Auth;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
//Used to get the token from the backend for authenticated api calls
|
||||
public class AuthInterceptor implements Interceptor {
|
||||
|
||||
private final TokenManager tokenManager;
|
||||
|
||||
public AuthInterceptor(Context context) {
|
||||
this.tokenManager = TokenManager.getInstance(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Response intercept(@NonNull Chain chain) throws IOException {
|
||||
String token = tokenManager.getToken();
|
||||
|
||||
//If we have a token then add it to the request
|
||||
if (token != null) {
|
||||
Request request = chain.request().newBuilder()
|
||||
.addHeader("Authorization", "Bearer " + token)
|
||||
.build();
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
//If no token then just pass the request
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.example.petstoremobile.api.Auth;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
//Store login token in shared preferences
|
||||
public class TokenManager {
|
||||
private static final String TOKEN_KEY = "token";
|
||||
private static final String USERNAME_KEY = "username";
|
||||
private static final String ROLE_KEY = "role";
|
||||
private static final String PREFS_NAME = "auth_prefs";
|
||||
|
||||
private static TokenManager instance;
|
||||
private SharedPreferences prefs;
|
||||
|
||||
private TokenManager(Context context) {
|
||||
prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static TokenManager getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
instance = new TokenManager(context);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
//save login data after login
|
||||
public void saveLoginData(String token, String username, String role) {
|
||||
prefs.edit()
|
||||
.putString(TOKEN_KEY, token)
|
||||
.putString(USERNAME_KEY, username)
|
||||
.putString(ROLE_KEY, role)
|
||||
.apply();
|
||||
}
|
||||
|
||||
//Getters
|
||||
public String getToken() {
|
||||
return prefs.getString(TOKEN_KEY, null);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return prefs.getString(USERNAME_KEY, null);
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return prefs.getString(ROLE_KEY, null);
|
||||
}
|
||||
|
||||
//Check if logged in
|
||||
public boolean isLoggedIn() {
|
||||
return getToken() != null;
|
||||
}
|
||||
|
||||
//Clear login data
|
||||
public void clearLoginData() {
|
||||
prefs.edit().clear().apply();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
39
app/src/main/java/com/example/petstoremobile/api/PetApi.java
Normal file
39
app/src/main/java/com/example/petstoremobile/api/PetApi.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.example.petstoremobile.api;
|
||||
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.PetDTO;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.DELETE;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface PetApi {
|
||||
// Get all pets
|
||||
@GET("v1/pets")
|
||||
Call<PageResponse<PetDTO>> getAllPets(
|
||||
@Query("page") int page,
|
||||
@Query("size") int size
|
||||
);
|
||||
|
||||
// Get pet by id
|
||||
@GET("v1/pets/{id}")
|
||||
Call<PetDTO> getPetById(@Path("id") Long id);
|
||||
|
||||
// Create pet
|
||||
@POST("v1/pets")
|
||||
Call<PetDTO> createPet(@Body PetDTO pet);
|
||||
|
||||
// Update pet
|
||||
@PUT("v1/pets/{id}")
|
||||
Call<PetDTO> updatePet(@Path("id") Long id, @Body PetDTO pet);
|
||||
|
||||
// Delete pet
|
||||
@DELETE("v1/pets/{id}")
|
||||
Call<Void> deletePet(@Path("id") Long id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.example.petstoremobile.api;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.petstoremobile.api.Auth.AuthApi;
|
||||
import com.example.petstoremobile.api.Auth.AuthInterceptor;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class RetrofitClient {
|
||||
//base URL
|
||||
public static final String BASE_URL = "http://10.0.2.2:8080/api/"; //for emulator testing change to computer ip if using hardware to test
|
||||
|
||||
|
||||
private static Retrofit retrofit = null;
|
||||
|
||||
public static Retrofit getClient(Context context) {
|
||||
//create an http logging using an interceptor
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(interceptor)
|
||||
.addInterceptor(new AuthInterceptor(context))
|
||||
.build();
|
||||
|
||||
//build the retrofit object with all needed properties
|
||||
retrofit = new Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create()) //JSON converter
|
||||
.client(client) //logging interceptor - OkHttpClient
|
||||
.build();
|
||||
|
||||
return retrofit;
|
||||
}
|
||||
|
||||
//associate the retrofit object with the API interface
|
||||
public static PetApi getPetApi(Context context) {
|
||||
return getClient(context).create(PetApi.class);
|
||||
}
|
||||
|
||||
public static ServiceApi getServiceApi(Context context) {
|
||||
return getClient(context).create(ServiceApi.class);
|
||||
}
|
||||
|
||||
public static SupplierApi getSupplierApi(Context context) {
|
||||
return getClient(context).create(SupplierApi.class);
|
||||
}
|
||||
|
||||
public static AuthApi getAuthApi(Context context) {
|
||||
return getClient(context).create(AuthApi.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.example.petstoremobile.api;
|
||||
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.DELETE;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface ServiceApi {
|
||||
// Get all services
|
||||
@GET("v1/services")
|
||||
Call<PageResponse<ServiceDTO>> getAllServices(
|
||||
@Query("page") int page,
|
||||
@Query("size") int size
|
||||
);
|
||||
|
||||
// Get service by id
|
||||
@GET("v1/services/{id}")
|
||||
Call<ServiceDTO> getServiceById(@Path("id") Long id);
|
||||
|
||||
// Create service
|
||||
@POST("v1/services")
|
||||
Call<ServiceDTO> createService(@Body ServiceDTO service);
|
||||
|
||||
// Update service
|
||||
@PUT("v1/services/{id}")
|
||||
Call<ServiceDTO> updateService(@Path("id") Long id, @Body ServiceDTO service);
|
||||
|
||||
// Delete service
|
||||
@DELETE("v1/services/{id}")
|
||||
Call<Void> deleteService(@Path("id") Long id);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.example.petstoremobile.api;
|
||||
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.DELETE;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface SupplierApi {
|
||||
// Get all suppliers
|
||||
@GET("v1/suppliers")
|
||||
Call<PageResponse<SupplierDTO>> getAllSuppliers(
|
||||
@Query("page") int page,
|
||||
@Query("size") int size
|
||||
);
|
||||
|
||||
// Get supplier by id
|
||||
@GET("v1/suppliers/{id}")
|
||||
Call<SupplierDTO> getSupplierById(@Path("id") Long id);
|
||||
|
||||
// Create supplier
|
||||
@POST("v1/suppliers")
|
||||
Call<SupplierDTO> createSupplier(@Body SupplierDTO supplier);
|
||||
|
||||
// Update supplier
|
||||
@PUT("v1/suppliers/{id}")
|
||||
Call<SupplierDTO> updateSupplier(@Path("id") Long id, @Body SupplierDTO supplier);
|
||||
|
||||
// Delete supplier
|
||||
@DELETE("v1/suppliers/{id}")
|
||||
Call<Void> deleteSupplier(@Path("id") Long id);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
//Used to send login data to the backend
|
||||
public class AuthDTO {
|
||||
public static class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public LoginRequest(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public String getPassword() { return password; }
|
||||
}
|
||||
|
||||
//Used to receive login data from the backend
|
||||
public static class LoginResponse {
|
||||
private String token;
|
||||
private String username;
|
||||
private String role;
|
||||
|
||||
public String getToken() { return token; }
|
||||
public String getUsername() { return username; }
|
||||
public String getRole() { return role; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//Used to get data from the API
|
||||
public class PageResponse<T> {
|
||||
private List<T> content;
|
||||
private int totalPages;
|
||||
private long totalElements;
|
||||
private int number;
|
||||
private int size;
|
||||
private boolean last;
|
||||
|
||||
public List<T> getContent() {
|
||||
return content;
|
||||
}
|
||||
public int getTotalPages() {
|
||||
return totalPages;
|
||||
}
|
||||
public long getTotalElements() {
|
||||
return totalElements;
|
||||
}
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
public boolean isLast() {
|
||||
return last;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
public class PetDTO {
|
||||
private Long petId;
|
||||
private String petName;
|
||||
private String petSpecies;
|
||||
private String petBreed;
|
||||
private Integer petAge;
|
||||
private String petStatus;
|
||||
private String petPrice;
|
||||
private String createdAt;
|
||||
private String updatedAt;
|
||||
|
||||
public Long getPetId() { return petId; }
|
||||
public String getPetName() { return petName; }
|
||||
public String getPetSpecies() { return petSpecies; }
|
||||
public String getPetBreed() { return petBreed; }
|
||||
public Integer getPetAge() { return petAge; }
|
||||
public String getPetStatus() { return petStatus; }
|
||||
public String getPetPrice() { return petPrice; }
|
||||
public String getCreatedAt() { return createdAt; }
|
||||
public String getUpdatedAt() { return updatedAt; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
public class ServiceDTO {
|
||||
private Long serviceId;
|
||||
private String serviceName;
|
||||
private String serviceDesc;
|
||||
private Integer serviceDuration;
|
||||
private Double servicePrice;
|
||||
private String createdAt;
|
||||
private String updatedAt;
|
||||
|
||||
public Long getServiceId() { return serviceId; }
|
||||
public String getServiceName() { return serviceName; }
|
||||
public String getServiceDesc() { return serviceDesc; }
|
||||
public Integer getServiceDuration() { return serviceDuration; }
|
||||
public Double getServicePrice() { return servicePrice; }
|
||||
public String getCreatedAt() { return createdAt; }
|
||||
public String getUpdatedAt() { return updatedAt; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
public class SupplierDTO {
|
||||
private Long supId;
|
||||
private String supCompany;
|
||||
private String supContactFirstName;
|
||||
private String supContactLastName;
|
||||
private String supEmail;
|
||||
private String supPhone;
|
||||
private String createdAt;
|
||||
private String updatedAt;
|
||||
|
||||
public Long getSupId() { return supId; }
|
||||
public String getSupCompany() { return supCompany; }
|
||||
public String getSupContactFirstName() { return supContactFirstName; }
|
||||
public String getSupContactLastName() { return supContactLastName; }
|
||||
public String getSupEmail() { return supEmail; }
|
||||
public String getSupPhone() { return supPhone; }
|
||||
public String getCreatedAt() { return createdAt; }
|
||||
public String getUpdatedAt() { return updatedAt; }
|
||||
}
|
||||
@@ -6,13 +6,19 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.PetAdapter;
|
||||
import com.example.petstoremobile.api.PetApi;
|
||||
import com.example.petstoremobile.api.RetrofitClient;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.PetDTO;
|
||||
import com.example.petstoremobile.fragments.ListFragment;
|
||||
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
|
||||
import com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment;
|
||||
@@ -22,11 +28,15 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PetFragment extends Fragment implements PetAdapter.OnPetClickListener {
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class PetFragment extends Fragment implements PetAdapter.OnPetClickListener {
|
||||
private List<Pet> petList = new ArrayList<>();
|
||||
private PetAdapter adapter;
|
||||
private ImageButton hamburger;
|
||||
private PetAdapter adapter;
|
||||
private PetApi api;
|
||||
|
||||
//load pet view
|
||||
@Override
|
||||
@@ -34,10 +44,14 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_pet, container, false);
|
||||
|
||||
//get retrofit
|
||||
api = RetrofitClient.getPetApi(requireContext());
|
||||
|
||||
hamburger = view.findViewById(R.id.btnHamburger);
|
||||
|
||||
loadPetData(); //TODO: Replace this with actual data when backend is working
|
||||
setupRecyclerView(view);
|
||||
loadPetData(); //TODO: Replace this with actual data when backend is working
|
||||
|
||||
|
||||
//Add button to opens the add dialog
|
||||
FloatingActionButton fabAddPet = view.findViewById(R.id.fabAddPet);
|
||||
@@ -114,15 +128,35 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
||||
openPetProfile(position);
|
||||
}
|
||||
|
||||
// Helper function to get a list of all pets (Loads hardcoded sample data for now) TODO: REPLACE THIS WITH A METHOD THAT GETS DATA FROM THE DATABASE
|
||||
// Helper function to get a list of all pets from the backend
|
||||
private void loadPetData() {
|
||||
petList.clear();
|
||||
petList.add(new Pet(1, "Buddy","Dog", "Labrador",2, "Available", 500.00));
|
||||
petList.add(new Pet(2, "Milo", "Cat", "Persian",1, "Available", 300.00));
|
||||
petList.add(new Pet(3, "Charlie","Dog", "Golden Retriever", 3, "Available", 550.00));
|
||||
petList.add(new Pet(4, "Luna", "Cat", "Siamese",2, "Adopted", 350.00));
|
||||
petList.add(new Pet(5, "Max", "Dog", "Beagle",1, "Available", 450.00));
|
||||
petList.add(new Pet(6, "Bella", "Cat", "Maine Coon",4, "Available", 400.00));
|
||||
api.getAllPets(0, 100).enqueue(new Callback<PageResponse<PetDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
petList.clear();
|
||||
|
||||
// Convert to pets
|
||||
List<Pet> pets = response.body().getContent()
|
||||
.stream()
|
||||
.map(Pet::new)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
petList.addAll(pets);
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) { // 4. here
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load pets", Toast.LENGTH_SHORT).show();
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//set up the recyclerview and adapter
|
||||
|
||||
@@ -6,13 +6,19 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.ServiceAdapter;
|
||||
import com.example.petstoremobile.api.RetrofitClient;
|
||||
import com.example.petstoremobile.api.ServiceApi;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||
import com.example.petstoremobile.fragments.ListFragment;
|
||||
import com.example.petstoremobile.fragments.listfragments.detailfragments.ServiceDetailFragment;
|
||||
import com.example.petstoremobile.models.Service;
|
||||
@@ -21,11 +27,16 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class ServiceFragment extends Fragment implements ServiceAdapter.OnServiceClickListener {
|
||||
|
||||
private List<Service> serviceList = new ArrayList<>();
|
||||
private ServiceAdapter adapter;
|
||||
private ImageButton hamburger;
|
||||
private ServiceApi api;
|
||||
|
||||
//load service view
|
||||
@Override
|
||||
@@ -33,10 +44,11 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_service, container, false);
|
||||
|
||||
api = RetrofitClient.getServiceApi(requireContext());
|
||||
hamburger = view.findViewById(R.id.btnHamburger);
|
||||
|
||||
loadServiceData(); //TODO: Replace this with actual data when backend is working
|
||||
setupRecyclerView(view);
|
||||
loadServiceData();
|
||||
|
||||
//Add button to opens the add dialog
|
||||
FloatingActionButton fabAddService = view.findViewById(R.id.fabAddService);
|
||||
@@ -106,14 +118,37 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
||||
openServiceDetails(position);
|
||||
}
|
||||
|
||||
// Helper function to get a list of all services (Loads hardcoded sample data for now) TODO: REPLACE THIS WITH A METHOD THAT GETS DATA FROM THE DATABASE
|
||||
// Helper function to get a list of all services from the backend
|
||||
private void loadServiceData() {
|
||||
serviceList.clear();
|
||||
serviceList.add(new Service(1, "Grooming", "Full grooming for your pet", 60, 50.00));
|
||||
serviceList.add(new Service(2, "Vaccination", "Standard vaccinations", 30, 75.00));
|
||||
serviceList.add(new Service(3, "Health Checkup", "Comprehensive health exam", 45, 100.00));
|
||||
serviceList.add(new Service(4, "Pet Sitting", "Overnight stay for your pet", 1440, 40.00));
|
||||
serviceList.add(new Service(5, "Training", "Basic obedience training session", 60, 60.00));
|
||||
api.getAllServices(0, 100).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
serviceList.clear();
|
||||
|
||||
// Convert to services
|
||||
List<Service> services = response.body().getContent()
|
||||
.stream()
|
||||
.map(Service::new)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
serviceList.addAll(services);
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load services", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//set up the recyclerview and adapter
|
||||
|
||||
@@ -6,13 +6,19 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.SupplierAdapter;
|
||||
import com.example.petstoremobile.api.RetrofitClient;
|
||||
import com.example.petstoremobile.api.SupplierApi;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||
import com.example.petstoremobile.fragments.ListFragment;
|
||||
import com.example.petstoremobile.fragments.listfragments.detailfragments.SupplierDetailFragment;
|
||||
import com.example.petstoremobile.models.Supplier;
|
||||
@@ -21,11 +27,16 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupplierClickListener {
|
||||
|
||||
private List<Supplier> supplierList = new ArrayList<>();
|
||||
private SupplierAdapter adapter;
|
||||
private ImageButton hamburger;
|
||||
private SupplierApi api;
|
||||
|
||||
//load supplier view
|
||||
@Override
|
||||
@@ -33,10 +44,11 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_supplier, container, false);
|
||||
|
||||
api = RetrofitClient.getSupplierApi(requireContext());
|
||||
hamburger = view.findViewById(R.id.btnHamburger);
|
||||
|
||||
loadSupplierData(); //TODO: Replace this with actual data when backend is working
|
||||
setupRecyclerView(view);
|
||||
loadSupplierData();
|
||||
|
||||
//Add button to opens the add dialog
|
||||
FloatingActionButton fabAddSupplier = view.findViewById(R.id.fabAddSupplier);
|
||||
@@ -107,14 +119,37 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
||||
openSupplierDetails(position);
|
||||
}
|
||||
|
||||
// Helper function to get a list of all suppliers (Loads hardcoded sample data for now) TODO: REPLACE THIS WITH A METHOD THAT GETS DATA FROM THE DATABASE
|
||||
// Helper function to get a list of all suppliers from the backend
|
||||
private void loadSupplierData() {
|
||||
supplierList.clear();
|
||||
supplierList.add(new Supplier(1, "Pet Food Co.", "John", "Doe", "john@petfood.com", "123-456-7890"));
|
||||
supplierList.add(new Supplier(2, "Toy Kingdom", "Jane", "Smith", "jane@toykingdom.com", "987-654-3210"));
|
||||
supplierList.add(new Supplier(3, "HealthPet", "Robert", "Brown", "robert@healthpet.com", "555-0199-234"));
|
||||
supplierList.add(new Supplier(4, "Groomers Choice", "Emily", "Davis", "emily@groomers.com", "444-555-6666"));
|
||||
supplierList.add(new Supplier(5, "Birdy Haven", "Michael", "Wilson", "michael@birdyhaven.com", "111-222-3333"));
|
||||
api.getAllSuppliers(0, 100).enqueue(new Callback<PageResponse<SupplierDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<SupplierDTO>> call, Response<PageResponse<SupplierDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
supplierList.clear();
|
||||
|
||||
// Convert to suppliers
|
||||
List<Supplier> suppliers = response.body().getContent()
|
||||
.stream()
|
||||
.map(Supplier::new)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
supplierList.addAll(suppliers);
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<SupplierDTO>> call, Throwable t) {
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load suppliers", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//set up the recyclerview and adapter
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.example.petstoremobile.models;
|
||||
|
||||
import com.example.petstoremobile.dtos.PetDTO;
|
||||
|
||||
public class Pet {
|
||||
private int petId;
|
||||
private String petName;
|
||||
@@ -20,6 +22,17 @@ public class Pet {
|
||||
this.petPrice = petPrice;
|
||||
}
|
||||
|
||||
//contructor to convert PetDTO to Pet
|
||||
public Pet(PetDTO dto) {
|
||||
this.petId = dto.getPetId().intValue();
|
||||
this.petName = dto.getPetName();
|
||||
this.petSpecies = dto.getPetSpecies();
|
||||
this.petBreed = dto.getPetBreed();
|
||||
this.petAge = dto.getPetAge();
|
||||
this.petStatus = dto.getPetStatus();
|
||||
this.petPrice = Double.parseDouble(dto.getPetPrice());
|
||||
}
|
||||
|
||||
//getter and setters
|
||||
public int getPetId() {
|
||||
return petId;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.example.petstoremobile.models;
|
||||
|
||||
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||
|
||||
public class Service {
|
||||
private int serviceId;
|
||||
private String serviceName;
|
||||
@@ -16,15 +18,19 @@ public class Service {
|
||||
this.servicePrice = servicePrice;
|
||||
}
|
||||
|
||||
public Service(ServiceDTO dto) {
|
||||
this.serviceId = dto.getServiceId().intValue();
|
||||
this.serviceName = dto.getServiceName();
|
||||
this.serviceDesc = dto.getServiceDesc();
|
||||
this.serviceDuration = dto.getServiceDuration();
|
||||
this.servicePrice = dto.getServicePrice();
|
||||
}
|
||||
|
||||
//getter and setters
|
||||
public int getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
// public void setServiceId(int serviceId) {
|
||||
// this.serviceId = serviceId;
|
||||
// }
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.example.petstoremobile.models;
|
||||
|
||||
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||
|
||||
public class Supplier {
|
||||
private int supId;
|
||||
private String supCompany;
|
||||
@@ -18,16 +20,21 @@ public class Supplier {
|
||||
this.supPhone = supPhone;
|
||||
}
|
||||
|
||||
public Supplier(SupplierDTO dto) {
|
||||
this.supId = dto.getSupId().intValue();
|
||||
this.supCompany = dto.getSupCompany();
|
||||
this.supContactFirstName = dto.getSupContactFirstName();
|
||||
this.supContactLastName = dto.getSupContactLastName();
|
||||
this.supEmail = dto.getSupEmail();
|
||||
this.supPhone = dto.getSupPhone();
|
||||
}
|
||||
|
||||
//getter and setters
|
||||
|
||||
public int getSupId() {
|
||||
return supId;
|
||||
}
|
||||
|
||||
// public void setSupId(int supId) {
|
||||
// this.supId = supId;
|
||||
// }
|
||||
|
||||
public String getSupCompany() {
|
||||
return supCompany;
|
||||
}
|
||||
|
||||
8
app/src/main/res/xml/network_security_config.xml
Normal file
8
app/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
Reference in New Issue
Block a user