<!-- Josh Channin -->
<body>
  <div class="container">
    <div class="wallet">
      <aside class="left-wallet">
        <div class="wallet-head">
          <h1> My Wallets </h1>
          <div class="modal-open">+
          </div>
        </div>
        <div class="cc-select">          
        </div>
      </aside>
      <content class="right-trans">
        <h1> Current Balance </h1>
        <h4 id="balance"></h4>
        <div class="trans-list">          
        </div>
      </content>
    </div>
  </div>

  <div class="modal">
    <div class="modal-body">
      <h3>Add a New Card</h3>
      <h5>Select a card on the left and enter the information</h5>
      <div class="modal-close">x</div>      
      <div class="modal-cards">
        <div class="md-cc visa">
          <div class="cc-img visa"></div>
        </div>      
       <div class="md-cc amex">
          <div class="cc-img amex"></div>
        </div>      
       <div class="md-cc mc">
          <div class="cc-img mc"></div>
        </div>    
      </div>      
        <form>
          <input type="text" id="ccnum" disabled> 
          <select name="month" id="month" required disabled>
             <option value="">Month</option>
              <option value="01">Janaury</option>
              <option value="02">February</option>
              <option value="03">March</option>
              <option value="04">April</option>
              <option value="05">May</option>
              <option value="06">June</option>
              <option value="07">July</option>
              <option value="08">August</option>
              <option value="09">September</option>
              <option value="10">October</option>
              <option value="11">November</option>
              <option value="12">December</option>
          </select>
          <select name="year" id="year" required disabled>
            <option value="">Year</option>
            <option value="16">2016</option>
            <option value="17">2017</option>
            <option value="18">2018</option>
            <option value="19">2019</option>
            <option value="20">2020</option>
            <option value="21">2021</option>
            <option value="22">2022</option>
            <option value="23">2023</option>
            <option value="24">2024</option>
          </select>
        </form>      
      <button class="modal-add-cc"> Add </button>      
  </div>
</body>
/* Josh Channin 
*/

@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400,600|Roboto:300,400');

body {
  font-family: 'Open Sans', sans-serif;
  background-color: rgb(255, 204, 102);
}

.container {
  width: 100%;
  padding: 40px 0px 40px 0px;
}

.wallet {
  margin: 0 auto;
  border-radius: 5px;
  background-color: #FFFFFF;
  box-shadow: 0px 8px 20px 6px rgb(255, 178, 22);
  -webkit-box-shadow: 0px 8px 20px 6px rgb(255, 178, 22);
  -moz-box-shadow: 0px 8px 20px 6px rgb(255, 178, 22);
  height: 680px;
  max-width: 900px;
  min-width: 800px;
  display: flex;
}

.left-wallet {
  background-color: #f2f2f2;
  width: 300px;
  height: initial;
  padding: 40px;
  border-radius: 5px;
}

.right-trans {
  background-color: #FFFFFF;
  width: 600px;
  height: initial;
  padding: 40px;
  border-radius: 5px;
}

h1 {
  color: #7d818e;
  margin: 0;
  font-weight: 400;
  font-size: 25px;
  font-family: 'Open Sans', sans-serif;
}

h4 {
  margin: 0;
  font-size: 30px;
  font-weight: bold;
  font-family: 'Open Sans', sans-serif;
}

.left-wallet h1,
.left-wallet modal-open,
.right-trans h1,
.right-trans #balance {
  font-family: 'Open Sans', sans-serif;
  display: inline-block;
}

#balance {
  float: right;
  line-height: 34px;
  font-size: 30px;
  font-weight: bold;
  color: #464646;
}

.modal-open {
  display: inline-block;
  float: right;
  padding: 0;
  font-size: 42px;
  line-height: 36px;
  color: #b7b7b7;
  cursor: pointer;
}

.modal-open:hover {
  display: inline-block;
  float: right;
  padding: 0;
  font-size: 42px;
  line-height: 36px;
  color: #868686;
  cursor: pointer;
}

.trans-list {
  display: none;
  border-top: 1px solid #f2f2f2;
  margin-top: 40px;
  overflow-y: scroll;
  max-height: 550px;
}

.trans {
  margin-top: 15px;
}

.trans-plus {
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/384009/plus-icon.png);
  background-repeat: no-repeat;
  width: 40px;
  height: 50px;
  display: block;
  float: left;
  position: relative;
  top: 15px;
}

