|
121 | 121 | </UserHeader>
|
122 | 122 | </div>
|
123 | 123 | <div class="normal-page__content">
|
124 |
| - <div v-if="navLinks.length >= 2" class="mb-4 max-w-full overflow-x-auto"> |
125 |
| - <NavTabs :links="navLinks" /> |
126 |
| - </div> |
127 |
| - <div v-if="projects.length > 0"> |
128 |
| - <ProjectsList :projects="projects" :project-link="(project) => `/project/${project.id}`"> |
129 |
| - <template #project-actions> |
130 |
| - <ButtonStyled color="brand"> |
131 |
| - <button><DownloadIcon /> Install</button> |
132 |
| - </ButtonStyled> |
133 |
| - <ButtonStyled circular> |
134 |
| - <button v-tooltip="'Follow'"> |
135 |
| - <HeartIcon /> |
136 |
| - </button> |
137 |
| - </ButtonStyled> |
138 |
| - <ButtonStyled circular> |
139 |
| - <button v-tooltip="'Save'"> |
140 |
| - <BookmarkIcon /> |
141 |
| - </button> |
142 |
| - </ButtonStyled> |
143 |
| - <ButtonStyled circular type="transparent"> |
144 |
| - <button> |
145 |
| - <MoreVerticalIcon /> |
146 |
| - </button> |
147 |
| - </ButtonStyled> |
148 |
| - </template> |
149 |
| - </ProjectsList> |
150 |
| - |
151 |
| - <div |
152 |
| - v-if="route.params.projectType !== 'collections'" |
153 |
| - :class="'project-list display-mode--' + cosmetics.searchDisplayMode.user" |
154 |
| - > |
155 |
| - <ProjectCard |
156 |
| - v-for="project in (route.params.projectType !== undefined |
157 |
| - ? projects.filter( |
158 |
| - (x) => |
159 |
| - x.project_type === |
160 |
| - route.params.projectType.substr(0, route.params.projectType.length - 1), |
161 |
| - ) |
162 |
| - : projects |
163 |
| - ) |
164 |
| - .slice() |
165 |
| - .sort((a, b) => b.downloads - a.downloads)" |
166 |
| - :id="project.slug || project.id" |
167 |
| - :key="project.id" |
168 |
| - :name="project.title" |
169 |
| - :display="cosmetics.searchDisplayMode.user" |
170 |
| - :featured-image="project.gallery.find((element) => element.featured)?.url" |
171 |
| - :description="project.description" |
172 |
| - :created-at="project.published" |
173 |
| - :updated-at="project.updated" |
174 |
| - :downloads="project.downloads.toString()" |
175 |
| - :follows="project.followers.toString()" |
176 |
| - :icon-url="project.icon_url" |
177 |
| - :categories="project.categories" |
178 |
| - :client-side="project.client_side" |
179 |
| - :server-side="project.server_side" |
180 |
| - :status=" |
181 |
| - auth.user && (auth.user.id === user.id || tags.staffRoles.includes(auth.user.role)) |
182 |
| - ? project.status |
183 |
| - : null |
184 |
| - " |
185 |
| - :type="project.project_type" |
186 |
| - :color="project.color" |
187 |
| - /> |
| 124 | + <ProjectsList |
| 125 | + v-if="flags.newProjectListUserPage" |
| 126 | + :projects="projects.filter((x) => x.status === 'approved' || x.status === 'archived')" |
| 127 | + :project-link="(project) => `/project/${project.id}`" |
| 128 | + :experimental-colors="flags.projectCardBackground" |
| 129 | + > |
| 130 | + <template #project-actions> |
| 131 | + <ButtonStyled color="brand"> |
| 132 | + <button><DownloadIcon /> Install</button> |
| 133 | + </ButtonStyled> |
| 134 | + <ButtonStyled circular> |
| 135 | + <button v-tooltip="'Follow'"> |
| 136 | + <HeartIcon /> |
| 137 | + </button> |
| 138 | + </ButtonStyled> |
| 139 | + <ButtonStyled circular> |
| 140 | + <button v-tooltip="'Save'"> |
| 141 | + <BookmarkIcon /> |
| 142 | + </button> |
| 143 | + </ButtonStyled> |
| 144 | + <ButtonStyled circular type="transparent"> |
| 145 | + <button> |
| 146 | + <MoreVerticalIcon /> |
| 147 | + </button> |
| 148 | + </ButtonStyled> |
| 149 | + </template> |
| 150 | + </ProjectsList> |
| 151 | + <template v-else> |
| 152 | + <div v-if="navLinks.length >= 2" class="mb-4 max-w-full overflow-x-auto"> |
| 153 | + <NavTabs :links="navLinks" /> |
188 | 154 | </div>
|
189 |
| - </div> |
190 |
| - <div v-else-if="route.params.projectType !== 'collections'" class="error"> |
191 |
| - <UpToDate class="icon" /><br /> |
192 |
| - <span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text"> |
193 |
| - <IntlFormatted :message-id="messages.profileNoProjectsAuthLabel"> |
194 |
| - <template #create-link="{ children }"> |
195 |
| - <a class="link" @click.prevent="$refs.modal_creation.show()"> |
196 |
| - <component :is="() => children" /> |
197 |
| - </a> |
198 |
| - </template> |
199 |
| - </IntlFormatted> |
200 |
| - </span> |
201 |
| - <span v-else class="text">{{ formatMessage(messages.profileNoProjectsLabel) }}</span> |
202 |
| - </div> |
203 |
| - <div v-if="['collections'].includes(route.params.projectType)" class="collections-grid"> |
204 |
| - <nuxt-link |
205 |
| - v-for="collection in collections.sort( |
| 155 | + <div v-if="projects.length > 0"> |
| 156 | + <div |
| 157 | + v-if="route.params.projectType !== 'collections'" |
| 158 | + :class="'project-list display-mode--' + cosmetics.searchDisplayMode.user" |
| 159 | + > |
| 160 | + <ProjectCard |
| 161 | + v-for="project in (route.params.projectType !== undefined |
| 162 | + ? projects.filter( |
| 163 | + (x) => |
| 164 | + x.project_type === |
| 165 | + route.params.projectType.substr(0, route.params.projectType.length - 1), |
| 166 | + ) |
| 167 | + : projects |
| 168 | + ) |
| 169 | + .slice() |
| 170 | + .sort((a, b) => b.downloads - a.downloads)" |
| 171 | + :id="project.slug || project.id" |
| 172 | + :key="project.id" |
| 173 | + :name="project.title" |
| 174 | + :display="cosmetics.searchDisplayMode.user" |
| 175 | + :featured-image="project.gallery.find((element) => element.featured)?.url" |
| 176 | + :description="project.description" |
| 177 | + :created-at="project.published" |
| 178 | + :updated-at="project.updated" |
| 179 | + :downloads="project.downloads.toString()" |
| 180 | + :follows="project.followers.toString()" |
| 181 | + :icon-url="project.icon_url" |
| 182 | + :categories="project.categories" |
| 183 | + :client-side="project.client_side" |
| 184 | + :server-side="project.server_side" |
| 185 | + :status=" |
| 186 | + auth.user && |
| 187 | + (auth.user.id === user.id || tags.staffRoles.includes(auth.user.role)) |
| 188 | + ? project.status |
| 189 | + : null |
| 190 | + " |
| 191 | + :type="project.project_type" |
| 192 | + :color="project.color" |
| 193 | + /> |
| 194 | + </div> |
| 195 | + </div> |
| 196 | + <div v-else-if="route.params.projectType !== 'collections'" class="error"> |
| 197 | + <UpToDate class="icon" /><br /> |
| 198 | + <span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text"> |
| 199 | + <IntlFormatted :message-id="messages.profileNoProjectsAuthLabel"> |
| 200 | + <template #create-link="{ children }"> |
| 201 | + <a class="link" @click.prevent="$refs.modal_creation.show()"> |
| 202 | + <component :is="() => children" /> |
| 203 | + </a> |
| 204 | + </template> |
| 205 | + </IntlFormatted> |
| 206 | + </span> |
| 207 | + <span v-else class="text">{{ formatMessage(messages.profileNoProjectsLabel) }}</span> |
| 208 | + </div> |
| 209 | + <div v-if="['collections'].includes(route.params.projectType)" class="collections-grid"> |
| 210 | + <nuxt-link |
| 211 | + v-for="collection in collections.sort( |
206 | 212 | (a, b) => new Date(b.created) - new Date(a.created),
|
207 | 213 | )"
|
208 |
| - :key="collection.id" |
209 |
| - :to="`/collection/${collection.id}`" |
210 |
| - class="card collection-item" |
211 |
| - > |
212 |
| - <div class="collection"> |
213 |
| - <Avatar :src="collection.icon_url" class="icon" /> |
214 |
| - <div class="details"> |
215 |
| - <h2 class="title">{{ collection.name }}</h2> |
216 |
| - <div class="stats"> |
217 |
| - <LibraryIcon aria-hidden="true" /> |
218 |
| - Collection |
| 214 | + :key="collection.id" |
| 215 | + :to="`/collection/${collection.id}`" |
| 216 | + class="card collection-item" |
| 217 | + > |
| 218 | + <div class="collection"> |
| 219 | + <Avatar :src="collection.icon_url" class="icon" /> |
| 220 | + <div class="details"> |
| 221 | + <h2 class="title">{{ collection.name }}</h2> |
| 222 | + <div class="stats"> |
| 223 | + <LibraryIcon aria-hidden="true" /> |
| 224 | + Collection |
| 225 | + </div> |
219 | 226 | </div>
|
220 | 227 | </div>
|
221 |
| - </div> |
222 |
| - <div class="description"> |
223 |
| - {{ collection.description }} |
224 |
| - </div> |
225 |
| - <div class="stat-bar"> |
226 |
| - <div class="stats"> |
| 228 | + <div class="description"> |
| 229 | + {{ collection.description }} |
| 230 | + </div> |
| 231 | + <div class="stat-bar"> |
| 232 | + <div class="stats"> |
227 | 233 | <BoxIcon />
|
228 | 234 | {{
|
229 | 235 | `${$formatNumber(collection.projects?.length || 0, false)} project${(collection.projects?.length || 0) !== 1 ? "s" : ""}`
|
230 | 236 | }}
|
231 | 237 | </div>
|
232 |
| - <div class="stats"> |
233 |
| - <template v-if="collection.status === 'listed'"> |
234 |
| - <WorldIcon /> |
235 |
| - <span> Public </span> |
236 |
| - </template> |
237 |
| - <template v-else-if="collection.status === 'unlisted'"> |
238 |
| - <LinkIcon /> |
239 |
| - <span> Unlisted </span> |
240 |
| - </template> |
241 |
| - <template v-else-if="collection.status === 'private'"> |
242 |
| - <LockIcon /> |
243 |
| - <span> Private </span> |
244 |
| - </template> |
245 |
| - <template v-else-if="collection.status === 'rejected'"> |
246 |
| - <XIcon /> |
247 |
| - <span> Rejected </span> |
248 |
| - </template> |
| 238 | + <div class="stats"> |
| 239 | + <template v-if="collection.status === 'listed'"> |
| 240 | + <WorldIcon /> |
| 241 | + <span> Public </span> |
| 242 | + </template> |
| 243 | + <template v-else-if="collection.status === 'unlisted'"> |
| 244 | + <LinkIcon /> |
| 245 | + <span> Unlisted </span> |
| 246 | + </template> |
| 247 | + <template v-else-if="collection.status === 'private'"> |
| 248 | + <LockIcon /> |
| 249 | + <span> Private </span> |
| 250 | + </template> |
| 251 | + <template v-else-if="collection.status === 'rejected'"> |
| 252 | + <XIcon /> |
| 253 | + <span> Rejected </span> |
| 254 | + </template> |
| 255 | + </div> |
249 | 256 | </div>
|
250 |
| - </div> |
251 |
| - </nuxt-link> |
252 |
| - </div> |
253 |
| - <div |
254 |
| - v-if="route.params.projectType === 'collections' && collections.length === 0" |
255 |
| - class="error" |
256 |
| - > |
257 |
| - <UpToDate class="icon" /><br /> |
258 |
| - <span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text"> |
259 |
| - <IntlFormatted :message-id="messages.profileNoCollectionsAuthLabel"> |
260 |
| - <template #create-link="{ children }"> |
261 |
| - <a |
262 |
| - class="link" |
263 |
| - @click.prevent="(event) => $refs.modal_collection_creation.show(event)" |
264 |
| - > |
265 |
| - <component :is="() => children" /> |
266 |
| - </a> |
267 |
| - </template> |
268 |
| - </IntlFormatted> |
269 |
| - </span> |
270 |
| - <span v-else class="text">{{ formatMessage(messages.profileNoCollectionsLabel) }}</span> |
271 |
| - </div> |
| 257 | + </nuxt-link> |
| 258 | + </div> |
| 259 | + <div |
| 260 | + v-if="route.params.projectType === 'collections' && collections.length === 0" |
| 261 | + class="error" |
| 262 | + > |
| 263 | + <UpToDate class="icon" /><br /> |
| 264 | + <span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text"> |
| 265 | + <IntlFormatted :message-id="messages.profileNoCollectionsAuthLabel"> |
| 266 | + <template #create-link="{ children }"> |
| 267 | + <a |
| 268 | + class="link" |
| 269 | + @click.prevent="(event) => $refs.modal_collection_creation.show(event)" |
| 270 | + > |
| 271 | + <component :is="() => children" /> |
| 272 | + </a> |
| 273 | + </template> |
| 274 | + </IntlFormatted> |
| 275 | + </span> |
| 276 | + <span v-else class="text">{{ formatMessage(messages.profileNoCollectionsLabel) }}</span> |
| 277 | + </div> |
| 278 | + </template> |
272 | 279 | </div>
|
273 | 280 | <div class="normal-page__sidebar">
|
274 | 281 | <UserSidebarOrganizations
|
|
281 | 288 | :download-count="sumDownloads"
|
282 | 289 | class="card flex-card experimental-styles-within"
|
283 | 290 | />
|
| 291 | + <UserSidebarCollections |
| 292 | + :collections="collections.filter((x) => x.status === 'listed')" |
| 293 | + :link="(collection) => `/collection/${collection.id}`" |
| 294 | + class="card flex-card experimental-styles-within" |
| 295 | + /> |
284 | 296 | <AdPlaceholder
|
285 | 297 | v-if="!auth.user || !isPermission(auth.user.badges, 1 << 0) || flags.showAdsWithPlus"
|
286 | 298 | />
|
@@ -313,6 +325,7 @@ import {
|
313 | 325 | UserSidebarBadges,
|
314 | 326 | UserSidebarOrganizations,
|
315 | 327 | ProjectsList,
|
| 328 | + UserSidebarCollections, |
316 | 329 | } from "@modrinth/ui";
|
317 | 330 | import { isStaff } from "~/helpers/users.js";
|
318 | 331 | import NavTabs from "~/components/ui/NavTabs.vue";
|
|
0 commit comments