temp remove Pay any bill from nav menu, added ui for add, delete, edit subs

This commit is contained in:
2025-07-26 18:09:56 +05:00
parent 7499793ff8
commit 86b51fa99b
14 changed files with 1110 additions and 101 deletions

View File

@@ -77,6 +77,11 @@
android:exported="false" android:exported="false"
android:label="Payment Review" android:label="Payment Review"
android:theme="@style/Theme.GridFlow.NoActionBar" /> android:theme="@style/Theme.GridFlow.NoActionBar" />
<activity
android:name=".AddSubscriptionActivity"
android:exported="false"
android:label="Add Subscription"
android:theme="@style/Theme.GridFlow.NoActionBar" />
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"

View File

@@ -0,0 +1,130 @@
package sh.sar.gridflow
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
import sh.sar.gridflow.R
import sh.sar.gridflow.databinding.ActivityAddSubscriptionBinding
class AddSubscriptionActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityAddSubscriptionBinding
private lateinit var drawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAddSubscriptionBinding.inflate(layoutInflater)
setContentView(binding.root)
setupViews()
}
private fun setupViews() {
// Setup toolbar with hamburger menu
setSupportActionBar(binding.toolbar)
supportActionBar?.apply {
title = "Add Subscription"
}
// Setup drawer toggle
drawerToggle = ActionBarDrawerToggle(
this, binding.drawerLayout, binding.toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
binding.drawerLayout.addDrawerListener(drawerToggle)
drawerToggle.syncState()
// Setup navigation
binding.navView.setNavigationItemSelectedListener(this)
// Handle continue button click
binding.btnContinue.setOnClickListener {
val subscriptionNumber = binding.editSubscriptionNumber.text.toString().trim()
val billNumber = binding.editBillNumber.text.toString().trim()
val alias = binding.editAlias.text.toString().trim()
if (validateInputs(subscriptionNumber, billNumber, alias)) {
Toast.makeText(this, "Continue action not implemented yet", Toast.LENGTH_SHORT).show()
}
}
}
private fun validateInputs(subscriptionNumber: String, billNumber: String, alias: String): Boolean {
var isValid = true
if (subscriptionNumber.isEmpty()) {
binding.editSubscriptionNumber.error = "Subscription number is required"
isValid = false
}
if (billNumber.isEmpty()) {
binding.editBillNumber.error = "Bill number is required"
isValid = false
}
if (alias.isEmpty()) {
binding.editAlias.error = "Alias/Description is required"
isValid = false
}
return isValid
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.nav_dashboard -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "dashboard")
startActivity(intent)
finish()
}
R.id.nav_bill_history -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "bill_history")
startActivity(intent)
finish()
}
R.id.nav_subscriptions -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "subscriptions")
startActivity(intent)
finish()
}
R.id.nav_band_rates -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "band_rates")
startActivity(intent)
finish()
}
R.id.nav_pay_any_bill -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "pay_any_bill")
startActivity(intent)
finish()
}
}
binding.drawerLayout.closeDrawer(GravityCompat.START)
return true
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
}

View File