.trans-minus {
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/384009/minus-icon.png);
  background-repeat: no-repeat;
  width: 40px;
  height: 50px;
  display: block;
  float: left;
  position: relative;
  top: 15px;
}

.trans-details {
  margin-top: 20px;
  display: inline-block;
  width: 80%;
}

.trans-name,
.trans-type-date {
  margin: 3px;
}

.trans-name {
  display: inline-block;
}

.trans-type-date {
  color: #888;
  padding-left: 40px;
}

.trans-amt {
  float: right;
  line-height: 55px;
  font-size: 18px;
  margin-top: 10px
}

.amt-green {
  color: rgb(113, 207, 66);
}

.amt-blue {
  color: rgb(166, 178, 216);
}

.cc-select {
  margin-top: 34px;
  overflow-y: scroll;
  max-height: 540px;
  padding: 5px;
}

.cc {
  cursor: pointer;
  background-color: #fff;
  padding: 20px;
  border-radius: 5px;
  margin-bottom: 30px;
  border: 1px solid #e1e1e1;
  transition: .1s ease-in-out;
}

.cc:hover {
  transform: scale(1.03);
  border: 1px solid gray;
}

.cc-active:hover {
  transform: scale(1);
  border: 4px solid rgb(132, 148, 202);
}

.cc-active {
  border: 4px solid rgb(132, 148, 202);
}

.cc-img {
  width: 60px;
  height: 40px;
  background-repeat: no-repeat;
  background-size: cover;
  border-radius: 4px;
  margin-bottom: 15px
}

.cc-img-main {
  width: 60px;
  height: 40px;
  background-repeat: no-repeat;
  background-size: cover;
  border-radius: 4px;
  margin-bottom: 15px
}

.cc-num {
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
}

.cc-date {
  margin-top: 8px;
  font-family: 'Roboto', sans-serif;
  color: #888;
}

.visa .cc-img,
.visa .cc-img-main {
  background-image: url("http://i.imgur.com/xYX6Tsy.png")
}

.amex .cc-img,
.amex .cc-img-main {
  background-image: url("http://i.imgur.com/47221vA.png")
}

.mc .cc-img,
.mc .cc-img-main {
  background-image: url("http://i.imgur.com/2fWTLRZ.png")
}



.modal {
  text-align: center;
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 1;
}

.modal-body {
  z-index: 2;
  background-color: #fff;
  border-radius: 5px;
  padding: 40px;
  padding-top: 10px;
  padding-bottom: 50px;
  display: inline-block;
  margin-top: 100px;
  width: 100%;
  max-width: 400px;
  position: relative;
}

.modal-close {
  position: absolute;
  top: 5px;
  right: 10px;
  font-size: 20px;
  cursor: pointer;
  font-weight: bold;
  color: #888;
}

.modal-close:hover {
  transform: scale(1.2);
  cursor: pointer;
}

.md-cc .cc-img {
  cursor: pointer;
}

.md-cc .cc-img:hover {
  cursor: pointer;
  transform: scale(1.25);
  transition: .1s ease-in-out;
}

.cc-md-active {
  transform: scale(1.25);
}

.cc-md-small {
  transform: scale(.80);
}

.modal-cards {
  width: 15%;
  display: inline-block;
  float: left;
}

.modal-add-cc {
  position: absolute;
  bottom: 15px;
  left: 190px;
  color: #fff;
  background-color: #0275d8;
  border-color: #0275d8;
  font-weight: 400;
  text-align: center;
  padding: .25rem 2rem;
  font-size: 1rem;
  border-radius: .25rem;
  -webkit-transition: all .2s ease-in-out;
  -o-transition: all .2s ease-in-out;
  transition: all .2s ease-in-out;
}

::-webkit-scrollbar {
  display: none;
}

form {
  width: 75%;
  float: right;
}

form>input,
form select {
  display: block;
  width: initial;
  border: 1px solid #e1e1e1;
  padding: 5px;
  margin: 5px
}

.modal-body>h3,
.modal-body>h5 {
  color: #777;
}

textarea:focus,
input:focus {
  outline: none;
}

.modal-body>h5 {
  border-top: 1px solid #e1e1e1;
  padding-top: 20px;
}

.no-trans {
  color: #888;
  text-align: center;
}

