Implement mockup for profile page

This commit is contained in:
Tuan Duong 2019-04-22 22:56:22 +07:00
parent d8dbf92b47
commit cde663ab15
8 changed files with 426 additions and 4 deletions

View File

@ -58,3 +58,11 @@ export function numberFormatter(num, digits) {
export function toThousandFilter(num) {
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}
/**
* Upper case first char
* @param {String} string
*/
export function uppercaseFirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1555641167698" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="977" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M702.784 879.008c-55.84 0-148.992 16.48-163.552 54.496l0 0.832c-32.448 0.864-40.032 0-54.496 0-14.528-38.048-107.68-54.528-163.552-54.528l-299.84 0 0-790.496 326.016 0c70.368 0 131.168 36.128 164.608 89.504 33.408-53.344 94.304-89.504 164.704-89.504l326.016 0 0 789.728-299.872-0.032zM484.736 252.864c0-63.744-68.832-109.024-136.288-109.024l-272.608 0 0 681.44 245.344 0c54.08-0.928 139.36 0.544 163.552 40.416l0-30.56c-1.024-37.792-0.032-89.312 0-91.36l0-473.408 0.032-17.536zM948.128 143.776l-272.544 0c-67.488 0-136.32 45.28-136.32 108.928l0 490.464c0.032 2.112 1.056 53.6 0 91.232l0 30.56c24.192-39.776 109.472-41.344 163.552-40.384l245.344 0 0-680.768z" p-id="978"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

1
src/icons/svg/skill.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1555640763920" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1499" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M264.032 719.136l256.064 0c11.04 17.088 23.584 32.96 37.792 47.296l-293.856 0 0-47.296zM264.032 644.32l221.664 0c-4.48-15.264-7.712-31.04-9.696-47.264l-211.968 0 0 47.264zM264.032 522.272l212.64 0c2.208-16.16 5.472-32.032 10.272-47.264l-222.944 0 0 47.264zM677.344 839.168l0 41.344c0 19.776-16.064 35.872-35.776 35.872l-537.184 0c-19.744 0-35.744-16.096-35.744-35.872l0-599.168 178.016-148.128 0 157.248-93.728 0 0 47.264 140.992 0 0-230.048 347.648 0c19.744 0 35.776 16.096 35.776 35.808l0 141.408c15.232-4.768 31.072-7.968 47.296-10.208l0-131.168c0.032-45.792-37.248-83.104-83.04-83.104l-381.408 0-238.816 198.72 0 621.344c0 45.792 37.248 83.104 83.04 83.104l537.184 0c45.792 0 83.072-37.248 83.072-83.104l0-31.168c-16.224-2.208-32.064-5.408-47.296-10.144l0 0zM199.84 475.04l-61.024 0 0 47.264 61.024 0 0-47.264zM138.848 766.432l61.024 0 0-47.296-61.024 0 0 47.296zM199.84 597.088l-61.024 0 0 47.264 61.024 0 0-47.264zM887.648 490.784l-37.536-28.768-95.424 124.48-85.792-65.76-28.832 37.536 123.36 94.56 124.224-162.048zM1002.656 562.048c0-131.68-107.104-238.752-238.784-238.752-131.616 0-238.688 107.104-238.688 238.752s107.104 238.752 238.688 238.752c131.648 0 238.752-107.072 238.752-238.752l0 0zM955.36 562.048c0 105.536-85.888 191.52-191.52 191.52-105.568 0-191.552-85.92-191.552-191.52s85.824-191.52 191.552-191.52c105.632 0 191.52 85.92 191.52 191.52l0 0z" p-id="1500"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -61,12 +61,14 @@ export default {
theme: 'Theme',
clipboardDemo: 'Clipboard',
i18n: 'I18n',
externalLink: 'External Link'
externalLink: 'External Link',
profile: 'Profile'
},
navbar: {
logOut: 'Log Out',
dashboard: 'Dashboard',
github: 'Github',
logOut: 'Log Out',
profile: 'Profile',
theme: 'Theme',
size: 'Global Size'
},

View File

@ -61,12 +61,14 @@ export default {
theme: '换肤',
clipboardDemo: 'Clipboard',
i18n: '国际化',
externalLink: '外链'
externalLink: '外链',
profile: '个人资料页'
},
navbar: {
logOut: '退出登录',
dashboard: '首页',
github: '项目地址',
logOut: '退出登录',
profile: '个人资料页',
theme: '换肤',
size: '布局大小'
},

