next/pages/user/[id].vue

229 lines
6.2 KiB
Vue
Raw Normal View History

2023-10-10 22:44:04 -04:00
<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>