|
2 | 2 | <main class="h-full flex flex-col justify-center px-4"> |
3 | 3 | <AppAccountLogo class="dark:text-neutral-100 h-16 md:h-20 mb-12" /> |
4 | 4 |
|
5 | | - <div class="space-y-2"> |
| 5 | + <div |
| 6 | + class="space-y-2" |
| 7 | + :loading="!recoveryState" |
| 8 | + > |
6 | 9 | <h2 class="text-3xl font-bold text-center mb-2 text-gray-900 dark:text-white"> |
7 | 10 | Account in Recovery |
8 | 11 | </h2> |
9 | 12 | <p class="text-center text-gray-600 dark:text-gray-400 text-lg"> |
10 | | - Your account is not ready yet |
| 13 | + {{ recoveryState!.type === 'notYet' ? "Your account is not ready yet" : "Your recovery request already expired" |
| 14 | + }} |
11 | 15 | </p> |
12 | 16 | </div> |
13 | 17 |
|
14 | | - <div class="flex flex-col items-center mt-8"> |
| 18 | + <div |
| 19 | + v-if="recoveryState!.type === 'notYet'" |
| 20 | + class="flex flex-col items-center mt-8" |
| 21 | + > |
15 | 22 | <div class="p-6 rounded-lg bg-gray-50 dark:bg-gray-800 max-w-md w-full text-center"> |
16 | 23 | <p class="text-gray-600 dark:text-gray-300 mb-4"> |
17 | | - Your account is currently in the recovery process. It will be ready in <span class="font-semibold text-gray-900 dark:text-white">24hs</span>. |
| 24 | + Your account is currently in the recovery process. It will be ready in <span |
| 25 | + class="font-semibold text-gray-900 dark:text-white" |
| 26 | + >{{ recoveryState!.time }}</span>. |
18 | 27 | </p> |
19 | 28 | <p class="text-sm text-gray-500 dark:text-gray-400"> |
20 | 29 | Please check back later |
|
28 | 37 | href="/" |
29 | 38 | class="inline-flex items-center gap-2 justify-center" |
30 | 39 | > |
31 | | - <ZkIcon |
32 | | - icon="arrow_back" |
33 | | - /> |
| 40 | + <ZkIcon icon="arrow_back" /> |
34 | 41 | Back to Home |
35 | 42 | </ZkLink> |
36 | 43 | </div> |
37 | 44 | </main> |
38 | 45 | </template> |
| 46 | + |
| 47 | +<script setup lang="ts"> |
| 48 | +import { formatDuration, intervalToDuration } from "date-fns"; |
| 49 | +import type { Address } from "viem"; |
| 50 | +import { z } from "zod"; |
| 51 | +
|
| 52 | +import { AddressSchema } from "@/utils/schemas"; |
| 53 | +
|
| 54 | +const route = useRoute(); |
| 55 | +const { checkRecoveryRequest, getPendingRecoveryData } = useRecoveryGuardian(); |
| 56 | +
|
| 57 | +const accountAddress = ref<Address | null>(null); |
| 58 | +
|
| 59 | +const params = z.object({ |
| 60 | + address: AddressSchema, |
| 61 | +}).safeParse(route.query); |
| 62 | +
|
| 63 | +const pendingRecovery = ref<Awaited<ReturnType<typeof checkRecoveryRequest>> | null>(null); |
| 64 | +const recoveryState = ref<{ type: "notYet"; time: string } | { type: "expired" } | null>(null); |
| 65 | +
|
| 66 | +if (!params.success) { |
| 67 | + throw createError({ |
| 68 | + statusCode: 404, |
| 69 | + statusMessage: "Page not found", |
| 70 | + fatal: true, |
| 71 | + }); |
| 72 | +} else { |
| 73 | + accountAddress.value = params.data.address; |
| 74 | + const recoveryRequestData = await getPendingRecoveryData(accountAddress.value); |
| 75 | + if (recoveryRequestData) { |
| 76 | + const recoveryData = await checkRecoveryRequest(recoveryRequestData[2]); |
| 77 | + pendingRecovery.value = recoveryData; |
| 78 | + if (recoveryData && recoveryData[2] > 0n) { |
| 79 | + recoveryState.value = { |
| 80 | + type: "notYet", time: formatDuration(intervalToDuration({ |
| 81 | + start: 0, |
| 82 | + end: parseFloat((recoveryData[2]).toString()) * 1000, |
| 83 | + })), |
| 84 | + }; |
| 85 | + } else if (recoveryData && recoveryData[2] === 0n) { |
| 86 | + recoveryState.value = { |
| 87 | + type: "expired", |
| 88 | + }; |
| 89 | + } |
| 90 | + } |
| 91 | +} |
| 92 | +</script> |
0 commit comments