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