Skip to content

Commit

Permalink
Merge pull request #1 from aritra-tech/v1.1.3
Browse files Browse the repository at this point in the history
v1.1.3
  • Loading branch information
aritra-tech authored Sep 18, 2023
2 parents 3119505 + 80e86dd commit 70c246c
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 40 deletions.
9 changes: 9 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion compose_cards/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ publishing {
register<MavenPublication>("release") {
groupId = "com.github.aritra-tech"
artifactId = "ComposeCards"
version = "1.0.3"
version = "1.1.3"

afterEvaluate {
from(components["release"])
Expand Down
110 changes: 71 additions & 39 deletions compose_cards/src/main/java/com/aritra/compose_cards/ui/CreditCard.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.aritra.compose_cards.ui

import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand Down Expand Up @@ -36,7 +36,17 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import com.aritra.compose_cards.R
import com.aritra.compose_cards.util.Card

/**
* Composable function to display a Credit Card view with animated flip functionality.
*
* @param cardNumber The text input for the credit card number.
* @param holderName The text input for the cardholder's name.
* @param expiryDate The text input for the card's expiry date.
* @param cardCVV The text input for the card's CVV (Card Verification Value) number.
*/


@Composable
fun CreditCard(
Expand All @@ -46,13 +56,22 @@ fun CreditCard(
cardCVV: TextFieldValue
) {

// Mutable state to track the flip state of the card
var backSwitch by remember { mutableStateOf(false) }

// Mutable state to track the detected card type (Visa, Mastercard, etc.)
var cardType by remember { mutableStateOf(Card.None) }

// Calculate the length of the card number and mask it for display
val length = if (cardNumber.text.length > 16) 16 else cardNumber.text.length
val maskedNumber =
remember { "*****************" }.replaceRange(0..length, cardNumber.text.take(16))

// Switch to back side of the card depending on the cvv number

val cvv = if (cardCVV.text.length > 3) 3 else cardCVV.text.length
val maskedCVV = remember { "*".repeat(3) }.replaceRange(0 until cvv, cardCVV.text.take(3))

// Determine whether to switch to the back side of the card based on CVV length
if (cardCVV.text.length == 1 && !backSwitch) {
backSwitch = true
} else if (cardCVV.text.length == 2) {
Expand All @@ -61,35 +80,53 @@ fun CreditCard(
backSwitch = false
}

// Show card type logo depending on the card number
// Detect and set the card type logo based on the card number's first digit
cardType = when {
cardNumber.text.isNotEmpty() -> {
when (cardNumber.text[0]) { // // Taking the first digits for identifying which card is it
'4' -> Card.Visa
'5' -> Card.Mastercard
'6' -> Card.RuPay
'3' -> Card.AmericanExpress
when (cardNumber.text.take(2)) {
"30", "36", "38" -> Card.DinersClub
"40" -> Card.Visa
"50", "51", "52", "53", "54", "55" -> Card.Mastercard
"56","57", "58", "63", "67" -> Card.Maestro
"60" -> Card.RuPay
"37" -> Card.AmericanExpress
else -> Card.None
}
}

else -> Card.None
}

// Set Card Color according to the card type

// Set the card's background color based on its type
val animatedColor = animateColorAsState(
targetValue =
if (cardType == Card.Visa) {
Color(0xFF1C478B)
} else if (cardType == Card.Mastercard) {
Color(0xFF3BB9A1)
} else if (cardType == Card.RuPay) {
Color(0xFFB2B1FD)
} else if (cardType == Card.AmericanExpress) {
Color(0xFFA671FC)
} else {
MaterialTheme.colors.onBackground
when (cardType) {
Card.Visa -> {
Color(0xFF1C478B)
}

Card.Mastercard -> {
Color(0xFF3BB9A1)
}

Card.RuPay -> {
Color(0xFFB2B1FD)
}

Card.AmericanExpress -> {
Color(0xFFA671FC)
}

Card.Maestro -> {
Color(0xFF99BEF8)
}

Card.DinersClub -> {
Color(0xFFFC4444)
}
else -> {
MaterialTheme.colors.onBackground
}
},
label = ""
)
Expand All @@ -101,7 +138,11 @@ fun CreditCard(
.fillMaxWidth()
.height(200.dp)
.graphicsLayer(
rotationY = animateFloatAsState(if (backSwitch) 180f else 0f).value,
rotationY = animateFloatAsState(
if (backSwitch) 180f else 0f,
label = "",
animationSpec = tween(500),
).value,
translationY = 0f
)
.clickable {
Expand All @@ -123,7 +164,7 @@ fun CreditCard(

AnimatedVisibility(visible = cardType != Card.None,
modifier = Modifier
.padding(16.dp)
.padding(start = 12.dp, top = 10.dp)
.constrainAs(cardImage) {
start.linkTo(parent.start)
top.linkTo(parent.top)
Expand All @@ -136,11 +177,12 @@ fun CreditCard(

Text(
text = maskedNumber.chunked(4).joinToString(" "),
style = MaterialTheme.typography.h6,
style = MaterialTheme.typography.h5,
maxLines = 1,
color = Color.White,
modifier = Modifier
.animateContentSize(spring())
.padding(bottom = 20.dp)
.constrainAs(number) {
linkTo(
start = parent.start,
Expand Down Expand Up @@ -231,15 +273,15 @@ fun CreditCard(
modifier = Modifier
.defaultMinSize(minWidth = 60.dp)
.clip(RoundedCornerShape(4.dp))
.background(Color.Gray),
.background(Color.White),
contentAlignment = Alignment.Center
) {
Text(
text = cardCVV.text,
text = maskedCVV,
style = MaterialTheme.typography.h6,
color = Color.White,
color = Color.Black,
modifier = Modifier
.animateContentSize()
.animateContentSize(TweenSpec(300))
.padding(vertical = 4.dp, horizontal = 16.dp)

)
Expand All @@ -249,20 +291,10 @@ fun CreditCard(
}
}

enum class Card(
val title: String,
@DrawableRes val image: Int
) {
None("", R.drawable.ic_visa),
Visa("", R.drawable.ic_visa),
Mastercard("", R.drawable.ic_mastercard),
RuPay("", R.drawable.rupay_logo),
AmericanExpress("", R.drawable.amex_logo)
}

@Preview
@Composable
fun PreviewPaymentCard(){
fun PreviewPaymentCard() {
CreditCard(
TextFieldValue("*****************"),
TextFieldValue("Aritra Das"),
Expand Down
16 changes: 16 additions & 0 deletions compose_cards/src/main/java/com/aritra/compose_cards/util/Card.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.aritra.compose_cards.util

import androidx.annotation.DrawableRes
import com.aritra.compose_cards.R

enum class Card(
@DrawableRes val image: Int
) {
None(R.drawable.ic_visa),
Visa(R.drawable.ic_visa),
Mastercard(R.drawable.ic_mastercard),
RuPay(R.drawable.rupay_logo),
AmericanExpress(R.drawable.amex_logo),
Maestro(R.drawable.maestro),
DinersClub(R.drawable.diner_clubs)
}
12 changes: 12 additions & 0 deletions compose_cards/src/main/res/drawable/diner_clubs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="52dp"
android:height="43dp"
android:viewportWidth="52"
android:viewportHeight="43">
<path
android:pathData="M30.463,42.177C41.723,42.231 52,32.91 52,21.57C52,9.171 41.723,0.6 30.463,0.604H20.773C9.379,0.6 0,9.173 0,21.57C0,32.912 9.379,42.231 20.773,42.177H30.463Z"
android:fillColor="#0079BE"/>
<path
android:pathData="M20.819,2.322C10.407,2.326 1.971,10.842 1.967,21.353C1.971,31.862 10.407,40.379 20.819,40.382C31.233,40.379 39.673,31.862 39.674,21.353C39.673,10.842 31.234,2.326 20.819,2.322ZM8.87,21.353C8.868,18.923 9.599,16.548 10.968,14.54C12.336,12.532 14.279,10.983 16.542,10.097V32.608C14.279,31.722 12.336,30.173 10.967,28.165C9.598,26.157 8.868,23.783 8.87,21.353ZM25.096,32.612V10.096C27.36,10.981 29.305,12.529 30.674,14.538C32.044,16.547 32.775,18.923 32.772,21.354C32.774,23.785 32.043,26.16 30.674,28.169C29.304,30.178 27.36,31.726 25.096,32.612Z"
android:fillColor="#ffffff"/>
</vector>
19 changes: 19 additions & 0 deletions compose_cards/src/main/res/drawable/maestro.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="41dp"
android:viewportWidth="64"
android:viewportHeight="41">
<group>
<clip-path
android:pathData="M0,0.472h64v39.554h-64z"/>
<path
android:pathData="M64,20.249C64,31.181 55.155,40.026 44.223,40.026C39.609,40.026 35.379,38.433 32.028,35.796C36.642,32.17 39.554,26.566 39.554,20.249C39.554,13.931 36.587,8.328 32.028,4.702C35.379,2.065 39.609,0.472 44.223,0.472C55.155,0.472 64,9.372 64,20.249Z"
android:fillColor="#0099DF"/>
<path
android:pathData="M32.028,4.702C32.028,4.702 32.028,4.702 32.028,4.702C36.587,8.328 39.554,13.931 39.554,20.249C39.554,26.566 36.642,32.17 32.028,35.796L31.972,35.796C27.413,32.225 24.446,26.567 24.446,20.249C24.446,13.932 27.413,8.328 31.972,4.702C31.972,4.702 31.973,4.702 31.972,4.702L32.028,4.702Z"
android:fillColor="#6C6BBD"/>
<path
android:pathData="M24.446,20.249C24.446,13.932 27.413,8.328 31.972,4.702C28.622,2.065 24.391,0.472 19.777,0.472C8.845,0.472 0,9.317 0,20.249C0,31.181 8.845,40.026 19.777,40.026C24.391,40.026 28.622,38.433 31.972,35.796C27.413,32.225 24.446,26.567 24.446,20.249Z"
android:fillColor="#EB001B"/>
</group>
</vector>

0 comments on commit 70c246c

Please sign in to comment.