@@ -203,6 +203,7 @@ class LoginActivity : AppCompatActivity() {
private fun handlePayWithoutAccount() { private fun handlePayWithoutAccount() {
Log.d(TAG, "Pay without account button clicked") Log.d(TAG, "Pay without account button clicked")
val intent = Intent(this, PayWithoutAccountActivity::class.java) val intent = Intent(this, PayWithoutAccountActivity::class.java)
intent.putExtra("hide_toolbar", true)
startActivity(intent) startActivity(intent)
} }

View File

@@ -10,6 +10,7 @@ import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
@@ -89,10 +90,15 @@ class MainActivity : AppCompatActivity() {
true true
} }
R.id.nav_pay_any_bill -> { R.id.nav_pay_any_bill -> {
val intent = Intent(this, PayWithoutAccountActivity::class.java) // Let default navigation handle it (will navigate to PayAnyBillFragment)
startActivity(intent) try {
drawerLayout.closeDrawers() navController.navigate(menuItem.itemId)
true menuItem.isChecked = true
drawerLayout.closeDrawers()
true
} catch (e: Exception) {
false
}
} }
else -> { else -> {
// Let the default navigation handle other items // Let the default navigation handle other items
@@ -107,6 +113,30 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
// Handle navigation extras from other activities
handleNavigationIntent(intent)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intent?.let { handleNavigationIntent(it) }
}
private fun handleNavigationIntent(intent: Intent) {
val navigateTo = intent.getStringExtra("navigate_to")
if (navigateTo != null) {
val navController = findNavController(R.id.nav_host_fragment_content_main)
when (navigateTo) {
"dashboard" -> navController.navigate(R.id.nav_dashboard)
"bill_history" -> navController.navigate(R.id.nav_bill_history)
"subscriptions" -> navController.navigate(R.id.nav_subscriptions)
"band_rates" -> navController.navigate(R.id.nav_band_rates)
"pay_any_bill" -> navController.navigate(R.id.nav_pay_any_bill)
}
// Close the drawer
binding.drawerLayout.closeDrawers()
}
} }
private fun initializeNavigationHeader(navView: NavigationView) { private fun initializeNavigationHeader(navView: NavigationView) {

View File

@@ -1,13 +1,19 @@
package sh.sar.gridflow package sh.sar.gridflow
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.GravityCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.navigation.NavigationView
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import sh.sar.gridflow.R
import sh.sar.gridflow.data.BillLookupResponse import sh.sar.gridflow.data.BillLookupResponse
import sh.sar.gridflow.databinding.ActivityPayWithoutAccountBinding import sh.sar.gridflow.databinding.ActivityPayWithoutAccountBinding
import sh.sar.gridflow.network.ApiResult import sh.sar.gridflow.network.ApiResult
@@ -15,11 +21,12 @@ import sh.sar.gridflow.network.FenakaApiService
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
class PayWithoutAccountActivity : AppCompatActivity() { class PayWithoutAccountActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityPayWithoutAccountBinding private var binding: ActivityPayWithoutAccountBinding? = null
private lateinit var apiService: FenakaApiService private lateinit var apiService: FenakaApiService
private var currentBill: BillLookupResponse? = null private var currentBill: BillLookupResponse? = null
private var drawerToggle: ActionBarDrawerToggle? = null
companion object { companion object {
private const val TAG = "PayWithoutAccountActivity" private const val TAG = "PayWithoutAccountActivity"
@@ -33,34 +40,161 @@ class PayWithoutAccountActivity : AppCompatActivity() {
Log.d(TAG, "PayWithoutAccountActivity onCreate") Log.d(TAG, "PayWithoutAccountActivity onCreate")
binding = ActivityPayWithoutAccountBinding.inflate(layoutInflater) // Check if toolbar should be hidden
setContentView(binding.root) val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
if (hideToolbar) {
// Use original layout for login context
binding = ActivityPayWithoutAccountBinding.inflate(layoutInflater)
setContentView(binding!!.root)
binding!!.toolbar.visibility = View.GONE
// Remove margin since toolbar is hidden
val scrollView = findViewById<android.widget.ScrollView>(R.id.scroll_view)
scrollView?.let { view ->
val params = view.layoutParams as androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams
params.topMargin = 0
view.layoutParams = params
}
} else {
// Use drawer layout for menu context
setContentView(R.layout.activity_pay_without_account_drawer)
// Don't use ViewBinding for drawer layout, access views manually
setupDrawer()
}
apiService = FenakaApiService() apiService = FenakaApiService()
setupClickListeners() setupClickListeners()
} }
private fun setupClickListeners() { private fun setupDrawer() {
binding.btnContinue.setOnClickListener { val toolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
handleContinue() setSupportActionBar(toolbar)
supportActionBar?.apply {
title = "Pay Without Account"
} }
binding.btnPay.setOnClickListener { val drawerLayout = findViewById<androidx.drawerlayout.widget.DrawerLayout>(R.id.drawer_layout)
handlePayment() drawerToggle = ActionBarDrawerToggle(
this, drawerLayout, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
drawerLayout.addDrawerListener(drawerToggle!!)
drawerToggle?.syncState()
val navView = findViewById<com.google.android.material.navigation.NavigationView>(R.id.nav_view)
navView.setNavigationItemSelectedListener(this)
}
// Helper methods to access views regardless of layout type
private fun getBillDetailsCard(): com.google.android.material.card.MaterialCardView {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.billDetailsCard
} else {
findViewById(R.id.bill_details_card)
}
}
private fun getInputFieldsLayout(): android.widget.LinearLayout {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.inputFieldsLayout
} else {
findViewById(R.id.input_fields_layout)
}
}
private fun getBillNumberInput(): com.google.android.material.textfield.TextInputEditText {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.etBillNumber
} else {
findViewById(R.id.et_bill_number)
}
}
private fun getSubscriptionNumberInput(): com.google.android.material.textfield.TextInputEditText {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.etSubscriptionNumber
} else {
findViewById(R.id.et_subscription_number)
}
}
private fun getContinueButton(): com.google.android.material.button.MaterialButton {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.btnContinue
} else {
findViewById(R.id.btn_continue)
}
}
// Additional helper methods for views that exist only in the original layout
private fun getTvBillNumber(): android.widget.TextView? {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.tvBillNumber
} else {
findViewById(R.id.tv_bill_number)
}
}
private fun getTvBillStatus(): android.widget.TextView? {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.tvBillStatus
} else {
findViewById(R.id.tv_bill_status)
}
}
private fun getPayButton(): com.google.android.material.button.MaterialButton? {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
return if (hideToolbar) {
binding!!.btnPay
} else {
findViewById(R.id.btn_pay)
}
}
private fun setupClickListeners() {
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
if (hideToolbar) {
// Use ViewBinding for original layout
binding!!.btnContinue.setOnClickListener {
handleContinue()
}
binding!!.btnPay.setOnClickListener {
handlePayment()
}
} else {
// Use findViewById for drawer layout
val btnContinue = findViewById<com.google.android.material.button.MaterialButton>(R.id.btn_continue)
val btnPay = findViewById<com.google.android.material.button.MaterialButton>(R.id.btn_pay)
btnContinue.setOnClickListener {
handleContinue()
}
btnPay.setOnClickListener {
handlePayment()
}
} }
} }
private fun handleContinue() { private fun handleContinue() {
// Check if we're showing the card - if so, hide it and show input fields // Check if we're showing the card - if so, hide it and show input fields
if (binding.billDetailsCard.visibility == View.VISIBLE) { if (getBillDetailsCard().visibility == View.VISIBLE) {
Log.d(TAG, "Hiding bill details card and showing input fields") Log.d(TAG, "Hiding bill details card and showing input fields")
showInputFields() showInputFields()
return return
} }
// Otherwise, perform bill search // Otherwise, perform bill search
val billNumber = binding.etBillNumber.text.toString().trim() val billNumber = getBillNumberInput().text.toString().trim()
val subscriptionNumber = binding.etSubscriptionNumber.text.toString().trim() val subscriptionNumber = getSubscriptionNumberInput().text.toString().trim()
Log.d(TAG, "handleContinue called with bill: $billNumber, subscription: $subscriptionNumber") Log.d(TAG, "handleContinue called with bill: $billNumber, subscription: $subscriptionNumber")
@@ -73,11 +207,11 @@ class PayWithoutAccountActivity : AppCompatActivity() {
} }
private fun showInputFields() { private fun showInputFields() {
binding.inputFieldsLayout.visibility = View.VISIBLE getInputFieldsLayout().visibility = View.VISIBLE
binding.billDetailsCard.visibility = View.GONE getBillDetailsCard().visibility = View.GONE
currentBill = null currentBill = null
// Update button text to Continue when showing input fields // Update button text to Continue when showing input fields
binding.btnContinue.text = "Continue" getContinueButton().text = "Continue"
} }
private fun fetchBillDetails(billNumber: String, subscriptionNumber: String) { private fun fetchBillDetails(billNumber: String, subscriptionNumber: String) {
@@ -149,63 +283,69 @@ class PayWithoutAccountActivity : AppCompatActivity() {
private fun showBillDetails(bill: BillLookupResponse) { private fun showBillDetails(bill: BillLookupResponse) {
// Hide input fields and show bill details // Hide input fields and show bill details
binding.inputFieldsLayout.visibility = View.GONE getInputFieldsLayout().visibility = View.GONE
binding.billDetailsCard.visibility = View.VISIBLE getBillDetailsCard().visibility = View.VISIBLE
// Update button text to Search Another Bill when showing card // Update button text to Search Another Bill when showing card
binding.btnContinue.text = "Search Another Bill" getContinueButton().text = "Search Another Bill"
// Set bill information // Set bill information (only set views that exist in both layouts)
binding.tvBillNumber.text = bill.billNumber getTvBillNumber()?.text = bill.billNumber
binding.tvBillAmount.text = "MVR ${bill.billAmount}" getTvBillStatus()?.text = bill.status.uppercase()
binding.tvBillStatus.text = bill.status.uppercase()
// Set customer information
binding.tvCustomerName.text = bill.customer.name
binding.tvAccountNumber.text = bill.customer.accountNumber
binding.tvPhoneNumber.text = bill.customer.phone
// Set address information
val address = "${bill.subscriptionAddress.property.name}, ${bill.subscriptionAddress.property.street.name}"
binding.tvAddress.text = address
// Set subscription information
binding.tvSubscriptionNumber.text = bill.subscription.subscriptionNumber
binding.tvServiceType.text = if (bill.subscription.serviceId == 1) "Electricity" else "Water"
// Format and set dates
val dueDateFormatted = formatDate(bill.dueDate)
val billDateFormatted = formatDate(bill.billDate)
binding.tvDueDate.text = dueDateFormatted
binding.tvBillDate.text = billDateFormatted
// Set payment status and button // Set payment status and button
val isPaid = bill.status == "paid" val isPaid = bill.status == "paid"
binding.btnPay.isEnabled = !isPaid getPayButton()?.let { payButton ->
binding.btnPay.alpha = if (isPaid) 0.5f else 1.0f payButton.isEnabled = !isPaid
binding.btnPay.text = if (isPaid) "Already Paid" else "Pay MVR ${bill.billAmount}" payButton.alpha = if (isPaid) 0.5f else 1.0f
payButton.text = if (isPaid) "Already Paid" else "Pay MVR ${bill.billAmount}"
}
// Set status color // Set status color based on payment status
when (bill.status.lowercase()) { getTvBillStatus()?.let { statusView ->
"paid" -> { when (bill.status.lowercase()) {
binding.tvBillStatus.setTextColor(getColor(android.R.color.holo_green_dark)) "paid" -> {
} statusView.setTextColor(getColor(android.R.color.holo_green_dark))
"unpaid" -> { }
binding.tvBillStatus.setTextColor(getColor(android.R.color.holo_red_dark)) "unpaid" -> {
} statusView.setTextColor(getColor(android.R.color.holo_red_dark))
else -> { }
binding.tvBillStatus.setTextColor(getColor(android.R.color.holo_orange_dark)) else -> {
statusView.setTextColor(getColor(android.R.color.holo_orange_dark))
}
} }
} }
// Show additional payment details if available // Note: Detailed bill information (customer name, address, etc.)
bill.billPaymentDetails?.let { paymentDetails -> // is only shown in the original layout from login screen
if (paymentDetails.paidAmount.toDoubleOrNull() ?: 0.0 > 0.0) { val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
binding.tvPaidAmount.visibility = View.VISIBLE if (hideToolbar) {
binding.tvPaidAmount.text = "Paid: MVR ${paymentDetails.paidAmount}" // Set detailed information only when using original layout
binding!!.tvBillAmount.text = "MVR ${bill.billAmount}"
if (paymentDetails.pendingAmount.toDoubleOrNull() ?: 0.0 > 0.0) { binding!!.tvCustomerName.text = bill.customer.name
binding.tvPendingAmount.visibility = View.VISIBLE binding!!.tvAccountNumber.text = bill.customer.accountNumber
binding.tvPendingAmount.text = "Pending: MVR ${paymentDetails.pendingAmount}" binding!!.tvPhoneNumber.text = bill.customer.phone
val address = "${bill.subscriptionAddress.property.name}, ${bill.subscriptionAddress.property.street.name}"
binding!!.tvAddress.text = address
binding!!.tvSubscriptionNumber.text = bill.subscription.subscriptionNumber
binding!!.tvServiceType.text = if (bill.subscription.serviceId == 1) "Electricity" else "Water"
val dueDateFormatted = formatDate(bill.dueDate)
val billDateFormatted = formatDate(bill.billDate)
binding!!.tvDueDate.text = dueDateFormatted
binding!!.tvBillDate.text = billDateFormatted
// Show payment details if available
bill.billPaymentDetails?.let { paymentDetails ->
if (paymentDetails.paidAmount.toDoubleOrNull() ?: 0.0 > 0.0) {
binding!!.tvPaidAmount.visibility = View.VISIBLE
binding!!.tvPaidAmount.text = "Paid: MVR ${paymentDetails.paidAmount}"
if (paymentDetails.pendingAmount.toDoubleOrNull() ?: 0.0 > 0.0) {
binding!!.tvPendingAmount.visibility = View.VISIBLE
binding!!.tvPendingAmount.text = "Pending: MVR ${paymentDetails.pendingAmount}"
}
} }
} }
} }
@@ -225,23 +365,23 @@ class PayWithoutAccountActivity : AppCompatActivity() {
private fun validateInput(billNumber: String, subscriptionNumber: String): Boolean { private fun validateInput(billNumber: String, subscriptionNumber: String): Boolean {
if (billNumber.isEmpty()) { if (billNumber.isEmpty()) {
binding.etBillNumber.error = "Bill number is required" getBillNumberInput().error = "Bill number is required"
return false return false
} }
if (subscriptionNumber.isEmpty()) { if (subscriptionNumber.isEmpty()) {
binding.etSubscriptionNumber.error = "Subscription number is required" getSubscriptionNumberInput().error = "Subscription number is required"
return false return false
} }
// Basic validation - you can add more specific validation rules here // Basic validation - you can add more specific validation rules here
if (billNumber.length < 3) { if (billNumber.length < 3) {
binding.etBillNumber.error = "Bill number must be at least 3 characters" getBillNumberInput().error = "Bill number must be at least 3 characters"
return false return false
} }
if (subscriptionNumber.length < 3) { if (subscriptionNumber.length < 3) {
binding.etSubscriptionNumber.error = "Subscription number must be at least 3 characters" getSubscriptionNumberInput().error = "Subscription number must be at least 3 characters"
return false return false
} }
@@ -249,15 +389,81 @@ class PayWithoutAccountActivity : AppCompatActivity() {
} }
private fun setLoading(isLoading: Boolean) { private fun setLoading(isLoading: Boolean) {
binding.btnContinue.isEnabled = !isLoading getContinueButton().isEnabled = !isLoading
binding.btnContinue.text = if (isLoading) "Searching Bill..." else "Continue" getContinueButton().text = if (isLoading) "Searching Bill..." else "Continue"
binding.etBillNumber.isEnabled = !isLoading getBillNumberInput().isEnabled = !isLoading
binding.etSubscriptionNumber.isEnabled = !isLoading getSubscriptionNumberInput().isEnabled = !isLoading
if (isLoading) { if (isLoading) {
binding.billDetailsCard.visibility = View.GONE getBillDetailsCard().visibility = View.GONE
binding.inputFieldsLayout.visibility = View.VISIBLE getInputFieldsLayout().visibility = View.VISIBLE
}
}
override fun onSupportNavigateUp(): Boolean {
onBackPressedDispatcher.onBackPressed()
return true
}
override fun onNavigationItemSelected(item: android.view.MenuItem): Boolean {
when (item.itemId) {
R.id.nav_dashboard -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "dashboard")
startActivity(intent)
finish()
}
R.id.nav_bill_history -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "bill_history")
startActivity(intent)
finish()
}
R.id.nav_subscriptions -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "subscriptions")
startActivity(intent)
finish()
}
R.id.nav_band_rates -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "band_rates")
startActivity(intent)
finish()
}
R.id.nav_pay_any_bill -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra("navigate_to", "pay_any_bill")
startActivity(intent)
finish()
}
}
val drawerLayout = findViewById<androidx.drawerlayout.widget.DrawerLayout>(R.id.drawer_layout)
drawerLayout?.closeDrawer(androidx.core.view.GravityCompat.START)
return true
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
// Check if toolbar is hidden (launched from login)
val hideToolbar = intent.getBooleanExtra("hide_toolbar", false)
if (hideToolbar) {
// If launched from login, go back to login
super.onBackPressed()
} else {
// If launched from main menu, check if drawer is open
val drawerLayout = findViewById<androidx.drawerlayout.widget.DrawerLayout>(R.id.drawer_layout)
if (drawerLayout?.isDrawerOpen(androidx.core.view.GravityCompat.START) == true) {
drawerLayout.closeDrawer(androidx.core.view.GravityCompat.START)
} else {
super.onBackPressed()
}
} }
} }
} }

