Remove duplicate components in web frontend Avatar, Badge, CopyCode, and Pagination (#3741)

This commit is contained in:
Prospector 2025-06-18 17:07:15 -07:00 committed by GitHub
parent ba4fecb0cb
commit dbde3c4669
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 55 additions and 508 deletions

View File

@ -1,46 +0,0 @@
<template>
<OmorphiaAvatar
:src="src"
:alt="alt"
:size="size"
:circle="circle"
:no-shadow="noShadow"
:loading="loading"
:raised="raised"
/>
</template>
<script setup>
import { Avatar as OmorphiaAvatar } from "@modrinth/ui";
const props = defineProps({
src: {
type: String,
default: null,
},
alt: {
type: String,
default: "",
},
size: {
type: String,
default: "2rem",
},
circle: {
type: Boolean,
default: false,
},
noShadow: {
type: Boolean,
default: false,
},
loading: {
type: String,
default: "eager",
},
raised: {
type: Boolean,
default: false,
},
});
</script>

View File

@ -1,131 +0,0 @@
<template>
<span
:class="
'badge flex items-center gap-1 font-semibold text-secondary ' + color + ' type--' + type
"
>
<template v-if="color"> <span class="circle" /> {{ capitalizeString(type) }}</template>
<!-- User roles -->
<template v-else-if="type === 'admin'"> <ModrinthIcon /> Modrinth Team</template>
<template v-else-if="type === 'moderator'"> <ModeratorIcon /> Moderator</template>
<template v-else-if="type === 'creator'"><CreatorIcon /> Creator</template>
<template v-else-if="type === 'plus'"><PlusIcon /> Modrinth Plus</template>
<!-- Project statuses -->
<template v-else-if="type === 'approved'"><GlobeIcon /> Public</template>
<template v-else-if="type === 'approved-general'"><CheckIcon /> Approved</template>
<template v-else-if="type === 'unlisted' || type === 'withheld'"
><LinkIcon /> Unlisted</template
>
<template v-else-if="type === 'private'"><LockIcon /> Private</template>
<template v-else-if="type === 'scheduled'"> <CalendarIcon /> Scheduled</template>
<template v-else-if="type === 'draft'"><DraftIcon /> Draft</template>
<template v-else-if="type === 'archived'"> <ArchiveIcon /> Archived</template>
<template v-else-if="type === 'rejected'"><CrossIcon /> Rejected</template>
<template v-else-if="type === 'processing'"> <ProcessingIcon /> Under review</template>
<!-- Team members -->
<template v-else-if="type === 'accepted'"><CheckIcon /> Accepted</template>
<template v-else-if="type === 'pending'"> <ProcessingIcon /> Pending </template>
<!-- Transaction statuses -->
<template v-else-if="type === 'success'"><CheckIcon /> Success</template>
<!-- Report status -->
<template v-else-if="type === 'closed'"> <CloseIcon /> Closed</template>
<!-- Other -->
<template v-else> <span class="circle" /> {{ capitalizeString(type) }} </template>
</span>
</template>
<script setup>
import {
GlobeIcon,
LinkIcon,
ModrinthIcon,
PlusIcon,
ScaleIcon as ModeratorIcon,
BoxIcon as CreatorIcon,
FileTextIcon as DraftIcon,
XIcon as CrossIcon,
ArchiveIcon,
UpdatedIcon as ProcessingIcon,
CheckIcon,
LockIcon,
CalendarIcon,
XCircleIcon as CloseIcon,
} from "@modrinth/assets";
import { capitalizeString } from "@modrinth/utils";
defineProps({
type: {
type: String,
required: true,
},
color: {
type: String,
default: "",
},
});
</script>
<style lang="scss" scoped>
.badge {
.circle {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: inline-block;
margin-right: 0.25rem;
background-color: var(--badge-color);
}
svg {
vertical-align: -15%;
width: 1em;
height: 1em;
}
&.type--closed,
&.type--withheld,
&.type--rejected,
&.red {
--badge-color: var(--color-red);
}
&.type--pending,
&.type--moderator,
&.type--processing,
&.type--scheduled,
&.orange {
--badge-color: var(--color-orange);
}
&.type--accepted,
&.type--admin,
&.type--success,
&.type--approved-general,
&.green {
--badge-color: var(--color-green);
}
&.type--creator,
&.blue {
--badge-color: var(--color-blue);
}
&.type--unlisted,
&.type--plus,
&.purple {
--badge-color: var(--color-purple);
}
&.type--private,
&.type--approved,
&.gray {
--badge-color: var(--color-secondary);
}
}
</style>

View File

@ -1,75 +0,0 @@
<template>
<button class="code" :class="{ copied }" title="Copy code to clipboard" @click="copyText">
<span>{{ text }}</span>
<CheckIcon v-if="copied" />
<ClipboardCopyIcon v-else />
</button>
</template>
<script>
import { CheckIcon, ClipboardCopyIcon } from "@modrinth/assets";
export default {
components: {
CheckIcon,
ClipboardCopyIcon,
},
props: {
text: {
type: String,
required: true,
},
},
data() {
return {
copied: false,
};
},
methods: {
async copyText() {
await navigator.clipboard.writeText(this.text);
this.copied = true;
},
},
};
</script>
<style lang="scss" scoped>
.code {
color: var(--color-text);
display: inline-flex;
grid-gap: 0.5rem;
font-family: var(--mono-font);
font-size: var(--font-size-sm);
margin: 0;
padding: 0.25rem 0.5rem;
background-color: var(--color-code-bg);
width: fit-content;
border-radius: 10px;
user-select: text;
transition:
opacity 0.5s ease-in-out,
filter 0.2s ease-in-out,
transform 0.05s ease-in-out,
outline 0.2s ease-in-out;
span {
overflow: hidden;
text-overflow: ellipsis;
}
svg {
width: 1em;
height: 1em;
}
&:hover {
filter: brightness(0.85);
}
&:active {
transform: scale(0.95);
filter: brightness(0.8);
}
}
</style>

View File

@ -104,13 +104,13 @@
</nuxt-link> </nuxt-link>
<template v-if="tags.rejectedStatuses.includes(notification.body.new_status)"> <template v-if="tags.rejectedStatuses.includes(notification.body.new_status)">
has been has been
<Badge :type="notification.body.new_status" /> <ProjectStatusBadge :status="notification.body.new_status" />
</template> </template>
<template v-else> <template v-else>
updated from updated from
<Badge :type="notification.body.old_status" /> <ProjectStatusBadge :status="notification.body.old_status" />
to to
<Badge :type="notification.body.new_status" /> <ProjectStatusBadge :status="notification.body.new_status" />
</template> </template>
by the moderators. by the moderators.
</template> </template>
@ -331,16 +331,13 @@ import {
XIcon, XIcon,
ExternalIcon, ExternalIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { useRelativeTime } from "@modrinth/ui"; import { Avatar, ProjectStatusBadge, CopyCode, useRelativeTime } from "@modrinth/ui";
import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue"; import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue";
import { getProjectLink, getVersionLink } from "~/helpers/projects.js"; import { getProjectLink, getVersionLink } from "~/helpers/projects.js";
import { getUserLink } from "~/helpers/users.js"; import { getUserLink } from "~/helpers/users.js";
import { acceptTeamInvite, removeSelfFromTeam } from "~/helpers/teams.js"; import { acceptTeamInvite, removeSelfFromTeam } from "~/helpers/teams.js";
import { markAsRead } from "~/helpers/notifications.ts"; import { markAsRead } from "~/helpers/notifications.ts";
import DoubleIcon from "~/components/ui/DoubleIcon.vue"; import DoubleIcon from "~/components/ui/DoubleIcon.vue";
import Avatar from "~/components/ui/Avatar.vue";
import Badge from "~/components/ui/Badge.vue";
import CopyCode from "~/components/ui/CopyCode.vue";
import Categories from "~/components/ui/search/Categories.vue"; import Categories from "~/components/ui/search/Categories.vue";
const app = useNuxtApp(); const app = useNuxtApp();

View File

@ -1,196 +0,0 @@
<template>
<div v-if="count > 1" class="columns paginates">
<a
:class="{ disabled: page === 1 }"
:tabindex="page === 1 ? -1 : 0"
class="left-arrow paginate has-icon"
aria-label="Previous Page"
:href="linkFunction(page - 1)"
@click.prevent="page !== 1 ? switchPage(page - 1) : null"
>
<LeftArrowIcon />
</a>
<div
v-for="(item, index) in pages"
:key="'page-' + item + '-' + index"
:class="{
'page-number': page !== item,
shrink: item > 99,
}"
class="page-number-container"
>
<div v-if="item === '-'" class="has-icon">
<GapIcon />
</div>
<a
v-else
:class="{
'page-number current': page === item,
shrink: item > 99,
}"
:href="linkFunction(item)"
@click.prevent="page !== item ? switchPage(item) : null"
>
{{ item }}
</a>
</div>
<a
:class="{
disabled: page === pages[pages.length - 1],
}"
:tabindex="page === pages[pages.length - 1] ? -1 : 0"
class="right-arrow paginate has-icon"
aria-label="Next Page"
:href="linkFunction(page + 1)"
@click.prevent="page !== pages[pages.length - 1] ? switchPage(page + 1) : null"
>
<RightArrowIcon />
</a>
</div>
</template>
<script>
import { GapIcon, LeftArrowIcon, RightArrowIcon } from "@modrinth/assets";
export default {
components: {
GapIcon,
LeftArrowIcon,
RightArrowIcon,
},
props: {
page: {
type: Number,
default: 1,
},
count: {
type: Number,
default: 1,
},
linkFunction: {
type: Function,
default() {
return () => "/";
},
},
},
emits: ["switch-page"],
computed: {
pages() {
let pages = [];
if (this.count > 7) {
if (this.page + 3 >= this.count) {
pages = [
1,
"-",
this.count - 4,
this.count - 3,
this.count - 2,
this.count - 1,
this.count,
];
} else if (this.page > 5) {
pages = [1, "-", this.page - 1, this.page, this.page + 1, "-", this.count];
} else {
pages = [1, 2, 3, 4, 5, "-", this.count];
}
} else {
pages = Array.from({ length: this.count }, (_, i) => i + 1);
}
return pages;
},
},
methods: {
switchPage(newPage) {
this.$emit("switch-page", newPage);
if (newPage !== null && newPage !== "" && !isNaN(newPage)) {
this.$emit("switch-page", Math.min(Math.max(newPage, 1), this.count));
}
},
},
};
</script>
<style scoped lang="scss">
a {
position: relative;
color: var(--color-button-text);
box-shadow: var(--shadow-raised), var(--shadow-inset);
padding: 0.5rem 1rem;
margin: 0;
border-radius: 2rem;
background: var(--color-raised-bg);
transition:
opacity 0.5s ease-in-out,
filter 0.2s ease-in-out,
transform 0.05s ease-in-out,
outline 0.2s ease-in-out;
&.page-number.current {
background: var(--color-brand);
color: var(--color-brand-inverted);
cursor: default;
outline: 2px solid transparent;
}
&.paginate.disabled {
background-color: transparent;
cursor: not-allowed;
filter: grayscale(50%);
opacity: 0.5;
}
}
.has-icon {
display: flex;
align-items: center;
svg {
width: 1em;
}
}
.page-number-container,
a,
.has-icon {
display: flex;
justify-content: center;
align-items: center;
}
.paginates {
height: 2em;
margin: 0.5rem 0;
> div,
.has-icon {
margin: 0 0.3em;
}
}
.left-arrow {
margin-left: auto !important;
}
.right-arrow {
margin-right: auto !important;
}
@media screen and (max-width: 400px) {
.paginates {
font-size: 80%;
}
}
@media screen and (max-width: 530px) {
a {
width: 2.5rem;
padding: 0.5rem 0;
}
}
</style>

