feat: address

This commit is contained in:
Alisa | Side.one 2023-05-15 09:36:48 +08:00
parent 8ae0e88925
commit ccf0d755df
4 changed files with 54 additions and 277 deletions

View File

@ -1,234 +0,0 @@
<script setup lang="ts">
import type { SearchHeader, SearchItem } from '@/@fake-db/types';
import axios from 'axios';
import { useThemeConfig } from '@core/composable/useThemeConfig';
interface Suggestion {
icon: string;
title: string;
url: object;
}
const { appContentLayoutNav } = useThemeConfig();
interface SuggestionGroup {
title: string;
content: Suggestion[];
}
defineOptions({
inheritAttrs: false,
});
// 👉 Is App Search Bar Visible
const isAppSearchBarVisible = ref(false);
// 👉 Default suggestions
const suggestionGroups: SuggestionGroup[] = [
{
title: 'Popular Searches',
content: [
{
icon: 'mdi-chart-donut',
title: 'Analytics',
url: { name: 'dashboards-analytics' },
},
{
icon: 'mdi-chart-bubble',
title: 'CRM',
url: { name: 'dashboards-crm' },
},
{
icon: 'mdi-file-outline',
title: 'Invoice List',
url: { name: 'apps-invoice-list' },
},
{
icon: 'mdi-account-group-outline',
title: 'User List',
url: { name: 'apps-user-list' },
},
],
},
{
title: 'Apps & Pages',
content: [
{
icon: 'mdi-calendar',
title: 'Calendar',
url: { name: 'apps-calendar' },
},
{
icon: 'mdi-file-plus-outline',
title: 'Invoice Add',
url: { name: 'apps-invoice-add' },
},
{
icon: 'mdi-currency-usd',
title: 'Pricing',
url: { name: 'pages-pricing' },
},
{
icon: 'mdi-account-cog-outline',
title: 'Account Settings',
url: { name: 'pages-account-settings-tab', params: { tab: 'account' } },
},
],
},
{
title: 'User Interface',
content: [
{
icon: 'mdi-alpha-a-box-outline',
title: 'Typography',
url: { name: 'pages-typography' },
},
{ icon: 'mdi-tab', title: 'Tabs', url: { name: 'components-tabs' } },
{
icon: 'mdi-gesture-tap-button',
title: 'Buttons',
url: { name: 'components-button' },
},
{
icon: 'mdi-keyboard-settings-outline',
title: 'Statistics',
url: { name: 'pages-cards-card-statistics' },
},
],
},
{
title: 'Popular Searches',
content: [
{
icon: 'mdi-format-list-checkbox',
title: 'Select',
url: { name: 'forms-select' },
},
{
icon: 'mdi-lastpass',
title: 'Combobox',
url: { name: 'forms-combobox' },
},
{
icon: 'mdi-calendar-range-outline',
title: 'Date & Time Picker',
url: { name: 'forms-date-time-picker' },
},
{
icon: 'mdi-hexagram-outline',
title: 'Rating',
url: { name: 'forms-rating' },
},
],
},
];
// 👉 No Data suggestion
const noDataSuggestions: Suggestion[] = [
{
title: 'Analytics Dashboard',
icon: 'mdi-cart-outline',
url: { name: 'dashboards-analytics' },
},
{
title: 'Account Settings',
icon: 'mdi-account-outline',
url: { name: 'pages-account-settings-tab', params: { tab: 'account' } },
},
{
title: 'Pricing Page',
icon: 'mdi-cash',
url: { name: 'pages-pricing' },
},
];
const searchQuery = ref('');
const searchResult = ref<(SearchItem | SearchHeader)[]>([]);
const router = useRouter();
// 👉 fetch search result API
watchEffect(() => {
axios
.get('/app-bar/search', {
params: {
q: searchQuery.value,
},
})
.then((response) => {
searchResult.value = response.data;
});
});
// 👉 redirect the selected page
const redirectToSuggestedOrSearchedPage = (selected: Suggestion) => {
router.push(selected.url);
isAppSearchBarVisible.value = false;
searchQuery.value = '';
};
const LazyAppBarSearch = defineAsyncComponent(
() => import('@core/components/AppBarSearch.vue')
);
</script>
<template>
<div
class="d-flex align-center cursor-pointer"
v-bind="$attrs"
@click="isAppSearchBarVisible = !isAppSearchBarVisible"
>
<!-- 👉 Search Trigger button -->
<IconBtn>
<VIcon icon="mdi-magnify" />
</IconBtn>
<span
v-if="appContentLayoutNav === 'vertical'"
class="d-none d-md-flex align-center text-disabled"
>
<span class="me-3">Search</span>
<span class="meta-key">&#8984;K</span>
</span>
</div>
<!-- 👉 App Bar Search -->
<LazyAppBarSearch
v-model:isDialogVisible="isAppSearchBarVisible"
v-model:search-query="searchQuery"
:search-results="searchResult"
:suggestions="suggestionGroups"
:no-data-suggestion="noDataSuggestions"
@item-selected="redirectToSuggestedOrSearchedPage"
>
<!--
<template #suggestions>
use this slot if you want to override default suggestions
</template>
-->
<!--
<template #noData>
use this slot to change the view of no data section
</template>
-->
<!--
<template #searchResult="{ item }">
use this slot to change the search item
</template>
-->
</LazyAppBarSearch>
</template>
<style lang="scss" scoped>
@use '@styles/variables/_vuetify.scss';
.meta-key {
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity));
border-radius: 6px;
block-size: 1.5625rem;
line-height: 1.3125rem;
padding-block: 0.125rem;
padding-inline: 0.25rem;
}
</style>

