You've already forked AstralRinth
forked from xxxOFFxxx/AstralRinth
New payouts system (#1456)
* initial * finish withdraw page * Finish frontend * Fix UI a bit * tester fixes
This commit is contained in:
@@ -6,130 +6,133 @@
|
||||
:link-stack="[{ href: '/dashboard/revenue', label: 'Revenue' }]"
|
||||
/>
|
||||
<h2>Transfer history</h2>
|
||||
<p>
|
||||
All of your transfers from your Modrinth balance to your PayPal or Venmo accounts will be
|
||||
listed here:
|
||||
</p>
|
||||
<div class="grid-table">
|
||||
<div class="grid-table__row grid-table__header">
|
||||
<div class="desktop">Date</div>
|
||||
<div class="desktop">Status</div>
|
||||
<div class="desktop">Amount</div>
|
||||
<div class="mobile">Transaction</div>
|
||||
<p>All of your withdrawals from your Modrinth balance will be listed here:</p>
|
||||
<div v-for="payout in sortedPayouts" :key="payout.id" class="universal-card recessed payout">
|
||||
<div class="platform">
|
||||
<PayPalIcon v-if="payout.method === 'paypal'" />
|
||||
<TremendousIcon v-else-if="payout.method === 'tremendous'" />
|
||||
<VenmoIcon v-else-if="payout.method === 'venmo'" />
|
||||
<UnknownIcon v-else />
|
||||
</div>
|
||||
<div
|
||||
v-for="(payout, index) in payouts.payouts.filter((x) => x.status === 'success')"
|
||||
:key="`payout-${index}`"
|
||||
class="grid-table__row"
|
||||
>
|
||||
<div>{{ $dayjs(payout.created).format('MMMM D, YYYY [at] h:mm A') }}</div>
|
||||
<div><Badge :type="payout.status" /></div>
|
||||
<div class="amount">{{ $formatMoney(payout.amount) }}</div>
|
||||
<div class="payout-info">
|
||||
<div>
|
||||
<strong>
|
||||
{{ $dayjs(payout.created).format('MMMM D, YYYY [at] h:mm A') }}
|
||||
</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span class="amount">{{ $formatMoney(payout.amount) }}</span>
|
||||
<template v-if="payout.fee">⋅ Fee {{ $formatMoney(payout.fee) }}</template>
|
||||
</div>
|
||||
<div class="payout-status">
|
||||
<span>
|
||||
<Badge v-if="payout.status === 'success'" color="green" type="Success" />
|
||||
<Badge v-else-if="payout.status === 'cancelling'" color="yellow" type="Cancelling" />
|
||||
<Badge v-else-if="payout.status === 'cancelled'" color="red" type="Cancelled" />
|
||||
<Badge v-else-if="payout.status === 'failed'" color="red" type="Failed" />
|
||||
<Badge v-else-if="payout.status === 'in-transit'" color="yellow" type="In transit" />
|
||||
<Badge v-else :type="payout.status" />
|
||||
</span>
|
||||
<template v-if="payout.method">
|
||||
<span>⋅</span>
|
||||
<span>{{ $formatWallet(payout.method) }} ({{ payout.method_address }})</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<button
|
||||
v-if="payout.status === 'in-transit'"
|
||||
class="iconified-button raised-button"
|
||||
@click="cancelPayout(payout.id)"
|
||||
>
|
||||
<XIcon /> Cancel payment
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Badge from '~/components/ui/Badge.vue'
|
||||
import Breadcrumbs from '~/components/ui/Breadcrumbs.vue'
|
||||
import { Badge, Breadcrumbs, XIcon, PayPalIcon, UnknownIcon } from 'omorphia'
|
||||
import dayjs from 'dayjs'
|
||||
import TremendousIcon from '~/assets/images/external/tremendous.svg'
|
||||
import VenmoIcon from '~/assets/images/external/venmo-small.svg'
|
||||
|
||||
useHead({
|
||||
title: 'Transfer history - Modrinth',
|
||||
})
|
||||
|
||||
const data = await useNuxtApp()
|
||||
const auth = await useAuth()
|
||||
|
||||
const { data: payouts } = await useAsyncData(`user/${auth.value.user.id}/payouts`, () =>
|
||||
useBaseFetch(`user/${auth.value.user.id}/payouts`)
|
||||
const { data: payouts, refresh } = await useAsyncData(`payout`, () =>
|
||||
useBaseFetch(`payout`, {
|
||||
apiVersion: 3,
|
||||
})
|
||||
)
|
||||
|
||||
const sortedPayouts = computed(() =>
|
||||
payouts.value.sort((a, b) => dayjs(b.created) - dayjs(a.created))
|
||||
)
|
||||
|
||||
async function cancelPayout(id) {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`payout/${id}`, {
|
||||
method: 'DELETE',
|
||||
apiVersion: 3,
|
||||
})
|
||||
await refresh()
|
||||
await useAuth(auth.value.token)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
data.$notify({
|
||||
group: 'main',
|
||||
title: 'An error occurred',
|
||||
text: err.data.description,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
stopLoading()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.grid-table {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
border-radius: var(--size-rounded-sm);
|
||||
overflow: hidden;
|
||||
margin-top: var(--spacing-card-md);
|
||||
.payout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
.grid-table__header {
|
||||
.mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-table__row {
|
||||
display: contents;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: var(--spacing-card-sm);
|
||||
|
||||
// Left edge of table
|
||||
&:first-child,
|
||||
&.mobile {
|
||||
padding-left: var(--spacing-card-bg);
|
||||
}
|
||||
|
||||
// Right edge of table
|
||||
&:last-child {
|
||||
padding-right: var(--spacing-card-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2n + 1) > div {
|
||||
background-color: var(--color-table-alternate-row);
|
||||
}
|
||||
|
||||
> div {
|
||||
padding-top: var(--spacing-card-bg);
|
||||
padding-bottom: var(--spacing-card-bg);
|
||||
}
|
||||
|
||||
&.grid-table__header > div {
|
||||
background-color: var(--color-bg);
|
||||
font-weight: bold;
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 560px) {
|
||||
.platform {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.grid-table__row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.75rem;
|
||||
background-color: var(--color-raised-bg);
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
border-radius: 20rem;
|
||||
|
||||
> div {
|
||||
padding: var(--spacing-card-xs) var(--spacing-card-bg);
|
||||
|
||||
&:first-child,
|
||||
&.mobile {
|
||||
padding-top: var(--spacing-card-bg);
|
||||
}
|
||||
|
||||
&:last-child,
|
||||
&.mobile {
|
||||
padding-bottom: var(--spacing-card-bg);
|
||||
}
|
||||
}
|
||||
svg {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-table__header {
|
||||
.mobile {
|
||||
display: flex;
|
||||
}
|
||||
.desktop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.payout-status {
|
||||
display: flex;
|
||||
gap: 0.5ch;
|
||||
}
|
||||
|
||||
.amount {
|
||||
color: var(--color-heading);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.input-group {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user