feat(pages): create user profile page
This commit is contained in:
		
							parent
							
								
									8a042ec028
								
							
						
					
					
						commit
						a5ca37b4b7
					
				
							
								
								
									
										228
									
								
								pages/user/[id].vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								pages/user/[id].vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,228 @@ | ||||
| <script lang="ts" setup> | ||||
| 	import { format, formatDistanceToNow, formatRelative } from "date-fns"; | ||||
| 	import { IUser } from "~/models/user"; | ||||
| 	import { IStory } from "~/models/stories"; | ||||
| 	import { favourites } from "~/lib/client/listActions"; | ||||
| 	import singleStory from "~/components/listings/singleStory.vue"; | ||||
| 	import icon from "~/components/icon.vue"; | ||||
| 	import adminPanel from "~/components/profile/adminPanel.vue"; | ||||
| 
 | ||||
| 	const rtr = useRoute(); | ||||
| 	const { data } = useAuth(); | ||||
| 
 | ||||
| 	const { data: userInfo } = await useApiFetch<IUser>(`/user/${rtr.params.id}`); | ||||
| 	if (userInfo === null) { | ||||
| 		navigateTo("/"); | ||||
| 	} | ||||
| 	const activeKey = ref("main"); | ||||
| 	const activeFavKey = ref("favs/stories"); | ||||
| 	const uLastVisit = Date.parse( | ||||
| 		(userInfo.value?.lastVisit || | ||||
| 			userInfo.value?.lastLogin) as unknown as string, | ||||
| 	); | ||||
| 
 | ||||
| 	const isSelf = userInfo.value?._id === parseInt(rtr.params.id as string); | ||||
| 
 | ||||
