Modrinth/pages/user/_id.vue
venashial 4d64df37f5
Versatile auth URLs & many UI fixes (#199)
* Make project cards right-align their last element

Spaces out elements in a `.project-card` using `justify-content: space-between;`.

Fixes modrinth/knossos#170

* Automatically set URL for auth redirect

* Make login button use base url or current origin

Allows the login button to work in dev environment

* Remove Axios base URL trailing slash

* Update authUrl() on dashboard to match default

* Remove 'code' query from URL on page load
Allow non-exact paths to highlight mod & dashboard tabs

Fixes modrinth/knossos#200

* Make page 5 button visible on page 4 (pagination)

Fixes modrinth/knossos#184

* Color links on legal pages

Fixes modrinth/knossos#166

* Set max notifications to 5 and ignore duplicates

Fixes modrinth/knossos#175

* Add space above report button when no user desc

Fixes modrinth/knossos#143

* Better text spacing from edge of mobile screen

Fixes modrinth/knossos#179

* Fix slanted bars in modrinth/knossos#57

* Fix checkbox grid and role label

Fixes modrinth/knossos#191

* Move mod 'settings' button to the far right

Fixes modrinth/knossos#138

* Abbreviate minutes to min. when time is too long

Not a perfect solution imo, but works for now

Fixes modrinth/knossos#193

* Fix mobile header margins & add breakpoints

Fixes modrinth/knossos#203

* Clean up nuxt config
Silence babel warning & styleResources

* Upgrade sass-loader to 10.1.1 and remove warning

* Remove added horizontal footer padding

https://github.com/modrinth/knossos/pull/199#discussion_r629011624

* Improve mobile header fix

* Fix up minor inconsistencies in mod header

* Remove hard coded date

* Cleans up pagination to be more intuitive

* Fixes member invite input on moble

* Fix login button when searching mods

* Improved mobile mod search

Consistently sized pagination buttons

Breakpoint for sort buttons on smaller screens

* Consistent link style on text-only pages

* Better 4k support

* Slightly better mobile project-card support

Shuffles categories under mod icon when there is room

* Animate homepage typewriter effect backwards

* Tiny commit to align mod icons in mod headers

* Make processing status include 'Under Review'

This can be later updated once the backend has a separate status

* Create vercel.json

* Update domain auto detection

* Test vercel NODE_ENV

* Remove console.log for debugging hosting services

* Make mobile first + fix shrinked text circle size

* Optimize SVG

* Change media queries to be more mobile first

* Remove `|| window.location.origin`

* re-deploy vercel

* Change "Processing" message to "Under review"
2021-05-27 09:27:13 -07:00

251 lines
6.1 KiB
Vue

<template>
<div class="page-container">
<div class="page-contents">
<div class="sidebar-l">
<div class="card">
<div class="user-info">
<img :src="user.avatar_url" :alt="user.username" />
<div class="text">
<h2>{{ user.username }}</h2>
<p v-if="user.role === 'admin'" class="badge red">Admin</p>
<p v-if="user.role === 'moderator'" class="badge yellow">
Moderator
</p>
<p v-if="user.role === 'developer'" class="badge green">
Developer
</p>
</div>
</div>
<p v-if="user.bio" class="bio">{{ user.bio }}</p>
<div class="buttons">
<nuxt-link
v-if="this.$auth.user && this.$auth.user.id != user.id"
:to="`/report/create?id=${user.id}&t=user`"
class="iconified-button"
>
<ReportIcon />
Report
</nuxt-link>
</div>
</div>
<div class="card stats">
<div class="stat">
<CalendarIcon />
<div class="info">
<h4>Joined</h4>
<p
v-tooltip="
$dayjs(user.created).format(
'[Joined] YYYY-MM-DD [at] HH:mm A'
)
"
class="value"
>
{{ $dayjs(user.created).fromNow() }}
</p>
</div>
</div>
<div class="stat">
<DownloadIcon />
<div class="info">
<h4>Downloads</h4>
<p class="value">
{{ sumDownloads() }}
</p>
</div>
</div>
</div>
<Advertisement
type="square"
small-screen="square"
ethical-ads-big
ethical-ads-small
ethical-ad-type="image"
/>
<m-footer class="footer" hide-small />
</div>
<div class="content">
<Advertisement type="banner" small-screen="destroy" />
<div class="mods">
<SearchResult
v-for="result in mods"
:id="result.slug || result.id"
:key="result.id"
:name="result.title"
:description="result.description"
:created-at="result.published"
:updated-at="result.updated"
:downloads="result.downloads.toString()"
:icon-url="result.icon_url"
:author-url="result.author_url"
:categories="result.categories"
:is-modrinth="true"
/>
</div>
<m-footer class="footer" hide-big centered />
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import SearchResult from '~/components/ui/ProjectCard'
import MFooter from '~/components/layout/MFooter'
import ReportIcon from '~/assets/images/utils/report.svg?inline'
import CalendarIcon from '~/assets/images/utils/calendar.svg?inline'
import DownloadIcon from '~/assets/images/utils/download.svg?inline'
import Advertisement from '~/components/ads/Advertisement'
export default {
auth: false,
components: {
Advertisement,
SearchResult,
CalendarIcon,
DownloadIcon,
MFooter,
ReportIcon,
},
async asyncData(data) {
try {
let res = await axios.get(
`https://api.modrinth.com/api/v1/user/${data.params.id}`
)
const user = res.data
let mods = []
res = await axios.get(
`https://api.modrinth.com/api/v1/user/${user.id}/mods`
)
if (res.data) {
res = await axios.get(
`https://api.modrinth.com/api/v1/mods?ids=${JSON.stringify(res.data)}`
)
mods = res.data
}
return {
mods,
user,
}
} catch {
data.error({
statusCode: 404,
message: 'User not found',
})
}
},
methods: {
formatNumber(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
},
sumDownloads() {
let sum = 0
for (const mod of this.mods) {
sum += mod.downloads
}
return this.formatNumber(sum)
},
},
head() {
return {
title: this.user.username + ' - Modrinth',
meta: [
{
hid: 'og:type',
name: 'og:type',
content: 'website',
},
{
hid: 'og:title',
name: 'og:title',
content: this.user.username,
},
{
hid: 'apple-mobile-web-app-title',
name: 'apple-mobile-web-app-title',
content: this.user.username,
},
{
hid: 'og:description',
name: 'og:description',
content: this.user.bio,
},
{
hid: 'description',
name: 'description',
content:
this.user.bio +
' - View minecraft mods on Modrinth today! Modrinth is a new and modern Minecraft modding platform that is compatible with CurseForge too!',
},
{
hid: 'og:url',
name: 'og:url',
content: `https://modrinth.com/user/${this.user.id}`,
},
{
hid: 'og:image',
name: 'og:image',
content:
this.user.avatar_url || 'https://cdn.modrinth.com/placeholder.png',
},
],
}
},
}
</script>
<style lang="scss" scoped>
.sidebar-l {
@media screen and (min-width: 1024px) {
min-width: 21rem;
}
.user-info {
@extend %row;
img {
width: 6rem;
height: 6rem;
margin-right: var(--spacing-card-md);
border-radius: var(--size-rounded-icon);
}
.text {
h2 {
margin: 0;
color: var(--color-text-dark);
font-size: var(--font-size-lg);
}
.badge {
display: inline-block;
}
}
}
.buttons {
@extend %column;
margin-top: 16px;
.iconified-button {
max-width: 4.5rem;
}
}
.stats {
display: flex;
flex-wrap: wrap;
.stat {
@extend %stat;
svg {
padding: 0.25rem;
border-radius: 50%;
background-color: var(--color-button-bg);
}
}
}
}
</style>