update redesign layout

This commit is contained in:
liangping 2023-06-15 11:06:30 +08:00
parent 18ce47b823
commit 4fdafa3131
3 changed files with 151 additions and 196 deletions

View File

@ -18,7 +18,7 @@
>
</div>
<div
class="hidden md:block"
class="hidden md:!block"
>
<a
class="link link-primary no-underline mr-4"

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { CosmosRestClient } from '@/libs/client';
import { useDashboard, useFormatter } from '@/stores';
import { useBlockchain, useDashboard, useFormatter } from '@/stores';
import type { Coin, CoinWithPrice, Delegation } from '@/types';
import { fromBech32, toBase64, toBech32, toHex } from '@cosmjs/encoding';
import { Icon } from '@iconify/vue';
@ -14,6 +14,7 @@ import {
} from './utils';
const dashboard = useDashboard();
const chainStore = useBlockchain()
const format = useFormatter();
const editable = ref(false); // to edit addresses
const sourceAddress = ref(''); //
@ -55,17 +56,20 @@ Object.values(conf.value).forEach((imported) => {
const accounts = computed(() => {
let a = [] as {
account: AccountEntry;
delegation: CoinWithPrice;
balances: CoinWithPrice[];
key: string,
subaccounts: {
account: AccountEntry;
delegation: CoinWithPrice;
balances: CoinWithPrice[];
}[]
}[];
Object.values(conf.value).forEach((x) => {
const composition = x.map((entry) => {
const d = delegations.value[entry.address];
let delegation = { } as CoinWithPrice
let delegation = {} as CoinWithPrice
if (d && d.length > 0) {
d.forEach((b) => {
delegation.amount = (Number(b.balance.amount) + Number( delegation.amount || 0)).toFixed()
delegation.amount = (Number(b.balance.amount) + Number(delegation.amount || 0)).toFixed()
delegation.denom = b.balance.denom;
});
delegation.value = format.tokenValueNumber(delegation)
@ -75,29 +79,34 @@ const accounts = computed(() => {
account: entry,
delegation,
balances: balances.value[entry.address]
? balances.value[entry.address].map(x => {
const value = format.tokenValueNumber(x)
return {
amount: x.amount,
denom: x.denom,
value,
change24h: format.priceChanges(x.denom)
}
})
: []
? balances.value[entry.address].map(x => {
const value = format.tokenValueNumber(x)
return {
amount: x.amount,
denom: x.denom,
value,
change24h: format.priceChanges(x.denom)
}
})
: []
}
});
a = a.concat(composition);
if (x.at(0)) a.push({ key: x.at(0)?.address || " ", subaccounts: composition });
});
return a;
});
const addresses = computed(() => {
return accounts.value.map((x) => x.account.address);
return accounts.value.flatMap(x => x.subaccounts.map(a => a.account.address))
// const temp = [] as string[]
// accounts.value.forEach((x) => x.accounts.forEach(a => {
// temp.push(a.account.address)
// }));
// return temp
});
const totalValue = computed(() => {
return accounts.value.reduce((s, e) => {
return accounts.value.flatMap(x => x.subaccounts).reduce((s, e) => {
s += e.delegation.value || 0
e.balances.forEach(b => {
s += b.value || 0
@ -106,8 +115,8 @@ const totalValue = computed(() => {
}, 0)
})
const totalChange= computed(() => {
return accounts.value.reduce((s, e) => {
const totalChange = computed(() => {
return accounts.value.flatMap(x => x.subaccounts).reduce((s, e) => {
s += (e.delegation.change24h || 0) * (e.delegation.value || 0) / 100
e.balances.forEach(b => {
s += (b.change24h || 0) * (b.value || 0) / 100
@ -223,168 +232,132 @@ async function loadBalances(endpoint: string, address: string) {
<template>
<div>
<div class="overflow-x-auto w-full card">
<div
class="lg:!flex lg:!items-center lg:!justify-between bg-base-100 p-5"
>
<div class="lg:!flex lg:!items-center lg:!justify-between bg-base-100 p-5">
<div class="min-w-0 flex-1">
<h2
class="text-2xl font-bold leading-7 sm:!truncate sm:!text-3xl sm:!tracking-tight"
>
<h2 class="text-2xl font-bold leading-7 sm:!truncate sm:!text-3xl sm:!tracking-tight">
Accounts
</h2>
<div
class="mt-1 flex flex-col sm:!mt-0 sm:!flex-row sm:!flex-wrap sm:!space-x-6"
>
<div class="mt-1 flex flex-col sm:!mt-0 sm:!flex-row sm:!flex-wrap sm:!space-x-6">
<div class="mt-2 flex items-center text-sm text-gray-500">
<svg
class="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
<svg class="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M6 3.75A2.75 2.75 0 018.75 1h2.5A2.75 2.75 0 0114 3.75v.443c.572.055 1.14.122 1.706.2C17.053 4.582 18 5.75 18 7.07v3.469c0 1.126-.694 2.191-1.83 2.54-1.952.599-4.024.921-6.17.921s-4.219-.322-6.17-.921C2.694 12.73 2 11.665 2 10.539V7.07c0-1.321.947-2.489 2.294-2.676A41.047 41.047 0 016 4.193V3.75zm6.5 0v.325a41.622 41.622 0 00-5 0V3.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25zM10 10a1 1 0 00-1 1v.01a1 1 0 001 1h.01a1 1 0 001-1V11a1 1 0 00-1-1H10z"
clip-rule="evenodd"
/>
clip-rule="evenodd" />
<path
d="M3 15.055v-.684c.126.053.255.1.39.142 2.092.642 4.313.987 6.61.987 2.297 0 4.518-.345 6.61-.987.135-.041.264-.089.39-.142v.684c0 1.347-.985 2.53-2.363 2.686a41.454 41.454 0 01-9.274 0C3.985 17.585 3 16.402 3 15.055z"
/>
d="M3 15.055v-.684c.126.053.255.1.39.142 2.092.642 4.313.987 6.61.987 2.297 0 4.518-.345 6.61-.987.135-.041.264-.089.39-.142v.684c0 1.347-.985 2.53-2.363 2.686a41.454 41.454 0 01-9.274 0C3.985 17.585 3 16.402 3 15.055z" />
</svg>
Manage all your assets in one page
</div>
</div>
</div>
<div class="mt-5 flex flex-col lg:!ml-4 lg:!mt-0 text-right">
<div class="mt-5 flex flex-col lg:!ml-4 lg:!mt-0 text-right">
<span>Total Value</span>
<span class="text-xl text-success font-bold">${{ format.formatNumber(totalValue, '0,0.[00]') }}</span>
<span class="text-sm" :class="format.color(totalChange)">{{ format.formatNumber(totalChange, '+0,0.[00]') }}</span>
<span class="text-sm" :class="format.color(totalChange)">{{ format.formatNumber(totalChange, '+0,0.[00]')
}}</span>
</div>
</div>
<div class="overflow-x-auto">
<table class="table table-compact w-full">
<!-- head -->
<thead class="rounded-none">
<tr>
<th v-if="editable"></th>
<th class="hidden md:block">Account</th>
<th>Delegation</th>
<th>Balance</th>
<th></th>
</tr>
</thead>
<tbody>
<!-- row 1 -->
<tr v-for="{account, balances, delegation} in accounts">
<td v-if="editable">
<Icon
icon="mdi:close-box"
class="text-error"
@click="removeAddress(account.address)"
></Icon>
</td>
<td class="px-4 hidden md:block">
<RouterLink :to="`/${account.chainName}/account/${account.address}`">
<div class="flex items-center space-x-2">
<div class="avatar">
<div class="mask mask-squircle w-8 h-8">
<img :src="account.logo" :alt="account.address" />
</div>
</div>
<div>
<div class="font-bold capitalize">
{{ account.chainName }}
</div>
<div class="text-sm opacity-50 hidden md:!block">
{{ account.address }}
</div>
</div>
</div>
</RouterLink>
</td>
<td>
<div v-if="delegation">
{{
format.formatToken(
delegation,
true,
'0,0.[0000]',
'all'
)
}}
<div
class="text-xs"
:class="format.priceColor(delegation.denom)"
>
${{ format.formatNumber(delegation.value, '0,0.[00]') }}
</div>
</div>
</td>
<td>
<ul tabindex="0" >
<li v-for="b in balances">
{{ format.formatToken(b, true, '0,0.[0000]', 'all') }}
<div class="text-xs" :class="format.priceColor(b.denom)">
${{ format.formatNumber(b.value, '0,0.[00]') }} ({{
format.formatNumber(b.change24h, '+0.[0]')
}}%)
</div>
</li>
</ul>
</td>
<th>
<button class="btn btn-ghost btn-xs hidden">details</button>
</th>
</tr>
</tbody>
<tfoot>
<th colspan="10">
<div class="flex justify-between">
<span>
<button
type="button"
class="inline-flex items-center rounded-md bg-primary px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm"
@click="toggleEdit"
>
<svg
class="-ml-0.5 mr-1.5 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
d="M2.695 14.763l-1.262 3.154a.5.5 0 00.65.65l3.155-1.262a4 4 0 001.343-.885L17.5 5.5a2.121 2.121 0 00-3-3L3.58 13.42a4 4 0 00-.885 1.343z"
/>
</svg>
Edit
</button>
<a
href="#address-modal"
class="inline-flex items-center ml-3 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
>
<svg
class="-ml-0.5 mr-1.5 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
d="M12.232 4.232a2.5 2.5 0 013.536 3.536l-1.225 1.224a.75.75 0 001.061 1.06l1.224-1.224a4 4 0 00-5.656-5.656l-3 3a4 4 0 00.225 5.865.75.75 0 00.977-1.138 2.5 2.5 0 01-.142-3.667l3-3z"
/>
<path
d="M11.603 7.963a.75.75 0 00-.977 1.138 2.5 2.5 0 01.142 3.667l-3 3a2.5 2.5 0 01-3.536-3.536l1.225-1.224a.75.75 0 00-1.061-1.06l-1.224 1.224a4 4 0 105.656 5.656l3-3a4 4 0 00-.225-5.865z"
/>
</svg>
Import
</a>
</span>
<RouterLink to="/wallet/keplr" class="btn btn-sm btn-primary hidden md:block">
Add chain to Keplr
</RouterLink>
</div>
</th>
</tfoot>
</table>
</div>
<div class="overflow-x-auto">
<div v-for="{ key, subaccounts } in accounts" class="bg-base-100 rounded-xl my-5 p-5">
<div class="flex justify-self-center">
<div class="mr-2 p-2">
<svg :fill="chainStore.current?.themeColor || '#666CFF'" height="28px" width="28px" version="1.1" id="Capa_1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 487.5 487.5"
xml:space="preserve">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M437,12.3C437,5.5,431.5,0,424.7,0H126.3C84.4,0,50.4,34.1,50.4,75.9v335.7c0,41.9,34.1,75.9,75.9,75.9h298.5 c6.8,0,12.3-5.5,12.3-12.3V139.6c0-6.8-5.5-12.3-12.3-12.3H126.3c-28.3,0-51.4-23.1-51.4-51.4S98,24.5,126.3,24.5h298.5 C431.5,24.5,437,19,437,12.3z M126.3,151.8h286.2V463H126.3c-28.3,0-51.4-23.1-51.4-51.4V131.7 C88.4,144.2,106.5,151.8,126.3,151.8z">
</path>
<path
d="M130.5,64.8c-6.8,0-12.3,5.5-12.3,12.3s5.5,12.3,12.3,12.3h280.1c6.8,0,12.3-5.5,12.3-12.3s-5.5-12.3-12.3-12.3H130.5z">
</path>
<path
d="M178,397.7c6.3,2.4,13.4-0.7,15.8-7.1l17.9-46.8h62.7c0.5,0,0.9-0.1,1.3-0.1l17.9,46.9c1.9,4.9,6.5,7.9,11.4,7.9 c1.5,0,2.9-0.3,4.4-0.8c6.3-2.4,9.5-9.5,7.1-15.8l-54-141.2c-3-7.9-10.4-13-18.8-13c-8.4,0-15.8,5.1-18.8,13l-54,141.2 C168.5,388.2,171.7,395.2,178,397.7z M243.7,260l22.7,59.3h-45.3L243.7,260z">
</path>
</g>
</g>
</g>
</svg>
</div>
<div>
<div class=" font-bold">{{ key }}</div>
<div class="dropdown">
<label tabindex="0" class="">{{ subaccounts.length }} addresses</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-200 rounded-box z-50">
<li v-for="x in subaccounts">
<a>
<img :src="x.account.logo" class="w-8 h-8 mr-2" />
<span class="font-bold capitalize">{{ x.account.chainName }} <br>
<span class="text-xs font-normal">{{ x.account.address }}</span>
</span>
<label class="btn btn-error btn-xs" @click="removeAddress(x.account.address)">Remove</label>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="divider"></div>
<div>
<div class="my-4 ml-6">Delegations</div>
<ul class="!menu bg-base-200 w-full rounded-box ">
<div v-for="x in subaccounts">
<li v-if="x.delegation.amount">
<a>
<img :src="x.account.logo" class="w-8 h-8 mr-2" />
<span class="font-bold">{{ format.formatToken(x.delegation, true, '0,0.[000000]', 'all') }} <br><span
class="text-xs" :class="format.color(x.delegation.change24h)">{{
format.formatNumber(x.delegation.change24h, '+0.[00]') }}%</span></span>
<span class="float-right text-right">${{ format.formatNumber(x.delegation.value, '0,0.[00]') }}<br><span
class="text-xs" :class="format.color(x.delegation.change24h)">{{
format.formatNumber((x.delegation.change24h || 0) * (x.delegation.value || 0) / 100, '+0,0.[00]')
}}</span></span>
</a>
</li>
</div>
</ul>
</div>
<div>
<div class="my-4 ml-6">Balances</div>
<ul class="!menu bg-base-200 w-full rounded-box ">
<div v-for="s in subaccounts">
<li v-for="x in s.balances">
<a>
<img :src="s.account.logo" class="w-8 h-8 mr-2" />
<span class="font-bold">{{ format.formatToken(x, true, '0,0.[000000]', 'all') }} <br><span
class="text-xs" :class="format.color(x.change24h)">{{ format.formatNumber(x.change24h, '+0.[00]')
}}%</span></span>
<span class="float-right text-right">${{ format.formatNumber(x.value, '0,0.[00]') }}<br><span
class="text-xs" :class="format.color(x.change24h)">{{ format.formatNumber((x.change24h || 0) *
(x.value || 0) / 100, '+0,0.[00]') }}</span></span>
</a>
</li>
</div>
</ul>
</div>
</div>
<div class=" text-center bg-base-100 rounded-xl p-4">
<a href="#address-modal"
class="inline-flex items-center ml-3 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50">
<svg class="-ml-0.5 mr-1.5 h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path
d="M12.232 4.232a2.5 2.5 0 013.536 3.536l-1.225 1.224a.75.75 0 001.061 1.06l1.224-1.224a4 4 0 00-5.656-5.656l-3 3a4 4 0 00.225 5.865.75.75 0 00.977-1.138 2.5 2.5 0 01-.142-3.667l3-3z" />
<path
d="M11.603 7.963a.75.75 0 00-.977 1.138 2.5 2.5 0 01.142 3.667l-3 3a2.5 2.5 0 01-3.536-3.536l1.225-1.224a.75.75 0 00-1.061-1.06l-1.224 1.224a4 4 0 105.656 5.656l3-3a4 4 0 00-.225-5.865z" />
</svg>
Import Address
</a>
<RouterLink to="/wallet/keplr">
<span class="btn btn-link">Add chain to Keplr</span>
</RouterLink>
</div>
</div>
<!-- Put this part before </body> tag -->
@ -395,10 +368,7 @@ async function loadBalances(endpoint: string, address: string) {
<div>
<label class="input-group input-group-sm w-full">
<span>Connected</span>
<select
v-model="selectedSource"
class="select select-bordered select-sm w-3/4"
>
<select v-model="selectedSource" class="select select-bordered select-sm w-3/4">
<option v-for="source in sourceOptions" :value="source">
<span class="overflow-hidden">{{ source.cosmosAddress }}</span>
</option>
@ -406,11 +376,7 @@ async function loadBalances(endpoint: string, address: string) {
</label>
<label class="input-group input-group-sm my-2">
<span>Custom</span>
<input
v-model="sourceAddress"
class="input input-bordered w-full input-sm"
placeholder="Input an address"
/>
<input v-model="sourceAddress" class="input input-bordered w-full input-sm" placeholder="Input an address" />
</label>
</div>
<div class="py-4 max-h-72 overflow-y-auto">
@ -424,19 +390,10 @@ async function loadBalances(endpoint: string, address: string) {
</div>
</div>
<div>
<div
class="tooltip"
:class="
acc.compatiable ? 'tooltip-success' : 'tooltip-error'
"
:data-tip="`Coin Type: ${acc.coinType}`"
>
<div
class="font-bold capitalize"
:class="
acc.compatiable ? 'text-green-500' : 'text-red-500'
"
>
<div class="tooltip" :class="acc.compatiable ? 'tooltip-success' : 'tooltip-error'
" :data-tip="`Coin Type: ${acc.coinType}`">
<div class="font-bold capitalize" :class="acc.compatiable ? 'text-green-500' : 'text-red-500'
">
{{ acc.chainName }}
</div>
</div>
@ -447,10 +404,7 @@ async function loadBalances(endpoint: string, address: string) {
</div>
</td>
<td class="text-right">
<span
class="btn !bg-yes !border-yes btn-xs text-white"
@click="addAddress(acc)"
>
<span class="btn !bg-yes !border-yes btn-xs text-white" @click="addAddress(acc)">
<Icon icon="mdi:plus" />
</span>
</td>

View File

@ -73,7 +73,8 @@ export const useFormatter = defineStore('formatter', {
const prices = this.dashboard.prices[id];
return prices;
},
color(change: number) {
color(change?: number) {
if(!change) return ""
switch (true) {
case change > 0:
return "text-success"