Skip to content

Commit 14eac46

Browse files
authored
feat: medal promotion on servers page (#4117)
* feat: medal promotion on servers page * feat: medal server card * fix: styling changes * fix: colors for dark mode only * fix: light mode medal promotion * feat: finish server card layout * feat: countdown on server panel * fix: lint * feat: use same gradient as promo * fix: scale for medal bg * fix: border around server icon * feat: medal subscr expiry date stuff * feat: progress on plans within the modal * feat: finalize plan modal stage * fix: unused scss * feat: remove buttons from cards * feat: upgrade button opens modal on server panel * feat: billing endpoint * fix: lint issues * fix: lint issues * fix: lint issues * feat: better handling of downgrades + existing plan checks * feat: update medal url * feat: proration visual in modal * feat: standardize upgrade modal into ServersUpgradeModalWrapper * feat: replace upgrade PurchaseModal with ServersUpgradeModalWrapper * feat: allow server region * fix: lint * fix: lint * fix: medal frontend completion * fix: lint issues * feat: ad * fix: hover tooltip + orange new server sparkle * feat: ad * fix: lint issues new eslint * feat: match ad * feat: support for ?dry=true * fix: lint isuses * fix: lint issues * fix: TeleportDropdownMenu imports * fix: hash nav issues * feat: clarify confirm changes btn * fix: lint issues * fix: "Using new payment method" * fix: lint * fix: re-add -mt-2 --------- Signed-off-by: Cal H. <hendersoncal117@gmail.com>
1 parent 9af1391 commit 14eac46

File tree

34 files changed

+2473
-282
lines changed

34 files changed

+2473
-282
lines changed

apps/app-frontend/src/components/ui/PromotionWrapper.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ function updateAdPosition() {
3434
<template>
3535
<div ref="adsWrapper" class="ad-parent relative flex w-full justify-center cursor-pointer bg-bg">
3636
<a
37-
href="https://modrinth.gg?from=app-placeholder"
37+
href="https://modrinth.gg/medal?app"
3838
target="_blank"
3939
class="flex max-h-[250px] min-h-[250px] min-w-[300px] max-w-[300px] flex-col gap-4 rounded-[inherit]"
4040
>
4141
<img
42-
src="https://cdn-raw.modrinth.com/modrinth-servers-placeholder-light.webp"
42+
src="https://cdn-raw.modrinth.com/medal-modrinth-servers-light.webp"
4343
alt="Host your next server with Modrinth Servers"
4444
class="hidden light-image rounded-[inherit]"
4545
/>
4646
<img
47-
src="https://cdn-raw.modrinth.com/modrinth-servers-placeholder-dark.webp"
47+
src="https://cdn-raw.modrinth.com/medal-modrinth-servers-dark.webp"
4848
alt="Host your next server with Modrinth Servers"
4949
class="dark-image rounded-[inherit]"
5050
/>

apps/frontend/src/assets/images/illustrations/medal_promo_background.svg

Lines changed: 490 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Loading

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ html {
131131

132132
--landing-raw-bg: #fff;
133133

134+
--medal-promotion-bg: #fff;
135+
--medal-promotion-bg-orange: #f0b051;
136+
--medal-promotion-text-orange: #faa624;
137+
--medal-promotion-bg-gradient: linear-gradient(90deg, rgba(255, 200, 118, 0.15) 0%, #fff 100%);
138+
134139
--banner-error-bg: #fee2e2;
135140
--banner-error-text: #991b1b;
136141
--banner-error-border: #ef4444;
@@ -237,6 +242,11 @@ html {
237242

238243
--landing-raw-bg: #000;
239244

245+
--medal-promotion-bg: #000;
246+
--medal-promotion-bg-orange: #ffb84b54;
247+
--medal-promotion-text-orange: #ffb84b;
248+
--medal-promotion-bg-gradient: linear-gradient(90deg, #ffb74b21, transparent 50%, #000 100%);
249+
240250
--hover-filter: brightness(120%);
241251
--active-filter: brightness(140%);
242252

apps/frontend/src/components/ui/AdPlaceholder.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<template>
22
<div class="ad-parent relative mb-3 flex w-full justify-center rounded-2xl bg-bg-raised">
33
<nuxt-link
4-
to="/servers"
4+
to="/servers?plan&ref=medal"
55
class="flex max-h-[250px] min-h-[250px] min-w-[300px] max-w-[300px] flex-col gap-4 rounded-[inherit]"
66
>
77
<img
8-
src="https://cdn-raw.modrinth.com/modrinth-servers-placeholder-light.webp"
8+
src="https://cdn-raw.modrinth.com/medal-modrinth-servers-light.webp"
99
alt="Host your next server with Modrinth Servers"
1010
class="light-image hidden rounded-[inherit]"
1111
/>
1212
<img
13-
src="https://cdn-raw.modrinth.com/modrinth-servers-placeholder-dark.webp"
13+
src="https://cdn-raw.modrinth.com/medal-modrinth-servers-dark.webp"
1414
alt="Host your next server with Modrinth Servers"
1515
class="dark-image rounded-[inherit]"
1616
/>

apps/frontend/src/components/ui/servers/ServerIcon.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div
3-
class="experimental-styles-within flex size-24 shrink-0 overflow-hidden rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
3+
class="experimental-styles-within flex size-16 shrink-0 overflow-hidden rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
44
>
55
<client-only>
66
<img

apps/frontend/src/components/ui/servers/ServerListing.vue

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,23 @@
44
:to="status === 'suspended' ? '' : `/servers/manage/${props.server_id}`"
55
>
66
<div
7-
v-tooltip="
8-
status === 'suspended'
9-
? suspension_reason === 'upgrading'
10-
? 'This server is being transferred to a new node. It will be unavailable until this process finishes.'
11-
: 'This server has been suspended. Please visit your billing settings or contact Modrinth Support for more information.'
12-
: ''
13-
"
14-
class="flex cursor-pointer flex-row items-center overflow-x-hidden rounded-3xl bg-bg-raised p-4 transition-transform duration-100"
15-
:class="status === 'suspended' ? '!rounded-b-none opacity-75' : 'active:scale-95'"
7+
class="-mb-2 flex flex-row items-center overflow-x-hidden rounded-2xl border-[1px] border-solid border-button-bg bg-bg-raised p-4 transition-transform duration-100"
8+
:class="{
9+
'!rounded-b-none border-b-0': status === 'suspended' || !!pendingChange,
10+
'opacity-75': status === 'suspended',
11+
'active:scale-95': status !== 'suspended' && !pendingChange,
12+
}"
1613
data-pyro-server-listing
1714
:data-pyro-server-listing-id="server_id"
1815
>
1916
<ServerIcon v-if="status !== 'suspended'" :image="image" />
2017
<div
2118
v-else
22-
class="bg-bg-secondary flex size-24 items-center justify-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
19+
class="bg-bg-secondary flex size-16 items-center justify-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
2320
>
24-
<LockIcon class="size-20 text-secondary" />
21+
<LockIcon class="size-12 text-secondary" />
2522
</div>
26-
<div class="ml-8 flex flex-col gap-2.5">
23+
<div class="ml-4 flex flex-col gap-2.5">
2724
<div class="flex flex-row items-center gap-2">
2825
<h2 class="m-0 text-xl font-bold text-contrast">{{ name }}</h2>
2926
<ChevronRightIcon />
@@ -41,7 +38,6 @@
4138
/>
4239
Using {{ projectData?.title || 'Unknown' }}
4340
</div>
44-
<div v-else class="min-h-[20px]"></div>
4541

4642
<div
4743
v-if="isConfiguring"
@@ -59,50 +55,67 @@
5955
/>
6056
</div>
6157
</div>
62-
<div
63-
v-if="status === 'suspended' && suspension_reason === 'upgrading'"
64-
class="relative -mt-4 flex w-full flex-row items-center gap-2 rounded-b-3xl bg-bg-blue p-4 text-sm font-bold text-contrast"
65-
>
66-
<PanelSpinner />
67-
Your server's hardware is currently being upgraded and will be back online shortly.
58+
</NuxtLink>
59+
<div
60+
v-if="status === 'suspended' && suspension_reason === 'upgrading'"
61+
class="relative -mt-2 flex w-full flex-row items-center gap-2 rounded-b-2xl border-[1px] border-t-0 border-solid border-bg-blue bg-bg-blue p-4 text-sm font-bold text-contrast"
62+
>
63+
<PanelSpinner />
64+
Your server's hardware is currently being upgraded and will be back online shortly.
65+
</div>
66+
<div
67+
v-else-if="status === 'suspended' && suspension_reason === 'cancelled'"
68+
class="relative -mt-2 flex w-full flex-col gap-2 rounded-b-2xl border-[1px] border-t-0 border-solid border-bg-red bg-bg-red p-4 text-sm font-bold text-contrast"
69+
>
70+
<div class="flex flex-row gap-2">
71+
<PanelErrorIcon class="!size-5" /> Your server has been cancelled. Please update your billing
72+
information or contact Modrinth Support for more information.
6873
</div>
69-
<div
70-
v-else-if="status === 'suspended' && suspension_reason === 'cancelled'"
71-
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
72-
>
73-
<div class="flex flex-row gap-2">
74-
<PanelErrorIcon class="!size-5" /> Your server has been cancelled. Please update your
75-
billing information or contact Modrinth Support for more information.
76-
</div>
77-
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
74+
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
75+
</div>
76+
<div
77+
v-else-if="status === 'suspended' && suspension_reason"
78+
class="relative -mt-2 flex w-full flex-col gap-2 rounded-b-2xl border-[1px] border-t-0 border-solid border-bg-red bg-bg-red p-4 text-sm font-bold text-contrast"
79+
>
80+
<div class="flex flex-row gap-2">
81+
<PanelErrorIcon class="!size-5" /> Your server has been suspended: {{ suspension_reason }}.
82+
Please update your billing information or contact Modrinth Support for more information.
7883
</div>
79-
<div
80-
v-else-if="status === 'suspended' && suspension_reason"
81-
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
82-
>
83-
<div class="flex flex-row gap-2">
84-
<PanelErrorIcon class="!size-5" /> Your server has been suspended: {{ suspension_reason }}.
85-
Please update your billing information or contact Modrinth Support for more information.
86-
</div>
87-
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
84+
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
85+
</div>
86+
<div
87+
v-else-if="status === 'suspended'"
88+
class="-mt-2flex relative w-full flex-col gap-2 rounded-b-2xl border-[1px] border-t-0 border-solid border-bg-red bg-bg-red p-4 text-sm font-bold text-contrast"
89+
>
90+
<div class="flex flex-row gap-2">
91+
<PanelErrorIcon class="!size-5" /> Your server has been suspended. Please update your billing
92+
information or contact Modrinth Support for more information.
8893
</div>
89-
<div
90-
v-else-if="status === 'suspended'"
91-
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
92-
>
93-
<div class="flex flex-row gap-2">
94-
<PanelErrorIcon class="!size-5" /> Your server has been suspended. Please update your
95-
billing information or contact Modrinth Support for more information.
96-
</div>
97-
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
94+
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
95+
</div>
96+
<div
97+
v-if="pendingChange && status !== 'suspended'"
98+
class="relative -mt-2 flex w-full flex-col gap-2 rounded-b-2xl border-[1px] border-t-0 border-solid border-orange bg-bg-orange p-4 text-sm font-bold text-contrast"
99+
>
100+
<div>
101+
Your server will {{ pendingChange.verb.toLowerCase() }} to the "{{ pendingChange.planSize }}"
102+
plan on {{ formatDate(pendingChange.date) }}.
98103
</div>
99-
</NuxtLink>
104+
<ServersSpecs
105+
class="!font-normal !text-contrast"
106+
:ram="Math.round((pendingChange.ramGb ?? 0) * 1024)"
107+
:storage="Math.round((pendingChange.storageGb ?? 0) * 1024)"
108+
:cpus="pendingChange.cpuBurst"
109+
bursting-link="https://docs.modrinth.com/servers/bursting"
110+
/>
111+
</div>
100112
</template>
101113

102114
<script setup lang="ts">
103115
import { ChevronRightIcon, LockIcon, SparklesIcon } from '@modrinth/assets'
104-
import { Avatar, CopyCode } from '@modrinth/ui'
116+
import { Avatar, CopyCode, ServersSpecs } from '@modrinth/ui'
105117
import type { Project, Server } from '@modrinth/utils'
118+
import dayjs from 'dayjs'
106119
107120
import { useModrinthServers } from '~/composables/servers/modrinth-servers.ts'
108121
@@ -111,7 +124,19 @@ import PanelSpinner from './PanelSpinner.vue'
111124
import ServerIcon from './ServerIcon.vue'
112125
import ServerInfoLabels from './ServerInfoLabels.vue'
113126
114-
const props = defineProps<Partial<Server>>()
127+
type PendingChange = {
128+
planSize: string
129+
cpu: number
130+
cpuBurst: number
131+
ramGb: number
132+
swapGb?: number
133+
storageGb?: number
134+
date: string | number | Date
135+
intervalChange?: string | null
136+
verb: string
137+
}
138+
139+
const props = defineProps<Partial<Server> & { pendingChange?: PendingChange }>()
115140
116141
if (props.server_id && props.status === 'available') {
117142
// Necessary only to get server icon
@@ -138,4 +163,12 @@ if (props.upstream) {
138163
const image = useState<string | undefined>(`server-icon-${props.server_id}`, () => undefined)
139164
const iconUrl = computed(() => projectData.value?.icon_url || undefined)
140165
const isConfiguring = computed(() => props.flows?.intro)
166+
167+
const formatDate = (d: unknown) => {
168+
try {
169+
return dayjs(d as any).format('MMMM D, YYYY')
170+
} catch {
171+
return ''
172+
}
173+
}
141174
</script>

0 commit comments

Comments
 (0)