Files
Rocketmc/apps/frontend/src/pages/settings/billing/charges.vue
Geometrically 3a4843fb46 Billing / plus frontend (#2130)
* [wip] initial

* [wip] subscriptions/plus frontend

* [wip] finish payment flow

* Charges page

* finish most subscriptions work

* Finish

* update eslint

* Fix issues

* fix intl extract

* fix omorphia locale extract

* fix responsiveness

* fix lint
2024-08-15 23:21:30 -07:00

89 lines
2.6 KiB
Vue

<template>
<div>
<section class="card">
<Breadcrumbs
current-title="Past charges"
:link-stack="[{ href: '/settings/billing', label: 'Billing and subscriptions' }]"
/>
<h2>Past charges</h2>
<p>All of your past charges to your Modrinth account will be listed here:</p>
<div
v-for="charge in charges"
:key="charge.id"
class="universal-card recessed flex items-center justify-between gap-4"
>
<div class="flex flex-col gap-1">
<div class="flex items-center gap-1">
<span class="font-bold text-primary">
<template v-if="charge.product.metadata.type === 'midas'"> Modrinth Plus </template>
<template v-else> Unknown product </template>
<template v-if="charge.metadata.modrinth_subscription_interval">
{{ charge.metadata.modrinth_subscription_interval }}
</template>
</span>
<span>{{ formatPrice(charge.amount, charge.currency) }}</span>
</div>
<div class="flex items-center gap-1">
<Badge :color="charge.status === 'succeeded' ? 'green' : 'red'" :type="charge.status" />
{{ $dayjs.unix(charge.created).format("YYYY-MM-DD") }}
</div>
</div>
<a
v-if="charge.receipt_url"
class="iconified-button raised-button"
:href="charge.receipt_url"
>
<ReceiptTextIcon />
View receipt
</a>
</div>
</section>
</div>
</template>
<script setup>
import { ReceiptTextIcon } from "@modrinth/assets";
import { Breadcrumbs, Badge } from "@modrinth/ui";
import { products } from "~/generated/state.json";
definePageMeta({
middleware: "auth",
});
const vintl = useVIntl();
const { data: charges } = await useAsyncData(
"billing/payments",
() => useBaseFetch("billing/payments", { internal: true }),
{
transform: (charges) => {
return charges.map((charge) => {
const product = products.find((product) =>
product.prices.some((price) => price.id === charge.metadata.modrinth_price_id),
);
charge.product = product;
return charge;
});
},
},
);
// TODO move to omorphia utils , duplicated from index
function formatPrice(price, currency) {
const formatter = new Intl.NumberFormat(vintl.locale, {
style: "currency",
currency,
});
const maxDigits = formatter.resolvedOptions().maximumFractionDigits;
const convertedPrice = price / Math.pow(10, maxDigits);
return formatter.format(convertedPrice);
}
console.log(charges);
</script>