From 24e90f0a540c98270b9473ba99a25af66600eb03 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Fri, 8 Nov 2024 23:52:32 +0000 Subject: [PATCH] feat(marketing): miami, overallocation card, misc fixes (#2926) * fix(marketing): make faq headings medium * feat(marketing): add card for overallocation * feat(marketing): add miami location * fix(marketing): 'login' -> 'sign in' consistency * feat: plan query string support + simplify buttons --- apps/frontend/src/pages/servers/index.vue | 247 +++++++++------------- 1 file changed, 103 insertions(+), 144 deletions(-) diff --git a/apps/frontend/src/pages/servers/index.vue b/apps/frontend/src/pages/servers/index.vue index 371538c19..0e652e9fd 100644 --- a/apps/frontend/src/pages/servers/index.vue +++ b/apps/frontend/src/pages/servers/index.vue @@ -167,7 +167,7 @@ class="hidden w-full rounded-2xl sm:block" /> -
+
+ +
+ +

Consistently fast

+

+ Under Pyro, infrastructure is never overloaded, meaning each Modrinth server always + runs at its full performance. + + See the infrastructure + +

+
@@ -406,7 +422,7 @@

Frequently Asked Questions

- + @@ -419,7 +435,7 @@
- + @@ -433,21 +449,21 @@
- + Where are Modrinth Servers located? Can I choose a region?

- Currently, Modrinth Servers are located in New York and Los Angeles. More regions - are coming soon! Your server's location is currently chosen algorithmically, but you - will be able to choose a region in the future. + Currently, Modrinth Servers are located in New York, Los Angeles, and Miami. More + regions are coming soon! Your server's location is currently chosen algorithmically, + but you will be able to choose a region in the future.

- + @@ -460,7 +476,7 @@
- + @@ -496,7 +512,7 @@ : "There's a plan for everyone! Choose the one that fits your needs." }} - Servers are currently US only, in New York and Los Angeles. More regions coming + Servers are currently US only, in New York, Los Angeles, and Miami. More regions coming soon! @@ -526,33 +542,22 @@ - Login - + Out of Stock + - + @@ -589,33 +594,22 @@ - Login - + Out of Stock + - + @@ -639,35 +633,24 @@

$24/month

- + - Login - + Out of Stock + - + @@ -685,11 +668,7 @@
- - Login - - - @@ -712,9 +691,9 @@ import { SortAscendingIcon, ExternalIcon, TerminalSquareIcon, - UserIcon, TransferIcon, VersionIcon, + ServerIcon, } from "@modrinth/assets"; import { products } from "~/generated/state.json"; import LoaderIcon from "~/components/ui/servers/icons/LoaderIcon.vue"; @@ -724,11 +703,6 @@ const pyroPlanProducts = pyroProducts.filter( (p) => p.metadata.ram === 4096 || p.metadata.ram === 6144 || p.metadata.ram === 8192, ); pyroPlanProducts.sort((a, b) => a.metadata.ram - b.metadata.ram); -// yep. this is a thing. -if (!pyroProducts.metadata) { - pyroProducts.metadata = {}; -} -pyroProducts.metadata.type = "pyro"; const title = "Modrinth Servers"; const description = @@ -772,7 +746,6 @@ const deletingSpeed = 25; const pauseTime = 2000; const loggedOut = computed(() => !auth.value.user); -const loginUrl = `/auth/sign-in?redirect=${encodeURIComponent("/servers#plan")}`; const outOfStockUrl = "https://support.modrinth.com"; const { data: hasServers } = await useAsyncData("ServerListCountCheck", async () => { @@ -920,7 +893,20 @@ onMounted(scrollToFaq); watch(() => route.hash, scrollToFaq); -const selectProduct = async (product, custom) => { +const plans = { + small: pyroPlanProducts?.[0], + medium: pyroPlanProducts?.[1], + large: pyroPlanProducts?.[2], + custom: pyroProducts || [], +}; + +const selectProduct = async (product) => { + if (loggedOut.value) { + data.$router.push(`/auth/sign-in?redirect=${encodeURIComponent("/servers?plan=" + product)}`); + return; + } + + await refreshCapacity(); if (isAtCapacity.value) { addNotification({ group: "main", @@ -931,80 +917,53 @@ const selectProduct = async (product, custom) => { return; } - await refreshCapacity(); + const selectedPlan = plans[product]; + if (!selectedPlan) return; - if (isAtCapacity.value) { + if ( + (product === "custom" && !selectedPlan.length) || + (product !== "custom" && !selectedPlan.metadata) + ) { addNotification({ group: "main", - title: "Server Capacity Full", + title: "Invalid product", type: "error", - text: "We are currently at capacity. Please try again later.", + text: "The selected product was found but lacks necessary data. Please contact support.", }); return; } - if (!auth.value.user) { - data.$router.push(loginUrl); - return; + // required for the purchase modal + if (!pyroProducts.metadata) { + pyroProducts.metadata = {}; } + pyroProducts.metadata.type = "pyro"; - customServer.value = !!custom; - selectedProduct.value = product; + customServer.value = product === "custom"; + selectedProduct.value = selectedPlan; showModal.value = true; modalKey.value++; await nextTick(); + if (purchaseModal.value && purchaseModal.value.show) { purchaseModal.value.show(); } }; -const openPurchaseModal = () => { - if (isAtCapacity.value) { - addNotification({ - group: "main", - title: "Server Capacity Full", - type: "error", - text: "We are currently at capacity. Please try again later.", - }); - return; - } - - refreshCapacity(); - - if (isAtCapacity.value) { - addNotification({ - group: "main", - title: "Server Capacity Full", - type: "error", - text: "We are currently at capacity. Please try again later.", - }); - return; +const planQuery = () => { + if (route.query.plan) { + document.getElementById("plan").scrollIntoView(); + selectProduct(route.query.plan); } - - customServer.value = false; - selectedProduct.value = pyroPlanProducts[0]; - showModal.value = true; - modalKey.value++; - nextTick(() => { - if (purchaseModal.value && purchaseModal.value.show) { - purchaseModal.value.show(); - } - }); }; onMounted(() => { startTyping(); - if (route.query.showModal) { - openPurchaseModal(); - } + planQuery(); }); watch(customer, (newCustomer) => { - if (newCustomer) { - if (route.query.showModal) { - openPurchaseModal(); - } - } + if (newCustomer) planQuery(); }); onMounted(() => {