React Profile Card with image upload
A Pen by HARUN PEHLİVAN on CodePen.
<div id="root"></div> | |
<a target="_blank" title="instagram/web__addict" href="https://www.instagram.com/harunpehlivantebimtebitagem/"><i class="fab fa-instagram"></i></a> |
React Profile Card with image upload
A Pen by HARUN PEHLİVAN on CodePen.
const ImgUpload =({ | |
onChange, | |
src | |
})=> | |
<label htmlFor="photo-upload" className="custom-file-upload fas"> | |
<div className="img-wrap img-upload" > | |
<img for="photo-upload" src={src}/> | |
</div> | |
<input id="photo-upload" type="file" onChange={onChange}/> | |
</label> | |
const Name =({ | |
onChange, | |
value | |
})=> | |
<div className="field"> | |
<label htmlFor="name"> | |
name: | |
</label> | |
<input | |
id="name" | |
type="text" | |
onChange={onChange} | |
maxlength="25" | |
value={value} | |
placeholder="Alexa" | |
required/> | |
</div> | |
const Status =({ | |
onChange, | |
value | |
})=> | |
<div className="field"> | |
<label htmlFor="status"> | |
status: | |
</label> | |
<input | |
id="status" | |
type="text" | |
onChange={onChange} | |
maxLength="35" | |
value={value} | |
placeholder="It's a nice day!" | |
required/> | |
</div> | |
const Profile =({ | |
onSubmit, | |
src, | |
name, | |
status, | |
})=> | |
<div className="card"> | |
<form onSubmit={onSubmit}> | |
<h1>Profile Card</h1> | |
<label className="custom-file-upload fas"> | |
<div className="img-wrap" > | |
<img for="photo-upload" src={src}/> | |
</div> | |
</label> | |
<div className="name">{name}</div> | |
<div className="status">{status}</div> | |
<button type="submit" className="edit">Edit Profile </button> | |
</form> | |
</div> | |
const Edit =({ | |
onSubmit, | |
children, | |
})=> | |
<div className="card"> | |
<form onSubmit={onSubmit}> | |
<h1>Profile Card</h1> | |
{children} | |
<button type="submit" className="save">Save </button> | |
</form> | |
</div> | |
class CardProfile extends React.Component { | |
state = { | |
file: '', | |
imagePreviewUrl: 'https://github.com/OlgaKoplik/CodePen/blob/master/profile.jpg?raw=true', | |
name:'', | |
status:'', | |
active: 'edit' | |
} | |
photoUpload = e =>{ | |
e.preventDefault(); | |
const reader = new FileReader(); | |
const file = e.target.files[0]; | |
reader.onloadend = () => { | |
this.setState({ | |
file: file, | |
imagePreviewUrl: reader.result | |
}); | |
} | |
reader.readAsDataURL(file); | |
} | |
editName = e =>{ | |
const name = e.target.value; | |
this.setState({ | |
name, | |
}); | |
} | |
editStatus = e => { | |
const status = e.target.value; | |
this.setState({ | |
status, | |
}); | |
} | |
handleSubmit= e =>{ | |
e.preventDefault(); | |
let activeP = this.state.active === 'edit' ? 'profile' : 'edit'; | |
this.setState({ | |
active: activeP, | |
}) | |
} | |
render() { | |
const {imagePreviewUrl, | |
name, | |
status, | |
active} = this.state; | |
return ( | |
<div> | |
{(active === 'edit')?( | |
<Edit onSubmit={this.handleSubmit}> | |
<ImgUpload onChange={this.photoUpload} src={imagePreviewUrl}/> | |
<Name onChange={this.editName} value={name}/> | |
<Status onChange={this.editStatus} value={status}/> | |
</Edit> | |
):( | |
<Profile | |
onSubmit={this.handleSubmit} | |
src={imagePreviewUrl} | |
name={name} | |
status={status}/>)} | |
</div> | |
) | |
} | |
} | |
ReactDOM.render( | |
<CardProfile/>, | |
document.getElementById('root') | |
) |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/5.0.1/react-router.min.js"></script> |
body{ | |
font-family: 'Hind Guntur', sans-serif; | |
color: #054231; | |
display: flex; | |
justify-content: center; | |
background: #49afa8; | |
background-image: url('https://res.cloudinary.com/tercuman-b-l-m-merkez/image/upload/v1622918289/leaf_xe3rvr.png'); | |
background-repeat: no-repeat, no-repeat; | |
background-position: 200% -40%; | |
background-size: 80%; | |
} | |
.card{ | |
width: 310px; | |
height: 627px; | |
padding: 15px; | |
margin-top: 40px; | |
border-radius: 25px; | |
display: flex; | |
justify-content: center; | |
box-shadow: 15px 10px 25px 0px #3fa1a9; | |
background: #fff; | |
background-image: url('https://res.cloudinary.com/tercuman-b-l-m-merkez/image/upload/v1622918361/leaf2_tqnrvr.png'); | |
background-repeat: no-repeat, no-repeat; | |
background-position: 120% -5%, 200% -40%; | |
background-size: 40%, 80%; | |
animation: open .5s; | |
} | |
@keyframes open { | |
0% {background-position: 166% -25%, 220% -69%;} | |
100%{background-position: 120% -5%, 200% -40%;} | |
} | |
form{ | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
} | |
.field{ | |
margin: 5px; | |
display: flex; | |
flex-direction: column; | |
} | |
input[type="file"] { | |
display: none; | |
} | |
.custom-file-upload { | |
border-radius: 50%; | |
display: inline-block; | |
position: relative; | |
padding: 6px; | |
cursor: pointer; | |
background: linear-gradient(270deg, #3fa1a9, #79f1a4); | |
margin-bottom: 25px; | |
} | |
.img-wrap{ | |
position: relative; | |
width: 200px; | |
height: 200px; | |
overflow: hidden; | |
border-radius: 50%; | |
} | |
.img-upload:before{ | |
content: "\f093"; | |
font-size: 90px; | |
position: absolute; | |
padding-top: 80px; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
text-align: center; | |
color: #63d3a6; | |
width: 200px; | |
height: 200px; | |
border-radius: 50%; | |
opacity: 0; | |
transition: .5s ease; | |
background-color: #fff; | |
} | |
.img-upload:hover:before{ | |
opacity: 1; | |
} | |
img { | |
width: auto; | |
height: 100%; | |
} | |
label{ | |
text-transform: uppercase; | |
font-weight: 700; | |
color: #676767; | |
} | |
input{ | |
border-radius: 15px; | |
border: 1px solid #b7b7b7; | |
padding: 5px 5px 5px 10px; | |
font-size: 18px; | |
transition: 0.2s; | |
} | |
input:focus{ | |
outline: none; | |
border: 1px solid #64d488; | |
} | |
input::placeholder{ | |
color: #bebebe; | |
} | |
.name{ | |
text-align: center; | |
text-transform: uppercase; | |
font-weight: 700; | |
color: #676767; | |
max-width: 220px; | |
overflow-wrap: break-word; | |
} | |
.status{ | |
text-align: center; | |
max-width: 220px; | |
overflow-wrap: break-word; | |
} | |
button{ | |
position: relative; | |
color: #054231; | |
letter-spacing: 1px; | |
margin: 20px; | |
font-size: 18px; | |
padding: 10px; | |
text-align: center; | |
transition: 0.5s; | |
border-radius: 10px; | |
cursor: pointer; | |
border-radius: 25px; | |
border: none; | |
background: #64d488; | |
} | |
.save{ | |
font-weight: 600; | |
left: -20px; | |
text-transform: uppercase; | |
letter-spacing: 1px; | |
width: 20px; | |
box-shadow: 20px 0px 40px 0px #63d3a6; | |
} | |
.edit{ | |
color: #fff; | |
width: 180px; | |
} | |
button:hover{ | |
left: 0; | |
color: #fff; | |
width: 180px; | |
box-shadow: 0px 0px 20px 0px #63d3a6; | |
} | |
button:focus{ | |
outline: none; | |
} | |
.lds-ripple { | |
display: inline-block; | |
position: relative; | |
width: 64px; | |
height: 64px; | |
} | |
.lds-ripple div { | |
position: absolute; | |
border: 4px solid #fff; | |
opacity: 1; | |
border-radius: 50%; | |
animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; | |
} | |
.lds-ripple div:nth-child(2) { | |
animation-delay: -0.5s; | |
} | |
.fa-instagram{ | |
position: absolute; | |
color: #79f1a4; | |
top: 3%; | |
right: 2%; | |
font-size: 38px; | |
} | |
.fa-instagram:hover{ | |
font-size: 42px; | |
color: #caff81; | |
transition: all .1s linear; | |
cursor: pointer; | |
} |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" rel="stylesheet" /> | |
<link href="https://fonts.googleapis.com/css?family=Hind+Guntur:300,400,500,600,700&display=swap" rel="stylesheet" /> |