View File

@ -29,7 +29,7 @@
{{ author }} {{ author }}
</nuxt-link> </nuxt-link>
</p> </p>
<Badge v-if="status && status !== 'approved'" :type="status" class="status" /> <ProjectStatusBadge v-if="status && status !== 'approved'" :status="status" class="status" />
</div> </div>
<p class="description"> <p class="description">
{{ description }} {{ description }}
@ -91,18 +91,16 @@
<script> <script>
import { CalendarIcon, UpdatedIcon, DownloadIcon, HeartIcon } from "@modrinth/assets"; import { CalendarIcon, UpdatedIcon, DownloadIcon, HeartIcon } from "@modrinth/assets";
import { Avatar, ProjectStatusBadge, useRelativeTime } from "@modrinth/ui";
import Categories from "~/components/ui/search/Categories.vue"; import Categories from "~/components/ui/search/Categories.vue";
import Badge from "~/components/ui/Badge.vue";
import EnvironmentIndicator from "~/components/ui/EnvironmentIndicator.vue"; import EnvironmentIndicator from "~/components/ui/EnvironmentIndicator.vue";
import Avatar from "~/components/ui/Avatar.vue";
import { useRelativeTime } from "@modrinth/ui";
export default { export default {
components: { components: {
ProjectStatusBadge,
EnvironmentIndicator, EnvironmentIndicator,
Avatar, Avatar,
Categories, Categories,
Badge,
CalendarIcon, CalendarIcon,
UpdatedIcon, UpdatedIcon,
DownloadIcon, DownloadIcon,

View File

@ -104,12 +104,9 @@
<script setup> <script setup>
import { ReportIcon, UnknownIcon, VersionIcon } from "@modrinth/assets"; import { ReportIcon, UnknownIcon, VersionIcon } from "@modrinth/assets";
import { Avatar, Badge, CopyCode, useRelativeTime } from "@modrinth/ui";
import { renderHighlightedString } from "~/helpers/highlight.js"; import { renderHighlightedString } from "~/helpers/highlight.js";
import { useRelativeTime } from "@modrinth/ui";
import Avatar from "~/components/ui/Avatar.vue";
import Badge from "~/components/ui/Badge.vue";
import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue"; import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue";
import CopyCode from "~/components/ui/CopyCode.vue";
const formatRelativeTime = useRelativeTime(); const formatRelativeTime = useRelativeTime();

View File

@ -214,7 +214,7 @@
</template> </template>
<script setup> <script setup>
import { OverflowMenu, MarkdownEditor } from "@modrinth/ui"; import { CopyCode, OverflowMenu, MarkdownEditor } from "@modrinth/ui";
import { import {
DropdownIcon, DropdownIcon,
ReplyIcon, ReplyIcon,
@ -226,7 +226,6 @@ import {
ScaleIcon, ScaleIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { useImageUpload } from "~/composables/image-upload.ts"; import { useImageUpload } from "~/composables/image-upload.ts";
import CopyCode from "~/components/ui/CopyCode.vue";
import ThreadMessage from "~/components/ui/thread/ThreadMessage.vue"; import ThreadMessage from "~/components/ui/thread/ThreadMessage.vue";
import { isStaff } from "~/helpers/users.js"; import { isStaff } from "~/helpers/users.js";
import { isApproved, isRejected } from "~/helpers/projects.js"; import { isApproved, isRejected } from "~/helpers/projects.js";

View File

@ -103,10 +103,8 @@ import {
ModrinthIcon, ModrinthIcon,
ScaleIcon, ScaleIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { AutoLink, OverflowMenu, useRelativeTime } from "@modrinth/ui"; import { AutoLink, Avatar, Badge, OverflowMenu, useRelativeTime } from "@modrinth/ui";
import { renderString } from "@modrinth/utils"; import { renderString } from "@modrinth/utils";
import Avatar from "~/components/ui/Avatar.vue";
import Badge from "~/components/ui/Badge.vue";
import { isStaff } from "~/helpers/users.js"; import { isStaff } from "~/helpers/users.js";
const props = defineProps({ const props = defineProps({

View File

@ -32,7 +32,7 @@
<h1 class="wrap-as-needed"> <h1 class="wrap-as-needed">
{{ project.title }} {{ project.title }}
</h1> </h1>
<Badge :type="project.status" /> <ProjectStatusBadge :status="project.status" />
</div> </div>
</div> </div>
<h2>Project settings</h2> <h2>Project settings</h2>
@ -870,6 +870,7 @@ import {
ProjectSidebarCreators, ProjectSidebarCreators,
ProjectSidebarDetails, ProjectSidebarDetails,
ProjectSidebarLinks, ProjectSidebarLinks,
ProjectStatusBadge,
ScrollablePanel, ScrollablePanel,
useRelativeTime, useRelativeTime,
} from "@modrinth/ui"; } from "@modrinth/ui";
@ -880,7 +881,6 @@ import dayjs from "dayjs";
import Accordion from "~/components/ui/Accordion.vue"; import Accordion from "~/components/ui/Accordion.vue";
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue"; import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
import AutomaticAccordion from "~/components/ui/AutomaticAccordion.vue"; import AutomaticAccordion from "~/components/ui/AutomaticAccordion.vue";
import Badge from "~/components/ui/Badge.vue";
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue"; import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue"; import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
import MessageBanner from "~/components/ui/MessageBanner.vue"; import MessageBanner from "~/components/ui/MessageBanner.vue";

View File

@ -242,8 +242,7 @@
import { formatProjectStatus } from "@modrinth/utils"; import { formatProjectStatus } from "@modrinth/utils";
import { UploadIcon, SaveIcon, TrashIcon, XIcon, IssuesIcon, CheckIcon } from "@modrinth/assets"; import { UploadIcon, SaveIcon, TrashIcon, XIcon, IssuesIcon, CheckIcon } from "@modrinth/assets";
import { Multiselect } from "vue-multiselect"; import { Multiselect } from "vue-multiselect";
import { ConfirmModal } from "@modrinth/ui"; import { ConfirmModal, Avatar } from "@modrinth/ui";
import Avatar from "~/components/ui/Avatar.vue";
import FileInput from "~/components/ui/FileInput.vue"; import FileInput from "~/components/ui/FileInput.vue";
const props = defineProps({ const props = defineProps({

View File

@ -630,7 +630,15 @@
</div> </div>
</template> </template>
<script> <script>
import { ButtonStyled, ConfirmModal, MarkdownEditor } from "@modrinth/ui"; import {
Avatar,
Badge,
CopyCode,
Checkbox,
ButtonStyled,
ConfirmModal,
MarkdownEditor,
} from "@modrinth/ui";
import { import {
FileIcon, FileIcon,
TrashIcon, TrashIcon,
@ -656,13 +664,9 @@ import { renderHighlightedString } from "~/helpers/highlight.js";
import { reportVersion } from "~/utils/report-helpers.ts"; import { reportVersion } from "~/utils/report-helpers.ts";
import { useImageUpload } from "~/composables/image-upload.ts"; import { useImageUpload } from "~/composables/image-upload.ts";
import Avatar from "~/components/ui/Avatar.vue";
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue"; import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
import Badge from "~/components/ui/Badge.vue";
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue"; import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
import CopyCode from "~/components/ui/CopyCode.vue";
import Categories from "~/components/ui/search/Categories.vue"; import Categories from "~/components/ui/search/Categories.vue";
import Checkbox from "~/components/ui/Checkbox.vue";
import FileInput from "~/components/ui/FileInput.vue"; import FileInput from "~/components/ui/FileInput.vue";
import Modal from "~/components/ui/Modal.vue"; import Modal from "~/components/ui/Modal.vue";

View File

@ -8,13 +8,11 @@ import {
DownloadIcon, DownloadIcon,
LinkIcon, LinkIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import Avatar from "~/components/ui/Avatar.vue"; import { Avatar, Checkbox, Badge } from "@modrinth/ui";
import LogoAnimated from "~/components/brand/LogoAnimated.vue"; import LogoAnimated from "~/components/brand/LogoAnimated.vue";
import Badge from "~/components/ui/Badge.vue";
import PrismIcon from "~/assets/images/external/prism.svg?component"; import PrismIcon from "~/assets/images/external/prism.svg?component";
import ATLauncher from "~/assets/images/external/atlauncher.svg?component"; import ATLauncher from "~/assets/images/external/atlauncher.svg?component";
import CurseForge from "~/assets/images/external/curseforge.svg?component"; import CurseForge from "~/assets/images/external/curseforge.svg?component";
import Checkbox from "~/components/ui/Checkbox.vue";
import { homePageProjects } from "~/generated/state.json"; import { homePageProjects } from "~/generated/state.json";

View File

@ -97,7 +97,7 @@
</template> </template>
<script setup> <script setup>
import { ChevronRightIcon, HistoryIcon } from "@modrinth/assets"; import { ChevronRightIcon, HistoryIcon } from "@modrinth/assets";
import Avatar from "~/components/ui/Avatar.vue"; import { Avatar } from "@modrinth/ui";
import NotificationItem from "~/components/ui/NotificationItem.vue"; import NotificationItem from "~/components/ui/NotificationItem.vue";
import { fetchExtraNotificationData, groupNotifications } from "~/helpers/notifications.ts"; import { fetchExtraNotificationData, groupNotifications } from "~/helpers/notifications.ts";

View File

@ -49,12 +49,14 @@
/> />
</template> </template>
<p v-else>You don't have any unread notifications.</p> <p v-else>You don't have any unread notifications.</p>
<div class="flex justify-end">
<Pagination :page="page" :count="pages" @switch-page="changePage" /> <Pagination :page="page" :count="pages" @switch-page="changePage" />
</div>
</section> </section>
</div> </div>
</template> </template>
<script setup> <script setup>
import { Button, Chips } from "@modrinth/ui"; import { Button, Pagination, Chips } from "@modrinth/ui";
import { HistoryIcon, CheckCheckIcon } from "@modrinth/assets"; import { HistoryIcon, CheckCheckIcon } from "@modrinth/assets";
import { import {
fetchExtraNotificationData, fetchExtraNotificationData,
@ -63,7 +65,6 @@ import {
} from "~/helpers/notifications.ts"; } from "~/helpers/notifications.ts";
import NotificationItem from "~/components/ui/NotificationItem.vue"; import NotificationItem from "~/components/ui/NotificationItem.vue";
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue"; import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
import Pagination from "~/components/ui/Pagination.vue";
useHead({ useHead({
title: "Notifications - Modrinth", title: "Notifications - Modrinth",

View File

@ -279,18 +279,19 @@
</div> </div>
<div> <div>
<Badge v-if="project.status" :type="project.status" class="status" /> <ProjectStatusBadge v-if="project.status" :status="project.status" />
</div> </div>
<div> <div>
<ButtonStyled circular>
<nuxt-link <nuxt-link
class="square-button"
:to="`/${$getProjectTypeForUrl(project.project_type, project.loaders)}/${ :to="`/${$getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id project.slug ? project.slug : project.id
}/settings`" }/settings`"
> >
<SettingsIcon /> <SettingsIcon />
</nuxt-link> </nuxt-link>
</ButtonStyled>
</div> </div>
</div> </div>
</div> </div>
@ -312,19 +313,23 @@ import {
SortAscendingIcon as AscendingIcon, SortAscendingIcon as AscendingIcon,
SortDescendingIcon as DescendingIcon, SortDescendingIcon as DescendingIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { commonMessages } from "@modrinth/ui"; import {
Avatar,
ButtonStyled,
Checkbox,
CopyCode,
ProjectStatusBadge,
commonMessages,
} from "@modrinth/ui";
import Badge from "~/components/ui/Badge.vue";
import Checkbox from "~/components/ui/Checkbox.vue";
import Modal from "~/components/ui/Modal.vue"; import Modal from "~/components/ui/Modal.vue";
import Avatar from "~/components/ui/Avatar.vue";
import ModalCreation from "~/components/ui/ModalCreation.vue"; import ModalCreation from "~/components/ui/ModalCreation.vue";
import CopyCode from "~/components/ui/CopyCode.vue";
export default defineNuxtComponent({ export default defineNuxtComponent({
components: { components: {
Avatar, Avatar,
Badge, ButtonStyled,
ProjectStatusBadge,
SettingsIcon, SettingsIcon,
TrashIcon, TrashIcon,
Checkbox, Checkbox,

View File

@ -527,7 +527,7 @@
</template> </template>
<script setup> <script setup>
import { Multiselect } from "vue-multiselect"; import { Multiselect } from "vue-multiselect";
import { ButtonStyled, useRelativeTime } from "@modrinth/ui"; import { Avatar, ButtonStyled, useRelativeTime } from "@modrinth/ui";
import { import {
CompassIcon, CompassIcon,
LogInIcon, LogInIcon,
@ -539,7 +539,6 @@ import {
} from "@modrinth/assets"; } from "@modrinth/assets";
import PrismLauncherLogo from "~/assets/images/external/prism.svg?component"; import PrismLauncherLogo from "~/assets/images/external/prism.svg?component";
import ATLauncherLogo from "~/assets/images/external/atlauncher.svg?component"; import ATLauncherLogo from "~/assets/images/external/atlauncher.svg?component";
import Avatar from "~/components/ui/Avatar.vue";
import ProjectCard from "~/components/ui/ProjectCard.vue"; import ProjectCard from "~/components/ui/ProjectCard.vue";
import { homePageProjects, homePageSearch, homePageNotifs } from "~/generated/state.json"; import { homePageProjects, homePageSearch, homePageNotifs } from "~/generated/state.json";

View File

@ -81,7 +81,9 @@
</div> </div>
<div class="mobile-row"> <div class="mobile-row">
is requesting to be is requesting to be
<Badge :type="project.requested_status ? project.requested_status : 'approved'" /> <ProjectStatusBadge
:status="project.requested_status ? project.requested_status : 'approved'"
/>
</div> </div>
</div> </div>
<div class="input-group"> <div class="input-group">
@ -103,7 +105,7 @@
</template> </template>
<script setup> <script setup>
import { Chips, useRelativeTime } from "@modrinth/ui"; import { Avatar, ProjectStatusBadge, Chips, useRelativeTime } from "@modrinth/ui";
import { import {
UnknownIcon, UnknownIcon,
EyeIcon, EyeIcon,
@ -112,8 +114,6 @@ import {
IssuesIcon, IssuesIcon,
ScaleIcon, ScaleIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import Avatar from "~/components/ui/Avatar.vue";
import Badge from "~/components/ui/Badge.vue";
import { formatProjectType } from "~/plugins/shorthands.js"; import { formatProjectType } from "~/plugins/shorthands.js";
import { asEncodedJsonArray, fetchSegmented } from "~/utils/fetch-helpers.ts"; import { asEncodedJsonArray, fetchSegmented } from "~/utils/fetch-helpers.ts";

View File

@ -205,6 +205,7 @@
import { PlusIcon, XIcon, TrashIcon, EditIcon, SaveIcon } from "@modrinth/assets"; import { PlusIcon, XIcon, TrashIcon, EditIcon, SaveIcon } from "@modrinth/assets";
import { import {
Checkbox, Checkbox,
CopyCode,
ConfirmModal, ConfirmModal,
commonSettingsMessages, commonSettingsMessages,
commonMessages, commonMessages,
@ -219,7 +220,6 @@ import {
getScopeValue, getScopeValue,
} from "~/composables/auth/scopes.ts"; } from "~/composables/auth/scopes.ts";
import CopyCode from "~/components/ui/CopyCode.vue";
import Modal from "~/components/ui/Modal.vue"; import Modal from "~/components/ui/Modal.vue";
const { formatMessage } = useVIntl(); const { formatMessage } = useVIntl();

View File

@ -355,6 +355,7 @@ import {
GlobeIcon, GlobeIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { import {
Avatar,
OverflowMenu, OverflowMenu,
ButtonStyled, ButtonStyled,
ContentPageHeader, ContentPageHeader,
@ -377,7 +378,6 @@ import BetaTesterBadge from "~/assets/images/badges/beta-tester.svg?component";
import UpToDate from "~/assets/images/illustrations/up_to_date.svg?component"; import UpToDate from "~/assets/images/illustrations/up_to_date.svg?component";
import ModalCreation from "~/components/ui/ModalCreation.vue"; import ModalCreation from "~/components/ui/ModalCreation.vue";
import Avatar from "~/components/ui/Avatar.vue";
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue"; import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue"; import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";