index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <script setup lang="ts">
  2. /* Import modules. */
  3. import moment from 'moment'
  4. definePageMeta({
  5. layout: 'admin',
  6. })
  7. useHead({
  8. title: `Club Dashboard — Hush Your Money`,
  9. meta: [
  10. { name: 'description', content: `Hush Your Money makes spending safu.` }
  11. ],
  12. })
  13. /* Initialize stores. */
  14. import { useSystemStore } from '@/stores/system'
  15. const System = useSystemStore()
  16. const profiles = ref(null)
  17. const status = ref(null)
  18. const system = ref(null)
  19. const clubAddress = ref(null)
  20. const clubPubkey = ref(null)
  21. const displayCreatedAt = computed(() => {
  22. if (!status.value || !status.value.createdAt) {
  23. return 'loading...'
  24. }
  25. return moment.unix(status.value.createdAt).format('llll')
  26. })
  27. const displayTimeAgo = computed(() => {
  28. if (!status.value || !status.value.createdAt) {
  29. return 'loading...'
  30. }
  31. return moment.unix(status.value.createdAt).fromNow()
  32. })
  33. const numProfiles = computed(() => {
  34. if (!profiles.value) {
  35. return 'loading...'
  36. }
  37. return Object.keys(profiles.value).length
  38. })
  39. const lastProfileUpdate = computed(() => {
  40. if (!profiles.value) {
  41. return 'loading...'
  42. }
  43. const times = []
  44. Object.keys(profiles.value).forEach(_profileid => {
  45. const profile = profiles.value[_profileid]
  46. const time = profile.updatedAt
  47. console.log('UPDATE TIME', time)
  48. times.push(time)
  49. })
  50. const sorted = times.sort((a, b) => {
  51. return b - a
  52. })
  53. return moment.unix(sorted[0]).format('llll')
  54. })
  55. const displayProfileTimeAgo = computed(() => {
  56. if (!profiles.value) {
  57. return 'loading...'
  58. }
  59. const times = []
  60. Object.keys(profiles.value).forEach(_profileid => {
  61. const profile = profiles.value[_profileid]
  62. const time = profile.updatedAt
  63. console.log('UPDATE TIME', time)
  64. times.push(time)
  65. })
  66. const sorted = times.sort((a, b) => {
  67. return b - a
  68. })
  69. return moment.unix(sorted[0]).fromNow()
  70. })
  71. const init = async () => {
  72. /* Request system (status). */
  73. system.value = await $fetch('/api/system')
  74. .catch(err => console.error(err))
  75. // console.log('SYSTEM', system.value)
  76. /* Set (system) status. */
  77. status.value = system.value.status
  78. /* Request profiles. */
  79. profiles.value = await $fetch('/api/profiles')
  80. .catch(err => console.error(err))
  81. // console.log('PROFILES', profiles.value)
  82. /* Request wallet. */
  83. const response = await $fetch('/api/wallet')
  84. .catch(err => console.error(err))
  85. console.log('WALLET', response)
  86. clubAddress.value = response.address
  87. clubPubkey.value = response.publicKey
  88. }
  89. onMounted(() => {
  90. init()
  91. })
  92. // onBeforeUnmount(() => {
  93. // console.log('Before Unmount!')
  94. // // Now is the time to perform all cleanup operations.
  95. // })
  96. </script>
  97. <template>
  98. <main class="max-w-5xl mx-auto py-5 flex flex-col gap-4">
  99. <h1 class="text-5xl font-medium">
  100. Club Dashboard
  101. </h1>
  102. <p>
  103. Welcome to the Hush Your Money Administration Area.
  104. </p>
  105. <div class="grid grid-cols-2 gap-6">
  106. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  107. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  108. {{numProfiles * 2}} Fusions??
  109. </h2>
  110. <h3 class="text-amber-700 text-2xl font-medium tracking-widest">
  111. {{lastProfileUpdate}}
  112. </h3>
  113. <h3 class="text-amber-700 text-base text-right font-medium tracking-widest">
  114. {{displayProfileTimeAgo}}
  115. </h3>
  116. </section>
  117. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  118. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  119. {{numProfiles}} Profiles
  120. </h2>
  121. <h3 class="text-amber-700 text-2xl font-medium tracking-widest">
  122. {{lastProfileUpdate}}
  123. </h3>
  124. <h3 class="text-amber-700 text-base text-right font-medium tracking-widest">
  125. {{displayProfileTimeAgo}}
  126. </h3>
  127. </section>
  128. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  129. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  130. {{Math.ceil(numProfiles * 3.33)}} Sessions??
  131. </h2>
  132. <h3 class="text-amber-700 text-2xl font-medium tracking-widest">
  133. {{lastProfileUpdate}}
  134. </h3>
  135. <h3 class="text-amber-700 text-base text-right font-medium tracking-widest">
  136. {{displayProfileTimeAgo}}
  137. </h3>
  138. </section>
  139. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  140. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  141. Last Club Startup
  142. </h2>
  143. <h3 class="text-amber-700 text-2xl font-medium tracking-widest">
  144. {{displayCreatedAt}}
  145. </h3>
  146. <h3 class="text-amber-700 text-base text-right font-medium tracking-widest">
  147. {{displayTimeAgo}}
  148. </h3>
  149. </section>
  150. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  151. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  152. Club Wallet
  153. </h2>
  154. <NuxtLink :to="'https://explorer.nexa.org/address/' + clubAddress" target="_blank" class="text-amber-700 text-base font-medium tracking-tight hover:text-amber-600 hover:underline">
  155. {{clubAddress}}
  156. </NuxtLink>
  157. <h3 class="text-amber-700 text-base text-right font-medium italic">
  158. Current signer of ALL Club messages
  159. </h3>
  160. </section>
  161. <section class="w-full px-5 py-3 flex flex-col gap-0 bg-amber-100 border-2 border-amber-300 rounded-2xl shadow">
  162. <h2 class="text-amber-500 text-base font-bold tracking-widest uppercase">
  163. Club Public Key
  164. </h2>
  165. <h3 class="text-amber-700 text-xs font-medium tracking-tight">
  166. {{clubPubkey}}
  167. </h3>
  168. <h3 class="text-amber-700 text-base text-right font-medium italic">
  169. Use this key to sign encrypted messages
  170. </h3>
  171. </section>
  172. </div>
  173. <pre class="text-xs">{{system}}</pre>
  174. <pre class="text-xs">{{profiles}}</pre>
  175. </main>
  176. </template>