redesign accounts page ui

This commit is contained in:
2026-05-14 05:24:31 +05:00
parent 3ddf687c8b
commit 6ed68df572
5 changed files with 176 additions and 131 deletions
@@ -1,10 +1,14 @@
package sh.sar.basedbank.ui.home
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import sh.sar.basedbank.api.mib.MibAccount
import sh.sar.basedbank.databinding.ItemAccountBinding
@@ -15,7 +19,7 @@ class AccountsAdapter(accounts: List<MibAccount>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private sealed class Item {
data class Header(val profileName: String, val profileType: String) : Item()
data class SectionTitle(val label: String, val chip: String) : Item()
data class Account(val account: MibAccount) : Item()
data class Card(val account: MibAccount) : Item()
}
@@ -29,30 +33,29 @@ class AccountsAdapter(accounts: List<MibAccount>) :
}
private fun buildItems(accounts: List<MibAccount>): List<Item> = buildList {
var lastProfile = ""
for (account in accounts) {
if (account.profileName != lastProfile) {
add(Item.Header(account.profileName, account.profileType))
lastProfile = account.profileName
}
if (account.profileType == "BML_PREPAID") {
add(Item.Card(account))
} else {
add(Item.Account(account))
}
val regular = accounts.filter { it.profileType != "BML_PREPAID" }
val prepaid = accounts.filter { it.profileType == "BML_PREPAID" }
if (regular.isNotEmpty()) {
add(Item.SectionTitle("Accounts", ""))
regular.forEach { add(Item.Account(it)) }
}
if (prepaid.isNotEmpty()) {
add(Item.SectionTitle("Cards", "BML"))
prepaid.forEach { add(Item.Card(it)) }
}
}
override fun getItemViewType(position: Int) = when (items[position]) {
is Item.Header -> TYPE_HEADER
is Item.Account -> TYPE_ACCOUNT
is Item.Card -> TYPE_CARD
is Item.SectionTitle -> TYPE_HEADER
is Item.Account -> TYPE_ACCOUNT
is Item.Card -> TYPE_CARD
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
TYPE_HEADER -> HeaderViewHolder(ItemProfileHeaderBinding.inflate(inflater, parent, false))
TYPE_HEADER -> SectionViewHolder(ItemProfileHeaderBinding.inflate(inflater, parent, false))
TYPE_CARD -> CardViewHolder(ItemCardBinding.inflate(inflater, parent, false))
else -> AccountViewHolder(ItemAccountBinding.inflate(inflater, parent, false))
}
@@ -60,23 +63,23 @@ class AccountsAdapter(accounts: List<MibAccount>) :
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (val item = items[position]) {
is Item.Header -> (holder as HeaderViewHolder).bind(item)
is Item.Account -> (holder as AccountViewHolder).bind(item.account)
is Item.Card -> (holder as CardViewHolder).bind(item.account)
is Item.SectionTitle -> (holder as SectionViewHolder).bind(item)
is Item.Account -> (holder as AccountViewHolder).bind(item.account)
is Item.Card -> (holder as CardViewHolder).bind(item.account)
}
}
override fun getItemCount() = items.size
private inner class HeaderViewHolder(private val binding: ItemProfileHeaderBinding) :
private inner class SectionViewHolder(private val binding: ItemProfileHeaderBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Item.Header) {
binding.tvProfileName.text = item.profileName
binding.tvProfileType.text = when (item.profileType) {
"BML" -> "Bank of Maldives"
"BML_PREPAID" -> "BML"
"0" -> "Personal"
else -> "Business"
fun bind(item: Item.SectionTitle) {
binding.tvProfileName.text = item.label
if (item.chip.isNotEmpty()) {
binding.tvProfileType.text = item.chip
binding.tvProfileType.visibility = View.VISIBLE
} else {
binding.tvProfileType.visibility = View.GONE
}
}
}
@@ -84,11 +87,20 @@ class AccountsAdapter(accounts: List<MibAccount>) :
private inner class AccountViewHolder(private val binding: ItemAccountBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(account: MibAccount) {
binding.tvAccountName.text = account.accountBriefName
binding.tvAccountName.text = account.accountBriefName
binding.tvAccountNumber.text = account.accountNumber
binding.tvPillBank.text = if (account.profileType.startsWith("BML")) "BML" else "MIB"
binding.tvPillType.text = friendlyAccountType(account.accountTypeName)
binding.tvPillProfile.text = when (account.profileType) {
"0" -> "Personal"
"1" -> "Business"
else -> account.profileName
}
binding.tvBalance.text = "${account.currencyName} ${account.availableBalance}"
binding.tvAccountType.text = account.accountTypeName
binding.tvStatus.text = account.statusDesc
binding.root.setOnLongClickListener {
copyToClipboard(it.context, account.accountNumber)
true
}
}
}
@@ -97,24 +109,25 @@ class AccountsAdapter(accounts: List<MibAccount>) :
fun bind(account: MibAccount) {
val brand = cardBrand(account.accountTypeName)
binding.tvCardBrand.text = brand.label
setBrandBackground(brand.color)
binding.tvCardName.text = account.accountBriefName
binding.tvCardNumber.text = account.accountNumber
val isPrepaid = account.profileType == "BML_PREPAID"
binding.layoutCardBalance.visibility = if (isPrepaid) View.VISIBLE else View.GONE
if (isPrepaid) {
binding.tvCardBalance.text = "${account.currencyName} ${account.availableBalance}"
}
}
private fun setBrandBackground(colorHex: String) {
val drawable = GradientDrawable().apply {
binding.tvCardBrand.background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = 100f
setColor(Color.parseColor(colorHex))
setColor(Color.parseColor(brand.color))
}
binding.tvCardName.text = account.accountBriefName
binding.tvCardNumber.text = account.accountNumber
binding.layoutCardBalance.visibility = View.VISIBLE
binding.tvCardBalance.text = "${account.currencyName} ${account.availableBalance}"
val isActive = account.statusDesc.equals("Active", ignoreCase = true)
if (isActive) {
binding.tvCardStatus.visibility = View.GONE
binding.root.alpha = 1f
} else {
binding.tvCardStatus.text = account.statusDesc
binding.tvCardStatus.visibility = View.VISIBLE
binding.root.alpha = 0.45f
}
binding.tvCardBrand.background = drawable
}
}
@@ -123,6 +136,27 @@ class AccountsAdapter(accounts: List<MibAccount>) :
private const val TYPE_ACCOUNT = 1
private const val TYPE_CARD = 2
private fun copyToClipboard(context: Context, accountNumber: String) {
val cm = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cm.setPrimaryClip(ClipData.newPlainText("Account Number", accountNumber))
Toast.makeText(context, "Account number copied", Toast.LENGTH_SHORT).show()
}
private fun friendlyAccountType(raw: String): String {
val u = raw.trim().uppercase()
return when {
u == "SAVINGS ACCOUNT" ||
u == "SAVING ACCOUNT" -> "Savings"
u == "CURRENT ACCOUNT" ||
u == "CURRENT ACCOUNT(PERSONAL)" ||
u == "CURRENT ACCOUNT(BUSINESS)" -> "Current"
u == "WADIAH RETAIL CURRENT ACCOUNT" ||
u == "WADIAH BUSINESS CURRENT ACCOUNT" -> "Islamic Current"
u == "BML ISLAMIC SAVINGS ACCOUNT" -> "Islamic Savings"
else -> raw.trim()
}
}
private data class Brand(val label: String, val color: String)
private fun cardBrand(productName: String): Brand = when {