sub2api/frontend/src/components/admin/payment/TopUsersLeaderboard.vue
erio 63d1860dc0 feat(payment): add complete payment system with multi-provider support
Add a full payment and subscription system supporting EasyPay (Alipay/WeChat),
Stripe, and direct Alipay/WeChat Pay providers with multi-instance load balancing.
2026-04-11 13:16:35 +08:00

53 lines
1.7 KiB
Vue

<template>
<div class="card p-4">
<h3 class="mb-4 text-sm font-semibold text-gray-900 dark:text-white">
{{ t('payment.admin.topUsers') }}
</h3>
<div
v-if="!users?.length"
class="flex h-32 items-center justify-center text-sm text-gray-500 dark:text-gray-400"
>
{{ t('payment.admin.noData') }}
</div>
<div v-else class="space-y-2">
<div
v-for="(user, idx) in users"
:key="user.user_id"
class="flex items-center justify-between rounded-lg px-3 py-2 hover:bg-gray-50 dark:hover:bg-dark-700"
>
<div class="flex items-center gap-3">
<span
:class="[
'flex h-6 w-6 items-center justify-center rounded-full text-xs font-bold',
rankClass(idx),
]"
>
{{ idx + 1 }}
</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ user.email }}</span>
</div>
<span class="text-sm font-medium text-gray-900 dark:text-white">
${{ user.amount.toFixed(2) }}
</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
defineProps<{
users: { user_id: number; email: string; amount: number }[]
}>()
function rankClass(idx: number): string {
if (idx === 0) return 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400'
if (idx === 1) return 'bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
if (idx === 2) return 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400'
return 'bg-gray-100 text-gray-500 dark:bg-dark-700 dark:text-gray-400'
}
</script>