refactor: removing useAsyncData for tanstack query (#5262)

* refactor: most places with useAsyncData replaced with tanstack query

* refactor report list and report view

* refactor organization page to use tanstack query

* fix types

* refactor collection page and include proper loading state

* fix followed projects proper loading state

* fix 404 handling

* fix organization loading and 404 states

* pnpm prepr

* refactor: remove useAsyncData on newsletter button

* refactor: remove useAsyncData on auth globals fetch

* refactor: settings/billing/index.vue to useQuery instead of useAsyncData

* refactor: user page to remove useAsyncData

* pnpm prepr

* fix reports pages

* fix notifications page

* fix billing page cannot read properties of null and prop warnings

* fix refresh causing 404 by removing useBaseFetch and use api-client

* fix stale data after removing organization from project

* pnpm prepr

* fix news erroring in build

* fix: project page loads header only after content

* fix: user page tanstack problems (start on migrating away from useBaseFetch)

* fix: start swapping useBaseFetch usages to api-client

* Revert "fix: start swapping useBaseFetch usages to api-client"

This reverts commit 3df3fab11d.

* fix: remove debug logging

* fix: lint

---------

Co-authored-by: Calum H. <calum@modrinth.com>
Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
This commit is contained in:
Truman Gao
2026-03-16 19:10:29 +00:00
committed by GitHub
co-authored by Calum H. Calum H.
parent d0c7575a23
commit 681ae5d1d8
53 changed files with 1686 additions and 1079 deletions
@@ -39,6 +39,7 @@
</template>
<script setup>
import { Badge, Breadcrumbs, useFormatDateTime, useFormatPrice } from '@modrinth/ui'
import { useQuery } from '@tanstack/vue-query'
import { products } from '~/generated/state.json'
@@ -53,23 +54,22 @@ const formatDate = useFormatDateTime({
day: '2-digit',
})
const { data: charges } = await useAsyncData(
'billing/payments',
() => useBaseFetch('billing/payments', { internal: true }),
{
transform: (charges) => {
return charges
.filter((charge) => charge.status !== 'open' && charge.status !== 'cancelled')
.map((charge) => {
const product = products.find((product) =>
product.prices.some((price) => price.id === charge.price_id),
)
const { data: charges } = useQuery({
queryKey: ['billing', 'payments'],
queryFn: async () => {
const charges = await useBaseFetch('billing/payments', { internal: true })
return charges
.filter((charge) => charge.status !== 'open' && charge.status !== 'cancelled')
.map((charge) => {
const product = products.find((product) =>
product.prices.some((price) => price.id === charge.price_id),
)
charge.product = product
charge.product = product
return charge
})
},
return charge
})
},
)
placeholderData: [],
})
</script>
@@ -299,12 +299,14 @@
<div class="flex text-2xl font-bold text-contrast">
<span class="text-contrast">
{{
formatPrice(
getProductPrice(getPyroProduct(subscription), subscription.interval)
.prices.intervals[subscription.interval],
getProductPrice(getPyroProduct(subscription), subscription.interval)
.currency_code,
)
getProductPrice(getPyroProduct(subscription), subscription.interval)
? formatPrice(
getProductPrice(getPyroProduct(subscription), subscription.interval)
.prices.intervals[subscription.interval],
getProductPrice(getPyroProduct(subscription), subscription.interval)
.currency_code,
)
: ''
}}
</span>
<span>/{{ subscription.interval.replace('ly', '') }}</span>
@@ -450,6 +452,7 @@
@proceed="removePaymentMethod(removePaymentMethodIndex)"
/>
<PurchaseModal
v-if="customer && paymentMethods"
ref="midasPurchaseModal"
:product="midasProduct"
:country="country"
@@ -620,6 +623,7 @@ import {
useVIntl,
} from '@modrinth/ui'
import { calculateSavings, getCurrency } from '@modrinth/utils'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { computed, ref } from 'vue'
import { useBaseFetch } from '@/composables/fetch.js'
@@ -734,25 +738,32 @@ const messages = defineMessages({
},
})
const [
{ data: paymentMethods, refresh: refreshPaymentMethods },
{ data: charges, refresh: refreshCharges },
{ data: customer, refresh: refreshCustomer },
{ data: subscriptions, refresh: refreshSubscriptions },
{ data: productsData, refresh: refreshProducts },
{ data: serversData, refresh: refreshServers },
] = await Promise.all([
useAsyncData('billing/payment_methods', () =>
useBaseFetch('billing/payment_methods', { internal: true }),
),
useAsyncData('billing/payments', () => useBaseFetch('billing/payments', { internal: true })),
useAsyncData('billing/customer', () => useBaseFetch('billing/customer', { internal: true })),
useAsyncData('billing/subscriptions', () =>
useBaseFetch('billing/subscriptions', { internal: true }),
),
useAsyncData('billing/products', () => useBaseFetch('billing/products', { internal: true })),
useAsyncData('servers', () => useServersFetch('servers')),
])
const queryClient = useQueryClient()
const { data: paymentMethods } = useQuery({
queryKey: ['billing', 'payment_methods'],
queryFn: () => useBaseFetch('billing/payment_methods', { internal: true }),
})
const { data: charges } = useQuery({
queryKey: ['billing', 'payments'],
queryFn: () => useBaseFetch('billing/payments', { internal: true }),
})
const { data: customer } = useQuery({
queryKey: ['billing', 'customer'],
queryFn: () => useBaseFetch('billing/customer', { internal: true }),
})
const { data: subscriptions } = useQuery({
queryKey: ['billing', 'subscriptions'],
queryFn: () => useBaseFetch('billing/subscriptions', { internal: true }),
})
const { data: productsData } = useQuery({
queryKey: ['billing', 'products'],
queryFn: () => useBaseFetch('billing/products', { internal: true }),
})
const { data: serversData } = useQuery({
queryKey: ['servers'],
queryFn: () => useServersFetch('servers'),
})
const midasProduct = ref(products.find((x) => x.metadata?.type === 'midas'))
const midasSubscription = computed(() =>
@@ -996,12 +1007,8 @@ const resubscribePyro = async (subscriptionId, wasSuspended) => {
const refresh = async () => {
await Promise.all([
refreshPaymentMethods(),
refreshCharges(),
refreshCustomer(),
refreshSubscriptions(),
refreshProducts(),
refreshServers(),
queryClient.invalidateQueries({ queryKey: ['billing'] }),
queryClient.invalidateQueries({ queryKey: ['servers'] }),
])
}