View File

@ -26,6 +26,11 @@
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
<router-link to="'/profile/index">
<el-dropdown-item>
{{ $t('navbar.profile') }}
</el-dropdown-item>
</router-link>
<router-link to="/">
<el-dropdown-item>
{{ $t('navbar.dashboard') }}

View File

@ -107,6 +107,20 @@ export const constantRoutes = [
meta: { title: 'guide', icon: 'guide', noCache: true }
}
]
},
{
path: '/profile',
component: Layout,
redirect: '/profile/index',
hidden: true,
children: [
{
path: 'index',
component: () => import('@/views/profile/index'),
name: 'Profile',
meta: { title: 'profile', icon: 'user', noCache: true }
}
]
}
]

389
src/views/profile/index.vue Normal file
View File

@ -0,0 +1,389 @@
<template>
<div class="app-container">
<el-form v-if="user" :model="user">
<el-row :gutter="20">
<el-col :span="6">
<el-card>
<div class="user-profile">
<div class="user-avatar box-center">
<pan-thumb :image="user.avatar" :height="'100px'" :width="'100px'" :hoverable="false" />
</div>
<div class="box-center">
<div class="user-name text-center">{{ user.name }}</div>
<div class="user-role text-center text-muted">{{ user.role | uppercaseFirst }}</div>
</div>
<div class="box-social">
<el-table :data="social" :show-header="false">
<el-table-column
prop="name"
label="Name"
/>
<el-table-column label="Count" align="left" width="100">
<template slot-scope="scope">
{{ scope.row.count | toThousandFilter }}
</template>
</el-table-column>
</el-table>
</div>
<div class="user-follow">
<el-button type="primary" style="width: 100%;">Follow</el-button>
</div>
</div>
</el-card>
<el-card class="box-card user-bio">
<div slot="header" class="clearfix">
<span>About me</span>
</div>
<div class="user-education user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="education" /><span>Education</span></div>
<div class="user-bio-section-body">
<div class="text-muted">
B.S. in Computer Science from the University of Technology
</div>
</div>
</div>
<div class="user-skills user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="skill" /><span>Skills</span></div>
<div class="user-bio-section-body">
<div class="progress-item">
<span>Vue</span>
<el-progress :percentage="70" />
</div>
<div class="progress-item">
<span>JavaScript</span>
<el-progress :percentage="18" />
</div>
<div class="progress-item">
<span>Css</span>
<el-progress :percentage="12" />
</div>
<div class="progress-item">
<span>ESLint</span>
<el-progress :percentage="100" status="success" />
</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="18">
<el-card>
<el-tabs v-model="activeActivity" @tab-click="handleClick">
<el-tab-pane label="Activity" name="first">
<div class="user-activity">
<div class="post">
<div class="user-block">
<img class="img-circle" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRDkaQO69Fro8SZLTVZQ75JH2R0T-sn5yIA_lKGwvvgQ0R0BoQtUQ" alt="user image">
<span class="username text-muted">
<a href="#">Iron Man</a>
<a href="#" class="pull-right btn-box-tool"><i class="fa fa-times" /></a>
</span>
<span class="description">Shared publicly - 7:30 PM today</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<ul class="list-inline">
<li><a href="#" class="link-black text-sm"><i class="el-icon-share" /> Share</a></li>
<li><a href="#" class="link-black text-sm"><svg-icon icon-class="like" /> Like</a></li>
<li class="pull-right">
<a href="#" class="link-black text-sm"><svg-icon icon-class="comment" /> Comments
(5)</a></li>
</ul>
<el-input v-model="input.comment1" placeholder="Type a comment" />
</div>
<div class="post">
<div class="user-block">
<img class="img-circle" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQMMN-8f9CQQ3MKJpboBJIqaiJ2Wus2Tf4w_vx9STtalxrY3qGJ" alt="user image">
<span class="username text-muted">
<a href="#">Captain American</a>
<a href="#" class="pull-right btn-box-tool"><i class="fa fa-times" /></a>
</span>
<span class="description">Sent you a message - yesterday</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<el-input v-model="input.reply" placeholder="Response">
<el-button slot="append">Send</el-button>
</el-input>
</div>
<div class="post">
<div class="user-block">
<img class="img-circle img-bordered-sm" src="https://cdn3.iconfinder.com/data/icons/movies-3/32/daredevil-superhero-marvel-comics-mutant-avatar-512.png" alt="User Image">
<span class="username">
<a href="#">Daredevil</a>
<a href="#" class="pull-right btn-box-tool"><i class="fa fa-times" /></a>
</span>
<span class="description">Posted 4 photos - 2 days ago</span>
</div>
<div class="user-images">
<el-carousel :interval="6000" type="card" height="200px">
<el-carousel-item v-for="item in carouselImages" :key="item">
<img :src="item" class="image">
</el-carousel-item>
</el-carousel>
</div>
<ul class="list-inline">
<li><a href="#" class="link-black text-sm"><i class="el-icon-share" /> Share</a></li>
<li><a href="#" class="link-black text-sm"><svg-icon icon-class="like" /> Like</a></li>
<li class="pull-right">
<a href="#" class="link-black text-sm"><svg-icon icon-class="comment" /> Comments
(5)</a></li>
</ul>
<el-input v-model="input.comment2" placeholder="Type a comment" />
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Timeline" name="second">
<div class="block">
<el-timeline>
<el-timeline-item timestamp="2019/4/20" placement="top">
<el-card>
<h4>Update Github template</h4>
<p>PanJiaChen committed 2019/4/20 20:46</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2019/4/21" placement="top">
<el-card>
<h4>Update Github template</h4>
<p>PanJiaChen committed 2019/4/21 20:46</p>
</el-card>
<el-card>
<h4>Update Github template</h4>
<p>PanJiaChen committed 2019/4/21 21:16</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2019/4/22" placement="top">
<el-card>
<h4>Deploy <a href="https://Panjiachen.github.io/vue-element-admin/" target="_blank">vue-template-admin</a></h4>
<p>PanJiaChen deployed 2019/4/22 10:23</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-tab-pane>
<el-tab-pane v-loading="updating" label="Account" name="third">
<el-form-item label="Name">
<el-input v-model="user.name" />
</el-form-item>
<el-form-item label="Email">
<el-input v-model="user.email" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Update</el-button>
</el-form-item>
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import PanThumb from '@/components/PanThumb'
export default {
name: 'EditUser',
components: { PanThumb },
data() {
return {
user: null,
social: [
{
'name': 'Followers',
'count': 1235
},
{
'name': 'Following',
'count': 23512
},
{
'name': 'Friends',
'count': 7242
}
],
activeActivity: 'first',
carouselImages: [
'https://cdn.laravue.dev/photo1.jpg',
'https://cdn.laravue.dev/photo2.jpg',
'https://cdn.laravue.dev/photo3.jpg',
'https://cdn.laravue.dev/photo4.jpg'
],
updating: false,
input: {
comment1: '',
comment2: '',
reply: ''
}
}
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
},
created() {
this.getUser()
},
methods: {
getUser() {
this.user = {
name: this.name,
role: this.roles.join(' | '),
email: 'admin@test.com',
avatar: this.avatar
}
},
handleClick(tab, event) {
console.log('Switching tab ', tab, event)
},
onSubmit() {
this.updating = true
setTimeout(() => {
this.$message({
message: 'User information has been updated successfully',
type: 'success',
duration: 5 * 1000
})
this.updating = false
}, 1000)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.user-profile {
.user-name {
font-weight: bold;
}
.box-center {
padding-top: 10px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.box-social {
padding-top: 30px;
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-bio {
margin-top: 20px;
color: #606266;
span {
padding-left: 4px;
}
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
.user-activity {
.user-block {
.username, .description {
display: block;
margin-left: 50px;
padding: 2px 0;
}
img {
width: 40px;
height: 40px;
float: left;
}
:after {
clear: both;
}
.img-circle {
border-radius: 50%;
border: 2px solid #d2d6de;
padding: 2px;
}
span {
font-weight: 500;
font-size: 12px;
}
}
.post {
font-size: 14px;
border-bottom: 1px solid #d2d6de;
margin-bottom: 15px;
padding-bottom: 15px;
color: #666;
.image {
width: 100%;
}
.user-images {
padding-top: 20px;
}
}
.list-inline {
padding-left: 0;
margin-left: -5px;
list-style: none;
li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
font-size: 13px;
}
.link-black {
&:hover, &:focus {
color: #999;
}
}
}
.el-carousel__item h3 {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 200px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
}
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
.pull-right {
float: right !important;
}
</style>