View File

@@ -7,7 +7,7 @@ import androidx.lifecycle.ViewModel
class PayAnyBillViewModel : ViewModel() { class PayAnyBillViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply { private val _text = MutableLiveData<String>().apply {
value = "Pay Any Bill\n\nComing soon..." value = "Coming Soon"
} }
val text: LiveData<String> = _text val text: LiveData<String> = _text
} }

View File

@@ -9,7 +9,10 @@ import androidx.recyclerview.widget.RecyclerView
import sh.sar.gridflow.data.CustomerSubscription import sh.sar.gridflow.data.CustomerSubscription
import sh.sar.gridflow.databinding.ItemSubscriptionDetailedBinding import sh.sar.gridflow.databinding.ItemSubscriptionDetailedBinding
class DetailedSubscriptionsAdapter : ListAdapter<CustomerSubscription, DetailedSubscriptionsAdapter.SubscriptionViewHolder>(SubscriptionDiffCallback()) { class DetailedSubscriptionsAdapter(
private val onEditClick: (CustomerSubscription) -> Unit,
private val onDeleteClick: (CustomerSubscription) -> Unit
) : ListAdapter<CustomerSubscription, DetailedSubscriptionsAdapter.SubscriptionViewHolder>(SubscriptionDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubscriptionViewHolder {
val binding = ItemSubscriptionDetailedBinding.inflate( val binding = ItemSubscriptionDetailedBinding.inflate(
@@ -21,14 +24,18 @@ class DetailedSubscriptionsAdapter : ListAdapter<CustomerSubscription, DetailedS
} }
override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) { override fun onBindViewHolder(holder: SubscriptionViewHolder, position: Int) {
holder.bind(getItem(position)) holder.bind(getItem(position), onEditClick, onDeleteClick)
} }
class SubscriptionViewHolder( class SubscriptionViewHolder(
private val binding: ItemSubscriptionDetailedBinding private val binding: ItemSubscriptionDetailedBinding
) : RecyclerView.ViewHolder(binding.root) { ) : RecyclerView.ViewHolder(binding.root) {
fun bind(subscription: CustomerSubscription) { fun bind(
subscription: CustomerSubscription,
onEditClick: (CustomerSubscription) -> Unit,
onDeleteClick: (CustomerSubscription) -> Unit
) {
with(binding) { with(binding) {
// Service icon and category // Service icon and category
val serviceIcon = when (subscription.subscription.serviceId) { val serviceIcon = when (subscription.subscription.serviceId) {
@@ -53,13 +60,13 @@ class DetailedSubscriptionsAdapter : ListAdapter<CustomerSubscription, DetailedS
textCustomerName.text = subscription.subscription.customer.name textCustomerName.text = subscription.subscription.customer.name
textCustomerPhone.text = subscription.subscription.customer.phone textCustomerPhone.text = subscription.subscription.customer.phone
// Action buttons - show coming soon toasts // Action buttons
btnEdit.setOnClickListener { btnEdit.setOnClickListener {
Toast.makeText(it.context, "Edit subscription coming soon", Toast.LENGTH_SHORT).show() onEditClick(subscription)
} }
btnDelete.setOnClickListener { btnDelete.setOnClickListener {
Toast.makeText(it.context, "Delete subscription coming soon", Toast.LENGTH_SHORT).show() onDeleteClick(subscription)
} }
} }
} }

View File

@@ -1,5 +1,7 @@
package sh.sar.gridflow.ui.subscriptions package sh.sar.gridflow.ui.subscriptions
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -8,6 +10,10 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import sh.sar.gridflow.AddSubscriptionActivity
import sh.sar.gridflow.data.CustomerSubscription
import sh.sar.gridflow.databinding.DialogDeleteSubscriptionBinding
import sh.sar.gridflow.databinding.DialogEditSubscriptionBinding
import sh.sar.gridflow.databinding.FragmentSubscriptionsBinding import sh.sar.gridflow.databinding.FragmentSubscriptionsBinding
class SubscriptionsFragment : Fragment() { class SubscriptionsFragment : Fragment() {
@@ -38,7 +44,10 @@ class SubscriptionsFragment : Fragment() {
private fun setupViews() { private fun setupViews() {
// Setup RecyclerView // Setup RecyclerView
subscriptionsAdapter = DetailedSubscriptionsAdapter() subscriptionsAdapter = DetailedSubscriptionsAdapter(
onEditClick = { subscription -> showEditDialog(subscription) },
onDeleteClick = { subscription -> showDeleteDialog(subscription) }
)
binding.recyclerSubscriptions.apply { binding.recyclerSubscriptions.apply {
layoutManager = LinearLayoutManager(requireContext()) layoutManager = LinearLayoutManager(requireContext())
adapter = subscriptionsAdapter adapter = subscriptionsAdapter
@@ -46,7 +55,8 @@ class SubscriptionsFragment : Fragment() {
// Handle FAB click // Handle FAB click
binding.fabAddSubscription.setOnClickListener { binding.fabAddSubscription.setOnClickListener {
Toast.makeText(context, "Add subscription coming soon", Toast.LENGTH_SHORT).show() val intent = Intent(requireContext(), AddSubscriptionActivity::class.java)
startActivity(intent)
} }
// Handle retry button // Handle retry button
@@ -112,6 +122,50 @@ class SubscriptionsFragment : Fragment() {
binding.textError.text = error binding.textError.text = error
} }
private fun showEditDialog(subscription: CustomerSubscription) {
val dialogBinding = DialogEditSubscriptionBinding.inflate(layoutInflater)
dialogBinding.editSubscriptionName.setText(subscription.name)
val dialog = AlertDialog.Builder(requireContext())
.setView(dialogBinding.root)
.create()
dialogBinding.btnCancel.setOnClickListener {
dialog.dismiss()
}
dialogBinding.btnSubmit.setOnClickListener {
val newName = dialogBinding.editSubscriptionName.text.toString().trim()
if (newName.isNotEmpty()) {
Toast.makeText(context, "Edit API call needed for: $newName", Toast.LENGTH_SHORT).show()
dialog.dismiss()
} else {
dialogBinding.editSubscriptionName.error = "Name cannot be empty"
}
}
dialog.show()
}
private fun showDeleteDialog(subscription: CustomerSubscription) {
val dialogBinding = DialogDeleteSubscriptionBinding.inflate(layoutInflater)
val dialog = AlertDialog.Builder(requireContext())
.setView(dialogBinding.root)
.create()
dialogBinding.btnCancel.setOnClickListener {
dialog.dismiss()
}
dialogBinding.btnYes.setOnClickListener {
Toast.makeText(context, "Delete API call needed for: ${subscription.name}", Toast.LENGTH_SHORT).show()
dialog.dismiss()
}
dialog.show()
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".AddSubscriptionActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.GridFlow.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_marginTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp"
android:gravity="center">
<!-- Logo and Title Section -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/iv_app_logo"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginBottom="24dp"
android:src="@mipmap/ic_launcher"
android:contentDescription="GridFlow Logo" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add New Subscription"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter your subscription details below"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"
android:alpha="0.7"
android:layout_marginBottom="32dp" />
</LinearLayout>
<!-- Subscription Form -->
<LinearLayout
android:id="@+id/input_form_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="32dp">
<!-- Input Fields Container -->
<LinearLayout
android:id="@+id/input_fields_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Subscription Number Input -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="Subscription Number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_subscription_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- Bill Number Input -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="Bill Number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_bill_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- Alias/Description Input -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:hint="Alias/Description"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_alias"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<!-- Continue Button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_continue"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Continue"
android:textSize="16sp"
android:textAllCaps="false"
android:layout_marginBottom="24dp" />
</LinearLayout>
<!-- Spacer for bottom -->
<View
android:layout_width="match_parent"
android:layout_height="32dp" />
</LinearLayout>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -1,10 +1,31 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:background="?android:attr/colorBackground"
android:background="?android:attr/colorBackground"> tools:context=".PayWithoutAccountActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.GridFlow.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_marginTop="?attr/actionBarSize">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -474,4 +495,6 @@
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".PayWithoutAccountActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.GridFlow.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_marginTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp"
android:gravity="center">
<!-- Logo and Title Section -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/iv_app_logo"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginBottom="24dp"
android:src="@mipmap/ic_launcher"
android:contentDescription="GridFlow Logo" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pay Without Account"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter your bill and subscription details"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"
android:alpha="0.7"
android:layout_marginBottom="32dp" />
</LinearLayout>
<!-- Payment Form -->
<LinearLayout
android:id="@+id/input_form_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="32dp">
<!-- Input Fields Container -->
<LinearLayout
android:id="@+id/input_fields_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Bill Number Input -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="Bill Number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_bill_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- Subscription Number Input -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:hint="Subscription Number"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_subscription_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<!-- Bill Details Card -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/bill_details_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:visibility="gone"
app:cardCornerRadius="12dp"
app:cardElevation="4dp"
app:strokeWidth="1dp"
app:strokeColor="?android:attr/textColorSecondary">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<!-- Bill Header -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bill Number"
android:textSize="12sp"
android:textColor="?android:attr/textColorSecondary"
android:alpha="0.7" />
<TextView
android:id="@+id/tv_bill_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5-5879"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="end">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textSize="12sp"
android:textColor="?android:attr/textColorSecondary"
android:alpha="0.7" />
<TextView
android:id="@+id/tv_bill_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PAID"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<!-- Continue/Search Another Bill Button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_pay"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Pay MVR 1,176.23"
android:textSize="16sp"
android:textAllCaps="false" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Continue/Search Another Bill Button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_continue"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Continue"
android:textSize="16sp"
android:textAllCaps="false"
android:layout_marginBottom="24dp" />
</LinearLayout>
<!-- Spacer for bottom -->
<View
android:layout_width="match_parent"
android:layout_height="32dp" />
</LinearLayout>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete Subscription"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="16dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Are you sure you want to remove this subscription?"
android:textSize="16sp"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="24dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_cancel"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_marginEnd="8dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yes"
android:backgroundTint="?android:attr/colorError" />
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit Subscription"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="16dp" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_subscription_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Subscription Name"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_cancel"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_marginEnd="8dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
</LinearLayout>

View File

@@ -1,29 +1,48 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true"
android:background="?android:attr/colorBackground" android:background="?android:attr/colorBackground"
tools:context=".ui.payanybill.PayAnyBillFragment"> tools:context=".ui.payanybill.PayAnyBillFragment">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="20dp" android:gravity="center"
android:gravity="center"> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginBottom="24dp"
android:src="@drawable/ic_pay_any_bill_24"
android:contentDescription="Pay Any Bill Icon"
android:alpha="0.6" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pay Any Bill"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="8dp" />
<TextView <TextView
android:id="@+id/text_pay_any_bill" android:id="@+id/text_pay_any_bill"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Coming Soon"
android:textSize="18sp" android:textSize="18sp"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorSecondary"
android:gravity="center" android:alpha="0.7" />
android:layout_marginTop="100dp"
tools:text="Pay Any Bill\n\nComing soon..." />
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.constraintlayout.widget.ConstraintLayout>