diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7671da8..6e22948 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -90,6 +90,10 @@
+
+
diff --git a/app/src/main/java/com/example/bdkipoc/bantuan/BantuanActivity.java b/app/src/main/java/com/example/bdkipoc/bantuan/BantuanActivity.java
index c1b41c2..db50b89 100644
--- a/app/src/main/java/com/example/bdkipoc/bantuan/BantuanActivity.java
+++ b/app/src/main/java/com/example/bdkipoc/bantuan/BantuanActivity.java
@@ -114,9 +114,10 @@ public class BantuanActivity extends AppCompatActivity {
}
if (btnForm != null) {
- btnForm.setOnClickListener(v ->
- android.widget.Toast.makeText(this, "Form Bantuan akan segera tersedia",
- android.widget.Toast.LENGTH_SHORT).show());
+ btnForm.setOnClickListener(v -> {
+ Intent intent = new Intent(this, BantuanFormActivity.class);
+ startActivity(intent);
+ });
}
if (btnWhatsApp != null) {
diff --git a/app/src/main/java/com/example/bdkipoc/bantuan/BantuanFormActivity.java b/app/src/main/java/com/example/bdkipoc/bantuan/BantuanFormActivity.java
new file mode 100644
index 0000000..9eaf291
--- /dev/null
+++ b/app/src/main/java/com/example/bdkipoc/bantuan/BantuanFormActivity.java
@@ -0,0 +1,552 @@
+package com.example.bdkipoc.bantuan;
+
+import android.app.DatePickerDialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+
+import com.example.bdkipoc.R;
+import com.example.bdkipoc.LoginActivity;
+
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class BantuanFormActivity extends AppCompatActivity {
+
+ // UI Components
+ private EditText etTerminalId, etNomorTelepon, etDeskripsiMasalah;
+ private Spinner spinnerTanggalKejadian, spinnerJenisMasalah;
+ private LinearLayout uploadContainer;
+ private TextView uploadText;
+ private Button btnKirim;
+ private LinearLayout backNavigation;
+
+ // Data
+ private String selectedDate = "";
+ private String selectedFileName = "";
+ private Uri selectedFileUri = null;
+ private ExecutorService executor = Executors.newSingleThreadExecutor();
+ private Handler mainHandler = new Handler(Looper.getMainLooper());
+
+ // File picker launcher
+ private ActivityResultLauncher filePickerLauncher;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Check authentication
+ if (!LoginActivity.isLoggedIn(this)) {
+ LoginActivity.logout(this);
+ return;
+ }
+
+ setContentView(R.layout.activity_bantuan_form);
+
+ initViews();
+ setupSpinners();
+ setupListeners();
+ setupFilePicker();
+ loadUserData();
+
+ // Initialize button state
+ updateButtonState();
+ }
+
+ private void initViews() {
+ // Form fields
+ etTerminalId = findViewById(R.id.et_terminal_id);
+ etNomorTelepon = findViewById(R.id.et_nomor_telepon);
+ etDeskripsiMasalah = findViewById(R.id.et_deskripsi_masalah);
+
+ // Spinners
+ spinnerTanggalKejadian = findViewById(R.id.spinner_tanggal_kejadian);
+ spinnerJenisMasalah = findViewById(R.id.spinner_jenis_masalah);
+
+ // Upload section
+ uploadContainer = findViewById(R.id.upload_container);
+ uploadText = findViewById(R.id.upload_text);
+
+ // Buttons
+ btnKirim = findViewById(R.id.btn_kirim);
+ backNavigation = findViewById(R.id.back_navigation);
+ }
+
+ private void setupSpinners() {
+ // Setup Date Spinner with date picker
+ String[] dateOptions = {"Pilih Tanggal Kejadian", "Pilih dari kalender"};
+ ArrayAdapter dateAdapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, dateOptions);
+ dateAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerTanggalKejadian.setAdapter(dateAdapter);
+
+ // Setup Issue Type Spinner
+ String[] issueTypes = {
+ "Pilih Jenis Masalah",
+ "Transaksi gagal tapi saldo terpotong",
+ "QRIS tidak terbaca",
+ "EDC tidak merespon / hang",
+ "Gagal cetak struk",
+ "Masalah koneksi internet",
+ "Error pada aplikasi",
+ "Masalah settlement",
+ "Kartu tidak terbaca",
+ "Printer bermasalah",
+ "Lainnya"
+ };
+ ArrayAdapter issueAdapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, issueTypes);
+ issueAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerJenisMasalah.setAdapter(issueAdapter);
+ }
+
+ private void setupListeners() {
+ // Back navigation
+ if (backNavigation != null) {
+ backNavigation.setOnClickListener(v -> onBackPressed());
+ }
+
+ // Date spinner listener
+ spinnerTanggalKejadian.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(android.widget.AdapterView> parent, View view, int position, long id) {
+ if (position == 1) { // "Pilih dari kalender"
+ showDatePicker();
+ }
+ updateButtonState();
+ }
+
+ @Override
+ public void onNothingSelected(android.widget.AdapterView> parent) {}
+ });
+
+ // Issue type spinner listener
+ spinnerJenisMasalah.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(android.widget.AdapterView> parent, View view, int position, long id) {
+ updateButtonState();
+ }
+
+ @Override
+ public void onNothingSelected(android.widget.AdapterView> parent) {}
+ });
+
+ // Text watchers for EditText fields
+ setupTextWatchers();
+
+ // Upload container listener
+ if (uploadContainer != null) {
+ uploadContainer.setOnClickListener(v -> openFilePicker());
+ }
+
+ // Submit button listener
+ if (btnKirim != null) {
+ btnKirim.setOnClickListener(v -> {
+ if (btnKirim.isEnabled()) {
+ submitForm();
+ }
+ });
+ }
+ }
+
+ private void setupTextWatchers() {
+ android.text.TextWatcher textWatcher = new android.text.TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(android.text.Editable s) {
+ updateButtonState();
+ }
+ };
+
+ if (etTerminalId != null) {
+ etTerminalId.addTextChangedListener(textWatcher);
+ }
+ if (etNomorTelepon != null) {
+ etNomorTelepon.addTextChangedListener(textWatcher);
+ }
+ if (etDeskripsiMasalah != null) {
+ etDeskripsiMasalah.addTextChangedListener(textWatcher);
+ }
+ }
+
+ private void updateButtonState() {
+ if (btnKirim == null) return;
+
+ boolean isFormValid = checkFormValidity();
+
+ if (isFormValid) {
+ // Active state - Red background
+ btnKirim.setBackgroundResource(R.drawable.button_active_background);
+ btnKirim.setTextColor(getResources().getColor(android.R.color.white));
+ btnKirim.setEnabled(true);
+ } else {
+ // Inactive state - Gray background
+ btnKirim.setBackgroundResource(R.drawable.button_inactive_background);
+ btnKirim.setTextColor(getResources().getColor(android.R.color.darker_gray));
+ btnKirim.setEnabled(false);
+ }
+ }
+
+ private boolean checkFormValidity() {
+ // Check if all required fields have values
+ boolean hasTerminalId = etTerminalId != null && !etTerminalId.getText().toString().trim().isEmpty();
+ boolean hasPhoneNumber = etNomorTelepon != null && !etNomorTelepon.getText().toString().trim().isEmpty();
+ boolean hasDate = !selectedDate.isEmpty();
+ boolean hasIssueType = spinnerJenisMasalah != null && spinnerJenisMasalah.getSelectedItemPosition() > 0;
+ boolean hasDescription = etDeskripsiMasalah != null && !etDeskripsiMasalah.getText().toString().trim().isEmpty();
+
+ return hasTerminalId && hasPhoneNumber && hasDate && hasIssueType && hasDescription;
+ }
+
+ private void setupFilePicker() {
+ filePickerLauncher = registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ if (result.getResultCode() == RESULT_OK && result.getData() != null) {
+ selectedFileUri = result.getData().getData();
+ if (selectedFileUri != null) {
+ selectedFileName = getFileName(selectedFileUri);
+ if (uploadText != null) {
+ uploadText.setText(selectedFileName);
+ uploadText.setTextColor(getResources().getColor(android.R.color.black));
+ }
+ }
+ }
+ });
+ }
+
+ private void loadUserData() {
+ try {
+ JSONObject userData = LoginActivity.getUserDataAsJson(this);
+ if (userData != null) {
+ // Auto-fill phone number if available
+ String phone = userData.optString("phone", userData.optString("mobile", ""));
+ if (!phone.isEmpty() && etNomorTelepon != null) {
+ etNomorTelepon.setText(phone);
+ }
+
+ // Auto-fill terminal ID if available
+ String terminalId = userData.optString("terminal_id", userData.optString("tid", ""));
+ if (!terminalId.isEmpty() && etTerminalId != null) {
+ etTerminalId.setText(terminalId);
+ }
+ }
+ } catch (Exception e) {
+ // Silent fail - user can fill manually
+ }
+
+ // Update button state after loading data
+ updateButtonState();
+ }
+
+ private void showDatePicker() {
+ Calendar calendar = Calendar.getInstance();
+ DatePickerDialog datePickerDialog = new DatePickerDialog(
+ this,
+ (view, year, month, dayOfMonth) -> {
+ Calendar selectedCalendar = Calendar.getInstance();
+ selectedCalendar.set(year, month, dayOfMonth);
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault());
+ selectedDate = dateFormat.format(selectedCalendar.getTime());
+
+ // Update spinner to show selected date
+ String[] updatedOptions = {"Pilih Tanggal Kejadian", selectedDate};
+ ArrayAdapter updatedAdapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, updatedOptions);
+ updatedAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerTanggalKejadian.setAdapter(updatedAdapter);
+ spinnerTanggalKejadian.setSelection(1);
+
+ // Update button state after date selection
+ updateButtonState();
+ },
+ calendar.get(Calendar.YEAR),
+ calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH)
+ );
+
+ // Set max date to today
+ datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());
+ datePickerDialog.show();
+ }
+
+ private void openFilePicker() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("*/*");
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Add multiple MIME types for different file types
+ String[] mimeTypes = {"image/*", "application/pdf", "text/*"};
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
+
+ try {
+ filePickerLauncher.launch(Intent.createChooser(intent, "Pilih File Pendukung"));
+ } catch (Exception e) {
+ Toast.makeText(this, "Error opening file picker: " + e.getMessage(),
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private String getFileName(Uri uri) {
+ String fileName = "File terpilih";
+ try {
+ android.database.Cursor cursor = getContentResolver().query(uri, null, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ int nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME);
+ if (nameIndex != -1) {
+ fileName = cursor.getString(nameIndex);
+ }
+ cursor.close();
+ }
+ } catch (Exception e) {
+ // Return default name if error
+ }
+ return fileName;
+ }
+
+ private void submitForm() {
+ if (!validateForm()) {
+ return;
+ }
+
+ // Disable button and show loading
+ btnKirim.setEnabled(false);
+ btnKirim.setText("Mengirim...");
+
+ // Prepare form data
+ String terminalId = etTerminalId.getText().toString().trim();
+ String nomorTelepon = etNomorTelepon.getText().toString().trim();
+ String deskripsiMasalah = etDeskripsiMasalah.getText().toString().trim();
+ String jenisMasalah = spinnerJenisMasalah.getSelectedItem().toString();
+
+ submitToAPI(terminalId, nomorTelepon, selectedDate, jenisMasalah, deskripsiMasalah);
+ }
+
+ private boolean validateForm() {
+ boolean isValid = true;
+
+ // Validate Terminal ID
+ if (etTerminalId.getText().toString().trim().isEmpty()) {
+ etTerminalId.setError("Terminal ID wajib diisi");
+ isValid = false;
+ }
+
+ // Validate Phone Number
+ if (etNomorTelepon.getText().toString().trim().isEmpty()) {
+ etNomorTelepon.setError("Nomor telepon wajib diisi");
+ isValid = false;
+ }
+
+ // Validate Date
+ if (selectedDate.isEmpty()) {
+ Toast.makeText(this, "Pilih tanggal kejadian", Toast.LENGTH_SHORT).show();
+ isValid = false;
+ }
+
+ // Validate Issue Type
+ if (spinnerJenisMasalah.getSelectedItemPosition() == 0) {
+ Toast.makeText(this, "Pilih jenis masalah", Toast.LENGTH_SHORT).show();
+ isValid = false;
+ }
+
+ // Validate Description
+ if (etDeskripsiMasalah.getText().toString().trim().isEmpty()) {
+ etDeskripsiMasalah.setError("Deskripsi masalah wajib diisi");
+ isValid = false;
+ }
+
+ return isValid;
+ }
+
+ private void submitToAPI(String terminalId, String nomorTelepon, String tanggalKejadian,
+ String jenisMasalah, String deskripsiMasalah) {
+
+ String authToken = LoginActivity.getToken(this);
+ if (authToken == null || authToken.isEmpty()) {
+ mainHandler.post(() -> {
+ btnKirim.setEnabled(true);
+ btnKirim.setText("Kirim Sekarang");
+ LoginActivity.logout(this);
+ });
+ return;
+ }
+
+ executor.execute(() -> {
+ HttpURLConnection connection = null;
+ try {
+ URL url = new URL("https://be-edc.msvc.app/tickets/create");
+ connection = (HttpURLConnection) url.openConnection();
+
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("Authorization", "Bearer " + authToken);
+ connection.setDoOutput(true);
+ connection.setConnectTimeout(15000);
+ connection.setReadTimeout(15000);
+
+ // Create JSON payload
+ JSONObject payload = new JSONObject();
+ payload.put("terminal_id", terminalId);
+ payload.put("phone_number", nomorTelepon);
+ payload.put("incident_date", tanggalKejadian);
+ payload.put("issue_type", jenisMasalah);
+ payload.put("description", deskripsiMasalah);
+
+ // Add user info
+ try {
+ JSONObject userData = LoginActivity.getUserDataAsJson(this);
+ if (userData != null) {
+ payload.put("user_name", userData.optString("name", ""));
+ payload.put("user_email", userData.optString("email", ""));
+ }
+ } catch (Exception e) {
+ // Continue without user info
+ }
+
+ // Send request
+ try (OutputStream os = connection.getOutputStream()) {
+ byte[] input = payload.toString().getBytes("utf-8");
+ os.write(input, 0, input.length);
+ }
+
+ int responseCode = connection.getResponseCode();
+
+ // Read response
+ BufferedReader reader;
+ if (responseCode >= 200 && responseCode < 300) {
+ reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ } else {
+ reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
+ }
+
+ StringBuilder response = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+ reader.close();
+
+ // Handle response
+ mainHandler.post(() -> {
+ btnKirim.setEnabled(true);
+ btnKirim.setText("Kirim Sekarang");
+
+ if (responseCode >= 200 && responseCode < 300) {
+ // Success
+ try {
+ JSONObject responseJson = new JSONObject(response.toString());
+ String message = responseJson.optString("message", "Tiket berhasil dibuat");
+
+ Toast.makeText(this, message, Toast.LENGTH_LONG).show();
+
+ // Clear form
+ clearForm();
+
+ // Optionally go back to previous screen
+ // finish();
+
+ } catch (Exception e) {
+ Toast.makeText(this, "Tiket berhasil dikirim!", Toast.LENGTH_LONG).show();
+ clearForm();
+ }
+ } else if (responseCode == 401) {
+ Toast.makeText(this, "Session expired. Please login again.",
+ Toast.LENGTH_LONG).show();
+ LoginActivity.logout(this);
+ } else {
+ // Error
+ try {
+ JSONObject errorJson = new JSONObject(response.toString());
+ String errorMessage = errorJson.optString("message", "Gagal mengirim tiket");
+ Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
+ } catch (Exception e) {
+ Toast.makeText(this, "Gagal mengirim tiket. Error: " + responseCode,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+
+ } catch (Exception e) {
+ mainHandler.post(() -> {
+ btnKirim.setEnabled(true);
+ btnKirim.setText("Kirim Sekarang");
+ Toast.makeText(this, "Network error: " + e.getMessage(),
+ Toast.LENGTH_LONG).show();
+ });
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ });
+ }
+
+ private void clearForm() {
+ if (etTerminalId != null) etTerminalId.setText("");
+ if (etNomorTelepon != null) etNomorTelepon.setText("");
+ if (etDeskripsiMasalah != null) etDeskripsiMasalah.setText("");
+
+ if (spinnerTanggalKejadian != null) spinnerTanggalKejadian.setSelection(0);
+ if (spinnerJenisMasalah != null) spinnerJenisMasalah.setSelection(0);
+
+ selectedDate = "";
+ selectedFileName = "";
+ selectedFileUri = null;
+
+ if (uploadText != null) {
+ uploadText.setText("Pilih di sini");
+ uploadText.setTextColor(getResources().getColor(android.R.color.darker_gray));
+ }
+
+ // Reload user data for next form
+ loadUserData();
+
+ // Update button state after clearing form
+ updateButtonState();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (!LoginActivity.isLoggedIn(this)) {
+ finish();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (executor != null && !executor.isShutdown()) {
+ executor.shutdown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_bantuan_form.xml b/app/src/main/res/layout/activity_bantuan_form.xml
index 3ed78ec..0fd5f80 100644
--- a/app/src/main/res/layout/activity_bantuan_form.xml
+++ b/app/src/main/res/layout/activity_bantuan_form.xml
@@ -6,7 +6,7 @@
android:background="#f5f5f5">
-
+
+ android:gravity="center_vertical"
+ android:clickable="true"
+ android:focusable="true">
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:background="@drawable/button_inactive_background"
+ android:elevation="2dp"
+ android:enabled="false"/>
\ No newline at end of file