Skip to content

Commit e225bc9

Browse files
IMB11Prospector
andauthored
feat: standardized page banners (#3610)
* feat: standardized site banners * fix: lint issues * fix: deduplicate SCSS with variant map * feat: color shades + reduced scss * feat: fix theming * chore: Remove shades-generator.ts * fix: lint issues --------- Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
1 parent f196430 commit e225bc9

File tree

6 files changed

+224
-126
lines changed

6 files changed

+224
-126
lines changed

apps/frontend/src/assets/styles/global.scss

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ html {
162162
--landing-green-label-bg: rgba(0, 216, 69, 0.15);
163163

164164
--landing-raw-bg: #fff;
165+
166+
--banner-error-bg: #fee2e2;
167+
--banner-error-text: #991b1b;
168+
--banner-error-border: #ef4444;
169+
170+
--banner-warning-bg: #ffedd5;
171+
--banner-warning-text: #713f12;
172+
--banner-warning-border: #f97316;
173+
174+
--banner-info-bg: #dbeafe;
175+
--banner-info-text: #1e3a8a;
176+
--banner-info-border: #3b82f6;
165177
}
166178

167179
.dark,
@@ -286,6 +298,18 @@ html {
286298

287299
--hover-filter: brightness(120%);
288300
--active-filter: brightness(140%);
301+
302+
--banner-error-bg: #4c1515;
303+
--banner-error-text: #fee2e2;
304+
--banner-error-border: #7f1d1d;
305+
306+
--banner-warning-bg: #4a2a0a;
307+
--banner-warning-text: #ffe6c0;
308+
--banner-warning-border: #b54708;
309+
310+
--banner-info-bg: #1e2a44;
311+
--banner-info-text: #dbeafe;
312+
--banner-info-border: #2563eb;
289313
}
290314

291315
.oled-mode {

apps/frontend/src/layouts/default.vue

Lines changed: 85 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -27,76 +27,90 @@
2727
</div>
2828
</div>
2929
<div ref="main_page" class="layout" :class="{ 'expanded-mobile-nav': isBrowseMenuOpen }">
30-
<div
30+
<PagewideBanner
3131
v-if="auth.user && !auth.user.email_verified && route.path !== '/auth/verify-email'"
32-
class="email-nag"
32+
variant="warning"
3333
>
34-
<template v-if="auth.user.email">
35-
<span>{{ formatMessage(verifyEmailBannerMessages.title) }}</span>
36-
<button class="btn" @click="resendVerifyEmail">
34+
<template #title>
35+
<span>
36+
{{
37+
auth?.user?.email
38+
? formatMessage(verifyEmailBannerMessages.title)
39+
: formatMessage(addEmailBannerMessages.title)
40+
}}
41+
</span>
42+
</template>
43+
<template #description>
44+
<span>
45+
{{
46+
auth?.user?.email
47+
? formatMessage(verifyEmailBannerMessages.description)
48+
: formatMessage(addEmailBannerMessages.description)
49+
}}
50+
</span>
51+
</template>
52+
<template #actions>
53+
<button v-if="auth?.user?.email" class="btn" @click="resendVerifyEmail">
3754
{{ formatMessage(verifyEmailBannerMessages.action) }}
3855
</button>
39-
</template>
40-
<template v-else>
41-
<span>{{ formatMessage(addEmailBannerMessages.title) }}</span>
42-
<nuxt-link class="btn" to="/settings/account">
56+
<nuxt-link v-else class="btn" to="/settings/account">
4357
<SettingsIcon aria-hidden="true" />
4458
{{ formatMessage(addEmailBannerMessages.action) }}
4559
</nuxt-link>
4660
</template>
47-
</div>
48-
<div
61+
</PagewideBanner>
62+
<PagewideBanner
4963
v-if="
50-
user &&
51-
user.subscriptions &&
5264
user.subscriptions.some((x) => x.status === 'payment-failed') &&
5365
route.path !== '/settings/billing'
5466
"
55-
class="email-nag"
67+
variant="error"
5668
>
57-
<span>{{ formatMessage(subscriptionPaymentFailedBannerMessages.title) }}</span>
58-
<nuxt-link class="btn" to="/settings/billing">
59-
<SettingsIcon aria-hidden="true" />
60-
{{ formatMessage(subscriptionPaymentFailedBannerMessages.action) }}
61-
</nuxt-link>
62-
</div>
63-
<div
69+
<template #title>
70+
<span>{{ formatMessage(subscriptionPaymentFailedBannerMessages.title) }}</span>
71+
</template>
72+
<template #description>
73+
<span>{{ formatMessage(subscriptionPaymentFailedBannerMessages.description) }}</span>
74+
</template>
75+
<template #actions>
76+
<nuxt-link class="btn" to="/settings/billing">
77+
<SettingsIcon aria-hidden="true" />
78+
{{ formatMessage(subscriptionPaymentFailedBannerMessages.action) }}
79+
</nuxt-link>
80+
</template>
81+
</PagewideBanner>
82+
<PagewideBanner
6483
v-if="
6584
config.public.apiBaseUrl.startsWith('https://staging-api.modrinth.com') &&
6685
!cosmetics.hideStagingBanner
6786
"
68-
class="site-banner site-banner--warning [&>*]:z-[6]"
87+
variant="warning"
6988
>
70-
<div class="site-banner__title">
71-
<IssuesIcon aria-hidden="true" />
89+
<template #title>
7290
<span>{{ formatMessage(stagingBannerMessages.title) }}</span>
73-
</div>
74-
<div class="site-banner__description">
91+
</template>
92+
<template #description>
7593
{{ formatMessage(stagingBannerMessages.description) }}
76-
</div>
77-
<div class="site-banner__actions">
78-
<Button transparent icon-only :action="hideStagingBanner" aria-label="Close banner"
79-
><XIcon aria-hidden="true"
80-
/></Button>
81-
</div>
82-
</div>
83-
<div
84-
v-if="generatedStateErrors && generatedStateErrors.length > 0"
85-
class="site-banner site-banner--warning [&>*]:z-[6]"
86-
>
87-
<div class="site-banner__title">
88-
<IssuesIcon aria-hidden="true" />
94+
</template>
95+
<template #actions_right>
96+
<Button transparent icon-only aria-label="Close" @click="hideStagingBanner">
97+
<XIcon aria-hidden="true" />
98+
</Button>
99+
</template>
100+
</PagewideBanner>
101+
<PagewideBanner v-if="generatedStateErrors?.length" variant="error">
102+
<template #title>
89103
<span>{{ formatMessage(failedToBuildBannerMessages.title) }}</span>
90-
</div>
91-
<div class="site-banner__description">
104+
</template>
105+
<template #description>
92106
{{
93107
formatMessage(failedToBuildBannerMessages.description, {
94108
errors: generatedStateErrors,
95109
url: config.public.apiBaseUrl,
96110
})
97111
}}
98-
</div>
99-
</div>
112+
</template>
113+
</PagewideBanner>
100114
<header
101115
class="experimental-styles-within desktop-only relative z-[5] mx-auto grid max-w-[1280px] grid-cols-[1fr_auto] items-center gap-2 px-6 py-4 lg:grid-cols-[auto_1fr_auto]"
102116
>
@@ -692,7 +706,14 @@ import {
692706
GitHubIcon,
693707
ScaleIcon,
694708
} from "@modrinth/assets";
695-
import { Button, ButtonStyled, OverflowMenu, Avatar, commonMessages } from "@modrinth/ui";
709+
import {
710+
Button,
711+
ButtonStyled,
712+
OverflowMenu,
713+
PagewideBanner,
714+
Avatar,
715+
commonMessages,
716+
} from "@modrinth/ui";
696717
import { isAdmin, isStaff } from "@modrinth/utils";
697718
import { errors as generatedStateErrors } from "~/generated/state.json";
698719
@@ -720,8 +741,13 @@ const basePopoutId = useId();
720741
721742
const verifyEmailBannerMessages = defineMessages({
722743
title: {
723-
id: "layout.banner.verify-email.title",
724-
defaultMessage: "For security purposes, please verify your email address on Modrinth.",
744+
id: "layout.banner.account-action",
745+
defaultMessage: "Account action required",
746+
},
747+
description: {
748+
id: "layout.banner.verify-email.description",
749+
defaultMessage:
750+
"For security reasons, Modrinth needs you to verify the email address associated with your account.",
725751
},
726752
action: {
727753
id: "layout.banner.verify-email.action",
@@ -731,8 +757,13 @@ const verifyEmailBannerMessages = defineMessages({
731757
732758
const addEmailBannerMessages = defineMessages({
733759
title: {
734-
id: "layout.banner.add-email.title",
735-
defaultMessage: "For security purposes, please enter your email on Modrinth.",
760+
id: "layout.banner.account-action",
761+
defaultMessage: "Account action required",
762+
},
763+
description: {
764+
id: "layout.banner.add-email.description",
765+
defaultMessage:
766+
"For security reasons, Modrinth needs you to register an email address to your account.",
736767
},
737768
action: {
738769
id: "layout.banner.add-email.button",
@@ -743,8 +774,12 @@ const addEmailBannerMessages = defineMessages({
743774
const subscriptionPaymentFailedBannerMessages = defineMessages({
744775
title: {
745776
id: "layout.banner.subscription-payment-failed.title",
777+
defaultMessage: "Billing action required.",
778+
},
779+
description: {
780+
id: "layout.banner.subscription-payment-failed.description",
746781
defaultMessage:
747-
"Your subscription failed to renew. Please update your payment method to prevent losing access.",
782+
"One or more subscriptions failed to renew. Please update your payment method to prevent losing access!",
748783
},
749784
action: {
750785
id: "layout.banner.subscription-payment-failed.button",
@@ -755,7 +790,7 @@ const subscriptionPaymentFailedBannerMessages = defineMessages({
755790
const stagingBannerMessages = defineMessages({
756791
title: {
757792
id: "layout.banner.staging.title",
758-
defaultMessage: "You’re viewing Modrinth’s staging environment.",
793+
defaultMessage: "You’re viewing Modrinth’s staging environment",
759794
},
760795
description: {
761796
id: "layout.banner.staging.description",
@@ -1347,72 +1382,6 @@ const footerLinks = [
13471382
}
13481383
}
13491384
1350-
.email-nag {
1351-
z-index: 6;
1352-
position: relative;
1353-
background-color: var(--color-raised-bg);
1354-
width: 100%;
1355-
display: flex;
1356-
align-items: center;
1357-
justify-content: center;
1358-
gap: 1rem;
1359-
padding: 0.5rem 1rem;
1360-
}
1361-
1362-
.site-banner--warning {
1363-
// On some pages, there's gradient backgrounds that seep underneath
1364-
// the banner, so we need to add a solid color underlay.
1365-
background-color: black;
1366-
border-bottom: 2px solid var(--color-red);
1367-
display: grid;
1368-
gap: 0.5rem;
1369-
grid-template: "title actions" "description actions";
1370-
padding-block: var(--gap-xl);
1371-
padding-inline: max(calc((100% - 80rem) / 2 + var(--gap-md)), var(--gap-xl));
1372-
z-index: 4;
1373-
position: relative;
1374-
1375-
&::before {
1376-
content: "";
1377-
position: absolute;
1378-
top: 0;
1379-
left: 0;
1380-
right: 0;
1381-
bottom: 0;
1382-
background-color: var(--color-red-bg);
1383-
z-index: 5;
1384-
}
1385-
1386-
.site-banner__title {
1387-
grid-area: title;
1388-
display: flex;
1389-
gap: 0.5rem;
1390-
align-items: center;
1391-
font-weight: bold;
1392-
font-size: var(--font-size-md);
1393-
color: var(--color-contrast);
1394-
1395-
svg {
1396-
color: var(--color-red);
1397-
width: 1.5rem;
1398-
height: 1.5rem;
1399-
flex-shrink: 0;
1400-
}
1401-
}
1402-
1403-
.site-banner__description {
1404-
grid-area: description;
1405-
}
1406-
1407-
.site-banner__actions {
1408-
grid-area: actions;
1409-
}
1410-
1411-
a {
1412-
color: var(--color-red);
1413-
}
1414-
}
1415-
14161385
@media (max-width: 1200px) {
14171386
.app-btn {
14181387
display: none;

apps/frontend/src/locales/en-US/index.json

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -344,35 +344,38 @@
344344
"layout.avatar.alt": {
345345
"message": "Your avatar"
346346
},
347+
"layout.banner.account-action": {
348+
"message": "Account action required"
349+
},
347350
"layout.banner.add-email.button": {
348351
"message": "Visit account settings"
349352
},
350-
"layout.banner.add-email.title": {
351-
"message": "For security purposes, please enter your email on Modrinth."
352-
},
353353
"layout.banner.build-fail.description": {
354354
"message": "This deploy of Modrinth's frontend failed to generate state from the API. This may be due to an outage or an error in configuration. Rebuild when the API is available. Error codes: {errors}; Current API URL is: {url}"
355355
},
356356
"layout.banner.build-fail.title": {
357-
"message": "Error generating state from API when building."
357+
"message": "Error generating state from API when building"
358358
},
359359
"layout.banner.staging.description": {
360360
"message": "The staging environment is completely separate from the production Modrinth database. This is used for testing and debugging purposes, and may be running in-development versions of the Modrinth backend or frontend newer than the production instance."
361361
},
362362
"layout.banner.staging.title": {
363-
"message": "You’re viewing Modrinth’s staging environment."
363+
"message": "You’re viewing Modrinth’s staging environment"
364364
},
365365
"layout.banner.subscription-payment-failed.button": {
366366
"message": "Update billing info"
367367
},
368368
"layout.banner.subscription-payment-failed.title": {
369-
"message": "Your subscription failed to renew. Please update your payment method to prevent losing access."
369+
"message": "Billing action required"
370+
},
371+
"layout.banner.subscription-payment-failed.description": {
372+
"message": "One or more subscriptions failed to renew. Please update your payment method to prevent losing access!"
370373
},
371374
"layout.banner.verify-email.action": {
372375
"message": "Re-send verification email"
373376
},
374-
"layout.banner.verify-email.title": {
375-
"message": "For security purposes, please verify your email address on Modrinth."
377+
"layout.banner.verify-email.description": {
378+
"message": "For security reasons, Modrinth needs you to verify the email address associated with your account."
376379
},
377380
"layout.footer.about": {
378381
"message": "About"

0 commit comments

Comments
 (0)