.valid-green {
  border: 2px solid green;
}

.valid-red {
  border: 2px solid darkred;
}
/* Josh Channin
   Fake data from generatedata.com
*/
var data = [
  {
    type: "visa",
    number: "**** **** **** 2562",
    month: "12",
    year: "17",
    id: 1,
    transactions: [
      {
        title: "Apple Iphone 6, 6g GB",
        vendor: "Electronics #343223",
        date: "12 July, 2015",
        amount: "650.00",
        currency: "$",
        action: "debit"
      },
      {
        title: "Funds Added",
        vendor: "Payment #343212",
        date: "11 July, 2015",
        amount: "900.00",
        currency: "$",
        action: "credit"
      },
      {
        title: "Energy Bill",
        vendor: "#343566",
        date: "11 July, 2015",
        amount: "84.96",
        currency: "$",
        action: "debit"
      },
      {
        title: "Mega Image SRL",
        vendor: "Food&Health #34365",
        date: "11 July, 2015",
        amount: "112.75",
        currency: "$",
        action: "debit"
      },
      {
        title: "ATM DV24",
        vendor: "#343253",
        date: "09 July, 2015",
        amount: "200.00",
        currency: "$",
        action: "debit"
      },
      {
        title: "Lukoil Station",
        vendor: "Gas #343279",
        date: "09 July, 2015",
        amount: "190.00",
        currency: "$",
        action: "debit"
      }
    ]
  },
  {
    type: "amex",
    number: "**** ****** 14525",
    month: "07",
    year: "19",
    id: 2,
    transactions: [
     {"title": "Sales and Marketing", "vendor": "Borland", "date": "23 Nov, 2016", "amount": "65.76", "currency": "$", "action": "debit"},
	{"title": "Tech Support", "vendor": "Microsoft", "date": "1 Aug, 2017", "amount": "64.62", "currency": "$", "action": "debit"},
	{"title": "Media Relations", "vendor": "Chami", "date": "8 Jun, 2017", "amount": "98.82", "currency": "$", "action": "debit"},
	{"title": "Accounting", "vendor": "Chami", "date": "21 Jan, 2017", "amount": "7889.84", "currency": "$", "action": "credit"},
	{"title": "Sales and Marketing", "vendor": "Lavasoft", "date": "24 Jul, 2017", "amount": "77.68", "currency": "$", "action": "debit"},
	{"title": "Asset Management", "vendor": "Cakewalk", "date": "11 Oct, 2016", "amount": "52.40", "currency": "$", "action": "credit"},
	{"title": "Finances", "vendor": "Sibelius", "date": "19 Aug, 2016", "amount": "32.20", "currency": "$", "action": "debit"},
	{"title": "Sales and Marketing", "vendor": "Chami", "date": "4 Jun, 2017", "amount": "72.62", "currency": "$", "action": "debit"},
	{"title": "Customer Relations", "vendor": "Finale", "date": "22 Aug, 2017", "amount": "77.77", "currency": "$", "action": "debit"},
	{"title": "Sales and Marketing", "vendor": "Apple Systems", "date": "19 May, 2017", "amount": "84.50", "currency": "$", "action": "credit"},
	{"title": "Quality Assurance", "vendor": "Cakewalk", "date": "29 Jul, 2017", "amount": "80.03", "currency": "$", "action": "debit"},
	{"title": "Public Relations", "vendor": "Altavista", "date": "10 Oct, 2017", "amount": "6.60", "currency": "$", "action": "credit"}
    ]
  },
  {
    type: "mc",
    number: "**** **** **** 8866",
    month: "02",
    year: "22",
    id: 3,
    transactions: [
     {"title": "Borland", "vendor": "Cursus Diam PC", "date": "30 Apr, 2017", "amount": "9647.17", "currency": "$", "action": "debit"},
	{"title": "Sibelius", "vendor": "Ridiculus Corporation", "date": "17 Apr, 2017", "amount": "1058.02", "currency": "$", "action": "credit"},
	{"title": "Altavista", "vendor": "Molestie Orci Tincidunt Company", "date": "9 Mar, 2018", "amount": "6622.94", "currency": "$", "action": "credit"},
	{"title": "Sibelius", "vendor": "Eu Industries", "date": "20 Mar, 2017", "amount": "2649.70", "currency": "$", "action": "credit"},
	{"title": "Yahoo", "vendor": "Mollis Nec Cursus Associates", "date": "20 Sep, 2016", "amount": "9343.63", "currency": "$", "action": "credit"},
	{"title": "Sibelius", "vendor": "Eget Metus Eu Incorporated", "date": "27 Jun, 2016", "amount": "6516.49", "currency": "$", "action": "credit"},
	{"title": "Google", "vendor": "Tempus Company", "date": "26 May, 2017", "amount": "8504.32", "currency": "$", "action": "debit"},
	{"title": "Chami", "vendor": "Id Ante Incorporated", "date": "13 Aug, 2017", "amount": "3592.96", "currency": "$", "action": "credit"},
	{"title": "Finale", "vendor": "Iaculis Quis Incorporated", "date": "2 Jan, 2017", "amount": "8743.26", "currency": "$", "action": "debit"},
	{"title": "Chami", "vendor": "Eu Nulla At Institute", "date": "5 Sep, 2017", "amount": "3112.89", "currency": "$", "action": "credit"},
	{"title": "Adobe", "vendor": "Arcu Nunc Inc.", "date": "22 Aug, 2017", "amount": "2239.85", "currency": "$", "action": "credit"},
	{"title": "Macromedia", "vendor": "Eros LLP", "date": "17 Feb, 2018", "amount": "3641.58", "currency": "$", "action": "debit"},
	{"title": "Macromedia", "vendor": "Diam Dictum Associates", "date": "24 Dec, 2016", "amount": "3592.79", "currency": "$", "action": "credit"},
	{"title": "Yahoo", "vendor": "Eget Odio Aliquam Corporation", "date": "30 Oct, 2016", "amount": "9453.17", "currency": "$", "action": "credit"},
	{"title": "Sibelius", "vendor": "Eros Non Enim Company", "date": "15 Feb, 2018", "amount": "5283.54", "currency": "$", "action": "debit"}
    ]
  }
];

