Created
August 6, 2019 07:48
-
-
Save jet2018/b4169bc24dd1f3008487fb02013ef3f7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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; | |
background-color:#fff; | |
padding: 1em; | |
} | |
[data-cart-info], | |
[data-credit-card] { | |
transform: scale(0.78); | |
margin-left: -3.4em; | |
} | |
[data-cc-info] input:focus, | |
[data-cc-digits] input:focus { | |
outline: none; | |
} | |
.mdc-card__primary-action, | |
.mdc-card__primary-action:hover { | |
cursor: auto; | |
padding: 20px; | |
min-height: inherit; | |
} | |
[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; | |
} | |
/* Add Your CSS From Here */ | |
[data-cart-info] span{ | |
display:inline-block; | |
vertical-align:middle; | |
} | |
.material-icons{ | |
font-size:150px; | |
} | |
[data-credit-card]{ | |
width:435px; | |
min-height:240px; | |
border-radius:10px; | |
background-color:#5d6874; | |
} | |
[data-card-type]{ | |
display:block; | |
width:120px; | |
height:60px; | |
} | |
[data-cc-digits]{ | |
margin-top:2em; | |
} | |
[data-cc-digits] input{ | |
color:#fff; | |
font-size:2em; | |
line-height:2em; | |
border:none; | |
background:none; | |
margin-right:0.5em; | |
} | |
[data-cc-info]{ | |
margin-top:1em; | |
} | |
[data-cc-info] input{ | |
color:#fff; | |
font-size:1.2em; | |
border:none; | |
background:none; | |
} | |
[data-cc-info] input:nth-child(2){ | |
padding-right:10px; | |
float:right; | |
} | |
[data-pay-btn]{ | |
position:fixed; | |
width:90%; | |
border:solid 1px; | |
bottom:20px; | |
} | |
</style> | |
<!--mystyles end here--> | |
</head> | |
<body> | |
<!--html begins here --> | |
<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" size="4" placeholder="----"> | |
<input type="text" size="4" placeholder="----"> | |
<input type="text" size="4" placeholder="----"> | |
<input type="text" size="4" placeholder="----"> | |
</div> | |
<div data-cc-info=""> | |
<input size="20" type="text" placeholder="Name Surname"> | |
<input size="6" type="text" placeholder="MM/YY"> | |
</div> | |
</div> | |
</div> | |
<button class="mdc-button" data-pay-btn="">Pay Now</button> | |
<!--and ends here --> | |
<script> | |
const supportedCards = { | |
visa, mastercard | |
}; | |
const countries = [ | |
{ | |
code: "US", | |
currency: "USD", | |
currencyName: '', | |
country: 'United States' | |
}, | |
{ | |
code: "NG", | |
currency: "NGN", | |
currencyName: '', | |
country: 'Nigeria' | |
}, | |
{ | |
code: 'KE', | |
currency: 'KES', | |
currencyName: '', | |
country: 'Kenya' | |
}, | |
{ | |
code: 'UG', | |
currency: 'UGX', | |
currencyName: '', | |
country: 'Uganda' | |
}, | |
{ | |
code: 'RW', | |
currency: 'RWF', | |
currencyName: '', | |
country: 'Rwanda' | |
}, | |
{ | |
code: 'TZ', | |
currency: 'TZS', | |
currencyName: '', | |
country: 'Tanzania' | |
}, | |
{ | |
code: 'ZA', | |
currency: 'ZAR', | |
currencyName: '', | |
country: 'South Africa' | |
}, | |
{ | |
code: 'CM', | |
currency: 'XAF', | |
currencyName: '', | |
country: 'Cameroon' | |
}, | |
{ | |
code: 'GH', | |
currency: 'GHS', | |
currencyName: '', | |
country: 'Ghana' | |
} | |
]; | |
const billHype = () => { | |
const billDisplay = document.querySelector('.mdc-typography--headline4'); | |
if (!billDisplay) return; | |
billDisplay.addEventListener('click', () => { | |
const billSpan = document.querySelector("[data-bill]"); | |
if (billSpan && | |
appState.bill && | |
appState.billFormatted && | |
appState.billFormatted === billSpan.textContent) { | |
window.speechSynthesis.speak( | |
new SpeechSynthesisUtterance(appState.billFormatted) | |
); | |
} | |
}); | |
}; | |
//myscripts start here | |
const appState ={}; | |
const smartCursor =(event,fieldIndex, fields) => { | |
if(event.target.value.length === event.target.size && fieldIndex < fields.length -1){ | |
fields[fieldIndex +1].focus(); | |
} | |
} | |
const smartInput = (event, index) => | |
{ | |
if(event.target.parentElement.hasAttribute("data-cc-digits")){ | |
if(/\d{d}$/.test(event.key) || event.key === "Backspace"){ | |
if(/\d/.test(event.key)){ | |
if(event.target.selectionStart < event,target.value.length){ | |
appState.cardDigits[index].splice(event.target.selectionStart,0,event.key); | |
} | |
else{ | |
appState.cardDigits[index].push(event.key) | |
} | |
setTimeout(() =>{ | |
event.target.value = "#".repeat(event.target.value.length); | |
if(event.target.value.length === 4){ | |
detectCardType(appState.cardDigits[0]) | |
} | |
}, 500); | |
} | |
else{ | |
appState.cardDigits[index].splice(event.target.selectionStart-1, 1) | |
} | |
} | |
else{ | |
event.preventDefault(); | |
} | |
} | |
} | |
const enableSmartTyping = () =>{ | |
const digitsNodeList = document.querySelectorAll("div[data-cc-digits] input"); | |
const infoNodeList = document.querySelectorAll("div[data-cc-info] input"); | |
const inputArray = []; | |
digitsNodeList.forEach(_Node => inputArray.push(_Node)); | |
infoNodeList.forEach(_Node => inputArray(_Node)); | |
inputArray.forEach((field,index, fields) => { | |
field.addEventListener("keyup", (event) =>{ | |
smartCursor(event, index, fields) | |
}) | |
field.addEventListener("keydown", (event) =>{ | |
smartInput(event, index) | |
}) | |
}) | |
} | |
const formatAsMoney = (amount, buyerCountry) => { | |
const findCountry = countries.find(value => value.country === buyerCountry); | |
if(findCountry){ | |
return amount.toLocaleString(`en-${findCountry.code}`,{ | |
style:"currency", | |
currency:findCountry.currency | |
}); | |
}else{ | |
return amount.toLocaleString(`en-US`,{ | |
style:'currency',currency:'USD' | |
}) | |
} | |
}; | |
const flagIfInvalid = ( field, isValid) => { | |
if(isValid){ | |
field.classList.remove("is-invalid"); | |
}else{ | |
field.classList.add("is-invalid") | |
} | |
}; | |
const expiryDateFormatIsValid = (field) =>{ | |
const reg = /^(((1|)[0-9])|((1)[0-9]))(\/)\d{2}$/; | |
const result = reg.test(field.value) | |
return result | |
}; | |
const detectCardType = (first4Digits) => { | |
} | |
const validateCardExpiryDate = () =>{ | |
const field = document.querySelector('[data-cc-info] input:last-child') | |
const month = field.value.split('/')[0] | |
const validDate = expiryDateFormatIsValid(field) | |
const year = `20${field.value.split('/')[1]}` | |
const expDate = new Date(`${year}/${month}`) | |
const results = validDate && expDate >= new Date() ? (console.log('valid date'), true) : (console.log('invalid date'), false) | |
flagIfInvalid(field, results); | |
return results | |
}; | |
const validateCardHolderName = () =>{ | |
const target = document.querySelector('[data-cc-info] input:first-child') | |
const isMatch = /^[a-zA-Z]{3,}\s[a-zA-Z]{3,}$/.test(target.value.trim()); | |
if(isMatch){ | |
flagIfInvalid(target, true) | |
console.log('valid Names') | |
return true | |
}else{ | |
flagIfInvalid(target, false) | |
console.log('Invalid Name: Require atleast three letters') | |
return false | |
} | |
}; | |
const validateCardNumber = () =>{ | |
} | |
const validatePayment =() =>{ | |
validateCardNumber(); | |
console.log(validateCardHolderName()); | |
validateCardExpiryDate(); | |
} | |
const acceptCardNumbers =(event, fieldIndex) =>{ | |
} | |
const uiCanInteract = () =>{ | |
document.querySelectorAll("div[data-cc-digits] input")[0].focus(); | |
const payBtn = document.querySelector('[data-pay-btn]'); | |
payBtn.addEventListener('click',validatePayment); | |
billHype(); | |
enableSmartTyping(); | |
}; | |
const displayCartTotal = ({results}) =>{ | |
const [data] = results; | |
const {itemsInCart, buyerCountry} = data; | |
appState.items = itemsInCart; | |
appState.country = buyerCountry; | |
appState.bill = itemsInCart.reduce((acc, curr) => acc + (curr.price * curr.qty), 0); | |
appState.billFormatted = formatAsMoney(appState.bill,appState.country); | |
const dataBill = document.querySelector('[data-bill]'); | |
dataBill.textContent = appState.billFormatted; | |
appState.cardDigits = []; | |
uiCanInteract(); | |
}; | |
const fetchBill = () => { | |
const apiHost = 'https://randomapi.com/api'; | |
const apiKey = '006b08a801d82d0c9824dcfdfdfa3b3c'; | |
const apiEndpoint = `${apiHost}/${apiKey}`; | |
fetch(apiEndpoint) | |
.then((response) => response.json()) | |
.then((data) => displayCartTotal(data)) | |
.catch((err) => {return console.log(err)}); | |
}; | |
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