You've already forked AstralRinth
forked from didirus/AstralRinth
Project, Search, User redesign (#1281)
* New project page * fix silly icon tailwind classes * Start new versions page, add new ButtonStyled component * Pagination and finish mocking up versions page functionality * green download button * hover animation * New Modal, Avatar refactor, subpages in NavTabs * lint * Download modal * New user page + fix lint * fix ui lint * Download animation fix * Versions filter + finish project page * Improve consistency of buttons on home page * Fix ButtonStyled breaking * Fix margin on version summary * finish search, new modals, user + project page mobile * fix gallery image pages * New project header * Fix gallery tab showing improperly * Use auto direction + position for all popouts * Preliminary user page * test to see if this fixes login stuff * remove extra slash * Add version actions, move download button on versions page * Listed -> public * Shorten download modal selector height * Fix user menu open direction * Change breakpoint for header collapse * Only underline title * Tighten padding on stats a little * New nav * Make mobile breakpoint more consistent * fix header breakpoint regression * Add sign in button * Fix edit icon color * Fix margin at top of screen * Fix user bios and ad width * Fix user nav showing when there's only one type of project * Fix plural projects on user page & extract i18n * Remove ads on mobile for now * Fix overflow menu showing hidden items * NavTabs on mobile * Fix navbar z index * Search filter overhaul + negative filters * fix no-max-height * port version filters, fix following/collections, lint * hide promos * ui lint * Disable modal background animation to reduce reported motion sickness * Hide install with modrinth app button on mobile --------- Signed-off-by: Geometrically <18202329+Geometrically@users.noreply.github.com> Co-authored-by: Prospector <prospectordev@gmail.com>
This commit is contained in:
@@ -1,169 +1,81 @@
|
||||
<template>
|
||||
<div v-if="user">
|
||||
<div v-if="user" class="experimental-styles-within">
|
||||
<ModalCreation ref="modal_creation" />
|
||||
<CollectionCreateModal ref="modal_collection_creation" />
|
||||
<div class="user-header-wrapper">
|
||||
<div class="user-header">
|
||||
<Avatar :src="user.avatar_url" size="md" circle :alt="user.username" />
|
||||
<h1 class="username">
|
||||
{{ user.username }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="normal-page">
|
||||
<div class="normal-page__sidebar">
|
||||
<div class="card sidebar">
|
||||
<h1 class="mobile-username">
|
||||
{{ user.username }}
|
||||
</h1>
|
||||
<div class="card__overlay">
|
||||
<NuxtLink
|
||||
v-if="auth.user && auth.user.id === user.id"
|
||||
to="/settings/profile"
|
||||
class="iconified-button"
|
||||
>
|
||||
<EditIcon />
|
||||
{{ formatMessage(commonMessages.editButton) }}
|
||||
</NuxtLink>
|
||||
<button
|
||||
v-else-if="auth.user"
|
||||
class="iconified-button"
|
||||
@click="() => reportUser(user.id)"
|
||||
>
|
||||
<ReportIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.profileReportButton) }}
|
||||
</button>
|
||||
<nuxt-link v-else class="iconified-button" to="/auth/sign-in">
|
||||
<ReportIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.profileReportButton) }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="sidebar__item">
|
||||
<Badge v-if="tags.staffRoles.includes(user.role)" :type="user.role" />
|
||||
<Badge v-else-if="isPermission(user.badges, 1 << 0)" type="plus" />
|
||||
<Badge v-else-if="projects.length > 0" type="creator" />
|
||||
</div>
|
||||
<span v-if="user.bio" class="sidebar__item bio">{{ user.bio }}</span>
|
||||
<hr class="card-divider" />
|
||||
<div class="primary-stat">
|
||||
<DownloadIcon class="primary-stat__icon" aria-hidden="true" />
|
||||
<div class="primary-stat__text">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileDownloadsStats"
|
||||
:values="{ count: formatCompactNumber(sumDownloads) }"
|
||||
>
|
||||
<template #stat="{ children }">
|
||||
<span class="primary-stat__counter">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
<div class="primary-stat">
|
||||
<HeartIcon class="primary-stat__icon" aria-hidden="true" />
|
||||
<div class="primary-stat__text">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileProjectsFollowersStats"
|
||||
:values="{ count: formatCompactNumber(sumFollows) }"
|
||||
>
|
||||
<template #stat="{ children }">
|
||||
<span class="primary-stat__counter">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-block__item secondary-stat">
|
||||
<SunriseIcon class="secondary-stat__icon" aria-hidden="true" />
|
||||
<span
|
||||
v-tooltip="
|
||||
formatMessage(commonMessages.dateAtTimeTooltip, {
|
||||
date: new Date(user.created),
|
||||
time: new Date(user.created),
|
||||
})
|
||||
"
|
||||
class="secondary-stat__text date"
|
||||
>
|
||||
{{
|
||||
formatMessage(messages.profileJoinedAt, { ago: formatRelativeTime(user.created) })
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<hr class="card-divider" />
|
||||
<div class="stats-block__item secondary-stat">
|
||||
<UserIcon class="secondary-stat__icon" aria-hidden="true" />
|
||||
<span class="secondary-stat__text">
|
||||
<IntlFormatted :message-id="messages.profileUserId">
|
||||
<template #~id>
|
||||
<CopyCode :text="user.id" />
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</span>
|
||||
</div>
|
||||
<template v-if="organizations.length > 0">
|
||||
<hr class="card-divider" />
|
||||
<div class="stats-block__item">
|
||||
<IntlFormatted :message-id="messages.profileOrganizations" />
|
||||
<div class="organizations-grid">
|
||||
<nuxt-link
|
||||
v-for="org in organizations"
|
||||
:key="org.id"
|
||||
v-tooltip="org.name"
|
||||
class="organization"
|
||||
:to="`/organization/${org.slug}`"
|
||||
>
|
||||
<Avatar :src="org.icon_url" :alt="'Icon for ' + org.name" size="xs" />
|
||||
</nuxt-link>
|
||||
<div class="new-page sidebar">
|
||||
<div class="normal-page__header pt-4">
|
||||
<div
|
||||
class="mb-4 grid grid-cols-1 gap-x-8 gap-y-6 border-0 border-b border-solid border-button-bg pb-6 lg:grid-cols-[1fr_auto]"
|
||||
>
|
||||
<div class="flex gap-4">
|
||||
<Avatar :src="user.avatar_url" :alt="user.username" size="96px" circle />
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<h1 class="m-0 text-2xl font-extrabold leading-none text-contrast">
|
||||
{{ user.username }}
|
||||
</h1>
|
||||
</div>
|
||||
<p class="m-0 line-clamp-2 max-w-[40rem]">
|
||||
{{
|
||||
user.bio
|
||||
? user.bio
|
||||
: projects.length === 0
|
||||
? "A Modrinth user."
|
||||
: "A Modrinth creator."
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center gap-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<ButtonStyled size="large">
|
||||
<NuxtLink v-if="auth.user && auth.user.id === user.id" to="/settings/profile">
|
||||
<EditIcon />
|
||||
{{ formatMessage(commonMessages.editButton) }}
|
||||
</NuxtLink>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled size="large" circular type="transparent">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{
|
||||
id: 'manage-projects',
|
||||
action: () => navigateTo('/dashboard/projects'),
|
||||
hoverOnly: true,
|
||||
shown: auth.user && auth.user.id === user.id,
|
||||
},
|
||||
{ divider: true, shown: auth.user && auth.user.id === user.id },
|
||||
{
|
||||
id: 'report',
|
||||
action: () => reportUser(user.id),
|
||||
color: 'red',
|
||||
hoverOnly: true,
|
||||
},
|
||||
{ id: 'copy-id', action: () => copyId() },
|
||||
]"
|
||||
>
|
||||
<MoreVerticalIcon />
|
||||
<template #manage-projects>
|
||||
<BoxIcon />
|
||||
{{ formatMessage(messages.profileManageProjectsButton) }}
|
||||
</template>
|
||||
<template #report>
|
||||
<ReportIcon />
|
||||
{{ formatMessage(commonMessages.reportButton) }}
|
||||
</template>
|
||||
<template #copy-id>
|
||||
<ClipboardCopyIcon />
|
||||
{{ formatMessage(commonMessages.copyIdButton) }}
|
||||
</template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="navLinks.length > 2" class="mb-4 max-w-full overflow-x-auto">
|
||||
<NavTabs :links="navLinks" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="normal-page__content">
|
||||
<Promotion v-if="!auth.user || !isPermission(auth.user.badges, 1 << 0)" :external="false" />
|
||||
<nav class="navigation-card">
|
||||
<NavRow
|
||||
:links="[
|
||||
{
|
||||
label: formatMessage(commonMessages.allProjectType),
|
||||
href: `/user/${user.username}`,
|
||||
},
|
||||
...projectTypes.map((x) => {
|
||||
return {
|
||||
label: formatMessage(getProjectTypeMessage(x, true)),
|
||||
href: `/user/${user.username}/${x}s`,
|
||||
};
|
||||
}),
|
||||
]"
|
||||
/>
|
||||
<div class="input-group">
|
||||
<NuxtLink
|
||||
v-if="auth.user && auth.user.id === user.id"
|
||||
class="iconified-button"
|
||||
to="/dashboard/projects"
|
||||
>
|
||||
<SettingsIcon />
|
||||
{{ formatMessage(messages.profileManageProjectsButton) }}
|
||||
</NuxtLink>
|
||||
<button
|
||||
v-if="route.params.projectType !== 'collections'"
|
||||
v-tooltip="
|
||||
formatMessage(commonMessages[`${cosmetics.searchDisplayMode.user}InputView`])
|
||||
"
|
||||
:aria-label="
|
||||
formatMessage(commonMessages[`${cosmetics.searchDisplayMode.user}InputView`])
|
||||
"
|
||||
class="square-button"
|
||||
@click="cycleSearchDisplayMode()"
|
||||
>
|
||||
<GridIcon v-if="cosmetics.searchDisplayMode.user === 'grid'" />
|
||||
<ImageIcon v-else-if="cosmetics.searchDisplayMode.user === 'gallery'" />
|
||||
<ListIcon v-else />
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div v-if="projects.length > 0">
|
||||
<div
|
||||
v-if="route.params.projectType !== 'collections'"
|
||||
@@ -268,7 +180,10 @@
|
||||
<span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text">
|
||||
<IntlFormatted :message-id="messages.profileNoCollectionsAuthLabel">
|
||||
<template #create-link="{ children }">
|
||||
<a class="link" @click.prevent="$refs.modal_collection_creation.show()">
|
||||
<a
|
||||
class="link"
|
||||
@click.prevent="(event) => $refs.modal_collection_creation.show(event)"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</a>
|
||||
</template>
|
||||
@@ -277,33 +192,135 @@
|
||||
<span v-else class="text">{{ formatMessage(messages.profileNoCollectionsLabel) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="normal-page__sidebar">
|
||||
<AdPlaceholder />
|
||||
<div class="card flex-card">
|
||||
<h2 class="text-lg text-contrast">{{ formatMessage(messages.profileDetails) }}</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<BoxIcon aria-hidden="true" class="stroke-[3] text-secondary" />
|
||||
<div class="text-secondary">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileProjectsStats"
|
||||
:values="{ count: formatCompactNumber(projects.length) }"
|
||||
>
|
||||
<template #stat="{ children }">
|
||||
<span class="font-bold text-primary">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<DownloadIcon aria-hidden="true" class="stroke-[3] text-secondary" />
|
||||
<div class="text-secondary">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileDownloadsStats"
|
||||
:values="{ count: formatCompactNumber(sumDownloads) }"
|
||||
>
|
||||
<template #stat="{ children }">
|
||||
<span class="font-bold text-primary">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<HeartIcon aria-hidden="true" class="text-secondary *:stroke-[3]" />
|
||||
<div class="text-secondary">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileProjectsFollowersStats"
|
||||
:values="{ count: formatCompactNumber(sumFollows) }"
|
||||
>
|
||||
<template #stat="{ children }">
|
||||
<span class="font-bold text-primary">
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<CalendarIcon aria-hidden="true" class="text-secondary *:stroke-[3]" />
|
||||
<div class="text-secondary">
|
||||
<IntlFormatted
|
||||
:message-id="messages.profileJoinedAt"
|
||||
:values="{ ago: formatRelativeTime(user.created) }"
|
||||
>
|
||||
<template #date="{ children }">
|
||||
<span class="font-bold text-primary">
|
||||
<component :is="() => children" />
|
||||
</span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="organizations.length > 0" class="card flex-card">
|
||||
<h2 class="text-lg text-contrast">{{ formatMessage(messages.profileOrganizations) }}</h2>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<nuxt-link
|
||||
v-for="org in organizations"
|
||||
:key="org.id"
|
||||
v-tooltip="org.name"
|
||||
class="organization"
|
||||
:to="`/organization/${org.slug}`"
|
||||
>
|
||||
<Avatar :src="org.icon_url" :alt="'Icon for ' + org.name" size="3rem" />
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="badges.length > 0" class="card flex-card">
|
||||
<h2 class="text-lg text-contrast">{{ formatMessage(messages.profileBadges) }}</h2>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div v-for="badge in badges" :key="badge">
|
||||
<StaffBadge v-if="badge === 'staff'" class="h-14 w-14" />
|
||||
<ModBadge v-else-if="badge === 'mod'" class="h-14 w-14" />
|
||||
<nuxt-link v-else-if="badge === 'plus'" to="/plus">
|
||||
<PlusBadge class="h-14 w-14" />
|
||||
</nuxt-link>
|
||||
<TenMClubBadge v-else-if="badge === '10m-club'" class="h-14 w-14" />
|
||||
<EarlyAdopterBadge v-else-if="badge === 'early-adopter'" class="h-14 w-14" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { LibraryIcon, BoxIcon, LinkIcon, LockIcon, XIcon } from "@modrinth/assets";
|
||||
import { Promotion } from "@modrinth/ui";
|
||||
import {
|
||||
LibraryIcon,
|
||||
BoxIcon,
|
||||
LinkIcon,
|
||||
LockIcon,
|
||||
XIcon,
|
||||
CalendarIcon,
|
||||
DownloadIcon,
|
||||
ClipboardCopyIcon,
|
||||
MoreVerticalIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { OverflowMenu, ButtonStyled } from "@modrinth/ui";
|
||||
import NavTabs from "~/components/ui/NavTabs.vue";
|
||||
import ProjectCard from "~/components/ui/ProjectCard.vue";
|
||||
import Badge from "~/components/ui/Badge.vue";
|
||||
import { reportUser } from "~/utils/report-helpers.ts";
|
||||
|
||||
import StaffBadge from "~/assets/images/badges/staff.svg?component";
|
||||
import ModBadge from "~/assets/images/badges/mod.svg?component";
|
||||
import PlusBadge from "~/assets/images/badges/plus.svg?component";
|
||||
import TenMClubBadge from "~/assets/images/badges/10m-club.svg?component";
|
||||
import EarlyAdopterBadge from "~/assets/images/badges/early-adopter.svg?component";
|
||||
|
||||
import ReportIcon from "~/assets/images/utils/report.svg?component";
|
||||
import SunriseIcon from "~/assets/images/utils/sunrise.svg?component";
|
||||
import DownloadIcon from "~/assets/images/utils/download.svg?component";
|
||||
import SettingsIcon from "~/assets/images/utils/settings.svg?component";
|
||||
import UpToDate from "~/assets/images/illustrations/up_to_date.svg?component";
|
||||
import UserIcon from "~/assets/images/utils/user.svg?component";
|
||||
import EditIcon from "~/assets/images/utils/edit.svg?component";
|
||||
import HeartIcon from "~/assets/images/utils/heart.svg?component";
|
||||
import GridIcon from "~/assets/images/utils/grid.svg?component";
|
||||
import ListIcon from "~/assets/images/utils/list.svg?component";
|
||||
import ImageIcon from "~/assets/images/utils/image.svg?component";
|
||||
import WorldIcon from "~/assets/images/utils/world.svg?component";
|
||||
import ModalCreation from "~/components/ui/ModalCreation.vue";
|
||||
import NavRow from "~/components/ui/NavRow.vue";
|
||||
import CopyCode from "~/components/ui/CopyCode.vue";
|
||||
import Avatar from "~/components/ui/Avatar.vue";
|
||||
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
|
||||
const data = useNuxtApp();
|
||||
const route = useNativeRoute();
|
||||
@@ -319,28 +336,41 @@ const formatCompactNumber = useCompactNumber();
|
||||
const formatRelativeTime = useRelativeTime();
|
||||
|
||||
const messages = defineMessages({
|
||||
profileProjectsStats: {
|
||||
id: "profile.stats.projects",
|
||||
defaultMessage:
|
||||
"{count, plural, one {<stat>{count}</stat> project} other {<stat>{count}</stat> projects}}",
|
||||
},
|
||||
profileDownloadsStats: {
|
||||
id: "profile.stats.downloads",
|
||||
defaultMessage:
|
||||
"{count, plural, one {<stat>{count}</stat> download} other {<stat>{count}</stat> downloads}}",
|
||||
"{count, plural, one {<stat>{count}</stat> project download} other {<stat>{count}</stat> project downloads}}",
|
||||
},
|
||||
profileProjectsFollowersStats: {
|
||||
id: "profile.stats.projects-followers",
|
||||
defaultMessage:
|
||||
"{count, plural, one {<stat>{count}</stat> follower} other {<stat>{count}</stat> followers}} of projects",
|
||||
"{count, plural, one {<stat>{count}</stat> project follower} other {<stat>{count}</stat> project followers}}",
|
||||
},
|
||||
profileJoinedAt: {
|
||||
id: "profile.joined-at",
|
||||
defaultMessage: "Joined {ago}",
|
||||
defaultMessage: "Joined <date>{ago}</date>",
|
||||
},
|
||||
profileUserId: {
|
||||
id: "profile.user-id",
|
||||
defaultMessage: "User ID: {id}",
|
||||
},
|
||||
profileDetails: {
|
||||
id: "profile.label.details",
|
||||
defaultMessage: "Details",
|
||||
},
|
||||
profileOrganizations: {
|
||||
id: "profile.label.organizations",
|
||||
defaultMessage: "Organizations",
|
||||
},
|
||||
profileBadges: {
|
||||
id: "profile.label.badges",
|
||||
defaultMessage: "Badges",
|
||||
},
|
||||
profileManageProjectsButton: {
|
||||
id: "profile.button.manage-projects",
|
||||
defaultMessage: "Manage projects",
|
||||
@@ -353,10 +383,6 @@ const messages = defineMessages({
|
||||
id: "profile.meta.description-with-bio",
|
||||
defaultMessage: "{bio} - Download {username}'s projects on Modrinth",
|
||||
},
|
||||
profileReportButton: {
|
||||
id: "profile.button.report",
|
||||
defaultMessage: "Report",
|
||||
},
|
||||
profileNoProjectsLabel: {
|
||||
id: "profile.label.no-projects",
|
||||
defaultMessage: "This user has no projects!",
|
||||
@@ -485,12 +511,64 @@ const sumFollows = computed(() => {
|
||||
return sum;
|
||||
});
|
||||
|
||||
function cycleSearchDisplayMode() {
|
||||
cosmetics.value.searchDisplayMode.user = data.$cycleValue(
|
||||
cosmetics.value.searchDisplayMode.user,
|
||||
tags.value.projectViewModes,
|
||||
);
|
||||
const badges = computed(() => {
|
||||
const badges = [];
|
||||
|
||||
if (user.value.role === "admin") {
|
||||
badges.push("staff");
|
||||
}
|
||||
|
||||
if (user.value.role === "moderator") {
|
||||
badges.push("mod");
|
||||
}
|
||||
|
||||
if (isPermission(user.value.badges, 1 << 0)) {
|
||||
badges.push("plus");
|
||||
}
|
||||
|
||||
if (sumDownloads.value > 10000000) {
|
||||
badges.push("10m-club");
|
||||
}
|
||||
|
||||
if (
|
||||
isPermission(user.value.badges, 1 << 1) ||
|
||||
isPermission(user.value.badges, 1 << 2) ||
|
||||
isPermission(user.value.badges, 1 << 3)
|
||||
) {
|
||||
badges.push("early-adopter");
|
||||
}
|
||||
|
||||
if (isPermission(user.value.badges, 1 << 4)) {
|
||||
badges.push("alpha-tester");
|
||||
}
|
||||
|
||||
if (isPermission(user.value.badges, 1 << 5)) {
|
||||
badges.push("contributor");
|
||||
}
|
||||
|
||||
if (isPermission(user.value.badges, 1 << 6)) {
|
||||
badges.push("translator");
|
||||
}
|
||||
|
||||
return badges;
|
||||
});
|
||||
|
||||
async function copyId() {
|
||||
await navigator.clipboard.writeText(project.value.id);
|
||||
}
|
||||
|
||||
const navLinks = computed(() => [
|
||||
{
|
||||
label: formatMessage(commonMessages.allProjectType),
|
||||
href: `/user/${user.value.username}`,
|
||||
},
|
||||
...projectTypes.value.map((x) => {
|
||||
return {
|
||||
label: formatMessage(getProjectTypeMessage(x, true)),
|
||||
href: `/user/${user.value.username}/${x}s`,
|
||||
};
|
||||
}),
|
||||
]);
|
||||
</script>
|
||||
<script>
|
||||
export default defineNuxtComponent({
|
||||
@@ -499,16 +577,6 @@ export default defineNuxtComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.organizations-grid {
|
||||
// 5 wide
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
|
||||
grid-gap: var(--gap-sm);
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.collections-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@@ -579,107 +647,7 @@ export default defineNuxtComponent({
|
||||
}
|
||||
}
|
||||
|
||||
.user-header-wrapper {
|
||||
display: flex;
|
||||
margin: 0 auto -1.5rem;
|
||||
max-width: 80rem;
|
||||
|
||||
.user-header {
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 0 1rem;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
|
||||
.username {
|
||||
display: none;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-username {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 501px) {
|
||||
.mobile-username {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-header-wrapper .user-header .username {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding-top: 2.5rem;
|
||||
}
|
||||
|
||||
.sidebar__item:not(:last-child) {
|
||||
margin: 0 0 0.75rem 0;
|
||||
}
|
||||
|
||||
.profile-picture {
|
||||
border-radius: var(--size-rounded-lg);
|
||||
height: 8rem;
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
|
||||
.bio {
|
||||
display: block;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.secondary-stat {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.secondary-stat__icon {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.secondary-stat__text {
|
||||
margin-left: 0.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.date {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.inputs {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
input {
|
||||
margin-top: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-wrapper {
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.sidebar {
|
||||
padding-top: 3rem;
|
||||
}
|
||||
.normal-page__header {
|
||||
grid-area: header;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user