// vars
var balance = 0;

// append cc to modal
var ccModalAppend= function(ccType, ccNum, month, year) {
	if(ccType == 'amex') {	
		$(".cc-select").prepend(
		  '<div class="cc ' +
		  ccType +
		  ' cc-active">\
		  <div class="cc-img-main"></div>\
		  <div class="cc-num">**** *******  ' +
		  ccNum +
		  '</div>\
		  <div class="cc-date">Valid Thru: ' +
		  month +
		  "/" +
		  year +
		  "</div>\
		  </div>"
		);
	} else {
		$(".cc-select").prepend(
		  '<div class="cc ' +
		  ccType +
		  ' cc-active">\
		  <div class="cc-img-main"></div>\
		  <div class="cc-num">**** **** **** ' +
		  ccNum +
		  '</div>\
		  <div class="cc-date">Valid Thru: ' +
		  month +
		  "/" +
		  year +
		  "</div>\
		  </div>"
		);
	}	
}


// append credit cards
var ccAppend = function(data) {
	$(".cc-select").append(
      '<div id="'+data.id+'" class="cc ' +
      data.type +
      '">\
      <div class="cc-img-main"></div>\
      <div class="cc-num">' +
      data.number +
      '</div>\
      <div class="cc-date">Valid Thru: ' +
      data.month +
      "/" +
      data.year +
      "</div>\
      </div>"
    )	
}

// load trams data 
var load = function(id, data) {  
      clearTrans();
      balance = 0;
      data.forEach(function(e) {
        if (e.id == id) {
          startAppend(e);
        }
      });
      balanceCalc(balance);  
      noTrans();
};

// count valid cc numbers
var countValid = function(ccType) {    
    if(ccType == 'amex') {
      if($('#ccnum').val().length != 15) {
        $('#ccnum').removeClass('valid-green')
        $('#ccnum').addClass('valid-red')
        return false;
      } else {
        $('#ccnum').addClass('valid-green')
        $('#ccnum').removeClass('valid-red')
        return true;
      }
    } else {
       if($('#ccnum').val().length != 16) {
        $('#ccnum').addClass('valid-red')
        $('#ccnum').removeClass('valid-green')
        return false;
      } else {
        $('#ccnum').addClass('valid-green')
        $('#ccnum').removeClass('valid-red')
        return true;
      }
    }  
}

