Skip to content
Snippets Groups Projects
Verified Commit c92c7ad5 authored by Mateusz Tyszczak's avatar Mateusz Tyszczak :scroll:
Browse files

Add account details card

parent 5cb2e6c5
No related branches found
No related tags found
No related merge requests found
Pipeline #118163 passed
...@@ -36,6 +36,7 @@ const complete = async(data: { account: string; wallet: UsedWallet }) => { ...@@ -36,6 +36,7 @@ const complete = async(data: { account: string; wallet: UsedWallet }) => {
const wax = await getWax(); const wax = await getWax();
const { accounts: [ account ] } = await wax.api.database_api.find_accounts({ accounts: [ settingsStore.settings.account! ], delayed_votes_active: false }); const { accounts: [ account ] } = await wax.api.database_api.find_accounts({ accounts: [ settingsStore.settings.account! ], delayed_votes_active: false });
void userStore.setUserData(account); void userStore.setUserData(account);
walletStore.closeWalletSelectModal();
}; };
</script> </script>
......
...@@ -27,7 +27,7 @@ const userStore = useUserStore(); ...@@ -27,7 +27,7 @@ const userStore = useUserStore();
<div class="fixed top-0 z-10 bg-background/60 backdrop-blur-sm px-4 h-[60px] border-b w-full md:w-[calc(100%-var(--sidebar-width))] flex items-center justify-between"> <div class="fixed top-0 z-10 bg-background/60 backdrop-blur-sm px-4 h-[60px] border-b w-full md:w-[calc(100%-var(--sidebar-width))] flex items-center justify-between">
<ToggleSidebar /> <ToggleSidebar />
<div v-if="settingsStore.isLoaded && hasUser" class="ml-2 inline-flex items-center"> <div v-if="settingsStore.isLoaded && hasUser" class="ml-2 inline-flex items-center">
<Avatar class="w-8 h-8 mr-2"> <Avatar class="w-8 h-8 mr-2 border">
<AvatarImage v-if="userStore.profileImage" :src="userStore.profileImage" /> <AvatarImage v-if="userStore.profileImage" :src="userStore.profileImage" />
<AvatarFallback v-if="settingsStore.isLoaded && hasUser">{{ settingsStore.settings.account?.slice(0, 2) }}</AvatarFallback> <AvatarFallback v-if="settingsStore.isLoaded && hasUser">{{ settingsStore.settings.account?.slice(0, 2) }}</AvatarFallback>
</Avatar> </Avatar>
......
<script setup lang="ts">
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { mdiAccountBadgeOutline, mdiOpenInNew } from '@mdi/js';
import { useSettingsStore } from '@/stores/settings.store';
import { computed } from 'vue';
import { useUserStore } from '@/stores/user.store';
const settingsStore = useSettingsStore();
const hasUser = computed(() => settingsStore.settings.account !== undefined);
const userStore = useUserStore();
</script>
<template>
<Card class="w-full">
<CardHeader>
<CardTitle class="inline-flex items-center justify-between">
<span>Account details</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountBadgeOutline"/></svg>
</CardTitle>
<CardDescription class="mr-8">Account description parsed from the metadata</CardDescription>
</CardHeader>
<CardContent>
<div class="space-y-4" v-if="hasUser">
<div class="flex space-x-1">
<div>
<Avatar v-if="userStore.isReady" shape="square" class="border rounded-xl w-20 h-20 mr-2">
<AvatarImage v-if="userStore.profileImage" :src="userStore.profileImage" />
<AvatarFallback>{{ settingsStore.settings.account?.slice(0, 12) }}</AvatarFallback>
</Avatar>
<Skeleton v-else class="rounded-xl w-20 h-20 mr-2" />
</div>
<div class="flex flex-col space-y-1 w-full mt-1">
<div v-if="userStore.isReady" class="inline-flex items-center text-lg/3 font-bold">
<span>{{ userStore.name }}</span>
<a v-if="userStore.website" :href="userStore.website" target="_blank" class="">
<svg class="ml-2 inline" width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiOpenInNew"/></svg>
</a>
</div>
<Skeleton v-else class="w-40 h-6" />
<span v-if="userStore.isReady" class="text-xs font-bold top-[-5px]">@{{ settingsStore.settings.account }}</span>
<Skeleton v-else class="w-40 h-6" />
<span v-if="userStore.isReady" class="text-sm">{{ userStore.about }}</span>
<span v-else class="space-y-1">
<Skeleton class="w-full h-4" />
<Skeleton class="w-full h-4" />
<Skeleton class="w-full h-4" />
</span>
</div>
</div>
</div>
</CardContent>
</Card>
</template>
\ No newline at end of file
<script setup lang="ts">
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { mdiAccountKeyOutline } from '@mdi/js';
import { useSettingsStore } from '@/stores/settings.store';
import { computed, onMounted, ref, watch } from 'vue';
import type { authority } from '@hiveio/wax/vite';
import { getWax } from '@/stores/wax.store';
import PublicKey from '@/components/hive/PublicKey.vue';
const settingsStore = useSettingsStore();
const hasUser = computed(() => settingsStore.settings.account !== undefined);
const memoKey = ref<null | string>(null);
const activeAuthority = ref<null | authority>(null);
const postingAuthority = ref<null | authority>(null);
const ownerAuthority = ref<null | authority>(null);
const retrieveAuthority = async() => {
try {
const wax = await getWax();
const { AccountAuthorityUpdateOperation } = await import("@hiveio/wax/vite");
const op = await AccountAuthorityUpdateOperation.createFor(wax, settingsStore.settings.account!);
memoKey.value = op.role("memo").value;
postingAuthority.value = op.role("posting").value;
activeAuthority.value = op.role("active").value;
ownerAuthority.value = op.role("owner").value;
} catch(error) {
console.error(error); // TODO: Handle error - toast
}
};
watch(hasUser, value => {
if(value)
void retrieveAuthority();
});
onMounted(() => {
if(hasUser.value)
void retrieveAuthority();
});
</script>
<template>
<Card class="w-full max-w-[600px] backdrop-blur-sm">
<CardHeader>
<CardTitle class="inline-flex items-center justify-between">
<span>Authority info</span>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill: hsla(var(--foreground) / 80%)" :d="mdiAccountKeyOutline"/></svg>
</CardTitle>
<CardDescription class="mr-8">Use this module to gather information about your Hive on-chain authorities</CardDescription>
</CardHeader>
<CardContent>
<div class="space-y-4" v-if="hasUser">
<div class="flex flex-col">
<h4>Memo</h4>
<PublicKey v-if="memoKey" :value="memoKey" />
<Skeleton v-if="!memoKey" class="ml-2 h-[40px] w-full rounded-xl" />
</div>
<div class="flex flex-col">
<h4>Posting</h4>
<PublicKey v-if="postingAuthority" v-for="(key, val) in postingAuthority.key_auths" :key="key" :value="val" :after-value="`(${key}/${postingAuthority.weight_threshold})`" />
<PublicKey :context="0" v-if="postingAuthority" v-for="(key, val) in postingAuthority.account_auths" :key="key" :value="val" :after-value="`(${key}/${postingAuthority.weight_threshold})`"/>
<Skeleton v-if="!postingAuthority" class="ml-2 h-[40px] w-full rounded-xl" />
</div>
<div class="flex flex-col">
<h4>Active</h4>
<PublicKey v-if="activeAuthority" v-for="(key, val) in activeAuthority.key_auths" :key="key" :value="val" :after-value="`(${key}/${activeAuthority.weight_threshold})`" />
<PublicKey :context="0" v-if="activeAuthority" v-for="(key, val) in activeAuthority.account_auths" :key="key" :value="val" :after-value="`(${key}/${activeAuthority.weight_threshold})`"/>
<Skeleton v-if="!activeAuthority" class="ml-2 h-[40px] w-full rounded-xl" />
</div>
<div class="flex flex-col">
<h4>Owner</h4>
<PublicKey v-if="ownerAuthority" v-for="(key, val) in ownerAuthority.key_auths" :key="key" :value="val" :after-value="`(${key}/${ownerAuthority.weight_threshold})`" />
<PublicKey :context="0" v-if="ownerAuthority" v-for="(key, val) in ownerAuthority.account_auths" :key="key" :value="val" :after-value="`(${key}/${ownerAuthority.weight_threshold})`"/>
<Skeleton v-if="!ownerAuthority" class="ml-2 h-[40px] w-full rounded-xl" />
</div>
</div>
</CardContent>
</Card>
</template>
\ No newline at end of file
...@@ -64,7 +64,7 @@ const updateAuthority = async() => { ...@@ -64,7 +64,7 @@ const updateAuthority = async() => {
</script> </script>
<template> <template>
<Card class="w-full max-w-[600px] backdrop-blur-sm"> <Card class="w-full max-w-[600px]">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Process Authority Update</span> <span>Process Authority Update</span>
......
...@@ -116,7 +116,7 @@ const createAccount = async() => { ...@@ -116,7 +116,7 @@ const createAccount = async() => {
</script> </script>
<template> <template>
<Card class="w-full max-w-[600px] backdrop-blur-sm"> <Card class="w-full max-w-[600px]">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Process Account Creation</span> <span>Process Account Creation</span>
......
...@@ -76,7 +76,7 @@ const encryptOrDecrypt = async () => { ...@@ -76,7 +76,7 @@ const encryptOrDecrypt = async () => {
</script> </script>
<template> <template>
<Card class="w-full max-w-[600px] backdrop-blur-sm"> <Card class="w-full max-w-[600px]">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Memo encryption</span> <span>Memo encryption</span>
......
...@@ -87,7 +87,7 @@ onMounted(() => { ...@@ -87,7 +87,7 @@ onMounted(() => {
</script> </script>
<template> <template>
<Card class="w-full max-w-[600px] backdrop-blur-sm"> <Card class="w-full max-w-[600px]">
<CardHeader> <CardHeader>
<CardTitle class="inline-flex items-center justify-between"> <CardTitle class="inline-flex items-center justify-between">
<span>Transaction signing</span> <span>Transaction signing</span>
......
<script setup lang="ts"> <script setup lang="ts">
import AuthorityCard from '@/components/utilcards/AuthorityCard.vue'; import AccountDetails from '@/components/utilcards/AccountDetails.vue';
</script> </script>
<template> <template>
<div class="flex p-8"> <div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 p-8">
<AuthorityCard /> <AccountDetails />
</div> </div>
</template> </template>
...@@ -9,7 +9,7 @@ export const useUserStore = defineStore('user', { ...@@ -9,7 +9,7 @@ export const useUserStore = defineStore('user', {
}), }),
getters: { getters: {
profileImage: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.profile_image : undefined, profileImage: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.profile_image : undefined,
name: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.name : undefined, name: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.name || ctx.userData?.name : undefined,
about: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.about : undefined, about: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.about : undefined,
website: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.website : undefined website: (ctx): undefined | string => ctx.isReady ? ctx.parsedJsonMetadata?.profile?.website : undefined
}, },
...@@ -22,7 +22,9 @@ export const useUserStore = defineStore('user', { ...@@ -22,7 +22,9 @@ export const useUserStore = defineStore('user', {
}, },
setUserData(data: ApiAccount) { setUserData(data: ApiAccount) {
this.userData = data; this.userData = data;
this.parsedJsonMetadata = JSON.parse(data.posting_json_metadata); try {
this.parsedJsonMetadata = JSON.parse(data.posting_json_metadata);
} catch {}
this.isReady = true; this.isReady = true;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment