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

@@ -0,0 +1,54 @@
import type { Labrinth } from '@modrinth/api-client'
export function getProductDisplayName(product: Labrinth.Billing.Internal.Product): string {
const { metadata } = product
if (metadata.type === 'pyro') {
const ramGB = metadata.ram / 1024
return `${ramGB}GB Server`
}
if (metadata.type === 'medal') {
const ramGB = metadata.ram / 1024
return `${ramGB}GB Medal Server (${metadata.region})`
}
return 'Unknown Product'
}
export function getProductDescription(product: Labrinth.Billing.Internal.Product): string {
const { metadata } = product
if (metadata.type === 'pyro') {
return `${metadata.cpu} vCPU, ${metadata.ram}MB RAM, ${metadata.storage}MB Storage`
}
if (metadata.type === 'medal') {
return `${metadata.cpu} vCPU, ${metadata.ram}MB RAM, ${metadata.storage}MB Storage`
}
return ''
}
export function getPriceForInterval(
product: Labrinth.Billing.Internal.Product,
currency: string,
interval: Labrinth.Billing.Internal.PriceDuration,
): number | undefined {
const productPrice = product.prices.find((x) => x.currency_code === currency)
if (!productPrice) return undefined
const { prices } = productPrice
if (prices.type === 'recurring') {
return prices.intervals[interval]
}
return undefined
}
export const monthsInInterval: Record<'monthly' | 'quarterly' | 'yearly', number> = {
monthly: 1,
quarterly: 3,
yearly: 12,
}