View File

@ -126,7 +126,7 @@ loadAccount(props.address);
</div>
<div class="mt-4 md:col-span-2 md:mt-0 md:ml-4">
<!-- button -->
<div class="flex justify-end mb-4">
<div class="flex justify-end mb-4 pr-5">
<label
for="send"
class="btn btn-primary btn-sm mr-2"
@ -167,7 +167,7 @@ loadAccount(props.address);
<div class="text-xs">${{ 0 }}</div>
</div>
<div
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-primary mr-2"
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary mr-2"
>
<span
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary text-sm"
@ -196,7 +196,7 @@ loadAccount(props.address);
<div class="text-xs">${{ 0 }}</div>
</div>
<div
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-primary mr-2"
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary mr-2"
>
<span
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary text-sm"
@ -234,7 +234,7 @@ loadAccount(props.address);
<div class="text-xs">${{ 0 }}</div>
</div>
<div
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-primary mr-2"
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary mr-2"
>
<span
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary text-sm"
@ -268,7 +268,7 @@ loadAccount(props.address);
<div class="text-xs">${{ 0 }}</div>
</div>
<div
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-primary mr-2"
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary mr-2"
>
<span
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary"
@ -277,9 +277,9 @@ loadAccount(props.address);
</div>
</div>
</div>
<div class="divider"></div>
{{ totalAmount }}
<div class="mt-4 text-lg font-semibold mr-5 pl-5 border-t pt-4">
{{ totalAmount }}
</div>
</div>
</div>
</div>
@ -302,18 +302,18 @@ loadAccount(props.address);
>
</div>
<div class="overdflow-x-auto">
<table class="table w-full">
<table class="table w-full text-sm table-zebra">
<thead>
<tr>
<th style="position: relative; z-index: 2;">Validator</th>
<th>Delegation</th>
<th>Rewards</th>
<th>Action</th>
<th class="py-3">Validator</th>
<th class="py-3">Delegation</th>
<th class="py-3">Rewards</th>
<th class="py-3">Action</th>
</tr>
</thead>
<tbody class="text-sm">
<tr v-for="v in delegations">
<td class="text-caption text-primary">
<tr v-for="(v, index) in delegations" :key="index">
<td class="text-caption text-primary py-3">
<RouterLink
:to="`/${chain}/staking/${v.delegation.validator_address}`"
>{{
@ -321,8 +321,10 @@ loadAccount(props.address);
}}</RouterLink
>
</td>
<td>{{ format.formatToken(v.balance, true, '0,0.[00]') }}</td>
<td>
<td class="py-3">
{{ format.formatToken(v.balance, true, '0,0.[00]') }}
</td>
<td class="py-3">
{{
format.formatTokens(
rewards?.rewards?.find(
@ -332,11 +334,11 @@ loadAccount(props.address);
)
}}
</td>
<td>
<td class="py-3">
<div class="flex justify-end">
<label
for="delegate"
class="btn btn-primary btn-sm mr-2"
class="btn btn-primary btn-xs mr-2"
@click="
dialog.open('delegate', {
validator_address: v.delegation.validator_address,
@ -346,7 +348,7 @@ loadAccount(props.address);
>
<label
for="redelegate"
class="btn btn-primary btn-sm mr-2"
class="btn btn-primary btn-xs mr-2"
@click="
dialog.open('redelegate', {
validator_address: v.delegation.validator_address,
@ -356,7 +358,7 @@ loadAccount(props.address);
>
<label
for="unbond"
class="btn btn-primary btn-sm"
class="btn btn-primary btn-xs"
@click="
dialog.open('unbond', {
validator_address: v.delegation.validator_address,
@ -379,19 +381,19 @@ loadAccount(props.address);
>
<h2 class="card-title mb-4">Unbonding Delegations</h2>
<div class="overflow-x-auto">
<table class="table">
<table class="table text-sm w-full">
<thead>
<tr>
<th style="position: relative; z-index: 2;">Creation Height</th>
<th>Initial Balance</th>
<th>Balance</th>
<th>Completion Time</th>
<th class="py-3">Creation Height</th>
<th class="py-3">Initial Balance</th>
<th class="py-3">Balance</th>
<th class="py-3">Completion Time</th>
</tr>
</thead>
<tbody class="text-sm">
<div v-for="v in unbonding">
<div v-for="(v, index) in unbonding" :key="index">
<tr>
<td class="text-caption text-primary">
<td class="text-caption text-primary py-3">
<RouterLink
:to="`/${chain}/staking/${v.validator_address}`"
>{{
@ -401,8 +403,8 @@ loadAccount(props.address);
</td>
</tr>
<tr v-for="entry in v.entries">
<td>{{ entry.creation_height }}</td>
<td>
<td class="py-3">{{ entry.creation_height }}</td>
<td class="py-3">
{{
format.formatToken(
{
@ -414,7 +416,7 @@ loadAccount(props.address);
)
}}
</td>
<td>
<td class="py-3">
{{
format.formatToken(
{
@ -426,7 +428,9 @@ loadAccount(props.address);
)
}}
</td>
<td>{{ format.toDay(entry.completion_time, 'to') }}</td>
<td class="py-3">
{{ format.toDay(entry.completion_time, 'to') }}
</td>
</tr>
</div>
</tbody>
@ -438,27 +442,29 @@ loadAccount(props.address);
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow">
<h2 class="card-title mb-4">Transactions</h2>
<div class="overflow-x-auto">
<table class="table w-full">
<table class="table w-full text-sm">
<thead>
<tr>
<th style="position: relative">Height</th>
<th>Hash</th>
<th>Messages</th>
<th>Time</th>
<th class="py-3">Height</th>
<th class="py-3">Hash</th>
<th class="py-3">Messages</th>
<th class="py-3">Time</th>
</tr>
</thead>
<tbody class="text-sm">
<tr v-for="v in txs">
<td class="text-sm text-primary">
<tr v-for="(v, index) in txs" :key="index">
<td class="text-sm text-primary py-3">
<RouterLink :to="`/${chain}/block/${v.height}`">{{
v.height
}}</RouterLink>
</td>
<td class="text-truncate" style="max-width: 200px">
<td class="text-truncate py-3" style="max-width: 200px">
{{ v.txhash }}
</td>
<td>
{{ format.messages(v.tx.body.messages) }}
<td class="flex items-center py-3">
<div class="mr-2">
{{ format.messages(v.tx.body.messages) }}
</div>
<Icon
v-if="v.code === 0"
icon="mdi-check"
@ -466,7 +472,7 @@ loadAccount(props.address);
/>
<Icon v-else icon="mdi-multiply" class="text-error text-lg" />
</td>
<td>{{ format.toDay(v.timestamp, 'from') }}</td>
<td class="py-3">{{ format.toDay(v.timestamp, 'from') }}</td>
</tr>
</tbody>
</table>

View File

@ -29,3 +29,8 @@
:where(input[type='checkbox']:checked ~ .collapse-content) {
padding-bottom: 0;
}
.table th:first-child {
position: relative;
z-index: 2;
}