From dc93d1320f6b568fce1f08cd7d3cc5129649bccf Mon Sep 17 00:00:00 2001 From: OnlyPapy98 Date: Fri, 5 Dec 2025 18:08:01 +0100 Subject: [PATCH] in progress! --- .../com/example/quiz/AnnulationTicket.java | 65 +++++ .../java/com/example/quiz/BetValidation.java | 54 +++- .../main/java/com/example/quiz/Caisse.java | 100 ++++++++ .../java/com/example/quiz/ListOfReunions.java | 26 ++ app/src/main/java/com/example/quiz/Login.java | 42 ++-- .../main/java/com/example/quiz/PageQuiz.java | 160 ++++++++---- .../main/java/com/example/quiz/WinTicket.java | 69 +++++ .../data/model/dtos/auth/LoginPayload.java | 17 ++ .../data/model/dtos/auth/LoginResponse.java | 237 ++++++++++++++++++ .../example/quiz/data/remote/ApiClient.java | 2 +- .../example/quiz/data/remote/ApiService.java | 5 + .../quiz/data/repository/LoginRepository.java | 44 ++++ .../example/quiz/utils/SessionManager.java | 9 +- .../quiz/viewModel/LoginViewModel.java | 27 ++ .../main/res/drawable/button_transparent.xml | 3 + app/src/main/res/drawable/camera.xml | 21 ++ app/src/main/res/drawable/edittext_border.xml | 2 +- .../res/drawable/edittext_outline_white.xml | 10 + app/src/main/res/drawable/hashtag.xml | 15 ++ .../res/drawable/horse_head_svgrepo_com.xml | 9 + .../res/drawable/rounded_button_green.xml | 2 +- app/src/main/res/drawable/settings_icon.xml | 11 + app/src/main/res/drawable/tpe.xml | 48 ++++ app/src/main/res/drawable/x_background.xml | 5 + .../res/layout/fragment_annulation_ticket.xml | 65 +++++ app/src/main/res/layout/fragment_caisse.xml | 86 +++++++ app/src/main/res/layout/fragment_login.xml | 86 +++---- .../main/res/layout/fragment_win_ticket.xml | 65 +++++ app/src/main/res/layout/pari_confirmation.xml | 136 ++++++++++ app/src/main/res/layout/pin_view.xml | 57 +++++ app/src/main/res/values/strings.xml | 9 + 31 files changed, 1350 insertions(+), 137 deletions(-) create mode 100644 app/src/main/java/com/example/quiz/AnnulationTicket.java create mode 100644 app/src/main/java/com/example/quiz/Caisse.java create mode 100644 app/src/main/java/com/example/quiz/WinTicket.java create mode 100644 app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginPayload.java create mode 100644 app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginResponse.java create mode 100644 app/src/main/java/com/example/quiz/data/repository/LoginRepository.java create mode 100644 app/src/main/java/com/example/quiz/viewModel/LoginViewModel.java create mode 100644 app/src/main/res/drawable/button_transparent.xml create mode 100644 app/src/main/res/drawable/camera.xml create mode 100644 app/src/main/res/drawable/edittext_outline_white.xml create mode 100644 app/src/main/res/drawable/hashtag.xml create mode 100644 app/src/main/res/drawable/horse_head_svgrepo_com.xml create mode 100644 app/src/main/res/drawable/settings_icon.xml create mode 100644 app/src/main/res/drawable/tpe.xml create mode 100644 app/src/main/res/drawable/x_background.xml create mode 100644 app/src/main/res/layout/fragment_annulation_ticket.xml create mode 100644 app/src/main/res/layout/fragment_caisse.xml create mode 100644 app/src/main/res/layout/fragment_win_ticket.xml create mode 100644 app/src/main/res/layout/pari_confirmation.xml create mode 100644 app/src/main/res/layout/pin_view.xml diff --git a/app/src/main/java/com/example/quiz/AnnulationTicket.java b/app/src/main/java/com/example/quiz/AnnulationTicket.java new file mode 100644 index 0000000..0c09d1f --- /dev/null +++ b/app/src/main/java/com/example/quiz/AnnulationTicket.java @@ -0,0 +1,65 @@ +package com.example.quiz; + +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.example.quiz.databinding.FragmentAnnulationTicketBinding; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link AnnulationTicket#newInstance} factory method to + * create an instance of this fragment. + */ +public class AnnulationTicket extends Fragment { + + FragmentAnnulationTicketBinding binding; + + public AnnulationTicket() { + // Required empty public constructor + } + + + public static AnnulationTicket newInstance() { + AnnulationTicket fragment = new AnnulationTicket(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentAnnulationTicketBinding.inflate(inflater, container, false); + return binding.getRoot(); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + binding.annuleTicketBtnBack.setOnClickListener(v->{ + getActivity().onBackPressed(); + }); + } + + @Override + public void onResume() { + super.onResume(); + AppCompatActivity activity = (AppCompatActivity) getActivity(); + if(activity != null){ + activity.getSupportActionBar().setTitle("Annulation Ticket"); + } + } +} + diff --git a/app/src/main/java/com/example/quiz/BetValidation.java b/app/src/main/java/com/example/quiz/BetValidation.java index 387854c..1b00d98 100644 --- a/app/src/main/java/com/example/quiz/BetValidation.java +++ b/app/src/main/java/com/example/quiz/BetValidation.java @@ -1,15 +1,19 @@ package com.example.quiz; +import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.fragment.app.Fragment; @@ -54,6 +58,7 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import dagger.hilt.android.AndroidEntryPoint; @@ -70,6 +75,8 @@ public class BetValidation extends Fragment { SharedViewModel shared; + private AlertDialog dialog; + private boolean order; @@ -169,7 +176,7 @@ public class BetValidation extends Fragment { textView.setWidth(80); textView.setHeight(100); textView.setGravity(Gravity.CENTER); - textView.setBackgroundResource(R.drawable.number_background); + textView.setBackgroundResource(Objects.equals(horse, "X") ?R.drawable.x_background: R.drawable.number_background); textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); textView.setOnClickListener(v -> { final List horses = new ArrayList<>(selectedHorses.getValue()); @@ -292,11 +299,7 @@ public class BetValidation extends Fragment { Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show(); break; case SUCCESS: - try { - printPari(pariResult.data); - } catch (WriterException e) { - throw new RuntimeException(e); - } + _showPariDialog(pariResult.data); break; } } @@ -358,6 +361,45 @@ public class BetValidation extends Fragment { } + @SuppressLint({"MissingInflatedId", "SetTextI18n"}) + void _showPariDialog(Pari pari){ + LayoutInflater inflater = getLayoutInflater(); + View view = inflater.inflate(R.layout.pari_confirmation, null); + TextView numero_course = (TextView) view.findViewById(R.id.alert_course_numero); + numero_course.setText("Numero Course: "+String.valueOf(shared.selectedCourse.getValue().getId())); + TextView alert_pari_type = (TextView) view.findViewById(R.id.alert_pari_type); + alert_pari_type.setText(shared.typeOfBet.getValue().getName()); + TextView is_elargie = (TextView) view.findViewById(R.id.alert_is_elargie); + is_elargie.setText(selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse()?"CE":"SI"); + TextView alert_combinaison = (TextView) view.findViewById(R.id.alert_combinaison); + alert_combinaison.setText(selectedHorses.getValue().stream() + .map(String::valueOf) + .collect(Collectors.joining("-"))); + TextView aler_coeff = (TextView) view.findViewById(R.id.alert_coeff); + aler_coeff.setText("Coef:"+String.valueOf(coeff)); + TextView alert_montant = (TextView) view.findViewById(R.id.alert_montant); + alert_montant.setText("Montant: "+String.valueOf(mise)+" CFA"); + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setView(view); + builder.setCancelable(false); + + dialog = builder.create(); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + view.findViewById(R.id.alert_validate).setOnClickListener(v->{ + try { + printPari(pari); + dialog.dismiss(); + } catch (WriterException e) { + throw new RuntimeException(e); + } + }); + view.findViewById(R.id.alert_cancel).setOnClickListener(v -> { + dialog.dismiss(); + }); + + } + void _initializeToZero(){ mise = 0; binding.mise.setText(String.valueOf(mise+" CFA")); diff --git a/app/src/main/java/com/example/quiz/Caisse.java b/app/src/main/java/com/example/quiz/Caisse.java new file mode 100644 index 0000000..e6da450 --- /dev/null +++ b/app/src/main/java/com/example/quiz/Caisse.java @@ -0,0 +1,100 @@ +package com.example.quiz; + +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.example.quiz.databinding.FragmentCaisseBinding; +import com.google.android.material.appbar.MaterialToolbar; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link Caisse#newInstance} factory method to + * create an instance of this fragment. + */ +public class Caisse extends Fragment { + + FragmentCaisseBinding binding; + + public Caisse() { + // Required empty public constructor + } + + // TODO: Rename and change types and number of parameters + public static Caisse newInstance() { + Caisse fragment = new Caisse(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentCaisseBinding.inflate(inflater, container, false); + return binding.getRoot(); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState){ + super.onViewCreated(view, savedInstanceState); + binding.soldeBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Sold sold = Sold.newInstance(); + getActivity().getSupportFragmentManager() + .beginTransaction() + .replace(R.id.nav_host_fragment_content_main, sold) + .addToBackStack(null) + .commit(); + } + }); + binding.winTicketBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + WinTicket winTicket = WinTicket.newInstance(); + getActivity().getSupportFragmentManager() + .beginTransaction() + .replace(R.id.nav_host_fragment_content_main, winTicket) + .addToBackStack(null) + .commit(); + } + }); + binding.cancelTicketBtn.setOnClickListener(v -> { + AnnulationTicket annulationTicket = AnnulationTicket.newInstance(); + getActivity().getSupportFragmentManager() + .beginTransaction() + .replace(R.id.nav_host_fragment_content_main, annulationTicket) + .addToBackStack(null) + .commit(); + }); + } + + @Override + public void onResume() { + super.onResume(); + AppCompatActivity activity = (AppCompatActivity) getActivity(); + if (activity != null){ + MaterialToolbar toolbar = activity.findViewById(R.id.toolbar); + activity.setSupportActionBar(toolbar); + if(toolbar != null){ + if(activity.getSupportActionBar() != null){ + activity.getSupportActionBar().setTitle("Caisse"); + toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green)); + toolbar.setTitleTextColor(getResources().getColor(R.color.white)); + toolbar.setVisibility(View.VISIBLE); + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/ListOfReunions.java b/app/src/main/java/com/example/quiz/ListOfReunions.java index aac4b7e..34982bd 100644 --- a/app/src/main/java/com/example/quiz/ListOfReunions.java +++ b/app/src/main/java/com/example/quiz/ListOfReunions.java @@ -23,9 +23,12 @@ import android.view.ViewGroup; import android.widget.Toast; import android.widget.Toolbar; +import com.anggastudio.printama.Pref; +import com.anggastudio.printama.Printama; import com.example.quiz.data.adapter.ReunionAdapter; import com.example.quiz.data.model.Reunion; import com.example.quiz.databinding.FragmentListOfReunionsBinding; +import com.example.quiz.utils.BluetoothUtils; import com.example.quiz.utils.Result; import com.example.quiz.viewModel.ReunionViewModel; import com.example.quiz.viewModel.SharedViewModel; @@ -67,7 +70,30 @@ public class ListOfReunions extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + requestPermission(); } + private void requestPermission(){ + Pref.init(getContext()); + if (BluetoothUtils.needsBluetoothPermissions()) { + if (!BluetoothUtils.hasBluetoothPermission(getContext())) { + // Demande la permission si non accordée + BluetoothUtils.requestBluetoothPermission(getActivity()); + return; // arrête ici, la popup va apparaître + } + } + + // 2️⃣ Permission OK, on peut afficher la liste + try { + Printama printama = Printama.with(getContext()); + if(!printama.isConnected()){ + BluetoothUtils.showPrinterList(getContext(), getActivity()); + } + } catch (SecurityException e) { + Toast.makeText(getContext(), + "Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show(); + } + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, diff --git a/app/src/main/java/com/example/quiz/Login.java b/app/src/main/java/com/example/quiz/Login.java index 4a15675..111c06a 100644 --- a/app/src/main/java/com/example/quiz/Login.java +++ b/app/src/main/java/com/example/quiz/Login.java @@ -1,25 +1,15 @@ package com.example.quiz; -import android.app.Activity; -import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import android.provider.Settings; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; -import android.widget.Toolbar; import com.example.quiz.databinding.FragmentLoginBinding; import com.example.quiz.utils.SharedPrefsHelper; @@ -73,27 +63,25 @@ public class Login extends Fragment { binding.loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if(binding.userNameInput.getText().toString().isEmpty()){ - binding.userNameInput.setError("Le nom d'utilisateur est obligatoire"); - binding.userNameInput.requestFocus(); - return; - } - if(binding.passwordInput.getText().toString().isEmpty()){ - binding.passwordInput.setError("Le mot de passe est obligatoire"); - binding.passwordInput.requestFocus(); - return; - } - if(binding.passwordInput.getText().toString().length() < 6){ - binding.passwordInput.setError("Le mot de passe doit contenir au moins 6 caractères "); - binding.passwordInput.requestFocus(); - return; - } + prefsHelper = SharedPrefsHelper.getInstance(getContext()); - prefsHelper.save("username", binding.userNameInput.getText().toString()); FragmentManager fragmentManager = getParentFragmentManager(); - ListOfReunions reunions = ListOfReunions.newInstance(binding.userNameInput.getText().toString()); + ListOfReunions reunions = ListOfReunions.newInstance(""); fragmentManager.beginTransaction() .replace(R.id.nav_host_fragment_content_main, reunions) + .addToBackStack(null) + .commit(); + } + }); + + binding.caisse.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Caisse caisse = Caisse.newInstance(); + FragmentManager fragmentManager = getParentFragmentManager(); + fragmentManager.beginTransaction() + .replace(R.id.nav_host_fragment_content_main, caisse) + .addToBackStack(null) .commit(); } }); diff --git a/app/src/main/java/com/example/quiz/PageQuiz.java b/app/src/main/java/com/example/quiz/PageQuiz.java index e9f7e29..a7f444b 100644 --- a/app/src/main/java/com/example/quiz/PageQuiz.java +++ b/app/src/main/java/com/example/quiz/PageQuiz.java @@ -1,22 +1,29 @@ package com.example.quiz; import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; import android.os.Bundle; -import com.anggastudio.printama.Pref; -import com.anggastudio.printama.Printama; -import com.example.quiz.utils.BluetoothUtils; +import com.example.quiz.data.model.dtos.auth.LoginPayload; +import com.example.quiz.data.model.dtos.auth.LoginResponse; +import com.example.quiz.utils.Result; import com.example.quiz.utils.SessionManager; import com.example.quiz.utils.SharedPrefsHelper; +import com.example.quiz.viewModel.LoginViewModel; import com.google.android.material.snackbar.Snackbar; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.os.Handler; +import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; +import android.widget.TextView; import android.widget.Toast; -import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; @@ -29,7 +36,10 @@ import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint public class PageQuiz extends AppCompatActivity { + LoginViewModel viewModel; private SessionManager sessionManager; + + private AlertDialog dialog; private Handler handler = new Handler(); private Runnable checkRunnable; @@ -38,48 +48,15 @@ public class PageQuiz extends AppCompatActivity { private SharedPrefsHelper prefsHelper; - private void requestPermission(){ - Pref.init(getApplicationContext()); - if (BluetoothUtils.needsBluetoothPermissions()) { - if (!BluetoothUtils.hasBluetoothPermission(getApplicationContext())) { - // Demande la permission si non accordée - BluetoothUtils.requestBluetoothPermission(this); - return; // arrête ici, la popup va apparaître - } - } - - // 2️⃣ Permission OK, on peut afficher la liste - try { - Printama printama = Printama.with(getApplicationContext()); - if(!printama.isConnected()){ - BluetoothUtils.showPrinterList(getApplicationContext(), this); - } - } catch (SecurityException e) { - Toast.makeText(getApplicationContext(), - "Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show(); - } - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - requestPermission(); binding = ActivityPageQuizBinding.inflate(getLayoutInflater()); + _showPinDialog(); setContentView(binding.getRoot()); sessionManager = new SessionManager(); - - // Vérification périodique - checkRunnable = new Runnable() { - @Override - public void run() { - if (sessionManager.isExpired()) { - Toast.makeText(getApplicationContext(), "I'm herer", Toast.LENGTH_LONG).show(); - } else { - handler.postDelayed(this, 60 * 1000); - } - } - }; - handler.postDelayed(checkRunnable, 60 * 1000); + prefsHelper = SharedPrefsHelper.getInstance(getApplicationContext()); + viewModel = new ViewModelProvider(this).get(LoginViewModel.class); setSupportActionBar(binding.toolbar); binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29")); binding.fab.setOnClickListener(new View.OnClickListener() { @@ -90,22 +67,97 @@ public class PageQuiz extends AppCompatActivity { .setAction("Action", null).show(); } }); - prefsHelper = SharedPrefsHelper.getInstance(getApplicationContext()); - FragmentManager fragmentManager = getSupportFragmentManager(); + } - if(prefsHelper.get("username") != null){ - ListOfReunions reunions = ListOfReunions.newInstance(prefsHelper.get("username")); - fragmentManager - .beginTransaction() - .replace(R.id.nav_host_fragment_content_main, reunions) - .commit(); - }else{ - Login login = Login.newInstance(); - fragmentManager - .beginTransaction() - .replace(R.id.nav_host_fragment_content_main, login) - .commit(); + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + + if (dialog != null && dialog.isShowing()) { + return super.dispatchTouchEvent(ev); } + + + if(sessionManager.isExpired()){ + _showPinDialog(); + return true; + } + sessionManager.updateLastExpiredDate(); + return super.dispatchTouchEvent(ev); + } + + void _showPinDialog(){ + LayoutInflater inflater = getLayoutInflater(); + View view = inflater.inflate(R.layout.pin_view, null); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setView(view); + builder.setCancelable(false); + + dialog = builder.create(); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + +// Bouton OK + view.findViewById(R.id.pin_validate).setOnClickListener(v -> { + TextView pin = view.findViewById(R.id.pin); + if(pin.getText().toString().isEmpty()){ + pin.setError("Entrez le pin!"); + return; + } + if(pin.getText().toString().length() != 5){ + pin.setError("Le pin doit contenir 5 chiffres!"); + return; + } + LoginPayload loginPayload = new LoginPayload( + pin.getText().toString() + ); + viewModel.login(loginPayload).observe(this, new Observer>() { + @Override + public void onChanged(Result loginResponseResult) { + switch (loginResponseResult.status){ + case LOADING: + Toast.makeText(getApplicationContext(), "Loading",Toast.LENGTH_SHORT).show(); + break; + case ERROR: + pin.setError("Pin incorrect"); + break; + case SUCCESS: + loginSuccess(loginResponseResult.data); + sessionManager.updateLastExpiredDate(); + dialog.dismiss(); + break; + } + } + }); + }); + + dialog.show(); + } + + + private void loginSuccess(LoginResponse loginResponse){ + prefsHelper.save("firstName", loginResponse.getPrenom()); + prefsHelper.save("lastName", loginResponse.getNom()); + prefsHelper.save("profile", loginResponse.getProfile()); + prefsHelper.save("limit", String.valueOf(loginResponse.getLimiteSuperieure())); + } + + @Override + protected void onResume() { + super.onResume(); + handler = new Handler(); + checkRunnable = new Runnable() { + @Override + public void run() { + if (sessionManager.isExpired()) { + if(dialog != null && !dialog.isShowing()){ + _showPinDialog(); + } + } else { + handler.postDelayed(this, 10); // check every second + } + } + }; + handler.postDelayed(checkRunnable, 10); } @Override diff --git a/app/src/main/java/com/example/quiz/WinTicket.java b/app/src/main/java/com/example/quiz/WinTicket.java new file mode 100644 index 0000000..6530dcc --- /dev/null +++ b/app/src/main/java/com/example/quiz/WinTicket.java @@ -0,0 +1,69 @@ +package com.example.quiz; + +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.example.quiz.databinding.FragmentWinTicketBinding; +import com.google.android.material.appbar.MaterialToolbar; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link WinTicket#newInstance} factory method to + * create an instance of this fragment. + */ +public class WinTicket extends Fragment { + + FragmentWinTicketBinding binding; + + + public WinTicket() { + // Required empty public constructor + } + public static WinTicket newInstance() { + WinTicket fragment = new WinTicket(); + Bundle args = new Bundle(); + + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentWinTicketBinding.inflate(inflater, container, false); + return binding.getRoot(); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + binding.winTicketBtnBack.setOnClickListener(v -> { + getActivity().onBackPressed(); + }); + } + + @Override + public void onResume() { + super.onResume(); + AppCompatActivity activity = (AppCompatActivity) getActivity(); + if (activity != null) { + activity.getSupportActionBar(); + MaterialToolbar toolbar = activity.findViewById(R.id.toolbar); + if(toolbar!= null){ + toolbar.setTitle("Ticket Gagnant"); + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginPayload.java b/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginPayload.java new file mode 100644 index 0000000..9a4033b --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginPayload.java @@ -0,0 +1,17 @@ +package com.example.quiz.data.model.dtos.auth; + +public class LoginPayload { + private String pin; + + public LoginPayload(String pin) { + this.pin = pin; + } + + public String getPin() { + return pin; + } + + public void setPin(String pin) { + this.pin = pin; + } +} diff --git a/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginResponse.java b/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginResponse.java new file mode 100644 index 0000000..3e10d86 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/model/dtos/auth/LoginResponse.java @@ -0,0 +1,237 @@ +package com.example.quiz.data.model.dtos.auth; + +public class LoginResponse { + private int id; + private String code; + private String profile; + private String principalCode; + private String caisseProfile; + private String statut; + private String zone; + private String kiosk; + private String fonction; + private String dateEmbauche; + private String derniereConnexion; + private String nom; + private String prenom; + private String autresNom; + private String dateNaissance; + private String lieuNaissance; + private String ville; + private String adresse; + private String cni; + private double limiteInferieure; + private double limiteSuperieure; + private double limiteParTransaction; + private String autreAdresse1; + + public LoginResponse(int id, String code, String profile, String principalCode, String caisseProfile, String statut, String zone, String kiosk, String fonction, String dateEmbauche, String derniereConnexion, String nom, String prenom, String autresNom, String dateNaissance, String lieuNaissance, String ville, String adresse, String cni, double limiteInferieure, double limiteSuperieure, double limiteParTransaction, String autreAdresse1) { + this.id = id; + this.code = code; + this.profile = profile; + this.principalCode = principalCode; + this.caisseProfile = caisseProfile; + this.statut = statut; + this.zone = zone; + this.kiosk = kiosk; + this.fonction = fonction; + this.dateEmbauche = dateEmbauche; + this.derniereConnexion = derniereConnexion; + this.nom = nom; + this.prenom = prenom; + this.autresNom = autresNom; + this.dateNaissance = dateNaissance; + this.lieuNaissance = lieuNaissance; + this.ville = ville; + this.adresse = adresse; + this.cni = cni; + this.limiteInferieure = limiteInferieure; + this.limiteSuperieure = limiteSuperieure; + this.limiteParTransaction = limiteParTransaction; + this.autreAdresse1 = autreAdresse1; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getProfile() { + return profile; + } + + public void setProfile(String profile) { + this.profile = profile; + } + + public String getPrincipalCode() { + return principalCode; + } + + public void setPrincipalCode(String principalCode) { + this.principalCode = principalCode; + } + + public String getCaisseProfile() { + return caisseProfile; + } + + public void setCaisseProfile(String caisseProfile) { + this.caisseProfile = caisseProfile; + } + + public String getStatut() { + return statut; + } + + public void setStatut(String statut) { + this.statut = statut; + } + + public String getZone() { + return zone; + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getKiosk() { + return kiosk; + } + + public void setKiosk(String kiosk) { + this.kiosk = kiosk; + } + + public String getFonction() { + return fonction; + } + + public void setFonction(String fonction) { + this.fonction = fonction; + } + + public String getDateEmbauche() { + return dateEmbauche; + } + + public void setDateEmbauche(String dateEmbauche) { + this.dateEmbauche = dateEmbauche; + } + + public String getDerniereConnexion() { + return derniereConnexion; + } + + public void setDerniereConnexion(String derniereConnexion) { + this.derniereConnexion = derniereConnexion; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public String getPrenom() { + return prenom; + } + + public void setPrenom(String prenom) { + this.prenom = prenom; + } + + public String getAutresNom() { + return autresNom; + } + + public void setAutresNom(String autresNom) { + this.autresNom = autresNom; + } + + public String getDateNaissance() { + return dateNaissance; + } + + public void setDateNaissance(String dateNaissance) { + this.dateNaissance = dateNaissance; + } + + public String getLieuNaissance() { + return lieuNaissance; + } + + public void setLieuNaissance(String lieuNaissance) { + this.lieuNaissance = lieuNaissance; + } + + public String getVille() { + return ville; + } + + public void setVille(String ville) { + this.ville = ville; + } + + public String getAdresse() { + return adresse; + } + + public void setAdresse(String adresse) { + this.adresse = adresse; + } + + public String getCni() { + return cni; + } + + public void setCni(String cni) { + this.cni = cni; + } + + public double getLimiteInferieure() { + return limiteInferieure; + } + + public void setLimiteInferieure(double limiteInferieure) { + this.limiteInferieure = limiteInferieure; + } + + public double getLimiteSuperieure() { + return limiteSuperieure; + } + + public void setLimiteSuperieure(double limiteSuperieure) { + this.limiteSuperieure = limiteSuperieure; + } + + public double getLimiteParTransaction() { + return limiteParTransaction; + } + + public void setLimiteParTransaction(double limiteParTransaction) { + this.limiteParTransaction = limiteParTransaction; + } + + public String getAutreAdresse1() { + return autreAdresse1; + } + + public void setAutreAdresse1(String autreAdresse1) { + this.autreAdresse1 = autreAdresse1; + } +} diff --git a/app/src/main/java/com/example/quiz/data/remote/ApiClient.java b/app/src/main/java/com/example/quiz/data/remote/ApiClient.java index 9839be5..32df308 100644 --- a/app/src/main/java/com/example/quiz/data/remote/ApiClient.java +++ b/app/src/main/java/com/example/quiz/data/remote/ApiClient.java @@ -20,7 +20,7 @@ import retrofit2.converter.gson.GsonConverterFactory; @Module @InstallIn(SingletonComponent.class) public class ApiClient { - private static final String BASE_URL = "https://performances-leeds-operations-continued.trycloudflare.com/api/v1/"; + private static final String BASE_URL = "https://970b6b1c025c.ngrok-free.app/api/v1/"; @Provides @Singleton diff --git a/app/src/main/java/com/example/quiz/data/remote/ApiService.java b/app/src/main/java/com/example/quiz/data/remote/ApiService.java index 9c429a3..588a813 100644 --- a/app/src/main/java/com/example/quiz/data/remote/ApiService.java +++ b/app/src/main/java/com/example/quiz/data/remote/ApiService.java @@ -3,6 +3,8 @@ package com.example.quiz.data.remote; import com.example.quiz.data.model.Course; import com.example.quiz.data.model.Pari; import com.example.quiz.data.model.Reunion; +import com.example.quiz.data.model.dtos.auth.LoginPayload; +import com.example.quiz.data.model.dtos.auth.LoginResponse; import java.util.List; @@ -21,4 +23,7 @@ public interface ApiService { @POST("pari") Call createPari(@Body Pari pari); + + @POST("auth/agent/login") + Call login(@Body LoginPayload loginPayload); } diff --git a/app/src/main/java/com/example/quiz/data/repository/LoginRepository.java b/app/src/main/java/com/example/quiz/data/repository/LoginRepository.java new file mode 100644 index 0000000..0af2f47 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/repository/LoginRepository.java @@ -0,0 +1,44 @@ +package com.example.quiz.data.repository; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import com.example.quiz.data.model.dtos.auth.LoginPayload; +import com.example.quiz.data.model.dtos.auth.LoginResponse; +import com.example.quiz.data.remote.ApiService; +import com.example.quiz.utils.Result; + +import javax.inject.Inject; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class LoginRepository { + private ApiService apiService; + @Inject + public LoginRepository(ApiService apiService) { + this.apiService = apiService; + } + + public LiveData> login(LoginPayload loginPayload){ + MutableLiveData> liveLogin = new MutableLiveData>(); + liveLogin.setValue(Result.loading()); + apiService.login(loginPayload).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful()){ + liveLogin.postValue(Result.success(response.body())); + }else{ + liveLogin.postValue(Result.error(response.message())); + } + } + + @Override + public void onFailure(Call call, Throwable throwable) { + liveLogin.postValue(Result.error(throwable.getMessage())); + } + }); + return liveLogin; + } +} diff --git a/app/src/main/java/com/example/quiz/utils/SessionManager.java b/app/src/main/java/com/example/quiz/utils/SessionManager.java index 439f935..1cea9af 100644 --- a/app/src/main/java/com/example/quiz/utils/SessionManager.java +++ b/app/src/main/java/com/example/quiz/utils/SessionManager.java @@ -5,19 +5,20 @@ import java.time.LocalDateTime; public class SessionManager { // 10 minutes en millisecondes - private static final long sessionExpiredTime = 60 * 1000; + private static final long sessionExpiredTime = 10 * 60 * 1000; private LocalDateTime lastExpiredDate; - public SessionManager() { - updateLastExpiredDate(); - } + public SessionManager() {} public void updateLastExpiredDate() { lastExpiredDate = LocalDateTime.now(); } public boolean isExpired() { + if (lastExpiredDate == null) { + return true; + } // Vérifie si le temps écoulé depuis lastExpiredDate > sessionExpiredTime Duration elapsed = Duration.between(lastExpiredDate, LocalDateTime.now()); return elapsed.toMillis() > sessionExpiredTime; diff --git a/app/src/main/java/com/example/quiz/viewModel/LoginViewModel.java b/app/src/main/java/com/example/quiz/viewModel/LoginViewModel.java new file mode 100644 index 0000000..3449c4a --- /dev/null +++ b/app/src/main/java/com/example/quiz/viewModel/LoginViewModel.java @@ -0,0 +1,27 @@ +package com.example.quiz.viewModel; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; + +import com.example.quiz.data.model.dtos.auth.LoginPayload; +import com.example.quiz.data.model.dtos.auth.LoginResponse; +import com.example.quiz.data.repository.LoginRepository; +import com.example.quiz.utils.Result; + +import javax.inject.Inject; + +import dagger.hilt.android.lifecycle.HiltViewModel; + +@HiltViewModel +public class LoginViewModel extends ViewModel { + LoginRepository loginRepository; + + @Inject + public LoginViewModel(LoginRepository loginRepository) { + this.loginRepository = loginRepository; + } + + public LiveData> login(LoginPayload loginPayload){ + return loginRepository.login(loginPayload); + } +} diff --git a/app/src/main/res/drawable/button_transparent.xml b/app/src/main/res/drawable/button_transparent.xml new file mode 100644 index 0000000..4072e78 --- /dev/null +++ b/app/src/main/res/drawable/button_transparent.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/drawable/camera.xml b/app/src/main/res/drawable/camera.xml new file mode 100644 index 0000000..d4da7be --- /dev/null +++ b/app/src/main/res/drawable/camera.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/drawable/edittext_border.xml b/app/src/main/res/drawable/edittext_border.xml index 46e54c1..a4fd278 100644 --- a/app/src/main/res/drawable/edittext_border.xml +++ b/app/src/main/res/drawable/edittext_border.xml @@ -1,7 +1,7 @@ - + + + + + + + diff --git a/app/src/main/res/drawable/hashtag.xml b/app/src/main/res/drawable/hashtag.xml new file mode 100644 index 0000000..950dcac --- /dev/null +++ b/app/src/main/res/drawable/hashtag.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/horse_head_svgrepo_com.xml b/app/src/main/res/drawable/horse_head_svgrepo_com.xml new file mode 100644 index 0000000..a912dcb --- /dev/null +++ b/app/src/main/res/drawable/horse_head_svgrepo_com.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/rounded_button_green.xml b/app/src/main/res/drawable/rounded_button_green.xml index b4b634d..f96eb08 100644 --- a/app/src/main/res/drawable/rounded_button_green.xml +++ b/app/src/main/res/drawable/rounded_button_green.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/settings_icon.xml b/app/src/main/res/drawable/settings_icon.xml new file mode 100644 index 0000000..fc8fd2a --- /dev/null +++ b/app/src/main/res/drawable/settings_icon.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/tpe.xml b/app/src/main/res/drawable/tpe.xml new file mode 100644 index 0000000..fa1683a --- /dev/null +++ b/app/src/main/res/drawable/tpe.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/x_background.xml b/app/src/main/res/drawable/x_background.xml new file mode 100644 index 0000000..2d79c26 --- /dev/null +++ b/app/src/main/res/drawable/x_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/layout/fragment_annulation_ticket.xml b/app/src/main/res/layout/fragment_annulation_ticket.xml new file mode 100644 index 0000000..4c0efe9 --- /dev/null +++ b/app/src/main/res/layout/fragment_annulation_ticket.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 35a4061..3565dd6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,8 @@ PMU Settings Solde + SOLDE + TICKET GAGNANT Derniers paris Autres Solde par course @@ -71,4 +73,11 @@ Hello blank fragment Coefficient Tout ordre + Entrez le pin + Confirmation Pari + non + oui + PMU + CAISSE + PARAMERES\n \ No newline at end of file