feat: start of cross platform page system (#4731)

* feat: abstract api-client DI into ui package

* feat: cross platform page system

* feat: tanstack as cross platform useAsyncData

* feat: archon servers routes + labrinth billing routes

* fix: dont use partial

* feat: migrate server list page to tanstack + api-client + re-enabled broken features!

* feat: migrate servers manage page to api-client before page system

* feat: migrate manage page to page system

* fix: type issues

* fix: upgrade wrapper bugs

* refactor: move state types into api-client

* feat: disable financial stuff on app frontend

* feat: finalize cross platform page system for now

* fix: lint

* fix: build issues

* feat: remove papaparse

* fix: lint

* fix: interface error

---------

Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
Calum H.
2025-11-14 17:15:09 +00:00
committed by GitHub
parent 26feaf753a
commit 7ccc32675b
79 changed files with 2631 additions and 1259 deletions

View File

@@ -1,16 +1,18 @@
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { InfoIcon } from '@modrinth/assets'
import { formatPrice } from '@modrinth/utils'
import { type MessageDescriptor, useVIntl } from '@vintl/vintl'
import { Menu } from 'floating-vue'
import { computed, inject, type Ref } from 'vue'
import { monthsInInterval, type ServerBillingInterval, type ServerPlan } from '../../utils/billing'
import { getPriceForInterval, monthsInInterval } from '../../utils/product-utils'
import type { ServerBillingInterval } from './ModrinthServersPurchaseModal.vue'
import ServersSpecs from './ServersSpecs.vue'
const props = withDefaults(
defineProps<{
plan: ServerPlan
plan: Labrinth.Billing.Internal.Product
title: MessageDescriptor
description: MessageDescriptor
buttonColor?: 'standard' | 'brand' | 'red' | 'orange' | 'green' | 'blue' | 'purple'
@@ -25,7 +27,7 @@ const props = withDefaults(
)
const emit = defineEmits<{
(e: 'select', plan: ServerPlan): void
(e: 'select', plan: Labrinth.Billing.Internal.Product): void
}>()
const { formatMessage, locale } = useVIntl()
@@ -36,13 +38,23 @@ const currency = inject<string>('currency')
const perMonth = computed(() => {
if (!props.plan || !currency || !selectedInterval?.value) return undefined
const total = props.plan.prices?.find((x) => x.currency_code === currency)?.prices?.intervals?.[
selectedInterval.value
]
const total = getPriceForInterval(props.plan, currency, selectedInterval.value)
if (!total) return undefined
return total / monthsInInterval[selectedInterval.value]
})
const planSpecs = computed(() => {
const metadata = props.plan.metadata
if (metadata.type === 'pyro' || metadata.type === 'medal') {
return {
ram: metadata.ram,
storage: metadata.storage,
cpu: metadata.cpu,
}
}
return null
})
const mostPopularStyle = computed(() => {
if (!props.mostPopular) return undefined
const style: Record<string, string> = {
@@ -121,11 +133,11 @@ const mostPopularStyle = computed(() => {
</template>
<template #popper>
<div class="w-fit rounded-md border border-contrast/10 p-3 shadow-lg">
<div v-if="planSpecs" class="w-fit rounded-md border border-contrast/10 p-3 shadow-lg">
<ServersSpecs
:ram="plan.metadata.ram!"
:storage="plan.metadata.storage!"
:cpus="plan.metadata.cpu!"
:ram="planSpecs.ram"
:storage="planSpecs.storage"
:cpus="planSpecs.cpu"
/>
</div>
</template>