// append trans data
var startAppend = function(e) {
    for (var i = 0; i < e.transactions.length; i++) {
        if (e.transactions[i].action == "credit") {
          var action = "trans-plus";
          var color = "green";
          balance = balance + parseFloat(e.transactions[i].amount,10);
        } else {
          var action = "trans-minus";
          var color = "blue";
          balance = balance - parseFloat(e.transactions[i].amount,10);
        }
        $(".trans-list").append(
          ' <div class="trans trans-' +
          e.type +
          '">\
          <div class="trans-details">\
          <span class="' +
          action +
          '"></span>\
          <h3 class="trans-name">' +
          e.transactions[i].title +
          '</h3>\
          <h5 class="trans-type-date">' +
          e.transactions[i].vendor +
          " - " +
          e.transactions[i].date +
		      '</h5>\
          </div>\
          <div class="trans-amt">\
          <h4 class="trans-amt amt-' +
          color +
          '">' +
          e.transactions[i].currency +
          " " +
          e.transactions[i].amount +
          "</h4>\
          </div>\
          </div>"
        ).show('fast');
      noTrans();
    }    
}

// calc balance and format
var balanceCalc = function balanceCalc(balance) {
     return balance < 0  ? $("#balance").html("$(" + Math.abs(balance).toLocaleString() + ")")  : $("#balance").html("$" + balance.toLocaleString() + "");
}

// clear trans list
var clearTrans = function(){
	$(".trans-list").empty().hide();
}

// clear modal
var clearModal = function() {
  $('.cc-img').removeClass('cc-md-active')
  $('#ccnum, #year, #month').val('')
  $('#ccnum').css('border','1px solid #e1e1e1;')
  $('#ccnum').removeClass('valid-red').removeClass('valid-green')
}

// no trans
var noTrans = function() {
    $('.trans-list').children().length == 0 ? $(".trans-list").append('<h5 class="no-trans"> No transactions for this card</h5>').show('fast') :"";
}

// load inital data
$(document).ready(function() {    
  data.forEach(function(e){
    ccAppend(e)
  })  
  $(".cc:eq(0)").addClass("cc-active")  
  load($(".cc-active").attr("id"),data)  
});

// click listener for active card
$(document).on("click", ".cc", function(e) {
  $(".cc").removeClass("cc-active");
  $(this).addClass("cc-active");
  load($(".cc-active").attr("id"),data)  
});

// click listener for active card in modal selector
$(document).on("click", ".cc-img", function(e) {
  $(".cc-img").removeClass("cc-md-active");
  $(this).addClass("cc-md-active");
  ($(".md-cc > .cc-md-active").attr("class").split(" ")[1] == 'amex') ? $('#ccnum').attr('placeholder','**** ****** *****') : $('#ccnum').attr('placeholder','**** **** **** ****')   
  $('#ccnum, #year, #month').removeAttr('disabled');
});

// close modal
$(document).on("click", ".modal-close", function(e) {
  $(".modal").hide();
  clearModal();
});

// open modal
$(".modal-open").on("click", function(e) {
  $(".modal").show();
});

// add new card logic
// TODO: Add numbous checks, sanitize, error catching
$(document).on("click", ".modal-add-cc", function(e) {
  var ccType = null;
  if ($(".md-cc > .cc-md-active").attr("class")) {
    ccType = $(".md-cc > .cc-md-active").attr("class").split(" ")[1];
  }
  var ccNum = $("#ccnum").val().substr($("#ccnum").val().length - 4);
  var month = $("#month").val();
  var year = $("#year").val();

  if (ccNum && month && year && ccType) {
    $(".modal").hide();
    $(".cc").removeClass("cc-active");
	
	  ccModalAppend(ccType,ccNum,month,year)
    var p = data[data.length-1].id + 1
    data.push({
      type: ccType,
      number: (ccType == 'amex') ? "**** ****** "+ccNum : "**** **** **** "+ccNum ,
      month: month,
      year: year,
      id: p,
      transactions: []
    })
    clearTrans()
    clearModal();
    load(ccType,data)
	
  } else {
    alert("Sorry, missing required fields"); // will do for now
  }
});

// keypress cc count
$('#ccnum').on('keyup', function(){
  var ccType = $(".md-cc > .cc-md-active").attr("class").split(" ")[1];
  countValid(ccType);
})
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js