| 	console.log("rtr", rtr); | ||||
| 	console.log("LVLVLVLVVLV", new Date(uLastVisit)); | ||||
| </script> | ||||
| <template> | ||||
| 	<a-card style="width: 100%"> | ||||
| 		<template #title> | ||||
| 			<div style="height: fit-content"> | ||||
| 				<a-card-meta style="align-items: center; margin: 0.5em"> | ||||
| 					<template #avatar> | ||||
| 						<a-avatar | ||||
| 							:size="75" | ||||
| 							:src="`/avatars/${userInfo?.profile.avatar}.png`" | ||||
| 						/> | ||||
| 					</template> | ||||
| 					<template #title> | ||||
| 						<a-typography-title :level="1" style="margin-top: 0.5em"> | ||||
| 							{{ userInfo!.username }} | ||||
| 						</a-typography-title> | ||||
| 					</template> | ||||
| 				</a-card-meta> | ||||
| 			</div> | ||||
| 			<a-badge-ribbon color="#d03f5b" v-if="userInfo?.profile.isAdmin"> | ||||
| 				<template #text> Administrator </template> | ||||
| 			</a-badge-ribbon> | ||||
| 		</template> | ||||
| 		<a-descriptions | ||||
| 			:column="2" | ||||
| 			:labelStyle="{ fontWeight: 'bold' }" | ||||
| 			:colon="false" | ||||
| 		> | ||||
| 			<a-descriptions-item label="Last visit"> | ||||
| 				<div v-if="userInfo?.banned" style="color: red; font-weight: bold"> | ||||
| 					BANNED | ||||
| 				</div> | ||||
| 				<div v-else-if="userInfo?.profile.hidden"> | ||||
| 					<i>Unknown</i> | ||||
| 				</div> | ||||
| 				<div v-else> | ||||
| 					<span> | ||||
| 						{{ format(uLastVisit, "MM/dd/yyyy @ hh:mm:ss a") }} | ||||
| 					</span> | ||||
| 					<span style="margin-left: 0.6em"> | ||||
| 						({{ formatDistanceToNow(uLastVisit, { addSuffix: true }) }}) | ||||
| 					</span> | ||||
| 				</div> | ||||
| 			</a-descriptions-item> | ||||
| 			<a-descriptions-item label="Website"> | ||||
| 				<a | ||||
| 					target="_blank" | ||||
| 					:href="`${ | ||||
| 						userInfo?.profile.website.startsWith('http') ? '' : 'http://' | ||||
| 					}${userInfo?.profile.website}`" | ||||
| 				> | ||||
| 					{{ userInfo?.profile.website }} | ||||
| 				</a> | ||||
| 			</a-descriptions-item> | ||||
| 			<a-descriptions-item label="Blog/Journal"> | ||||
| 				<a | ||||
| 					target="_blank" | ||||
| 					:href="`${ | ||||
| 						userInfo?.profile.blog.startsWith('http') ? '' : 'http://' | ||||
| 					}${userInfo?.profile.blog}`" | ||||
| 				> | ||||
| 					{{ userInfo?.profile.blog }} | ||||
| 				</a> | ||||
| 			</a-descriptions-item> | ||||
| 			<a-descriptions-item label="Occupation"> | ||||
| 				{{ userInfo?.profile.occupation }} | ||||
| 			</a-descriptions-item> | ||||
| 			<a-descriptions-item | ||||
| 				label="Email" | ||||
| 				v-if="userInfo?.profile.showEmail || data?.user?.profile.isAdmin" | ||||
| 			> | ||||
| 				{{ userInfo?.email }} | ||||
| 			</a-descriptions-item> | ||||
| 		</a-descriptions> | ||||
| 		<a-divider style="border: 1px solid #3e1560" /> | ||||
| 		<a-tabs centered v-model:active-key="activeKey"> | ||||
| 			<a-tab-pane key="main" tab="Profile"> | ||||
| 				<div v-html="userInfo?.profile.bio"></div> | ||||
| 			</a-tab-pane> | ||||
| 			<a-tab-pane key="stories" tab="Stories"> | ||||
| 				<listings-stories :prefix="`/user/${$route.params.id}/stories`" /> | ||||
| 			</a-tab-pane> | ||||
| 			<a-tab-pane key="favs" tab="Favourites"> | ||||
| 				<a-tabs centered v-model:active-key="activeFavKey"> | ||||
| 					<a-tab-pane key="favs/stories" tab="Stories"> | ||||
| 						<a-list | ||||
| 							:pagination="{ | ||||
| 								defaultPageSize: 20, | ||||
| 								total: userInfo?.favs.stories.length, | ||||
| 								defaultCurrent: 1, | ||||
| 								// onChange: pagiChange, | ||||
| 								hideOnSinglePage: true, | ||||
| 								showSizeChanger: false, | ||||
| 							}" | ||||
| 							:data-source="userInfo?.favs.stories" | ||||
| 							item-layout="vertical" | ||||
| 						> | ||||
| 							<template #renderItem="{ item }"> | ||||
| 								<!-- {{ item.title }} --> | ||||
| 								<a-row :gutter="[25, 0]" :align="'middle'"> | ||||
| 									<a-col :span="23"> | ||||
| 										<single-story :story="item" /> | ||||
| 									</a-col> | ||||
| 									<a-col :span="1" v-if="isSelf"> | ||||
| 										<a | ||||
| 											style="color: red" | ||||
| 											@click=" | ||||
| 												() => | ||||
| 													favourites( | ||||
| 														userInfo?.favs.stories || [], | ||||
| 														item._id, | ||||
| 														true, | ||||
| 														'story', | ||||
| 													) | ||||
| 											" | ||||
| 										> | ||||
| 											<icon istyle="regular" name="trash" color="#f00" /> | ||||
| 										</a> | ||||
| 									</a-col> | ||||
| 								</a-row> | ||||
| 							</template> | ||||
| 						</a-list> | ||||
| 					</a-tab-pane> | ||||
| 					<a-tab-pane key="favs/authors" tab="Authors"> | ||||
| 						<a-list | ||||
| 							item-layout="horizontal" | ||||
| 							:data-source="userInfo?.favs.authors" | ||||
| 							:grid="{ gutter: 16, column: 3 }" | ||||
| 						> | ||||
| 							<template #renderItem="{ item }"> | ||||
| 								<a-list-item style="display: flex; align-items: center"> | ||||
| 									<a-list-item-meta | ||||
| 										style="align-items: center; width: min-content" | ||||
| 									> | ||||
| 										<template #avatar> | ||||
| 											<a-avatar :src="`/avatars/${item.profile.avatar}.png`" /> | ||||
| 										</template> | ||||
| 										<template #title :style="{ background: 'pink' }"> | ||||
| 											<nuxt-link :to="`/user/${item._id}`"> | ||||
| 												{{ item.username }} | ||||
| 											</nuxt-link> | ||||
| 										</template> | ||||
| 									</a-list-item-meta> | ||||
| 									<template #actions v-if="isSelf"> | ||||
| 										<span> | ||||
| 											<a | ||||
| 												style="color: red" | ||||
| 												@click=" | ||||
| 													() => | ||||
| 														favourites( | ||||
| 															userInfo?.favs.authors || [], | ||||
| 															item._id, | ||||
| 															true, | ||||
| 															'author', | ||||
| 														) | ||||
| 												" | ||||
| 											> | ||||
| 												<icon istyle="regular" name="trash" color="#f00" /> | ||||
| 											</a> | ||||
| 										</span> | ||||
| 									</template> | ||||
| 								</a-list-item> | ||||
| 							</template> | ||||
| 						</a-list> | ||||
| 					</a-tab-pane> | ||||
| 				</a-tabs> | ||||
| 			</a-tab-pane> | ||||
| 			<a-tab-pane key="admin" tab="Admin" v-if="data?.user?.profile.isAdmin"> | ||||
| 				<admin-panel :user="userInfo" /> | ||||
| 			</a-tab-pane> | ||||
| 		</a-tabs> | ||||
| 	</a-card> | ||||
| </template> | ||||
| <style> | ||||
| 	.ant-list-item-action { | ||||
| 		width: min-content; | ||||
| 	} | ||||
| 
 | ||||
| 	.ant-ribbon-wrapper { | ||||
| 		position: unset !important; | ||||
| 		zoom: 200%; | ||||
| 	} | ||||
| 
 | ||||
| 	.ant-list-item-meta-title { | ||||
| 		margin-top: 0.1em; | ||||
| 	} | ||||
| 
 | ||||
| 	.ant-card-head-title, | ||||
| 	.ant-card-head { | ||||
| 		height: 110% !important; | ||||
| 	} | ||||
| 
 | ||||
| 	.ant-list-item-meta-content { | ||||
| 		align-self: center !important; | ||||
| 	} | ||||
| </style> | ||||
| <style scoped> | ||||
| 	.ant-list-items > * + * { | ||||
| 		margin-top: 1.2em; | ||||
| 	} | ||||
| </style> | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user