feat: add profile page
This commit is contained in:
parent
0c93b0f2b1
commit
581b5891f2
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<div class="profile-page">
|
||||
<div class="user-info">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-10 offset-md-1">
|
||||
<img
|
||||
:src="profile.image"
|
||||
class="user-img"
|
||||
>
|
||||
<h4>{{ profile.username }}</h4>
|
||||
<p v-if="profile.bio">
|
||||
{{ profile.bio }}
|
||||
</p>
|
||||
<button
|
||||
v-if="isUserAuthorized"
|
||||
class="btn btn-sm btn-outline-secondary action-btn"
|
||||
>
|
||||
<i class="ion-plus-round" />
|
||||
|
||||
Follow {{ profile.username }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-10 offset-md-1">
|
||||
<div class="articles-toggle">
|
||||
<ul class="nav nav-pills outline-active">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link active"
|
||||
href=""
|
||||
>My Articles</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
href=""
|
||||
>Favorited Articles</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="article-preview">
|
||||
<div class="article-meta">
|
||||
<a href=""><img src="http://i.imgur.com/Qr71crq.jpg"></a>
|
||||
<div class="info">
|
||||
<a
|
||||
href=""
|
||||
class="author"
|
||||
>Eric Simons</a>
|
||||
<span class="date">January 20th</span>
|
||||
</div>
|
||||
<button class="btn btn-outline-primary btn-sm pull-xs-right">
|
||||
<i class="ion-heart" /> 29
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
href=""
|
||||
class="preview-link"
|
||||
>
|
||||
<h1>How to build webapps that scale</h1>
|
||||
<p>This is the description for the post.</p>
|
||||
<span>Read more...</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="article-preview">
|
||||
<div class="article-meta">
|
||||
<a href=""><img src="http://i.imgur.com/N4VcUeJ.jpg"></a>
|
||||
<div class="info">
|
||||
<a
|
||||
href=""
|
||||
class="author"
|
||||
>Albert Pai</a>
|
||||
<span class="date">January 20th</span>
|
||||
</div>
|
||||
<button class="btn btn-outline-primary btn-sm pull-xs-right">
|
||||
<i class="ion-heart" /> 32
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
href=""
|
||||
class="preview-link"
|
||||
>
|
||||
<h1>The song you won't ever stop singing. No matter how hard you try.</h1>
|
||||
<p>This is the description for the post.</p>
|
||||
<span>Read more...</span>
|
||||
<ul class="tag-list">
|
||||
<li class="tag-default tag-pill tag-outline">Music</li>
|
||||
<li class="tag-default tag-pill tag-outline">Song</li>
|
||||
</ul>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
import { useProfile } from '../services/profile/getProfile'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Profile',
|
||||
setup () {
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
|
||||
const username = computed<string>(() => route.params.username as string)
|
||||
|
||||
const { profile } = useProfile(username.value)
|
||||
|
||||
const isUserAuthorized = computed(() => store.state.user !== null)
|
||||
|
||||
return {
|
||||
profile,
|
||||
isUserAuthorized,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
@ -10,6 +10,8 @@ const router = createRouter({
|
|||
{ path: '/article/:slug', component: () => import('./pages/Article.vue') },
|
||||
{ path: '/login', component: () => import('./pages/Login.vue') },
|
||||
{ path: '/register', component: () => import('./pages/Register.vue') },
|
||||
{ path: '/@:username', component: () => import('./pages/Profile.vue') },
|
||||
{ path: '/@:username/favorites', component: () => import('./pages/Profile.vue') },
|
||||
],
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -67,10 +67,6 @@ export async function deleteFavoriteArticle (slug: string) {
|
|||
return request.delete<ArticleResponse>(`/articles/${slug}/favorite`).then(res => res.article)
|
||||
}
|
||||
|
||||
export async function getProfile (username: string) {
|
||||
return request.get<ProfileResponse>(`/profiles/${username}`).then(res => res.profile)
|
||||
}
|
||||
|
||||
export async function putProfile (form: Partial<Profile>) {
|
||||
return request.put<ProfileResponse>('/user', form).then(res => res.profile)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
import { reactive, watchEffect } from 'vue'
|
||||
import { request } from '../index'
|
||||
|
||||
export async function getProfile (username: string) {
|
||||
return request.get<ProfileResponse>(`/profiles/${username}`).then(res => res.profile)
|
||||
}
|
||||
|
||||
export function useProfile (username: string) {
|
||||
const profile = reactive<Profile>({} as Profile)
|
||||
|
||||
async function fetchProfile () {
|
||||
const profileData = await getProfile(username)
|
||||
Object.assign(profile, profileData)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
fetchProfile()
|
||||
})
|
||||
|
||||
return {
|
||||
profile,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue