Skip to content

Instantly share code, notes, and snippets.

@justinecodez
Created July 15, 2019 08:20
Show Gist options
  • Save justinecodez/4ab3e87f8d1b639a84e1a69f8de51e23 to your computer and use it in GitHub Desktop.
Save justinecodez/4ab3e87f8d1b639a84e1a69f8de51e23 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Mini App</title>
<style>
body {
margin: 0;
padding: 1em;
background-color:white;
}
[data-cart-info],
[data-credit-card] {
transform: scale(0.78);
margin-left: -3.4em;
}
[data-cart-info] span{
display:inline-block;
vertical-align:middle;
}
.material-icons{
font-size:150px;
}
[data-cc-digits]{
margin-top:2em;
}
[data-cc-digits] input{
color:white;
font-size:2em;
line-height:2em;
border:none;
background:none;
margin-right:0.5em;
}
[data-cc-info]{
margin-top:1em;
}
[data-cc-info] input:focus,
[data-cc-digits] input:focus {
outline: none;
}
[data-cc-info] input{
color:white;
font-size:1.2em;
border:none;
background:none;
}
.mdc-card__primary-action,
.mdc-card__primary-action:hover {
cursor: auto;
padding: 20px;
min-height: inherit;
}
[data-credit-card]{
width:435px;
min-height:240px;
border-radius:10px;
background-color:#5d6874;
}
[data-credit-card] img{
display:block;
width:120px;
height:60px;
}
[data-credit-card] [data-card-type] {
transition: width 1.5s;
margin-left: calc(100% - 130px);
}
[data-credit-card].is-visa {
background: linear-gradient(135deg, #622774 0%, #c53364 100%);
}
[data-credit-card].is-mastercard {
background: linear-gradient(135deg, #65799b 0%, #5e2563 100%);
}
.is-visa [data-card-type],
.is-mastercard [data-card-type] {
width: auto;
}
input.is-invalid,
.is-invalid input {
text-decoration: line-through;
}
::placeholder {
color: #fff;
}
[data-pay-btn]{
position:fixed;
width:90%;
border:solid 1px;
bottom:20px;
}
</style>
</head>
<body>
<div data-cart-info>
<h1 class="mdc-typography--headline4">
<span class="material-icons">shopping_cart</span>
<span data-bill></span>
</h1>
</div>
<div data-credit-card class="mdc-card" mdc-card--outlined>
<div class="mdc-card__primary-action">
<img data-card-type src="https://placehold.it/120x60.png?text=Card">
<div data-cc-digits>
<input type="text" placeholder="----" size="4">
<input type="text" placeholder="----" size="4">
<input type="text" placeholder="----" size="4">
<input type="text" placeholder="----" size="4">
</div>
<div data-cc-info>
<input type="text" size="20" placeholder="Name Surname">
<input type="text" size="6" placeholder="MM/YY" style="padding:10px;float:right">
</div>
</div>
</div>
<button class="mdc-button" data-pay-btn>Pay & Checkout Now</button>
<script>
const countries = [
{
code: "US",
currency: "USD",
country: 'United States'
},
{
code: "NG",
currency: "NGN",
country: 'Nigeria'
},
{
code: 'KE',
currency: 'KES',
country: 'Kenya'
},
{
code: 'UG',
currency: 'UGX',
country: 'Uganda'
},
{
code: 'RW',
currency: 'RWF',
country: 'Rwanda'
},
{
code: 'TZ',
currency: 'TZS',
country: 'Tanzania'
},
{
code: 'ZA',
currency: 'ZAR',
country: 'South Africa'
},
{
code: 'CM',
currency: 'XAF',
country: 'Cameroon'
},
{
code: 'GH',
currency: 'GHS',
country: 'Ghana'
}
];
const appState = {};
const formatAsMoney = (amount,buyerCountry)=>{
const country = countries.find(country =>country.country ==buyerCountry);
if(country){
return amount.toLocaleString(country.code,{style:'currency', currency: country.currency});
}else{
return amount.toLocaleString(countries[0].code,{style:'currency',currency:countries[0].currency})
}
}
const flagIfInvalid =(field,isValid) => {
if(isValid){
field.remove('is-invalid')
}else{
field.add('is-invalid')
}
}
const expiryDateFormatIsValid = (target) => {
const res = /^\d{2}\/\d{2}$/g.test(target.value);
return res;
}
const validateCardExpiryDate = ({target})=>{
let date1 = new Date();
let date2 = new Date(target);
if (expiryDateFormatIsValid(target) && (date1 < date2)){
flagIfInvalid(true);
return true;
}else{
flagIfInvalid(false)
return false;
}
}
const detectCardType = ({target})=>{
let image = document.querySelector("[data-card-type]");
if(target.value[0]=='4'){
image.src = supportedCards.visa;
document.querySelector("[data-credit-card]").classList.add("is-visa")
return"is-visa";
}else if(target.value[0]=='5'){
document.querySelector("[data-credit-card]").classList.add("is-mastercard")
document.querySelector("[data-credit-card]").classList.remove("is-visa")
image.src = supportedCards.mastercard;
return "is-mastercard"
}
}
const validateCardHolderName = ({target}) =>{
if(/^[a-zA-Z]{3,}\s[a-zA-Z]{3,}$/.test(target)){
flagIfInvalid(true);
return true;
}else {
flagIfInvalid(false);
return false;
}
}
const validateCardNumber = ()=>{
}
const uiCanInteract = ({target})=>{
document.querySelector("[data-cc-digits]input:nth-child[1]").addEventListener('blur',detectCardType)
document.querySelector('[data-cc-info]input:nth-child[1]').addEventListener('blur',validateCardHolderName)
docement.querySelector('[data-cc-info]input:nth-child[2]').addEventListener('blur',(event)=>{validateCardExpiryDate})
document.querySelector('data-pay-btn').addEventListener('click',(event)=>{validateCardNumber()})
document.querySelector('[data-cc-digit]input:nth-child[1]').focus();
}
const displayCartTotal = ({results})=>{
const [data] = results;
const {itemsInCart,buyerCountry} = data;
appState.items = itemsInCart;
appState.country = buyerCountry;
appState.bill = itemsInCart.reduce((qty,n)=>qty+n)
appState.billFormatted = formatAsMoney(appState.bill,appState.country);
document.querySelector('data-bill').textContent = appState.billFormatted;
uiCanInteract();
}
const fetchBill = ()=>{
const api = "https://randomapi.com/api/006b08a801d82d0c9824dcfdfdfa3b3c";
fetch(api)
.then(response=>response.json())
.then(data=>displayCartTotal(data))
.catch(error=>console.log(error))
}
const startApp =()=>{
fetchBill();
}
startApp();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment