Files
vmall/apps/mall/pages/user/coupons.vue
T

64 lines
1.9 KiB
Vue

<script setup lang="ts">
import { t as pick } from "@vmall/shared";
import type { Coupon } from "@vmall/shared";
definePageMeta({ middleware: "auth" });
const { locale, t } = useI18n();
const { $api } = useNuxtApp();
const coupons = ref<Coupon[]>([]);
const loading = ref(true);
const error = ref("");
const statusLabels = computed<Record<string, string>>(() => ({
claimed: t("user.couponClaimed"),
redeemed: t("user.couponRedeemed"),
expired: t("user.couponExpired"),
}));
async function load(): Promise<void> {
loading.value = true;
error.value = "";
try {
coupons.value = await $api.listMyCoupons();
} catch {
error.value = t("user.loadFailed");
} finally {
loading.value = false;
}
}
onMounted(() => void load());
</script>
<template>
<VCard class="min-h-[560px]">
<h1 class="text-text mb-4 text-xl font-bold">{{ t("user.couponsTitle") }}</h1>
<p v-if="error" class="border-danger/30 bg-danger/10 text-danger mb-4 border px-3.5 py-2.5">
{{ error }}
</p>
<div v-else-if="loading" class="text-muted py-10">{{ t("common.loading") }}</div>
<UiEmptyState v-else-if="coupons.length === 0" :text="t('user.noCoupons')" />
<VTable v-else>
<thead>
<tr>
<th>{{ t("user.couponTitle") }}</th>
<th>{{ t("user.amount") }}</th>
<th>{{ t("user.threshold") }}</th>
<th>{{ t("user.expiresAt") }}</th>
<th>{{ t("user.couponStatus") }}</th>
</tr>
</thead>
<tbody>
<tr v-for="coupon in coupons" :key="coupon.id">
<td>{{ pick(coupon.title, locale) }}</td>
<td><PriceText :amount-minor="coupon.amount_minor" :currency="coupon.currency" /></td>
<td><PriceText :amount-minor="coupon.threshold_minor" :currency="coupon.currency" /></td>
<td>{{ coupon.ends_at.slice(0, 10) }}</td>
<td>{{ statusLabels[coupon.status] ?? coupon.status }}</td>
</tr>
</tbody>
</VTable>
</VCard>
</template>