Skip to content

Instantly share code, notes, and snippets.

@lukemico
Created November 9, 2019 02:32
Show Gist options
  • Save lukemico/ba7d23f4c6e30d37f718b76ab9f6f096 to your computer and use it in GitHub Desktop.
Save lukemico/ba7d23f4c6e30d37f718b76ab9f6f096 to your computer and use it in GitHub Desktop.
ReactJS Bank App
<div id ="container" class="mainContainer"></div>

ReactJS Bank App

ReactJS form application showcasing a fake bank-account transfer funds screen with front-end side functionality and validation.

Includes examples of:

  • Validation
  • Modals
  • Controlled and Uncontrolled react form components
    • React Checkboxes.
    • React Selects.

Also Includes: Simple React Routing, and Google Maps integration

A Pen by Orlando Paredes Hamsho on CodePen.

License.

class Application extends React.Component{
constructor(props) {
super(props);
//Initializing State
this.state = {
route:"contact",
fromAccount:0,
toAccount:0,
transferType: "",
ammount: 0,
memo:{
text:"",
len:0
},
fromAccounts:[
{"id":"154","amount":1212.0,"name":"Jimmy's Account"},
{"id":"164","amount":1412.0,"name":"Account 1"},
{"id":"174","amount":1612.0,"name":"Account 2"},
{"id":"184","amount":1812.0,"name":"Account 3"},
{"id":"194","amount":1912.0,"name":"Account 4"},
{"id":"204","amount":2012.0,"name":"Account 5"}
],
toAccounts:[
{"id":"164","amount":1412.0,"name":"Account 1"},
{"id":"174","amount":1612.0,"name":"Account 2"},
{"id":"184","amount":1812.0,"name":"Account 3"},
{"id":"194","amount":1912.0,"name":"Account 4"},
{"id":"204","amount":2012.0,"name":"Account 5"}
],
startDate:this.getToday(),
endDate:null,
frequency:null,
modal:false,
form: [],
errors:[]
};
}
//Helper Functions
changeFrom(event){
const fromAccount = event.target.value;
let toAccounts = [...this.state.fromAccounts];
toAccounts = _.without(toAccounts,_.find(toAccounts,["id",fromAccount]));
const toAccount = (fromAccount === this.state.toAccount) ? 0 : this.state.toAccount;
this.setState({fromAccount,toAccounts, toAccount});
}
changeTo(event){this.setState({toAccount: event.target.value});}
changeAmmount(event){this.setState({ammount: event.target.value});}
changeMemo(event){this.setState({memo:{text:event.target.value,len:event.target.value.length}});}
changeTransfer(event){this.setState({transferType: event.target.value, endDate:null, frequency:null});}
changeFrequency(event){this.setState({frequency: event.target.value});}
changeStartDate(event){this.setState({startDate: event.target.value});}
changeEndDate(event){this.setState({endDate: event.target.value});}
showModal(modal){this.setState({modal})}
confirmSubmit(){this.setState({modal:false, route:"confirm" })}
restart(){this.setState({
route:"form",
fromAccount:0,
toAccount:0,
transferType: "",
ammount: 0,
memo:{
text:"",
len:0
},
startDate:this.getToday(),
endDate:null,
frequency:null,
modal:false,
form: [],
errors:[]
})}
setRoute(route){this.setState({route})}
validate(){
let errors = {};
let valid = true;
if(!this.state.fromAccount) errors.fromAccount="From Account Field is Required";
if(!this.state.toAccount) errors.toAccount="To Account Field is Required";
if(!this.state.startDate) errors.startDate="From Account Field is Required";
if(!this.state.ammount) errors.ammount="Ammount Field is Required";
if(!this.state.transferType){
errors.transferType="Transfer Type Field is Required";
}else if(this.state.transferType==="Automatic Transfer"){
if(!this.state.endDate) errors.endDate="End Date Field is Required";
if(!this.state.frequency) errors.frequency="Frequency Field is Required";
}
if (Object.getOwnPropertyNames(errors).length>0) valid = false;
this.setState({errors})
console.log(errors);
return valid;
}
getToday(){
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth()+1; //January is 0!
let yyyy = today.getFullYear();
if(dd<10) dd='0'+dd;
if(mm<10) mm='0'+mm;
today = yyyy+'-'+mm+'-'+dd;
return today;
}
//Handle Form Submitting
handleSubmit(event){
event.preventDefault();
if(!this.validate()) return;
this.setState({
modal:true,
form:[
{"From Account": this.state.fromAccount },
{"To Account": this.state.toAccount },
{"Transfer Type": this.state.transferType },
{"Date" : this.state.startDate },
{"End Date" : this.state.endDate },
{"Frequency": this.state.frequency },
{"Ammount": "$"+this.state.ammount },
{"Memo": this.state.memo.text }
]
})
}
//Helper Render Function
showHiddenFields(radio){
if(radio==="One Time Transfer"){
return (
<fieldset className={(this.state.errors.startDate)?"error" : ""}>
<label className="main-label">Transfer Date</label>
<input type="date" value={this.state.startDate} onChange={this.changeStartDate.bind(this)}/>
<i className="fa fa-calendar fa-fw"></i>
</fieldset>
);
}else if(radio==="Automatic Transfer"){
return (
<HiddenFields startDate={this.state.startDate} endDate={this.state.endDate} frequency={this.state.frequency}
changeStartDate={this.changeStartDate.bind(this)}
changeEndDate={this.changeEndDate.bind(this)}
changeFrequency={this.changeFrequency.bind(this)} errors={this.state.errors}/>
);
}
}
renderModal(){
if(!this.state.modal) return;
console.log("Showing Modal");
return(
<div className="modalWindow">
<div className="modal-content">
<a href="#" className="close-button" onClick={() => {this.showModal(false)}} />
<Verify form={this.state.form} showModal={this.showModal.bind(this)} confirmSubmit={this.confirmSubmit.bind(this)}/>
</div>
</div>
);
}
router(route){
if(route==="form"){
return(
<div>
<h3>Transfer Funds</h3>
<form onSubmit={this.handleSubmit.bind(this)} >
<Select onChange={this.changeFrom.bind(this)} account={this.state.fromAccount} title="From account"
css_class={(this.state.errors.fromAccount)?"half-width error" : "half-width"} serverResponse={this.state.fromAccounts}/>
<Select onChange={this.changeTo.bind(this)} account={this.state.toAccount} title="To account"
css_class={(this.state.errors.toAccount)?"half-width right error" : "half-width right"} serverResponse={this.state.toAccounts}/>
<fieldset className={(this.state.errors.transferType)?"half-width error" : "half-width"}>
<label className="main-label">Transfer Type</label>
<input type="radio" name="rad_transferType" id="radTransferType_ott" value="One Time Transfer"
onClick={this.changeTransfer.bind(this)}/>
<label htmlFor="radTransferType_ott">One-Time Transfer</label><br/>
<input type="radio" name="rad_transferType" id="radTransferType_at" value="Automatic Transfer"
onClick={this.changeTransfer.bind(this)}/>
<label htmlFor="radTransferType_at">Automatic Transfer</label>
</fieldset>
<fieldset className={(this.state.errors.ammount)?"half-width right error" : "half-width right"}>
<label className="main-label">Amount</label>
<i className="fa fa-dollar fa-fw"></i>
<input type="number" value={this.state.ammount} onChange={this.changeAmmount.bind(this)}/>
</fieldset>
{this.showHiddenFields(this.state.transferType)}
<Memo onChange={this.changeMemo.bind(this)} memo={this.state.memo} maxlen={120}/>
<fieldset className="button-holder">
<input type="button" className="button simpleButton" value="Cancel" />
<input type="submit" className="button CTAButton" value="Next" />
</fieldset>
</form>
</div>
);
} else if (route === "confirm"){
return <Confirm form={this.state.form} setRoute={this.restart.bind(this)}/>
} else if (route === "profile"){
return <Profile />;
} else if (route === "home"){
return <Home />;
} else if (route === "contact"){
return <Contact />;
}
}
render(){
console.log(this.state);
return (
<div className="divMain">
<Header setRoute={this.setRoute.bind(this)}/>
<section className="mainSection">
{this.router(this.state.route)}
</section>
<input type="checkbox" name="chkOpenMenu" id="chkOpenMenu" className="hide" />
<label htmlFor="chkOpenMenu" className="lblOpenMenu smallDisplay">
<span className="openItem"></span>
<span className="closeItem"></span>
</label>
<Footer/>
<input type="checkbox" name="chkShowFooter" id="chkShowFooter" defaultChecked="true" className="hide" />
{this.renderModal()}
</div>
);
}
}
const Header = (props) => {
return(
<div>
<div className="btnMenu" >
<label htmlFor="chkMenu">
<i className="fa fa-bars"></i>
</label>
</div>
<input type="checkbox" id="chkMenu" />
<nav className="menu">
<div className="title">National Bank</div>
<ul>
<li><label htmlFor="chkMenu" onClick={() => props.setRoute("profile")}>Transfer Activity</label></li>
<li><label htmlFor="chkMenu" onClick={() => props.setRoute("form")}>Transactions</label></li>
<li><label htmlFor="chkMenu" onClick={() => props.setRoute("contact")}>Contact</label></li>
</ul>
</nav>
</div>
);
}
const Memo = (props) => {
return(
<fieldset>
<label className="main-label">Memo (OPTIONAL: Maximum of {props.maxlen} characters)</label>
<textarea maxLength={props.maxlen} id="memoText" onChange={props.onChange} value={props.memo.text}/>
<span>{props.maxlen - props.memo.len} characters remaining.</span>
</fieldset>
);
}
class Select extends React.Component{
constructor(props) {
super(props);
}
componentWillMount(){
//Load Data here!
}
render(){
return(
<fieldset className={this.props.css_class}>
<label>{this.props.title}</label>
<i className="fa fa-user fa-fw"></i>
<select onChange={this.props.onChange} value={this.props.account}>
{this.props.serverResponse.map( (option) => {
return (
<option key={option.id} value={option.id}>
{option.name}
</option>
);
})}
</select>
</fieldset>
);
}
}
const HiddenFields = (props) => {
return (
<div>
<fieldset className={(props.errors.startDate)?"half-width error" : "half-width"}>
<label className="main-label">Start Date</label>
<input type="date" value={props.startDate} onChange={props.changeStartDate} />
<i className="fa fa-calendar fa-fw"></i>
</fieldset>
<fieldset className={(props.errors.endDate)?"half-width right error" : "half-width right"}>
<label className="main-label">End Date</label>
<input type="date" value={props.endDate} onChange={props.changeEndDate} />
<i className="fa fa-calendar fa-fw"></i>
</fieldset>
<fieldset className={(props.errors.frequency)?"error" : ""}>
<label className="main-label">Frequency</label>
<select value={props.frequency} onChange={props.changeFrequency}>
<option value="Weekly">Weekly</option>
<option value="Bi-Monthly">1st and 15th of each month</option>
<option value="Monthly">Every Month</option>
<option value="Every Two Months">Every Two Months</option>
</select>
<i className="fa fa-refresh fa-fw"></i>
</fieldset>
</div>
);
}
const Verify = (props) => {
return(
<div>
<h3>Please verify your data</h3>
<div className="modal-body">
<Summary form={props.form}/>
<fieldset className="button-holder">
<input type="button" className="button simpleButton" value="Previous" onClick={() => props.showModal(false)} />
<input type="submit" className="button CTAButton" value="Submit" onClick={() => props.confirmSubmit()}/>
</fieldset>
</div>
</div>
);
}
const Confirm = (props) => {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10) dd='0'+dd;
if(mm<10) mm='0'+mm;
today = mm+'/'+dd+'/'+yyyy;
return(
<div className="confirm">
<div className="notice success">
<i className="fa fa-smile-o"></i>
<p>Your transfer has been successfully completed on {today} with confirmation number {Math.random() * 10000000000000000}</p>
</div>
<h3>Summary</h3>
<Summary form={props.form}/>
<div className="button-holder">
<input type="button" className="button CTAButton" value="Do Another Transaction" onClick={() => props.setRoute("form")}/>
</div>
</div>
);
}
const Summary = (props) => {
return(
<dl>
{props.form.map(
(field) => {
var key = Object.getOwnPropertyNames(field);
if(!field[key[0]]) return null;
return (
<div key={key[0]+field[key[0]]}>
<dt>{key[0]}</dt>
<dd>{field[key[0]]}</dd>
</div>
);
}
)}
</dl>
);
}
const pendingData = [
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"},
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"},
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"},
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"},
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"},
{Type:"Automatic", Amount:"$2.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/23/2016"}
];
const processedData = [
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
{Type:"Automatic", Amount:"$5.99", From:"Account 1", To:"Account 2", "Transaction Date":"05/24/2016"},
];
const Profile = (props) => {
return(
<div className="transfer-activity profile">
<h3>Transfer Activity</h3>
<h4>Pending Transfers</h4>
<SimpleTable data={processedData}/>
<h4>Processed Transfers</h4>
<SimpleTable data={pendingData}/>
</div>
);
}
class SimpleTable extends React.Component{
constructor(props){
super(props);
this.state = {
header:[]
}
}
componentWillMount(){
this.setState({header:Object.getOwnPropertyNames(this.props.data[0])});
}
renderHeader(columns){
return(
<thead>
<tr>
{columns.map((column, index) => {
return(
<td key={index}>{column}</td>
);
})}
</tr>
</thead>
);
}
renderBody(rows, columns){
return(
<tbody>
{rows.map((row,index) => {
return(
<tr key={index}>
{columns.map((column,innerIndex) => {
return (
<td key={innerIndex}>{row[column]}</td>
);
})}
</tr>
)
})}
</tbody>
);
}
render(){
if(this.state.header.length === 0) return false;
return(
<div className="transfer-activity-table">
<table className="">
{this.renderHeader(this.state.header)}
{this.renderBody(this.props.data,this.state.header)}
</table>
</div>
);
}
}
class GMap extends React.Component {
state = { zoom: 10 };
static propTypes() {
initialCenter: React.PropTypes.objectOf(React.PropTypes.number).isRequired
}
render() {
return <div className="GMap">
<div className='GMap-canvas' ref="mapCanvas">
</div>
</div>
}
componentDidMount() {
// create the map, marker and infoWindow after the component has
// been rendered because we need to manipulate the DOM for Google =(
this.map = this.createMap()
this.marker = this.createMarker()
this.infoWindow = this.createInfoWindow()
// have to define google maps event listeners here too
// because we can't add listeners on the map until its created
google.maps.event.addListener(this.map, 'zoom_changed', ()=> this.handleZoomChange())
}
// clean up event listeners when component unmounts
componentDidUnMount() {
google.maps.event.clearListeners(map, 'zoom_changed')
}
createMap() {
let mapOptions = {
zoom: this.state.zoom,
center: this.mapCenter()
}
return new google.maps.Map(this.refs.mapCanvas, mapOptions)
}
mapCenter() {
return new google.maps.LatLng(
this.props.initialCenter.lat,
this.props.initialCenter.lng
)
}
createMarker() {
return new google.maps.Marker({
position: this.mapCenter(),
map: this.map
})
}
createInfoWindow() {
let contentString = "<div class='InfoWindow'>National Bank</div>"
return new google.maps.InfoWindow({
map: this.map,
anchor: this.marker,
content: contentString
})
}
handleZoomChange() {
this.setState({
zoom: this.map.getZoom()
})
}
}
var initialCenter = { lng: -103.4054536, lat: 20.6737777 }
const Contact = (props) => {
return(
<div className="profile">
<h3>Contact Page</h3>
<GMap initialCenter={initialCenter} />
<ul className="profile-content">
<li>
<h4>Phone Number</h4>
<p>555-555555</p>
</li>
<li>
<h4>Email</h4>
<p>national@bank.com</p>
</li>
<li>
<h4>Location</h4>
<p>27 Maple Drive, Washington DC</p>
</li>
</ul>
</div>
);
}
const Footer = (props) => {
return(
<footer>
<div className="firstLevelFooter"></div>
<div className="secondLevelFooter"></div>
</footer>
);
}
ReactDOM.render(<Application/>,document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=Lato:300,400,700&subset=latin-ext');
@import url('https://fonts.googleapis.com/css?family=Open+Sans:700');
.GMap {
padding-top: 60%;
width: 100%;
position: relative;
}
.GMap-canvas {
top:10px;
display: block;
width: 100%;
height: 100%;
position: absolute;
}
/*
Z-map:
wantToContainer 5
lblOpenMenu 10
*/
/* [START] Added by FGP on 10:07am Mar 3 2016 */
body{
overflow-x: hidden;
}
footer{
width:200%;
position:relative;
left:-50%;
}
.mainContainer{
display:inline-block;
width:100%;
max-width:1024px;
}
.divMain header{
display:none;
}
/*** Menu **/
.menu{
position:relative;
background-color:#004B8C;
width:100%;
/*
width:85%;
max-width:1024px;
*/
display:inline-block;
width: 200%;
position: relative;
left: -50%;
}
.menu:after{
content:"";
display:block;
position:absolute;
width:3px;
background-color:#FFC107;
height:100%;
top:0;
right:3%;
}
.menu:before{
content:"";
display:block;
position:absolute;
width:3px;
background-color:RED;
height:100%;
top:0;
right:2%;
}
.menu .title{
color:#fff;
font-size:2rem;
font-family: 'Open Sans', sans-serif;
margin:0.8em 0 0 0;
}
.menu ul{
list-style:none;
margin:20px 0 0 0;
padding:0;
text-align:center;
}
.menu li{
display:inline-block;
text-align:center;
width:150px;
}
.menu li:hover{
background-color:#0F74CC;
}
.menu a, .menu label{
text-decoration:none;
color:WHITE;
display:inline-block;
cursor: pointer;
padding-top:2px;
padding-bottom:2px;
position:relative;
min-width:100px;
width:auto;
height:30px;
line-height:30px;
cursor: pointer;
padding: 2px 10px;
}
.menu a:hover{
}
#chkMenu{
display:none;
}
.btnMenu{
display:none;
position: fixed;
top: 15px;
left: 15px;
z-index: 1;
}
.btnMenu i{cursor:pointer}
@media only screen and (max-width: 520px){
p{
text-align:justify;
text-indent: 1.5rem;
font-size:.8rem;
}
.menu:after{
width:100%;
height:2px;
top:45px;
left:0;
}
.menu:before{
width:100%;
height:2px;
top:40px;
left:0;
}
.menu .title{
position:absolute;
top:0;
left:0;
}
.btnMenu{
display:inline-block;
}
.mainContainer{
margin-top:50px;
}
.menu{
position:fixed;
top:0;
z-index:10;
width:50%;
min-width: 250px;
height:100%;
transition: left 500ms linear;
-webkit-transition: left 500ms linear;
box-shadow: 2px 0 10px rgba(0,0,0,1);
}
#chkMenu + .menu{
//display:none;
left:-90%;
}
#chkMenu:checked + .menu{
//display:block;
left:0;
}
.menu ul{
margin-top:50px;
}
.menu li{
display:block;
}
.menu a{
width:80%;
text-align:left;
}
p{
text-align: left;
text-indent: inherit;
font-size: 1em;
}
}
/* [END] Added by FGP on 10:08am Mar 3 2016*/
*{
font-family: 'Lato', sans-serif;
}
body, html{
padding:0;
margin:0;
background: #fbfbfb;
background: -moz-linear-gradient(top, #fbfbfb 0%, #ededed 46%, #ededed 100%);
background: -webkit-linear-gradient(top, #fbfbfb 0%, #ededed 46%, #ededed 100%);
background: linear-gradient(to bottom, #fbfbfb 0%, #ededed 46%, #ededed 100%);
text-align:center;
}
main{
width:970px;
max-width:100%;
position:relative;
text-align:left;
display:inline-block;
background-color:WHITE;
min-height: 700px;
margin-bottom:30px;
}
.divMain{
width:inherit;
max-width:inherit;
position: relative
}
header{
height:122px;
width:100%;
background-color:#223D84;
}
h2{
margin:20px;
border-bottom:1px solid #abc1cf;
color:#696969;
font-size:20px;
font-weight:100;
}
h1, h2, h3, h4{
padding:0 20px;
margin: 1.5em 0 1em 0;
text-align: left;
color: #004B8C;
}
/******************************************************************/
form{
width:100%;
font-size:16px;
text-align:left;
padding: 20px 20px;
}
form, form *{box-sizing: border-box;}
label{
font-weight:bold;
color:#004B8C;
cursor: pointer;
}
.main-label{
display:block;
margin: 25px 0 0 0;
}
input[type=text],
input[type=number],
input[type=date],
textarea,
select{
width:100%;
display:block;
padding:8px;
margin: 5px 0 0 0;
font-size:16px;
transition: border-color 1s ease;
}
input[type=number],input[type=date],select{padding-left:30px;}
option{position: relative}
input[type=radio] {
margin: 0 10px 0 0;
display: inline-block;
vertical-align:middle;
}
input[type=radio] + label {
display: inline-block;
vertical-align:middle;
}
textarea{padding-bottom:20px;}
textarea+span{
position:absolute;
bottom: 8px;
right:8px;
color:rgb(0,120,0);
}
#radTransferType_ott{
margin-top: 5px;
}
fieldset{
border:none;
padding:0;
margin:0;
position:relative;
}
fieldset .fa{
position:absolute;
bottom: 11px; left:8px;
text-align:center;
}
input[type=date]~.fa{bottom:13px;}
.half-width{
display:inline-block;
width:45%;
vertical-align: top;
margin: 0 5% 10px 0;
}
.half-width.right{
margin: 0 0 10px 5%;
}
.button-holder{
margin-top: 30px;
text-align:right;
}
.error{
color:red !important;
}
.error label:after{
content: "(Required)";
color: red;
display:inline-block;
margin-left: 5px;
}
.error input[type=text],
.error input[type=date],
.error input[type=number],
.error select{
border:1px solid red;
}
/*****************************Modal********************************/
.modalWindow{
position: fixed;
width: 100%;
background: rgba(0,0,0,0.5);
top: 0;
left: 0;
height: 100%;
text-align: center;
z-index: 2;
}
.modalWindow .modal-content {
display: block;
text-align: left;
background: white;
box-shadow: 0px 2px 5px rgba(0,0,0,0.5);
max-width: 90%;
max-height:90%;
width: 600px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
font-size: 16px;
z-index: 2;
}
.modalWindow * {
box-sizing: border-box;
}
.modalWindow .modal-body{
max-height: 350px;
position: relative;
overflow: auto;
}
.modalWindow h3{
padding: 2em;
margin: 0;
text-align: center;
background: #004B8C;
color: white;
}
.modalWindow .button-holder{
padding: 0 2em 1em 2em;
}
a.close-button{
background: #000;
color:#fff;
border:1px solid white;
border-radius: 200em;
padding:10px;
display:block;
position: absolute;
left:100%;
top: 0;
transform: translate(-50%,-50%);
}
a.close-button:after{
font-size:16px;
content: "x";
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
}
dl {
margin: 0;
padding: 0;
paddinG: 0 2em 1em 2em;
}
dl div {
font-size: 0;
word-break: break-all;
hyphens: auto;
}
dt {
display: inline-block;
width: 30%;
font-size: 16px;
}
dd {
display: inline-block;
width: 70%;
font-size: 16px;
}
dd, dt {
padding: 5px;
margin: 0;
vertical-align: top;
}
/****************************Confirm******************************/
.confirm{
text-align:left;
}
.confirm *{
box-sizing: border-box;
}
.confirm dl{
background: white;
border-radius: 0 0 10px 10px;
}
.confirm h3{
margin: 1em 0 0 0;
padding: 0;
background: #fff;
padding: 20px 1.8em;
border-radius: 10px 10px 0 0;
}
.confirm .button {
width: auto;
}
.confirm .button-holder {
margin: 30px 20px 20px 20px;
}
/****************************Notice*******************************/
.notice{
border: 1px solid gold;
background: lightyellow;
padding: 10px;
color: goldenrod;
text-align: left;
position: relative;
border-radius: 10px;
margin:20px;
}
.notice.error{}
.notice.success{
border-color: green;
color: green;
background: lightgreen;
}
.notice .fa{
display: block;
font-size: 2em;
vertical-align:middle;
position: absolute;
left:10px;
top:50%;
transform:translate(0,-50%);
}
.notice p{
display: inline-block;
vertical-align:middle;
width:100%;
padding: 0 10px 0 40px;
}
/************************Transfer-Activity**************************/
.transfer-activity h3,.transfer-activity h4{padding:0}
.transfer-activity h3{margin:0 0 1.5em 0}
.transfer-activity h4{text-align:left;margin-top:1em;}
.transfer-activity tbody tr{cursor:pointer}
.table-hover>tbody>tr:hover {
background-color: #fff;
}
/****************************Profile*******************************/
.profile {
padding:20px
}
.profile h3, .profile h4{padding: 0; margin-top:8px;}
.profile-picture{
display:block;
width: 100px;
height: 100px;
border:1px solid #B1B1B1;
color:#B1B1B1;
padding:0;
margin: 10px auto;
font-size:100px;
position:relative;
}
.profile-picture .fa{
position: absolute;
display: block;
left: 50%;
top: 50%;
transform:translate(-50%,-50%);
}
.profile-content{
margin:0;
padding:0;
padding-top:20px;
}
.profile-content li{
list-style:none;
text-align: left;
}
.profile img{
width:100%;
height:auto;
margin-bottom:10px;
}
/*Table*/
.transfer-activity-table{
width:100%;
overflow-x:auto;
margin-bottom: 5%;
}
.transfer-activity-table table{
width:100%;
max-width:100%;
min-width: 600px;
text-align:center;
border-collapse:collapse;
margin-top:10px;
}
.transfer-activity-table thead {
background:#004B8C;
color:white;
}
.transfer-activity-table tbody tr:hover {
background:#ddd;
}
.transfer-activity-table th {
padding: 1em 10px;
}
.transfer-activity-table td {
padding: 1em 10px;
}
/******************************************************************/
.mainSection{
width: calc(100% - 100px);
display:inline-block;
margin:25px;
background-color: #fff;
margin-top:45px;
}
/* Main Footer and Content */
.mainFooter{
width:100%;
background-color:#f6f9fa;
min-height:300px;
}
.firstLevelFooter{
background-color:#f2f2f2;
height:84px;
}
.secondLevelFooter{
min-height:36px;
background: #004B8C;
color:WHITE;
text-align:center;
font-weight:bold;
font-size:12px;
}
.secondLevelFooter a{
display:inline-block;
position:relative;
//height:100%;
padding:11px;
color:WHITE;
text-decoration:none;
}
.secondLevelFooter a:hover{
background-color:#d0e5f4;
color:#00233b;
cursor:pointer;
}
.thirdLevelFooter{
height:275px;
background-color:#f6f9fa;
position:relative;
}
/* Flying Popup (fixed at bottom) */
.flyPopup{
color:WHITE;
background-color:#003a57;
position:fixed;
bottom:0;
margin-left:auto;
margin-right:auto;
left:0;
right:0;
border-top-left-radius:10px;
border-top-right-radius:10px;
width:inherit;
font-size:10px;
padding:10px;
}
.footerCloseBtn{
position:absolute;
right:-5px;
top:-5px;
color:GREEN;
background-color:WHITE;
border: solid 1px gray;
width:10px;
height:10px;
text-align:center;
}
#chkShowFooter{
position:fixed;
top:0;
}
#chkShowFooter + .flyPopup{
display:none;
}
#chkShowFooter:checked + .flyPopup{
display:block;
}
/* I want to... menu */
.lblOpenMenu{
color:WHITE;
}
.wantToContainer{
position: static;
display: none;
float: right;
right: 0;
background-color: #f6f6f6;
border: 1px solid #e9e9e9;
width: 209px;
padding-bottom: 15px;
margin-top:15px;
}
.wantToContainer ul{
margin: 0 25px;
width: 158px;
padding: 0;
border-bottom: 1px dotted #B8B8B8;
}
.wantToContainer li{
font-size:12px;
color:#0b6997;
/*background; url(https://statmcstg.usaa.com/mcontent/static_assets/Media/control_sprite.png) no-repeat -13000px -2px;*/
list-style: none;
padding: 0 0 10px 14px;
}
.wantToContainer a{
color:inherit;
text-decoration:none;
}
.wantToContainer a:hover{
text-decoration:underline;
}
.wantToContainer h4{
font-weight:bold;
text-transform:uppercase;
margin:5px;
color: #666666;
font-size:11px;
}
/* UTILITIES */
.hide{
display:none;
}
.smallDisplay{
display:none;
}
.bigDisplay{
display:block;
}
.button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0 5px;
padding: 10px;
width: 100px;
border:0;
color: white;
cursor: pointer;
font-size: 16px;
}
.simpleButton{
background: #B00D20;
}
.simpleButton:hover{
background:#da132a;
}
.CTAButton{
background: #004B8C;
}
.CTAButton:hover{
background: #0F74CC;
}
@media screen and (max-width:600px){
.half-width,.half-width.right{
width:100%;
margin:20px 0 0 0;
}
}
@media screen and (max-width:480px){
dl dt,dl dd{
width:100%;
margin-top: 5px;
}
dl dd{text-align:right}
.mainSection{
width: 90%;
margin:25px;
}
.wantToContainer{
padding:0;
margin:0;
top:0;
width:100%;
position:fixed;
z-index:5;
overflow:hidden;
transition: height 400ms linear;
-webkit-transition: height 400ms linear;
-moz-transition: height 400ms linear;
-o-transition: height 400ms linear;
transition: height 400ms linear;
}
.wantToContainer ul{
border:none;
}
.wantToContainer li{
display:inline-block;
width:100%;
}
.lblOpenMenu{
position:fixed;
top:0;
right:0;
z-index:10;
}
/* Menu control for phone-size display */
#chkOpenMenu + label + aside{
overflow:hidden;
height:0;
}
#chkOpenMenu:checked + label + aside{
height:140px;
}
#chkOpenMenu + label .openItem{
display:block;
}
#chkOpenMenu:checked + label .openItem{
display:none;
}
#chkOpenMenu + label .closeItem{
display:none;
color:BLACK;
}
#chkOpenMenu:checked + label .closeItem{
display:block;
}
/* small utilities */
.smallDisplay{
display:block;
}
.bigDisplay{
display:none !important;
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment